Merge "Update the strings for bluetooth hearing device details page in U" into udc-dev
diff --git a/res-product/values/strings.xml b/res-product/values/strings.xml
index d149707..5b6474e 100644
--- a/res-product/values/strings.xml
+++ b/res-product/values/strings.xml
@@ -676,4 +676,8 @@
<string name="lockpassword_confirm_your_password_details_frp" product="tablet">Your tablet was reset to factory settings. To use this tablet, enter your previous password.</string>
<!-- An explanation text that the password needs to be solved because the device was factory reset. [CHAR LIMIT=100] -->
<string name="lockpassword_confirm_your_password_details_frp" product="device">Your device was reset to factory settings. To use this device, enter your previous password.</string>
+ <!-- Message of incompatible charging battery tip [CHAR LIMIT=NONE] -->
+ <string name="battery_tip_incompatible_charging_message" product="default">Battery charging slowly or won\'t charge. Check if the cable and power adapter work with your phone</string>
+ <string name="battery_tip_incompatible_charging_message" product="device">Battery charging slowly or won\'t charge. Check if the cable and power adapter work with your device</string>
+ <string name="battery_tip_incompatible_charging_message" product="tablet">Battery charging slowly or won\'t charge. Check if the cable and power adapter work with your tablet</string>
</resources>
diff --git a/res/drawable-night/flash_notifications_illustration.xml b/res/drawable-night/flash_notifications_illustration.xml
new file mode 100644
index 0000000..28c4097
--- /dev/null
+++ b/res/drawable-night/flash_notifications_illustration.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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" xmlns:aapt="http://schemas.android.com/aapt"
+ android:viewportWidth="412"
+ android:viewportHeight="300"
+ android:width="412dp"
+ android:height="300dp">
+ <path
+ android:pathData="M28 0H384A28 28 0 0 1 412 28V272A28 28 0 0 1 384 300H28A28 28 0 0 1 0 272V28A28 28 0 0 1 28 0Z"
+ android:fillColor="#000000" />
+ <path
+ android:pathData="M257.719 40.9297H152.039C148.085 40.9297 144.879 44.1353 144.879 48.0897V264.77C144.879 268.724 148.085 271.93 152.039 271.93H257.719C261.673 271.93 264.879 268.724 264.879 264.77V48.0897C264.879 44.1353 261.673 40.9297 257.719 40.9297Z">
+ <aapt:attr
+ name="android:fillColor">
+ <gradient
+ android:startX="204.879"
+ android:startY="271.93"
+ android:endX="204.879"
+ android:endY="40.9297"
+ android:tileMode="clamp">
+ <item
+ android:color="#2E3192"
+ android:offset="0" />
+ <item
+ android:color="#000000"
+ android:offset="1" />
+ </gradient>
+ </aapt:attr>
+ </path>
+ <path
+ android:pathData="M205.25 206.5C255.094 206.5 295.5 166.094 295.5 116.25C295.5 66.4063 255.094 26 205.25 26C155.406 26 115 66.4063 115 116.25C115 166.094 155.406 206.5 205.25 206.5Z"
+ android:fillColor="#FEEFC3"
+ android:fillAlpha="0.3" />
+ <path
+ android:pathData="M205.29 186.541C244.11 186.541 275.58 155.071 275.58 116.251C275.58 77.4308 244.11 45.9609 205.29 45.9609C166.47 45.9609 135 77.4308 135 116.251C135 155.071 166.47 186.541 205.29 186.541Z"
+ android:fillColor="#FEEFC3"
+ android:fillAlpha="0.8" />
+ <path
+ android:pathData="M257.78 40.9805H151.22C147.232 40.9805 144 44.2 144 48.1715V265.789C144 269.761 147.232 272.98 151.22 272.98H257.78C261.768 272.98 265 269.761 265 265.789V48.1715C265 44.2 261.768 40.9805 257.78 40.9805Z"
+ android:fillColor="#000000" />
+ <path
+ android:pathData="M269.34 107.531V98.6406C269.34 98.0518 269.106 97.4872 268.69 97.0709C268.274 96.6545 267.709 96.4206 267.12 96.4206V49.7506C267.118 46.8032 265.945 43.9773 263.86 41.8941C261.775 39.8108 258.948 38.6406 256 38.6406H153.77C150.824 38.6433 148 39.8146 145.917 41.8976C143.834 43.9805 142.663 46.8049 142.66 49.7506V263.111C142.663 266.056 143.834 268.881 145.917 270.964C148 273.047 150.824 274.218 153.77 274.221H256C258.946 274.218 261.77 273.047 263.853 270.964C265.936 268.881 267.107 266.056 267.11 263.111V154.211C267.403 154.211 267.692 154.153 267.962 154.041C268.232 153.928 268.477 153.764 268.683 153.557C268.89 153.35 269.053 153.104 269.164 152.833C269.275 152.563 269.331 152.273 269.33 151.981V129.761C269.331 129.469 269.275 129.179 269.164 128.91C269.053 128.64 268.889 128.394 268.683 128.188C268.476 127.981 268.231 127.818 267.961 127.707C267.691 127.596 267.402 127.539 267.11 127.541V109.761C267.403 109.762 267.694 109.705 267.965 109.594C268.236 109.482 268.483 109.318 268.69 109.11C268.897 108.903 269.061 108.657 269.173 108.386C269.285 108.114 269.341 107.824 269.34 107.531ZM264.9 263.111C264.892 265.466 263.951 267.722 262.283 269.384C260.615 271.047 258.355 271.981 256 271.981H153.77C151.413 271.978 149.154 271.04 147.487 269.374C145.82 267.707 144.883 265.448 144.88 263.091V49.7506C144.883 47.3937 145.82 45.134 147.487 43.4674C149.154 41.8007 151.413 40.8633 153.77 40.8606H256C258.357 40.8633 260.617 41.8007 262.283 43.4674C263.95 45.134 264.888 47.3937 264.89 49.7506L264.9 263.111Z"
+ android:fillColor="#80868B" />
+ <path
+ android:pathData="M206.5 88.9805H206.5A32.5 32.5 0 0 1 239 121.4805V121.4805A32.5 32.5 0 0 1 206.5 153.9805H206.5A32.5 32.5 0 0 1 174 121.4805V121.4805A32.5 32.5 0 0 1 206.5 88.9805Z"
+ android:fillColor="#D2E3FC" />
+ <path
+ android:pathData="M228 205.98H228A12 12 0 0 1 240 217.98V217.98A12 12 0 0 1 228 229.98H228A12 12 0 0 1 216 217.98V217.98A12 12 0 0 1 228 205.98Z"
+ android:fillColor="#5BB974" />
+ <path
+ android:pathData="M184 205.98H184A12 12 0 0 1 196 217.98V217.98A12 12 0 0 1 184 229.98H184A12 12 0 0 1 172 217.98V217.98A12 12 0 0 1 184 205.98Z"
+ android:fillColor="#EE675C" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/flash_notifications_illustration.xml b/res/drawable/flash_notifications_illustration.xml
new file mode 100644
index 0000000..64c110b
--- /dev/null
+++ b/res/drawable/flash_notifications_illustration.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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" xmlns:aapt="http://schemas.android.com/aapt"
+ android:viewportWidth="412"
+ android:viewportHeight="300"
+ android:width="412dp"
+ android:height="300dp">
+ <path
+ android:pathData="M28 0H384A28 28 0 0 1 412 28V272A28 28 0 0 1 384 300H28A28 28 0 0 1 0 272V28A28 28 0 0 1 28 0Z"
+ android:fillColor="#FFFFFF" />
+ <path
+ android:pathData="M205.25 205.5C255.094 205.5 295.5 165.094 295.5 115.25C295.5 65.4063 255.094 25 205.25 25C155.406 25 115 65.4063 115 115.25C115 165.094 155.406 205.5 205.25 205.5Z"
+ android:fillColor="#FCC934"
+ android:fillAlpha="0.3" />
+ <path
+ android:pathData="M205.29 185.541C244.11 185.541 275.58 154.071 275.58 115.251C275.58 76.4308 244.11 44.9609 205.29 44.9609C166.47 44.9609 135 76.4308 135 115.251C135 154.071 166.47 185.541 205.29 185.541Z"
+ android:fillColor="#FCC934"
+ android:fillAlpha="0.8" />
+ <path
+ android:pathData="M257.78 39.9805H151.22C147.232 39.9805 144 43.2 144 47.1715V264.789C144 268.761 147.232 271.98 151.22 271.98H257.78C261.768 271.98 265 268.761 265 264.789V47.1715C265 43.2 261.768 39.9805 257.78 39.9805Z"
+ android:fillColor="#FFFFFF" />
+ <path
+ android:pathData="M269.34 107.531V98.6406C269.34 98.0518 269.106 97.4872 268.69 97.0709C268.274 96.6545 267.709 96.4206 267.12 96.4206V49.7506C267.118 46.8032 265.945 43.9773 263.86 41.8941C261.775 39.8108 258.948 38.6406 256 38.6406H153.77C150.824 38.6433 148 39.8146 145.917 41.8976C143.834 43.9805 142.663 46.8049 142.66 49.7506V263.111C142.663 266.056 143.834 268.881 145.917 270.964C148 273.047 150.824 274.218 153.77 274.221H256C258.946 274.218 261.77 273.047 263.853 270.964C265.936 268.881 267.107 266.056 267.11 263.111V154.211C267.403 154.211 267.692 154.153 267.962 154.041C268.232 153.928 268.477 153.764 268.683 153.557C268.89 153.35 269.053 153.104 269.164 152.833C269.275 152.563 269.331 152.273 269.33 151.981V129.761C269.331 129.469 269.275 129.179 269.164 128.91C269.053 128.64 268.889 128.394 268.683 128.188C268.476 127.981 268.231 127.818 267.961 127.707C267.691 127.596 267.402 127.539 267.11 127.541V109.761C267.403 109.762 267.694 109.705 267.965 109.594C268.236 109.482 268.483 109.318 268.69 109.11C268.897 108.903 269.061 108.657 269.173 108.386C269.285 108.114 269.341 107.824 269.34 107.531ZM264.9 263.111C264.892 265.466 263.951 267.722 262.283 269.384C260.615 271.047 258.355 271.981 256 271.981H153.77C151.413 271.978 149.154 271.04 147.487 269.374C145.82 267.707 144.883 265.448 144.88 263.091V49.7506C144.883 47.3937 145.82 45.134 147.487 43.4674C149.154 41.8007 151.413 40.8633 153.77 40.8606H256C258.357 40.8633 260.617 41.8007 262.283 43.4674C263.95 45.134 264.888 47.3937 264.89 49.7506L264.9 263.111Z"
+ android:fillColor="#DADCE0" />
+ <path
+ android:pathData="M206.5 88.9805H206.5A32.5 32.5 0 0 1 239 121.4805V121.4805A32.5 32.5 0 0 1 206.5 153.9805H206.5A32.5 32.5 0 0 1 174 121.4805V121.4805A32.5 32.5 0 0 1 206.5 88.9805Z"
+ android:fillColor="#669DF6" />
+ <path
+ android:pathData="M228 205.98H228A12 12 0 0 1 240 217.98V217.98A12 12 0 0 1 228 229.98H228A12 12 0 0 1 216 217.98V217.98A12 12 0 0 1 228 205.98Z"
+ android:fillColor="#1E8E3E" />
+ <path
+ android:pathData="M184 205.98H184A12 12 0 0 1 196 217.98V217.98A12 12 0 0 1 184 229.98H184A12 12 0 0 1 172 217.98V217.98A12 12 0 0 1 184 205.98Z"
+ android:fillColor="#D93025" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_important_outline.xml b/res/drawable/ic_important_outline.xml
index 7a628bb..642582c 100644
--- a/res/drawable/ic_important_outline.xml
+++ b/res/drawable/ic_important_outline.xml
@@ -20,6 +20,7 @@
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
+ android:autoMirrored="true"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
diff --git a/res/drawable/ic_lock_24dp.xml b/res/drawable/ic_lock_24dp.xml
new file mode 100644
index 0000000..a3f699f
--- /dev/null
+++ b/res/drawable/ic_lock_24dp.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2016 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:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="?android:attr/colorPrimary"
+ android:pathData="M12,15m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
+ <path
+ android:fillColor="?android:attr/colorPrimary"
+ android:pathData="M18,8h-1.5V5.5C16.5,3.01 14.49,1 12,1S7.5,3.01 7.5,5.5V8H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9.5,5.5C9.5,4.12 10.62,3 12,3c1.38,0 2.5,1.12 2.5,2.5V8h-5V5.5zM18,20H6V10h1.5h9H18V20z"/>
+</vector>
diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml
index e3c9a01..5271e6a 100644
--- a/res/layout/fingerprint_enroll_introduction.xml
+++ b/res/layout/fingerprint_enroll_introduction.xml
@@ -94,7 +94,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
- android:src="@drawable/ic_device_locked_24dp"/>
+ android:src="@drawable/ic_lock_24dp"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
diff --git a/res/layout/notification_history.xml b/res/layout/notification_history.xml
index 557f172..29744cc 100644
--- a/res/layout/notification_history.xml
+++ b/res/layout/notification_history.xml
@@ -186,9 +186,9 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
+ android:id="@+id/today_header"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:text="@string/notification_history_today"
android:textColor="?android:attr/textColorPrimary"
android:textAppearance="@style/TextAppearance.HomepageCardTitle"
android:paddingBottom="16dp" />
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
index f154abc..0d5ccfb 100644
--- a/res/layout/panel_layout.xml
+++ b/res/layout/panel_layout.xml
@@ -20,6 +20,7 @@
android:id="@+id/panel_container"
android:layout_width="@dimen/settings_panel_width"
android:layout_height="wrap_content"
+ android:fitsSystemWindows="true"
android:layout_gravity="center_horizontal"
android:background="@drawable/settings_panel_rounded_top_corner_background" >
@@ -67,7 +68,7 @@
android:maxLines="1"
android:textColor="?android:attr/textColorPrimary"
android:textSize="24sp"
- android:fontFamily="sans-serif-reqular"/>
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"/>
<TextView
android:id="@+id/header_subtitle"
@@ -77,7 +78,7 @@
android:maxLines="1"
android:textColor="?android:attr/textColorSecondary"
android:textSize="14sp"
- android:fontFamily="sans-serif-reqular" />
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium" />
</LinearLayout>
</LinearLayout>
@@ -90,7 +91,7 @@
android:gravity="center"
android:textColor="?android:attr/textColorPrimary"
android:textSize="24sp"
- android:fontFamily="sans-serif-reqular"/>
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"/>
<ProgressBar
android:id="@+id/progress_bar"
diff --git a/res/layout/tare_homepage.xml b/res/layout/tare_homepage.xml
index def8cb7..4cd649f 100644
--- a/res/layout/tare_homepage.xml
+++ b/res/layout/tare_homepage.xml
@@ -27,8 +27,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
- android:textOff="@string/off"
- android:textOn="@string/on"
+ android:textOff="@string/tare_off"
+ android:textOn="@string/tare_on"
android:showText="true"
android:background="?android:attr/colorBackground" />
<TextView
diff --git a/res/layout/zen_mode_senders_overlay_image.xml b/res/layout/zen_mode_senders_overlay_image.xml
deleted file mode 100644
index eba98da..0000000
--- a/res/layout/zen_mode_senders_overlay_image.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <RelativeLayout android:id="@+id/zen_mode_settings_senders_overlay_view"
- android:layout_centerInParent="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/zen_conversations_image_margin_vertical"
- android:layout_marginBottom="@dimen/zen_conversations_image_margin_vertical">
- </RelativeLayout>
-</RelativeLayout>
diff --git a/res/layout/zen_rule_type.xml b/res/layout/zen_rule_type.xml
index bd50273..4c1b84b 100644
--- a/res/layout/zen_rule_type.xml
+++ b/res/layout/zen_rule_type.xml
@@ -23,8 +23,8 @@
<ImageView
android:id="@+id/icon"
- android:layout_width="@dimen/app_icon_size"
- android:layout_height="@dimen/app_icon_size"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
android:layout_gravity="center"/>
<RelativeLayout
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 57e47f2..0d54cf4 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -51,9 +51,6 @@
<dimen name="conversation_icon_size">32dp</dimen>
<dimen name="zen_mode_settings_button_margin_vertical">24dp</dimen>
- <dimen name="zen_conversations_image_margin_vertical">24dp</dimen>
- <dimen name="zen_conversations_icon_offset">32dp</dimen>
- <dimen name="zen_conversations_icon_size">50dp</dimen>
<dimen name="zen_schedule_rule_checkbox_padding">7dp</dimen>
<dimen name="zen_schedule_day_margin">17dp</dimen>
@@ -164,6 +161,7 @@
<dimen name="sfps_lottie_translate_x">12dp</dimen>
<dimen name="sfps_lottie_translate_y">12dp</dimen>
<dimen name="udfps_lottie_translate_y">0dp</dimen>
+ <dimen name="udfps_lottie_padding_top">20dp</dimen>
<!-- Face -->
<item name="face_preview_translate_y" format="float" type="dimen">0</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a870f5d..2538245 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -26,10 +26,6 @@
<string name="deny">Deny</string>
<!-- Used in confirmation dialogs as the action that the user will tap to turn on the feature. [CHAR LIMIT=40]-->
<string name="confirmation_turn_on">Turn on</string>
- <!-- State enabled. [CHAR LIMIT=NONE] -->
- <string name="on">On</string>
- <!-- State is disabled. [CHAR LIMIT=NONE] -->
- <string name="off">Off</string>
<!-- Device Info screen. Used for a status item's value when the proper value is not known -->
<string name="device_info_default">Unknown</string>
@@ -569,6 +565,8 @@
<string name="location_settings_title">Location</string>
<!-- Used in the location settings to control turning on/off the feature entirely [CHAR LIMIT=60] -->
<string name="location_settings_primary_switch_title">Use location</string>
+ <!-- Summary for Location settings when location is off [CHAR LIMIT=NONE] -->
+ <string name="location_settings_summary_location_off">Off</string>
<!-- Summary for Location settings when location is on, explaining how many apps have location permission [CHAR LIMIT=NONE]-->
<string name="location_settings_summary_location_on">{count, plural,
=1 {On - # app has access to location}
@@ -1603,6 +1601,8 @@
<string name="android_beam_settings_title">Android Beam</string>
<!-- Used to describe the on state of the Android Beam feature [CHAR LIMIT=NONE] -->
<string name="android_beam_on_summary">Ready to transmit app content via NFC</string>
+ <!-- Used to describe the off state of the Android Beam feature [CHAR LIMIT=NONE] -->
+ <string name="android_beam_off_summary">Off</string>
<!-- Used to describe the enabled state of the Android Beam feature when NFC, which it relies on, is turned off [CHAR LIMIT=NONE] -->
<string name="nfc_disabled_summary">Unavailable because NFC is turned off</string>
<!-- Explanation of the Android Beam feature in the Android Beam settings panel. The use of "beam" here is as a verb and not considered trademarked. [CHAR LIMIT=NONE] -->
@@ -2202,6 +2202,8 @@
<string name="emergency_address_summary">Used as your location when you make an emergency call over Wi\u2011Fi</string>
<!-- Message of private dns that provides a help link. [CHAR LIMIT=NONE] -->
<string name="private_dns_help_message"><annotation id="url">Learn more</annotation> about Private DNS features</string>
+ <!-- Message to display when private dns is on. [CHAR LIMIT=10] -->
+ <string name="private_dns_mode_on">On</string>
<!-- Message to display when wifi calling needs activation [CHAR LIMIT=NONE] -->
<string name="wifi_calling_settings_activation_instructions">Activate Wi\u2011Fi Calling</string>
@@ -2235,6 +2237,10 @@
<string name="display_settings">Display</string>
<!-- Sound & display settings screen, accelerometer-based rotation check box label -->
<string name="accelerometer_title">Auto-rotate screen</string>
+ <!-- Sound & display settings screen, locked rotation check box label [CHAR LIMIT=30] -->
+ <string name="auto_rotate_option_off">Off</string>
+ <!-- Sound & display settings screen, accelerometer-based rotation check box label [CHAR LIMIT=30] -->
+ <string name="auto_rotate_option_on">On</string>
<!-- Sound & display settings screen, face-based rotation check box label [CHAR LIMIT=30] -->
<string name="auto_rotate_option_face_based">On - Face-based</string>
<!-- SmartAutoRotatePreferenceFragment settings screen, face-based rotation switch label [CHAR LIMIT=30] -->
@@ -2272,6 +2278,10 @@
<string name="auto_brightness_title">Adaptive brightness</string>
<!-- Description about the feature adaptive brightness -->
<string name="auto_brightness_description">Your screen brightness will automatically adjust to your environment and activities. You can move the slider manually to help adaptive brightness learn your preferences.</string>
+ <!-- Setting option summary when adaptive brightness is on [CHAR LIMIT=NONE] -->
+ <string name="auto_brightness_summary_on">On</string>
+ <!-- Setting option summary when adaptive brightness is off [CHAR LIMIT=NONE] -->
+ <string name="auto_brightness_summary_off">Off</string>
<!-- Display settings screen, display white balance settings title [CHAR LIMIT=30] -->
<string name="display_white_balance_title">Display white balance</string>
@@ -2473,6 +2483,7 @@
<string name="sim_lock_settings">SIM lock settings</string>
<!-- Security & screen lock settings screen, SIM lock setting option name [CHAR LIMIT=40] -->
<string name="sim_lock_settings_category">SIM lock</string>
+ <!-- Security & screen lock settings screen, SIM card lock setting summary when on [CHAR LIMIT=NONE] -->
<!-- SIM lock settings screen, setting check box label [CHAR LIMIT=40] -->
<string name="sim_pin_toggle">Lock SIM</string>
<!-- SIM card lock settings screen, setting option name to change the SIM PIN [CHAR LIMIT=40] -->
@@ -2606,6 +2617,10 @@
<string name="meid_multi_sim">MEID (sim slot <xliff:g id="meid_slot_id">%1$d</xliff:g>)</string>
<!-- About phone screen, title for primary MEID for multi-sim devices -->
<string name="meid_multi_sim_primary">MEID (sim slot <xliff:g id="meid_slot_id_primary">%1$d</xliff:g>) (primary)</string>
+ <!-- The status text when (Wi-Fi or Bluetooth) scanning is on. [CHAR LIMIT=100] -->
+ <string name="scanning_status_text_on">On</string>
+ <!-- The status text when (Wi-Fi or Bluetooth) scanning is off. [CHAR LIMIT=100] -->
+ <string name="scanning_status_text_off">Off</string>
<!-- About phone, status item title. The phone MEID number of the current LTE/CDMA device. [CHAR LIMIT=30] -->
<string name="status_meid_number">MEID</string>
<!-- About phone, status item title. The ICCID of the current LTE device. [CHAR LIMIT=30] -->
@@ -4508,6 +4523,10 @@
<string name="accessibility_vibration_settings_title">Vibration & haptics</string>
<!-- Summary for preference screen for configuring vibrations. [CHAR LIMIT=NONE] -->
<string name="accessibility_vibration_settings_summary">Control the vibration strength for different usages</string>
+ <!-- "Vibration & haptics" preference's state when enabled. This text is shown next to the "Vibration & haptics" preference title. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_vibration_settings_state_on">On</string>
+ <!-- "Vibration & haptics" preference's state when disabled. This text is shown next to the "Vibration & haptics" preference title. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_vibration_settings_state_off">Off</string>
<!-- Summary for vibration preference shown when it is disabled because the device is in silent mode. [CHAR LIMIT=NONE] -->
<string name="accessibility_vibration_setting_disabled_for_silent_mode_summary">Setting disabled because device is set to silent</string>
<!-- Title for the category of preferences to configure device vibrations related to calls. [CHAR LIMIT=NONE] -->
@@ -4656,6 +4675,10 @@
<string name="accessibility_summary_shortcut_enabled">Shortcut on</string>
<!-- Preference's shortcut when disabled. [CHAR LIMIT=NONE] -->
<string name="accessibility_summary_shortcut_disabled">Off</string>
+ <!-- Preference's state when enabled. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_summary_state_enabled">On</string>
+ <!-- Preference's state when disabled. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_summary_state_disabled">Off</string>
<!-- Accessibility service's preference's state when enabled but not running (like maybe it crashed). -->
<string name="accessibility_summary_state_stopped">Not working. Tap for info.</string>
<!-- Accessibility service's description when enabled but not running (like maybe it crashed). -->
@@ -4724,6 +4747,11 @@
<!-- Title for accessibility menu item to launch a settings activity. [CHAR LIMIT=15] -->
<string name="accessibility_menu_item_settings">Settings</string>
+ <!-- Summary for the enabled state of an accessibility feature. [CHAR LIMIT=10] -->
+ <string name="accessibility_feature_state_on">On</string>
+ <!-- Summary for the disabled state of an accessibility feature. [CHAR LIMIT=10] -->
+ <string name="accessibility_feature_state_off">Off</string>
+
<!-- Title for the preference category containing the video caption preview. [CHAR LIMIT=35] -->
<string name="captioning_preview_title">Preview</string>
<!-- Title for the preference catgeory containing standard video caption options. [CHAR LIMIT=35] -->
@@ -4905,6 +4933,8 @@
<string name="print_settings">Printing</string>
<!-- Print setting summary in settings screen [CHAR LIMIT=50] -->
+ <string name="print_settings_summary_no_service">Off</string>
+
<string name="print_settings_summary">{count, plural,
=1 {1 print service on}
other {# print services on}
@@ -4931,6 +4961,11 @@
<!-- Title for print menu item to launch the add printers activity. [CHAR LIMIT=25] -->
<string name="print_menu_item_add_printers">Add printers</string>
+ <!-- Summary for the enabled state of a print feature. [CHAR LIMIT=10] -->
+ <string name="print_feature_state_on">On</string>
+ <!-- Summary for the disabled state of a print feature. [CHAR LIMIT=10] -->
+ <string name="print_feature_state_off">Off</string>
+
<!-- Title of the action bar button to got to Play Store to download a print service. [CHAR LIMIT=25] -->
<string name="print_menu_item_add_service">Add service</string>
@@ -5156,8 +5191,6 @@
<string name="battery_tip_charge_to_full_button">Charge to full</string>
<!-- Title of incompatible charging battery tip [CHAR LIMIT=NONE] -->
<string name="battery_tip_incompatible_charging_title">Issue with charging accessory</string>
- <!-- Message of incompatible charging battery tip [CHAR LIMIT=NONE] -->
- <string name="battery_tip_incompatible_charging_message">Battery charging slowly or won\'t charge. Check if the cable and power adapter work with your phone</string>
<!-- Content description for the incompatible charging battery tip button [CHAR LIMIT=NONE] -->
<string name="battery_tip_incompatible_charging_content_description">Learn more about incompatible charging</string>
@@ -5554,6 +5587,10 @@
<string name="adaptive_connectivity_title">Adaptive connectivity</string>
<!-- Summary of Adaptive connectivity preference. [CHAR LIMIT=NONE] -->
<string name="adaptive_connectivity_summary">Extends battery life and improves device performance by automatically managing your network connections</string>
+ <!-- Switch on text of Adaptive connectivity preference. [CHAR LIMIT=NONE]-->
+ <string name="adaptive_connectivity_switch_on">On</string>
+ <!-- Switch off text of Adaptive connectivity preference. [CHAR LIMIT=NONE]-->
+ <string name="adaptive_connectivity_switch_off">Off</string>
<!-- Title for adaptive connectivity main switch preferences. [CHAR LIMIT=50] -->
<string name="adaptive_connectivity_main_switch_title">Use adaptive connectivity</string>
@@ -5646,6 +5683,10 @@
<!-- Backup and reset Settings screen --><skip />
<!-- Backup and reset settings menu and activity title -->
<string name="privacy_settings_title">Backup</string>
+ <!-- Summary for the Backup settings when it is turned on. -->
+ <string name="backup_summary_state_on">On</string>
+ <!-- Summary for the Backup settings when it is turned off. -->
+ <string name="backup_summary_state_off">Off</string>
<!-- Backup section title -->
<string name="backup_section_title">Backup & restore</string>
<!-- Personal data section title -->
@@ -5732,7 +5773,7 @@
<string name="notification_log_title">Notification log</string>
<string name="notification_history_title">Notification history</string>
- <string name="notification_history_today">Last 24 hours</string>
+ <string name="notification_history_today">Last %d hours</string>
<string name="notification_history_snooze">Snoozed</string>
<string name="notification_history_dismiss">Recently dismissed</string>
@@ -7112,6 +7153,9 @@
<!-- Sound: Summary for the spatializer effect. [CHAR LIMIT=NONE]-->
<string name="spatial_audio_text">Audio from compatible media becomes more immersive</string>
+ <!-- Sound: Summary for the Spatial audio setting when it is off. [CHAR LIMIT=NONE]-->
+ <string name="spatial_summary_off">Off</string>
+
<!-- Sound: Summary for the Spatial audio setting when it is on with one output device enabled. [CHAR LIMIT=NONE]-->
<string name="spatial_summary_on_one">On / <xliff:g id="output device" example="Phone speaker">%1$s</xliff:g></string>
@@ -7304,6 +7348,9 @@
<!-- Sound settings screen, summary format of do not disturb when on with extra info. [CHAR LIMIT=NONE] -->
<string name="zen_mode_sound_summary_on_with_info">On / <xliff:g name="dnd_summary" example="No sound except alarms and media">%1$s</xliff:g></string>
+ <!-- Sound settings screen, summary format of do not disturb when on with no extra information. [CHAR LIMIT=NONE] -->
+ <string name="zen_mode_sound_summary_on">On</string>
+
<!-- Do not disturb: Summary for zen mode duration setting indicating user will be prompted to set dnd duration whenever dnd is manually toggled on [CHAR LIMIT=NONE]-->
<string name="zen_mode_duration_summary_always_prompt">Ask every time</string>
@@ -8187,8 +8234,6 @@
<!-- [CHAR LIMIT=120] Zen mode settings: Title for conversations settings page -->
<string name="zen_mode_conversations_title">Conversations</string>
- <!-- [CHAR LIMIT=120] Zen mode settings: Header for conversations settings page -->
- <string name="zen_mode_conversations_section_title">Conversations that can interrupt</string>
<string name="zen_mode_from_all_conversations">All conversations</string>
<string name="zen_mode_from_important_conversations">Priority conversations</string>
<!-- [CHAR LIMIT=40] Version of the above for "priority conversations" when it is a non-first member of a list -->
@@ -8435,6 +8480,19 @@
<!-- PIN entry dialog title for entering the administrator PIN [CHAR LIMIT=none] -->
<string name="restr_pin_enter_admin_pin">Enter admin PIN</string>
+ <!-- Switch On/Off -->
+ <string name="switch_on_text">On</string>
+ <string name="switch_off_text">Off</string>
+
+ <!-- Switch text for nfc feature being on [CHAR LIMIT=NONE] -->
+ <string name="nfc_setting_on">On</string>
+ <!-- Switch text for nfc feature being off [CHAR LIMIT=NONE] -->
+ <string name="nfc_setting_off">Off</string>
+
+ <!-- The subtext when screen pinning feature is enabled. [CHAR LIMIT=28] -->
+ <string name="screen_pinning_switch_on_text">On</string>
+ <!-- The subtext when screen pinning feature is disabled. [CHAR LIMIT=28] -->
+ <string name="screen_pinning_switch_off_text">Off</string>
<!-- [CHAR LIMIT=28] Screen pinning title -->
<string name="screen_pinning_title">App pinning</string>
<!-- [CHAR LIMIT=none] Screen pinning introduction -->
@@ -8588,7 +8646,11 @@
<!-- Label for notification settings for an specific app [CHAR LIMIT=40] -->
<string name="notifications_label">Notifications</string>
<!-- App notification summary with notifications enabled [CHAR LIMIT=40] -->
+ <string name="notifications_enabled">On</string>
+ <!-- App notification summary with notifications enabled [CHAR LIMIT=40] -->
<string name="notifications_enabled_with_info"><xliff:g id="notifications_sent" example="~6 per week">%1$s</xliff:g> / <xliff:g id="notifications_categories_off" example="3 categories turned off">%2$s</xliff:g> </string>
+ <!-- Label for showing apps with blocked notifications in list [CHAR LIMIT=30] -->
+ <string name="notifications_disabled">Off</string>
<!-- Permissions preference summary [CHAR LIMIT=40] -->
<string name="notifications_categories_off">{count, plural,
@@ -9423,6 +9485,12 @@
<!-- Description of message shown when app is blocklisted for background data access [CHAR LIMIT=NONE] -->
<string name="restrict_background_blocklisted">Background data is turned off</string>
+ <!-- Summary for the Data Saver feature being on [CHAR LIMIT=NONE] -->
+ <string name="data_saver_on">On</string>
+
+ <!-- Summary for the Data Saver feature being off [CHAR LIMIT=NONE] -->
+ <string name="data_saver_off">Off</string>
+
<!-- Switch label to enable the Data Saver feature [CHAR LIMIT=NONE] -->
<string name="data_saver_switch_title">Use Data Saver</string>
@@ -9441,9 +9509,15 @@
<!-- Summary for suggestion adding more fingerprints [CHAR LIMIT=55] -->
<string name="suggestion_additional_fingerprints_summary">Unlock with a different finger</string>
+ <!-- Summary of battery saver when on [CHAR LIMIT=NONE] -->
+ <string name="battery_saver_on_summary">On</string>
+
<!-- Summary of battery saver when it is off and scheduled [CHAR LIMIT=NONE] -->
<string name="battery_saver_off_scheduled_summary">Will turn on at <xliff:g id="battery_percentage" example="15%">%1$s</xliff:g></string>
+ <!-- Summary of battery saver when it is off and scheduled [CHAR LIMIT=NONE] -->
+ <string name="battery_saver_off_summary">Off</string>
+
<!-- Preference title for battery usage list page[CHAR_LIMIT=50]-->
<string name="app_battery_usage_title">App battery usage</string>
@@ -9589,6 +9663,9 @@
<!-- Title of screen controlling which apps have access to send premium SMS messages [CHAR LIMIT=60] -->
<string name="premium_sms_access">Premium SMS access</string>
+ <!-- Summary for Bluetooth when disabled. [CHAR LIMIT=NONE] -->
+ <string name="bluetooth_disabled">Off</string>
+
<!-- Summary for Bluetooth when connected to one device. [CHAR LIMIT=NONE] -->
<string name="bluetooth_connected_summary">Connected to <xliff:g name="device">%1$s</xliff:g></string>
@@ -9825,6 +9902,10 @@
<!-- Title text for the assist gesture [CHAR LIMIT=60] DO NOT TRANSLATE -->
<string name="assist_gesture_title" translatable="false">Assist gesture</string>
+ <!-- Switch text for each gesture setting state -->
+ <string name="gesture_setting_on">On</string>
+ <string name="gesture_setting_off">Off</string>
+
<!-- setting enable OEM unlock Checkbox's summary to explain this Checkbox is disabled because the bootloader has been unlocked [CHAR_LIMIT=60] -->
<string name="oem_unlock_enable_disabled_summary_bootloader_unlocked">Bootloader is already unlocked</string>
<!-- setting enable OEM unlock Checkbox's summary to explain this Checkbox is disabled because there is no connectivity or the device is locked by the carrier [CHAR_LIMIT=60] -->
@@ -10628,6 +10709,9 @@
<!-- Label for the on position of a switch on the mobile network details page which allows
disabling/enabling a SIM. The SIM is enabled in this state. [CHAR LIMIT=40] -->
<string name="mobile_network_use_sim_on">Use SIM</string>
+ <!-- Label for the off position of a switch on the mobile network details page which allows
+ disabling/enabling a SIM. The SIM is disabled in this state. [CHAR LIMIT=40] -->
+ <string name="mobile_network_use_sim_off">Off</string>
<!-- Text shown in an information footer on the SIM details page for a physical SIM notifying
the user that the way to disable this SIM is to physically remove it. This is in contrast
to eSIM's, which can disabled using an on/off toggle switch. [CHAR LIMIT=NONE] -->
@@ -11447,6 +11531,10 @@
<!-- TARE settings title in developer options; "TARE" is the name of the feature and cannot be
translated. [CHAR LIMIT=40] -->
<string name="tare_settings">TARE Settings</string>
+ <!-- Summary for the TARE feature being on (ie. enabled) [CHAR LIMIT=NONE] -->
+ <string name="tare_on">On</string>
+ <!-- Summary for the TARE feature being off (ie. disabled) [CHAR LIMIT=NONE] -->
+ <string name="tare_off">Off</string>
<!-- Allows user to revert the TARE settings to their default values [CHAR LIMIT=40] -->
<string name="tare_revert">Revert to Default Settings</string>
<!-- Allows user to view AlarmManager policy factors. Alarm in this context is referring to the
@@ -11708,6 +11796,10 @@
<string name="dream_complications_toggle_title">Show additional information</string>
<!-- The summary of what overlays this toggle controls [CHAR LIMIT=none] -->
<string name="dream_complications_toggle_summary">Display things like the time, weather, or other information on the screen saver</string>
+ <!-- The title of the toggle which enables/disables the home controls button on top of the screen saver [CHAR LIMIT=none] -->
+ <string name="dream_home_controls_toggle_title">Show home controls</string>
+ <!-- The summary of the home controls toggle [CHAR LIMIT=none] -->
+ <string name="dream_home_controls_toggle_summary">Show home controls button from the screen saver</string>
<!-- The title of the category to show for the screensaver miscellaneous settings [CHAR LIMIT=none] -->
<string name="dream_more_settings_category">More settings</string>
<!-- The title of the screen saver setup page [CHAR LIMIT=none] -->
@@ -11781,7 +11873,8 @@
<string name="find_broadcast_password_dialog_connection_error">Can\u2019t connect. Try again.</string>
<!-- The error message of enter password dialog in bluetooth find broadcast page [CHAR LIMIT=none] -->
<string name="find_broadcast_password_dialog_password_error">Wrong password</string>
-
+ <!-- The error message of join the broadcast session by scanning the QR code [CHAR LIMIT=none] -->
+ <string name="find_broadcast_join_broadcast_error">Can\u2019t join the broadcast</string>
<!-- [CHAR LIMIT=NONE] Le audio QR code scanner sub-title -->
<string name="bt_le_audio_scan_qr_code_scanner">To start listening, center the QR code below</string>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index dd3882e..eeba1c7 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -220,6 +220,7 @@
<!-- Note that Dialog themes do not set list dividers -->
<style name="Theme.Panel" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
<item name="android:windowBackground">@null</item>
+ <item name="android:windowTranslucentNavigation">true</item>
<item name="android:dividerHorizontal">@*android:drawable/list_divider_material</item>
<item name="android:windowNoTitle">true</item>
<item name="android:listDivider">@*android:drawable/list_divider_material</item>
diff --git a/res/xml/accessibility_tap_assistance.xml b/res/xml/accessibility_tap_assistance.xml
index 63adc9d..22667b4 100644
--- a/res/xml/accessibility_tap_assistance.xml
+++ b/res/xml/accessibility_tap_assistance.xml
@@ -24,6 +24,7 @@
android:entries="@array/long_press_timeout_selector_list_titles"
android:entryValues="@array/long_press_timeout_selector_values"
android:key="select_long_press_timeout_preference"
+ android:summary="%s"
android:persistent="false"
android:title="@string/accessibility_long_press_timeout_preference_title"
settings:controller="com.android.settings.accessibility.SelectLongPressTimeoutPreferenceController"/>
diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml
index 5b744fb..9857a4d 100644
--- a/res/xml/app_notification_settings.xml
+++ b/res/xml/app_notification_settings.xml
@@ -26,17 +26,15 @@
<com.android.settings.widget.SettingsMainSwitchPreference
android:key="block" />
- <com.android.settingslib.widget.FooterPreference
+ <Preference
android:key="block_desc" />
-
<!-- Conversations added here -->
<PreferenceCategory
android:title="@string/conversations_category_title"
android:key="conversations"
- android:visibility="gone"
- settings:allowDividerAbove="false"
- settings:allowDividerBelow="false">
+ android:visibility="gone">
+
</PreferenceCategory>
<com.android.settingslib.RestrictedSwitchPreference
android:key="invalid_conversation_switch"
@@ -49,25 +47,13 @@
android:key="bubble_pref_link"
android:title="@string/notification_bubbles_title"
android:icon="@drawable/ic_create_bubble"
- settings:allowDividerAbove="false"
settings:controller="com.android.settings.notification.app.BubbleSummaryPreferenceController">
</Preference>
<!-- Channels/Channel groups added here -->
<PreferenceCategory
android:key="channels"
- android:layout="@layout/empty_view"
- settings:allowDividerAbove="true"
- settings:allowDividerBelow="true" />
-
- <!-- Show badge -->
- <com.android.settingslib.RestrictedSwitchPreference
- android:key="badge"
- android:title="@string/notification_badge_title"
- settings:useAdditionalSummary="true"
- android:order="1001"
- settings:allowDividerAbove="true"
- settings:restrictedSwitchSummary="@string/enabled_by_admin" />
+ android:layout="@layout/empty_view" />
<!-- Importance toggle -->
<com.android.settingslib.RestrictedSwitchPreference
@@ -86,18 +72,25 @@
android:title="@string/app_notification_override_dnd_title"
android:summary="@string/app_notification_override_dnd_summary"/>
- <Preference
- android:key="app_link"
- android:order="1003"
- android:icon="@drawable/ic_settings_24dp"
- android:title="@string/app_settings_link" />
+ <!-- Show badge -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="badge"
+ android:title="@string/notification_badge_title"
+ settings:useAdditionalSummary="true"
+ android:order="1001"
+ android:icon="@drawable/ic_notification_dot"
+ settings:allowDividerAbove="true"
+ settings:restrictedSwitchSummary="@string/enabled_by_admin" />
- <com.android.settingslib.widget.FooterPreference
- android:key="desc"
- android:order="5000" />
+ <Preference
+ android:key="app_link"
+ android:order="1003"
+ android:icon="@drawable/ic_settings_24dp"
+ android:title="@string/app_settings_link" />
<com.android.settingslib.widget.FooterPreference
android:key="deleted"
+ android:icon="@drawable/ic_trash_can"
android:order="8000" />
</PreferenceScreen>
diff --git a/res/xml/conversation_notification_settings.xml b/res/xml/conversation_notification_settings.xml
index 9078e2d..89812a7 100644
--- a/res/xml/conversation_notification_settings.xml
+++ b/res/xml/conversation_notification_settings.xml
@@ -96,4 +96,11 @@
android:summary="@string/demote_conversation_summary"
settings:allowDividerAbove="true"/>
+ <!-- only used in ChannelPanelActivity -->
+ <Preference
+ android:key="convo_promote"
+ android:icon="@drawable/ic_promote_conversation"
+ android:title="@string/promote_conversation_title"
+ android:summary="@string/promote_conversation_summary" />
+
</PreferenceScreen>
diff --git a/res/xml/dream_fragment_overview.xml b/res/xml/dream_fragment_overview.xml
index 3321fd1..8377a06 100644
--- a/res/xml/dream_fragment_overview.xml
+++ b/res/xml/dream_fragment_overview.xml
@@ -46,6 +46,12 @@
android:summary="@string/dream_complications_toggle_summary"
settings:controller="com.android.settings.dream.DreamComplicationPreferenceController"/>
+ <SwitchPreference
+ android:key="dream_home_controls_toggle"
+ android:title="@string/dream_home_controls_toggle_title"
+ android:summary="@string/dream_home_controls_toggle_summary"
+ settings:controller="com.android.settings.dream.DreamHomeControlsPreferenceController"/>
+
<com.android.settings.applications.SpacePreference
android:layout_height="16dp" />
diff --git a/res/xml/flash_notifications_settings.xml b/res/xml/flash_notifications_settings.xml
index 7496486..0017fa6 100644
--- a/res/xml/flash_notifications_settings.xml
+++ b/res/xml/flash_notifications_settings.xml
@@ -20,14 +20,13 @@
android:title="@string/flash_notifications_title">
<com.android.settingslib.widget.TopIntroPreference
+ android:key="flash_notifications_intro"
android:title="@string/flash_notifications_intro" />
- <!-- TODO update when rawRes added
<com.android.settingslib.widget.IllustrationPreference
- android:key="flash_notifications_guide_preference"
- settings:lottie_rawRes="@raw/NOT ADDED"
- settings:searchable="false" />
- -->
+ android:key="flash_notifications_illustration"
+ settings:searchable="false"
+ settings:lottie_rawRes="@drawable/flash_notifications_illustration"/>
<SwitchPreference
android:key="camera_flash_notification_preference"
diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml
index 69fa4d2..ff41a0b 100644
--- a/res/xml/language_settings.xml
+++ b/res/xml/language_settings.xml
@@ -37,5 +37,13 @@
android:name="classname"
android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
</Preference>
+
+ <Preference
+ android:key="regional_preferences"
+ android:title="@string/regional_preferences_title"
+ android:summary="@string/regional_preferences_summary"
+ android:fragment="com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment"
+ settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesController" />
+
</PreferenceCategory>
</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/zen_mode_conversations_settings.xml b/res/xml/zen_mode_conversations_settings.xml
deleted file mode 100644
index e72d03c..0000000
--- a/res/xml/zen_mode_conversations_settings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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.
--->
-<PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:key="zen_mode_conversations_settings"
- android:title="@string/zen_mode_conversations_title">
- <!-- Conversations -->
- <PreferenceCategory
- android:key="zen_mode_conversations_radio_buttons"
- android:title="@string/zen_mode_conversations_section_title">
-
- <!-- Senders image -->
- <com.android.settingslib.widget.LayoutPreference
- android:key="zen_mode_conversations_image"
- android:layout="@layout/zen_mode_senders_overlay_image"
- android:selectable="false"/>
- </PreferenceCategory>
-</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceController.java b/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceController.java
index e6b49d0..ded8aca 100644
--- a/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceController.java
@@ -19,21 +19,30 @@
import android.content.Context;
import android.provider.Settings;
+import androidx.annotation.IntDef;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
-import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.google.common.primitives.Ints;
-import java.util.Optional;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/** Preference controller that controls the button or gesture in accessibility button page. */
public class AccessibilityButtonGesturePreferenceController extends BasePreferenceController
implements Preference.OnPreferenceChangeListener {
- private Optional<Integer> mDefaultGesture = Optional.empty();
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ Mode.BUTTON,
+ Mode.GESTURE,
+ })
+ private @interface Mode {
+ int BUTTON = 1;
+ int GESTURE = 2;
+ }
public AccessibilityButtonGesturePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
@@ -47,12 +56,9 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- final ListPreference listPreference = (ListPreference) preference;
final Integer value = Ints.tryParse((String) newValue);
if (value != null) {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_BUTTON_MODE, value);
- updateState(listPreference);
+ putCurrentAccessibilityButtonMode(value);
}
return true;
}
@@ -62,21 +68,17 @@
super.updateState(preference);
final ListPreference listPreference = (ListPreference) preference;
- listPreference.setValue(getCurrentAccessibilityButtonMode());
+ listPreference.setValue(String.valueOf(getCurrentAccessibilityButtonMode()));
}
- private String getCurrentAccessibilityButtonMode() {
- final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_BUTTON_MODE, getDefaultGestureValue());
- return String.valueOf(mode);
+ @Mode
+ private int getCurrentAccessibilityButtonMode() {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_BUTTON_MODE, Mode.BUTTON);
}
- private int getDefaultGestureValue() {
- if (!mDefaultGesture.isPresent()) {
- final String[] valuesList = mContext.getResources().getStringArray(
- R.array.accessibility_button_gesture_selector_values);
- mDefaultGesture = Optional.of(Integer.parseInt(valuesList[0]));
- }
- return mDefaultGesture.get();
+ private void putCurrentAccessibilityButtonMode(@Mode int mode) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mode);
}
}
diff --git a/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceController.java
index 167e08f..fc62be5 100644
--- a/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceController.java
@@ -19,21 +19,30 @@
import android.content.Context;
import android.provider.Settings;
+import androidx.annotation.IntDef;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
-import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.google.common.primitives.Ints;
-import java.util.Optional;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/** Preference controller that controls the preferred location in accessibility button page. */
public class AccessibilityButtonLocationPreferenceController extends BasePreferenceController
implements Preference.OnPreferenceChangeListener {
- private Optional<Integer> mDefaultLocation = Optional.empty();
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ Location.FLOATING_MENU,
+ Location.NAVIGATION_BAR,
+ })
+ private @interface Location {
+ int FLOATING_MENU = 1;
+ int NAVIGATION_BAR = 0;
+ }
public AccessibilityButtonLocationPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
@@ -47,12 +56,9 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- final ListPreference listPreference = (ListPreference) preference;
final Integer value = Ints.tryParse((String) newValue);
if (value != null) {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_BUTTON_MODE, value);
- updateState(listPreference);
+ putCurrentAccessibilityButtonMode(value);
}
return true;
}
@@ -62,21 +68,17 @@
super.updateState(preference);
final ListPreference listPreference = (ListPreference) preference;
- listPreference.setValue(getCurrentAccessibilityButtonMode());
+ listPreference.setValue(String.valueOf(getCurrentAccessibilityButtonMode()));
}
- private String getCurrentAccessibilityButtonMode() {
- final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_BUTTON_MODE, getDefaultLocationValue());
- return String.valueOf(mode);
+ @Location
+ private int getCurrentAccessibilityButtonMode() {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_BUTTON_MODE, Location.FLOATING_MENU);
}
- private int getDefaultLocationValue() {
- if (!mDefaultLocation.isPresent()) {
- final String[] valuesList = mContext.getResources().getStringArray(
- R.array.accessibility_button_location_selector_values);
- mDefaultLocation = Optional.of(Integer.parseInt(valuesList[0]));
- }
- return mDefaultLocation.get();
+ private void putCurrentAccessibilityButtonMode(@Location int location) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_BUTTON_MODE, location);
}
}
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java b/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
index 89e29c4..547c456 100644
--- a/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
@@ -18,6 +18,7 @@
import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
+import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
@@ -72,8 +73,7 @@
@Override
public int getMetricsCategory() {
- // TODO(b/262839191): To be updated settings_enums.proto
- return 0;
+ return SettingsEnums.ACCESSIBILITY_HEARING_AID_SETTINGS;
}
@Override
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index cf02960..426d7c9 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -266,8 +266,8 @@
: context.getText(R.string.accessibility_summary_shortcut_disabled);
} else {
serviceState = serviceEnabled
- ? context.getText(R.string.on)
- : context.getText(R.string.off);
+ ? context.getText(R.string.accessibility_summary_state_enabled)
+ : context.getText(R.string.accessibility_summary_state_disabled);
}
final CharSequence serviceSummary = info.loadSummary(context.getPackageManager());
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index 33dab82..01158bf 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -66,6 +66,7 @@
protected int mSavedCheckBoxValue = NOT_SET;
protected ShortcutPreference mShortcutPreference;
+ protected Dialog mDialog;
private AccessibilityManager.TouchExplorationStateChangeListener
mTouchExplorationStateChangeListener;
private AccessibilitySettingsContentObserver mSettingsContentObserver;
@@ -167,12 +168,15 @@
@Override
public void onResume() {
super.onResume();
+
final AccessibilityManager am = getPrefContext().getSystemService(
AccessibilityManager.class);
am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
mSettingsContentObserver.register(getContentResolver());
updateShortcutPreferenceData();
updateShortcutPreference();
+
+ updateEditShortcutDialogIfNeeded();
}
@Override
@@ -200,31 +204,30 @@
@Override
public Dialog onCreateDialog(int dialogId) {
- final Dialog dialog;
switch (dialogId) {
case DialogEnums.EDIT_SHORTCUT:
final int dialogType = WizardManagerHelper.isAnySetupWizard(getIntent())
? AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC_SUW :
AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC;
- dialog = AccessibilityDialogUtils.showEditShortcutDialog(
+ mDialog = AccessibilityDialogUtils.showEditShortcutDialog(
getPrefContext(), dialogType, getShortcutTitle(),
this::callOnAlertDialogCheckboxClicked);
- setupEditShortcutDialog(dialog);
- return dialog;
+ setupEditShortcutDialog(mDialog);
+ return mDialog;
case DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
- dialog = AccessibilityGestureNavigationTutorial
+ mDialog = AccessibilityGestureNavigationTutorial
.createAccessibilityTutorialDialogForSetupWizard(
getPrefContext(), getUserShortcutTypes(),
this::callOnTutorialDialogButtonClicked);
} else {
- dialog = AccessibilityGestureNavigationTutorial
+ mDialog = AccessibilityGestureNavigationTutorial
.createAccessibilityTutorialDialog(
getPrefContext(), getUserShortcutTypes(),
this::callOnTutorialDialogButtonClicked);
}
- dialog.setCanceledOnTouchOutside(false);
- return dialog;
+ mDialog.setCanceledOnTouchOutside(false);
+ return mDialog;
default:
throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
}
@@ -368,6 +371,13 @@
getPreferenceScreen().addPreference(generalCategory);
}
+ private void updateEditShortcutDialogIfNeeded() {
+ if (mDialog == null || !mDialog.isShowing()) {
+ return;
+ }
+ AccessibilityDialogUtils.updateShortcutInDialog(getContext(), mDialog);
+ }
+
@VisibleForTesting
void saveNonEmptyUserShortcutType(int type) {
if (type == AccessibilityUtil.UserShortcutType.EMPTY) {
@@ -412,7 +422,7 @@
}
if (!mShortcutPreference.isChecked()) {
- return context.getText(R.string.off);
+ return context.getText(R.string.switch_off_text);
}
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context,
diff --git a/src/com/android/settings/accessibility/AccessibilityUtil.java b/src/com/android/settings/accessibility/AccessibilityUtil.java
index bfb1806..e2e2933 100644
--- a/src/com/android/settings/accessibility/AccessibilityUtil.java
+++ b/src/com/android/settings/accessibility/AccessibilityUtil.java
@@ -130,7 +130,8 @@
static CharSequence getSummary(Context context, String settingsSecureKey) {
final boolean enabled = Settings.Secure.getInt(context.getContentResolver(),
settingsSecureKey, State.OFF) == State.ON;
- final int resId = enabled ? R.string.on : R.string.off;
+ final int resId = enabled ? R.string.accessibility_feature_state_on
+ : R.string.accessibility_feature_state_off;
return context.getResources().getText(resId);
}
diff --git a/src/com/android/settings/accessibility/AutoclickPreferenceController.java b/src/com/android/settings/accessibility/AutoclickPreferenceController.java
index 7410352..74cd0ac 100644
--- a/src/com/android/settings/accessibility/AutoclickPreferenceController.java
+++ b/src/com/android/settings/accessibility/AutoclickPreferenceController.java
@@ -53,7 +53,7 @@
final boolean enabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, OFF) == ON;
if (!enabled) {
- return mContext.getResources().getText(R.string.off);
+ return mContext.getResources().getText(R.string.accessibility_feature_state_off);
}
final int delayMillis = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
diff --git a/src/com/android/settings/accessibility/CaptioningFontSizeController.java b/src/com/android/settings/accessibility/CaptioningFontSizeController.java
index 196117b..67a8e8a 100644
--- a/src/com/android/settings/accessibility/CaptioningFontSizeController.java
+++ b/src/com/android/settings/accessibility/CaptioningFontSizeController.java
@@ -16,14 +16,12 @@
package com.android.settings.accessibility;
-import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.view.accessibility.CaptioningManager;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController;
@@ -46,22 +44,20 @@
}
@Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- final ListPreference listPreference = screen.findPreference(getPreferenceKey());
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ final ListPreference listPreference = (ListPreference) preference;
final float fontSize = mCaptioningManager.getFontScale();
+
listPreference.setValue(Float.toString(fontSize));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- final ListPreference listPreference = (ListPreference) preference;
- final ContentResolver cr = mContext.getContentResolver();
Settings.Secure.putFloat(
- cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE,
+ mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE,
Float.parseFloat((String) newValue));
- listPreference.setValue((String) newValue);
mCaptionHelper.setEnabled(true);
- return false;
+ return true;
}
}
diff --git a/src/com/android/settings/accessibility/CaptioningTypefaceController.java b/src/com/android/settings/accessibility/CaptioningTypefaceController.java
index 3876d39..d8222fa 100644
--- a/src/com/android/settings/accessibility/CaptioningTypefaceController.java
+++ b/src/com/android/settings/accessibility/CaptioningTypefaceController.java
@@ -16,14 +16,12 @@
package com.android.settings.accessibility;
-import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController;
@@ -44,23 +42,21 @@
}
@Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- final ListPreference listPreference = screen.findPreference(getPreferenceKey());
- final ContentResolver cr = mContext.getContentResolver();
- final CaptionStyle attrs = CaptionStyle.getCustomStyle(cr);
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ final ListPreference listPreference = (ListPreference) preference;
+ final CaptionStyle attrs = CaptionStyle.getCustomStyle(mContext.getContentResolver());
final String rawTypeface = attrs.mRawTypeface;
+
listPreference.setValue(rawTypeface == null ? "" : rawTypeface);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- final ListPreference listPreference = (ListPreference) preference;
- final ContentResolver cr = mContext.getContentResolver();
Settings.Secure.putString(
- cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, (String) newValue);
- listPreference.setValue((String) newValue);
+ mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE,
+ (String) newValue);
mCaptionHelper.setEnabled(true);
- return false;
+ return true;
}
}
diff --git a/src/com/android/settings/accessibility/FlashNotificationsPreferenceFragment.java b/src/com/android/settings/accessibility/FlashNotificationsPreferenceFragment.java
index f35d1a1..f796474 100644
--- a/src/com/android/settings/accessibility/FlashNotificationsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/FlashNotificationsPreferenceFragment.java
@@ -16,6 +16,7 @@
package com.android.settings.accessibility;
+import android.app.settings.SettingsEnums;
import android.content.Context;
import com.android.settings.R;
@@ -41,8 +42,7 @@
@Override
public int getMetricsCategory() {
- // TODO: Flash notifications have to add SettingsEnums.
- return 0;
+ return SettingsEnums.FLASH_NOTIFICATION_SETTINGS;
}
@Override
diff --git a/src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java b/src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java
index 2f0f833..bd447be 100644
--- a/src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java
+++ b/src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java
@@ -22,7 +22,6 @@
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
-import android.util.ArrayMap;
import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;
@@ -30,7 +29,6 @@
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
-import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
@@ -52,9 +50,6 @@
@VisibleForTesting
ListPreference mPreference;
- private final ArrayMap<String, String> mValueTitleMap = new ArrayMap<>();
- private int mDefaultSize;
-
@Retention(RetentionPolicy.SOURCE)
@IntDef({
Size.SMALL,
@@ -75,8 +70,6 @@
updateAvailabilityStatus();
}
};
-
- initValueTitleMap();
}
@Override
@@ -94,11 +87,9 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- final ListPreference listPreference = (ListPreference) preference;
final Integer value = Ints.tryParse((String) newValue);
if (value != null) {
putAccessibilityFloatingMenuSize(value);
- updateState(listPreference);
}
return true;
}
@@ -108,7 +99,7 @@
super.updateState(preference);
final ListPreference listPreference = (ListPreference) preference;
- listPreference.setValue(String.valueOf(getAccessibilityFloatingMenuSize(mDefaultSize)));
+ listPreference.setValue(String.valueOf(getAccessibilityFloatingMenuSize()));
}
@Override
@@ -129,25 +120,10 @@
mPreference.setEnabled(AccessibilityUtil.isFloatingMenuEnabled(mContext));
}
- private void initValueTitleMap() {
- if (mValueTitleMap.size() == 0) {
- final String[] values = mContext.getResources().getStringArray(
- R.array.accessibility_button_size_selector_values);
- final String[] titles = mContext.getResources().getStringArray(
- R.array.accessibility_button_size_selector_titles);
- final int mapSize = values.length;
-
- mDefaultSize = Integer.parseInt(values[0]);
- for (int i = 0; i < mapSize; i++) {
- mValueTitleMap.put(values[i], titles[i]);
- }
- }
- }
-
@Size
- private int getAccessibilityFloatingMenuSize(@Size int defaultValue) {
+ private int getAccessibilityFloatingMenuSize() {
return Settings.Secure.getInt(mContentResolver,
- Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, defaultValue);
+ Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, Size.SMALL);
}
private void putAccessibilityFloatingMenuSize(@Size int value) {
diff --git a/src/com/android/settings/accessibility/HearingDevicePairingDetail.java b/src/com/android/settings/accessibility/HearingDevicePairingDetail.java
index aa9b587..35997dd 100644
--- a/src/com/android/settings/accessibility/HearingDevicePairingDetail.java
+++ b/src/com/android/settings/accessibility/HearingDevicePairingDetail.java
@@ -16,6 +16,7 @@
package com.android.settings.accessibility;
+import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.le.ScanFilter;
@@ -61,8 +62,7 @@
@Override
public int getMetricsCategory() {
- // TODO(b/262839191): To be updated settings_enums.proto
- return 0;
+ return SettingsEnums.HEARING_AID_PAIRING;
}
@Override
diff --git a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
index 99e0dc0..2aba16e 100644
--- a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
@@ -87,7 +87,8 @@
resId = R.string.accessibility_screen_magnification_short_summary;
} else {
final boolean enabled = isChecked();
- resId = (enabled ? R.string.on : R.string.off);
+ resId = (enabled ? R.string.accessibility_feature_state_on :
+ R.string.accessibility_feature_state_off);
}
return mContext.getString(resId);
}
diff --git a/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java b/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
index 02fdf9e..98855f7 100644
--- a/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
@@ -94,7 +94,8 @@
resId = R.string.accessibility_screen_magnification_navbar_short_summary;
} else {
final boolean enabled = isChecked();
- resId = (enabled ? R.string.on : R.string.off);
+ resId = (enabled ? R.string.accessibility_feature_state_on :
+ R.string.accessibility_feature_state_off);
}
return mContext.getText(resId);
}
diff --git a/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceController.java b/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceController.java
index e5532c5..16ebe9d 100644
--- a/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceController.java
+++ b/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceController.java
@@ -50,11 +50,9 @@
if (!(preference instanceof ListPreference)) {
return false;
}
- final ListPreference listPreference = (ListPreference) preference;
final int newValue = Integer.parseInt((String) object);
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LONG_PRESS_TIMEOUT, newValue);
- updateState(listPreference);
return true;
}
@@ -62,16 +60,9 @@
@Override
public void updateState(Preference preference) {
super.updateState(preference);
- if (!(preference instanceof ListPreference)) {
- return;
- }
final ListPreference listPreference = (ListPreference) preference;
- listPreference.setValue(getLongPressTimeoutValue());
- }
- @Override
- public CharSequence getSummary() {
- return mLongPressTimeoutValueToTitleMap.get(getLongPressTimeoutValue());
+ listPreference.setValue(getLongPressTimeoutValue());
}
private String getLongPressTimeoutValue() {
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 22c57b7..edbd120 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -120,7 +120,6 @@
private AccessibilityQuickSettingsTooltipWindow mTooltipWindow;
private boolean mNeedsQSTooltipReshow = false;
private int mNeedsQSTooltipType = QuickSettingsTooltipType.GUIDE_TO_EDIT;
- private boolean mSavedAccessibilityFloatingMenuEnabled;
private ImageView mImageGetterCacheView;
protected final Html.ImageGetter mImageGetter = (String str) -> {
if (str != null && str.startsWith(IMG_PREFIX)) {
@@ -276,8 +275,6 @@
AccessibilityManager.class);
am.removeTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
mSettingsContentObserver.unregister(getContentResolver());
- mSavedAccessibilityFloatingMenuEnabled = AccessibilityUtil.isFloatingMenuEnabled(
- getContext());
super.onPause();
}
@@ -661,7 +658,7 @@
}
if (!mShortcutPreference.isChecked()) {
- return context.getText(R.string.off);
+ return context.getText(R.string.switch_off_text);
}
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context,
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 04a80dc..2011725 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -431,7 +431,7 @@
@Override
protected CharSequence getShortcutTypeSummary(Context context) {
if (!mShortcutPreference.isChecked()) {
- return context.getText(R.string.off);
+ return context.getText(R.string.switch_off_text);
}
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context,
@@ -752,6 +752,6 @@
final int uerShortcutType = getUserShortcutTypeFromSettings(context);
return (uerShortcutType != AccessibilityUtil.UserShortcutType.EMPTY)
? context.getText(R.string.accessibility_summary_shortcut_enabled)
- : context.getText(R.string.off);
+ : context.getText(R.string.accessibility_summary_shortcut_disabled);
}
}
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceController.java b/src/com/android/settings/accessibility/VibrationPreferenceController.java
index fef0958..61606b8 100644
--- a/src/com/android/settings/accessibility/VibrationPreferenceController.java
+++ b/src/com/android/settings/accessibility/VibrationPreferenceController.java
@@ -44,6 +44,9 @@
public CharSequence getSummary() {
final boolean isVibrateOn = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.VIBRATE_ON, ON) == ON;
- return mContext.getText(isVibrateOn ? R.string.on : R.string.off);
+ return mContext.getText(
+ isVibrateOn
+ ? R.string.accessibility_vibration_settings_state_on
+ : R.string.accessibility_vibration_settings_state_off);
}
}
diff --git a/src/com/android/settings/accounts/AddAccountSettings.java b/src/com/android/settings/accounts/AddAccountSettings.java
index 81db4df..85e942b 100644
--- a/src/com/android/settings/accounts/AddAccountSettings.java
+++ b/src/com/android/settings/accounts/AddAccountSettings.java
@@ -103,7 +103,8 @@
intent.putExtras(addAccountOptions)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
- startActivityForResultAsUser(intent, ADD_ACCOUNT_REQUEST, mUserHandle);
+ startActivityForResultAsUser(
+ new Intent(intent), ADD_ACCOUNT_REQUEST, mUserHandle);
} else {
setResult(RESULT_OK);
if (mPendingIntent != null) {
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index ed45c2b..e771ff4 100644
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -437,7 +437,8 @@
}
}
- private static void showLockScreen(Context context, Runnable successRunnable) {
+ /** Shows the lock screen if the keyguard is secured. */
+ public static void showLockScreen(Context context, Runnable successRunnable) {
final KeyguardManager keyguardManager = context.getSystemService(
KeyguardManager.class);
diff --git a/src/com/android/settings/applications/appinfo/AppNotificationPreferenceController.java b/src/com/android/settings/applications/appinfo/AppNotificationPreferenceController.java
index 0f48355..6698fca 100644
--- a/src/com/android/settings/applications/appinfo/AppNotificationPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppNotificationPreferenceController.java
@@ -99,11 +99,11 @@
return "";
}
if (appRow.banned) {
- return context.getText(R.string.off);
+ return context.getText(R.string.notifications_disabled);
} else if (appRow.channelCount == 0) {
return NotificationBackend.getSentSummary(context, appRow.sentByApp, false);
} else if (appRow.channelCount == appRow.blockedChannelCount) {
- return context.getText(R.string.off);
+ return context.getText(R.string.notifications_disabled);
} else {
if (appRow.blockedChannelCount == 0) {
return NotificationBackend.getSentSummary(context, appRow.sentByApp, false);
diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
index f8c1f64..e16d0d8 100644
--- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
@@ -24,7 +24,9 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
import android.credentials.CredentialManager;
import android.credentials.CredentialProviderInfo;
import android.credentials.SetEnabledProvidersException;
@@ -32,6 +34,7 @@
import android.os.Bundle;
import android.os.OutcomeReceiver;
import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
@@ -162,10 +165,54 @@
PreferenceGroup group = screen.findPreference(getPreferenceKey());
Context context = screen.getContext();
+ mPrefs.putAll(buildPreferenceList(context, group));
+ }
- for (CredentialProviderInfo service : mServices) {
- group.addPreference(createPreference(context, service));
+ /** Aggregates the list of services and builds a list of UI prefs to show. */
+ @VisibleForTesting
+ public Map<String, SwitchPreference> buildPreferenceList(
+ Context context, PreferenceGroup group) {
+ // Group the services by package name.
+ Map<String, List<CredentialProviderInfo>> groupedInfos = new HashMap<>();
+ for (CredentialProviderInfo cpi : mServices) {
+ String packageName = cpi.getServiceInfo().packageName;
+ if (!groupedInfos.containsKey(packageName)) {
+ groupedInfos.put(packageName, new ArrayList<>());
+ }
+
+ groupedInfos.get(packageName).add(cpi);
}
+
+ // Build the pref list.
+ Map<String, SwitchPreference> output = new HashMap<>();
+ for (String packageName : groupedInfos.keySet()) {
+ List<CredentialProviderInfo> infos = groupedInfos.get(packageName);
+ CredentialProviderInfo firstInfo = infos.get(0);
+ ServiceInfo firstServiceInfo = firstInfo.getServiceInfo();
+ CharSequence title = firstInfo.getLabel(context);
+ Drawable icon = firstInfo.getServiceIcon(context);
+
+ if (infos.size() > 1) {
+ // If there is more than one then group them under the package.
+ ApplicationInfo appInfo = firstServiceInfo.applicationInfo;
+ if (appInfo.nonLocalizedLabel != null) {
+ title = appInfo.loadLabel(mPm);
+ }
+ icon = mIconFactory.getBadgedIcon(appInfo, getUser());
+ }
+
+ // If there is no title then don't show anything.
+ if (TextUtils.isEmpty(title)) {
+ continue;
+ }
+
+ // Build the pref and add it to the output & group.
+ SwitchPreference pref = addProviderPreference(context, title, icon, packageName, firstInfo.getSettingsSubtitle());
+ output.put(packageName, pref);
+ group.addPreference(pref);
+ }
+
+ return output;
}
/** Creates a preference object based on the provider info. */
@@ -176,7 +223,8 @@
context,
label == null ? "" : label,
service.getServiceIcon(mContext),
- service.getServiceInfo().packageName);
+ service.getServiceInfo().packageName,
+ service.getSettingsSubtitle());
}
/**
@@ -234,16 +282,20 @@
@NonNull Context prefContext,
@NonNull CharSequence title,
@Nullable Drawable icon,
- @NonNull String packageName) {
+ @NonNull String packageName,
+ @Nullable CharSequence subtitle) {
final SwitchPreference pref = new SwitchPreference(prefContext);
pref.setTitle(title);
pref.setChecked(mEnabledPackageNames.contains(packageName));
- mPrefs.put(packageName, pref);
if (icon != null) {
pref.setIcon(Utils.getSafeIcon(icon));
}
+ if (subtitle != null) {
+ pref.setSummary(subtitle);
+ }
+
pref.setOnPreferenceClickListener(
p -> {
boolean isChecked = pref.isChecked();
diff --git a/src/com/android/settings/backup/BackupDataPreferenceController.java b/src/com/android/settings/backup/BackupDataPreferenceController.java
index 7c6775a..25ef58c 100644
--- a/src/com/android/settings/backup/BackupDataPreferenceController.java
+++ b/src/com/android/settings/backup/BackupDataPreferenceController.java
@@ -54,7 +54,8 @@
public CharSequence getSummary() {
if (!mPSCD.isBackupGray()) {
return mPSCD.isBackupEnabled()
- ? mContext.getText(R.string.on) : mContext.getText(R.string.off);
+ ? mContext.getText(R.string.accessibility_feature_state_on)
+ : mContext.getText(R.string.accessibility_feature_state_off);
}
return null;
}
diff --git a/src/com/android/settings/backup/BackupSettingsHelper.java b/src/com/android/settings/backup/BackupSettingsHelper.java
index 4a8ae0c..b55172e 100644
--- a/src/com/android/settings/backup/BackupSettingsHelper.java
+++ b/src/com/android/settings/backup/BackupSettingsHelper.java
@@ -58,7 +58,8 @@
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
if (userManager.getUserProfiles().size() == 1) {
try {
- int resId = mBackupManager.isBackupEnabled() ? R.string.on : R.string.off;
+ int resId = mBackupManager.isBackupEnabled()
+ ? R.string.backup_summary_state_on : R.string.backup_summary_state_off;
return mContext.getText(resId).toString();
} catch (RemoteException e) {
Log.e(TAG, "Error getting isBackupEnabled", e);
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index 9b1b30a..835e15d 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -63,6 +63,7 @@
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
@@ -328,6 +329,23 @@
final ViewGroup.LayoutParams containerLp =
portraitLayoutContainer.getLayoutParams();
containerLp.height = 0;
+
+ // In the portrait mode, the title and lottie animation view may
+ // overlap when title needs three lines, so adding some paddings
+ // between them, and adjusting the fp progress view here accordingly.
+ final int layoutLottieAnimationPadding = (int) getResources()
+ .getDimension(R.dimen.udfps_lottie_padding_top);
+ portraitLayoutContainer.setPadding(0,
+ layoutLottieAnimationPadding, 0, 0);
+ final ImageView progressView = udfpsEnrollView.findViewById(
+ R.id.udfps_enroll_animation_fp_progress_view);
+ progressView.setPadding(0, -(layoutLottieAnimationPadding),
+ 0, layoutLottieAnimationPadding);
+ final ImageView fingerprintView = udfpsEnrollView.findViewById(
+ R.id.udfps_enroll_animation_fp_view);
+ fingerprintView.setPadding(0, -layoutLottieAnimationPadding,
+ 0, layoutLottieAnimationPadding);
+
portraitLayoutContainer.addView(udfpsEnrollView);
setOnHoverListener(false, defaultLayout, udfpsEnrollView);
} else if (rotation == Surface.ROTATION_270) {
diff --git a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModel.java b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModel.java
index 2a918f5..b1b420d 100644
--- a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModel.java
+++ b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModel.java
@@ -58,7 +58,6 @@
private final MutableLiveData<Boolean> mAcquireLiveData = new MutableLiveData<>();
private final MutableLiveData<Integer> mPointerDownLiveData = new MutableLiveData<>();
private final MutableLiveData<Integer> mPointerUpLiveData = new MutableLiveData<>();
- private final MutableLiveData<Boolean> mDoneLiveData = new MutableLiveData<>(false);
private byte[] mToken = null;
private final int mUserId;
@@ -78,11 +77,6 @@
+ ", post progress as " + progress);
}
mProgressLiveData.postValue(progress);
-
- final Boolean done = remaining == 0;
- if (!done.equals(mDoneLiveData.getValue())) {
- mDoneLiveData.postValue(done);
- }
}
@Override
@@ -143,7 +137,6 @@
* clear progress
*/
public void clearProgressLiveData() {
- mDoneLiveData.setValue(false);
mProgressLiveData.setValue(new EnrollmentProgress(INITIAL_STEPS, INITIAL_REMAINING));
mHelpMessageLiveData.setValue(null);
mErrorMessageLiveData.setValue(null);
@@ -180,10 +173,6 @@
return mPointerUpLiveData;
}
- public LiveData<Boolean> getDoneLiveData() {
- return mDoneLiveData;
- }
-
/**
* Starts enrollment and return latest isEnrolling() result
*/
@@ -202,7 +191,6 @@
// Clear data
mProgressLiveData.setValue(new EnrollmentProgress(INITIAL_STEPS, INITIAL_REMAINING));
- mDoneLiveData.setValue(false);
mHelpMessageLiveData.setValue(null);
mErrorMessageLiveData.setValue(null);
diff --git a/src/com/android/settings/bluetooth/BluetoothBroadcastDialog.java b/src/com/android/settings/bluetooth/BluetoothBroadcastDialog.java
index b9cc29e..7fa63b0 100644
--- a/src/com/android/settings/bluetooth/BluetoothBroadcastDialog.java
+++ b/src/com/android/settings/bluetooth/BluetoothBroadcastDialog.java
@@ -19,6 +19,7 @@
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
@@ -27,6 +28,7 @@
import android.widget.Button;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import com.android.settings.R;
@@ -128,6 +130,12 @@
return SettingsEnums.DIALOG_LE_AUDIO_BROADCAST;
}
+ @Override
+ public void onCancel(@NonNull DialogInterface dialog) {
+ dismiss();
+ getActivity().finish();
+ }
+
private void launchFindBroadcastsActivity() {
Bundle bundle = new Bundle();
bundle.putString(KEY_DEVICE_ADDRESS, mDeviceAddress);
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java b/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java
index ea89053..6c435a2 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java
@@ -20,6 +20,7 @@
import static com.android.settings.bluetooth.BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS;
+import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.util.Log;
@@ -32,10 +33,8 @@
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.search.SearchIndexable;
/** Settings fragment containing bluetooth audio routing. */
-@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class BluetoothDetailsAudioRoutingFragment extends RestrictedDashboardFragment {
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
@@ -73,8 +72,7 @@
@Override
public int getMetricsCategory() {
- // TODO(b/262839191): To be updated settings_enums.proto
- return 0;
+ return SettingsEnums.BLUETOOTH_AUDIO_ROUTING;
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java
index a365b42..05bc179 100644
--- a/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java
@@ -19,6 +19,7 @@
import static android.bluetooth.BluetoothDevice.BOND_NONE;
import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
+import android.app.Activity;
import android.app.AlertDialog;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice;
@@ -27,6 +28,7 @@
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.le.ScanFilter;
import android.content.Context;
+import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@@ -34,6 +36,7 @@
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -43,6 +46,7 @@
import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -65,6 +69,7 @@
public static final String KEY_DEVICE_ADDRESS = "device_address";
public static final String PREF_KEY_BROADCAST_SOURCE_LIST = "broadcast_source_list";
+ public static final int REQUEST_SCAN_BT_BROADCAST_QR_CODE = 0;
@VisibleForTesting
String mDeviceAddress;
@@ -79,6 +84,7 @@
BluetoothFindBroadcastsHeaderController mBluetoothFindBroadcastsHeaderController;
private LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
+ private LocalBluetoothLeBroadcastMetadata mLocalBroadcastMetadata;
private Executor mExecutor;
private int mSourceId;
@@ -183,6 +189,7 @@
mCachedDevice = getCachedDevice(mDeviceAddress);
mLeBroadcastAssistant = getLeBroadcastAssistant();
mExecutor = Executors.newSingleThreadExecutor();
+ mLocalBroadcastMetadata = new LocalBluetoothLeBroadcastMetadata();
super.onAttach(context);
if (mCachedDevice == null || mLeBroadcastAssistant == null) {
@@ -229,6 +236,34 @@
}
}
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ Log.d(TAG, "onActivityResult: " + requestCode + ", resultCode: " + resultCode);
+ if (requestCode == REQUEST_SCAN_BT_BROADCAST_QR_CODE) {
+ if (resultCode == Activity.RESULT_OK) {
+
+ //Get BroadcastMetadata
+ String broadcastMetadata = data.getStringExtra(
+ QrCodeScanModeFragment.KEY_BROADCAST_METADATA);
+ BluetoothLeBroadcastMetadata source = convertToBroadcastMetadata(broadcastMetadata);
+
+ if (source != null) {
+ Log.d(TAG, "onActivityResult source Id = " + source.getBroadcastId());
+ //Create preference for the broadcast source
+ updateListCategoryFromBroadcastMetadata(source, false);
+ //Add Source
+ addSource(mBroadcastSourceListCategory.findPreference(
+ Integer.toString(source.getBroadcastId())));
+ } else {
+ Toast.makeText(getContext(),
+ R.string.find_broadcast_join_broadcast_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ }
+ }
+ }
+
@VisibleForTesting
void finishFragmentIfNecessary() {
if (mCachedDevice.getBondState() == BOND_NONE) {
@@ -466,4 +501,8 @@
public void setSourceId(int sourceId) {
mSourceId = sourceId;
}
+
+ private BluetoothLeBroadcastMetadata convertToBroadcastMetadata(String qrCodeString) {
+ return mLocalBroadcastMetadata.convertToBroadcastMetadata(qrCodeString);
+ }
}
diff --git a/src/com/android/settings/bluetooth/BluetoothFindBroadcastsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsHeaderController.java
index 1282abd..d34476b 100644
--- a/src/com/android/settings/bluetooth/BluetoothFindBroadcastsHeaderController.java
+++ b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsHeaderController.java
@@ -137,7 +137,8 @@
.putExtra(BluetoothBroadcastUtils.EXTRA_BLUETOOTH_SINK_IS_GROUP, true)
.putExtra(BluetoothBroadcastUtils.EXTRA_BLUETOOTH_DEVICE_SINK,
mCachedDevice.getDevice());
- mContext.startActivity(intent);
+ mBluetoothFindBroadcastsFragment.startActivityForResult(intent,
+ BluetoothFindBroadcastsFragment.REQUEST_SCAN_BT_BROADCAST_QR_CODE);
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java b/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java
index bf72877..6e82649 100644
--- a/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java
+++ b/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java
@@ -74,7 +74,7 @@
@Override
public String getSummary() {
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
- return mContext.getString(R.string.off);
+ return mContext.getString(R.string.bluetooth_disabled);
}
switch (mBluetoothAdapter.getConnectionState()) {
case BluetoothAdapter.STATE_CONNECTED:
@@ -95,7 +95,7 @@
final Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
if (devices == null) {
Log.e(TAG, "getConnectedDeviceSummary, bonded devices are null");
- return mContext.getString(R.string.off);
+ return mContext.getString(R.string.bluetooth_disabled);
} else if (devices.isEmpty()) {
Log.e(TAG, "getConnectedDeviceSummary, no bonded devices");
return mContext.getString(R.string.disconnected);
diff --git a/src/com/android/settings/bluetooth/QrCodeScanModeController.java b/src/com/android/settings/bluetooth/QrCodeScanModeController.java
deleted file mode 100644
index 4504b4b..0000000
--- a/src/com/android/settings/bluetooth/QrCodeScanModeController.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothLeBroadcastMetadata;
-import android.content.Context;
-import android.util.Log;
-
-import com.android.settingslib.bluetooth.BluetoothUtils;
-import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
-import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
-import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
-
-public class QrCodeScanModeController {
-
- private static final boolean DEBUG = BluetoothUtils.D;
- private static final String TAG = "QrCodeScanModeController";
-
- private LocalBluetoothLeBroadcastMetadata mLocalBroadcastMetadata;
- private LocalBluetoothLeBroadcastAssistant mLocalBroadcastAssistant;
- private LocalBluetoothManager mLocalBluetoothManager;
- private LocalBluetoothProfileManager mProfileManager;
-
- public QrCodeScanModeController(Context context) {
- if (DEBUG) {
- Log.d(TAG, "QrCodeScanModeController constructor.");
- }
- mLocalBluetoothManager = Utils.getLocalBtManager(context);
- mProfileManager = mLocalBluetoothManager.getProfileManager();
- mLocalBroadcastMetadata = new LocalBluetoothLeBroadcastMetadata();
- CachedBluetoothDeviceManager cachedDeviceManager = new CachedBluetoothDeviceManager(context,
- mLocalBluetoothManager);
- mLocalBroadcastAssistant = new LocalBluetoothLeBroadcastAssistant(context,
- cachedDeviceManager, mProfileManager);
- }
-
- private BluetoothLeBroadcastMetadata convertToBroadcastMetadata(String qrCodeString) {
- return mLocalBroadcastMetadata.convertToBroadcastMetadata(qrCodeString);
- }
-
- public void addSource(BluetoothDevice sink, String sourceMetadata,
- boolean isGroupOp) {
- mLocalBroadcastAssistant.addSource(sink,
- convertToBroadcastMetadata(sourceMetadata), isGroupOp);
- }
-}
diff --git a/src/com/android/settings/bluetooth/QrCodeScanModeFragment.java b/src/com/android/settings/bluetooth/QrCodeScanModeFragment.java
index d53e2d4..f89dac6 100644
--- a/src/com/android/settings/bluetooth/QrCodeScanModeFragment.java
+++ b/src/com/android/settings/bluetooth/QrCodeScanModeFragment.java
@@ -16,9 +16,11 @@
package com.android.settings.bluetooth;
+import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
+import android.content.Intent;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Rect;
@@ -67,13 +69,14 @@
private static final Duration VIBRATE_DURATION_QR_CODE_RECOGNITION = Duration.ofMillis(3);
+ public static final String KEY_BROADCAST_METADATA = "key_broadcast_metadata";
+
private boolean mIsGroupOp;
private int mCornerRadius;
private BluetoothDevice mSink;
private String mBroadcastMetadata;
private Context mContext;
private QrCamera mCamera;
- private QrCodeScanModeController mController;
private TextureView mTextureView;
private TextView mSummary;
private TextView mErrorMessage;
@@ -87,7 +90,6 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getContext();
- mController = new QrCodeScanModeController(mContext);
}
@Override
@@ -215,10 +217,10 @@
break;
case MESSAGE_SCAN_BROADCAST_SUCCESS:
- /* TODO(b/265281156) : Move the logic to BluetoothFindBroadcastsFragment.
- * We only pass the QR code string to the previous page.
- */
- mController.addSource(mSink, mBroadcastMetadata, mIsGroupOp);
+ Log.d(TAG, "scan success");
+ final Intent resultIntent = new Intent();
+ resultIntent.putExtra(KEY_BROADCAST_METADATA, mBroadcastMetadata);
+ getActivity().setResult(Activity.RESULT_OK, resultIntent);
notifyUserForQrCodeRecognition();
break;
default:
diff --git a/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentController.java b/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentController.java
index f5d6bfe..ee0021e 100644
--- a/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentController.java
+++ b/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentController.java
@@ -54,9 +54,9 @@
public CharSequence getSummary() {
if (mNfcAdapter != null) {
if (mNfcAdapter.isEnabled()) {
- return mContext.getText(R.string.on);
+ return mContext.getText(R.string.nfc_setting_on);
} else {
- return mContext.getText(R.string.off);
+ return mContext.getText(R.string.nfc_setting_off);
}
}
return null;
diff --git a/src/com/android/settings/datausage/DataSaverPreference.java b/src/com/android/settings/datausage/DataSaverPreference.java
index fd64506..305d061 100644
--- a/src/com/android/settings/datausage/DataSaverPreference.java
+++ b/src/com/android/settings/datausage/DataSaverPreference.java
@@ -44,7 +44,7 @@
@Override
public void onDataSaverChanged(boolean isDataSaving) {
- setSummary(isDataSaving ? R.string.on : R.string.off);
+ setSummary(isDataSaving ? R.string.data_saver_on : R.string.data_saver_off);
}
@Override
diff --git a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
index d567466..a50ce4c 100644
--- a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
+++ b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
@@ -77,7 +77,7 @@
boolean isLocationEnabled =
timeZoneCapabilitiesAndConfig.getCapabilities().isUseLocationEnabled();
if (isChecked && !isLocationEnabled) {
- new LocationToggleDisabledDialogFragment(mContext)
+ new LocationToggleDisabledDialogFragment()
.show(mFragment.getFragmentManager(), TAG);
// Toggle status is not updated.
return false;
diff --git a/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java b/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java
index 61d46c6..046a659 100644
--- a/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java
+++ b/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java
@@ -19,7 +19,6 @@
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.settings.SettingsEnums;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
@@ -32,11 +31,7 @@
*/
public class LocationToggleDisabledDialogFragment extends InstrumentedDialogFragment {
- private final Context mContext;
-
- public LocationToggleDisabledDialogFragment(Context context) {
- mContext = context;
- }
+ public LocationToggleDisabledDialogFragment() {}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
@@ -48,7 +43,7 @@
R.string.location_time_zone_detection_location_is_off_dialog_ok_button,
(dialog, which) -> {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
- mContext.startActivity(intent);
+ getContext().startActivity(intent);
})
.setNegativeButton(
R.string.location_time_zone_detection_location_is_off_dialog_cancel_button,
diff --git a/src/com/android/settings/development/BluetoothLeAudioPreferenceController.java b/src/com/android/settings/development/BluetoothLeAudioPreferenceController.java
index 00d0dd2..867bc2a 100644
--- a/src/com/android/settings/development/BluetoothLeAudioPreferenceController.java
+++ b/src/com/android/settings/development/BluetoothLeAudioPreferenceController.java
@@ -77,17 +77,19 @@
return;
}
- final boolean leAudioEnabled =
- (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED);
- ((SwitchPreference) mPreference).setChecked(leAudioEnabled);
-
final boolean leAudioSwitchSupported =
SystemProperties.getBoolean(LE_AUDIO_DYNAMIC_SWITCH_PROPERTY, false);
- if (!leAudioSwitchSupported) {
+
+ final int isLeAudioSupportedStatus = mBluetoothAdapter.isLeAudioSupported();
+ final boolean leAudioEnabled =
+ (isLeAudioSupportedStatus == BluetoothStatusCodes.FEATURE_SUPPORTED);
+
+ ((SwitchPreference) mPreference).setChecked(leAudioEnabled);
+
+ // Disable option if Bluetooth is disabled or if switch is not supported
+ if (isLeAudioSupportedStatus == BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED
+ || !leAudioSwitchSupported) {
mPreference.setEnabled(false);
- } else {
- SystemProperties.set(LE_AUDIO_DYNAMIC_ENABLED_PROPERTY,
- Boolean.toString(leAudioEnabled));
}
}
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java
index 4105db1..e82d541 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java
@@ -20,6 +20,7 @@
import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.text.TextUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
@@ -106,6 +107,10 @@
.sorted().toArray();
public void setText(int viewId, CharSequence text) {
+ if (!isAdded()) {
+ Log.d(TAG, "Fragment not attached yet.");
+ return;
+ }
setText(viewId, text, true);
}
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index ffb10fb..d925de3 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -57,7 +57,9 @@
@Override
public CharSequence getSummary() {
- return mContext.getText(isChecked() ? R.string.on : R.string.off);
+ return mContext.getText(isChecked()
+ ? R.string.auto_brightness_summary_on
+ : R.string.auto_brightness_summary_off);
}
@Override
diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
index 73f81eb..3747f06 100644
--- a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
@@ -175,7 +175,7 @@
@Override
public CharSequence getSummary() {
- int activeStringId = R.string.off;
+ int activeStringId = R.string.auto_rotate_option_off;
if (!RotationPolicy.isRotationLocked(mContext)) {
final int cameraRotate = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
@@ -186,7 +186,7 @@
&& !isCameraLocked()
&& !isPowerSaveMode()
? R.string.auto_rotate_option_face_based
- : R.string.on;
+ : R.string.auto_rotate_option_on;
}
return mContext.getString(activeStringId);
}
diff --git a/src/com/android/settings/dream/DreamHomeControlsPreferenceController.java b/src/com/android/settings/dream/DreamHomeControlsPreferenceController.java
new file mode 100644
index 0000000..b39f3b1
--- /dev/null
+++ b/src/com/android/settings/dream/DreamHomeControlsPreferenceController.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 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.dream;
+
+import android.content.Context;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.dream.DreamBackend;
+
+/**
+ * Controller for the {@link androidx.preference.SwitchPreference} which controls if dream
+ * overlays should be enabled.
+ */
+public class DreamHomeControlsPreferenceController extends TogglePreferenceController {
+ private final DreamBackend mBackend;
+
+ public DreamHomeControlsPreferenceController(Context context, String key) {
+ this(context, key, DreamBackend.getInstance(context));
+ }
+
+ @VisibleForTesting
+ public DreamHomeControlsPreferenceController(Context context, String key,
+ DreamBackend dreamBackend) {
+ super(context, key);
+ mBackend = dreamBackend;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ final boolean supported =
+ mBackend.getSupportedComplications()
+ .contains(DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS);
+ return supported ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+ }
+
+ @Override
+ public boolean isChecked() {
+ return mBackend.getEnabledComplications().contains(
+ DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS);
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ mBackend.setHomeControlsEnabled(isChecked);
+ return true;
+ }
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_display;
+ }
+}
diff --git a/src/com/android/settings/dream/DreamSettings.java b/src/com/android/settings/dream/DreamSettings.java
index df50a08..824aa15 100644
--- a/src/com/android/settings/dream/DreamSettings.java
+++ b/src/com/android/settings/dream/DreamSettings.java
@@ -224,6 +224,10 @@
mPreviewButton.setOnClickListener(v -> dreamBackend.preview(dreamBackend.getActiveDream()));
mRecyclerView = super.onCreateRecyclerView(inflater, parent, bundle);
+ // The enable/disable status change of the nested RecyclerView(Dream Picker) causes the
+ // focus moving. Make the RecyclerView unfocusable to prevent the unexpected scrolling when
+ // the focus changes in the TalkBack mode.
+ mRecyclerView.setFocusable(false);
updatePaddingForPreviewButton();
return mRecyclerView;
}
diff --git a/src/com/android/settings/emergency/EmergencyGestureEntrypointPreferenceController.java b/src/com/android/settings/emergency/EmergencyGestureEntrypointPreferenceController.java
index bcf3f21..155efd3 100644
--- a/src/com/android/settings/emergency/EmergencyGestureEntrypointPreferenceController.java
+++ b/src/com/android/settings/emergency/EmergencyGestureEntrypointPreferenceController.java
@@ -95,7 +95,8 @@
public CharSequence getSummary() {
return mContext.getText(
mEmergencyNumberUtils.getEmergencyGestureEnabled()
- ? R.string.on : R.string.off);
+ ? R.string.gesture_setting_on
+ : R.string.gesture_setting_off);
}
/**
diff --git a/src/com/android/settings/fuelgauge/BatterySaverController.java b/src/com/android/settings/fuelgauge/BatterySaverController.java
index 2a39ab3..c712ab0 100644
--- a/src/com/android/settings/fuelgauge/BatterySaverController.java
+++ b/src/com/android/settings/fuelgauge/BatterySaverController.java
@@ -97,7 +97,7 @@
public CharSequence getSummary() {
final boolean isPowerSaveOn = mPowerManager.isPowerSaveMode();
if (isPowerSaveOn) {
- return mContext.getString(R.string.on);
+ return mContext.getString(R.string.battery_saver_on_summary);
}
final ContentResolver resolver = mContext.getContentResolver();
@@ -109,7 +109,7 @@
return percent != 0 ?
mContext.getString(R.string.battery_saver_off_scheduled_summary,
Utils.formatPercentage(percent)) :
- mContext.getString(R.string.off);
+ mContext.getString(R.string.battery_saver_off_summary);
} else {
return mContext.getString(R.string.battery_saver_pref_auto_routine_summary);
}
diff --git a/src/com/android/settings/fuelgauge/InactiveApps.java b/src/com/android/settings/fuelgauge/InactiveApps.java
index 0d87ae7..284e5be 100644
--- a/src/com/android/settings/fuelgauge/InactiveApps.java
+++ b/src/com/android/settings/fuelgauge/InactiveApps.java
@@ -32,7 +32,6 @@
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.os.Bundle;
-import android.provider.Settings;
import android.text.TextUtils;
import androidx.preference.ListPreference;
@@ -51,9 +50,6 @@
private static final CharSequence[] FULL_SETTABLE_BUCKETS_NAMES =
{"ACTIVE", "WORKING_SET", "FREQUENT", "RARE", "RESTRICTED"};
- private static final CharSequence[] REDUCED_SETTABLE_BUCKETS_NAMES =
- Arrays.copyOfRange(FULL_SETTABLE_BUCKETS_NAMES, 0, 4);
-
private static final CharSequence[] FULL_SETTABLE_BUCKETS_VALUES = {
Integer.toString(STANDBY_BUCKET_ACTIVE),
Integer.toString(STANDBY_BUCKET_WORKING_SET),
@@ -62,9 +58,6 @@
Integer.toString(STANDBY_BUCKET_RESTRICTED)
};
- private static final CharSequence[] REDUCED_SETTABLE_BUCKETS_VALUES =
- Arrays.copyOfRange(FULL_SETTABLE_BUCKETS_VALUES, 0, 4);
-
private UsageStatsManager mUsageStats;
@Override
@@ -94,13 +87,8 @@
final Context context = getActivity();
final PackageManager pm = context.getPackageManager();
final String settingsPackage = context.getPackageName();
- final boolean allowRestrictedBucket = Settings.Global.getInt(getContentResolver(),
- Settings.Global.ENABLE_RESTRICTED_BUCKET,
- Settings.Global.DEFAULT_ENABLE_RESTRICTED_BUCKET) == 1;
- final CharSequence[] bucketNames = allowRestrictedBucket
- ? FULL_SETTABLE_BUCKETS_NAMES : REDUCED_SETTABLE_BUCKETS_NAMES;
- final CharSequence[] bucketValues = allowRestrictedBucket
- ? FULL_SETTABLE_BUCKETS_VALUES : REDUCED_SETTABLE_BUCKETS_VALUES;
+ final CharSequence[] bucketNames = FULL_SETTABLE_BUCKETS_NAMES;
+ final CharSequence[] bucketValues = FULL_SETTABLE_BUCKETS_VALUES;
Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index b6858fc..ac72ced 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -26,6 +26,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.settingslib.fuelgauge.Estimate;
+import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -83,7 +84,7 @@
@Override
public List<String> getSystemAppsAllowlist() {
- return null;
+ return new ArrayList<>();
}
@Override
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java
index c5dfb0d..37eddf3 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java
@@ -42,7 +42,8 @@
final Context context,
final @NonNull List<BatteryDiffEntry> appDiffEntries,
final @NonNull List<BatteryDiffEntry> systemDiffEntries,
- final Set<String> systemAppsSet,
+ final @NonNull Set<String> systemAppsPackageNames,
+ final @NonNull Set<Integer> systemAppsUids,
final boolean isAccumulated) {
mAppEntries = appDiffEntries;
mSystemEntries = systemDiffEntries;
@@ -51,7 +52,8 @@
final PowerUsageFeatureProvider featureProvider =
FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context);
purgeBatteryDiffData(featureProvider);
- combineBatteryDiffEntry(context, featureProvider, systemAppsSet);
+ combineBatteryDiffEntry(
+ context, featureProvider, systemAppsPackageNames, systemAppsUids);
}
processAndSortEntries(mAppEntries);
@@ -73,9 +75,13 @@
}
/** Combines into SystemAppsBatteryDiffEntry and OthersBatteryDiffEntry. */
- private void combineBatteryDiffEntry(final Context context,
- final PowerUsageFeatureProvider featureProvider, final Set<String> systemAppsSet) {
- combineIntoSystemApps(context, featureProvider, systemAppsSet, mAppEntries);
+ private void combineBatteryDiffEntry(
+ final Context context,
+ final PowerUsageFeatureProvider featureProvider,
+ final @NonNull Set<String> systemAppsPackageNames,
+ final @NonNull Set<Integer> systemAppsUids) {
+ combineIntoSystemApps(
+ context, featureProvider, systemAppsPackageNames, systemAppsUids, mAppEntries);
combineSystemItemsIntoOthers(context, featureProvider, mSystemEntries);
}
@@ -113,14 +119,16 @@
private static void combineIntoSystemApps(
final Context context,
final PowerUsageFeatureProvider featureProvider,
- final Set<String> systemAppsSet,
- final List<BatteryDiffEntry> appEntries) {
+ final @NonNull Set<String> systemAppsPackageNames,
+ final @NonNull Set<Integer> systemAppsUids,
+ final @NonNull List<BatteryDiffEntry> appEntries) {
final List<String> systemAppsAllowlist = featureProvider.getSystemAppsAllowlist();
BatteryDiffEntry.SystemAppsBatteryDiffEntry systemAppsDiffEntry = null;
final Iterator<BatteryDiffEntry> appListIterator = appEntries.iterator();
while (appListIterator.hasNext()) {
final BatteryDiffEntry batteryDiffEntry = appListIterator.next();
- if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist, systemAppsSet)) {
+ if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist,
+ systemAppsPackageNames, systemAppsUids)) {
if (systemAppsDiffEntry == null) {
systemAppsDiffEntry = new BatteryDiffEntry.SystemAppsBatteryDiffEntry(context);
}
@@ -168,8 +176,11 @@
}
@VisibleForTesting
- static boolean needsCombineInSystemApp(final BatteryDiffEntry batteryDiffEntry,
- final List<String> systemAppsAllowlist, final Set<String> systemAppsSet) {
+ static boolean needsCombineInSystemApp(
+ final BatteryDiffEntry batteryDiffEntry,
+ final @NonNull List<String> systemAppsAllowlist,
+ final @NonNull Set<String> systemAppsPackageNames,
+ final @NonNull Set<Integer> systemAppsUids) {
if (batteryDiffEntry.mBatteryHistEntry.mIsHidden) {
return true;
}
@@ -179,11 +190,12 @@
return false;
}
- if (systemAppsAllowlist != null && systemAppsAllowlist.contains(packageName)) {
+ if (systemAppsAllowlist.contains(packageName)) {
return true;
}
- return systemAppsSet != null && systemAppsSet.contains(packageName);
+ int uid = (int) batteryDiffEntry.mBatteryHistEntry.mUid;
+ return systemAppsPackageNames.contains(packageName) || systemAppsUids.contains(uid);
}
/**
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java
index 4506922..1f25ae0 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java
@@ -33,6 +33,7 @@
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -77,10 +78,8 @@
private List<BatteryLevelData.PeriodBatteryLevelData> mHourlyBatteryLevelsPerDay;
private Map<Long, Map<String, BatteryHistEntry>> mBatteryHistoryMap;
- // The start timestamp of battery level data. As we don't know when is the full charge cycle
- // start time when loading app usage data, this value is used as the start time of querying app
- // usage data.
- private long mStartTimestampOfLevelData;
+ // Raw start timestamp with round to the nearest hour.
+ private long mRawStartTimestamp;
private boolean mIsCurrentBatteryHistoryLoaded = false;
private boolean mIsCurrentAppUsageLoaded = false;
@@ -105,6 +104,7 @@
DataProcessManager(
Context context,
Handler handler,
+ final long rawStartTimestamp,
@NonNull final DataProcessor.UsageMapAsyncResponse callbackFunction,
@NonNull final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay,
@NonNull final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
@@ -114,7 +114,7 @@
mCallbackFunction = callbackFunction;
mHourlyBatteryLevelsPerDay = hourlyBatteryLevelsPerDay;
mBatteryHistoryMap = batteryHistoryMap;
- mStartTimestampOfLevelData = getStartTimestampOfBatteryLevelData();
+ mRawStartTimestamp = rawStartTimestamp;
}
/**
@@ -154,21 +154,6 @@
}
@VisibleForTesting
- long getStartTimestampOfBatteryLevelData() {
- for (int dailyIndex = 0; dailyIndex < mHourlyBatteryLevelsPerDay.size(); dailyIndex++) {
- if (mHourlyBatteryLevelsPerDay.get(dailyIndex) == null) {
- continue;
- }
- final List<Long> timestamps =
- mHourlyBatteryLevelsPerDay.get(dailyIndex).getTimestamps();
- if (timestamps.size() > 0) {
- return timestamps.get(0);
- }
- }
- return 0;
- }
-
- @VisibleForTesting
List<AppUsageEvent> getAppUsageEventList() {
return mAppUsageEventList;
}
@@ -251,7 +236,7 @@
final int workProfileUserId = getWorkProfileUserId();
final UsageEvents usageEventsForCurrentUser =
DataProcessor.getAppUsageEventsForUser(
- mContext, currentUserId, mStartTimestampOfLevelData);
+ mContext, currentUserId, mRawStartTimestamp);
// If fail to load usage events for current user, return null directly and screen-on
// time will not be shown in the UI.
if (usageEventsForCurrentUser == null) {
@@ -262,7 +247,7 @@
if (workProfileUserId != Integer.MIN_VALUE) {
usageEventsForWorkProfile =
DataProcessor.getAppUsageEventsForUser(
- mContext, workProfileUserId, mStartTimestampOfLevelData);
+ mContext, workProfileUserId, mRawStartTimestamp);
} else {
Log.d(TAG, "there is no work profile");
}
@@ -309,7 +294,7 @@
final List<AppUsageEvent> appUsageEventList =
DatabaseUtils.getAppUsageEventForUsers(
mContext, Calendar.getInstance(), getCurrentUserIds(),
- mStartTimestampOfLevelData);
+ mRawStartTimestamp);
Log.d(TAG, String.format("execute loadDatabaseAppUsageList size=%d in %d/ms",
appUsageEventList.size(), (System.currentTimeMillis() - startTime)));
return appUsageEventList;
@@ -376,7 +361,7 @@
// Generates the indexed AppUsagePeriod list data for each corresponding time slot for
// further use.
mAppUsagePeriodMap = DataProcessor.generateAppUsagePeriodMap(
- mHourlyBatteryLevelsPerDay, mAppUsageEventList);
+ mRawStartTimestamp, mHourlyBatteryLevelsPerDay, mAppUsageEventList);
}
private void tryToGenerateFinalDataAndApplyCallback() {
@@ -489,10 +474,12 @@
return null;
}
+ final long rawStartTimestamp = Collections.min(batteryHistoryMap.keySet());
// Start the async task to compute diff usage data and load labels and icons.
new DataProcessManager(
context,
handler,
+ rawStartTimestamp,
asyncResponseDelegate,
batteryLevelData.getHourlyBatteryLevelsPerDay(),
processedBatteryHistoryMap).start();
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
index 2a926d0..338cb11 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
@@ -61,7 +61,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -84,7 +83,8 @@
private static final float TOTAL_HOURLY_TIME_THRESHOLD = DateUtils.HOUR_IN_MILLIS * 2;
private static final long MIN_TIME_SLOT = DateUtils.HOUR_IN_MILLIS * 2;
private static final String MEDIASERVER_PACKAGE_NAME = "mediaserver";
- private static final Map<String, BatteryHistEntry> EMPTY_BATTERY_MAP = new HashMap<>();
+ private static final String ANDROID_CORE_APPS_SHARED_USER_ID = "android.uid.shared";
+ private static final Map<String, BatteryHistEntry> EMPTY_BATTERY_MAP = new ArrayMap<>();
private static final BatteryHistEntry EMPTY_BATTERY_HIST_ENTRY =
new BatteryHistEntry(new ContentValues());
@@ -102,7 +102,7 @@
static long sTestCurrentTimeMillis = 0;
@VisibleForTesting
- static Set<String> sTestSystemAppsSet;
+ static Set<String> sTestSystemAppsPackageNames;
@VisibleForTesting
static IUsageStatsManager sUsageStatsManager =
@@ -185,7 +185,7 @@
if (context == null) {
return null;
}
- final Map<Long, UsageEvents> resultMap = new HashMap();
+ final Map<Long, UsageEvents> resultMap = new ArrayMap();
final UserManager userManager = context.getSystemService(UserManager.class);
if (userManager == null) {
return null;
@@ -265,8 +265,9 @@
@Nullable
public static Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>>
generateAppUsagePeriodMap(
- final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay,
- final List<AppUsageEvent> appUsageEventList) {
+ final long rawStartTimestamp,
+ final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay,
+ final List<AppUsageEvent> appUsageEventList) {
if (appUsageEventList.isEmpty()) {
Log.w(TAG, "appUsageEventList is empty");
return null;
@@ -275,12 +276,12 @@
// distribution.
Collections.sort(appUsageEventList, TIMESTAMP_COMPARATOR);
final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>> resultMap =
- new HashMap<>();
+ new ArrayMap<>();
final long dailySize = hourlyBatteryLevelsPerDay.size();
for (int dailyIndex = 0; dailyIndex < hourlyBatteryLevelsPerDay.size(); dailyIndex++) {
final Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>> dailyMap =
- new HashMap<>();
+ new ArrayMap<>();
resultMap.put(dailyIndex, dailyMap);
if (hourlyBatteryLevelsPerDay.get(dailyIndex) == null) {
continue;
@@ -288,8 +289,12 @@
final List<Long> timestamps = hourlyBatteryLevelsPerDay.get(dailyIndex).getTimestamps();
final long hourlySize = timestamps.size() - 1;
for (int hourlyIndex = 0; hourlyIndex < timestamps.size() - 1; hourlyIndex++) {
- // The start and end timestamps of this slot should be the adjacent timestamps.
- final long startTimestamp = timestamps.get(hourlyIndex);
+ // The start slot timestape is the near hour timestamp instead of the last full
+ // charge time. So use rawStartTimestamp instead of reading the timestamp from
+ // hourlyBatteryLevelsPerDay here.
+ final long startTimestamp =
+ dailyIndex == 0 && hourlyIndex == 0 && !sDebug
+ ? rawStartTimestamp : timestamps.get(hourlyIndex);
// The final slot is to show the data from last even hour until now but the
// timestamp in hourlyBatteryLevelsPerDay is not the real value. So use current
// timestamp instead of reading the timestamp from hourlyBatteryLevelsPerDay here.
@@ -386,7 +391,7 @@
if (appUsagePeriodMap == null) {
return null;
}
- final Map<Integer, Map<Integer, Long>> deviceScreenOnTime = new HashMap<>();
+ final Map<Integer, Map<Integer, Long>> deviceScreenOnTime = new ArrayMap<>();
insertHourlyDeviceScreenOnTime(appUsagePeriodMap, deviceScreenOnTime);
insertDailyDeviceScreenOnTime(appUsagePeriodMap, deviceScreenOnTime);
insertAllDeviceScreenOnTime(deviceScreenOnTime);
@@ -428,7 +433,7 @@
final Context context) {
final List<BatteryHistEntry> batteryHistEntryList =
getBatteryHistListFromFromStatsService(context);
- return batteryHistEntryList == null ? new HashMap<>()
+ return batteryHistEntryList == null ? new ArrayMap<>()
: batteryHistEntryList.stream().collect(Collectors.toMap(e -> e.getKey(), e -> e));
}
@@ -436,14 +441,14 @@
* @return Returns the processed history map which has interpolated to every hour data.
* The start and end timestamp must be the even hours.
* The keys of processed history map should contain every hour between the start and end
- * timestamp. If there's no data in some key, the value will be the empty hashmap.
+ * timestamp. If there's no data in some key, the value will be the empty map.
*/
static Map<Long, Map<String, BatteryHistEntry>> getHistoryMapWithExpectedTimestamps(
Context context,
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
final long startTime = System.currentTimeMillis();
final List<Long> rawTimestampList = new ArrayList<>(batteryHistoryMap.keySet());
- final Map<Long, Map<String, BatteryHistEntry>> resultMap = new HashMap();
+ final Map<Long, Map<String, BatteryHistEntry>> resultMap = new ArrayMap();
if (rawTimestampList.isEmpty()) {
Log.d(TAG, "empty batteryHistoryMap in getHistoryMapWithExpectedTimestamps()");
return resultMap;
@@ -636,11 +641,12 @@
if (batteryHistoryMap.isEmpty()) {
return null;
}
- final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new HashMap<>();
- final Set<String> systemAppsSet = getSystemAppsSet(context);
+ final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new ArrayMap<>();
+ final Set<String> systemAppsPackageNames = getSystemAppsPackageNames(context);
+ final Set<Integer> systemAppsUids = getSystemAppsUids(context);
// Insert diff data from [0][0] to [maxDailyIndex][maxHourlyIndex].
- insertHourlyUsageDiffData(context, systemAppsSet, hourlyBatteryLevelsPerDay,
- batteryHistoryMap, appUsagePeriodMap, resultMap);
+ insertHourlyUsageDiffData(context, systemAppsPackageNames, systemAppsUids,
+ hourlyBatteryLevelsPerDay, batteryHistoryMap, appUsagePeriodMap, resultMap);
// Insert diff data from [0][SELECTED_INDEX_ALL] to [maxDailyIndex][SELECTED_INDEX_ALL].
insertDailyUsageDiffData(context, hourlyBatteryLevelsPerDay, resultMap);
// Insert diff data [SELECTED_INDEX_ALL][SELECTED_INDEX_ALL].
@@ -699,9 +705,10 @@
return null;
}
- final Set<String> systemAppsSet = getSystemAppsSet(context);
- return new BatteryDiffData(
- context, appEntries, systemEntries, systemAppsSet, /* isAccumulated= */ false);
+ final Set<String> systemAppsPackageNames = getSystemAppsPackageNames(context);
+ final Set<Integer> systemAppsUids = getSystemAppsUids(context);
+ return new BatteryDiffData(context, appEntries, systemEntries,
+ systemAppsPackageNames, systemAppsUids, /* isAccumulated= */ false);
}
/**
@@ -738,7 +745,7 @@
return null;
}
- final Map<Long, Map<String, List<AppUsagePeriod>>> allUsagePeriods = new HashMap<>();
+ final Map<Long, Map<String, List<AppUsagePeriod>>> allUsagePeriods = new ArrayMap<>();
for (int i = 0; i < usageEventsByInstanceId.size(); i++) {
// The usage periods for an instance are determined by the usage events with its
@@ -850,8 +857,8 @@
*/
static Map<Integer, Map<Integer, BatteryDiffData>> getBatteryUsageMapFromStatsService(
final Context context) {
- final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new HashMap<>();
- final Map<Integer, BatteryDiffData> allUsageMap = new HashMap<>();
+ final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new ArrayMap<>();
+ final Map<Integer, BatteryDiffData> allUsageMap = new ArrayMap<>();
// Always construct the map whether the value is null or not.
allUsageMap.put(SELECTED_INDEX_ALL,
generateBatteryDiffData(context, getBatteryHistListFromFromStatsService(context)));
@@ -932,7 +939,7 @@
final List<AppUsagePeriod> usagePeriodList,
final long userId,
final String packageName) {
- usagePeriodMap.computeIfAbsent(userId, key -> new HashMap<>());
+ usagePeriodMap.computeIfAbsent(userId, key -> new ArrayMap<>());
final Map<String, List<AppUsagePeriod>> packageNameMap = usagePeriodMap.get(userId);
packageNameMap.computeIfAbsent(packageName, key -> new ArrayList<>());
packageNameMap.get(packageName).addAll(usagePeriodList);
@@ -963,7 +970,7 @@
for (final int dailyIndex : appUsagePeriodMap.keySet()) {
final Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>> dailyAppUsageMap =
appUsagePeriodMap.get(dailyIndex);
- final Map<Integer, Long> dailyScreenOnTime = new HashMap<>();
+ final Map<Integer, Long> dailyScreenOnTime = new ArrayMap<>();
resultMap.put(dailyIndex, dailyScreenOnTime);
if (dailyAppUsageMap == null) {
continue;
@@ -1004,7 +1011,7 @@
for (final int dailyIndex : appUsagePeriodMap.keySet()) {
Map<Integer, Long> dailyResultMap = resultMap.get(dailyIndex);
if (dailyResultMap == null) {
- dailyResultMap = new HashMap<>();
+ dailyResultMap = new ArrayMap<>();
resultMap.put(dailyIndex, dailyResultMap);
}
dailyResultMap.put(
@@ -1015,10 +1022,10 @@
private static void insertAllDeviceScreenOnTime(
final Map<Integer, Map<Integer, Long>> resultMap) {
- final Map<Integer, Long> dailyAllMap = new HashMap<>();
+ final Map<Integer, Long> dailyAllMap = new ArrayMap<>();
resultMap.keySet().forEach(
key -> dailyAllMap.put(key, resultMap.get(key).get(SELECTED_INDEX_ALL)));
- final Map<Integer, Long> allUsageMap = new HashMap<>();
+ final Map<Integer, Long> allUsageMap = new ArrayMap<>();
allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedScreenOnTime(dailyAllMap));
resultMap.put(SELECTED_INDEX_ALL, allUsageMap);
}
@@ -1168,7 +1175,7 @@
// Case 1: upper timestamp is zero since scheduler is delayed!
if (upperTimestamp == 0) {
log(context, "job scheduler is delayed", currentSlot, null);
- resultMap.put(currentSlot, new HashMap<>());
+ resultMap.put(currentSlot, new ArrayMap<>());
return;
}
// Case 2: upper timestamp is closed to the current timestamp.
@@ -1181,7 +1188,7 @@
// Case 3: lower timestamp is zero before starting to collect data.
if (lowerTimestamp == 0) {
log(context, "no lower timestamp slot data", currentSlot, null);
- resultMap.put(currentSlot, new HashMap<>());
+ resultMap.put(currentSlot, new ArrayMap<>());
return;
}
interpolateHistoryForSlot(context,
@@ -1217,12 +1224,12 @@
resultMap.put(currentSlot, upperEntryDataMap);
} else {
log(context, "in the different booting section", currentSlot, null);
- resultMap.put(currentSlot, new HashMap<>());
+ resultMap.put(currentSlot, new ArrayMap<>());
}
return;
}
log(context, "apply interpolation arithmetic", currentSlot, null);
- final Map<String, BatteryHistEntry> newHistEntryMap = new HashMap<>();
+ final Map<String, BatteryHistEntry> newHistEntryMap = new ArrayMap<>();
final double timestampLength = upperTimestamp - lowerTimestamp;
final double timestampDiff = currentSlot - lowerTimestamp;
// Applies interpolation arithmetic for each BatteryHistEntry.
@@ -1369,7 +1376,8 @@
private static void insertHourlyUsageDiffData(
Context context,
- final Set<String> systemAppsSet,
+ final Set<String> systemAppsPackageNames,
+ final Set<Integer> systemAppsUids,
final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay,
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap,
final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>>
@@ -1385,7 +1393,7 @@
// Math.abs(timestamp[i+1] data - timestamp[i] data);
// since we want to aggregate every two hours data into a single time slot.
for (int dailyIndex = 0; dailyIndex < hourlyBatteryLevelsPerDay.size(); dailyIndex++) {
- final Map<Integer, BatteryDiffData> dailyDiffMap = new HashMap<>();
+ final Map<Integer, BatteryDiffData> dailyDiffMap = new ArrayMap<>();
resultMap.put(dailyIndex, dailyDiffMap);
if (hourlyBatteryLevelsPerDay.get(dailyIndex) == null) {
continue;
@@ -1399,7 +1407,8 @@
workProfileUserId,
hourlyIndex,
timestamps,
- systemAppsSet,
+ systemAppsPackageNames,
+ systemAppsUids,
appUsagePeriodMap == null
|| appUsagePeriodMap.get(dailyIndex) == null
? null
@@ -1417,7 +1426,7 @@
for (int index = 0; index < hourlyBatteryLevelsPerDay.size(); index++) {
Map<Integer, BatteryDiffData> dailyUsageMap = resultMap.get(index);
if (dailyUsageMap == null) {
- dailyUsageMap = new HashMap<>();
+ dailyUsageMap = new ArrayMap<>();
resultMap.put(index, dailyUsageMap);
}
dailyUsageMap.put(
@@ -1432,7 +1441,7 @@
final List<BatteryDiffData> diffDataList = new ArrayList<>();
resultMap.keySet().forEach(
key -> diffDataList.add(resultMap.get(key).get(SELECTED_INDEX_ALL)));
- final Map<Integer, BatteryDiffData> allUsageMap = new HashMap<>();
+ final Map<Integer, BatteryDiffData> allUsageMap = new ArrayMap<>();
allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedUsageDiffData(context, diffDataList));
resultMap.put(SELECTED_INDEX_ALL, allUsageMap);
}
@@ -1444,7 +1453,8 @@
final int workProfileUserId,
final int currentIndex,
final List<Long> timestamps,
- final Set<String> systemAppsSet,
+ final Set<String> systemAppsPackageNames,
+ final Set<Integer> systemAppsUids,
final Map<Long, Map<String, List<AppUsagePeriod>>> appUsageMap,
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
final List<BatteryDiffEntry> appEntries = new ArrayList<>();
@@ -1598,8 +1608,8 @@
return null;
}
- return new BatteryDiffData(
- context, appEntries, systemEntries, systemAppsSet, /* isAccumulated= */ false);
+ return new BatteryDiffData(context, appEntries, systemEntries,
+ systemAppsPackageNames, systemAppsUids, /* isAccumulated= */ false);
}
private static long getScreenOnTime(@Nullable final List<AppUsagePeriod> appUsagePeriodList) {
@@ -1657,7 +1667,7 @@
@Nullable
private static BatteryDiffData getAccumulatedUsageDiffData(
final Context context, final Collection<BatteryDiffData> diffEntryListData) {
- final Map<String, BatteryDiffEntry> diffEntryMap = new HashMap<>();
+ final Map<String, BatteryDiffEntry> diffEntryMap = new ArrayMap<>();
final List<BatteryDiffEntry> appEntries = new ArrayList<>();
final List<BatteryDiffEntry> systemEntries = new ArrayList<>();
@@ -1683,7 +1693,8 @@
}
return diffEntryList.isEmpty() ? null : new BatteryDiffData(context, appEntries,
- systemEntries, /* systemAppsSet= */ null, /* isAccumulated= */ true);
+ systemEntries, /* systemAppsPackageNames= */ new ArraySet<>(),
+ /* systemAppsUids= */ new ArraySet<>(), /* isAccumulated= */ true);
}
private static void computeUsageDiffDataPerEntry(
@@ -1899,11 +1910,22 @@
return null;
}
- private static Set<String> getSystemAppsSet(Context context) {
- return sTestSystemAppsSet != null ? sTestSystemAppsSet
+ private static Set<String> getSystemAppsPackageNames(Context context) {
+ return sTestSystemAppsPackageNames != null ? sTestSystemAppsPackageNames
: AppListRepositoryUtil.getSystemPackageNames(context, context.getUserId(), false);
}
+ private static Set<Integer> getSystemAppsUids(Context context) {
+ Set<Integer> result = new ArraySet<>();
+ try {
+ result.add(context.getPackageManager().getUidForSharedUser(
+ ANDROID_CORE_APPS_SHARED_USER_ID));
+ } catch (PackageManager.NameNotFoundException e) {
+ // No Android Core Apps
+ }
+ return result;
+ }
+
private static long getCurrentTimeMillis() {
return sTestCurrentTimeMillis > 0 ? sTestCurrentTimeMillis : System.currentTimeMillis();
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
index 2b330cc..655114f 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
@@ -139,13 +139,13 @@
Context context,
final Calendar calendar,
final List<Integer> userIds,
- final long startTimestampOfLevelData) {
+ final long rawStartTimestamp) {
final long startTime = System.currentTimeMillis();
final long sixDaysAgoTimestamp = getTimestampSixDaysAgo(calendar);
// Query a longer time period and then trim to the original time period in order to make
// sure the app usage calculation near the boundaries is correct.
final long queryTimestamp =
- Math.max(startTimestampOfLevelData, sixDaysAgoTimestamp) - USAGE_QUERY_BUFFER_HOURS;
+ Math.max(rawStartTimestamp, sixDaysAgoTimestamp) - USAGE_QUERY_BUFFER_HOURS;
Log.d(TAG, "sixDayAgoTimestamp: " + sixDaysAgoTimestamp);
final String queryUserIdString = userIds.stream()
.map(userId -> String.valueOf(userId))
diff --git a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
index 2b32eec..49a9de6 100644
--- a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
+++ b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
@@ -128,7 +128,8 @@
if (!mAssistOnly) {
isEnabled = isEnabled || isSilenceGestureEnabled();
}
- return mContext.getText(isEnabled ? R.string.on : R.string.off);
+ return mContext.getText(
+ isEnabled ? R.string.gesture_setting_on : R.string.gesture_setting_off);
}
@Override
diff --git a/src/com/android/settings/gestures/GesturePreferenceController.java b/src/com/android/settings/gestures/GesturePreferenceController.java
index 9e8181c..71c3c9a 100644
--- a/src/com/android/settings/gestures/GesturePreferenceController.java
+++ b/src/com/android/settings/gestures/GesturePreferenceController.java
@@ -60,7 +60,8 @@
@Override
public CharSequence getSummary() {
- return mContext.getText(isChecked() ? R.string.on : R.string.off);
+ return mContext.getText(
+ isChecked() ? R.string.gesture_setting_on : R.string.gesture_setting_off);
}
@Override
diff --git a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
index a3bc052..6aac772 100644
--- a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
+++ b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
@@ -51,7 +51,7 @@
public CharSequence getSummary() {
return mContext.getText(
OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)
- ? R.string.on : R.string.off);
+ ? R.string.gesture_setting_on : R.string.gesture_setting_off);
}
@Override
diff --git a/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java b/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java
index 50b6cb0..03b0259 100644
--- a/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java
+++ b/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java
@@ -104,7 +104,7 @@
break;
// VOLUME_HUSH_OFF
default:
- summary = mContext.getText(R.string.off);
+ summary = mContext.getText(R.string.switch_off_text);
}
preference.setEnabled(true);
mPreference.setSwitchEnabled(true);
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
index 2db3382..0f49ee1 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
@@ -37,10 +37,10 @@
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.inputmethod.NewKeyboardSettingsUtils.KeyboardInfo;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
-import java.util.Locale;
-import java.util.Map;
public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
implements InputManager.InputDeviceListener {
@@ -53,7 +53,7 @@
private int mUserId;
private int mInputDeviceId;
private Context mContext;
- private Map<String, KeyboardInfo> mKeyboardLanguageLayouts = new HashMap<>();
+ private ArrayList<KeyboardInfo> mKeyboardInfoList = new ArrayList<>();
@Override
public void onActivityCreated(final Bundle icicle) {
@@ -74,8 +74,16 @@
PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceScreen.removeAll();
List<InputMethodInfo> infoList = mImm.getEnabledInputMethodListAsUser(mUserId);
+ Collections.sort(infoList, new Comparator<InputMethodInfo>() {
+ public int compare(InputMethodInfo o1, InputMethodInfo o2) {
+ String s1 = o1.loadLabel(mContext.getPackageManager()).toString();
+ String s2 = o2.loadLabel(mContext.getPackageManager()).toString();
+ return s1.compareTo(s2);
+ }
+ });
+
for (InputMethodInfo info : infoList) {
- mKeyboardLanguageLayouts.clear();
+ mKeyboardInfoList.clear();
List<InputMethodSubtype> subtypes =
mImm.getEnabledInputMethodSubtypeList(info, true);
for (InputMethodSubtype subtype : subtypes) {
@@ -88,51 +96,58 @@
}
private void mapLanguageWithLayout(InputMethodInfo info, InputMethodSubtype subtype) {
+ CharSequence subtypeLabel = getSubtypeLabel(mContext, info, subtype);
KeyboardLayout[] keyboardLayouts = getKeyboardLayouts(info, subtype);
String layout = getKeyboardLayout(info, subtype);
- String language = getLanguage(info, subtype);
+
if (layout != null) {
for (int i = 0; i < keyboardLayouts.length; i++) {
if (keyboardLayouts[i].getDescriptor().equals(layout)) {
KeyboardInfo keyboardInfo = new KeyboardInfo(
- language,
+ subtypeLabel,
keyboardLayouts[i].getLabel(),
info,
subtype);
- mKeyboardLanguageLayouts.put(subtype.getLanguageTag(), keyboardInfo);
+ mKeyboardInfoList.add(keyboardInfo);
break;
}
}
} else {
// if there is no auto-selected layout, we should show "Default"
KeyboardInfo keyboardInfo = new KeyboardInfo(
- language,
+ subtypeLabel,
mContext.getString(R.string.keyboard_default_layout),
info,
subtype);
- mKeyboardLanguageLayouts.put(subtype.getLanguageTag(), keyboardInfo);
+ mKeyboardInfoList.add(keyboardInfo);
}
}
private void updatePreferenceLayout(PreferenceScreen preferenceScreen, InputMethodInfo info) {
- if (mKeyboardLanguageLayouts.isEmpty()) {
+ if (mKeyboardInfoList.isEmpty()) {
return;
}
PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
- preferenceCategory.setTitle(info.loadLabel(mContext.getPackageManager()).toString());
+ preferenceCategory.setTitle(info.loadLabel(mContext.getPackageManager()));
preferenceCategory.setKey(info.getPackageName());
preferenceScreen.addPreference(preferenceCategory);
- for (Map.Entry<String, KeyboardInfo> entry : mKeyboardLanguageLayouts.entrySet()) {
+ Collections.sort(mKeyboardInfoList, new Comparator<KeyboardInfo>() {
+ public int compare(KeyboardInfo o1, KeyboardInfo o2) {
+ String s1 = o1.getSubtypeLabel().toString();
+ String s2 = o2.getSubtypeLabel().toString();
+ return s1.compareTo(s2);
+ }
+ });
+
+ for (KeyboardInfo keyboardInfo : mKeyboardInfoList) {
final Preference pref = new Preference(mContext);
- String key = "keyboard_language_" + entry.getKey();
- NewKeyboardSettingsUtils.KeyboardInfo keyboardInfo = entry.getValue();
- pref.setKey(key);
- pref.setTitle(keyboardInfo.getLanguage());
+ pref.setKey(keyboardInfo.getPrefId());
+ pref.setTitle(keyboardInfo.getSubtypeLabel());
pref.setSummary(keyboardInfo.getLayout());
pref.setOnPreferenceClickListener(
preference -> {
showKeyboardLayoutPicker(
- keyboardInfo.getLanguage(),
+ keyboardInfo.getSubtypeLabel(),
keyboardInfo.getLayout(),
mInputDeviceIdentifier,
mUserId,
@@ -215,7 +230,7 @@
}
private void showKeyboardLayoutPicker(
- String language,
+ CharSequence subtypeLabel,
String layout,
InputDeviceIdentifier inputDeviceIdentifier,
int userId,
@@ -229,7 +244,7 @@
arguments.putParcelable(
NewKeyboardSettingsUtils.EXTRA_INPUT_METHOD_SUBTYPE, inputMethodSubtype);
arguments.putInt(NewKeyboardSettingsUtils.EXTRA_USER_ID, userId);
- arguments.putString(NewKeyboardSettingsUtils.EXTRA_TITLE, language);
+ arguments.putCharSequence(NewKeyboardSettingsUtils.EXTRA_TITLE, subtypeLabel);
arguments.putString(NewKeyboardSettingsUtils.EXTRA_KEYBOARD_LAYOUT, layout);
new SubSettingLauncher(mContext)
.setSourceMetricsCategory(getMetricsCategory())
@@ -248,16 +263,9 @@
mInputDeviceIdentifier, mUserId, info, subtype);
}
- private String getLanguage(InputMethodInfo info, InputMethodSubtype subtype) {
- String language;
- if (subtype.getLanguageTag().isEmpty()) {
- language = subtype.getDisplayName(
- mContext,
- info.getPackageName(),
- info.getServiceInfo().applicationInfo).toString();
- } else {
- language = Locale.forLanguageTag(subtype.getLanguageTag()).getDisplayName();
- }
- return language;
+ private CharSequence getSubtypeLabel(
+ Context context, InputMethodInfo info, InputMethodSubtype subtype) {
+ return subtype.getDisplayName(
+ context, info.getPackageName(), info.getServiceInfo().applicationInfo);
}
}
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
index 605095f..761e95e 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
@@ -36,7 +36,7 @@
super.onAttach(context);
InputManager inputManager = getContext().getSystemService(InputManager.class);
Bundle arguments = getArguments();
- final String title = arguments.getString(NewKeyboardSettingsUtils.EXTRA_TITLE);
+ final CharSequence title = arguments.getCharSequence(NewKeyboardSettingsUtils.EXTRA_TITLE);
final String layout = arguments.getString(NewKeyboardSettingsUtils.EXTRA_KEYBOARD_LAYOUT);
final int userId = arguments.getInt(NewKeyboardSettingsUtils.EXTRA_USER_ID);
final InputDeviceIdentifier identifier =
diff --git a/src/com/android/settings/inputmethod/NewKeyboardSettingsUtils.java b/src/com/android/settings/inputmethod/NewKeyboardSettingsUtils.java
index dda5500..506d1e7 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardSettingsUtils.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardSettingsUtils.java
@@ -72,24 +72,28 @@
}
static class KeyboardInfo {
- String mLanguage;
+ CharSequence mSubtypeLabel;
String mLayout;
InputMethodInfo mInputMethodInfo;
InputMethodSubtype mInputMethodSubtype;
KeyboardInfo(
- String language,
+ CharSequence subtypeLabel,
String layout,
InputMethodInfo inputMethodInfo,
InputMethodSubtype inputMethodSubtype) {
- mLanguage = language;
+ mSubtypeLabel = subtypeLabel;
mLayout = layout;
mInputMethodInfo = inputMethodInfo;
mInputMethodSubtype = inputMethodSubtype;
}
- String getLanguage() {
- return mLanguage;
+ String getPrefId() {
+ return mInputMethodInfo.getId() + "_" + mInputMethodSubtype.hashCode();
+ }
+
+ CharSequence getSubtypeLabel() {
+ return mSubtypeLabel;
}
String getLayout() {
diff --git a/src/com/android/settings/inputmethod/SpellCheckerPreferenceController.java b/src/com/android/settings/inputmethod/SpellCheckerPreferenceController.java
index 68e46e9..f0bb8d9 100644
--- a/src/com/android/settings/inputmethod/SpellCheckerPreferenceController.java
+++ b/src/com/android/settings/inputmethod/SpellCheckerPreferenceController.java
@@ -66,7 +66,7 @@
return;
}
if (!mTextServicesManager.isSpellCheckerEnabled()) {
- preference.setSummary(R.string.off);
+ preference.setSummary(R.string.switch_off_text);
} else {
final SpellCheckerInfo sci = mTextServicesManager.getCurrentSpellChecker();
if (sci != null) {
diff --git a/src/com/android/settings/language/LanguagePreferenceController.java b/src/com/android/settings/language/LanguagePreferenceController.java
index 08033cd..cbccb00 100644
--- a/src/com/android/settings/language/LanguagePreferenceController.java
+++ b/src/com/android/settings/language/LanguagePreferenceController.java
@@ -16,12 +16,22 @@
package com.android.settings.language;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.util.FeatureFlagUtils;
+import com.android.settings.Settings;
import com.android.settings.core.BasePreferenceController;
+/**
+ * This is a display controller for new language activity entry.
+ * TODO(b/273642892): When new layout is on board, this class shall be removed.
+ */
public class LanguagePreferenceController extends BasePreferenceController {
+ private static final String TAG = LanguagePreferenceController.class.getSimpleName();
+
+ private boolean mCacheIsFeatureOn = false;
public LanguagePreferenceController(Context context, String key) {
super(context, key);
@@ -31,6 +41,27 @@
public int getAvailabilityStatus() {
boolean isFeatureOn = FeatureFlagUtils
.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+
+ // LanguageSettingsActivity is a new entry page for new language layout.
+ // LanguageAndInputSettingsActivity is existed entry page for current language layout.
+ if (mCacheIsFeatureOn != isFeatureOn) {
+ setActivityEnabled(
+ mContext, Settings.LanguageAndInputSettingsActivity.class, !isFeatureOn);
+ setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, isFeatureOn);
+ mCacheIsFeatureOn = isFeatureOn;
+ }
return isFeatureOn ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
+
+ private static void setActivityEnabled(Context context, Class klass, final boolean isEnabled) {
+ PackageManager packageManager = context.getPackageManager();
+
+ ComponentName componentName =
+ new ComponentName(context, klass);
+ final int flag = isEnabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+
+ packageManager.setComponentEnabledSetting(
+ componentName, flag, PackageManager.DONT_KILL_APP);
+ }
}
\ No newline at end of file
diff --git a/src/com/android/settings/location/LocationForWorkPreferenceController.java b/src/com/android/settings/location/LocationForWorkPreferenceController.java
index 3341b8f..dc4d1d9 100644
--- a/src/com/android/settings/location/LocationForWorkPreferenceController.java
+++ b/src/com/android/settings/location/LocationForWorkPreferenceController.java
@@ -44,7 +44,8 @@
final boolean switchState = mPreference.isChecked();
mUserManager.setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, !switchState,
Utils.getManagedProfile(mUserManager));
- mPreference.setSummary(switchState ? R.string.on : R.string.off);
+ mPreference.setSummary(switchState
+ ? R.string.switch_on_text : R.string.switch_off_text);
return true;
}
return false;
@@ -80,11 +81,11 @@
mLocationEnabler.isManagedProfileRestrictedByBase();
if (isRestrictedByBase || !enabled) {
mPreference.setChecked(false);
- summaryResId = enabled ? R.string.off
+ summaryResId = enabled ? R.string.switch_off_text
: R.string.location_app_permission_summary_location_off;
} else {
mPreference.setChecked(true);
- summaryResId = R.string.on;
+ summaryResId = R.string.switch_on_text;
}
mPreference.setSummary(summaryResId);
}
diff --git a/src/com/android/settings/location/LocationServicesBluetoothScanningPreferenceController.java b/src/com/android/settings/location/LocationServicesBluetoothScanningPreferenceController.java
index cc2b704..ccda572 100644
--- a/src/com/android/settings/location/LocationServicesBluetoothScanningPreferenceController.java
+++ b/src/com/android/settings/location/LocationServicesBluetoothScanningPreferenceController.java
@@ -46,7 +46,8 @@
public CharSequence getSummary() {
final boolean bleScanOn = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1;
- final int resId = bleScanOn ? R.string.on : R.string.off;
+ int resId =
+ bleScanOn ? R.string.scanning_status_text_on : R.string.scanning_status_text_off;
return mContext.getString(resId);
}
diff --git a/src/com/android/settings/location/LocationServicesWifiScanningPreferenceController.java b/src/com/android/settings/location/LocationServicesWifiScanningPreferenceController.java
index 1e8412e..2814f9d 100644
--- a/src/com/android/settings/location/LocationServicesWifiScanningPreferenceController.java
+++ b/src/com/android/settings/location/LocationServicesWifiScanningPreferenceController.java
@@ -47,7 +47,8 @@
@Override
public CharSequence getSummary() {
final boolean wifiScanOn = mWifiManager.isScanAlwaysAvailable();
- final int resId = wifiScanOn ? R.string.on : R.string.off;
+ int resId =
+ wifiScanOn ? R.string.scanning_status_text_on : R.string.scanning_status_text_off;
return mContext.getString(resId);
}
diff --git a/src/com/android/settings/location/TopLevelLocationPreferenceController.java b/src/com/android/settings/location/TopLevelLocationPreferenceController.java
index 464344e..5c1043a 100644
--- a/src/com/android/settings/location/TopLevelLocationPreferenceController.java
+++ b/src/com/android/settings/location/TopLevelLocationPreferenceController.java
@@ -58,7 +58,7 @@
}
return sSummary;
} else {
- return mContext.getString(R.string.off);
+ return mContext.getString(R.string.location_settings_summary_location_off);
}
}
diff --git a/src/com/android/settings/network/AdaptiveConnectivityPreferenceController.java b/src/com/android/settings/network/AdaptiveConnectivityPreferenceController.java
index 0b7acc7..a938515 100644
--- a/src/com/android/settings/network/AdaptiveConnectivityPreferenceController.java
+++ b/src/com/android/settings/network/AdaptiveConnectivityPreferenceController.java
@@ -48,7 +48,7 @@
public CharSequence getSummary() {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED, 1) == 1
- ? mContext.getString(R.string.on)
- : mContext.getString(R.string.off);
+ ? mContext.getString(R.string.adaptive_connectivity_switch_on)
+ : mContext.getString(R.string.adaptive_connectivity_switch_off);
}
}
diff --git a/src/com/android/settings/network/InternetPreferenceController.java b/src/com/android/settings/network/InternetPreferenceController.java
index ad1a5f0..898585c 100644
--- a/src/com/android/settings/network/InternetPreferenceController.java
+++ b/src/com/android/settings/network/InternetPreferenceController.java
@@ -101,7 +101,7 @@
mInternetUpdater = new InternetUpdater(context, lifecycle, this);
mInternetType = mInternetUpdater.getInternetType();
mLifecycleOwner = lifecycleOwner;
- mMobileNetworkRepository = MobileNetworkRepository.create(context, this);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
lifecycle.addObserver(this);
}
@@ -156,14 +156,16 @@
/** @OnLifecycleEvent(ON_RESUME) */
@OnLifecycleEvent(ON_RESUME)
public void onResume() {
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, this,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ mMobileNetworkRepository.updateEntity();
mSummaryHelper.register(true);
}
/** @OnLifecycleEvent(ON_PAUSE) */
@OnLifecycleEvent(ON_PAUSE)
public void onPause() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
mSummaryHelper.register(false);
}
diff --git a/src/com/android/settings/network/MobileNetworkRepository.java b/src/com/android/settings/network/MobileNetworkRepository.java
index e483a4d..1e57c48 100644
--- a/src/com/android/settings/network/MobileNetworkRepository.java
+++ b/src/com/android/settings/network/MobileNetworkRepository.java
@@ -20,6 +20,7 @@
import static com.android.internal.telephony.TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED;
+import android.annotation.NonNull;
import android.app.settings.SettingsEnums;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -56,10 +57,12 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
+import androidx.annotation.GuardedBy;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
@@ -72,14 +75,17 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static ExecutorService sExecutor = Executors.newSingleThreadExecutor();
- private static Map<String, SubscriptionInfoEntity> sCacheSubscriptionInfoEntityMap =
+ private static Map<Integer, SubscriptionInfoEntity> sCacheSubscriptionInfoEntityMap =
new ArrayMap<>();
- private static Map<String, MobileNetworkInfoEntity> sCacheMobileNetworkInfoEntityMap =
+ private static Map<Integer, MobileNetworkInfoEntity> sCacheMobileNetworkInfoEntityMap =
new ArrayMap<>();
- private static Map<String, UiccInfoEntity> sCacheUiccInfoEntityMap = new ArrayMap<>();
+ private static Map<Integer, UiccInfoEntity> sCacheUiccInfoEntityMap = new ArrayMap<>();
+ private static Collection<MobileNetworkCallback> sCallbacks = new CopyOnWriteArrayList<>();
+ private static final Object sInstanceLock = new Object();
+ @GuardedBy("sInstanceLock")
+ private static MobileNetworkRepository sInstance;
private SubscriptionManager mSubscriptionManager;
- private TelephonyManager mTelephonyManager;
private MobileNetworkDatabase mMobileNetworkDatabase;
private SubscriptionInfoDao mSubscriptionInfoDao;
private UiccInfoDao mUiccInfoDao;
@@ -88,7 +94,6 @@
private List<SubscriptionInfoEntity> mActiveSubInfoEntityList = new ArrayList<>();
private List<UiccInfoEntity> mUiccInfoEntityList = new ArrayList<>();
private List<MobileNetworkInfoEntity> mMobileNetworkInfoEntityList = new ArrayList<>();
- private MobileNetworkCallback mCallback;
private Context mContext;
private AirplaneModeObserver mAirplaneModeObserver;
private Uri mAirplaneModeSettingUri;
@@ -100,35 +105,34 @@
private int mCardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
private int mPortIndex = TelephonyManager.INVALID_PORT_INDEX;
private int mCardId = TelephonyManager.UNINITIALIZED_CARD_ID;
- private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private boolean mIsEuicc = false;
private boolean mIsRemovable = false;
private boolean mIsActive = false;
private Map<Integer, SubscriptionInfo> mSubscriptionInfoMap = new ArrayMap<>();
private Map<Integer, TelephonyManager> mTelephonyManagerMap = new HashMap<>();
private Map<Integer, PhoneCallStateTelephonyCallback> mTelephonyCallbackMap = new HashMap<>();
+ private BroadcastReceiver mDataSubscriptionChangedReceiver = null;
- public static MobileNetworkRepository create(Context context,
- MobileNetworkCallback mobileNetworkCallback) {
- return new MobileNetworkRepository(context, mobileNetworkCallback,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ @NonNull
+ public static MobileNetworkRepository getInstance(Context context) {
+ synchronized (sInstanceLock) {
+ if (sInstance != null) {
+ return sInstance;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Init the instance.");
+ }
+ sInstance = new MobileNetworkRepository(context);
+ return sInstance;
+ }
}
- public static MobileNetworkRepository createBySubId(Context context,
- MobileNetworkCallback mobileNetworkCallback, int subId) {
- return new MobileNetworkRepository(context, mobileNetworkCallback, subId);
- }
-
- private MobileNetworkRepository(Context context, MobileNetworkCallback mobileNetworkCallback,
- int subId) {
- mSubId = subId;
+ private MobileNetworkRepository(Context context) {
mContext = context;
mMobileNetworkDatabase = MobileNetworkDatabase.getInstance(context);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
- mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_CREATED,
- subId);
+ mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_CREATED);
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
- mCallback = mobileNetworkCallback;
mSubscriptionInfoDao = mMobileNetworkDatabase.mSubscriptionInfoDao();
mUiccInfoDao = mMobileNetworkDatabase.mUiccInfoDao();
mMobileNetworkInfoDao = mMobileNetworkDatabase.mMobileNetworkInfoDao();
@@ -138,6 +142,8 @@
mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
mFilter.addAction(ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
+ mDataSubscriptionChangedReceiver = new DataSubscriptionChangedReceiver();
+ mContext.registerReceiver(mDataSubscriptionChangedReceiver, mFilter);
}
private class AirplaneModeObserver extends ContentObserver {
@@ -157,56 +163,98 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
if (uri.equals(mAirplaneModeSettingUri)) {
- mCallback.onAirplaneModeChanged(isAirplaneModeOn());
+ boolean isAirplaneModeOn = isAirplaneModeOn();
+ for (MobileNetworkCallback callback : sCallbacks) {
+ callback.onAirplaneModeChanged(isAirplaneModeOn);
+ }
}
}
}
- private final BroadcastReceiver mDataSubscriptionChangedReceiver = new BroadcastReceiver() {
+ private class DataSubscriptionChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
onSubscriptionsChanged();
}
- };
+ }
- public void addRegister(LifecycleOwner lifecycleOwner) {
+ /**
+ * Register all callbacks and listener.
+ *
+ * @param lifecycleOwner The lifecycle owner.
+ * @param mobileNetworkCallback A callback to receive all MobileNetwork's changes.
+ * @param subId The subscription ID to register relevant changes and listener for specific
+ * subscription.
+ */
+ public void addRegister(LifecycleOwner lifecycleOwner,
+ MobileNetworkCallback mobileNetworkCallback, int subId) {
+ sCallbacks.add(mobileNetworkCallback);
mSubscriptionManager.addOnSubscriptionsChangedListener(mContext.getMainExecutor(), this);
mAirplaneModeObserver.register(mContext);
- mContext.registerReceiver(mDataSubscriptionChangedReceiver, mFilter);
observeAllSubInfo(lifecycleOwner);
observeAllUiccInfo(lifecycleOwner);
observeAllMobileNetworkInfo(lifecycleOwner);
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ addRegisterBySubId(subId);
+ createTelephonyManagerBySubId(subId);
+ }
}
private void addRegisterBySubId(int subId) {
- if (!mTelephonyCallbackMap.containsKey(subId)) {
- PhoneCallStateTelephonyCallback
- telephonyCallback = new PhoneCallStateTelephonyCallback();
- mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(),
- telephonyCallback);
- mTelephonyCallbackMap.put(subId, telephonyCallback);
- mTelephonyManagerMap.put(subId, mTelephonyManager);
- }
- if (!mDataContentObserverMap.containsKey(subId)) {
- MobileDataContentObserver dataContentObserver = new MobileDataContentObserver(
- new Handler(Looper.getMainLooper()));
- dataContentObserver.register(mContext, subId);
- dataContentObserver.setOnMobileDataChangedListener(() -> {
- sExecutor.execute(() -> {
- insertMobileNetworkInfo(mContext, String.valueOf(subId));
- });
+ MobileDataContentObserver dataContentObserver = new MobileDataContentObserver(
+ new Handler(Looper.getMainLooper()));
+ dataContentObserver.setOnMobileDataChangedListener(() -> {
+ sExecutor.execute(() -> {
+ insertMobileNetworkInfo(mContext, subId,
+ getTelephonyManagerBySubId(mContext, subId));
});
- mDataContentObserverMap.put(subId, dataContentObserver);
+ });
+ dataContentObserver.register(mContext, subId);
+ mDataContentObserverMap.put(subId, dataContentObserver);
+ }
+
+ private void createTelephonyManagerBySubId(int subId) {
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ return;
}
+ PhoneCallStateTelephonyCallback
+ telephonyCallback = new PhoneCallStateTelephonyCallback();
+ TelephonyManager telephonyManager = mContext.getSystemService(
+ TelephonyManager.class).createForSubscriptionId(subId);
+ telephonyManager.registerTelephonyCallback(mContext.getMainExecutor(),
+ telephonyCallback);
+ mTelephonyCallbackMap.put(subId, telephonyCallback);
+ mTelephonyManagerMap.put(subId, telephonyManager);
+ }
+
+ private TelephonyManager getTelephonyManagerBySubId(Context context, int subId) {
+ TelephonyManager telephonyManager = mTelephonyManagerMap.get(subId);
+ if (telephonyManager != null) {
+ return telephonyManager;
+ }
+
+ if (context != null) {
+ telephonyManager = context.getSystemService(TelephonyManager.class);
+ if (telephonyManager != null) {
+ telephonyManager = telephonyManager.createForSubscriptionId(subId);
+ } else if (DEBUG) {
+ Log.d(TAG, "Can not get TelephonyManager for subId " + subId);
+ }
+ }
+
+ return telephonyManager;
+
}
private void removerRegisterBySubId(int subId) {
if (mTelephonyCallbackMap.containsKey(subId)) {
- TelephonyManager tm = mTelephonyManagerMap.get(subId);
- PhoneCallStateTelephonyCallback callback = mTelephonyCallbackMap.get(subId);
- if (callback != null) {
- tm.unregisterTelephonyCallback(callback);
- mTelephonyCallbackMap.remove(subId);
+ TelephonyManager telephonyManager = getTelephonyManagerBySubId(mContext, subId);
+ if (telephonyManager != null) {
+ PhoneCallStateTelephonyCallback callback = mTelephonyCallbackMap.get(subId);
+ if (callback != null) {
+ telephonyManager.unregisterTelephonyCallback(callback);
+ mTelephonyCallbackMap.remove(subId);
+ }
}
}
if (mDataContentObserverMap.containsKey(subId)) {
@@ -215,25 +263,43 @@
}
}
- public void removeRegister() {
- mSubscriptionManager.removeOnSubscriptionsChangedListener(this);
- mAirplaneModeObserver.unRegister(mContext);
- if (mDataSubscriptionChangedReceiver != null) {
- mContext.unregisterReceiver(mDataSubscriptionChangedReceiver);
- }
- mDataContentObserverMap.forEach((id, observer) -> {
- observer.unRegister(mContext);
- });
- mDataContentObserverMap.clear();
-
- mTelephonyManagerMap.forEach((id, manager) -> {
- TelephonyCallback callback = mTelephonyCallbackMap.get(manager.getSubscriptionId());
- if (callback != null) {
- manager.unregisterTelephonyCallback(callback);
+ public void removeRegister(MobileNetworkCallback mobileNetworkCallback) {
+ sCallbacks.remove(mobileNetworkCallback);
+ if (sCallbacks.isEmpty()) {
+ mSubscriptionManager.removeOnSubscriptionsChangedListener(this);
+ mAirplaneModeObserver.unRegister(mContext);
+ if (mDataSubscriptionChangedReceiver != null) {
+ mContext.unregisterReceiver(mDataSubscriptionChangedReceiver);
+ mDataSubscriptionChangedReceiver = null;
}
- });
- mTelephonyCallbackMap.clear();
- mTelephonyManagerMap.clear();
+ mDataContentObserverMap.forEach((id, observer) -> {
+ observer.unRegister(mContext);
+ });
+ mDataContentObserverMap.clear();
+
+ mTelephonyManagerMap.forEach((id, manager) -> {
+ TelephonyCallback callback = mTelephonyCallbackMap.get(id);
+ if (callback != null) {
+ manager.unregisterTelephonyCallback(callback);
+ }
+ });
+ mTelephonyCallbackMap.clear();
+ mTelephonyManagerMap.clear();
+ }
+ }
+
+ public void updateEntity() {
+ // Check the latest state after back to the UI.
+ if (sCacheSubscriptionInfoEntityMap != null || !sCacheSubscriptionInfoEntityMap.isEmpty()) {
+ sExecutor.execute(() -> {
+ onSubscriptionsChanged();
+ });
+ }
+
+ boolean isAirplaneModeOn = isAirplaneModeOn();
+ for (MobileNetworkCallback callback : sCallbacks) {
+ callback.onAirplaneModeChanged(isAirplaneModeOn);
+ }
}
private void observeAllSubInfo(LifecycleOwner lifecycleOwner) {
@@ -284,18 +350,6 @@
return mMobileNetworkInfoDao.queryMobileNetworkInfoBySubId(subId);
}
- public int getSubInfosCount() {
- return mSubscriptionInfoDao.count();
- }
-
- public int getUiccInfosCount() {
- return mUiccInfoDao.count();
- }
-
- public int getMobileNetworkInfosCount() {
- return mMobileNetworkInfoDao.count();
- }
-
private void getUiccInfoBySubscriptionInfo(UiccSlotInfo[] uiccSlotInfos,
SubscriptionInfo subInfo) {
for (int i = 0; i < uiccSlotInfos.length; i++) {
@@ -317,7 +371,7 @@
mPortIndex = portInfo.getPortIndex();
} else if (DEBUG) {
Log.d(TAG, "Can not get port index and physicalSlotIndex for subId "
- + mSubId);
+ + subInfo.getSubscriptionId());
}
});
if (mPhysicalSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
@@ -334,70 +388,82 @@
private void onAvailableSubInfoChanged(
List<SubscriptionInfoEntity> availableSubInfoEntityList) {
- mAvailableSubInfoEntityList = availableSubInfoEntityList;
- mActiveSubInfoEntityList = mAvailableSubInfoEntityList.stream()
- .filter(SubscriptionInfoEntity::isActiveSubscription)
- .filter(SubscriptionInfoEntity::isSubscriptionVisible)
- .collect(Collectors.toList());
+ mAvailableSubInfoEntityList = new ArrayList<>(availableSubInfoEntityList);
if (DEBUG) {
Log.d(TAG, "onAvailableSubInfoChanged, availableSubInfoEntityList = "
+ availableSubInfoEntityList);
}
- mCallback.onAvailableSubInfoChanged(availableSubInfoEntityList);
+ for (MobileNetworkCallback callback : sCallbacks) {
+ callback.onAvailableSubInfoChanged(availableSubInfoEntityList);
+ }
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_SUB_INFO_IS_CHANGED, 0);
- setActiveSubInfoList(mActiveSubInfoEntityList);
+ onActiveSubInfoListChanged(mAvailableSubInfoEntityList);
}
- private void setActiveSubInfoList(List<SubscriptionInfoEntity> activeSubInfoEntityList) {
+ private void onActiveSubInfoListChanged(
+ List<SubscriptionInfoEntity> availableSubInfoEntityList) {
+ mActiveSubInfoEntityList = availableSubInfoEntityList.stream()
+ .filter(SubscriptionInfoEntity::isActiveSubscription)
+ .filter(SubscriptionInfoEntity::isSubscriptionVisible)
+ .collect(Collectors.toList());
if (DEBUG) {
- Log.d(TAG,
- "onActiveSubInfoChanged, activeSubInfoEntityList = " + activeSubInfoEntityList);
+ Log.d(TAG, "onActiveSubInfoChanged, activeSubInfoEntityList = "
+ + mActiveSubInfoEntityList);
}
- mCallback.onActiveSubInfoChanged(mActiveSubInfoEntityList);
+ List<SubscriptionInfoEntity> activeSubInfoEntityList = new ArrayList<>(
+ mActiveSubInfoEntityList);
+ for (MobileNetworkCallback callback : sCallbacks) {
+ callback.onActiveSubInfoChanged(activeSubInfoEntityList);
+ }
}
private void onAllUiccInfoChanged(List<UiccInfoEntity> uiccInfoEntityList) {
- mUiccInfoEntityList = uiccInfoEntityList;
- mCallback.onAllUiccInfoChanged(uiccInfoEntityList);
+ mUiccInfoEntityList = new ArrayList<>(uiccInfoEntityList);
+ for (MobileNetworkCallback callback : sCallbacks) {
+ callback.onAllUiccInfoChanged(uiccInfoEntityList);
+ }
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_UICC_INFO_IS_CHANGED, 0);
}
private void onAllMobileNetworkInfoChanged(
List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) {
- mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList;
- mCallback.onAllMobileNetworkInfoChanged(mobileNetworkInfoEntityList);
+ mMobileNetworkInfoEntityList = new ArrayList<>(mobileNetworkInfoEntityList);
+ for (MobileNetworkCallback callback : sCallbacks) {
+ callback.onAllMobileNetworkInfoChanged(mobileNetworkInfoEntityList);
+ }
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_MOBILE_NETWORK_INFO_IS_CHANGED, 0);
}
- public void insertSubInfo(Context context, SubscriptionInfo info) {
+ private void insertSubInfo(Context context, SubscriptionInfo info) {
+ int subId = info.getSubscriptionId();
+ createTelephonyManagerBySubId(subId);
+ TelephonyManager telephonyManager = getTelephonyManagerBySubId(context, subId);
SubscriptionInfoEntity subInfoEntity =
- convertToSubscriptionInfoEntity(context, info);
- String subId = String.valueOf(mSubId);
+ convertToSubscriptionInfoEntity(context, info, telephonyManager);
if (subInfoEntity != null) {
if (!sCacheSubscriptionInfoEntityMap.containsKey(subId)
|| (sCacheSubscriptionInfoEntityMap.get(subId) != null
&& !sCacheSubscriptionInfoEntityMap.get(subId).equals(subInfoEntity))) {
sCacheSubscriptionInfoEntityMap.put(subId, subInfoEntity);
if (DEBUG) {
- Log.d(TAG, "convert subId " + subId + "to SubscriptionInfoEntity: "
+ Log.d(TAG, "Convert subId " + subId + " to SubscriptionInfoEntity: "
+ subInfoEntity);
}
mMobileNetworkDatabase.insertSubsInfo(subInfoEntity);
- addRegisterBySubId(mSubId);
- insertUiccInfo(subId);
- insertMobileNetworkInfo(context, subId);
mMetricsFeatureProvider.action(mContext,
- SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_SUB_INFO, mSubId);
- } else if (DEBUG) {
- Log.d(TAG, "Can not insert subInfo, the entity is null");
+ SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_SUB_INFO, subId);
+ insertUiccInfo(subId, telephonyManager);
+ insertMobileNetworkInfo(context, subId, telephonyManager);
}
+ } else if (DEBUG) {
+ Log.d(TAG, "Can not insert subInfo, the entity is null");
}
}
- public void deleteAllInfoBySubId(String subId) {
+ private void deleteAllInfoBySubId(String subId) {
if (DEBUG) {
Log.d(TAG, "deleteAllInfoBySubId, subId = " + subId);
}
@@ -412,20 +478,23 @@
removerRegisterBySubId(id);
mSubscriptionInfoMap.remove(id);
mTelephonyManagerMap.remove(id);
- sCacheSubscriptionInfoEntityMap.remove(subId);
- sCacheUiccInfoEntityMap.remove(subId);
- sCacheMobileNetworkInfoEntityMap.remove(subId);
+ sCacheSubscriptionInfoEntityMap.remove(id);
+ sCacheUiccInfoEntityMap.remove(id);
+ sCacheMobileNetworkInfoEntityMap.remove(id);
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_DELETE_DATA, id);
}
- public SubscriptionInfoEntity convertToSubscriptionInfoEntity(Context context,
- SubscriptionInfo subInfo) {
- mSubId = subInfo.getSubscriptionId();
- mTelephonyManager = context.getSystemService(
- TelephonyManager.class).createForSubscriptionId(mSubId);
-
- UiccSlotInfo[] uiccSlotInfos = mTelephonyManager.getUiccSlotsInfo();
+ private SubscriptionInfoEntity convertToSubscriptionInfoEntity(Context context,
+ SubscriptionInfo subInfo, TelephonyManager telephonyManager) {
+ int subId = subInfo.getSubscriptionId();
+ if (telephonyManager == null) {
+ if (DEBUG) {
+ Log.d(TAG, "Can not get TelephonyManager for subId " + subId);
+ }
+ return null;
+ }
+ UiccSlotInfo[] uiccSlotInfos = telephonyManager.getUiccSlotsInfo();
if (uiccSlotInfos == null || uiccSlotInfos.length == 0) {
if (DEBUG) {
Log.d(TAG, "uiccSlotInfos = null or empty");
@@ -435,12 +504,10 @@
getUiccInfoBySubscriptionInfo(uiccSlotInfos, subInfo);
SubscriptionInfo firstRemovableSubInfo = SubscriptionUtil.getFirstRemovableSubscription(
context);
- SubscriptionInfo subscriptionOrDefault = SubscriptionUtil.getSubscriptionOrDefault(
- context, mSubId);
- if(DEBUG){
- Log.d(TAG, "convert subscriptionInfo to entity for subId = " + mSubId);
+ if (DEBUG) {
+ Log.d(TAG, "convert subscriptionInfo to entity for subId = " + subId);
}
- return new SubscriptionInfoEntity(String.valueOf(mSubId),
+ return new SubscriptionInfoEntity(String.valueOf(subId),
subInfo.getSimSlotIndex(),
subInfo.getCarrierId(), subInfo.getDisplayName().toString(),
subInfo.getCarrierName() != null ? subInfo.getCarrierName().toString() : "",
@@ -453,24 +520,23 @@
SubscriptionUtil.isSubscriptionVisible(mSubscriptionManager, context, subInfo),
SubscriptionUtil.getFormattedPhoneNumber(context, subInfo),
firstRemovableSubInfo == null ? false
- : firstRemovableSubInfo.getSubscriptionId() == mSubId,
- String.valueOf(SubscriptionUtil.getDefaultSimConfig(context, mSubId)),
- subscriptionOrDefault == null ? false
- : subscriptionOrDefault.getSubscriptionId() == mSubId,
- mSubscriptionManager.isValidSubscriptionId(mSubId),
- mSubscriptionManager.isUsableSubscriptionId(mSubId),
- mSubscriptionManager.isActiveSubscriptionId(mSubId),
+ : firstRemovableSubInfo.getSubscriptionId() == subId,
+ String.valueOf(SubscriptionUtil.getDefaultSimConfig(context, subId)),
+ SubscriptionUtil.isDefaultSubscription(context, subId),
+ mSubscriptionManager.isValidSubscriptionId(subId),
+ mSubscriptionManager.isUsableSubscriptionId(subId),
+ mSubscriptionManager.isActiveSubscriptionId(subId),
true /*availableSubInfo*/,
- mSubscriptionManager.getDefaultVoiceSubscriptionId() == mSubId,
- mSubscriptionManager.getDefaultSmsSubscriptionId() == mSubId,
- mSubscriptionManager.getDefaultDataSubscriptionId() == mSubId,
- mSubscriptionManager.getDefaultSubscriptionId() == mSubId,
- mSubscriptionManager.getActiveDataSubscriptionId() == mSubId);
+ mSubscriptionManager.getDefaultVoiceSubscriptionId() == subId,
+ mSubscriptionManager.getDefaultSmsSubscriptionId() == subId,
+ mSubscriptionManager.getDefaultDataSubscriptionId() == subId,
+ mSubscriptionManager.getDefaultSubscriptionId() == subId,
+ mSubscriptionManager.getActiveDataSubscriptionId() == subId);
}
}
- public void insertUiccInfo(String subId) {
- UiccInfoEntity uiccInfoEntity = convertToUiccInfoEntity();
+ private void insertUiccInfo(int subId, TelephonyManager telephonyManager) {
+ UiccInfoEntity uiccInfoEntity = convertToUiccInfoEntity(subId, telephonyManager);
if (DEBUG) {
Log.d(TAG, "uiccInfoEntity = " + uiccInfoEntity);
}
@@ -479,51 +545,76 @@
sCacheUiccInfoEntityMap.put(subId, uiccInfoEntity);
mMobileNetworkDatabase.insertUiccInfo(uiccInfoEntity);
mMetricsFeatureProvider.action(mContext,
- SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_UICC_INFO,
- Integer.parseInt(subId));
+ SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_UICC_INFO, subId);
}
}
- public void insertMobileNetworkInfo(Context context, String subId) {
- MobileNetworkInfoEntity mobileNetworkInfoEntity = convertToMobileNetworkInfoEntity(context);
+ private void insertMobileNetworkInfo(Context context, int subId,
+ TelephonyManager telephonyManager) {
+ MobileNetworkInfoEntity mobileNetworkInfoEntity = convertToMobileNetworkInfoEntity(context,
+ subId, telephonyManager);
+
if (DEBUG) {
- Log.d(TAG, "mobileNetworkInfoEntity = " + mobileNetworkInfoEntity);
+ Log.d(TAG, "insertMobileNetworkInfo, mobileNetworkInfoEntity = "
+ + mobileNetworkInfoEntity);
}
+
+ if (mobileNetworkInfoEntity == null) {
+ return;
+ }
+
if (!sCacheMobileNetworkInfoEntityMap.containsKey(subId)
|| !sCacheMobileNetworkInfoEntityMap.get(subId).equals(mobileNetworkInfoEntity)) {
sCacheMobileNetworkInfoEntityMap.put(subId, mobileNetworkInfoEntity);
mMobileNetworkDatabase.insertMobileNetworkInfo(mobileNetworkInfoEntity);
mMetricsFeatureProvider.action(mContext,
- SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_MOBILE_NETWORK_INFO,
- Integer.parseInt(subId));
+ SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_MOBILE_NETWORK_INFO, subId);
}
}
- public MobileNetworkInfoEntity convertToMobileNetworkInfoEntity(Context context) {
- return new MobileNetworkInfoEntity(String.valueOf(mSubId),
- MobileNetworkUtils.isContactDiscoveryEnabled(context, mSubId),
- MobileNetworkUtils.isContactDiscoveryVisible(context, mSubId),
- mTelephonyManager.isDataEnabled(),
- MobileNetworkUtils.isCdmaOptions(context, mSubId),
- MobileNetworkUtils.isGsmOptions(context, mSubId),
- MobileNetworkUtils.isWorldMode(context, mSubId),
- MobileNetworkUtils.shouldDisplayNetworkSelectOptions(context, mSubId),
- MobileNetworkUtils.isTdscdmaSupported(context, mSubId),
+ private MobileNetworkInfoEntity convertToMobileNetworkInfoEntity(Context context, int subId,
+ TelephonyManager telephonyManager) {
+ boolean isDataEnabled = false;
+ boolean isDataRoamingEnabled = false;
+ if (telephonyManager != null) {
+ isDataEnabled = telephonyManager.isDataEnabled();
+ isDataRoamingEnabled = telephonyManager.isDataRoamingEnabled();
+ } else if (DEBUG) {
+ Log.d(TAG, "TelephonyManager is null, subId = " + subId);
+ }
+
+ return new MobileNetworkInfoEntity(String.valueOf(subId),
+ MobileNetworkUtils.isContactDiscoveryEnabled(context, subId),
+ MobileNetworkUtils.isContactDiscoveryVisible(context, subId),
+ isDataEnabled,
+ MobileNetworkUtils.isCdmaOptions(context, subId),
+ MobileNetworkUtils.isGsmOptions(context, subId),
+ MobileNetworkUtils.isWorldMode(context, subId),
+ MobileNetworkUtils.shouldDisplayNetworkSelectOptions(context, subId),
+ MobileNetworkUtils.isTdscdmaSupported(context, subId),
MobileNetworkUtils.activeNetworkIsCellular(context),
SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager),
- mTelephonyManager.isDataRoamingEnabled()
+ isDataRoamingEnabled
);
}
- private UiccInfoEntity convertToUiccInfoEntity() {
- return new UiccInfoEntity(String.valueOf(mSubId), String.valueOf(mPhysicalSlotIndex),
- mLogicalSlotIndex, mCardId, mIsEuicc, isMultipleEnabledProfilesSupported(),
- mCardState, mIsRemovable, mIsActive, mPortIndex
+ private UiccInfoEntity convertToUiccInfoEntity(int subId, TelephonyManager telephonyManager) {
+ return new UiccInfoEntity(String.valueOf(subId), String.valueOf(mPhysicalSlotIndex),
+ mLogicalSlotIndex, mCardId, mIsEuicc,
+ isMultipleEnabledProfilesSupported(telephonyManager), mCardState, mIsRemovable,
+ mIsActive, mPortIndex
);
}
- private boolean isMultipleEnabledProfilesSupported() {
- List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
+ private boolean isMultipleEnabledProfilesSupported(TelephonyManager telephonyManager) {
+ if (telephonyManager == null) {
+ if (DEBUG) {
+ Log.d(TAG, "TelephonyManager is null");
+ }
+ return false;
+ }
+
+ List<UiccCardInfo> cardInfos = telephonyManager.getUiccCardsInfo();
if (cardInfos == null) {
if (DEBUG) {
Log.d(TAG, "UICC card info list is empty.");
@@ -540,11 +631,11 @@
SubscriptionUtil.getSelectableSubscriptionInfoList(mContext));
}
- private void insertAvailableSubInfoToEntity(List<SubscriptionInfo> availableInfoList) {
+ private void insertAvailableSubInfoToEntity(List<SubscriptionInfo> inputAvailableInfoList) {
sExecutor.execute(() -> {
SubscriptionInfoEntity[] availableInfoArray = mAvailableSubInfoEntityList.toArray(
new SubscriptionInfoEntity[0]);
- if ((availableInfoList == null || availableInfoList.size() == 0)
+ if ((inputAvailableInfoList == null || inputAvailableInfoList.size() == 0)
&& mAvailableSubInfoEntityList.size() != 0) {
if (DEBUG) {
Log.d(TAG, "availableSudInfoList from framework is empty, remove all subs");
@@ -554,11 +645,12 @@
deleteAllInfoBySubId(info.subId);
}
- } else if (availableInfoList != null) {
- SubscriptionInfo[] infoArray = availableInfoList.toArray(new SubscriptionInfo[0]);
+ } else if (inputAvailableInfoList != null) {
+ SubscriptionInfo[] inputAvailableInfoArray = inputAvailableInfoList.toArray(
+ new SubscriptionInfo[0]);
// Remove the redundant subInfo
- if (availableInfoList.size() <= mAvailableSubInfoEntityList.size()) {
- for (SubscriptionInfo subInfo : infoArray) {
+ if (inputAvailableInfoList.size() <= mAvailableSubInfoEntityList.size()) {
+ for (SubscriptionInfo subInfo : inputAvailableInfoArray) {
int subId = subInfo.getSubscriptionId();
if (mSubscriptionInfoMap.containsKey(subId)) {
mSubscriptionInfoMap.remove(subId);
@@ -571,11 +663,20 @@
deleteAllInfoBySubId(String.valueOf(key));
}
}
+ } else if (inputAvailableInfoList.size() < mAvailableSubInfoEntityList.size()) {
+ // Check the subInfo between the new list from framework and old list in
+ // the database, if the subInfo is not existed in the new list, delete it
+ // from the database.
+ for (SubscriptionInfoEntity info : availableInfoArray) {
+ if (sCacheSubscriptionInfoEntityMap.containsKey(info.getSubId())) {
+ deleteAllInfoBySubId(info.subId);
+ }
+ }
}
}
// Insert all new available subInfo to database.
- for (SubscriptionInfo subInfo : infoArray) {
+ for (SubscriptionInfo subInfo : inputAvailableInfoArray) {
if (DEBUG) {
Log.d(TAG, "insert subInfo to subInfoEntity, subInfo = " + subInfo);
}
@@ -586,7 +687,7 @@
}
continue;
}
- mSubscriptionInfoMap.put(mSubId, subInfo);
+ mSubscriptionInfoMap.put(subInfo.getSubscriptionId(), subInfo);
insertSubInfo(mContext, subInfo);
}
}
@@ -603,7 +704,9 @@
@Override
public void onCallStateChanged(int state) {
- mCallback.onCallStateChanged(state);
+ for (MobileNetworkCallback callback : sCallbacks) {
+ callback.onCallStateChanged(state);
+ }
}
}
diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.java b/src/com/android/settings/network/MobileNetworkSummaryController.java
index 449323d..99a2731 100644
--- a/src/com/android/settings/network/MobileNetworkSummaryController.java
+++ b/src/com/android/settings/network/MobileNetworkSummaryController.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.os.UserManager;
+import android.telephony.SubscriptionManager;
import android.telephony.euicc.EuiccManager;
import android.util.Log;
@@ -87,7 +88,7 @@
mMetricsFeatureProvider = FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();
mUserManager = context.getSystemService(UserManager.class);
mLifecycleOwner = lifecycleOwner;
- mMobileNetworkRepository = MobileNetworkRepository.create(context, this);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
mIsAirplaneModeOn = mMobileNetworkRepository.isAirplaneModeOn();
if (lifecycle != null) {
lifecycle.addObserver(this);
@@ -96,13 +97,14 @@
@OnLifecycleEvent(ON_RESUME)
public void onResume() {
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
- update();
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, this,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ mMobileNetworkRepository.updateEntity();
}
@OnLifecycleEvent(ON_PAUSE)
public void onPause() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
}
@Override
diff --git a/src/com/android/settings/network/NetworkProviderCallsSmsController.java b/src/com/android/settings/network/NetworkProviderCallsSmsController.java
index 4ad0470..0c71aa7 100644
--- a/src/com/android/settings/network/NetworkProviderCallsSmsController.java
+++ b/src/com/android/settings/network/NetworkProviderCallsSmsController.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.os.UserManager;
import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
@@ -71,7 +72,7 @@
mIsRtlMode = context.getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL;
mLifecycleOwner = lifecycleOwner;
- mMobileNetworkRepository = MobileNetworkRepository.create(context, this);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
if (lifecycle != null) {
lifecycle.addObserver(this);
}
@@ -79,13 +80,14 @@
@OnLifecycleEvent(Event.ON_RESUME)
public void onResume() {
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
- update();
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, this,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ mMobileNetworkRepository.updateEntity();
}
@OnLifecycleEvent(Event.ON_PAUSE)
public void onPause() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
}
@Override
@@ -101,7 +103,9 @@
return setSummaryResId(R.string.calls_sms_no_sim);
} else {
final StringBuilder summary = new StringBuilder();
- for (SubscriptionInfoEntity subInfo : list) {
+ SubscriptionInfoEntity[] entityArray = list.toArray(
+ new SubscriptionInfoEntity[0]);
+ for (SubscriptionInfoEntity subInfo : entityArray) {
int subsSize = list.size();
int subId = Integer.parseInt(subInfo.subId);
final CharSequence displayName = subInfo.uniqueName;
@@ -125,7 +129,7 @@
.append(")");
}
// Do not add ", " for the last subscription.
- if (!subInfo.equals(list.get(list.size() - 1))) {
+ if (list.size() > 0 && !subInfo.equals(list.get(list.size() - 1))) {
summary.append(", ");
}
diff --git a/src/com/android/settings/network/NetworkProviderSimListController.java b/src/com/android/settings/network/NetworkProviderSimListController.java
index 46249ab..db27291 100644
--- a/src/com/android/settings/network/NetworkProviderSimListController.java
+++ b/src/com/android/settings/network/NetworkProviderSimListController.java
@@ -65,19 +65,20 @@
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
mPreferences = new ArrayMap<>();
mLifecycleOwner = lifecycleOwner;
- mMobileNetworkRepository = MobileNetworkRepository.create(context, this);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
lifecycle.addObserver(this);
}
@OnLifecycleEvent(ON_RESUME)
public void onResume() {
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
- update();
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, this,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ mMobileNetworkRepository.updateEntity();
}
@OnLifecycleEvent(ON_PAUSE)
public void onPause() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
}
@Override
diff --git a/src/com/android/settings/network/PrivateDnsPreferenceController.java b/src/com/android/settings/network/PrivateDnsPreferenceController.java
index 04db834..ed6f9ed 100644
--- a/src/com/android/settings/network/PrivateDnsPreferenceController.java
+++ b/src/com/android/settings/network/PrivateDnsPreferenceController.java
@@ -130,7 +130,7 @@
case PRIVATE_DNS_MODE_OFF:
return res.getString(R.string.private_dns_mode_off);
case PRIVATE_DNS_MODE_OPPORTUNISTIC:
- return dnsesResolved ? res.getString(R.string.on)
+ return dnsesResolved ? res.getString(R.string.private_dns_mode_on)
: res.getString(R.string.private_dns_mode_opportunistic);
case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
return dnsesResolved
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 13bb519..9c4ac03 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -688,6 +688,12 @@
.findFirst().orElse(null);
}
+ public static boolean isDefaultSubscription(Context context, int subId) {
+ SubscriptionAnnotation subInfo = getDefaultSubscriptionSelection(
+ new SelectableSubscriptions(context, true).call());
+ return subInfo != null && subInfo.getSubscriptionId() == subId;
+ }
+
public static SubscriptionInfo getSubscriptionOrDefault(Context context, int subscriptionId) {
return getSubscription(context, subscriptionId,
(subscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) ? null : (
diff --git a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
index 4f9e138..b4e768c 100644
--- a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
+++ b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
@@ -52,7 +52,7 @@
LifecycleOwner lifecycleOwner, int subId) {
super(context, key);
mSubId = subId;
- mMobileNetworkRepository = MobileNetworkRepository.createBySubId(context, this, mSubId);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
mLifecycleOwner = lifecycleOwner;
if (lifecycle != null) {
lifecycle.addObserver(this);
@@ -66,12 +66,13 @@
@OnLifecycleEvent(ON_START)
public void onStart() {
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, this, mSubId);
+ mMobileNetworkRepository.updateEntity();
}
@OnLifecycleEvent(ON_STOP)
public void onStop() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
}
@Override
@@ -114,15 +115,12 @@
@Override
public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
// TODO(b/262195754): Need the intent to enabled the feature.
-// if (DataServiceUtils.shouldUpdateEntityList(mSubscriptionInfoEntityList,
-// subInfoEntityList)) {
-// mSubscriptionInfoEntityList = subInfoEntityList;
-// mSubscriptionInfoEntityList.forEach(entity -> {
-// if (Integer.parseInt(entity.subId) == mSubId) {
-// mSubscriptionInfoEntity = entity;
-// update();
-// }
-// });
-// }
+// mSubscriptionInfoEntityList = subInfoEntityList;
+// mSubscriptionInfoEntityList.forEach(entity -> {
+// if (Integer.parseInt(entity.subId) == mSubId) {
+// mSubscriptionInfoEntity = entity;
+// update();
+// }
+// });
}
}
diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
index 106929b..01ec5df 100644
--- a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
@@ -75,7 +75,7 @@
mManager = context.getSystemService(SubscriptionManager.class);
mIsRtlMode = context.getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL;
- mMobileNetworkRepository = MobileNetworkRepository.create(context, this);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
mLifecycleOwner = lifecycleOwner;
if (lifecycle != null) {
lifecycle.addObserver(this);
@@ -104,13 +104,13 @@
@OnLifecycleEvent(ON_RESUME)
public void onResume() {
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
- updateEntries();
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, this, getDefaultSubscriptionId());
+ mMobileNetworkRepository.updateEntity();
}
@OnLifecycleEvent(ON_PAUSE)
public void onPause() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
}
@Override
@@ -303,6 +303,4 @@
updateEntries();
refreshSummary(mPreference);
}
-
-
}
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index 971bb49..cf78942 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -58,7 +58,6 @@
private SwitchPreference mPreference;
private TelephonyManager mTelephonyManager;
private SubscriptionManager mSubscriptionManager;
- private MobileDataContentObserver mDataContentObserver;
private FragmentManager mFragmentManager;
@VisibleForTesting
int mDialogType;
@@ -79,9 +78,7 @@
super(context, key);
mSubId = subId;
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
- mDataContentObserver = new MobileDataContentObserver(new Handler(Looper.getMainLooper()));
- mDataContentObserver.setOnMobileDataChangedListener(() -> updateState(mPreference));
- mMobileNetworkRepository = MobileNetworkRepository.createBySubId(context, this, mSubId);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
mLifecycleOwner = lifecycleOwner;
if (lifecycle != null) {
lifecycle.addObserver(this);
@@ -103,12 +100,13 @@
@OnLifecycleEvent(ON_START)
public void onStart() {
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, this, mSubId);
+ mMobileNetworkRepository.updateEntity();
}
@OnLifecycleEvent(ON_STOP)
public void onStop() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
}
@Override
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 1ff5e17..0f2d02bf 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -23,6 +23,7 @@
import android.os.Bundle;
import android.os.UserManager;
import android.provider.Settings;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -150,14 +151,14 @@
MobileNetworkUtils.getSearchableSubscriptionId(context));
Log.d(LOG_TAG, "display subId from intent: " + mSubId);
} else {
- Log.d(LOG_TAG, "intent is null, can not get the subId from intent.");
+ Log.d(LOG_TAG, "intent is null, can not get subId " + mSubId + " from intent.");
}
} else {
mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID,
MobileNetworkUtils.getSearchableSubscriptionId(context));
Log.d(LOG_TAG, "display subId from getArguments(): " + mSubId);
}
- mMobileNetworkRepository = MobileNetworkRepository.create(context, this);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
mExecutor.execute(() -> {
mSubscriptionInfoEntity = mMobileNetworkRepository.getSubInfoById(
String.valueOf(mSubId));
@@ -165,9 +166,7 @@
mMobileNetworkRepository.queryMobileNetworkInfoBySubId(
String.valueOf(mSubId));
});
- if (mSubId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- return Arrays.asList();
- }
+
return Arrays.asList(
new DataUsageSummaryPreferenceController(getActivity(), getSettingsLifecycle(),
this, mSubId),
@@ -188,8 +187,14 @@
super.onAttach(context);
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- Log.d(LOG_TAG, "Invalid subId request " + mSubId);
- return;
+ Log.d(LOG_TAG, "Invalid subId, get the default subscription to show.");
+ SubscriptionInfo info = SubscriptionUtil.getSubscriptionOrDefault(context, mSubId);
+ if (info == null) {
+ Log.d(LOG_TAG, "Invalid subId request " + mSubId);
+ return;
+ }
+ mSubId = info.getSubscriptionId();
+ Log.d(LOG_TAG, "Show NetworkSettings fragment for subId" + mSubId);
}
Intent intent = getIntent();
@@ -269,7 +274,7 @@
use(OpenNetworkSelectPagePreferenceController.class).init(mSubId);
final AutoSelectPreferenceController autoSelectPreferenceController =
use(AutoSelectPreferenceController.class)
- .init(mSubId)
+ .init(getLifecycle(), mSubId)
.addListener(openNetworkSelectPagePreferenceController);
use(NetworkPreferenceCategoryController.class).init(mSubId)
.setChildren(Arrays.asList(autoSelectPreferenceController));
@@ -291,7 +296,11 @@
use(ContactDiscoveryPreferenceController.class).init(getParentFragmentManager(), mSubId);
use(NrAdvancedCallingPreferenceController.class).init(mSubId);
use(TransferEsimPreferenceController.class).init(mSubId, mSubscriptionInfoEntity);
- use(ConvertToEsimPreferenceController.class).init(mSubId, mSubscriptionInfoEntity);
+ final ConvertToEsimPreferenceController convertToEsimPreferenceController =
+ use(ConvertToEsimPreferenceController.class);
+ if (convertToEsimPreferenceController != null) {
+ convertToEsimPreferenceController.init(mSubId, mSubscriptionInfoEntity);
+ }
}
@Override
@@ -315,13 +324,13 @@
@Override
public void onResume() {
super.onResume();
- mMobileNetworkRepository.addRegister(this);
+ mMobileNetworkRepository.addRegister(this, this, mSubId);
+ mMobileNetworkRepository.updateEntity();
// TODO: remove log after fixing b/182326102
Log.d(LOG_TAG, "onResume() subId=" + mSubId);
}
private void onSubscriptionDetailChanged() {
-
if (mSubscriptionInfoEntity != null) {
/**
* Update the title when SIM stats got changed
@@ -344,7 +353,7 @@
@Override
public void onDestroy() {
super.onDestroy();
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
}
@VisibleForTesting
@@ -451,7 +460,7 @@
ContactDiscoveryDialogFragment fragment = getContactDiscoveryFragment(mSubId);
if (mSubscriptionInfoEntity == null) {
- Log.d(LOG_TAG, "Zoey, showContactDiscoveryDialog, Invalid subId request " + mSubId);
+ Log.d(LOG_TAG, "showContactDiscoveryDialog, Invalid subId request " + mSubId);
onDestroy();
return;
}
@@ -488,13 +497,20 @@
}
mSubInfoEntityList = subInfoEntityList;
- mSubInfoEntityList.forEach(entity -> {
+ SubscriptionInfoEntity[] entityArray = mSubInfoEntityList.toArray(
+ new SubscriptionInfoEntity[0]);
+ for (SubscriptionInfoEntity entity : entityArray) {
int subId = Integer.parseInt(entity.subId);
mSubscriptionInfoMap.put(subId, entity);
- if (subId == mSubId) {
+ if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && subId == mSubId) {
mSubscriptionInfoEntity = entity;
- onSubscriptionDetailChanged();
+ Log.d(LOG_TAG, "Set subInfo for subId " + mSubId);
+ break;
+ } else if (entity.isDefaultSubscriptionSelection) {
+ mSubscriptionInfoEntity = entity;
+ Log.d(LOG_TAG, "Set subInfo to default subInfo.");
}
- });
+ }
+ onSubscriptionDetailChanged();
}
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
index 308da88..265eb16 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
@@ -949,7 +949,12 @@
boolean isWifiCallingEnabled;
if (phoneAccountHandle != null) {
final Intent intent = buildPhoneAccountConfigureIntent(context, phoneAccountHandle);
- isWifiCallingEnabled = intent != null;
+ if (intent == null) {
+ Log.d(TAG, "Can not get phoneAccount configure intent.");
+ isWifiCallingEnabled = false;
+ } else {
+ isWifiCallingEnabled = true;
+ }
} else {
if (queryImsState == null) {
queryImsState = new WifiCallingQueryImsState(context, subId);
@@ -959,7 +964,6 @@
return isWifiCallingEnabled;
}
-
/**
* Returns preferred status of Calls & SMS separately when Provider Model is enabled.
*/
diff --git a/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java b/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java
index 688084f..7ad9e03 100644
--- a/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java
+++ b/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java
@@ -314,29 +314,13 @@
@VisibleForTesting
protected boolean shouldShowWifiCallingForSub(int subId) {
if (SubscriptionManager.isValidSubscriptionId(subId)
- && MobileNetworkUtils.isWifiCallingEnabled(
- mContext, subId, queryImsState(subId),
- getPhoneAccountHandleForSubscriptionId(subId))
- && isWifiCallingAvailableForCarrier(subId)) {
+ && MobileNetworkUtils.isWifiCallingEnabled(mContext, subId, queryImsState(subId),
+ null)) {
return true;
}
return false;
}
- private boolean isWifiCallingAvailableForCarrier(int subId) {
- boolean isWifiCallingAvailableForCarrier = false;
- if (mCarrierConfigManager != null) {
- final PersistableBundle carrierConfig =
- mCarrierConfigManager.getConfigForSubId(subId);
- if (carrierConfig != null) {
- isWifiCallingAvailableForCarrier = carrierConfig.getBoolean(
- CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL);
- }
- }
- Log.d(TAG, "isWifiCallingAvailableForCarrier:" + isWifiCallingAvailableForCarrier);
- return isWifiCallingAvailableForCarrier;
- }
-
@Override
public String getPreferenceKey() {
return KEY_PREFERENCE_WIFICALLING_GROUP;
diff --git a/src/com/android/settings/network/telephony/RoamingPreferenceController.java b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
index af56a88..ff5da52 100644
--- a/src/com/android/settings/network/telephony/RoamingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
@@ -81,7 +81,7 @@
super(context, key);
mSubId = subId;
mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
- mMobileNetworkRepository = MobileNetworkRepository.createBySubId(context, this, mSubId);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
mLifecycleOwner = lifecycleOwner;
if (lifecycle != null) {
lifecycle.addObserver(this);
@@ -100,7 +100,8 @@
@OnLifecycleEvent(ON_START)
public void onStart() {
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, this, mSubId);
+ mMobileNetworkRepository.updateEntity();
if (mListener == null) {
mListener = new GlobalSettingsChangeListener(mContext,
Settings.Global.DATA_ROAMING) {
@@ -126,7 +127,7 @@
@OnLifecycleEvent(ON_STOP)
public void onStop() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(this);
stopMonitor();
stopMonitorSubIdSpecific();
}
diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
index 2d7ba38..1bc2f90 100644
--- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
@@ -25,7 +25,6 @@
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
-import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
diff --git a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
index 72d9e91..e3e83dc 100644
--- a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
+++ b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
@@ -34,8 +34,10 @@
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.Preference;
@@ -45,6 +47,7 @@
import com.android.settings.R;
import com.android.settings.network.AllowedNetworkTypesListener;
import com.android.settings.network.CarrierConfigCache;
+import com.android.settings.network.helper.ServiceStateStatus;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.network.telephony.TelephonyTogglePreferenceController;
import com.android.settingslib.utils.ThreadUtils;
@@ -62,6 +65,9 @@
public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController
implements LifecycleObserver{
private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1);
+ private static final String LOG_TAG = "AutoSelectPreferenceController";
+ private static final String INTERNAL_LOG_TAG_INIT = "Init";
+ private static final String INTERNAL_LOG_TAG_AFTERSET = "AfterSet";
private final Handler mUiHandler;
private PreferenceScreen mPreferenceScreen;
@@ -76,6 +82,7 @@
private AtomicBoolean mUpdatingConfig;
private int mCacheOfModeStatus;
private AtomicLong mRecursiveUpdate;
+ ServiceStateStatus mServiceStateStatus;
public AutoSelectPreferenceController(Context context, String key) {
super(context, key);
@@ -129,12 +136,6 @@
@Override
public boolean isChecked() {
- if (!mUpdatingConfig.get()) {
- mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
- for (OnNetworkSelectModeListener lsn : mListeners) {
- lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
- }
- }
return mCacheOfModeStatus == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
}
@@ -197,12 +198,23 @@
//Update UI in UI thread
final long durationMillis = SystemClock.elapsedRealtime() - startMillis;
+
mUiHandler.postDelayed(() -> {
- mRecursiveUpdate.getAndIncrement();
- mSwitchPreference.setEnabled(true);
- mSwitchPreference.setChecked(isChecked());
- mRecursiveUpdate.decrementAndGet();
- dismissProgressBar();
+ ThreadUtils.postOnBackgroundThread(() -> {
+ queryNetworkSelectionMode(INTERNAL_LOG_TAG_AFTERSET);
+
+ //Update UI in UI thread
+ mUiHandler.post(() -> {
+ mRecursiveUpdate.getAndIncrement();
+ if (mSwitchPreference != null) {
+ mSwitchPreference.setEnabled(true);
+ mSwitchPreference.setChecked(isChecked());
+ }
+ mRecursiveUpdate.decrementAndGet();
+ updateListenerValue();
+ dismissProgressBar();
+ });
+ });
}, Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0));
});
}
@@ -210,7 +222,7 @@
/**
* Initialization based on given subscription id.
**/
- public AutoSelectPreferenceController init(int subId) {
+ public AutoSelectPreferenceController init(Lifecycle lifecycle, int subId) {
mSubId = subId;
mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
.createForSubscriptionId(mSubId);
@@ -221,6 +233,29 @@
CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL)
: false;
+ mServiceStateStatus = new ServiceStateStatus(lifecycle, mTelephonyManager,
+ new HandlerExecutor(mUiHandler)) {
+ @Override
+ protected void setValue(ServiceState status) {
+ if (status == null) {
+ return;
+ }
+ updateUiAutoSelectValue(status);
+ }
+ };
+
+ ThreadUtils.postOnBackgroundThread(() -> {
+ queryNetworkSelectionMode(INTERNAL_LOG_TAG_INIT);
+ //Update UI in UI thread
+ mUiHandler.post(() -> {
+ if (mSwitchPreference != null) {
+ mRecursiveUpdate.getAndIncrement();
+ mSwitchPreference.setChecked(isChecked());
+ mRecursiveUpdate.decrementAndGet();
+ updateListenerValue();
+ }
+ });
+ });
return this;
}
@@ -230,6 +265,39 @@
return this;
}
+ private void queryNetworkSelectionMode(String tag) {
+ mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
+ Log.d(LOG_TAG, tag + ": query command done. mCacheOfModeStatus: " + mCacheOfModeStatus);
+ }
+
+ @VisibleForTesting
+ void updateUiAutoSelectValue(ServiceState status) {
+ if (status == null) {
+ return;
+ }
+ if (!mUpdatingConfig.get()) {
+ int networkSelectionMode = status.getIsManualSelection()
+ ? TelephonyManager.NETWORK_SELECTION_MODE_MANUAL
+ : TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
+ if (mCacheOfModeStatus == networkSelectionMode) {
+ return;
+ }
+ mCacheOfModeStatus = networkSelectionMode;
+ Log.d(LOG_TAG, "updateUiAutoSelectValue: mCacheOfModeStatus: " + mCacheOfModeStatus);
+
+ mRecursiveUpdate.getAndIncrement();
+ updateState(mSwitchPreference);
+ mRecursiveUpdate.decrementAndGet();
+ updateListenerValue();
+ }
+ }
+
+ private void updateListenerValue() {
+ for (OnNetworkSelectModeListener lsn : mListeners) {
+ lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
+ }
+ }
+
private void showAutoSelectProgressBar() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(mContext);
diff --git a/src/com/android/settings/nfc/AndroidBeamEnabler.java b/src/com/android/settings/nfc/AndroidBeamEnabler.java
index a1ecffd..31ef702 100644
--- a/src/com/android/settings/nfc/AndroidBeamEnabler.java
+++ b/src/com/android/settings/nfc/AndroidBeamEnabler.java
@@ -65,7 +65,7 @@
if (mNfcAdapter.isNdefPushEnabled() && mPreference.isEnabled()) {
mPreference.setSummary(R.string.android_beam_on_summary);
} else {
- mPreference.setSummary(R.string.off);
+ mPreference.setSummary(R.string.android_beam_off_summary);
}
break;
case NfcAdapter.STATE_TURNING_ON:
diff --git a/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceController.java b/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceController.java
index 78ba9ea..3dac732 100644
--- a/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceController.java
@@ -44,7 +44,7 @@
return mContext.getString(
areBubblesEnabled()
? R.string.notifications_bubble_setting_on_summary
- : R.string.off);
+ : R.string.switch_off_text);
}
@Override
diff --git a/src/com/android/settings/notification/DockAudioMediaPreferenceController.java b/src/com/android/settings/notification/DockAudioMediaPreferenceController.java
index d9367d5..7170434 100644
--- a/src/com/android/settings/notification/DockAudioMediaPreferenceController.java
+++ b/src/com/android/settings/notification/DockAudioMediaPreferenceController.java
@@ -19,6 +19,8 @@
import static com.android.settings.notification.SettingPref.TYPE_GLOBAL;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Resources;
import android.provider.Settings.Global;
@@ -41,7 +43,7 @@
DEFAULT_DOCK_AUDIO_MEDIA, DOCK_AUDIO_MEDIA_DISABLED, DOCK_AUDIO_MEDIA_ENABLED) {
@Override
public boolean isApplicable(Context context) {
- return context.getResources().getBoolean(
+ return isLeDesk() && context.getResources().getBoolean(
com.android.settings.R.bool.has_dock_settings);
}
@@ -60,4 +62,18 @@
}
};
}
+
+ /**
+ * Checks the state of docking type
+ * @return true if it is low-end dock types
+ */
+ private boolean isLeDesk() {
+ IntentFilter intentFilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
+ Intent dockStatus = mContext.registerReceiver(null, intentFilter);
+ if (dockStatus == null) {
+ return false;
+ }
+ int dockState = dockStatus.getIntExtra(Intent.EXTRA_DOCK_STATE, -1);
+ return dockState == Intent.EXTRA_DOCK_STATE_LE_DESK;
+ }
}
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
index 4ec9ccd..56d3f0e 100644
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
@@ -65,6 +65,7 @@
private static final String TAG = "NotifAccessSettings";
private static final String ALLOWED_KEY = "allowed";
private static final String NOT_ALLOWED_KEY = "not_allowed";
+ private static final int MAX_CN_LENGTH = 500;
private static final ManagedServiceSettings.Config CONFIG =
new ManagedServiceSettings.Config.Builder()
@@ -101,6 +102,12 @@
.setNoun(CONFIG.noun)
.setSetting(CONFIG.setting)
.setTag(CONFIG.tag)
+ .setValidator(info -> {
+ if (info.getComponentName().flattenToString().length() > MAX_CN_LENGTH) {
+ return false;
+ }
+ return true;
+ })
.build();
mServiceListing.addCallback(this::updateList);
diff --git a/src/com/android/settings/notification/SpatialAudioParentPreferenceController.java b/src/com/android/settings/notification/SpatialAudioParentPreferenceController.java
index 5f2a9cb..8ae0493 100644
--- a/src/com/android/settings/notification/SpatialAudioParentPreferenceController.java
+++ b/src/com/android/settings/notification/SpatialAudioParentPreferenceController.java
@@ -71,7 +71,7 @@
return mContext.getString(R.string.spatial_summary_on_one,
mContext.getString(R.string.spatial_audio_wired_headphones));
} else {
- return mContext.getString(R.string.off);
+ return mContext.getString(R.string.spatial_summary_off);
}
}
}
diff --git a/src/com/android/settings/notification/app/AppConversationListPreferenceController.java b/src/com/android/settings/notification/app/AppConversationListPreferenceController.java
index dd44a13..4f63576 100644
--- a/src/com/android/settings/notification/app/AppConversationListPreferenceController.java
+++ b/src/com/android/settings/notification/app/AppConversationListPreferenceController.java
@@ -127,15 +127,13 @@
return;
}
- if (!mConversations.isEmpty()) {
- // TODO: if preference has children, compare with newly loaded list
- mPreference.removeAll();
- mPreference.setTitle(getTitleResId());
- populateConversations();
- }
+ mPreference.setTitle(getTitleResId());
+ populateConversations();
}
private void populateConversations() {
+ mPreference.removeAll();
+ mPreference.setVisible(!mConversations.isEmpty());
for (ConversationChannelWrapper conversation : mConversations) {
if (conversation.getNotificationChannel().isDemoted()) {
continue;
diff --git a/src/com/android/settings/notification/app/AppNotificationSettings.java b/src/com/android/settings/notification/app/AppNotificationSettings.java
index ebcd261..5a14bc9 100644
--- a/src/com/android/settings/notification/app/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/app/AppNotificationSettings.java
@@ -98,14 +98,13 @@
mBackend));
mControllers.add(new DndPreferenceController(context, mBackend));
mControllers.add(new AppLinkPreferenceController(context));
- mControllers.add(new DescriptionPreferenceController(context));
- mControllers.add(new NotificationsOffPreferenceController(context));
- mControllers.add(new DeletedChannelsPreferenceController(context, mBackend));
mControllers.add(new ChannelListPreferenceController(context, mBackend));
mControllers.add(new AppConversationListPreferenceController(context, mBackend));
mControllers.add(new InvalidConversationInfoPreferenceController(context, mBackend));
mControllers.add(new InvalidConversationPreferenceController(context, mBackend));
mControllers.add(new BubbleSummaryPreferenceController(context, mBackend));
+ mControllers.add(new NotificationsOffPreferenceController(context));
+ mControllers.add(new DeletedChannelsPreferenceController(context, mBackend));
return new ArrayList<>(mControllers);
}
}
diff --git a/src/com/android/settings/notification/app/BadgePreferenceController.java b/src/com/android/settings/notification/app/BadgePreferenceController.java
index 108fa1d..9d55fa3 100644
--- a/src/com/android/settings/notification/app/BadgePreferenceController.java
+++ b/src/com/android/settings/notification/app/BadgePreferenceController.java
@@ -62,9 +62,16 @@
if (isDefaultChannel()) {
return true;
} else {
- return mAppRow == null ? false : mAppRow.showBadge;
+ return mAppRow == null
+ ? false
+ : mAppRow.channelCount == 0
+ ? false
+ : mAppRow.showBadge;
}
}
+ if (mAppRow.channelCount == 0) {
+ return false;
+ }
return true;
}
diff --git a/src/com/android/settings/notification/app/ConversationNotificationSettings.java b/src/com/android/settings/notification/app/ConversationNotificationSettings.java
index b452309..02ea6c0 100644
--- a/src/com/android/settings/notification/app/ConversationNotificationSettings.java
+++ b/src/com/android/settings/notification/app/ConversationNotificationSettings.java
@@ -99,6 +99,7 @@
mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(),
mBackend, false /* isAppPage */, null /* dependentFieldListener */));
mControllers.add(new ConversationDemotePreferenceController(context, this, mBackend));
+ mControllers.add(new ConversationPromotePreferenceController(context, this, mBackend));
mControllers.add(new BubbleCategoryPreferenceController(context));
mControllers.add(new BubbleLinkPreferenceController(context));
return new ArrayList<>(mControllers);
diff --git a/src/com/android/settings/notification/app/DescriptionPreferenceController.java b/src/com/android/settings/notification/app/DescriptionPreferenceController.java
deleted file mode 100644
index 0a5bb2f..0000000
--- a/src/com/android/settings/notification/app/DescriptionPreferenceController.java
+++ /dev/null
@@ -1,73 +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.notification.app;
-
-import android.content.Context;
-import android.text.TextUtils;
-
-import androidx.preference.Preference;
-
-import com.android.settings.core.PreferenceControllerMixin;
-
-public class DescriptionPreferenceController extends NotificationPreferenceController
- implements PreferenceControllerMixin {
-
- private static final String KEY_DESC = "desc";
-
- public DescriptionPreferenceController(Context context) {
- super(context, null);
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_DESC;
- }
-
- @Override
- public boolean isAvailable() {
- if (!super.isAvailable()) {
- return false;
- }
- if (mChannel == null && !hasValidGroup()) {
- return false;
- }
- if (mChannel != null && !TextUtils.isEmpty(mChannel.getDescription())) {
- return true;
- }
- if (hasValidGroup() && !TextUtils.isEmpty(mChannelGroup.getDescription())) {
- return true;
- }
- return false;
- }
-
- @Override
- boolean isIncludedInFilter() {
- return false;
- }
-
- public void updateState(Preference preference) {
- if (mAppRow != null) {
- if (mChannel != null) {
- preference.setTitle(mChannel.getDescription());
- } else if (hasValidGroup()) {
- preference.setTitle(mChannelGroup.getDescription());
- }
- }
- preference.setEnabled(false);
- preference.setSelectable(false);
- }
-}
diff --git a/src/com/android/settings/notification/history/NotificationHistoryActivity.java b/src/com/android/settings/notification/history/NotificationHistoryActivity.java
index 021ba6f..b71d295 100644
--- a/src/com/android/settings/notification/history/NotificationHistoryActivity.java
+++ b/src/com/android/settings/notification/history/NotificationHistoryActivity.java
@@ -78,6 +78,7 @@
// R.integer.config_notificationServiceArchiveSize, which is the Number of notifications kept
// in the notification service historical archive
private static final int MAX_RECENT_DISMISS_ITEM_COUNT = 50;
+ private static final int HISTORY_HOURS = 24;
private ViewGroup mHistoryOn;
private ViewGroup mHistoryOff;
@@ -243,6 +244,8 @@
mHistoryOn = findViewById(R.id.history_on);
mHistoryEmpty = findViewById(R.id.history_on_empty);
mSwitchBar = findViewById(R.id.main_switch_bar);
+ ((TextView) findViewById(R.id.today_header)).setText(
+ getString(R.string.notification_history_today, HISTORY_HOURS));
ActionBar actionBar = getActionBar();
if (actionBar != null) {
diff --git a/src/com/android/settings/notification/zen/ZenModeBackend.java b/src/com/android/settings/notification/zen/ZenModeBackend.java
index 85f9aee..1079865 100644
--- a/src/com/android/settings/notification/zen/ZenModeBackend.java
+++ b/src/com/android/settings/notification/zen/ZenModeBackend.java
@@ -312,21 +312,6 @@
return R.string.zen_mode_from_no_conversations;
}
- protected int getConversationSummary() {
- int conversationType = getPriorityConversationSenders();
-
- switch (conversationType) {
- case NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE:
- return R.string.zen_mode_from_all_conversations;
- case NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT:
- return R.string.zen_mode_from_important_conversations;
- case NotificationManager.Policy.CONVERSATION_SENDERS_NONE:
- return R.string.zen_mode_from_no_conversations;
- default:
- return R.string.zen_mode_from_no_conversations;
- }
- }
-
protected int getContactsCallsSummary(ZenPolicy policy) {
int peopleType = policy.getPriorityCallSenders();
switch (peopleType) {
diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsImagePreferenceController.java b/src/com/android/settings/notification/zen/ZenModeConversationsImagePreferenceController.java
deleted file mode 100644
index 78c8134..0000000
--- a/src/com/android/settings/notification/zen/ZenModeConversationsImagePreferenceController.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2020 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.notification.zen;
-
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
-
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.service.notification.ConversationChannelWrapper;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.LayoutPreference;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Updates the DND Settings conversations image resource based on the conversations channels.
- */
-public class ZenModeConversationsImagePreferenceController
- extends AbstractZenModePreferenceController {
- private static final int MAX_CONVERSATIONS_SHOWN = 5;
- private final int mIconSizePx;
- private final int mIconOffsetPx;
- private final ArrayList<Drawable> mConversationDrawables = new ArrayList<>();
- private final NotificationBackend mNotificationBackend;
-
- private ViewGroup mViewGroup;
- private LayoutPreference mPreference;
-
- public ZenModeConversationsImagePreferenceController(Context context, String key,
- Lifecycle lifecycle, NotificationBackend notificationBackend) {
- super(context, key, lifecycle);
- mNotificationBackend = notificationBackend;
- mIconSizePx =
- mContext.getResources().getDimensionPixelSize(R.dimen.zen_conversations_icon_size);
- mIconOffsetPx = mContext.getResources()
- .getDimensionPixelSize(R.dimen.zen_conversations_icon_offset);
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mPreference = (LayoutPreference) screen.findPreference(KEY);
- mViewGroup =
- (ViewGroup) mPreference.findViewById(R.id.zen_mode_settings_senders_overlay_view);
- loadConversations();
- }
-
- @Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY;
- }
-
- @Override
- public void updateState(Preference preference) {
- loadConversations();
-
- mViewGroup.removeAllViews();
- final int conversationSenders = mBackend.getPriorityConversationSenders();
- if (conversationSenders == CONVERSATION_SENDERS_ANYONE) {
- mViewGroup.setContentDescription(
- mContext.getResources().getString(R.string.zen_mode_from_all_conversations));
- } else if (conversationSenders == CONVERSATION_SENDERS_IMPORTANT) {
- mViewGroup.setContentDescription(
- mContext.getResources().getString(
- R.string.zen_mode_from_important_conversations));
- } else {
- mViewGroup.setContentDescription(null);
- mViewGroup.setVisibility(View.GONE);
- return;
- }
-
- final int numDrawablesToShow = Math.min(MAX_CONVERSATIONS_SHOWN,
- mConversationDrawables.size());
- for (int i = 0; i < numDrawablesToShow; i++) {
- ImageView iv = new ImageView(mContext);
- iv.setImageDrawable(mConversationDrawables.get(i));
- iv.setLayoutParams(new ViewGroup.LayoutParams(mIconSizePx, mIconSizePx));
-
- FrameLayout fl = new FrameLayout(mContext);
- fl.addView(iv);
- fl.setPadding((numDrawablesToShow - i - 1) * mIconOffsetPx, 0, 0, 0);
- mViewGroup.addView(fl);
- }
-
- mViewGroup.setVisibility(numDrawablesToShow > 0 ? View.VISIBLE : View.GONE);
- }
-
- private void loadConversations() {
- // Load conversations
- new AsyncTask<Void, Void, Void>() {
- private List<Drawable> mDrawables = new ArrayList<>();
- @Override
- protected Void doInBackground(Void... unused) {
- mDrawables.clear();
- final int conversationSenders = mBackend.getPriorityConversationSenders();
- if (conversationSenders == CONVERSATION_SENDERS_NONE) {
- return null;
- }
- ParceledListSlice<ConversationChannelWrapper> conversations =
- mNotificationBackend.getConversations(
- conversationSenders == CONVERSATION_SENDERS_IMPORTANT);
- if (conversations != null) {
- for (ConversationChannelWrapper conversation : conversations.getList()) {
- if (!conversation.getNotificationChannel().isDemoted()) {
- Drawable drawable = mNotificationBackend.getConversationDrawable(
- mContext,
- conversation.getShortcutInfo(),
- conversation.getPkg(),
- conversation.getUid(),
- conversation.getNotificationChannel()
- .isImportantConversation());
- if (drawable != null) {
- mDrawables.add(drawable);
- }
- }
- }
- }
-
- return null;
- }
-
- @Override
- protected void onPostExecute(Void unused) {
- if (mContext == null) {
- return;
- }
- mConversationDrawables.clear();
- mConversationDrawables.addAll(mDrawables);
- updateState(mPreference);
- }
- }.execute();
- }
-}
diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java
deleted file mode 100644
index f23bf61..0000000
--- a/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2020 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.notification.zen;
-
-import android.app.NotificationManager;
-import android.content.Context;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-/**
- * Controls the summary for preference found at:
- * Settings > Sound > Do Not Disturb > People > Conversations
- */
-public class ZenModeConversationsPreferenceController extends AbstractZenModePreferenceController {
- private final ZenModeBackend mBackend;
- private Preference mPreference;
-
- public ZenModeConversationsPreferenceController(Context context,
- String key, Lifecycle lifecycle) {
- super(context, key, lifecycle);
- mBackend = ZenModeBackend.getInstance(context);
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY;
- }
-
- @Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mPreference = screen.findPreference(KEY);
- }
-
- @Override
- public void updateState(Preference preference) {
- super.updateState(preference);
- switch (getZenMode()) {
- case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
- case Settings.Global.ZEN_MODE_ALARMS:
- mPreference.setEnabled(false);
- mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary(
- NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS));
- break;
- default:
- preference.setEnabled(true);
- preference.setSummary(mBackend.getConversationSummary());
- }
- }
-}
diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java b/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java
deleted file mode 100644
index 5c68126..0000000
--- a/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 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.notification.zen;
-
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-
-import com.android.settings.R;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Settings > Sound > Do Not Disturb > Conversations
- */
-@SearchIndexable
-public class ZenModeConversationsSettings extends ZenModeSettingsBase {
- private final NotificationBackend mNotificationBackend = new NotificationBackend();
-
- @Override
- protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
- return buildPreferenceControllers(context, getSettingsLifecycle(), mNotificationBackend);
- }
-
- private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
- Lifecycle lifecycle, NotificationBackend notificationBackend) {
- List<AbstractPreferenceController> controllers = new ArrayList<>();
- controllers.add(new ZenModeConversationsImagePreferenceController(context,
- "zen_mode_conversations_image", lifecycle, notificationBackend));
- controllers.add(new ZenModePriorityConversationsPreferenceController(context,
- "zen_mode_conversations_radio_buttons", lifecycle, notificationBackend));
- return controllers;
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.zen_mode_conversations_settings;
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.DND_CONVERSATIONS;
- }
-
- /**
- * For Search.
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.zen_mode_conversations_settings) {
-
- @Override
- public List<AbstractPreferenceController> createPreferenceControllers(
- Context context) {
- return buildPreferenceControllers(context, null, null);
- }
- };
-}
diff --git a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
deleted file mode 100644
index a8387a3..0000000
--- a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2020 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.notification.zen;
-
-import android.app.NotificationManager;
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.icu.text.MessageFormat;
-import android.os.AsyncTask;
-import android.service.notification.ConversationChannelWrapper;
-import android.view.View;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settings.notification.app.ConversationListSettings;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.SelectorWithWidgetPreference;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Options to choose the priority conversations that are allowed to bypass DND.
- */
-public class ZenModePriorityConversationsPreferenceController
- extends AbstractZenModePreferenceController {
- private static final int UNSET = -1;
- @VisibleForTesting static final String KEY_ALL = "conversations_all";
- @VisibleForTesting static final String KEY_IMPORTANT = "conversations_important";
- @VisibleForTesting static final String KEY_NONE = "conversations_none";
-
- private final NotificationBackend mNotificationBackend;
-
- private int mNumImportantConversations = UNSET;
- private int mNumConversations = UNSET;
- private PreferenceCategory mPreferenceCategory;
- private List<SelectorWithWidgetPreference> mSelectorWithWidgetPreferences = new ArrayList<>();
- private Context mPreferenceScreenContext;
-
- public ZenModePriorityConversationsPreferenceController(Context context, String key,
- Lifecycle lifecycle, NotificationBackend notificationBackend) {
- super(context, key, lifecycle);
- mNotificationBackend = notificationBackend;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- mPreferenceScreenContext = screen.getContext();
- mPreferenceCategory = screen.findPreference(getPreferenceKey());
- if (mPreferenceCategory.findPreference(KEY_ALL) == null) {
- makeRadioPreference(KEY_ALL, R.string.zen_mode_from_all_conversations);
- makeRadioPreference(KEY_IMPORTANT, R.string.zen_mode_from_important_conversations);
- makeRadioPreference(KEY_NONE, R.string.zen_mode_from_no_conversations);
- updateChannelCounts();
- }
-
- super.displayPreference(screen);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updateChannelCounts();
- }
-
- @Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY;
- }
-
- @Override
- public void updateState(Preference preference) {
- final int currSetting = mBackend.getPriorityConversationSenders();
-
- for (SelectorWithWidgetPreference pref : mSelectorWithWidgetPreferences) {
- pref.setChecked(keyToSetting(pref.getKey()) == currSetting);
- pref.setSummary(getSummary(pref.getKey()));
- }
- }
-
- private static int keyToSetting(String key) {
- switch (key) {
- case KEY_ALL:
- return NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
- case KEY_IMPORTANT:
- return NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
- default:
- return NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
- }
- }
-
- private String getSummary(String key) {
- int numConversations;
- if (KEY_ALL.equals(key)) {
- numConversations = mNumConversations;
- } else if (KEY_IMPORTANT.equals(key)) {
- numConversations = mNumImportantConversations;
- } else {
- return null;
- }
-
- if (numConversations == UNSET) {
- return null;
- } else {
- MessageFormat msgFormat = new MessageFormat(
- mContext.getString(R.string.zen_mode_conversations_count),
- Locale.getDefault());
- Map<String, Object> args = new HashMap<>();
- args.put("count", numConversations);
- return msgFormat.format(args);
- }
- }
-
- private void updateChannelCounts() {
- // Load conversations
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... unused) {
- ParceledListSlice<ConversationChannelWrapper> allConversations =
- mNotificationBackend.getConversations(false);
- int numConversations = 0;
- if (allConversations != null) {
- for (ConversationChannelWrapper conversation : allConversations.getList()) {
- if (!conversation.getNotificationChannel().isDemoted()) {
- numConversations++;
- }
- }
- }
- mNumConversations = numConversations;
-
- ParceledListSlice<ConversationChannelWrapper> impConversations =
- mNotificationBackend.getConversations(true);
- int numImportantConversations = 0;
- if (impConversations != null) {
- for (ConversationChannelWrapper conversation : impConversations.getList()) {
- if (!conversation.getNotificationChannel().isDemoted()) {
- numImportantConversations++;
- }
- }
- }
- mNumImportantConversations = numImportantConversations;
- return null;
- }
-
- @Override
- protected void onPostExecute(Void unused) {
- if (mContext == null) {
- return;
- }
- updateState(mPreferenceCategory);
- }
- }.execute();
- }
-
- private SelectorWithWidgetPreference makeRadioPreference(String key, int titleId) {
- final SelectorWithWidgetPreference pref =
- new SelectorWithWidgetPreference(mPreferenceCategory.getContext());
- if (KEY_ALL.equals(key) || KEY_IMPORTANT.equals(key)) {
- pref.setExtraWidgetOnClickListener(mConversationSettingsWidgetClickListener);
- }
- pref.setKey(key);
- pref.setTitle(titleId);
- pref.setOnClickListener(mRadioButtonClickListener);
- mPreferenceCategory.addPreference(pref);
- mSelectorWithWidgetPreferences.add(pref);
- return pref;
- }
-
- private View.OnClickListener mConversationSettingsWidgetClickListener =
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- new SubSettingLauncher(mPreferenceScreenContext)
- .setDestination(ConversationListSettings.class.getName())
- .setSourceMetricsCategory(SettingsEnums.DND_CONVERSATIONS)
- .launch();
- }
- };
-
- private SelectorWithWidgetPreference.OnClickListener mRadioButtonClickListener =
- new SelectorWithWidgetPreference.OnClickListener() {
- @Override
- public void onRadioButtonClicked(SelectorWithWidgetPreference preference) {
- int selectedConversationSetting = keyToSetting(preference.getKey());
- if (selectedConversationSetting != mBackend.getPriorityConversationSenders()) {
- mBackend.saveConversationSenders(selectedConversationSetting);
- }
- }
- };
-}
diff --git a/src/com/android/settings/notification/zen/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/zen/ZenModeRuleSettingsBase.java
index 5297801..cda5b1a 100644
--- a/src/com/android/settings/notification/zen/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/zen/ZenModeRuleSettingsBase.java
@@ -48,6 +48,7 @@
protected boolean mDisableListeners;
protected AutomaticZenRule mRule;
protected String mId;
+ private boolean mRuleRemoved;
protected ZenAutomaticRuleHeaderPreferenceController mHeader;
protected ZenRuleButtonsPreferenceController mActionButtons;
@@ -162,6 +163,10 @@
}
private boolean refreshRuleOrFinish() {
+ if (mRuleRemoved && getActivity() != null) {
+ getActivity().finish();
+ return true;
+ }
mRule = getZenRule();
if (DEBUG) Log.d(TAG, "mRule=" + mRule);
mHeader.setRule(mRule);
@@ -196,4 +201,8 @@
}
mDisableListeners = false;
}
+
+ void onRuleRemoved() {
+ mRuleRemoved = true;
+ }
}
diff --git a/src/com/android/settings/notification/zen/ZenModeSettings.java b/src/com/android/settings/notification/zen/ZenModeSettings.java
index b849edf..a707e53 100644
--- a/src/com/android/settings/notification/zen/ZenModeSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeSettings.java
@@ -194,7 +194,7 @@
String description = ZenModeConfig.getDescription(mContext, true, config, false);
if (description == null) {
- return mContext.getString(R.string.on);
+ return mContext.getString(R.string.zen_mode_sound_summary_on);
} else {
return mContext.getString(R.string.zen_mode_sound_summary_on_with_info,
description);
diff --git a/src/com/android/settings/notification/zen/ZenModeSettingsFooterPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeSettingsFooterPreferenceController.java
index 1964ccd..6a57441 100644
--- a/src/com/android/settings/notification/zen/ZenModeSettingsFooterPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeSettingsFooterPreferenceController.java
@@ -274,7 +274,7 @@
}
private int getAllowRes(boolean allow) {
- return allow ? R.string.on : R.string.off;
+ return allow ? R.string.zen_mode_sound_summary_on : R.string.switch_off_text;
}
@Override
diff --git a/src/com/android/settings/notification/zen/ZenRuleButtonsPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleButtonsPreferenceController.java
index 023a770..082b2a5 100644
--- a/src/com/android/settings/notification/zen/ZenRuleButtonsPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleButtonsPreferenceController.java
@@ -39,11 +39,11 @@
implements PreferenceControllerMixin {
public static final String KEY = "zen_action_buttons";
- private final PreferenceFragmentCompat mFragment;
+ private final ZenModeRuleSettingsBase mFragment;
private String mId;
private AutomaticZenRule mRule;
- public ZenRuleButtonsPreferenceController(Context context, PreferenceFragmentCompat fragment,
+ public ZenRuleButtonsPreferenceController(Context context, ZenModeRuleSettingsBase fragment,
Lifecycle lc) {
super(context, KEY, lc);
mFragment = fragment;
@@ -106,12 +106,7 @@
mBackend.removeZenRule(id);
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_ZEN_DELETE_RULE_OK);
- new SubSettingLauncher(mContext)
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
- .setDestination(ZenModeAutomationSettings.class.getName())
- .setSourceMetricsCategory(MetricsProto.MetricsEvent
- .NOTIFICATION_ZEN_MODE_AUTOMATION)
- .launch();
+ mFragment.onRuleRemoved();
}
});
}
diff --git a/src/com/android/settings/notification/zen/ZenRulePreference.java b/src/com/android/settings/notification/zen/ZenRulePreference.java
index ed65037..ed3033a 100644
--- a/src/com/android/settings/notification/zen/ZenRulePreference.java
+++ b/src/com/android/settings/notification/zen/ZenRulePreference.java
@@ -165,7 +165,7 @@
}
return (rule == null || !rule.isEnabled())
- ? mContext.getResources().getString(R.string.off)
- : mContext.getResources().getString(R.string.on);
+ ? mContext.getResources().getString(R.string.switch_off_text)
+ : mContext.getResources().getString(R.string.switch_on_text);
}
}
diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java
index 77949eb..60b8f88 100644
--- a/src/com/android/settings/panel/SettingsPanelActivity.java
+++ b/src/com/android/settings/panel/SettingsPanelActivity.java
@@ -29,12 +29,15 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
/**
@@ -144,9 +147,33 @@
window.setGravity(Gravity.BOTTOM);
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT);
+ setupNavigationBar();
mPanelFragment = new PanelFragment();
mPanelFragment.setArguments(new Bundle(mBundle));
fragmentManager.beginTransaction().add(R.id.main_content, mPanelFragment).commit();
}
}
+
+ /**
+ * Adjust bottom edge and color.
+ */
+ private void setupNavigationBar() {
+ // Extend the panel all the way to the bottom of the screen, as opposed to sitting on top of
+ // the navigation bar.
+ ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(),
+ (v, windowInsets) -> {
+ v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(), 0);
+ return windowInsets; // propagate down to panel layout root element
+ });
+
+ // When using 3-button navigation in light mode, the system picks white navigation buttons
+ // which are not sufficiently contrasted from the panel background.
+ WindowInsetsControllerCompat windowInsetsController =
+ ViewCompat.getWindowInsetsController(getWindow().getDecorView());
+
+ if (windowInsetsController != null) {
+ boolean forceNavigationButtonsDark = !Utils.isNightMode(this);
+ windowInsetsController.setAppearanceLightNavigationBars(forceNavigationButtonsDark);
+ }
+ }
}
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index 020b725..26e84be 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -21,12 +21,14 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.app.RemoteLockscreenValidationSession;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
+import android.os.Bundle;
import android.os.UserManager;
import android.util.Log;
@@ -147,7 +149,8 @@
private boolean mRemoteLockscreenValidation;
@Nullable private RemoteLockscreenValidationSession mRemoteLockscreenValidationSession;
@Nullable private ComponentName mRemoteLockscreenValidationServiceComponent;
- boolean mRequestGatekeeperPasswordHandle;
+ private boolean mRequestGatekeeperPasswordHandle;
+ private boolean mTaskOverlay;
public Builder(@NonNull Activity activity) {
mActivity = activity;
@@ -253,6 +256,14 @@
}
/**
+ * @param taskOverlay specifies whether the activity should be launched as a task overlay.
+ */
+ @NonNull public Builder setTaskOverlay(boolean taskOverlay) {
+ mTaskOverlay = taskOverlay;
+ return this;
+ }
+
+ /**
* @param foregroundOnly if true, the confirmation activity will be finished if it loses
* foreground.
*/
@@ -371,7 +382,8 @@
mBuilder.mCheckBoxLabel, mBuilder.mRemoteLockscreenValidation,
mBuilder.mRemoteLockscreenValidationSession,
mBuilder.mRemoteLockscreenValidationServiceComponent, mBuilder.mAllowAnyUserId,
- mBuilder.mForegroundOnly, mBuilder.mRequestGatekeeperPasswordHandle);
+ mBuilder.mForegroundOnly, mBuilder.mRequestGatekeeperPasswordHandle,
+ mBuilder.mTaskOverlay);
}
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@@ -381,7 +393,8 @@
@Nullable CharSequence checkboxLabel, boolean remoteLockscreenValidation,
@Nullable RemoteLockscreenValidationSession remoteLockscreenValidationSession,
@Nullable ComponentName remoteLockscreenValidationServiceComponent,
- boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle) {
+ boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle,
+ boolean taskOverlay) {
Optional<Class<?>> activityClass = determineAppropriateActivityClass(
returnCredentials, forceVerifyPath, userId, remoteLockscreenValidationSession);
if (activityClass.isEmpty()) {
@@ -392,7 +405,7 @@
returnCredentials, external, forceVerifyPath, userId, alternateButton,
checkboxLabel, remoteLockscreenValidation, remoteLockscreenValidationSession,
remoteLockscreenValidationServiceComponent, allowAnyUser, foregroundOnly,
- requestGatekeeperPasswordHandle);
+ requestGatekeeperPasswordHandle, taskOverlay);
}
private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
@@ -402,7 +415,8 @@
boolean remoteLockscreenValidation,
@Nullable RemoteLockscreenValidationSession remoteLockscreenValidationSession,
@Nullable ComponentName remoteLockscreenValidationServiceComponent,
- boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle) {
+ boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle,
+ boolean taskOverlay) {
final Intent intent = new Intent();
intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header);
@@ -434,28 +448,39 @@
Intent inIntent = mFragment != null ? mFragment.getActivity().getIntent() :
mActivity.getIntent();
copyInternalExtras(inIntent, intent);
+ Bundle launchOptions = createLaunchOptions(taskOverlay);
if (external) {
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
copyOptionalExtras(inIntent, intent);
if (mActivityResultLauncher != null) {
mActivityResultLauncher.launch(intent);
} else if (mFragment != null) {
- mFragment.startActivity(intent);
+ mFragment.startActivity(intent, launchOptions);
} else {
- mActivity.startActivity(intent);
+ mActivity.startActivity(intent, launchOptions);
}
} else {
if (mActivityResultLauncher != null) {
mActivityResultLauncher.launch(intent);
} else if (mFragment != null) {
- mFragment.startActivityForResult(intent, request);
+ mFragment.startActivityForResult(intent, request, launchOptions);
} else {
- mActivity.startActivityForResult(intent, request);
+ mActivity.startActivityForResult(intent, request, launchOptions);
}
}
return true;
}
+ private Bundle createLaunchOptions(boolean taskOverlay) {
+ if (!taskOverlay) {
+ return null;
+ }
+ ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchTaskId(mActivity.getTaskId());
+ options.setTaskOverlay(true /* taskOverlay */, true /* canResume */);
+ return options.toBundle();
+ }
+
private Optional<Integer> passwordQualityToLockTypes(int quality) {
switch (quality) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 328e440..fbcebb8 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -24,8 +24,6 @@
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PATTERN;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PIN;
-import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
-
import android.app.Activity;
import android.app.KeyguardManager;
import android.app.RemoteLockscreenValidationSession;
@@ -63,13 +61,6 @@
public class ConfirmDeviceCredentialActivity extends FragmentActivity {
public static final String TAG = ConfirmDeviceCredentialActivity.class.getSimpleName();
- /**
- * If the intent is sent from {@link com.android.systemui.keyguard.WorkLockActivityController}
- * then check for device policy management flags.
- */
- public static final String EXTRA_FROM_WORK_LOCK_ACTIVITY_CONTROLLER =
- "from_work_lock_activity_controller";
-
// The normal flow that apps go through
private static final int CREDENTIAL_NORMAL = 1;
// Unlocks the managed profile when the primary profile is unlocked
@@ -80,15 +71,6 @@
public static class InternalActivity extends ConfirmDeviceCredentialActivity {
}
- public static Intent createIntent(CharSequence title, CharSequence details) {
- Intent intent = new Intent();
- intent.setClassName(SETTINGS_PACKAGE_NAME,
- ConfirmDeviceCredentialActivity.class.getName());
- intent.putExtra(KeyguardManager.EXTRA_TITLE, title);
- intent.putExtra(KeyguardManager.EXTRA_DESCRIPTION, details);
- return intent;
- }
-
private BiometricFragment mBiometricFragment;
private DevicePolicyManager mDevicePolicyManager;
private LockPatternUtils mLockPatternUtils;
@@ -97,6 +79,7 @@
private Handler mHandler = new Handler(Looper.getMainLooper());
private Context mContext;
private boolean mCheckDevicePolicyManager;
+ private boolean mTaskOverlay;
private String mTitle;
private CharSequence mDetails;
@@ -186,6 +169,8 @@
boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction());
boolean remoteValidation =
KeyguardManager.ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL.equals(intent.getAction());
+ mTaskOverlay = isInternalActivity()
+ && intent.getBooleanExtra(KeyguardManager.EXTRA_FORCE_TASK_OVERLAY, false);
mUserId = UserHandle.myUserId();
if (isInternalActivity()) {
@@ -417,6 +402,12 @@
*/
private void showConfirmCredentials() {
boolean launched = false;
+ ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(this)
+ .setHeader(mTitle)
+ .setDescription(mDetails)
+ .setExternal(true)
+ .setUserId(mUserId)
+ .setTaskOverlay(mTaskOverlay);
// The only difference between CREDENTIAL_MANAGED and CREDENTIAL_NORMAL is that for
// CREDENTIAL_MANAGED, we launch the real confirm credential activity with an explicit
// but fake challenge value (0L). This will result in ConfirmLockPassword calling
@@ -429,22 +420,9 @@
// LockPatternChecker and LockPatternUtils. verifyPassword should be the only API to use,
// which optionally accepts a challenge.
if (mCredentialMode == CREDENTIAL_MANAGED) {
- final ChooseLockSettingsHelper.Builder builder =
- new ChooseLockSettingsHelper.Builder(this);
- launched = builder.setHeader(mTitle)
- .setDescription(mDetails)
- .setExternal(true)
- .setUserId(mUserId)
- .setForceVerifyPath(true)
- .show();
+ launched = builder.setForceVerifyPath(true).show();
} else if (mCredentialMode == CREDENTIAL_NORMAL) {
- final ChooseLockSettingsHelper.Builder builder =
- new ChooseLockSettingsHelper.Builder(this);
- launched = builder.setHeader(mTitle) // Show the title string in the header area
- .setDescription(mDetails)
- .setExternal(true)
- .setUserId(mUserId)
- .show();
+ launched = builder.show();
}
if (!launched) {
Log.d(TAG, "No pin/pattern/pass set");
diff --git a/src/com/android/settings/print/PrintSettingPreferenceController.java b/src/com/android/settings/print/PrintSettingPreferenceController.java
index 2a75e48..8714a11 100644
--- a/src/com/android/settings/print/PrintSettingPreferenceController.java
+++ b/src/com/android/settings/print/PrintSettingPreferenceController.java
@@ -117,7 +117,7 @@
final List<PrintServiceInfo> services =
mPrintManager.getPrintServices(PrintManager.ENABLED_SERVICES);
if (services == null || services.isEmpty()) {
- return mContext.getText(R.string.off);
+ return mContext.getText(R.string.print_settings_summary_no_service);
} else {
return StringUtil.getIcuPluralsString(mContext, services.size(),
R.string.print_settings_summary);
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index 46250c7..ed21b6f 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -204,9 +204,9 @@
preference.setPersistent(false);
if (service.isEnabled()) {
- preference.setSummary(getString(R.string.on));
+ preference.setSummary(getString(R.string.print_feature_state_on));
} else {
- preference.setSummary(getString(R.string.off));
+ preference.setSummary(getString(R.string.print_feature_state_off));
}
Drawable drawable = service.getResolveInfo().loadIcon(pm);
diff --git a/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java b/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java
index 20d7f58..1c5015f 100644
--- a/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java
+++ b/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java
@@ -23,6 +23,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.internal.app.LocaleHelper;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -53,9 +54,8 @@
Log.w(getLogTag(), "No selected language.");
return "";
}
- return Locale.forLanguageTag(selectedLanguage)
- .stripExtensions()
- .getDisplayName(Locale.forLanguageTag(selectedLanguage));
+ Locale locale = Locale.forLanguageTag(selectedLanguage);
+ return LocaleHelper.getDisplayName(locale.stripExtensions(), locale, true);
}
Log.w(getLogTag(), "Incorrect option : " + option);
return "";
diff --git a/src/com/android/settings/security/ScreenPinningPreferenceController.java b/src/com/android/settings/security/ScreenPinningPreferenceController.java
index dae6b8e..c72d018 100644
--- a/src/com/android/settings/security/ScreenPinningPreferenceController.java
+++ b/src/com/android/settings/security/ScreenPinningPreferenceController.java
@@ -38,7 +38,7 @@
public CharSequence getSummary() {
return Settings.System.getInt(mContext.getContentResolver(),
Settings.System.LOCK_TO_APP_ENABLED, 0) != 0
- ? mContext.getText(R.string.on)
- : mContext.getText(R.string.off);
+ ? mContext.getText(R.string.screen_pinning_switch_on_text)
+ : mContext.getText(R.string.screen_pinning_switch_off_text);
}
}
diff --git a/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt b/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt
index fbdde0b..7f7d8c5 100644
--- a/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt
@@ -16,17 +16,25 @@
package com.android.settings.spa.app.appinfo
+import android.app.AppOpsManager
import android.content.Context
import android.content.pm.ApplicationInfo
import android.os.UserManager
+import android.widget.Toast
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.android.settings.R
import com.android.settings.Utils
+import com.android.settings.applications.appinfo.AppInfoDashboardFragment
import com.android.settingslib.spa.widget.scaffold.MoreOptionsAction
+import com.android.settingslib.spaprivileged.framework.common.appOpsManager
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
import com.android.settingslib.spaprivileged.framework.common.userManager
import com.android.settingslib.spaprivileged.model.app.IPackageManagers
@@ -35,6 +43,8 @@
import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
import com.android.settingslib.spaprivileged.template.scaffold.RestrictedMenuItem
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withContext
@Composable
@@ -44,13 +54,11 @@
packageManagers: IPackageManagers = PackageManagers,
) {
val state = app.produceState(packageManagers).value ?: return
- when {
- // We don't allow uninstalling update for DO/PO if it's a system app, because it will clear
- // data on all users. We also don't allow uninstalling for all users if it's DO/PO for any
- // user.
- state.isProfileOrDeviceOwner -> return
- !state.shownUninstallUpdates && !state.shownUninstallForAllUsers -> return
- }
+ var restrictedSettingsAllowed by rememberSaveable { mutableStateOf(false) }
+ if (!state.shownUninstallUpdates &&
+ !state.shownUninstallForAllUsers &&
+ !(state.shouldShowAccessRestrictedSettings && !restrictedSettingsAllowed)
+ ) return
MoreOptionsAction {
val restrictions =
Restrictions(userId = app.userId, keys = listOf(UserManager.DISALLOW_APPS_CONTROL))
@@ -70,13 +78,37 @@
packageInfoPresenter.startUninstallActivity(forAllUsers = true)
}
}
+ if (state.shouldShowAccessRestrictedSettings && !restrictedSettingsAllowed) {
+ MenuItem(text = stringResource(R.string.app_restricted_settings_lockscreen_title)) {
+ app.allowRestrictedSettings(packageInfoPresenter.context) {
+ restrictedSettingsAllowed = true
+ }
+ }
+ }
+ }
+}
+
+private fun ApplicationInfo.allowRestrictedSettings(context: Context, onSuccess: () -> Unit) {
+ AppInfoDashboardFragment.showLockScreen(context) {
+ context.appOpsManager.setMode(
+ AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
+ uid,
+ packageName,
+ AppOpsManager.MODE_ALLOWED,
+ )
+ onSuccess()
+ val toastString = context.getString(
+ R.string.toast_allows_restricted_settings_successfully,
+ loadLabel(context.packageManager),
+ )
+ Toast.makeText(context, toastString, Toast.LENGTH_LONG).show()
}
}
private data class AppInfoSettingsMoreOptionsState(
- val isProfileOrDeviceOwner: Boolean,
val shownUninstallUpdates: Boolean,
val shownUninstallForAllUsers: Boolean,
+ val shouldShowAccessRestrictedSettings: Boolean,
)
@Composable
@@ -86,20 +118,40 @@
val context = LocalContext.current
return produceState<AppInfoSettingsMoreOptionsState?>(initialValue = null, this) {
withContext(Dispatchers.IO) {
- value = AppInfoSettingsMoreOptionsState(
- isProfileOrDeviceOwner = Utils.isProfileOrDeviceOwner(
- context.userManager, context.devicePolicyManager, packageName
- ),
- shownUninstallUpdates = isShowUninstallUpdates(context),
- shownUninstallForAllUsers = isShowUninstallForAllUsers(
- userManager = context.userManager,
- packageManagers = packageManagers,
- ),
- )
+ value = getMoreOptionsState(context, packageManagers)
}
}
}
+private suspend fun ApplicationInfo.getMoreOptionsState(
+ context: Context,
+ packageManagers: IPackageManagers,
+) = coroutineScope {
+ val shownUninstallUpdatesDeferred = async {
+ isShowUninstallUpdates(context)
+ }
+ val shownUninstallForAllUsersDeferred = async {
+ isShowUninstallForAllUsers(
+ userManager = context.userManager,
+ packageManagers = packageManagers,
+ )
+ }
+ val shouldShowAccessRestrictedSettingsDeferred = async {
+ shouldShowAccessRestrictedSettings(context.appOpsManager)
+ }
+ val isProfileOrDeviceOwner =
+ Utils.isProfileOrDeviceOwner(context.userManager, context.devicePolicyManager, packageName)
+ AppInfoSettingsMoreOptionsState(
+ // We don't allow uninstalling update for DO/PO if it's a system app, because it will clear
+ // data on all users.
+ shownUninstallUpdates = !isProfileOrDeviceOwner && shownUninstallUpdatesDeferred.await(),
+ // We also don't allow uninstalling for all users if it's DO/PO for any user.
+ shownUninstallForAllUsers =
+ !isProfileOrDeviceOwner && shownUninstallForAllUsersDeferred.await(),
+ shouldShowAccessRestrictedSettings = shouldShowAccessRestrictedSettingsDeferred.await(),
+ )
+}
+
private fun ApplicationInfo.isShowUninstallUpdates(context: Context): Boolean =
isUpdatedSystemApp && context.userManager.isUserAdmin(userId) &&
!context.resources.getBoolean(R.bool.config_disable_uninstall_update)
@@ -116,3 +168,8 @@
): Boolean = userManager.aliveUsers
.filter { it.id != userId }
.any { packageManagers.isPackageInstalledAsUser(packageName, it.id) }
+
+private fun ApplicationInfo.shouldShowAccessRestrictedSettings(appOpsManager: AppOpsManager) =
+ appOpsManager.noteOpNoThrow(
+ AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, uid, packageName, null, null
+ ) == AppOpsManager.MODE_IGNORED
diff --git a/src/com/android/settings/spa/core/instrumentation/SpaLogProvider.kt b/src/com/android/settings/spa/core/instrumentation/SpaLogProvider.kt
index 9b3e2d6..31d5797 100644
--- a/src/com/android/settings/spa/core/instrumentation/SpaLogProvider.kt
+++ b/src/com/android/settings/spa/core/instrumentation/SpaLogProvider.kt
@@ -92,8 +92,11 @@
return null
}
- fun getAction(): Int {
- return event.action
+ fun getAction(): Int = when (event) {
+ LogEvent.PAGE_ENTER -> SettingsEnums.PAGE_VISIBLE
+ LogEvent.PAGE_LEAVE -> SettingsEnums.PAGE_HIDE
+ LogEvent.ENTRY_CLICK -> SettingsEnums.ACTION_SETTINGS_TILE_CLICK
+ LogEvent.ENTRY_SWITCH -> SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE
}
//TODO(b/253979024): Will be implemented in subsequent CLs.
diff --git a/src/com/android/settings/widget/SwitchBar.java b/src/com/android/settings/widget/SwitchBar.java
index 7d47457..ad0294c 100644
--- a/src/com/android/settings/widget/SwitchBar.java
+++ b/src/com/android/settings/widget/SwitchBar.java
@@ -134,7 +134,7 @@
lp.setMarginEnd(switchBarMarginEnd);
setBackgroundColor(mBackgroundColor);
- setSwitchBarText(R.string.on, R.string.off);
+ setSwitchBarText(R.string.switch_on_text, R.string.switch_off_text);
addOnSwitchChangeListener(
(switchView, isChecked) -> setTextViewLabelAndBackground(isChecked));
diff --git a/src/com/android/settings/wifi/WifiSummaryUpdater.java b/src/com/android/settings/wifi/WifiSummaryUpdater.java
index 030db5a..93bbe0f 100644
--- a/src/com/android/settings/wifi/WifiSummaryUpdater.java
+++ b/src/com/android/settings/wifi/WifiSummaryUpdater.java
@@ -87,7 +87,7 @@
@Override
public String getSummary() {
if (!mWifiTracker.enabled) {
- return mContext.getString(R.string.off);
+ return mContext.getString(R.string.switch_off_text);
}
if (!mWifiTracker.connected) {
return mContext.getString(R.string.disconnected);
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettings.java b/src/com/android/settings/wifi/calling/WifiCallingSettings.java
index 8926696..42ce1b1 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettings.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettings.java
@@ -257,7 +257,8 @@
for (SubscriptionInfo subInfo : subInfoList) {
int subId = subInfo.getSubscriptionId();
try {
- if (queryImsState(subId).isWifiCallingProvisioned()) {
+ if (MobileNetworkUtils.isWifiCallingEnabled(getContext(), subId,
+ queryImsState(subId), null)) {
selectedList.add(subInfo);
}
} catch (Exception exception) {}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java
index da44228..3976056 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java
@@ -16,7 +16,6 @@
package com.android.settings.accessibility;
-import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
@@ -93,13 +92,4 @@
final String gestureValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_GESTURE);
assertThat(mListPreference.getValue()).isEqualTo(gestureValue);
}
-
- @Test
- public void onPreferenceChange_a11yBtnModeFloatingMenu_floatingMenuValue() {
- final String floatingMenuValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
-
- mController.onPreferenceChange(mListPreference, floatingMenuValue);
-
- assertThat(mListPreference.getValue()).isEqualTo(floatingMenuValue);
- }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceControllerTest.java
index 4510d84..53a3397 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceControllerTest.java
@@ -16,7 +16,6 @@
package com.android.settings.accessibility;
-import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
@@ -94,13 +93,4 @@
final String navigationBarValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
assertThat(mListPreference.getValue()).isEqualTo(navigationBarValue);
}
-
- @Test
- public void onPreferenceChange_a11yBtnModeFloatingMenu_floatingMenuValue() {
- final String floatingMenuValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
-
- mController.onPreferenceChange(mListPreference, floatingMenuValue);
-
- assertThat(mListPreference.getValue()).isEqualTo(floatingMenuValue);
- }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index 16d1483..c4609d6 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
@@ -194,7 +194,7 @@
mServiceInfo, SERVICE_ENABLED);
assertThat(summary).isEqualTo(
- mContext.getString(R.string.on));
+ mContext.getString(R.string.accessibility_summary_state_enabled));
}
@Test
@@ -205,13 +205,13 @@
mServiceInfo, SERVICE_DISABLED);
assertThat(summary).isEqualTo(
- mContext.getString(R.string.off));
+ mContext.getString(R.string.accessibility_summary_state_disabled));
}
@Test
public void getServiceSummary_enableServiceAndHasSummary_showsEnabledSummary() {
final String service_enabled = mContext.getString(
- R.string.on);
+ R.string.accessibility_summary_state_enabled);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
@@ -225,7 +225,7 @@
@Test
public void getServiceSummary_disableServiceAndHasSummary_showsCombineDisabledSummary() {
final String service_disabled = mContext.getString(
- R.string.off);
+ R.string.accessibility_summary_state_disabled);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java
index c89d526..83c5bc2 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java
@@ -80,7 +80,7 @@
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY);
assertThat(result)
- .isEqualTo(mContext.getText(R.string.on));
+ .isEqualTo(mContext.getText(R.string.accessibility_feature_state_on));
}
@Test
@@ -90,7 +90,7 @@
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY);
assertThat(result)
- .isEqualTo(mContext.getText(R.string.off));
+ .isEqualTo(mContext.getText(R.string.accessibility_feature_state_off));
}
@Test
@@ -98,7 +98,7 @@
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY);
assertThat(result)
- .isEqualTo(mContext.getText(R.string.off));
+ .isEqualTo(mContext.getText(R.string.accessibility_feature_state_off));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/AutoclickPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AutoclickPreferenceControllerTest.java
index 106b617..aaaf303 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AutoclickPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AutoclickPreferenceControllerTest.java
@@ -60,7 +60,7 @@
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, OFF);
assertThat(mController.getSummary())
- .isEqualTo(mContext.getText(R.string.off));
+ .isEqualTo(mContext.getText(R.string.accessibility_feature_state_off));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptioningFontSizeControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptioningFontSizeControllerTest.java
index c20cf5d..8aeb37e 100644
--- a/tests/robotests/src/com/android/settings/accessibility/CaptioningFontSizeControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/CaptioningFontSizeControllerTest.java
@@ -64,6 +64,7 @@
mPreference = new ListPreference(mContext);
mPreference.setEntries(R.array.captioning_font_size_selector_titles);
mPreference.setEntryValues(R.array.captioning_font_size_selector_values);
+ mPreference.setSummary("%s");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
@@ -76,28 +77,19 @@
}
@Test
- public void displayPreference_byDefault_shouldReturnDefault() {
- mController.displayPreference(mScreen);
+ public void updateState_byDefault_shouldReturnDefault() {
+ mController.updateState(mPreference);
- assertThat(mPreference.getEntry().toString()).isEqualTo("Medium");
+ assertThat(mPreference.getSummary().toString()).isEqualTo("Medium");
}
@Test
- public void displayPreference_bySmallValue_shouldReturnSmall() {
+ public void updateState_bySmallValue_shouldReturnSmall() {
mShadowCaptioningManager.setFontScale(0.5f);
- mController.displayPreference(mScreen);
+ mController.updateState(mPreference);
- assertThat(mPreference.getEntry().toString()).isEqualTo("Small");
- }
-
- @Test
- public void onPreferenceChange_shouldReturnSmall() {
- mController.displayPreference(mScreen);
-
- mController.onPreferenceChange(mPreference, "0.5");
-
- assertThat(mPreference.getEntry().toString()).isEqualTo("Small");
+ assertThat(mPreference.getSummary().toString()).isEqualTo("Small");
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptioningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptioningPreferenceControllerTest.java
index 9fb7ea4..c44bed1 100644
--- a/tests/robotests/src/com/android/settings/accessibility/CaptioningPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/CaptioningPreferenceControllerTest.java
@@ -58,7 +58,7 @@
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, ON);
assertThat(mController.getSummary()).isEqualTo(
- mContext.getText(R.string.on));
+ mContext.getText(R.string.accessibility_feature_state_on));
}
@Test
@@ -67,6 +67,6 @@
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF);
assertThat(mController.getSummary()).isEqualTo(
- mContext.getText(R.string.off));
+ mContext.getText(R.string.accessibility_feature_state_off));
}
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptioningTypefaceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptioningTypefaceControllerTest.java
index 0ca455c..4d33fb3 100644
--- a/tests/robotests/src/com/android/settings/accessibility/CaptioningTypefaceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/CaptioningTypefaceControllerTest.java
@@ -64,6 +64,7 @@
mPreference = new ListPreference(mContext);
mPreference.setEntries(R.array.captioning_typeface_selector_titles);
mPreference.setEntryValues(R.array.captioning_typeface_selector_values);
+ mPreference.setSummary("%s");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
@@ -76,29 +77,20 @@
}
@Test
- public void displayPreference_byDefault_shouldReturnDefault() {
- mController.displayPreference(mScreen);
+ public void updateState_byDefault_shouldReturnDefault() {
+ mController.updateState(mPreference);
- assertThat(mPreference.getEntry().toString()).isEqualTo("Default");
+ assertThat(mPreference.getSummary().toString()).isEqualTo("Default");
}
@Test
- public void displayPreference_bySerif_shouldReturnSerif() {
+ public void updateState_bySerif_shouldReturnSerif() {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, "serif");
- mController.displayPreference(mScreen);
+ mController.updateState(mPreference);
- assertThat(mPreference.getEntry().toString()).isEqualTo("Serif");
- }
-
- @Test
- public void onPreferenceChange_bySerif_shouldReturnSerif() {
- mController.displayPreference(mScreen);
-
- mController.onPreferenceChange(mPreference, "serif");
-
- assertThat(mPreference.getEntry().toString()).isEqualTo("Serif");
+ assertThat(mPreference.getSummary().toString()).isEqualTo("Serif");
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/ColorInversionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/ColorInversionPreferenceControllerTest.java
index 47cfdaf..e034498 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ColorInversionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ColorInversionPreferenceControllerTest.java
@@ -52,7 +52,7 @@
DISPLAY_INVERSION_ENABLED, State.ON);
assertThat(mController.getSummary().toString().contains(
- mContext.getText(R.string.on))).isTrue();
+ mContext.getText(R.string.accessibility_feature_state_on))).isTrue();
}
@Test
@@ -61,7 +61,7 @@
DISPLAY_INVERSION_ENABLED, State.OFF);
assertThat(mController.getSummary().toString().contains(
- mContext.getText(R.string.off))).isTrue();
+ mContext.getText(R.string.accessibility_feature_state_off))).isTrue();
}
@Retention(RetentionPolicy.SOURCE)
diff --git a/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
index c02131b..1a00cc1 100644
--- a/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
@@ -50,7 +50,7 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, ON);
assertThat(mController.getSummary().toString().contains(
- mContext.getText(R.string.on))).isTrue();
+ mContext.getText(R.string.accessibility_feature_state_on))).isTrue();
}
@Test
@@ -59,6 +59,6 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF);
assertThat(mController.getSummary().toString().contains(
- mContext.getText(R.string.off))).isTrue();
+ mContext.getText(R.string.accessibility_feature_state_off))).isTrue();
}
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
index 8ccde4f..c7d70e0 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
@@ -64,13 +64,13 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.on));
+ .isEqualTo(mContext.getString(R.string.accessibility_feature_state_on));
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.off));
+ .isEqualTo(mContext.getString(R.string.accessibility_feature_state_off));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
index b2427c6..83fe496 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
@@ -89,13 +89,13 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, ON);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getText(R.string.on));
+ .isEqualTo(mContext.getText(R.string.accessibility_feature_state_on));
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, OFF);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getText(R.string.off));
+ .isEqualTo(mContext.getText(R.string.accessibility_feature_state_off));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
index c266b56..a045dea 100644
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
@@ -92,7 +92,7 @@
controller.updateState(mPreference);
assertThat(mPreference.getSummary().toString()).isEqualTo(
- mContext.getString(R.string.on));
+ mContext.getString(R.string.accessibility_vibration_settings_state_on));
}
@Test
@@ -103,7 +103,7 @@
controller.updateState(mPreference);
assertThat(mPreference.getSummary().toString()).isEqualTo(
- mContext.getString(R.string.on));
+ mContext.getString(R.string.accessibility_vibration_settings_state_on));
}
@Test
@@ -114,7 +114,7 @@
controller.updateState(mPreference);
assertThat(mPreference.getSummary().toString()).isEqualTo(
- mContext.getString(R.string.off));
+ mContext.getString(R.string.accessibility_vibration_settings_state_off));
}
private VibrationPreferenceController createPreferenceController() {
diff --git a/tests/robotests/src/com/android/settings/backup/BackupDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/backup/BackupDataPreferenceControllerTest.java
index 98f48f5..1a6537b 100644
--- a/tests/robotests/src/com/android/settings/backup/BackupDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/backup/BackupDataPreferenceControllerTest.java
@@ -73,7 +73,7 @@
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.on));
+ .isEqualTo(mContext.getString(R.string.accessibility_feature_state_on));
}
@Test
@@ -83,7 +83,7 @@
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.off));
+ .isEqualTo(mContext.getString(R.string.accessibility_feature_state_off));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java b/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java
index 6e922dd..b6ef32c 100644
--- a/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java
+++ b/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java
@@ -90,7 +90,7 @@
String backupSummary = mBackupSettingsHelper.getSummary();
- assertThat(backupSummary).isEqualTo(mContext.getString(R.string.on));
+ assertThat(backupSummary).isEqualTo(mContext.getString(R.string.backup_summary_state_on));
}
@Test
@@ -100,7 +100,7 @@
String backupSummary = mBackupSettingsHelper.getSummary();
- assertThat(backupSummary).isEqualTo(mContext.getString(R.string.off));
+ assertThat(backupSummary).isEqualTo(mContext.getString(R.string.backup_summary_state_off));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
index 2886194..2232960 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
@@ -43,6 +43,7 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
+import android.graphics.Rect;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.SensorProperties;
import android.hardware.fingerprint.FingerprintManager;
@@ -58,6 +59,7 @@
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -81,6 +83,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
@RunWith(RobolectricTestRunner.class)
public class FingerprintEnrollEnrollingTest {
@@ -246,6 +249,78 @@
}
@Test
+ public void fingerprintUdfpsOverlayEnrollment_checkViewOverlapPortrait() {
+ FeatureFlagUtils.setEnabled(mContext,
+ FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
+ when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_90);
+ initializeActivityFor(TYPE_UDFPS_OPTICAL);
+
+ final GlifLayout defaultLayout = mActivity.findViewById(R.id.setup_wizard_layout);
+ final TextView headerTextView = defaultLayout.getHeaderTextView();
+ final TextView descriptionTextView = defaultLayout.getDescriptionTextView();
+ final FrameLayout lottieAnimationContainer = mActivity.findViewById(R.id.layout_container);
+ final UdfpsEnrollView udfpsEnrollView =
+ defaultLayout.findViewById(R.id.udfps_animation_view);
+
+ final int[] headerTextViewPosition = new int[2];
+ final int[] descriptionTextViewPosition = new int[2];
+ final int[] lottieAnimationPosition = new int[2];
+ final int[] udfpsEnrollViewPosition = new int[2];
+ final AtomicReference<Rect> rectHeaderTextView = new AtomicReference<>(
+ new Rect(0, 0, 0, 0));
+ final AtomicReference<Rect> rectDescriptionTextView =
+ new AtomicReference<>(new Rect(0, 0, 0, 0));
+ final AtomicReference<Rect> rectLottieAnimationView = new AtomicReference<>(
+ new Rect(0, 0, 0, 0));
+ final AtomicReference<Rect> rectUdfpsEnrollView = new AtomicReference<>(
+ new Rect(0, 0, 0, 0));
+
+ headerTextView.getViewTreeObserver().addOnDrawListener(() -> {
+ headerTextView.getLocationOnScreen(headerTextViewPosition);
+ rectHeaderTextView.set(new Rect(headerTextViewPosition[0], headerTextViewPosition[1],
+ headerTextViewPosition[0] + headerTextView.getWidth(),
+ headerTextViewPosition[1] + headerTextView.getHeight()));
+ });
+
+ descriptionTextView.getViewTreeObserver().addOnDrawListener(() -> {
+ descriptionTextView.getLocationOnScreen(descriptionTextViewPosition);
+ rectDescriptionTextView.set(new Rect(descriptionTextViewPosition[0],
+ descriptionTextViewPosition[1], descriptionTextViewPosition[0]
+ + descriptionTextView.getWidth(), descriptionTextViewPosition[1]
+ + descriptionTextView.getHeight()));
+
+ });
+
+ udfpsEnrollView.getViewTreeObserver().addOnDrawListener(() -> {
+ udfpsEnrollView.getLocationOnScreen(udfpsEnrollViewPosition);
+ rectUdfpsEnrollView.set(new Rect(udfpsEnrollViewPosition[0],
+ udfpsEnrollViewPosition[1], udfpsEnrollViewPosition[0]
+ + udfpsEnrollView.getWidth(), udfpsEnrollViewPosition[1]
+ + udfpsEnrollView.getHeight()));
+ });
+
+ lottieAnimationContainer.getViewTreeObserver().addOnDrawListener(() -> {
+ lottieAnimationContainer.getLocationOnScreen(lottieAnimationPosition);
+ rectLottieAnimationView.set(new Rect(lottieAnimationPosition[0],
+ lottieAnimationPosition[1], lottieAnimationPosition[0]
+ + lottieAnimationContainer.getWidth(), lottieAnimationPosition[1]
+ + lottieAnimationContainer.getHeight()));
+ });
+
+ // Check if the HeaderTextView and DescriptionTextView overlapped
+ assertThat(rectHeaderTextView.get()
+ .intersect(rectDescriptionTextView.get())).isFalse();
+
+ // Check if the DescriptionTextView and Lottie animation overlapped
+ assertThat(rectDescriptionTextView.get()
+ .intersect(rectLottieAnimationView.get())).isFalse();
+
+ // Check if the Lottie animation and UDSPFEnrollView overlapped
+ assertThat(rectLottieAnimationView.get()
+ .intersect(rectUdfpsEnrollView.get())).isFalse();
+ }
+
+ @Test
public void forwardEnrollProgressEvents() {
FeatureFlagUtils.setEnabled(mContext,
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java
index b2da579..9bd4f1b 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java
@@ -26,8 +26,6 @@
import androidx.test.core.app.ApplicationProvider;
-import com.android.settings.R;
-import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -44,8 +42,6 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import java.util.List;
-
/** Tests for {@link BluetoothDetailsAudioRoutingFragment}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothUtils.class})
@@ -92,17 +88,6 @@
assertThat(mFragment.mCachedDevice.getAddress()).isEqualTo(TEST_ADDRESS);
}
- @Test
- public void getNonIndexableKeys_existInXmlLayout() {
- final List<String> niks = BluetoothDetailsAudioRoutingFragment.SEARCH_INDEX_DATA_PROVIDER
- .getNonIndexableKeys(mContext);
- final List<String> keys =
- XmlTestUtils.getKeysFromPreferenceXml(mContext,
- R.xml.bluetooth_audio_routing_fragment);
-
- assertThat(keys).containsAtLeastElementsIn(niks);
- }
-
private void setupEnvironment() {
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java
index dcd45ce..2aca4a3 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java
@@ -132,7 +132,7 @@
mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF);
- verify(mListener).onSummaryChanged(mContext.getString(R.string.off));
+ verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled));
}
@Test
@@ -197,12 +197,12 @@
mShadowBluetoothAdapter.setEnabled(false);
mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF);
- verify(mListener).onSummaryChanged(mContext.getString(R.string.off));
+ verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled));
// Turning ON means not enabled
mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_TURNING_ON);
// There should still be only one invocation of disabled message
- verify(mListener).onSummaryChanged(mContext.getString(R.string.off));
+ verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled));
mShadowBluetoothAdapter.setEnabled(true);
mDeviceConnected[0] = false;
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java
index c894716..8acb81c 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java
@@ -92,13 +92,13 @@
public void getSummary_nfcOn_shouldProvideOnSummary() {
mShadowNfcAdapter.setEnabled(true);
assertThat(mController.getSummary().toString()).contains(
- mContext.getString(R.string.on));
+ mContext.getString(R.string.switch_on_text));
}
@Test
public void getSummary_nfcOff_shouldProvideOffSummary() {
mShadowNfcAdapter.setEnabled(false);
assertThat(mController.getSummary().toString()).contains(
- mContext.getString(R.string.off));
+ mContext.getString(R.string.switch_off_text));
}
}
diff --git a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
index 4fa0003..0229173 100644
--- a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
@@ -109,7 +109,7 @@
mController.setChecked(true);
assertThat(mController.getSummary())
- .isEqualTo(mContext.getText(R.string.on));
+ .isEqualTo(mContext.getText(R.string.auto_brightness_summary_on));
}
@Test
@@ -117,7 +117,7 @@
mController.setChecked(false);
assertThat(mController.getSummary())
- .isEqualTo(mContext.getText(R.string.off));
+ .isEqualTo(mContext.getText(R.string.auto_brightness_summary_off));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
index c1a98ef..0e7a86f 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
@@ -86,9 +86,9 @@
doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName();
doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
Manifest.permission.CAMERA, PACKAGE_NAME);
- when(mContext.getString(R.string.off))
+ when(mContext.getString(R.string.auto_rotate_option_off))
.thenReturn("Off");
- when(mContext.getString(R.string.on))
+ when(mContext.getString(R.string.auto_rotate_option_on))
.thenReturn("On");
when(mContext.getString(R.string.auto_rotate_option_face_based))
.thenReturn("On - Face-based");
diff --git a/tests/robotests/src/com/android/settings/dream/DreamHomeControlsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/dream/DreamHomeControlsPreferenceControllerTest.java
new file mode 100644
index 0000000..452604c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/dream/DreamHomeControlsPreferenceControllerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 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.dream;
+
+import static com.android.settingslib.dream.DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.util.ArraySet;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settingslib.dream.DreamBackend;
+
+import org.junit.After;
+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.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowContentResolver;
+import org.robolectric.shadows.ShadowSettings;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowSettings.ShadowSecure.class})
+public class DreamHomeControlsPreferenceControllerTest {
+
+ private Context mContext;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+ private DreamHomeControlsPreferenceController mController;
+ private SwitchPreference mPreference;
+ private DreamBackend mBackend;
+ private ShadowContentResolver mShadowContentResolver;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = ApplicationProvider.getApplicationContext();
+ mShadowContentResolver = Shadow.extract(mContext.getContentResolver());
+ mBackend = new DreamBackend(mContext);
+ mController = new DreamHomeControlsPreferenceController(mContext, "key", mBackend);
+ mPreference = new SwitchPreference(mContext);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
+ mController.displayPreference(mScreen);
+
+ // Make home controls supported by default
+ mBackend.setSupportedComplications(
+ new ArraySet<>(new Integer[]{COMPLICATION_TYPE_HOME_CONTROLS}));
+ }
+
+ @After
+ public void tearDown() {
+ ShadowSettings.ShadowSecure.reset();
+ }
+
+ @Test
+ public void testSetChecked_setTrue_enablesSetting() {
+ mBackend.setHomeControlsEnabled(false);
+ assertThat(mBackend.getEnabledComplications())
+ .doesNotContain(COMPLICATION_TYPE_HOME_CONTROLS);
+
+ mController.setChecked(true);
+ assertThat(mBackend.getEnabledComplications())
+ .contains(COMPLICATION_TYPE_HOME_CONTROLS);
+ }
+
+ @Test
+ public void testSetChecked_setFalse_disablesSetting() {
+ mBackend.setHomeControlsEnabled(true);
+ assertThat(mBackend.getEnabledComplications())
+ .contains(COMPLICATION_TYPE_HOME_CONTROLS);
+
+ mController.setChecked(false);
+ assertThat(mBackend.getEnabledComplications())
+ .doesNotContain(COMPLICATION_TYPE_HOME_CONTROLS);
+ }
+
+ @Test
+ public void testIsChecked_returnsFalse() {
+ mBackend.setHomeControlsEnabled(false);
+ assertThat(mController.isChecked()).isFalse();
+ }
+
+ @Test
+ public void testIsChecked_returnsTrue() {
+ mBackend.setHomeControlsEnabled(true);
+ assertThat(mBackend.getEnabledComplications())
+ .contains(COMPLICATION_TYPE_HOME_CONTROLS);
+ assertThat(mController.isChecked()).isTrue();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
index 58c69b1..f18228b 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
@@ -88,7 +88,7 @@
Locale.setDefault(new Locale("en_US"));
org.robolectric.shadows.ShadowSettings.set24HourTimeFormat(false);
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
- DataProcessor.sTestSystemAppsSet = Set.of();
+ DataProcessor.sTestSystemAppsPackageNames = Set.of();
mFeatureFactory = FakeFeatureFactory.setupForTest();
mContext = spy(RuntimeEnvironment.application);
doReturn(mContext).when(mContext).getApplicationContext();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java
index 0985fe7..27539a5 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java
@@ -63,7 +63,7 @@
createBatteryDiffEntry(mContext, /*consumePower=*/ 0, /*isHidden=*/ true);
final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
- hiddenDiffEntry, List.of(), Set.of());
+ hiddenDiffEntry, List.of(), Set.of(), Set.of());
assertThat(needsCombineInSystemApp).isTrue();
}
@@ -77,7 +77,7 @@
mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
- batteryDiffEntry, List.of(), Set.of(ConvertUtils.FAKE_PACKAGE_NAME));
+ batteryDiffEntry, List.of(), Set.of(ConvertUtils.FAKE_PACKAGE_NAME), Set.of());
assertThat(needsCombineInSystemApp).isTrue();
}
@@ -91,7 +91,7 @@
mApplicationInfo.flags = 0;
final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
- batteryDiffEntry, List.of(), Set.of());
+ batteryDiffEntry, List.of(), Set.of(), Set.of());
assertThat(needsCombineInSystemApp).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java
index 395f655..37f05bc 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java
@@ -107,7 +107,7 @@
mBatteryDiffEntry = spy(mBatteryDiffEntry);
mBatteryUsageBreakdownController.mBatteryDiffData =
new BatteryDiffData(mContext, Arrays.asList(mBatteryDiffEntry), Arrays.asList(),
- Set.of(), /* isAccumulated= */ false);
+ Set.of(), Set.of(), /* isAccumulated= */ false);
// Adds fake testing data.
BatteryDiffEntry.sResourceCache.put(
"fakeBatteryDiffEntryKey",
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
index 67c972f..aab91e0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
@@ -82,8 +82,8 @@
doReturn(66).when(mIntent).getIntExtra(eq(BatteryManager.EXTRA_LEVEL), anyInt());
mDataProcessManager = new DataProcessManager(
- mContext, /*handler=*/ null, /*callbackFunction=*/ null,
- /*hourlyBatteryLevelsPerDay=*/ new ArrayList<>(),
+ mContext, /*handler=*/ null, /*rawStartTimestamp=*/ 0L,
+ /*callbackFunction=*/ null, /*hourlyBatteryLevelsPerDay=*/ new ArrayList<>(),
/*batteryHistoryMap=*/ new HashMap<>());
}
@@ -174,7 +174,7 @@
DatabaseUtils.sFakeAppUsageEventSupplier = () -> cursor;
final DataProcessManager dataProcessManager = new DataProcessManager(
- mContext, /*handler=*/ null, /*callbackFunction=*/ null,
+ mContext, /*handler=*/ null, /*rawStartTimestamp=*/ 2L, /*callbackFunction=*/ null,
hourlyBatteryLevelsPerDay, /*batteryHistoryMap=*/ new HashMap<>());
dataProcessManager.start();
@@ -250,42 +250,6 @@
}
@Test
- public void getStartTimestampOfBatteryLevelData_returnExpectedResult() {
- final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay =
- new ArrayList<>();
- final List<Long> timestamps = new ArrayList<>();
- timestamps.add(101L);
- timestamps.add(1001L);
- final List<Integer> levels = new ArrayList<>();
- levels.add(1);
- levels.add(2);
- hourlyBatteryLevelsPerDay.add(null);
- hourlyBatteryLevelsPerDay.add(
- new BatteryLevelData.PeriodBatteryLevelData(timestamps, levels));
-
- final DataProcessManager dataProcessManager = new DataProcessManager(
- mContext, /*handler=*/ null, /*callbackFunction=*/ null,
- hourlyBatteryLevelsPerDay, /*batteryHistoryMap=*/ null);
-
- assertThat(dataProcessManager.getStartTimestampOfBatteryLevelData()).isEqualTo(101);
- }
-
- @Test
- public void getStartTimestampOfBatteryLevelData_emptyLevels_returnZero() {
- final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay =
- new ArrayList<>();
- hourlyBatteryLevelsPerDay.add(null);
- hourlyBatteryLevelsPerDay.add(
- new BatteryLevelData.PeriodBatteryLevelData(new ArrayList<>(), new ArrayList<>()));
-
- final DataProcessManager dataProcessManager = new DataProcessManager(
- mContext, /*handler=*/ null, /*callbackFunction=*/ null,
- hourlyBatteryLevelsPerDay, /*batteryHistoryMap=*/ null);
-
- assertThat(dataProcessManager.getStartTimestampOfBatteryLevelData()).isEqualTo(0);
- }
-
- @Test
public void getBatteryLevelData_emptyHistoryMap_returnNull() {
assertThat(DataProcessManager.getBatteryLevelData(
mContext,
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
index 1d3f72b..aa15472 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
@@ -93,7 +93,7 @@
mFeatureFactory = FakeFeatureFactory.setupForTest();
mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider;
- DataProcessor.sTestSystemAppsSet = Set.of();
+ DataProcessor.sTestSystemAppsPackageNames = Set.of();
DataProcessor.sUsageStatsManager = mUsageStatsManager;
doReturn(mIntent).when(mContext).registerReceiver(
isA(BroadcastReceiver.class), isA(IntentFilter.class));
@@ -250,7 +250,7 @@
final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>> periodMap =
DataProcessor.generateAppUsagePeriodMap(
- hourlyBatteryLevelsPerDay, appUsageEventList);
+ 14400000L, hourlyBatteryLevelsPerDay, appUsageEventList);
assertThat(periodMap).hasSize(3);
// Day 1
@@ -288,7 +288,7 @@
hourlyBatteryLevelsPerDay.add(
new BatteryLevelData.PeriodBatteryLevelData(new ArrayList<>(), new ArrayList<>()));
assertThat(DataProcessor.generateAppUsagePeriodMap(
- hourlyBatteryLevelsPerDay, new ArrayList<>())).isNull();
+ 0L, hourlyBatteryLevelsPerDay, new ArrayList<>())).isNull();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
index 0006485..d0f6485 100644
--- a/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
@@ -67,7 +67,7 @@
OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true);
assertThat(mController.getSummary())
- .isEqualTo(mContext.getText(R.string.on));
+ .isEqualTo(mContext.getText(R.string.switch_on_text));
}
@Test
@@ -75,6 +75,6 @@
OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false);
assertThat(mController.getSummary())
- .isEqualTo(mContext.getText(R.string.off));
+ .isEqualTo(mContext.getText(R.string.switch_off_text));
}
}
diff --git a/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java
index 8f06d37..04467a4 100644
--- a/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java
@@ -137,7 +137,7 @@
VOLUME_HUSH_OFF);
mController.updateState(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(mContext.getResources().getText(
- R.string.off));
+ R.string.switch_off_text));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/inputmethod/SpellCheckerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/SpellCheckerPreferenceControllerTest.java
index e13e2a7..b050970 100644
--- a/tests/robotests/src/com/android/settings/inputmethod/SpellCheckerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/inputmethod/SpellCheckerPreferenceControllerTest.java
@@ -97,7 +97,7 @@
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mAppContext.getString(R.string.off));
+ .isEqualTo(mAppContext.getString(R.string.switch_off_text));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/location/LocationForWorkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationForWorkPreferenceControllerTest.java
index a8a1a86..03f4663 100644
--- a/tests/robotests/src/com/android/settings/location/LocationForWorkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationForWorkPreferenceControllerTest.java
@@ -97,7 +97,7 @@
verify(mUserManager)
.setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, false, mUserHandle);
- verify(mPreference).setSummary(R.string.on);
+ verify(mPreference).setSummary(R.string.switch_on_text);
}
@Test
@@ -109,7 +109,7 @@
verify(mUserManager)
.setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, mUserHandle);
- verify(mPreference).setSummary(R.string.off);
+ verify(mPreference).setSummary(R.string.switch_off_text);
}
@Test
@@ -147,7 +147,7 @@
mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
verify(mPreference).setEnabled(true);
- verify(mPreference).setSummary(R.string.on);
+ verify(mPreference).setSummary(R.string.switch_on_text);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/location/TopLevelLocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/TopLevelLocationPreferenceControllerTest.java
index 0801586..15fdd89 100644
--- a/tests/robotests/src/com/android/settings/location/TopLevelLocationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/TopLevelLocationPreferenceControllerTest.java
@@ -53,7 +53,7 @@
public void getSummary_whenLocationIsOff_shouldReturnStringForOff() {
mLocationManager.setLocationEnabledForUser(false, android.os.Process.myUserHandle());
assertThat(mController.getSummary()).isEqualTo(
- mContext.getString(R.string.off));
+ mContext.getString(R.string.location_settings_summary_location_off));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityPreferenceControllerTest.java
index 654d3bf..9ba6238 100644
--- a/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityPreferenceControllerTest.java
@@ -74,7 +74,7 @@
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED, 1);
- assertThat(mController.getSummary()).isEqualTo(mContext.getString(R.string.on));
+ assertThat(mController.getSummary()).isEqualTo(mContext.getString(R.string.switch_on_text));
}
@Test
@@ -83,6 +83,6 @@
Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED, 0);
assertThat(mController.getSummary())
- .isEqualTo(mContext.getString(R.string.off));
+ .isEqualTo(mContext.getString(R.string.switch_off_text));
}
}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
index b5735ef..912fada 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
@@ -95,10 +95,11 @@
doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
doReturn(mEuiccManager).when(mContext).getSystemService(EuiccManager.class);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
- mMobileNetworkRepository = MobileNetworkRepository.create(mContext, mMobileNetworkCallback);
+ mMobileNetworkRepository = MobileNetworkRepository.getInstance(mContext);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
- mMobileNetworkRepository.addRegister(mLifecycleOwner);
+ mMobileNetworkRepository.addRegister(mLifecycleOwner, mMobileNetworkCallback,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("");
when(mSubscriptionManager.isActiveSubscriptionId(anyInt())).thenReturn(true);
@@ -114,7 +115,7 @@
@After
public void tearDown() {
- mMobileNetworkRepository.removeRegister();
+ mMobileNetworkRepository.removeRegister(mMobileNetworkCallback);
SubscriptionUtil.setActiveSubscriptionsForTesting(null);
SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
}
diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java
index 71da26e..057b6cb 100644
--- a/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java
@@ -224,7 +224,7 @@
when(lp.getValidatedPrivateDnsServers()).thenReturn(NON_EMPTY_ADDRESS_LIST);
updateLinkProperties(lp);
mController.updateState(mPreference);
- verify(mPreference).setSummary(getResourceString(R.string.on));
+ verify(mPreference).setSummary(getResourceString(R.string.private_dns_mode_on));
reset(mPreference);
lp = mock(LinkProperties.class);
diff --git a/tests/robotests/src/com/android/settings/network/TetherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/TetherPreferenceControllerTest.java
index 63b9241..54d616d 100644
--- a/tests/robotests/src/com/android/settings/network/TetherPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/TetherPreferenceControllerTest.java
@@ -141,7 +141,7 @@
when(mTetheringManager.getTetherableWifiRegexs()).thenReturn(new String[]{"456"});
mController.updateSummary();
- verify(mPreference).setSummary(R.string.off);
+ verify(mPreference).setSummary(R.string.switch_off_text);
}
@Test
@@ -172,7 +172,7 @@
ReflectionHelpers.getField(mController, "mAirplaneModeObserver");
observer.onChange(true, Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON));
- verify(mPreference).setSummary(R.string.off);
+ verify(mPreference).setSummary(R.string.switch_off_text);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java
index d237b27..5e4efd0 100644
--- a/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java
@@ -19,14 +19,19 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.provider.Settings.Global;
import androidx.fragment.app.FragmentActivity;
@@ -72,6 +77,7 @@
mController = new DockAudioMediaPreferenceController(mContext, mSetting, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
doReturn(mScreen).when(mSetting).getPreferenceScreen();
+ fakeDockState(Intent.EXTRA_DOCK_STATE_LE_DESK);
}
@Test
@@ -91,6 +97,34 @@
}
@Test
+ public void isAvailable_undocked_shouldReturnFalse() {
+ when(mContext.registerReceiver(nullable(BroadcastReceiver.class),
+ any(IntentFilter.class))).thenReturn(null);
+ when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
+ .thenReturn(true);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_highEndDock_shouldReturnFalse() {
+ fakeDockState(Intent.EXTRA_DOCK_STATE_HE_DESK);
+ when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
+ .thenReturn(true);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_lowEndDock_shouldReturnTrue() {
+ fakeDockState(Intent.EXTRA_DOCK_STATE_LE_DESK);
+ when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
+ .thenReturn(true);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
public void displayPreference_dockAudioDisabled_shouldSelectFirstItem() {
Global.putInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0);
@@ -127,4 +161,11 @@
assertThat(Global.getInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0))
.isEqualTo(1);
}
+
+ private void fakeDockState(int dockState) {
+ Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
+ intent.putExtra(Intent.EXTRA_DOCK_STATE, dockState);
+ when(mContext.registerReceiver(nullable(BroadcastReceiver.class),
+ any(IntentFilter.class))).thenReturn(intent);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/notification/app/AppConversationListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/AppConversationListPreferenceControllerTest.java
new file mode 100644
index 0000000..198c80a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/app/AppConversationListPreferenceControllerTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2023 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.notification.app;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationChannel;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ShortcutInfo;
+import android.service.notification.ConversationChannelWrapper;
+
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.notification.NotificationBackend;
+
+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.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+@RunWith(RobolectricTestRunner.class)
+public class AppConversationListPreferenceControllerTest {
+
+ private Context mContext;
+
+ @Mock
+ private NotificationBackend mBackend;
+
+ private AppConversationListPreferenceController mController;
+ private NotificationBackend.AppRow mAppRow;
+ private PreferenceCategory mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = ApplicationProvider.getApplicationContext();
+
+ mAppRow = new NotificationBackend.AppRow();
+ mAppRow.uid = 42;
+ mAppRow.pkg = "com.example.exampling";
+
+ mController = new AppConversationListPreferenceController(mContext, mBackend);
+ mController.onResume(mAppRow, null, null, null, null, null, new ArrayList<>());
+
+ mPreference = new PreferenceCategory(mContext);
+ PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
+ preferenceScreen.addPreference(mPreference);
+ }
+
+ @Test
+ public void updateState_someConversations_loadsConversations() {
+ when(mBackend.getConversations(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
+ conversationList(
+ conversationChannel("1", "msg", "Mario", "Messages", "M", false),
+ conversationChannel("2", "msg", "Luigi", "Messages", "L", false)
+ ));
+
+ mController.updateState(mPreference);
+ ShadowApplication.runBackgroundTasks();
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getPreferenceCount()).isEqualTo(2);
+ assertThat(mPreference.getPreference(0).getTitle().toString()).isEqualTo("Mario");
+ assertThat(mPreference.getPreference(0).getSummary().toString()).isEqualTo("Messages");
+ assertThat(mPreference.getPreference(1).getTitle().toString()).isEqualTo("Luigi");
+ assertThat(mPreference.getPreference(1).getSummary().toString()).isEqualTo("Messages");
+ }
+
+ @Test
+ public void updateState_someConversations_loadsNotDemotedOnly() {
+ when(mBackend.getConversations(eq(mAppRow.pkg), eq(mAppRow.uid)))
+ .thenReturn(conversationList(
+ conversationChannel("1", "msg", "Mario", "Messages", "M", false),
+ conversationChannel("2", "msg", "Luigi", "Messages", "L", true)
+ ));
+
+ mController.updateState(mPreference);
+ ShadowApplication.runBackgroundTasks();
+
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getPreferenceCount()).isEqualTo(1);
+ assertThat(mPreference.getPreference(0).getTitle().toString()).isEqualTo("Mario");
+ }
+
+ @Test
+ public void updateState_noConversations_hides() {
+ when(mBackend.getConversations(eq(mAppRow.pkg), eq(mAppRow.uid)))
+ .thenReturn(conversationList());
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isVisible()).isFalse();
+ assertThat(mPreference.getPreferenceCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void updateState_refreshes() {
+ when(mBackend.getConversations(eq(mAppRow.pkg), eq(mAppRow.uid)))
+ .thenReturn(conversationList());
+ mController.updateState(mPreference);
+ assertThat(mPreference.isVisible()).isFalse();
+
+ // Empty -> present
+ when(mBackend.getConversations(eq(mAppRow.pkg), eq(mAppRow.uid)))
+ .thenReturn(conversationList(
+ conversationChannel("1", "msg", "Mario", "Messages", "M", false)
+ ));
+ mController.updateState(mPreference);
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getPreferenceCount()).isEqualTo(1);
+
+ // Present -> empty
+ when(mBackend.getConversations(eq(mAppRow.pkg), eq(mAppRow.uid)))
+ .thenReturn(conversationList());
+ mController.updateState(mPreference);
+ assertThat(mPreference.isVisible()).isFalse();
+ assertThat(mPreference.getPreferenceCount()).isEqualTo(0);
+ }
+
+ private static ParceledListSlice<ConversationChannelWrapper> conversationList(
+ ConversationChannelWrapper... channels) {
+ return new ParceledListSlice<>(Arrays.asList(channels));
+ }
+
+ private ConversationChannelWrapper conversationChannel(String id, String parentId,
+ String shortcutName, String parentLabel, String shortcutId, boolean demoted) {
+ NotificationChannel channel = new NotificationChannel(id, "Channel", IMPORTANCE_DEFAULT);
+ channel.setDemoted(demoted);
+ channel.setConversationId(parentId, shortcutId);
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
+ shortcutName).build();
+
+ ConversationChannelWrapper ccw = new ConversationChannelWrapper();
+ ccw.setPkg(mAppRow.pkg);
+ ccw.setUid(mAppRow.uid);
+ ccw.setNotificationChannel(channel);
+ ccw.setShortcutInfo(shortcutInfo);
+ ccw.setParentChannelLabel(parentLabel);
+ return ccw;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/app/BadgePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BadgePreferenceControllerTest.java
index d871776..cf852c1 100644
--- a/tests/robotests/src/com/android/settings/notification/app/BadgePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/BadgePreferenceControllerTest.java
@@ -97,6 +97,7 @@
@Test
public void testIsAvailable_notIfAppBlocked() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.channelCount = 1;
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class), null, null, null, null, null);
assertFalse(mController.isAvailable());
@@ -105,6 +106,7 @@
@Test
public void testIsAvailable_notIfChannelBlocked() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.channelCount = 1;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null, null, null, null);
@@ -114,6 +116,7 @@
@Test
public void testIsAvailable_channel_notIfAppOff() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.channelCount = 1;
appRow.showBadge = false;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
@@ -125,6 +128,7 @@
@Test
public void testIsAvailable_notIfOffGlobally() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.channelCount = 1;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null, null);
@@ -136,6 +140,7 @@
@Test
public void testIsAvailable_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.channelCount = 1;
mController.onResume(appRow, null, null, null, null, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 1);
@@ -143,9 +148,20 @@
}
@Test
+ public void testIsAvailable_appNoChannels() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.channelCount = 0;
+ mController.onResume(appRow, null, null, null, null, null, null);
+ Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 1);
+
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
public void testIsAvailable_defaultChannel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
+ appRow.channelCount = 1;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
@@ -159,6 +175,7 @@
public void testIsAvailable_channel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
+ appRow.channelCount = 1;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null, null);
@@ -183,6 +200,7 @@
public void testIsAvailable_filteredOut() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
+ appRow.channelCount = 1;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null, new ArrayList<>());
@@ -195,6 +213,7 @@
public void testIsAvailable_filteredIn() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
+ appRow.channelCount = 1;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null,
@@ -206,9 +225,11 @@
@Test
public void testUpdateState_disabledByAdmin() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.channelCount = 1;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
- mController.onResume(new NotificationBackend.AppRow(), channel, null,
+ mController.onResume(appRow, channel, null,
null, null, mock(RestrictedLockUtils.EnforcedAdmin.class), null);
Preference pref = new RestrictedSwitchPreference(mContext);
@@ -220,6 +241,7 @@
@Test
public void testUpdateState_channel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ appRow.channelCount = 1;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.canShowBadge()).thenReturn(true);
mController.onResume(appRow, channel, null, null, null, null, null);
@@ -240,6 +262,7 @@
public void testUpdateState_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
+ appRow.channelCount = 1;
mController.onResume(appRow, null, null, null, null, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
@@ -257,6 +280,7 @@
public void testOnPreferenceChange_on_channel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
+ appRow.channelCount = 1;
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
channel.setShowBadge(false);
@@ -276,6 +300,7 @@
public void testOnPreferenceChange_off_channel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
+ appRow.channelCount = 1;
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
channel.setShowBadge(true);
@@ -295,6 +320,7 @@
public void testOnPreferenceChange_on_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = false;
+ appRow.channelCount = 1;
mController.onResume(appRow, null, null, null, null, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
@@ -312,6 +338,7 @@
public void testOnPreferenceChange_off_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
+ appRow.channelCount = 1;
mController.onResume(appRow, null, null, null, null, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
diff --git a/tests/robotests/src/com/android/settings/notification/app/DescriptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/DescriptionPreferenceControllerTest.java
deleted file mode 100644
index 3ce67a2..0000000
--- a/tests/robotests/src/com/android/settings/notification/app/DescriptionPreferenceControllerTest.java
+++ /dev/null
@@ -1,170 +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.notification.app;
-
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_NONE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationChannel;
-import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.os.UserManager;
-
-import androidx.preference.Preference;
-
-import com.android.settings.notification.NotificationBackend;
-
-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 org.robolectric.shadows.ShadowApplication;
-
-@RunWith(RobolectricTestRunner.class)
-public class DescriptionPreferenceControllerTest {
-
- private Context mContext;
- @Mock
- private NotificationManager mNm;
- @Mock
- private UserManager mUm;
-
- private DescriptionPreferenceController mController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- ShadowApplication shadowApplication = ShadowApplication.getInstance();
- shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
- shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
- mContext = RuntimeEnvironment.application;
- mController = spy(new DescriptionPreferenceController(mContext));
- }
-
- @Test
- public void testNoCrashIfNoOnResume() {
- mController.isAvailable();
- mController.updateState(mock(Preference.class));
- }
-
- @Test
- public void testIsAvailable_notIfNull() {
- mController.onResume(null, null, null, null, null, null, null);
- assertFalse(mController.isAvailable());
- }
-
- @Test
- public void testIsAvailable_notIfChannelGroupBlocked() {
- NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
- NotificationChannelGroup group = mock(NotificationChannelGroup.class);
- mController.onResume(appRow, null, group, null, null, null, null);
- assertFalse(mController.isAvailable());
- }
-
- @Test
- public void testIsAvailable_notIfChannelBlocked() {
- NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
- NotificationChannel channel = mock(NotificationChannel.class);
- when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
- mController.onResume(appRow, channel, null, null, null, null, null);
- assertFalse(mController.isAvailable());
- }
-
- @Test
- public void testIsAvailable_notIfNoChannelDesc() {
- NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
- NotificationChannel channel = mock(NotificationChannel.class);
- when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
- mController.onResume(appRow, channel, null, null, null, null, null);
- assertFalse(mController.isAvailable());
- }
-
- @Test
- public void testIsAvailable_notIfNoChannelGroupDesc() {
- NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
- NotificationChannelGroup group = mock(NotificationChannelGroup.class);
- mController.onResume(appRow, null, group, null, null, null, null);
- assertFalse(mController.isAvailable());
- }
-
- @Test
- public void testIsAvailable_channel() {
- NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
- NotificationChannel channel = mock(NotificationChannel.class);
- when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
- when(channel.getDescription()).thenReturn("AAA");
- mController.onResume(appRow, channel, null, null, null, null, null);
- assertTrue(mController.isAvailable());
- }
-
- @Test
- public void testIsAvailable_channelGroup() {
- NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
- NotificationChannelGroup group = mock(NotificationChannelGroup.class);
- when(group.getDescription()).thenReturn("something");
- when(group.isBlocked()).thenReturn(false);
- mController.onResume(appRow, null, group, null, null, null, null);
- assertTrue(mController.isAvailable());
- }
-
- @Test
- public void testIsAvailable_alwaysFiltered() {
- assertFalse(mController.isIncludedInFilter());
- }
-
- @Test
- public void testUpdateState_channel() {
- NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
- NotificationChannel channel = mock(NotificationChannel.class);
- when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
- when(channel.getDescription()).thenReturn("AAA");
- mController.onResume(appRow, channel, null, null, null, null, null);
-
- Preference pref = new Preference(RuntimeEnvironment.application);
- mController.updateState(pref);
-
- assertEquals("AAA", pref.getTitle());
- assertFalse(pref.isEnabled());
- assertFalse(pref.isSelectable());
- }
-
- @Test
- public void testUpdateState_channelGroup() {
- NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
- NotificationChannelGroup group = mock(NotificationChannelGroup.class);
- when(group.getDescription()).thenReturn("something");
- mController.onResume(appRow, null, group, null, null, null, null);
-
- Preference pref = new Preference(RuntimeEnvironment.application);
- mController.updateState(pref);
-
- assertEquals("something", pref.getTitle());
- assertFalse(pref.isEnabled());
- assertFalse(pref.isSelectable());
- }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java
deleted file mode 100644
index d5834f9..0000000
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2020 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.notification.zen;
-
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
-
-import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_ALL;
-import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_IMPORTANT;
-import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_NONE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.content.ContentResolver;
-import android.content.Context;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.notification.NotificationBackend;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.SelectorWithWidgetPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenModePriorityConversationsPreferenceControllerTest {
-
- private ZenModePriorityConversationsPreferenceController mController;
-
- @Mock
- private ZenModeBackend mZenBackend;
- @Mock
- private PreferenceCategory mMockPrefCategory;
- @Mock
- private NotificationManager.Policy mPolicy;
- @Mock
- private PreferenceScreen mPreferenceScreen;
- @Mock
- private NotificationBackend mNotifBackend;
-
- private List<SelectorWithWidgetPreference> mSelectorWithWidgetPreferences;
- private ContentResolver mContentResolver;
- private Context mContext;
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mController = new ZenModePriorityConversationsPreferenceController(
- mContext, "test_key", mock(Lifecycle.class), mNotifBackend);
- ReflectionHelpers.setField(mController, "mBackend", mZenBackend);
-
- when(mMockPrefCategory.getContext()).thenReturn(mContext);
- when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
- .thenReturn(mMockPrefCategory);
- captureRadioButtons();
- }
-
- @Test
- public void displayPreference_radioButtonsCreatedOnlyOnce() {
- when(mMockPrefCategory.findPreference(any())).thenReturn(mock(Preference.class));
-
- // radio buttons were already created, so don't re-create them
- mController.displayPreference(mPreferenceScreen);
- verify(mMockPrefCategory, never()).addPreference(any());
- }
-
- @Test
- public void clickAllConversations() {
- SelectorWithWidgetPreference allConversationsRb = getButton(KEY_ALL);
- allConversationsRb.onClick();
-
- verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_ANYONE);
- }
-
- @Test
- public void clickImportantConversations() {
- SelectorWithWidgetPreference importantConversationsRb = getButton(KEY_IMPORTANT);
- importantConversationsRb.onClick();
-
- verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_IMPORTANT);
- }
-
- @Test
- public void clickNoConversations() {
- SelectorWithWidgetPreference noConversationsRb = getButton(KEY_NONE);
- noConversationsRb.onClick();
-
- verify(mZenBackend)
- .saveConversationSenders(CONVERSATION_SENDERS_NONE);
- }
-
- private void captureRadioButtons() {
- ArgumentCaptor<SelectorWithWidgetPreference> rbCaptor =
- ArgumentCaptor.forClass(SelectorWithWidgetPreference.class);
- mController.displayPreference(mPreferenceScreen);
-
- // verifies 3 buttons were added
- verify(mMockPrefCategory, times(3)).addPreference(rbCaptor.capture());
- mSelectorWithWidgetPreferences = rbCaptor.getAllValues();
- assertThat(mSelectorWithWidgetPreferences.size()).isEqualTo(3);
-
- reset(mMockPrefCategory);
- }
-
- private SelectorWithWidgetPreference getButton(String key) {
- for (SelectorWithWidgetPreference pref : mSelectorWithWidgetPreferences) {
- if (key.equals(pref.getKey())) {
- return pref;
- }
- }
- return null;
- }
-}
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 5cdc12a..ea55b90 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -16,11 +16,13 @@
package com.android.settings.panel;
+import static android.content.res.Configuration.UI_MODE_NIGHT_NO;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
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.mock;
import static org.mockito.Mockito.never;
@@ -30,15 +32,20 @@
import android.content.res.Configuration;
import android.os.Build;
+import android.view.View;
import android.view.Window;
import android.view.WindowManager;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,6 +68,9 @@
private PanelFragment mPanelFragment;
@Mock
private FragmentManager mFragmentManager;
+ @Mock
+ private FragmentTransaction mTransaction;
+ private int mOriginalUiMode;
@Before
public void setUp() {
@@ -76,6 +86,15 @@
mSettingsPanelActivity.mPanelFragment = mPanelFragment;
when(mFragmentManager.findFragmentById(R.id.main_content)).thenReturn(mPanelFragment);
when(mSettingsPanelActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
+ mOriginalUiMode = mSettingsPanelActivity.getResources().getConfiguration().uiMode;
+ when(mFragmentManager.beginTransaction()).thenReturn(mTransaction);
+ when(mTransaction.add(anyInt(), any())).thenReturn(mTransaction);
+ when(mTransaction.commit()).thenReturn(0); // don't care about return value
+ }
+
+ @After
+ public void tearDown() {
+ mSettingsPanelActivity.getResources().getConfiguration().uiMode = mOriginalUiMode;
}
@Test
@@ -179,4 +198,24 @@
verify(mPanelFragment, never()).updatePanelWithAnimation();
}
+
+ @Test
+ public void onCreated_isWindowBottomPaddingZero() {
+ int paddingBottom = mSettingsPanelActivity.getWindow().getDecorView().getPaddingBottom();
+ assertThat(paddingBottom).isEqualTo(0);
+ }
+
+ @Test
+ public void notInNightMode_lightNavigationBarAppearance() {
+ Configuration config = mSettingsPanelActivity.getResources().getConfiguration();
+ config.uiMode = UI_MODE_NIGHT_NO;
+ mSettingsPanelActivity.onConfigurationChanged(config); // forces creation
+
+ mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent());
+ verify(mFragmentManager).beginTransaction();
+
+ View decorView = mSettingsPanelActivity.getWindow().getDecorView();
+ WindowInsetsControllerCompat controller = ViewCompat.getWindowInsetsController(decorView);
+ assertThat(controller.isAppearanceLightNavigationBars()).isTrue();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/print/PrintSettingsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/print/PrintSettingsPreferenceControllerTest.java
index 9cecf4c..a6c9955 100644
--- a/tests/robotests/src/com/android/settings/print/PrintSettingsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/print/PrintSettingsPreferenceControllerTest.java
@@ -145,7 +145,7 @@
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.off));
+ .isEqualTo(mContext.getString(R.string.print_settings_summary_no_service));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/security/ScreenPinningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ScreenPinningPreferenceControllerTest.java
index 0b6643b..4f694bc 100644
--- a/tests/robotests/src/com/android/settings/security/ScreenPinningPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/ScreenPinningPreferenceControllerTest.java
@@ -76,7 +76,7 @@
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.off));
+ .isEqualTo(mContext.getString(R.string.switch_off_text));
}
@Test
@@ -87,7 +87,7 @@
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.on));
+ .isEqualTo(mContext.getString(R.string.switch_on_text));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/widget/SwitchBarTest.java b/tests/robotests/src/com/android/settings/widget/SwitchBarTest.java
index 7eb2878..0c297f4 100644
--- a/tests/robotests/src/com/android/settings/widget/SwitchBarTest.java
+++ b/tests/robotests/src/com/android/settings/widget/SwitchBarTest.java
@@ -55,8 +55,8 @@
@Test
public void cycleChecked_defaultLabel_shouldUpdateTextAndBackground() {
- final int defaultOnText = R.string.on;
- final int defaultOffText = R.string.off;
+ final int defaultOnText = R.string.switch_on_text;
+ final int defaultOffText = R.string.switch_off_text;
assertThat(((TextView) mBar.findViewById(R.id.switch_text)).getText())
.isEqualTo(mContext.getString(defaultOffText));
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
index e060c0f..99040db 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
@@ -110,7 +110,7 @@
mWifiTracker.enabled = false;
assertThat(mSummaryUpdater.getSummary())
- .isEqualTo(mContext.getString(R.string.off));
+ .isEqualTo(mContext.getString(R.string.switch_off_text));
}
@Test
diff --git a/tests/spa_unit/AndroidManifest.xml b/tests/spa_unit/AndroidManifest.xml
index ec77741..5a7f565 100644
--- a/tests/spa_unit/AndroidManifest.xml
+++ b/tests/spa_unit/AndroidManifest.xml
@@ -19,6 +19,8 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.android.settings.tests.spa_unit">
+ <uses-permission android:name="android.permission.MANAGE_APPOPS" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
<application android:debuggable="true">
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptionsTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptionsTest.kt
index 318deba..7103516 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptionsTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptionsTest.kt
@@ -16,6 +16,8 @@
package com.android.settings.spa.app.appinfo
+import android.app.AppOpsManager
+import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager
import android.content.Context
import android.content.pm.ApplicationInfo
@@ -27,6 +29,7 @@
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import androidx.test.core.app.ApplicationProvider
@@ -36,6 +39,7 @@
import com.android.settings.Utils
import com.android.settingslib.spa.testutils.delay
import com.android.settingslib.spa.testutils.waitUntilExists
+import com.android.settingslib.spaprivileged.framework.common.appOpsManager
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
import com.android.settingslib.spaprivileged.framework.common.userManager
import com.android.settingslib.spaprivileged.model.app.IPackageManagers
@@ -46,6 +50,7 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.verify
import org.mockito.MockitoSession
import org.mockito.Spy
import org.mockito.quality.Strictness
@@ -73,6 +78,12 @@
@Mock
private lateinit var devicePolicyManager: DevicePolicyManager
+ @Mock
+ private lateinit var appOpsManager: AppOpsManager
+
+ @Mock
+ private lateinit var keyguardManager: KeyguardManager
+
@Spy
private var resources = context.resources
@@ -90,6 +101,9 @@
whenever(context.packageManager).thenReturn(packageManager)
whenever(context.userManager).thenReturn(userManager)
whenever(context.devicePolicyManager).thenReturn(devicePolicyManager)
+ whenever(context.appOpsManager).thenReturn(appOpsManager)
+ whenever(context.getSystemService(KeyguardManager::class.java)).thenReturn(keyguardManager)
+ whenever(keyguardManager.isKeyguardSecure).thenReturn(false)
whenever(Utils.isProfileOrDeviceOwner(userManager, devicePolicyManager, PACKAGE_NAME))
.thenReturn(false)
}
@@ -143,6 +157,35 @@
)
}
+ @Test
+ fun shouldShowAccessRestrictedSettings() {
+ whenever(
+ appOpsManager.noteOpNoThrow(
+ AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, UID, PACKAGE_NAME, null, null
+ )
+ ).thenReturn(AppOpsManager.MODE_IGNORED)
+ val app = ApplicationInfo().apply {
+ packageName = PACKAGE_NAME
+ uid = UID
+ }
+
+ setContent(app)
+ composeTestRule.onRoot().performClick()
+
+ composeTestRule.waitUntilExists(
+ hasText(context.getString(R.string.app_restricted_settings_lockscreen_title))
+ )
+ composeTestRule
+ .onNodeWithText(context.getString(R.string.app_restricted_settings_lockscreen_title))
+ .performClick()
+ verify(appOpsManager).setMode(
+ AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
+ UID,
+ PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED,
+ )
+ }
+
private fun setContent(app: ApplicationInfo) {
composeTestRule.setContent {
CompositionLocalProvider(LocalContext provides context) {
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 249ce72..4e2b3be 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -36,6 +36,10 @@
// instrumented Settings app.
],
+ errorprone: {
+ javacflags: ["-Xep:CheckReturnValue:WARN"]
+ },
+
// Include all test java files.
srcs: ["src/**/*.java"],
diff --git a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
index 2633ea7..9cfa7ed 100644
--- a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
@@ -46,6 +46,7 @@
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Set;
@RunWith(AndroidJUnit4.class)
@@ -55,6 +56,13 @@
private PreferenceScreen mScreen;
private PreferenceCategory mCredentialsPreferenceCategory;
+ private static final String TEST_PACKAGE_NAME_A = "com.android.providerA";
+ private static final String TEST_PACKAGE_NAME_B = "com.android.providerB";
+ private static final String TEST_PACKAGE_NAME_C = "com.android.providerC";
+ private static final String TEST_TITLE_APP_A = "test app A";
+ private static final String TEST_TITLE_APP_B = "test app B";
+ private static final String TEST_TITLE_SERVICE_C = "test service C1";
+
@Before
public void setUp() {
mContext = spy(ApplicationProvider.getApplicationContext());
@@ -67,7 +75,7 @@
mScreen.addPreference(mCredentialsPreferenceCategory);
}
- @Test
+ /*@Test
// Tests that getAvailabilityStatus() does not throw an exception if it's called before the
// Controller is initialized (this can happen during indexing).
public void getAvailabilityStatus_withoutInit_returnsUnavailable() {
@@ -114,11 +122,11 @@
@Test
public void buildSwitchPreference() {
CredentialProviderInfo providerInfo1 =
- createCredentialProviderInfo(
- "com.android.provider1", "ClassA", "Service Title", false);
+ createCredentialProviderInfoWithSubtitle(
+ "com.android.provider1", "ClassA", "Service Title", null);
CredentialProviderInfo providerInfo2 =
- createCredentialProviderInfo(
- "com.android.provider2", "ClassA", "Service Title", false);
+ createCredentialProviderInfoWithSubtitle(
+ "com.android.provider2", "ClassA", "Service Title", "Summary Text");
CredentialManagerPreferenceController controller =
createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
@@ -139,11 +147,13 @@
SwitchPreference pref = controller.createPreference(mContext, providerInfo1);
assertThat(pref.getTitle().toString()).isEqualTo("Service Title");
assertThat(pref.isChecked()).isTrue();
+ assertThat(pref.getSummary()).isNull();
// Create the pref (not checked).
SwitchPreference pref2 = controller.createPreference(mContext, providerInfo2);
assertThat(pref2.getTitle().toString()).isEqualTo("Service Title");
assertThat(pref2.isChecked()).isFalse();
+ assertThat(pref2.getSummary().toString()).isEqualTo("Summary Text");
}
@Test
@@ -217,10 +227,10 @@
@Test
public void handlesCredentialProviderInfoEnabledDisabled() {
CredentialProviderInfo providerInfo1 =
- createCredentialProviderInfo(
+ createCredentialProviderInfoWithIsEnabled(
"com.android.provider1", "ClassA", "Service Title", false);
CredentialProviderInfo providerInfo2 =
- createCredentialProviderInfo(
+ createCredentialProviderInfoWithIsEnabled(
"com.android.provider2", "ClassA", "Service Title", true);
CredentialManagerPreferenceController controller =
createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
@@ -242,6 +252,64 @@
assertThat(enabledServices.size()).isEqualTo(1);
assertThat(enabledServices.contains("com.android.provider1/ClassA")).isFalse();
assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue();
+ }*/
+
+ @Test
+ public void displayPreference_withServices_preferencesAdded_sameAppShouldBeMerged() {
+ CredentialProviderInfo serviceA1 =
+ createCredentialProviderInfoWithAppLabel(
+ TEST_PACKAGE_NAME_A,
+ "CredManProviderA1",
+ TEST_TITLE_APP_A,
+ "test service A1");
+ CredentialProviderInfo serviceB1 =
+ createCredentialProviderInfoWithAppLabel(
+ TEST_PACKAGE_NAME_B,
+ "CredManProviderB1",
+ TEST_TITLE_APP_B,
+ "test service B");
+ CredentialProviderInfo serviceC1 =
+ createCredentialProviderInfoWithAppLabel(
+ TEST_PACKAGE_NAME_C,
+ "CredManProviderC1",
+ "test app C1",
+ TEST_TITLE_SERVICE_C);
+ CredentialProviderInfo serviceC2 =
+ createCredentialProviderInfoWithAppLabel(
+ TEST_PACKAGE_NAME_C,
+ "CredManProviderC2",
+ "test app C2",
+ TEST_TITLE_SERVICE_C);
+ CredentialProviderInfo serviceC3 =
+ createCredentialProviderInfoBuilder(
+ TEST_PACKAGE_NAME_C,
+ "CredManProviderC3",
+ "test app C3",
+ TEST_TITLE_SERVICE_C)
+ .setEnabled(true)
+ .build();
+
+ CredentialManagerPreferenceController controller =
+ createControllerWithServices(
+ Lists.newArrayList(serviceA1, serviceB1, serviceC1, serviceC2, serviceC3));
+ controller.displayPreference(mScreen);
+
+ assertThat(controller.isConnected()).isFalse();
+ assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(3);
+
+ Map<String, SwitchPreference> prefs =
+ controller.buildPreferenceList(mContext, mCredentialsPreferenceCategory);
+ assertThat(prefs.keySet()).containsExactly(TEST_PACKAGE_NAME_A, TEST_PACKAGE_NAME_B, TEST_PACKAGE_NAME_C);
+ assertThat(prefs.size()).isEqualTo(3);
+ assertThat(prefs.containsKey(TEST_PACKAGE_NAME_A)).isTrue();
+ assertThat(prefs.get(TEST_PACKAGE_NAME_A).getTitle()).isEqualTo(TEST_TITLE_APP_A);
+ assertThat(prefs.get(TEST_PACKAGE_NAME_A).isChecked()).isFalse();
+ assertThat(prefs.containsKey(TEST_PACKAGE_NAME_B)).isTrue();
+ assertThat(prefs.get(TEST_PACKAGE_NAME_B).getTitle()).isEqualTo(TEST_TITLE_APP_B);
+ assertThat(prefs.get(TEST_PACKAGE_NAME_B).isChecked()).isFalse();
+ assertThat(prefs.containsKey(TEST_PACKAGE_NAME_C)).isTrue();
+ assertThat(prefs.get(TEST_PACKAGE_NAME_C).getTitle()).isEqualTo(TEST_TITLE_SERVICE_C);
+ assertThat(prefs.get(TEST_PACKAGE_NAME_C).isChecked()).isTrue();
}
private CredentialManagerPreferenceController createControllerWithServices(
@@ -259,11 +327,19 @@
private CredentialProviderInfo createCredentialProviderInfo(
String packageName, String className) {
- return createCredentialProviderInfo(packageName, className, null, false);
+ return createCredentialProviderInfoBuilder(packageName, className, null, "App Name")
+ .build();
}
- private CredentialProviderInfo createCredentialProviderInfo(
- String packageName, String className, CharSequence label, boolean isEnabled) {
+ private CredentialProviderInfo createCredentialProviderInfoWithIsEnabled(
+ String packageName, String className, CharSequence serviceLabel, boolean isEnabled) {
+ return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, "App Name")
+ .setEnabled(isEnabled)
+ .build();
+ }
+
+ private CredentialProviderInfo createCredentialProviderInfoWithSubtitle(
+ String packageName, String className, CharSequence label, CharSequence subtitle) {
ServiceInfo si = new ServiceInfo();
si.packageName = packageName;
si.name = className;
@@ -275,7 +351,27 @@
return new CredentialProviderInfo.Builder(si)
.setOverrideLabel(label)
- .setEnabled(isEnabled)
+ .setSettingsSubtitle(subtitle)
.build();
}
+
+ private CredentialProviderInfo createCredentialProviderInfoWithAppLabel(
+ String packageName, String className, CharSequence serviceLabel, String appLabel) {
+ return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, appLabel)
+ .build();
+ }
+
+ private CredentialProviderInfo.Builder createCredentialProviderInfoBuilder(
+ String packageName, String className, CharSequence serviceLabel, String appLabel) {
+ ServiceInfo si = new ServiceInfo();
+ si.packageName = packageName;
+ si.name = className;
+ si.nonLocalizedLabel = serviceLabel;
+
+ si.applicationInfo = new ApplicationInfo();
+ si.applicationInfo.packageName = packageName;
+ si.applicationInfo.nonLocalizedLabel = appLabel;
+
+ return new CredentialProviderInfo.Builder(si).setOverrideLabel(serviceLabel);
+ }
}
diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFinishViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFinishViewModelTest.java
new file mode 100644
index 0000000..34ef801
--- /dev/null
+++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFinishViewModelTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2023 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.biometrics2.ui.viewmodel;
+
+import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON;
+import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
+import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
+
+import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK;
+import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FINGERPRINT_ENROLL_FINISH_ACTION_NEXT_BUTTON_CLICK;
+import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository;
+import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Application;
+import android.content.Intent;
+import android.hardware.fingerprint.FingerprintManager;
+
+import androidx.lifecycle.LiveData;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
+import com.android.settings.testutils.InstantTaskExecutorRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidJUnit4.class)
+public class FingerprintEnrollFinishViewModelTest {
+
+ private static final int USER_ID = 334;
+ private static final int MAX_ENROLLABLE = 5;
+
+ @Rule public final MockitoRule mockito = MockitoJUnit.rule();
+ @Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
+
+ @Mock private FingerprintManager mFingerprintManager;
+
+ private Application mApplication;
+ private EnrollmentRequest mRequest;
+ private FingerprintEnrollFinishViewModel mViewModel;
+
+ @Before
+ public void setUp() {
+ mApplication = ApplicationProvider.getApplicationContext();
+ mRequest = new EnrollmentRequest(new Intent(), mApplication);
+ mViewModel = new FingerprintEnrollFinishViewModel(mApplication, USER_ID, mRequest,
+ newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, MAX_ENROLLABLE));
+ }
+
+ @Test
+ public void testCanAssumeSfps() {
+ mViewModel = new FingerprintEnrollFinishViewModel(mApplication, USER_ID, mRequest,
+ newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, MAX_ENROLLABLE));
+ assertThat(mViewModel.canAssumeSfps()).isFalse();
+
+ mViewModel = new FingerprintEnrollFinishViewModel(mApplication, USER_ID, mRequest,
+ newFingerprintRepository(mFingerprintManager, TYPE_REAR, MAX_ENROLLABLE));
+ assertThat(mViewModel.canAssumeSfps()).isFalse();
+
+ mViewModel = new FingerprintEnrollFinishViewModel(mApplication, USER_ID, mRequest,
+ newFingerprintRepository(mFingerprintManager, TYPE_POWER_BUTTON, MAX_ENROLLABLE));
+ assertThat(mViewModel.canAssumeSfps()).isTrue();
+ }
+
+ @Test
+ public void testIsAnotherFingerprintEnrollable() {
+ setupFingerprintEnrolledFingerprints(mFingerprintManager, USER_ID, MAX_ENROLLABLE);
+ assertThat(mViewModel.isAnotherFingerprintEnrollable()).isFalse();
+
+ setupFingerprintEnrolledFingerprints(mFingerprintManager, USER_ID, MAX_ENROLLABLE - 1);
+ assertThat(mViewModel.isAnotherFingerprintEnrollable()).isTrue();
+ }
+
+ @Test
+ public void testGetRequest() {
+ assertThat(mViewModel.getRequest()).isEqualTo(mRequest);
+ }
+
+ @Test
+ public void testOnAddButtonClick() {
+ final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
+
+ // Test init value
+ assertThat(actionLiveData.getValue()).isNull();
+
+ // Test onAddButtonClick()
+ mViewModel.onAddButtonClick();
+ assertThat(actionLiveData.getValue()).isEqualTo(
+ FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK);
+
+ // Clear
+ mViewModel.clearActionLiveData();
+ assertThat(actionLiveData.getValue()).isNull();
+ }
+
+ @Test
+ public void testOnNextButtonClick() {
+ final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
+
+ // Test init value
+ assertThat(actionLiveData.getValue()).isNull();
+
+ // Test onNextButtonClick()
+ mViewModel.onNextButtonClick();
+ assertThat(actionLiveData.getValue()).isEqualTo(
+ FINGERPRINT_ENROLL_FINISH_ACTION_NEXT_BUTTON_CLICK);
+
+ // Clear
+ mViewModel.clearActionLiveData();
+ assertThat(actionLiveData.getValue()).isNull();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java
index 634514f..323618a 100644
--- a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java
+++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java
@@ -36,11 +36,13 @@
import android.content.res.Resources;
import android.os.CancellationSignal;
+import androidx.lifecycle.LiveData;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.R;
import com.android.settings.biometrics.fingerprint.FingerprintUpdater;
import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
+import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage;
import com.android.settings.testutils.InstantTaskExecutorRule;
import org.junit.Before;
@@ -64,6 +66,8 @@
@Mock private FingerprintUpdater mFingerprintUpdater;
private FingerprintEnrollProgressViewModel mViewModel;
+ private final TestWrapper<CancellationSignal> mCancellationSignalWrapper = new TestWrapper<>();
+ private final TestWrapper<EnrollmentCallback> mCallbackWrapper = new TestWrapper<>();
@Before
public void setUp() {
@@ -72,6 +76,15 @@
.thenReturn(false);
mViewModel = new FingerprintEnrollProgressViewModel(mApplication, mFingerprintUpdater,
TEST_USER_ID);
+
+ mCancellationSignalWrapper.mValue = null;
+ mCallbackWrapper.mValue = null;
+ doAnswer(invocation -> {
+ mCancellationSignalWrapper.mValue = invocation.getArgument(1);
+ mCallbackWrapper.mValue = invocation.getArgument(3);
+ return null;
+ }).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class),
+ eq(TEST_USER_ID), any(EnrollmentCallback.class), anyInt());
}
@Test
@@ -100,64 +113,151 @@
@Test
public void testCancelEnrollment() {
- @EnrollReason final int enrollReason = ENROLL_ENROLL;
- final byte[] token = new byte[] { 1, 2, 3 };
- mViewModel.setToken(token);
-
- final TestWrapper<CancellationSignal> signalWrapper = new TestWrapper<>();
- doAnswer(invocation -> {
- signalWrapper.mValue = invocation.getArgument(1);
- return null;
- }).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class),
- eq(TEST_USER_ID), any(EnrollmentCallback.class), anyInt());
-
// Start enrollment
- final boolean ret = mViewModel.startEnrollment(enrollReason);
+ mViewModel.setToken(new byte[] { 1, 2, 3 });
+ final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
assertThat(ret).isTrue();
- assertThat(signalWrapper.mValue).isNotNull();
+ assertThat(mCancellationSignalWrapper.mValue).isNotNull();
// Cancel enrollment
mViewModel.cancelEnrollment();
- assertThat(signalWrapper.mValue.isCanceled()).isTrue();
+ assertThat(mCancellationSignalWrapper.mValue.isCanceled()).isTrue();
}
@Test
public void testProgressUpdate() {
- @EnrollReason final int enrollReason = ENROLL_ENROLL;
- final byte[] token = new byte[] { 1, 2, 3 };
- mViewModel.setToken(token);
-
- final TestWrapper<EnrollmentCallback> callbackWrapper = new TestWrapper<>();
- doAnswer(invocation -> {
- callbackWrapper.mValue = invocation.getArgument(3);
- return null;
- }).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class),
- eq(TEST_USER_ID), any(EnrollmentCallback.class), anyInt());
-
// Start enrollment
- final boolean ret = mViewModel.startEnrollment(enrollReason);
+ mViewModel.setToken(new byte[] { 1, 2, 3 });
+ final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
assertThat(ret).isTrue();
- assertThat(callbackWrapper.mValue).isNotNull();
+ assertThat(mCallbackWrapper.mValue).isNotNull();
+
+ // Test default value
+ final LiveData<EnrollmentProgress> progressLiveData = mViewModel.getProgressLiveData();
+ EnrollmentProgress progress = progressLiveData.getValue();
+ assertThat(progress).isNotNull();
+ assertThat(progress.getSteps()).isEqualTo(-1);
+ assertThat(progress.getRemaining()).isEqualTo(0);
// Update first progress
- callbackWrapper.mValue.onEnrollmentProgress(25);
- EnrollmentProgress progress = mViewModel.getProgressLiveData().getValue();
+ mCallbackWrapper.mValue.onEnrollmentProgress(25);
+ progress = progressLiveData.getValue();
assertThat(progress).isNotNull();
assertThat(progress.getSteps()).isEqualTo(25);
assertThat(progress.getRemaining()).isEqualTo(25);
// Update second progress
- callbackWrapper.mValue.onEnrollmentProgress(20);
- progress = mViewModel.getProgressLiveData().getValue();
+ mCallbackWrapper.mValue.onEnrollmentProgress(20);
+ progress = progressLiveData.getValue();
assertThat(progress).isNotNull();
assertThat(progress.getSteps()).isEqualTo(25);
assertThat(progress.getRemaining()).isEqualTo(20);
+
+ // Update latest progress
+ mCallbackWrapper.mValue.onEnrollmentProgress(0);
+ progress = progressLiveData.getValue();
+ assertThat(progress).isNotNull();
+ assertThat(progress.getSteps()).isEqualTo(25);
+ assertThat(progress.getRemaining()).isEqualTo(0);
}
- // TODO(b/260957933): FingerprintEnrollProgressViewModel::getErrorLiveData() and
- // FingerprintEnrollProgressViewModel::getHelpLiveData() doesn't built into apk because no one
- // uses it. We shall test it when new FingerprintEnrollEnrolling has used these 2 methods.
+ @Test
+ public void testGetErrorMessageLiveData() {
+ // Start enrollment
+ mViewModel.setToken(new byte[] { 1, 2, 3 });
+ final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
+ assertThat(ret).isTrue();
+ assertThat(mCallbackWrapper.mValue).isNotNull();
+
+ // Check default value
+ final LiveData<EnrollmentStatusMessage> liveData = mViewModel.getErrorMessageLiveData();
+ assertThat(liveData.getValue()).isNull();
+
+ // Notify error message
+ final int errMsgId = 3;
+ final String errMsg = "test error message";
+ mCallbackWrapper.mValue.onEnrollmentError(errMsgId, errMsg);
+ final EnrollmentStatusMessage value = liveData.getValue();
+ assertThat(value).isNotNull();
+ assertThat(value.getMsgId()).isEqualTo(errMsgId);
+ assertThat(value.getStr().toString()).isEqualTo(errMsg);
+ }
+
+ @Test
+ public void testGetHelpMessageLiveData() {
+ // Start enrollment
+ mViewModel.setToken(new byte[] { 1, 2, 3 });
+ final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
+ assertThat(ret).isTrue();
+ assertThat(mCallbackWrapper.mValue).isNotNull();
+
+ // Check default value
+ final LiveData<EnrollmentStatusMessage> liveData = mViewModel.getHelpMessageLiveData();
+ assertThat(liveData.getValue()).isNull();
+
+ // Notify help message
+ final int errMsgId = 3;
+ final String errMsg = "test error message";
+ mCallbackWrapper.mValue.onEnrollmentHelp(errMsgId, errMsg);
+ final EnrollmentStatusMessage value = liveData.getValue();
+ assertThat(value).isNotNull();
+ assertThat(value.getMsgId()).isEqualTo(errMsgId);
+ assertThat(value.getStr().toString()).isEqualTo(errMsg);
+ }
+
+ @Test
+ public void testGetAcquireLiveData() {
+ // Start enrollment
+ mViewModel.setToken(new byte[] { 1, 2, 3 });
+ final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
+ assertThat(ret).isTrue();
+ assertThat(mCallbackWrapper.mValue).isNotNull();
+
+ // Check default value
+ final LiveData<Boolean> liveData = mViewModel.getAcquireLiveData();
+ assertThat(liveData.getValue()).isNull();
+
+ // Notify acquire message
+ mCallbackWrapper.mValue.onAcquired(true);
+ assertThat(liveData.getValue()).isTrue();
+ }
+
+ @Test
+ public void testGetPointerDownLiveData() {
+ // Start enrollment
+ mViewModel.setToken(new byte[] { 1, 2, 3 });
+ final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
+ assertThat(ret).isTrue();
+ assertThat(mCallbackWrapper.mValue).isNotNull();
+
+ // Check default value
+ final LiveData<Integer> liveData = mViewModel.getPointerDownLiveData();
+ assertThat(liveData.getValue()).isNull();
+
+ // Notify acquire message
+ final int value = 33;
+ mCallbackWrapper.mValue.onPointerDown(value);
+ assertThat(liveData.getValue()).isEqualTo(value);
+ }
+
+ @Test
+ public void testGetPointerUpLiveData() {
+ // Start enrollment
+ mViewModel.setToken(new byte[] { 1, 2, 3 });
+ final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
+ assertThat(ret).isTrue();
+ assertThat(mCallbackWrapper.mValue).isNotNull();
+
+ // Check default value
+ final LiveData<Integer> liveData = mViewModel.getPointerUpLiveData();
+ assertThat(liveData.getValue()).isNull();
+
+ // Notify acquire message
+ final int value = 44;
+ mCallbackWrapper.mValue.onPointerUp(value);
+ assertThat(liveData.getValue()).isEqualTo(value);
+ }
private static class TestWrapper<T> {
T mValue;
diff --git a/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java b/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java
new file mode 100644
index 0000000..6622753
--- /dev/null
+++ b/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 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.language;
+
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.util.FeatureFlagUtils;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.Settings;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LanguagePreferenceControllerTest {
+ private boolean mCacheFeatureFlagSwitch = false;
+ private Context mContext;
+ private LanguagePreferenceController mController;
+
+ @Before
+ public void setup() {
+ mContext = ApplicationProvider.getApplicationContext();
+ mCacheFeatureFlagSwitch =
+ FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ mController = new LanguagePreferenceController(mContext, "key");
+
+ }
+
+ @After
+ public void tearDown() {
+ FeatureFlagUtils.setEnabled(
+ mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI, mCacheFeatureFlagSwitch);
+ }
+
+ @Test
+ public void getAvailabilityStatus_featureFlagOff_returnUnavailable() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
+ false);
+
+ int result = mController.getAvailabilityStatus();
+
+ assertEquals(CONDITIONALLY_UNAVAILABLE, result);
+ }
+
+ @Test
+ public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivityEnabled() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
+ false);
+
+ mController.getAvailabilityStatus();
+
+ assertTrue(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
+ assertFalse(isActivityEnable(mContext, Settings.LanguageSettingsActivity.class));
+ }
+
+ @Test
+ public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivitydisabled() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
+ true);
+
+ mController.getAvailabilityStatus();
+
+ assertFalse(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
+ assertTrue(isActivityEnable(mContext, Settings.LanguageSettingsActivity.class));
+ }
+
+ private static boolean isActivityEnable(Context context, Class klazz) {
+ PackageManager packageManager = context.getPackageManager();
+ ComponentName componentName =
+ new ComponentName(context, klazz);
+ int flag = packageManager.getComponentEnabledSetting(componentName);
+ return flag == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+ }
+}
diff --git a/tests/unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.java
index 292b4a9..39f2050 100644
--- a/tests/unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.java
@@ -28,9 +28,11 @@
import android.content.Context;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import androidx.lifecycle.Lifecycle;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -61,6 +63,10 @@
private CarrierConfigCache mCarrierConfigCache;
@Mock
private ProgressDialog mProgressDialog;
+ @Mock
+ private ServiceState mTestServiceState;
+ @Mock
+ private Lifecycle mLifecycle;
private PersistableBundle mCarrierConfig;
private AutoSelectPreferenceController mController;
@@ -88,7 +94,16 @@
mController = new AutoSelectPreferenceController(mContext, "auto_select");
mController.mProgressDialog = mProgressDialog;
mController.mSwitchPreference = mSwitchPreference;
- mController.init(SUB_ID);
+ mController.init(mLifecycle, SUB_ID);
+ sleepAfterInit();
+ }
+
+ private void sleepAfterInit() {
+ try {
+ Thread.sleep(2000);
+ } catch (Exception e) {
+ fail("Sleep timeout " + e);
+ }
}
@Test
@@ -111,7 +126,8 @@
@Test
public void updateState_isRoaming_enabled() {
- when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(true);
+ when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
+ when(mTestServiceState.getRoaming()).thenReturn(true);
mController.updateState(mSwitchPreference);
@@ -120,7 +136,8 @@
@Test
public void updateState_notRoamingWithAutoSelectOn_disabled() {
- when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(false);
+ when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
+ when(mTestServiceState.getRoaming()).thenReturn(false);
doReturn(OPERATOR_NAME).when(mTelephonyManager).getSimOperatorName();
mController.updateState(mSwitchPreference);
@@ -136,6 +153,34 @@
when(mCarrierConfigCache.getConfigForSubId(SUB_ID)).thenReturn(null);
// Should not crash
- mController.init(SUB_ID);
+ mController.init(mLifecycle, SUB_ID);
+ }
+
+ @Test
+ public void updateUiAutoSelectValue_serviceStateGetIsManualSelection_isCheckedFalse() {
+ when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
+ TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
+ when(mTestServiceState.getIsManualSelection()).thenReturn(true);
+ mController.init(mLifecycle, SUB_ID);
+ sleepAfterInit();
+
+ mController.updateUiAutoSelectValue(mTestServiceState);
+
+ assertThat(mController.isChecked()).isFalse();
+ assertThat(mSwitchPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void updateUiAutoSelectValue_serviceStateGetIsAutoSelection_isCheckedTrue() {
+ when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
+ TelephonyManager.NETWORK_SELECTION_MODE_MANUAL);
+ when(mTestServiceState.getIsManualSelection()).thenReturn(false);
+ mController.init(mLifecycle, SUB_ID);
+ sleepAfterInit();
+
+ mController.updateUiAutoSelectValue(mTestServiceState);
+
+ assertThat(mController.isChecked()).isTrue();
+ assertThat(mSwitchPreference.isChecked()).isTrue();
}
}