Snap for 13061484 from fdb47cee3b to 25Q2-release
Change-Id: Ie5fa996b7118f2010f1aa442b97a1dac1dbdd649
This commit is contained in:
22
res/drawable-v35/expressive_battery_hints_chip_bg.xml
Normal file
22
res/drawable-v35/expressive_battery_hints_chip_bg.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2025 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/settingslib_expressive_radius_medium" />
|
||||
<stroke android:width="1dp" android:color="@color/settingslib_materialColorOutline" />
|
||||
</shape>
|
||||
21
res/drawable-v35/expressive_battery_hints_chip_bg_ripple.xml
Normal file
21
res/drawable-v35/expressive_battery_hints_chip_bg_ripple.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2025 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.
|
||||
-->
|
||||
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:attr/colorControlHighlight">
|
||||
<item android:drawable="@drawable/expressive_battery_hints_chip_bg"/>
|
||||
</ripple>
|
||||
@@ -1,21 +0,0 @@
|
||||
<!--
|
||||
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="960" android:viewportHeight="960"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q614,800 707,707Q800,614 800,480Q800,473 799.5,465.5Q799,458 799,453Q794,482 772,501Q750,520 720,520L640,520Q607,520 583.5,496.5Q560,473 560,440L560,400L400,400L400,320Q400,287 423.5,263.5Q447,240 480,240L520,240L520,240Q520,217 532.5,199.5Q545,182 563,171Q543,166 522.5,163Q502,160 480,160Q346,160 253,253Q160,346 160,480Q160,480 160,480Q160,480 160,480L360,480Q426,480 473,527Q520,574 520,640L520,680L400,680L400,790Q420,795 439.5,797.5Q459,800 480,800Z"/>
|
||||
</vector>
|
||||
25
res/drawable/ic_settings_language_32dp.xml
Normal file
25
res/drawable/ic_settings_language_32dp.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<!--
|
||||
Copyright (C) 2025 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="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,880Q396.67,880 323.67,848.5Q250.67,817 196.5,762.83Q142.33,708.67 111.17,635.33Q80,562 80,478.67Q80,395 111.17,322.5Q142.33,250 196.5,195.83Q250.67,141.67 323.67,110.83Q396.67,80 480,80Q563.67,80 636.5,110.83Q709.33,141.67 763.5,195.83Q817.67,250 848.83,322.5Q880,395 880,478.67Q880,562 848.83,635.33Q817.67,708.67 763.5,762.83Q709.33,817 636.5,848.5Q563.67,880 480,880ZM480,814Q512,778 534,734Q556,690 570,632.67L390.67,632.67Q404,687.33 426,732.33Q448,777.33 480,814ZM388.67,800.67Q366,764.33 349.5,723.17Q333,682 322,632.67L182.67,632.67Q217.67,696.67 265.5,736Q313.33,775.33 388.67,800.67ZM572,800Q638.67,778.67 691.5,735.67Q744.33,692.67 777.33,632.67L638.67,632.67Q627,681.33 610.83,722.5Q594.67,763.67 572,800ZM158,566L309.33,566Q306.33,541.33 305.5,520.5Q304.67,499.67 304.67,478.67Q304.67,455 305.83,435.5Q307,416 310,393.33L158,393.33Q151.67,416 149.17,435.17Q146.67,454.33 146.67,478.67Q146.67,503 149.17,523.17Q151.67,543.33 158,566ZM377.33,566L583.33,566Q587,538.67 588.17,519.17Q589.33,499.67 589.33,478.67Q589.33,458.33 588.17,439.5Q587,420.67 583.33,393.33L377.33,393.33Q373.67,420.67 372.5,439.5Q371.33,458.33 371.33,478.67Q371.33,499.67 372.5,519.17Q373.67,538.67 377.33,566ZM650,566L802,566Q808.33,543.33 810.83,523.17Q813.33,503 813.33,478.67Q813.33,454.33 810.83,435.17Q808.33,416 802,393.33L650.67,393.33Q653.67,423.33 654.83,442.17Q656,461 656,478.67Q656,500.33 654.5,519.83Q653,539.33 650,566ZM638,326.67L777.33,326.67Q745.67,264 692.83,221Q640,178 571.33,159.33Q594,195 610.17,235.5Q626.33,276 638,326.67ZM390.67,326.67L570.67,326.67Q559.33,276.67 535.67,230.67Q512,184.67 480,147.33Q450,177.33 429,219.67Q408,262 390.67,326.67ZM182.67,326.67L322.67,326.67Q333,278 348.83,237.83Q364.67,197.67 388,160Q319.33,178.67 267.5,221Q215.67,263.33 182.67,326.67Z"/>
|
||||
</vector>
|
||||
43
res/layout-v35/expressive_warning_frame_preference.xml
Normal file
43
res/layout-v35/expressive_warning_frame_preference.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!--
|
||||
~ Copyright (C) 2025 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/settingslib_expressive_preference"
|
||||
android:id="@+id/preference_frame"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/warning_chip_frame"
|
||||
android:visibility="gone"
|
||||
android:clickable="false"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/settingslib_expressive_space_small1"
|
||||
android:layout_marginTop="-8dp">
|
||||
<Space
|
||||
android:id="@+id/warning_padding_placeholder"
|
||||
android:layout_width="@dimen/settingslib_expressive_space_medium3"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginEnd="@dimen/settingslib_expressive_space_extrasmall6"/>
|
||||
|
||||
<include layout="@layout/power_anomaly_hints"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -44,7 +44,8 @@
|
||||
android:textAlignment="textStart"
|
||||
android:text="@string/add_a_language"
|
||||
style="@style/Base.Widget.AppCompat.Button.Borderless"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"/>
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -17,13 +17,12 @@
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical|start"
|
||||
android:padding="8dp"
|
||||
android:background="@drawable/battery_hints_chip_bg_ripple">
|
||||
android:id="@+id/warning_chip"
|
||||
android:padding="8dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="20dp"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time_summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="4dp"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
|
||||
<include layout="@layout/power_anomaly_hints"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/anomaly_hints"
|
||||
android:paddingBottom="20dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -66,6 +66,8 @@
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:progressBackgroundTint="@color/settingslib_materialColorOutline"
|
||||
android:progressTint="@color/settingslib_materialColorPrimaryFixed"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"/>
|
||||
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/Theme.AppCompat.DayNight">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -43,17 +45,24 @@
|
||||
android:id="@+id/private_dns_mode_provider"
|
||||
layout="@layout/preference_widget_dialog_radiobutton"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/private_dns_mode_provider_hostname"
|
||||
android:hint="@string/private_dns_mode_provider_hostname_hint"
|
||||
style="@android:style/Widget.CompoundButton.RadioButton"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textFilter|textUri|textMultiLine"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/private_dns_mode_provider_hostname_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="3dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:minHeight="@dimen/developer_option_dialog_min_height"/>
|
||||
android:hint="@string/private_dns_title"
|
||||
android:theme="@style/Theme.Settings"
|
||||
app:endIconMode="clear_text"
|
||||
app:errorEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/private_dns_mode_provider_hostname"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textFilter|textUri|textMultiLine"
|
||||
android:layout_marginStart="3dp"
|
||||
android:layout_marginEnd="8dp"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</RadioGroup>
|
||||
|
||||
<include
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<include layout="@layout/preference_app"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/warning_chip"
|
||||
android:id="@+id/warning_chip_frame"
|
||||
android:visibility="gone"
|
||||
android:clickable="false"
|
||||
android:layout_width="match_parent"
|
||||
@@ -32,13 +32,12 @@
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||
|
||||
<Space
|
||||
android:id="@+id/warning_padding_placeholder"
|
||||
android:layout_width="@dimen/secondary_app_icon_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginEnd="16dp"/>
|
||||
|
||||
<include layout="@layout/power_anomaly_hints" />
|
||||
|
||||
<include layout="@layout/power_anomaly_hints"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -555,4 +555,10 @@
|
||||
<dimen name="display_block_padding">5dp</dimen>
|
||||
<dimen name="display_block_highlight_width">2dp</dimen>
|
||||
<dimen name="display_block_corner_radius">10dp</dimen>
|
||||
|
||||
<!-- Locale Picker -->
|
||||
<dimen name="locale_picker_dialog_icon_padding">10dp</dimen>
|
||||
<dimen name="locale_picker_dialog_title_padding">16dp</dimen>
|
||||
<dimen name="locale_picker_dialog_message_padding_left_right">24dp</dimen>
|
||||
<dimen name="locale_picker_dialog_message_padding_bottom">32dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -305,8 +305,6 @@
|
||||
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
<string name="connected_device_media_device_title">Media devices</string>
|
||||
<!-- Title for temporary bond device group [CHAR LIMIT=none]-->
|
||||
<string name="connected_device_temp_bond_device_title">Guest devices</string>
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
<string name="connected_device_call_device_title">Call devices</string>
|
||||
<!-- Title for connected device group [CHAR LIMIT=none]-->
|
||||
@@ -502,7 +500,7 @@
|
||||
<!-- The text of the confirmation dialog showing the system locale will be changed. [CHAR LIMIT=NONE]-->
|
||||
<string name="desc_notice_device_locale_settings_change">Your device settings and regional preferences will change.</string>
|
||||
|
||||
<!-- A dialog button for confirmmation of system locale change. [CHAR LIMIT=25]-->
|
||||
<!-- A dialog button for confirmation of system locale change. [CHAR LIMIT=25]-->
|
||||
<string name="button_label_confirmation_of_system_locale_change">Change</string>
|
||||
|
||||
<!-- Title for saying this selected locale is unavailable to use. [CHAR LIMIT=50]-->
|
||||
@@ -530,10 +528,11 @@
|
||||
<!-- Category for more language settings. [CHAR LIMIT=NONE]-->
|
||||
<string name="more_language_settings_category">More language settings</string>
|
||||
<!-- Title for asking to change system locale region or not. [CHAR LIMIT=50]-->
|
||||
<string name="title_change_system_locale_region">Change region to %s ?</string>
|
||||
<string name="title_change_system_locale_region">Change region to <xliff:g id="system_language_region" example="Canada">%1$s</xliff:g> ?</string>
|
||||
<!-- Message for asking to change system locale region or not. [CHAR LIMIT=50]-->
|
||||
<string name="body_change_system_locale_region">Your device will keep %s as a system language</string>
|
||||
<string name="top_intro_numbering_system_title">The digits used will be dependent on the numbering system</string>
|
||||
<string name="body_change_system_locale_region">Your device will keep <xliff:g id="system_language" example="English">%1$s</xliff:g> as a system language</string>
|
||||
<!-- Description for the numbering system language. [CHAR LIMIT=NONE]-->
|
||||
<string name="top_intro_numbering_system_title">Most apps will use your regional preferences</string>
|
||||
|
||||
<!-- Regional Preferences begin -->
|
||||
<!-- The title of the menu entry of regional preferences. [CHAR LIMIT=50] -->
|
||||
@@ -2937,6 +2936,12 @@
|
||||
<string name="emergency_address_title">Emergency address</string>
|
||||
<!-- Summary of Update Emergency Address preference, explaining usage of emergency address [CHAR LIMIT=NONE] -->
|
||||
<string name="emergency_address_summary">Used as your location when you make an emergency call over Wi\u2011Fi</string>
|
||||
<!-- Title of a preference for private DNS provider hostname [CHAR LIMIT=40] -->
|
||||
<string name="private_dns_title">Hostname</string>
|
||||
<!-- Message of private dns hostname that the field is required. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_dns_field_require">The field is required</string>
|
||||
<!-- The error if the private dns hostname is not valid -->
|
||||
<string name="private_dns_hostname_invalid">The hostname you typed isn\u2019t valid</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] -->
|
||||
@@ -13968,13 +13973,15 @@
|
||||
<string name="audio_sharing_share_with_button_label">Share with <xliff:g example="My buds" id="device_name">%1$s</xliff:g></string>
|
||||
<!-- Text for audio sharing close button [CHAR LIMIT=none]-->
|
||||
<string name="audio_sharing_close_button_label">Close</string>
|
||||
<!-- Content for audio sharing share dialog with no device, ask users to connect device [CHAR LIMIT=none]-->
|
||||
<!-- Content for audio sharing share dialog with no second device, ask users to connect device [CHAR LIMIT=none]-->
|
||||
<string name="audio_sharing_dialog_connect_device_content">Connect another pair of compatible headphones, or share your stream\'s name and password with the other person</string>
|
||||
<!-- Content for audio sharing share dialog with no device, ask users to scan qr code [CHAR LIMIT=none]-->
|
||||
<!-- Content for audio sharing share dialog with no second device, ask users to scan qr code [CHAR LIMIT=none]-->
|
||||
<string name="audio_sharing_dialog_qr_code_content">Let others scan this code and listen to your audio\n\nStream name: <xliff:g example="Pixel 8" id="stream_name">%1$s</xliff:g>\nPassword: <xliff:g example="123456" id="password">%2$s</xliff:g></string>
|
||||
<!-- Content for audio sharing share dialog with no device, ask users to pair new device [CHAR LIMIT=none]-->
|
||||
<!-- Content for audio sharing share dialog with no second device and no password, ask users to scan qr code [CHAR LIMIT=none]-->
|
||||
<string name="audio_sharing_dialog_qr_code_content_no_password">Let others scan this code and listen to your audio\n\nStream name: <xliff:g example="Pixel 8" id="stream_name">%1$s</xliff:g></string>
|
||||
<!-- Content for audio sharing share dialog with no second device, ask users to pair new device [CHAR LIMIT=none]-->
|
||||
<string name="audio_sharing_dialog_pair_new_device_content">or pair another set of compatible headphones</string>
|
||||
<!-- Content for audio sharing share dialog with no device, ask users to pair device [CHAR LIMIT=none]-->
|
||||
<!-- Content for audio sharing share dialog with no second device, ask users to pair device [CHAR LIMIT=none]-->
|
||||
<string name="audio_sharing_dialog_pair_device_content">Pair another set of compatible headphones, or share your audio stream QR code with the other person</string>
|
||||
<!-- Text for sharing audio sharing state [CHAR LIMIT=none]-->
|
||||
<string name="audio_sharing_sharing_label">Sharing audio</string>
|
||||
|
||||
@@ -26,17 +26,6 @@
|
||||
settings:allowDividerBelow="true"
|
||||
settings:controller="com.android.settings.slices.SlicePreferenceController" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="audio_sharing_device_list"
|
||||
android:title="@string/audio_sharing_device_group_title"
|
||||
settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingDevicePreferenceController">
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="temp_bond_device_list"
|
||||
android:title="@string/connected_device_temp_bond_device_title"
|
||||
settings:controller="com.android.settings.connecteddevice.audiosharing.TemporaryBondDeviceGroupController" />
|
||||
|
||||
<Preference
|
||||
android:fragment="com.android.settings.connecteddevice.audiosharing.AudioSharingDashboardFragment"
|
||||
android:icon="@drawable/ic_bt_le_audio_sharing"
|
||||
@@ -45,6 +34,12 @@
|
||||
settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingPreferenceController"
|
||||
settings:searchable="false" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="audio_sharing_device_list"
|
||||
android:title="@string/audio_sharing_device_group_title"
|
||||
settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingDevicePreferenceController">
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="available_device_list"
|
||||
android:title="@string/connected_device_media_device_title"
|
||||
|
||||
@@ -31,6 +31,13 @@
|
||||
<com.android.settingslib.widget.LayoutPreference
|
||||
android:key="languages_picker"
|
||||
android:layout="@layout/locale_order_list" />
|
||||
|
||||
<Preference
|
||||
android:key="add_a_language"
|
||||
android:title="@string/add_a_language"
|
||||
android:icon="@drawable/ic_add_24dp"
|
||||
settings:isPreferenceVisible="false"
|
||||
settings:fragment="com.android.settings.localepicker.SystemLocalePickerFragment"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -139,13 +138,8 @@ public class ApprovalPreferenceController extends BasePreferenceController {
|
||||
public void disable(final ComponentName cn) {
|
||||
logSpecialPermissionChange(true, cn.getPackageName());
|
||||
mNm.setNotificationListenerAccessGranted(cn, false);
|
||||
if (!mNm.isNotificationPolicyAccessGrantedForPackage(
|
||||
cn.getPackageName())) {
|
||||
if (android.app.Flags.modesApi()) {
|
||||
mNm.removeAutomaticZenRules(cn.getPackageName(), /* fromUser= */ true);
|
||||
} else {
|
||||
mNm.removeAutomaticZenRules(cn.getPackageName());
|
||||
}
|
||||
if (!mNm.isNotificationPolicyAccessGrantedForPackage(cn.getPackageName())) {
|
||||
mNm.removeAutomaticZenRules(cn.getPackageName(), /* fromUser= */ true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public class FriendlyWarningDialogFragment extends InstrumentedDialogFragment {
|
||||
NotificationAccessDetails parent = (NotificationAccessDetails) getTargetFragment();
|
||||
|
||||
final String summary = getResources().getString(
|
||||
Flags.modesApi() && Flags.modesUi()
|
||||
Flags.modesUi()
|
||||
? R.string.notification_listener_disable_modes_warning_summary
|
||||
: R.string.notification_listener_disable_warning_summary,
|
||||
label);
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ScaryWarningDialogFragment extends InstrumentedDialogFragment {
|
||||
((TextView) content.findViewById(R.id.prompt)).setText(prompt);
|
||||
|
||||
((TextView) content.findViewById(R.id.settings_description)).setText(
|
||||
Flags.modesApi() && Flags.modesUi()
|
||||
Flags.modesUi()
|
||||
? R.string.nls_feature_modes_settings_summary
|
||||
: R.string.nls_feature_settings_summary);
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ public class FriendlyWarningDialogFragment extends InstrumentedDialogFragment {
|
||||
final String label = args.getString(KEY_LABEL);
|
||||
|
||||
final String title = getResources().getString(
|
||||
Flags.modesApi() && Flags.modesUi()
|
||||
Flags.modesUi()
|
||||
? R.string.zen_modes_access_revoke_warning_dialog_title
|
||||
: R.string.zen_access_revoke_warning_dialog_title,
|
||||
label);
|
||||
final String summary = getResources()
|
||||
.getString(Flags.modesApi() && Flags.modesUi()
|
||||
.getString(Flags.modesUi()
|
||||
? R.string.zen_modes_access_revoke_warning_dialog_summary
|
||||
: R.string.zen_access_revoke_warning_dialog_summary);
|
||||
|
||||
|
||||
@@ -57,12 +57,12 @@ public class ScaryWarningDialogFragment extends InstrumentedDialogFragment {
|
||||
final String label = args.getString(KEY_LABEL);
|
||||
|
||||
final String title = getResources().getString(
|
||||
Flags.modesApi() && Flags.modesUi()
|
||||
Flags.modesUi()
|
||||
? R.string.zen_modes_access_warning_dialog_title
|
||||
: R.string.zen_access_warning_dialog_title,
|
||||
label);
|
||||
final String summary = getResources()
|
||||
.getString(Flags.modesApi() && Flags.modesUi()
|
||||
.getString(Flags.modesUi()
|
||||
? R.string.zen_modes_access_warning_dialog_summary
|
||||
: R.string.zen_access_warning_dialog_summary);
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ZenAccessController extends BasePreferenceController {
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
Preference preference = screen.findPreference(getPreferenceKey());
|
||||
if (preference != null) {
|
||||
preference.setTitle(Flags.modesApi() && Flags.modesUi()
|
||||
preference.setTitle(Flags.modesUi()
|
||||
? R.string.manage_zen_modes_access_title
|
||||
: R.string.manage_zen_access_title);
|
||||
}
|
||||
@@ -116,11 +116,7 @@ public class ZenAccessController extends BasePreferenceController {
|
||||
|
||||
public static void deleteRules(final Context context, final String pkg) {
|
||||
final NotificationManager mgr = context.getSystemService(NotificationManager.class);
|
||||
if (android.app.Flags.modesApi()) {
|
||||
mgr.removeAutomaticZenRules(pkg, /* fromUser= */ true);
|
||||
} else {
|
||||
mgr.removeAutomaticZenRules(pkg);
|
||||
}
|
||||
mgr.removeAutomaticZenRules(pkg, /* fromUser= */ true);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ZenAccessDetails extends AppInfoWithHeader implements
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
requireActivity().setTitle(Flags.modesApi() && Flags.modesUi()
|
||||
requireActivity().setTitle(Flags.modesUi()
|
||||
? R.string.manage_zen_modes_access_title
|
||||
: R.string.manage_zen_access_title);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public class ZenAccessDetails extends AppInfoWithHeader implements
|
||||
preference.setSummary(getString(R.string.zen_access_disabled_package_warning));
|
||||
return;
|
||||
}
|
||||
preference.setTitle(Flags.modesApi() && Flags.modesUi()
|
||||
preference.setTitle(Flags.modesUi()
|
||||
? R.string.zen_modes_access_detail_switch
|
||||
: R.string.zen_access_detail_switch);
|
||||
preference.setChecked(ZenAccessController.hasAccess(context, mPackageName));
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.flags.Flags;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
/** Controller to maintain available media Bluetooth devices */
|
||||
@@ -61,14 +60,6 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
|
||||
|
||||
@Override
|
||||
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
|
||||
// If the device is temporary bond, it shouldn't be shown here.
|
||||
if (Flags.enableTemporaryBondDevicesUi()
|
||||
&& BluetoothUtils.isTemporaryBondDevice(cachedDevice.getDevice())) {
|
||||
Log.d(TAG,
|
||||
"isFilterMatched() Filter out temporary bond device " + cachedDevice.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
final int currentAudioProfile;
|
||||
|
||||
if (mAudioMode == AudioManager.MODE_RINGTONE
|
||||
|
||||
@@ -57,14 +57,6 @@ public class ConnectedBluetoothDeviceUpdater extends BluetoothDeviceUpdater {
|
||||
|
||||
@Override
|
||||
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
|
||||
// If the device is temporary bond, it shouldn't be shown here.
|
||||
if (Flags.enableTemporaryBondDevicesUi()
|
||||
&& BluetoothUtils.isTemporaryBondDevice(cachedDevice.getDevice())) {
|
||||
Log.d(TAG,
|
||||
"isFilterMatched() Filter out temporary bond device " + cachedDevice.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
final int currentAudioProfile;
|
||||
|
||||
if (mAudioMode == AudioManager.MODE_RINGTONE
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.connecteddevice.audiosharing.AudioSharingDevicePreferenceController;
|
||||
import com.android.settings.connecteddevice.audiosharing.TemporaryBondDeviceGroupController;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.overlay.SurveyFeatureProvider;
|
||||
@@ -35,7 +34,6 @@ import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.slices.SlicePreferenceController;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.HearingAidStatsLogUtils;
|
||||
import com.android.settingslib.flags.Flags;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
|
||||
@@ -84,9 +82,6 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
||||
}
|
||||
if (BluetoothUtils.isAudioSharingUIAvailable(context)) {
|
||||
use(AudioSharingDevicePreferenceController.class).init(this);
|
||||
if (Flags.enableTemporaryBondDevicesUi()) {
|
||||
use(TemporaryBondDeviceGroupController.class).init(this);
|
||||
}
|
||||
}
|
||||
use(AvailableMediaDeviceGroupController.class).init(this);
|
||||
use(ConnectedDeviceGroupController.class).init(this);
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.flags.Flags;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
public class AudioSharingBluetoothDeviceUpdater extends BluetoothDeviceUpdater
|
||||
@@ -52,14 +51,6 @@ public class AudioSharingBluetoothDeviceUpdater extends BluetoothDeviceUpdater
|
||||
|
||||
@Override
|
||||
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
|
||||
// If the device is temporary bond, it shouldn't be shown here.
|
||||
if (Flags.enableTemporaryBondDevicesUi()
|
||||
&& BluetoothUtils.isTemporaryBondDevice(cachedDevice.getDevice())) {
|
||||
Log.d(TAG,
|
||||
"isFilterMatched() Filter out temporary bond device " + cachedDevice.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isFilterMatched = false;
|
||||
if (isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)) {
|
||||
// If device is LE audio device and has a broadcast source,
|
||||
|
||||
@@ -67,7 +67,6 @@ import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** PreferenceController to control the dialog to choose the active device for calls and alarms */
|
||||
public class AudioSharingCallAudioPreferenceController extends AudioSharingBasePreferenceController
|
||||
@@ -404,21 +403,11 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP
|
||||
|
||||
private void updateDeviceItemsInSharingSession() {
|
||||
mGroupedConnectedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(mBtManager);
|
||||
if (Flags.enableTemporaryBondDevicesUi()) {
|
||||
mGroupedConnectedDevices =
|
||||
mGroupedConnectedDevices.entrySet().stream()
|
||||
.filter(entry -> !anyTemporaryBondDevice(entry.getValue()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
mDeviceItemsInSharingSession =
|
||||
AudioSharingUtils.buildOrderedConnectedLeadAudioSharingDeviceItem(
|
||||
mBtManager, mGroupedConnectedDevices, /* filterByInSharing= */ true);
|
||||
}
|
||||
|
||||
private boolean anyTemporaryBondDevice(List<BluetoothDevice> connectedDevices) {
|
||||
return connectedDevices.stream().anyMatch(BluetoothUtils::isTemporaryBondDevice);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Pair<Integer, AudioSharingDeviceItem> getActiveItemWithIndex() {
|
||||
List<AudioSharingDeviceItem> deviceItems = new ArrayList<>(mDeviceItemsInSharingSession);
|
||||
|
||||
@@ -186,14 +186,17 @@ public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
|
||||
Drawable qrCodeDrawable = metadata == null ? null : getQrCodeDrawable(metadata,
|
||||
getContext()).orElse(null);
|
||||
if (qrCodeDrawable != null) {
|
||||
String broadcastName =
|
||||
metadata.getBroadcastName() == null ? "" : metadata.getBroadcastName();
|
||||
boolean hasPassword = metadata.getBroadcastCode() != null
|
||||
&& metadata.getBroadcastCode().length > 0;
|
||||
String message = hasPassword ? getString(
|
||||
R.string.audio_sharing_dialog_qr_code_content, broadcastName,
|
||||
new String(metadata.getBroadcastCode(), StandardCharsets.UTF_8)) :
|
||||
getString(R.string.audio_sharing_dialog_qr_code_content_no_password,
|
||||
broadcastName);
|
||||
builder.setCustomImage(qrCodeDrawable)
|
||||
.setCustomMessage(
|
||||
getString(
|
||||
R.string.audio_sharing_dialog_qr_code_content,
|
||||
metadata.getBroadcastName(),
|
||||
new String(
|
||||
metadata.getBroadcastCode(),
|
||||
StandardCharsets.UTF_8)))
|
||||
.setCustomMessage(message)
|
||||
.setCustomMessage2(R.string.audio_sharing_dialog_pair_new_device_content)
|
||||
.setCustomNegativeButton(R.string.audio_streams_dialog_close,
|
||||
v -> onCancelClick());
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.connecteddevice.audiosharing;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settingslib.bluetooth.BluetoothCallback;
|
||||
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.flags.Flags;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
/**
|
||||
* Controller to maintain the {@link androidx.preference.PreferenceGroup} for all connected
|
||||
* temporary bond devices. It uses {@link DevicePreferenceCallback} to add/remove
|
||||
* {@link Preference}
|
||||
*/
|
||||
public class TemporaryBondDeviceGroupController extends BasePreferenceController implements
|
||||
DefaultLifecycleObserver, DevicePreferenceCallback, BluetoothCallback {
|
||||
private static final String TAG = "TemporaryBondDeviceGroupController";
|
||||
private static final String KEY = "temp_bond_device_list";
|
||||
|
||||
@Nullable
|
||||
private final BluetoothEventManager mEventManager;
|
||||
@Nullable
|
||||
private PreferenceGroup mPreferenceGroup;
|
||||
@Nullable
|
||||
private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
|
||||
|
||||
|
||||
public TemporaryBondDeviceGroupController(@NonNull Context context) {
|
||||
super(context, KEY);
|
||||
LocalBluetoothManager btManager = Utils.getLocalBtManager(mContext);
|
||||
mEventManager = btManager == null ? null : btManager.getEventManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(@NonNull LifecycleOwner owner) {
|
||||
if (!isAvailable()) {
|
||||
Log.d(TAG, "Skip onStart(), feature is not supported.");
|
||||
return;
|
||||
}
|
||||
if (mEventManager == null) {
|
||||
Log.d(TAG, "onStart() Bluetooth is not supported on this device");
|
||||
return;
|
||||
}
|
||||
var unused = ThreadUtils.postOnBackgroundThread(() -> {
|
||||
mEventManager.registerCallback(this);
|
||||
if (mBluetoothDeviceUpdater != null) {
|
||||
mBluetoothDeviceUpdater.registerCallback();
|
||||
mBluetoothDeviceUpdater.refreshPreference();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(@NonNull LifecycleOwner owner) {
|
||||
var unused = ThreadUtils.postOnBackgroundThread(() -> {
|
||||
if (mBluetoothDeviceUpdater != null) {
|
||||
mBluetoothDeviceUpdater.unregisterCallback();
|
||||
}
|
||||
if (mEventManager != null) {
|
||||
mEventManager.unregisterCallback(this);
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "onStop() Bluetooth is not supported on this device");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(@NonNull PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreferenceGroup = screen.findPreference(KEY);
|
||||
if (mPreferenceGroup != null) {
|
||||
mPreferenceGroup.setVisible(false);
|
||||
}
|
||||
|
||||
if (isAvailable() && mBluetoothDeviceUpdater != null) {
|
||||
mBluetoothDeviceUpdater.setPrefContext(screen.getContext());
|
||||
mBluetoothDeviceUpdater.forceUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceAdded(@NonNull Preference preference) {
|
||||
if (mPreferenceGroup != null) {
|
||||
mPreferenceGroup.addPreference(preference);
|
||||
Log.d(TAG, "Temporary bond device added");
|
||||
if (mPreferenceGroup.getPreferenceCount() == 1) {
|
||||
mPreferenceGroup.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceRemoved(@NonNull Preference preference) {
|
||||
if (mPreferenceGroup != null) {
|
||||
mPreferenceGroup.removePreference(preference);
|
||||
Log.d(TAG, "Temporary bond device removed");
|
||||
if (mPreferenceGroup.getPreferenceCount() == 0) {
|
||||
mPreferenceGroup.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return (BluetoothUtils.isAudioSharingUIAvailable(mContext)
|
||||
&& mBluetoothDeviceUpdater != null && Flags.enableTemporaryBondDevicesUi())
|
||||
? AVAILABLE_UNSEARCHABLE
|
||||
: UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the controller.
|
||||
*
|
||||
* @param fragment The fragment to provide the context and metrics category for {@link
|
||||
* TemporaryBondDeviceGroupUpdater} and provide the host for dialogs.
|
||||
*/
|
||||
public void init(@NonNull DashboardFragment fragment) {
|
||||
mBluetoothDeviceUpdater = new TemporaryBondDeviceGroupUpdater(fragment.getContext(),
|
||||
TemporaryBondDeviceGroupController.this,
|
||||
fragment.getMetricsCategory());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setBluetoothDeviceUpdater(@Nullable BluetoothDeviceUpdater bluetoothDeviceUpdater) {
|
||||
mBluetoothDeviceUpdater = bluetoothDeviceUpdater;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setPreferenceGroup(@Nullable PreferenceGroup preferenceGroup) {
|
||||
mPreferenceGroup = preferenceGroup;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.connecteddevice.audiosharing;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
|
||||
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.flags.Flags;
|
||||
|
||||
/** Maintain and update connected temporary bond bluetooth devices */
|
||||
public class TemporaryBondDeviceGroupUpdater extends BluetoothDeviceUpdater {
|
||||
private static final String TAG = "TemporaryBondDeviceGroupUpdater";
|
||||
private static final String PREF_KEY_PREFIX = "temp_bond_bt_";
|
||||
|
||||
public TemporaryBondDeviceGroupUpdater(
|
||||
@NonNull Context context,
|
||||
@NonNull DevicePreferenceCallback devicePreferenceCallback,
|
||||
int metricsCategory) {
|
||||
super(context, devicePreferenceCallback, metricsCategory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilterMatched(@NonNull CachedBluetoothDevice cachedDevice) {
|
||||
// Only connected temporary bond device should be shown in this section when Audio
|
||||
// sharing UI is available.
|
||||
boolean isFilterMatched = Flags.enableTemporaryBondDevicesUi()
|
||||
&& BluetoothUtils.isTemporaryBondDevice(cachedDevice.getDevice())
|
||||
&& isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)
|
||||
&& BluetoothUtils.isAudioSharingUIAvailable(mContext);
|
||||
Log.d(
|
||||
TAG,
|
||||
"isFilterMatched() device : "
|
||||
+ cachedDevice.getName()
|
||||
+ ", isFilterMatched : "
|
||||
+ isFilterMatched);
|
||||
return isFilterMatched;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPreferenceKeyPrefix() {
|
||||
return PREF_KEY_PREFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(CachedBluetoothDevice cachedBluetoothDevice) {
|
||||
super.update(cachedBluetoothDevice);
|
||||
Log.d(TAG, "Map : " + mPreferenceMap);
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ import com.android.settingslib.widget.TwoTargetPreference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* The Settings screen for External Displays configuration and connection management.
|
||||
@@ -85,8 +86,6 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
|
||||
BUILTIN_DISPLAY_LIST(70, "builtin_display_list_preference",
|
||||
R.string.builtin_display_settings_category),
|
||||
|
||||
DISPLAYS_LIST(80, "displays_list_preference", null),
|
||||
|
||||
// If shown, footer should appear below everything.
|
||||
FOOTER(90, "footer_preference", null);
|
||||
|
||||
@@ -333,15 +332,6 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
|
||||
return args != null ? args.getInt(DISPLAY_ID_ARG, INVALID_DISPLAY) : INVALID_DISPLAY;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private PreferenceCategory getDisplaysListPreference(@NonNull Context context) {
|
||||
if (mDisplaysPreference == null) {
|
||||
mDisplaysPreference = new PreferenceCategory(context);
|
||||
PrefBasics.DISPLAYS_LIST.apply(mDisplaysPreference);
|
||||
}
|
||||
return mDisplaysPreference;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private PreferenceCategory getBuiltinDisplayListPreference(@NonNull Context context) {
|
||||
if (mBuiltinDisplayPreference == null) {
|
||||
@@ -455,6 +445,26 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
|
||||
EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE));
|
||||
}
|
||||
|
||||
private static PreferenceCategory getCategoryForDisplay(@NonNull Display display,
|
||||
@NonNull PrefRefresh screen, @NonNull Context context) {
|
||||
// The rest of the settings are in a category with the display name as the title.
|
||||
String categoryKey = "expanded_display_items_" + display.getDisplayId();
|
||||
var category = (PreferenceCategory) screen.findUnusedPreference(categoryKey);
|
||||
|
||||
if (category != null) {
|
||||
screen.addPreference(category);
|
||||
} else {
|
||||
category = new PreferenceCategory(context);
|
||||
screen.addPreference(category);
|
||||
category.setPersistent(false);
|
||||
category.setKey(categoryKey);
|
||||
category.setTitle(display.getName());
|
||||
category.setOrder(PrefBasics.BUILTIN_DISPLAY_LIST.order + 1);
|
||||
}
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
private void showDisplaySettings(@NonNull Display display, @NonNull PrefRefresh screen,
|
||||
@NonNull Context context) {
|
||||
final var isEnabled = mInjector != null && mInjector.isDisplayEnabled(display);
|
||||
@@ -469,8 +479,18 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
|
||||
if (!isTopologyPaneEnabled(mInjector)) {
|
||||
screen.addPreference(updateIllustrationImage(context, displayRotation));
|
||||
}
|
||||
screen.addPreference(updateResolutionPreference(context, display));
|
||||
screen.addPreference(updateRotationPreference(context, display, displayRotation));
|
||||
|
||||
Consumer<Preference> adder;
|
||||
if (isTopologyPaneEnabled(mInjector)) {
|
||||
adder = getCategoryForDisplay(display, screen, context)::addPreference;
|
||||
// The category may have already been populated if it was retrieved from the PrefRefresh
|
||||
// backup, but we still need to update resolution and rotation items.
|
||||
} else {
|
||||
adder = screen::addPreference;
|
||||
}
|
||||
|
||||
adder.accept(updateResolutionPreference(context, display));
|
||||
adder.accept(updateRotationPreference(context, display, displayRotation));
|
||||
if (isResolutionSettingEnabled(mInjector)) {
|
||||
// Do not show the footer about changing resolution affecting apps. This is not in the
|
||||
// UX design for v2, and there is no good place to put it, since (a) if it is on the
|
||||
@@ -483,12 +503,12 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
|
||||
// TODO(b/352648432): probably remove footer once the pane and rest of v2 UI is in
|
||||
// place.
|
||||
if (!isTopologyPaneEnabled(mInjector)) {
|
||||
screen.addPreference(updateFooterPreference(context,
|
||||
adder.accept(updateFooterPreference(context,
|
||||
EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE));
|
||||
}
|
||||
}
|
||||
if (isDisplaySizeSettingEnabled(mInjector)) {
|
||||
screen.addPreference(updateSizePreference(context));
|
||||
adder.accept(updateSizePreference(context));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,23 +528,28 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
|
||||
private void showDisplaysList(@NonNull List<Display> displaysToShow,
|
||||
@NonNull PrefRefresh screen, @NonNull Context context) {
|
||||
maybeAddV2Components(context, screen);
|
||||
var displayGroupPref = getDisplaysListPreference(context);
|
||||
if (!displaysToShow.isEmpty()) {
|
||||
screen.addPreference(displayGroupPref);
|
||||
}
|
||||
try (var groupCleanable = new PrefRefresh(displayGroupPref)) {
|
||||
for (var display : displaysToShow) {
|
||||
var pref = getDisplayPreference(context, display, groupCleanable);
|
||||
pref.setSummary(display.getMode().getPhysicalWidth() + " x "
|
||||
+ display.getMode().getPhysicalHeight());
|
||||
}
|
||||
int order = PrefBasics.BUILTIN_DISPLAY_LIST.order;
|
||||
for (var display : displaysToShow) {
|
||||
var pref = getDisplayPreference(context, display, screen, ++order);
|
||||
pref.setSummary(display.getMode().getPhysicalWidth() + " x "
|
||||
+ display.getMode().getPhysicalHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static String displayListDisplayCategoryKey(int displayId) {
|
||||
return "display_list_display_category_" + displayId;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static String resolutionRotationPreferenceKey(int displayId) {
|
||||
return "display_id_" + displayId;
|
||||
}
|
||||
|
||||
private Preference getDisplayPreference(@NonNull Context context,
|
||||
@NonNull Display display, @NonNull PrefRefresh groupCleanable) {
|
||||
var itemKey = "display_id_" + display.getDisplayId();
|
||||
var categoryKey = itemKey + "_category";
|
||||
@NonNull Display display, @NonNull PrefRefresh groupCleanable, int categoryOrder) {
|
||||
var itemKey = resolutionRotationPreferenceKey(display.getDisplayId());
|
||||
var categoryKey = displayListDisplayCategoryKey(display.getDisplayId());
|
||||
var category = (PreferenceCategory) groupCleanable.findUnusedPreference(categoryKey);
|
||||
|
||||
if (category != null) {
|
||||
@@ -534,6 +559,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
|
||||
category = new PreferenceCategory(context);
|
||||
category.setPersistent(false);
|
||||
category.setKey(categoryKey);
|
||||
category.setOrder(categoryOrder);
|
||||
// Must add the category to the hierarchy before adding its descendants. Otherwise
|
||||
// the category will not have a preference manager, which causes an exception when a
|
||||
// child is added to it.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController.A2DP_OFFLOAD_SUPPORTED_PROPERTY;
|
||||
import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController.A2DP_OFFLOAD_DISABLED_PROPERTY;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
@@ -105,13 +106,14 @@ public class BluetoothLeAudioHwOffloadPreferenceController
|
||||
(mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
final boolean leAudioOffloadSupported =
|
||||
SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_SUPPORTED_PROPERTY, false);
|
||||
final boolean a2dpOffloadDisabled =
|
||||
SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false);
|
||||
if (leAudioEnabled && leAudioOffloadSupported && !a2dpOffloadDisabled) {
|
||||
((TwoStatePreference) mPreference).setChecked(true);
|
||||
SystemProperties.set(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, "true");
|
||||
} else {
|
||||
final boolean a2dpOffloadSupported =
|
||||
SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false);
|
||||
|
||||
if(!leAudioEnabled || !leAudioOffloadSupported || !a2dpOffloadSupported) {
|
||||
mPreference.setEnabled(false);
|
||||
} else {
|
||||
((TwoStatePreference) mPreference).setChecked(false);
|
||||
SystemProperties.set(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, "false");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ public class DesktopExperiencePreferenceController extends DeveloperOptionsPrefe
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
if (DesktopModeStatus.isInternalDisplayEligibleToHostDesktops(mContext)
|
||||
if (DesktopModeStatus.isDeviceEligibleForDesktopMode(mContext)
|
||||
&& !DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODE.isTrue()) {
|
||||
return mContext.getString(
|
||||
R.string.enable_desktop_experience_features_summary_with_desktop);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.deviceinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserManager;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
@@ -30,6 +31,7 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.network.SubscriptionUtil;
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -51,8 +53,13 @@ public class PhoneNumberPreferenceController extends BasePreferenceController {
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return SubscriptionUtil.isSimHardwareVisible(mContext) ?
|
||||
AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
if (!SubscriptionUtil.isSimHardwareVisible(mContext) || Utils.isWifiOnly(mContext)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
if (!mContext.getSystemService(UserManager.class).isAdminUser()) {
|
||||
return DISABLED_FOR_USER;
|
||||
}
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -93,10 +93,10 @@ public class PowerUsageTimeController extends BasePreferenceController {
|
||||
|| (summaryTimeMs == 0 && !TextUtils.equals(anomalyHintKey, preference.getKey()))) {
|
||||
return false;
|
||||
}
|
||||
preference.setTimeTitle(mContext.getString(titleResId));
|
||||
preference.setTimeSummary(getPowerUsageTimeInfo(summaryTimeMs));
|
||||
preference.setTitle(mContext.getString(titleResId));
|
||||
preference.setSummary(getPowerUsageTimeInfo(summaryTimeMs));
|
||||
if (TextUtils.equals(anomalyHintKey, preference.getKey())) {
|
||||
preference.setAnomalyHint(anomalyHintText);
|
||||
preference.setHint(anomalyHintText);
|
||||
}
|
||||
preference.setVisible(true);
|
||||
return true;
|
||||
|
||||
@@ -17,74 +17,17 @@
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.widget.GroupSectionDividerMixin;
|
||||
|
||||
/** Custom preference for displaying the app power usage time. */
|
||||
public class PowerUsageTimePreference extends Preference {
|
||||
public class PowerUsageTimePreference extends WarningFramePreference implements
|
||||
GroupSectionDividerMixin {
|
||||
private static final String TAG = "PowerUsageTimePreference";
|
||||
|
||||
@VisibleForTesting CharSequence mTimeTitle;
|
||||
@VisibleForTesting CharSequence mTimeSummary;
|
||||
@VisibleForTesting CharSequence mAnomalyHintText;
|
||||
|
||||
public PowerUsageTimePreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setLayoutResource(R.layout.power_usage_time);
|
||||
}
|
||||
|
||||
void setTimeTitle(CharSequence timeTitle) {
|
||||
if (!TextUtils.equals(mTimeTitle, timeTitle)) {
|
||||
mTimeTitle = timeTitle;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void setTimeSummary(CharSequence timeSummary) {
|
||||
if (!TextUtils.equals(mTimeSummary, timeSummary)) {
|
||||
mTimeSummary = timeSummary;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void setAnomalyHint(CharSequence anomalyHintText) {
|
||||
if (!TextUtils.equals(mAnomalyHintText, anomalyHintText)) {
|
||||
mAnomalyHintText = anomalyHintText;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void showAnomalyHint(PreferenceViewHolder view) {
|
||||
if (TextUtils.isEmpty(mAnomalyHintText)) {
|
||||
return;
|
||||
}
|
||||
final View anomalyHintView = view.findViewById(R.id.anomaly_hints);
|
||||
if (anomalyHintView == null) {
|
||||
return;
|
||||
}
|
||||
final TextView warningInfo = anomalyHintView.findViewById(R.id.warning_info);
|
||||
if (warningInfo == null) {
|
||||
return;
|
||||
}
|
||||
warningInfo.setText(mAnomalyHintText);
|
||||
anomalyHintView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
|
||||
((TextView) view.findViewById(R.id.time_title)).setText(mTimeTitle);
|
||||
((TextView) view.findViewById(R.id.time_summary)).setText(mTimeSummary);
|
||||
|
||||
showAnomalyHint(view);
|
||||
setSelectable(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.widget.SettingsThemeHelper;
|
||||
|
||||
/**
|
||||
* Custom preference for displaying the {@link Preference} with an optional hint chip.
|
||||
*/
|
||||
public class WarningFramePreference extends Preference {
|
||||
private final int mTitleColorNormal;
|
||||
private final int mSummaryColorNormal;
|
||||
private final int mWarningChipBackgroundResId;
|
||||
private final boolean mIsExpressiveTheme;
|
||||
|
||||
@Nullable private CharSequence mHintText;
|
||||
|
||||
public WarningFramePreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mIsExpressiveTheme = SettingsThemeHelper.isExpressiveTheme(context);
|
||||
int layoutResId =
|
||||
mIsExpressiveTheme
|
||||
? R.layout.expressive_warning_frame_preference
|
||||
: R.layout.warning_frame_preference;
|
||||
setLayoutResource(layoutResId);
|
||||
mWarningChipBackgroundResId =
|
||||
mIsExpressiveTheme
|
||||
? R.drawable.expressive_battery_hints_chip_bg_ripple
|
||||
: R.drawable.battery_hints_chip_bg_ripple;
|
||||
mTitleColorNormal =
|
||||
Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary);
|
||||
mSummaryColorNormal =
|
||||
Utils.getColorAttrDefaultColor(context, android.R.attr.textColorSecondary);
|
||||
}
|
||||
|
||||
/** Sets the text of hint to show. */
|
||||
public void setHint(@Nullable CharSequence hintText) {
|
||||
if (!TextUtils.equals(mHintText, hintText)) {
|
||||
mHintText = hintText;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
|
||||
if (mIsExpressiveTheme) {
|
||||
final View preferenceFrame = view.findViewById(R.id.preference_frame);
|
||||
preferenceFrame.setBackground(null);
|
||||
preferenceFrame.setPadding(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
final View warningChipFrame = view.findViewById(R.id.warning_chip_frame);
|
||||
warningChipFrame
|
||||
.findViewById(R.id.warning_padding_placeholder)
|
||||
.setVisibility(getIcon() != null ? View.VISIBLE : View.GONE);
|
||||
if (!TextUtils.isEmpty(mHintText)) {
|
||||
((TextView) warningChipFrame.findViewById(R.id.warning_info)).setText(mHintText);
|
||||
warningChipFrame.setVisibility(View.VISIBLE);
|
||||
warningChipFrame
|
||||
.findViewById(R.id.warning_chip)
|
||||
.setBackgroundResource(mWarningChipBackgroundResId);
|
||||
} else {
|
||||
warningChipFrame.setVisibility(View.GONE);
|
||||
}
|
||||
((TextView) view.findViewById(android.R.id.title)).setTextColor(mTitleColorNormal);
|
||||
((TextView) view.findViewById(android.R.id.summary)).setTextColor(mSummaryColorNormal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* 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.fuelgauge.batteryusage;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
class AnomalyAppItemPreference extends PowerGaugePreference {
|
||||
|
||||
private static final String TAG = "AnomalyAppItemPreference";
|
||||
|
||||
private CharSequence mAnomalyHintText;
|
||||
|
||||
AnomalyAppItemPreference(Context context) {
|
||||
super(context, /* attrs */ null);
|
||||
setLayoutResource(R.layout.anomaly_app_item_preference);
|
||||
}
|
||||
|
||||
void setAnomalyHint(@Nullable CharSequence anomalyHintText) {
|
||||
if (!TextUtils.equals(mAnomalyHintText, anomalyHintText)) {
|
||||
mAnomalyHintText = anomalyHintText;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder viewHolder) {
|
||||
super.onBindViewHolder(viewHolder);
|
||||
final LinearLayout warningChipView =
|
||||
(LinearLayout) viewHolder.findViewById(R.id.warning_chip);
|
||||
|
||||
if (!TextUtils.isEmpty(mAnomalyHintText)) {
|
||||
((TextView) warningChipView.findViewById(R.id.warning_info)).setText(mAnomalyHintText);
|
||||
warningChipView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
warningChipView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -381,15 +381,15 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
||||
continue;
|
||||
}
|
||||
final String prefKey = entry.getKey();
|
||||
AnomalyAppItemPreference preference = mRootPreferenceGroup.findPreference(prefKey);
|
||||
PowerGaugePreference preference = mRootPreferenceGroup.findPreference(prefKey);
|
||||
if (preference != null) {
|
||||
isAdded = true;
|
||||
} else {
|
||||
preference = (AnomalyAppItemPreference) mPreferenceCache.get(prefKey);
|
||||
preference = (PowerGaugePreference) mPreferenceCache.get(prefKey);
|
||||
}
|
||||
// Creates new instance if cached preference is not found.
|
||||
if (preference == null) {
|
||||
preference = new AnomalyAppItemPreference(mPrefContext);
|
||||
preference = new PowerGaugePreference(mPrefContext);
|
||||
preference.setKey(prefKey);
|
||||
mPreferenceCache.put(prefKey, preference);
|
||||
}
|
||||
@@ -398,7 +398,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
||||
preference.setOrder(++preferenceOrder);
|
||||
preference.setSingleLineTitle(true);
|
||||
// Updates App item preference style
|
||||
preference.setAnomalyHint(isAnomalyBatteryDiffEntry(entry) ? mAnomalyHintString : null);
|
||||
preference.setHint(isAnomalyBatteryDiffEntry(entry) ? mAnomalyHintString : null);
|
||||
// Sets the BatteryDiffEntry to preference for launching detailed page.
|
||||
preference.setBatteryDiffEntry(entry);
|
||||
preference.setSelectable(entry.validForRestriction());
|
||||
|
||||
@@ -28,7 +28,7 @@ import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settingslib.widget.AppPreference;
|
||||
import com.android.settings.fuelgauge.WarningFramePreference;
|
||||
|
||||
/**
|
||||
* Custom preference for displaying battery usage info as a bar and an icon on the left for the
|
||||
@@ -37,7 +37,7 @@ import com.android.settingslib.widget.AppPreference;
|
||||
* <p>The battery usage info could be usage percentage or usage time. The preference won't show any
|
||||
* icon if it is null.
|
||||
*/
|
||||
public class PowerGaugePreference extends AppPreference {
|
||||
public class PowerGaugePreference extends WarningFramePreference {
|
||||
|
||||
// Please see go/battery-usage-app-list-alpha
|
||||
private static final float SELECTABLE_ALPHA = 1f;
|
||||
@@ -51,7 +51,6 @@ public class PowerGaugePreference extends AppPreference {
|
||||
private CharSequence mContentDescription;
|
||||
private CharSequence mProgress;
|
||||
private CharSequence mProgressContentDescription;
|
||||
private boolean mShowAnomalyIcon;
|
||||
|
||||
public PowerGaugePreference(
|
||||
Context context, Drawable icon, CharSequence contentDescription, BatteryEntry info) {
|
||||
@@ -79,7 +78,6 @@ public class PowerGaugePreference extends AppPreference {
|
||||
setWidgetLayoutResource(R.layout.preference_widget_summary);
|
||||
mInfo = info;
|
||||
mContentDescription = contentDescription;
|
||||
mShowAnomalyIcon = false;
|
||||
mTitleColorNormal =
|
||||
Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary);
|
||||
}
|
||||
@@ -108,17 +106,6 @@ public class PowerGaugePreference extends AppPreference {
|
||||
return mProgress.toString();
|
||||
}
|
||||
|
||||
/** Sets whether to show anomaly icon */
|
||||
public void shouldShowAnomalyIcon(boolean showAnomalyIcon) {
|
||||
mShowAnomalyIcon = showAnomalyIcon;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
/** Gets whether to show anomaly icon */
|
||||
public boolean showAnomalyIcon() {
|
||||
return mShowAnomalyIcon;
|
||||
}
|
||||
|
||||
public void setBatteryDiffEntry(BatteryDiffEntry entry) {
|
||||
mBatteryDiffEntry = entry;
|
||||
}
|
||||
@@ -149,12 +136,6 @@ public class PowerGaugePreference extends AppPreference {
|
||||
if (!TextUtils.isEmpty(mProgressContentDescription)) {
|
||||
subtitle.setContentDescription(mProgressContentDescription);
|
||||
}
|
||||
if (mShowAnomalyIcon) {
|
||||
subtitle.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||
R.drawable.ic_warning_24dp, 0, 0, 0);
|
||||
} else {
|
||||
subtitle.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0);
|
||||
}
|
||||
if (mContentDescription != null) {
|
||||
final TextView titleView = (TextView) view.findViewById(android.R.id.title);
|
||||
titleView.setContentDescription(mContentDescription);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.settings.homepage.contextualcards.conditional;
|
||||
|
||||
import android.app.Flags;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -87,12 +86,8 @@ public class DndConditionCardController implements ConditionalCardController {
|
||||
|
||||
@Override
|
||||
public void onActionClick() {
|
||||
if (Flags.modesApi()) {
|
||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG,
|
||||
/* fromUser= */ true);
|
||||
} else {
|
||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG);
|
||||
}
|
||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG,
|
||||
/* fromUser= */ true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,19 +29,20 @@ import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.window.OnBackInvokedCallback;
|
||||
import android.window.OnBackInvokedDispatcher;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.android.internal.app.LocaleStore;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.utils.CustomDialogHelper;
|
||||
|
||||
/**
|
||||
* Create a dialog for system locale events.
|
||||
@@ -58,7 +59,6 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
|
||||
static final String ARG_SHOW_DIALOG = "arg_show_dialog";
|
||||
|
||||
private boolean mShouldKeepDialog;
|
||||
private AlertDialog mAlertDialog;
|
||||
private OnBackInvokedDispatcher mBackDispatcher;
|
||||
|
||||
private OnBackInvokedCallback mBackCallback = () -> {
|
||||
@@ -106,45 +106,53 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
|
||||
LocaleListEditor parentFragment = (LocaleListEditor) getParentFragment();
|
||||
LocaleDialogController controller = getLocaleDialogController(getContext(), this,
|
||||
parentFragment);
|
||||
LocaleDialogController.DialogContent dialogContent = controller.getDialogContent();
|
||||
ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.locale_dialog, null);
|
||||
setDialogTitle(viewGroup, dialogContent.mTitle);
|
||||
setDialogMessage(viewGroup, dialogContent.mMessage);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext())
|
||||
.setView(viewGroup);
|
||||
if (!dialogContent.mPositiveButton.isEmpty()) {
|
||||
builder.setPositiveButton(dialogContent.mPositiveButton, controller);
|
||||
}
|
||||
if (!dialogContent.mNegativeButton.isEmpty()) {
|
||||
builder.setNegativeButton(dialogContent.mNegativeButton, controller);
|
||||
}
|
||||
mAlertDialog = builder.create();
|
||||
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(PRIORITY_DEFAULT, mBackCallback);
|
||||
mAlertDialog.setCanceledOnTouchOutside(false);
|
||||
mAlertDialog.setOnDismissListener(dialogInterface -> {
|
||||
mAlertDialog.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(
|
||||
mBackCallback);
|
||||
Dialog dialog = createDialog(getContext(), controller);
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
getOnBackInvokedDispatcher(dialog).registerOnBackInvokedCallback(PRIORITY_DEFAULT,
|
||||
mBackCallback);
|
||||
dialog.setOnDismissListener(dialogInterface -> {
|
||||
getOnBackInvokedDispatcher(dialog).unregisterOnBackInvokedCallback(
|
||||
mBackCallback);
|
||||
});
|
||||
|
||||
return mAlertDialog;
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private static void setDialogTitle(View root, String content) {
|
||||
TextView titleView = root.findViewById(R.id.dialog_title);
|
||||
if (titleView == null) {
|
||||
return;
|
||||
private Dialog createDialog(Context context, LocaleDialogController controller) {
|
||||
CustomDialogHelper dialogHelper = new CustomDialogHelper(context);
|
||||
LocaleDialogController.DialogContent dialogContent = controller.getDialogContent();
|
||||
dialogHelper.setIcon(context.getDrawable(R.drawable.ic_settings_language_32dp))
|
||||
.setTitle(dialogContent.mTitle)
|
||||
.setMessage(dialogContent.mMessage)
|
||||
.setIconPadding(0,
|
||||
context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_icon_padding),
|
||||
0, 0)
|
||||
.setTitlePadding(0,
|
||||
context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_title_padding),
|
||||
0,
|
||||
context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_title_padding))
|
||||
.setMessagePadding(context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_message_padding_left_right), 0,
|
||||
context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_message_padding_left_right),
|
||||
context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_message_padding_bottom))
|
||||
.setPositiveButton(dialogContent.mPositiveButton,
|
||||
view -> {
|
||||
controller.onClick(dialogHelper.getDialog(),
|
||||
DialogInterface.BUTTON_POSITIVE);
|
||||
dialogHelper.getDialog().dismiss();
|
||||
});
|
||||
if (dialogContent.mNegativeButton != 0) {
|
||||
dialogHelper.setBackButton(dialogContent.mNegativeButton, view -> {
|
||||
controller.onClick(dialogHelper.getDialog(), DialogInterface.BUTTON_NEGATIVE);
|
||||
dialogHelper.getDialog().dismiss();
|
||||
});
|
||||
}
|
||||
titleView.setText(content);
|
||||
}
|
||||
|
||||
private static void setDialogMessage(View root, String content) {
|
||||
TextView textView = root.findViewById(R.id.dialog_msg);
|
||||
if (textView == null) {
|
||||
return;
|
||||
}
|
||||
textView.setText(content);
|
||||
return dialogHelper.getDialog();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -158,11 +166,11 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public OnBackInvokedDispatcher getOnBackInvokedDispatcher() {
|
||||
public @NonNull OnBackInvokedDispatcher getOnBackInvokedDispatcher(@NonNull Dialog dialog) {
|
||||
if (mBackDispatcher != null) {
|
||||
return mBackDispatcher;
|
||||
} else {
|
||||
return mAlertDialog.getOnBackInvokedDispatcher();
|
||||
return dialog.getOnBackInvokedDispatcher();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,15 +231,15 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
|
||||
R.string.title_change_system_locale), mLocaleInfo.getFullNameNative());
|
||||
dialogContent.mMessage = mContext.getString(
|
||||
R.string.desc_notice_device_locale_settings_change);
|
||||
dialogContent.mPositiveButton = mContext.getString(
|
||||
R.string.button_label_confirmation_of_system_locale_change);
|
||||
dialogContent.mNegativeButton = mContext.getString(R.string.cancel);
|
||||
dialogContent.mPositiveButton =
|
||||
R.string.button_label_confirmation_of_system_locale_change;
|
||||
dialogContent.mNegativeButton = R.string.cancel;
|
||||
break;
|
||||
case DIALOG_NOT_AVAILABLE_LOCALE:
|
||||
dialogContent.mTitle = String.format(mContext.getString(
|
||||
R.string.title_unavailable_locale), mLocaleInfo.getFullNameNative());
|
||||
dialogContent.mMessage = mContext.getString(R.string.desc_unavailable_locale);
|
||||
dialogContent.mPositiveButton = mContext.getString(R.string.okay);
|
||||
dialogContent.mPositiveButton = R.string.okay;
|
||||
break;
|
||||
case DIALOG_ADD_SYSTEM_LOCALE:
|
||||
dialogContent.mTitle = String.format(mContext.getString(
|
||||
@@ -239,8 +247,8 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
|
||||
mLocaleInfo.getFullNameNative());
|
||||
dialogContent.mMessage = mContext.getString(
|
||||
R.string.desc_system_locale_addition);
|
||||
dialogContent.mPositiveButton = mContext.getString(R.string.add);
|
||||
dialogContent.mNegativeButton = mContext.getString(R.string.cancel);
|
||||
dialogContent.mPositiveButton = R.string.add;
|
||||
dialogContent.mNegativeButton = R.string.cancel;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -252,8 +260,8 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
|
||||
static class DialogContent {
|
||||
String mTitle = "";
|
||||
String mMessage = "";
|
||||
String mPositiveButton = "";
|
||||
String mNegativeButton = "";
|
||||
int mPositiveButton = 0;
|
||||
int mNegativeButton = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,9 +43,10 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@@ -53,10 +54,12 @@ import com.android.internal.app.LocalePicker;
|
||||
import com.android.internal.app.LocaleStore;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RestrictedSettingsFragment;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
import com.android.settingslib.search.SearchIndexableRaw;
|
||||
import com.android.settingslib.utils.CustomDialogHelper;
|
||||
import com.android.settingslib.utils.StringUtil;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
@@ -69,6 +72,8 @@ import java.util.Locale;
|
||||
*/
|
||||
@SearchIndexable
|
||||
public class LocaleListEditor extends RestrictedSettingsFragment implements View.OnTouchListener {
|
||||
public static final int REQUEST_LOCALE_PICKER = 0;
|
||||
|
||||
protected static final String INTENT_LOCALE_KEY = "localeInfo";
|
||||
protected static final String EXTRA_SYSTEM_LOCALE_DIALOG_TYPE = "system_locale_dialog_type";
|
||||
protected static final String EXTRA_RESULT_LOCALE = "result_locale";
|
||||
@@ -81,16 +86,16 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
|
||||
private static final String INDEX_KEY_ADD_LANGUAGE = "add_language";
|
||||
private static final String KEY_LANGUAGES_PICKER = "languages_picker";
|
||||
private static final String KEY_CATEGORY_TERMS_OF_ADDRESS = "key_category_terms_of_address";
|
||||
private static final String KEY_ADD_A_LANGUAGE = "add_a_language";
|
||||
private static final String TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT = "dialog_confirm_system_default";
|
||||
private static final String TAG_DIALOG_NOT_AVAILABLE = "dialog_not_available_locale";
|
||||
private static final String TAG_DIALOG_ADD_SYSTEM_LOCALE = "dialog_add_system_locale";
|
||||
private static final int MENU_ID_REMOVE = Menu.FIRST + 1;
|
||||
private static final int REQUEST_LOCALE_PICKER = 0;
|
||||
|
||||
private LocaleDragAndDropAdapter mAdapter;
|
||||
private Menu mMenu;
|
||||
private View mAddLanguage;
|
||||
private AlertDialog mSuggestionDialog = null;
|
||||
private Preference mAddLanguagePreference;
|
||||
private boolean mRemoveMode;
|
||||
private boolean mShowingRemoveDialog;
|
||||
private boolean mLocaleAdditionMode = false;
|
||||
@@ -281,7 +286,11 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
|
||||
private void setRemoveMode(boolean mRemoveMode) {
|
||||
this.mRemoveMode = mRemoveMode;
|
||||
mAdapter.setRemoveMode(mRemoveMode);
|
||||
mAddLanguage.setVisibility(mRemoveMode ? View.INVISIBLE : View.VISIBLE);
|
||||
if (Flags.settingsExpressiveDesignEnabled()) {
|
||||
mAddLanguagePreference.setVisible(!mRemoveMode);
|
||||
} else {
|
||||
mAddLanguage.setVisibility(mRemoveMode ? View.INVISIBLE : View.VISIBLE);
|
||||
}
|
||||
updateVisibilityOfRemoveMenu();
|
||||
}
|
||||
|
||||
@@ -330,7 +339,6 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
|
||||
private void showDialogForAddedLocale() {
|
||||
Log.d(TAG, "show confirmation dialog");
|
||||
Intent intent = this.getIntent();
|
||||
String dialogType = intent.getStringExtra(EXTRA_SYSTEM_LOCALE_DIALOG_TYPE);
|
||||
String appLocaleTag = intent.getStringExtra(EXTRA_APP_LOCALE);
|
||||
|
||||
LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(
|
||||
@@ -344,17 +352,6 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
|
||||
localeDialogFragment.show(mFragmentManager, TAG_DIALOG_ADD_SYSTEM_LOCALE);
|
||||
}
|
||||
|
||||
private void customizeLayout(AlertDialog.Builder dialogBuilder, String language) {
|
||||
View dialogView = getLocaleDialogView();
|
||||
dialogBuilder.setView(dialogView);
|
||||
TextView title = dialogView.findViewById(R.id.dialog_title);
|
||||
title.setText(
|
||||
String.format(getContext().getResources().getString(
|
||||
R.string.title_system_locale_addition), language));
|
||||
TextView message = dialogView.findViewById(R.id.dialog_msg);
|
||||
message.setText(R.string.desc_system_locale_addition);
|
||||
}
|
||||
|
||||
protected View getLocaleDialogView() {
|
||||
LayoutInflater inflater = this.getLayoutInflater();
|
||||
return inflater.inflate(R.layout.locale_dialog, null);
|
||||
@@ -374,25 +371,33 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
|
||||
return;
|
||||
}
|
||||
|
||||
int messagePaddingLeftRight = getContext().getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_message_padding_left_right);
|
||||
int messagePaddingBottom = getContext().getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_message_padding_bottom);
|
||||
// All locales selected, warning dialog, can't remove them all
|
||||
if (checkedCount == mAdapter.getItemCount()) {
|
||||
mShowingRemoveDialog = true;
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.dlg_remove_locales_error_title)
|
||||
.setMessage(R.string.dlg_remove_locales_error_message)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})
|
||||
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
mShowingRemoveDialog = false;
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
|
||||
CustomDialogHelper dialogHelper = createRegionDialog(getContext(),
|
||||
getContext().getString(R.string.dlg_remove_locales_error_title));
|
||||
dialogHelper.setMessage(R.string.dlg_remove_locales_error_message)
|
||||
.setMessagePadding(messagePaddingLeftRight, 0, messagePaddingLeftRight,
|
||||
messagePaddingBottom)
|
||||
.setPositiveButton(android.R.string.ok,
|
||||
view -> {
|
||||
dialogHelper.getDialog().dismiss();
|
||||
})
|
||||
.setBackButton(R.string.cancel, view -> {
|
||||
dialogHelper.getDialog().dismiss();
|
||||
});
|
||||
dialogHelper.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(@NonNull DialogInterface dialog) {
|
||||
mShowingRemoveDialog = false;
|
||||
}
|
||||
});
|
||||
dialogHelper.getDialog().show();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -400,54 +405,63 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
|
||||
R.string.dlg_remove_locales_title);
|
||||
mShowingRemoveDialog = true;
|
||||
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
CustomDialogHelper dialogHelper = createRegionDialog(getContext(), title);
|
||||
if (mAdapter.isFirstLocaleChecked()) {
|
||||
builder.setMessage(R.string.dlg_remove_locales_message);
|
||||
dialogHelper.setMessage(R.string.dlg_remove_locales_message)
|
||||
.setMessagePadding(messagePaddingLeftRight, 0, messagePaddingLeftRight,
|
||||
messagePaddingBottom);
|
||||
}
|
||||
|
||||
builder.setTitle(title)
|
||||
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
setRemoveMode(false);
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.locale_remove_menu,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// This is a sensitive area to change.
|
||||
// removeChecked() triggers a system update and "kills" the frame.
|
||||
// This means that saveState + restoreState are called before
|
||||
// setRemoveMode is called.
|
||||
// So we want that mRemoveMode and dialog status have the right
|
||||
// values
|
||||
// before that save.
|
||||
// We can't just call setRemoveMode(false) before calling
|
||||
// removeCheched
|
||||
// because that unchecks all items and removeChecked would have
|
||||
// nothing
|
||||
// to remove.
|
||||
mRemoveMode = false;
|
||||
mShowingRemoveDialog = false;
|
||||
LocaleStore.LocaleInfo firstLocale =
|
||||
mAdapter.getFeedItemList().get(0);
|
||||
mAdapter.removeChecked();
|
||||
boolean isFirstRemoved =
|
||||
firstLocale != mAdapter.getFeedItemList().get(0);
|
||||
showConfirmDialog(isFirstRemoved, isFirstRemoved ? firstLocale
|
||||
: mAdapter.getFeedItemList().get(0));
|
||||
setRemoveMode(false);
|
||||
}
|
||||
dialogHelper.setPositiveButton(R.string.locale_remove_menu,
|
||||
view -> {
|
||||
// This is a sensitive area to change.
|
||||
// removeChecked() triggers a system update and "kills" the frame.
|
||||
// This means that saveState + restoreState are called before
|
||||
// setRemoveMode is called.
|
||||
// So we want that mRemoveMode and dialog status have the right
|
||||
// values
|
||||
// before that save.
|
||||
// We can't just call setRemoveMode(false) before calling
|
||||
// removeCheched
|
||||
// because that unchecks all items and removeChecked would have
|
||||
// nothing
|
||||
// to remove.
|
||||
mRemoveMode = false;
|
||||
mShowingRemoveDialog = false;
|
||||
LocaleStore.LocaleInfo firstLocale =
|
||||
mAdapter.getFeedItemList().get(0);
|
||||
mAdapter.removeChecked();
|
||||
boolean isFirstRemoved =
|
||||
firstLocale != mAdapter.getFeedItemList().get(0);
|
||||
showConfirmDialog(isFirstRemoved, isFirstRemoved ? firstLocale
|
||||
: mAdapter.getFeedItemList().get(0));
|
||||
setRemoveMode(false);
|
||||
dialogHelper.getDialog().dismiss();
|
||||
})
|
||||
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
mShowingRemoveDialog = false;
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
.setBackButton(R.string.cancel, view -> {
|
||||
setRemoveMode(false);
|
||||
dialogHelper.getDialog().dismiss();
|
||||
});
|
||||
dialogHelper.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(@NonNull DialogInterface dialog) {
|
||||
mShowingRemoveDialog = false;
|
||||
}
|
||||
});
|
||||
dialogHelper.getDialog().show();
|
||||
}
|
||||
|
||||
private CustomDialogHelper createRegionDialog(Context context, String title) {
|
||||
CustomDialogHelper dialogHelper = new CustomDialogHelper(context);
|
||||
dialogHelper.setIcon(context.getDrawable(R.drawable.ic_settings_language_32dp))
|
||||
.setTitle(title)
|
||||
.setIconPadding(0, context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_icon_padding), 0, 0)
|
||||
.setTitlePadding(0, context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_title_padding), 0,
|
||||
context.getResources().getDimensionPixelSize(
|
||||
R.dimen.locale_picker_dialog_title_padding));
|
||||
return dialogHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -483,20 +497,23 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
|
||||
list.setAdapter(mAdapter);
|
||||
list.setOnTouchListener(this);
|
||||
list.requestFocus();
|
||||
if (Flags.settingsExpressiveDesignEnabled()) {
|
||||
mAddLanguagePreference = getPreferenceScreen().findPreference(KEY_ADD_A_LANGUAGE);
|
||||
} else {
|
||||
mAddLanguage = layout.findViewById(R.id.add_language);
|
||||
mAddLanguage.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(@NonNull View v) {
|
||||
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
||||
.logSettingsTileClick(INDEX_KEY_ADD_LANGUAGE, getMetricsCategory());
|
||||
|
||||
mAddLanguage = layout.findViewById(R.id.add_language);
|
||||
mAddLanguage.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
||||
.logSettingsTileClick(INDEX_KEY_ADD_LANGUAGE, getMetricsCategory());
|
||||
|
||||
final Intent intent = new Intent(getActivity(),
|
||||
LocalePickerWithRegionActivity.class);
|
||||
intent.putExtras(getActivity().getIntent().getExtras());
|
||||
startActivityForResult(intent, REQUEST_LOCALE_PICKER);
|
||||
}
|
||||
});
|
||||
final Intent intent = new Intent(getActivity(),
|
||||
LocalePickerWithRegionActivity.class);
|
||||
intent.putExtras(getActivity().getIntent().getExtras());
|
||||
startActivityForResult(intent, REQUEST_LOCALE_PICKER);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -75,9 +75,6 @@ public abstract class LocalePickerBaseListPreferenceController extends
|
||||
public LocalePickerBaseListPreferenceController(@NonNull Context context,
|
||||
@NonNull String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mLocaleList = getLocaleCollectorController(context).getSupportedLocaleList(null,
|
||||
false, false);
|
||||
mLocaleOptions = new ArrayList<>(mLocaleList.size());
|
||||
mPreferences = new ArrayMap<>();
|
||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||
}
|
||||
@@ -246,7 +243,7 @@ public abstract class LocalePickerBaseListPreferenceController extends
|
||||
private void setupLocaleList() {
|
||||
mLocaleList = getLocaleCollectorController(mContext).getSupportedLocaleList(
|
||||
mParentLocale, false, mIsCountryMode);
|
||||
mLocaleOptions.clear();
|
||||
mLocaleOptions = new ArrayList<>(mLocaleList.size());
|
||||
}
|
||||
|
||||
private List<LocaleStore.LocaleInfo> getSortedLocaleList(
|
||||
@@ -262,7 +259,9 @@ public abstract class LocalePickerBaseListPreferenceController extends
|
||||
boolean shouldShowLocaleEditor = shouldShowLocaleEditor(localeInfo);
|
||||
if (shouldShowLocaleEditor) {
|
||||
List<LocaleStore.LocaleInfo> feedItemList = getUserLocaleList();
|
||||
feedItemList.add(localeInfo);
|
||||
for (LocaleStore.LocaleInfo locale : mLocaleList) {
|
||||
feedItemList.add(locale);
|
||||
}
|
||||
LocaleList localeList = new LocaleList(feedItemList.stream()
|
||||
.map(LocaleStore.LocaleInfo::getLocale)
|
||||
.toArray(Locale[]::new));
|
||||
|
||||
@@ -23,14 +23,12 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivitySettingsManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
@@ -55,6 +53,7 @@ import com.android.settingslib.HelpUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.google.common.net.InternetDomainName;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -64,7 +63,7 @@ import java.util.Map;
|
||||
* Dialog to set the Private DNS
|
||||
*/
|
||||
public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat implements
|
||||
DialogInterface.OnClickListener, RadioGroup.OnCheckedChangeListener, TextWatcher {
|
||||
RadioGroup.OnCheckedChangeListener, TextWatcher {
|
||||
|
||||
public static final String ANNOTATION_URL = "url";
|
||||
|
||||
@@ -80,16 +79,9 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static final String MODE_KEY = Settings.Global.PRIVATE_DNS_MODE;
|
||||
TextInputLayout mHostnameLayout;
|
||||
@VisibleForTesting
|
||||
static final String HOSTNAME_KEY = Settings.Global.PRIVATE_DNS_SPECIFIER;
|
||||
|
||||
public static String getHostnameFromSettings(ContentResolver cr) {
|
||||
return Settings.Global.getString(cr, HOSTNAME_KEY);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
EditText mEditText;
|
||||
EditText mHostnameText;
|
||||
@VisibleForTesting
|
||||
RadioGroup mRadioGroup;
|
||||
@VisibleForTesting
|
||||
@@ -136,22 +128,17 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat
|
||||
// by the controller.
|
||||
holder.itemView.setEnabled(true);
|
||||
}
|
||||
|
||||
setSaveButtonListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View view) {
|
||||
final Context context = getContext();
|
||||
final ContentResolver contentResolver = context.getContentResolver();
|
||||
|
||||
mMode = ConnectivitySettingsManager.getPrivateDnsMode(context);
|
||||
|
||||
mEditText = view.findViewById(R.id.private_dns_mode_provider_hostname);
|
||||
mEditText.addTextChangedListener(this);
|
||||
mEditText.setText(getHostnameFromSettings(contentResolver));
|
||||
|
||||
mRadioGroup = view.findViewById(R.id.private_dns_radio_group);
|
||||
mRadioGroup.setOnCheckedChangeListener(this);
|
||||
mRadioGroup.check(PRIVATE_DNS_MAP.getOrDefault(mMode, R.id.private_dns_mode_opportunistic));
|
||||
mRadioGroup.setOnCheckedChangeListener(this);
|
||||
|
||||
// Initial radio button text
|
||||
final RadioButton offRadioButton = view.findViewById(R.id.private_dns_mode_off);
|
||||
@@ -163,6 +150,13 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat
|
||||
final RadioButton providerRadioButton = view.findViewById(R.id.private_dns_mode_provider);
|
||||
providerRadioButton.setText(com.android.settingslib.R.string.private_dns_mode_provider);
|
||||
|
||||
mHostnameLayout = view.findViewById(R.id.private_dns_mode_provider_hostname_layout);
|
||||
mHostnameText = view.findViewById(R.id.private_dns_mode_provider_hostname);
|
||||
if (mHostnameText != null) {
|
||||
mHostnameText.setText(ConnectivitySettingsManager.getPrivateDnsHostname(context));
|
||||
mHostnameText.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
final TextView helpTextView = view.findViewById(R.id.private_dns_help_info);
|
||||
helpTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
final Intent helpIntent = HelpUtils.getHelpIntent(context,
|
||||
@@ -176,22 +170,8 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat
|
||||
} else {
|
||||
helpTextView.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
final Context context = getContext();
|
||||
if (mMode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME) {
|
||||
// Only clickable if hostname is valid, so we could save it safely
|
||||
ConnectivitySettingsManager.setPrivateDnsHostname(context,
|
||||
mEditText.getText().toString());
|
||||
}
|
||||
|
||||
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider().action(context,
|
||||
SettingsEnums.ACTION_PRIVATE_DNS_MODE, mMode);
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(context, mMode);
|
||||
}
|
||||
updateDialogInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -241,24 +221,58 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat
|
||||
return getEnforcedAdmin() != null;
|
||||
}
|
||||
|
||||
private Button getSaveButton() {
|
||||
final AlertDialog dialog = (AlertDialog) getDialog();
|
||||
if (dialog == null) {
|
||||
return null;
|
||||
}
|
||||
return dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
}
|
||||
|
||||
private void updateDialogInfo() {
|
||||
final boolean modeProvider = PRIVATE_DNS_MODE_PROVIDER_HOSTNAME == mMode;
|
||||
if (mEditText != null) {
|
||||
mEditText.setEnabled(modeProvider);
|
||||
}
|
||||
final Button saveButton = getSaveButton();
|
||||
if (saveButton != null) {
|
||||
saveButton.setEnabled(modeProvider
|
||||
? InternetDomainName.isValid(mEditText.getText().toString())
|
||||
: true);
|
||||
if (mHostnameLayout != null) {
|
||||
mHostnameLayout.setEnabled(modeProvider);
|
||||
mHostnameLayout.setErrorEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSaveButtonListener() {
|
||||
View.OnClickListener onClickListener = v -> doSaveButton();
|
||||
DialogInterface.OnShowListener onShowListener = dialog -> {
|
||||
if (dialog == null) {
|
||||
Log.e(TAG, "The DialogInterface is null!");
|
||||
return;
|
||||
}
|
||||
Button saveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
if (saveButton == null) {
|
||||
Log.e(TAG, "Can't get the save button!");
|
||||
return;
|
||||
}
|
||||
saveButton.setOnClickListener(onClickListener);
|
||||
};
|
||||
setOnShowListener(onShowListener);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void doSaveButton() {
|
||||
Context context = getContext();
|
||||
if (mMode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME) {
|
||||
if (mHostnameLayout == null || mHostnameText == null) {
|
||||
Log.e(TAG, "Can't find hostname resources!");
|
||||
return;
|
||||
}
|
||||
if (mHostnameText.getText().isEmpty()) {
|
||||
mHostnameLayout.setError(context.getString(R.string.private_dns_field_require));
|
||||
Log.w(TAG, "The hostname is empty!");
|
||||
return;
|
||||
}
|
||||
if (!InternetDomainName.isValid(mHostnameText.getText().toString())) {
|
||||
mHostnameLayout.setError(context.getString(R.string.private_dns_hostname_invalid));
|
||||
Log.w(TAG, "The hostname is invalid!");
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectivitySettingsManager.setPrivateDnsHostname(context,
|
||||
mHostnameText.getText().toString());
|
||||
}
|
||||
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(context, mMode);
|
||||
|
||||
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
||||
.action(context, SettingsEnums.ACTION_PRIVATE_DNS_MODE, mMode);
|
||||
getDialog().dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ public class PrivateDnsPreferenceController extends BasePreferenceController
|
||||
com.android.settingslib.R.string.private_dns_mode_opportunistic);
|
||||
case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
|
||||
return dnsesResolved
|
||||
? PrivateDnsModeDialogPreference.getHostnameFromSettings(cr)
|
||||
? ConnectivitySettingsManager.getPrivateDnsHostname(mContext)
|
||||
: res.getString(
|
||||
com.android.settingslib.R.string.private_dns_mode_provider_failure);
|
||||
}
|
||||
|
||||
@@ -107,8 +107,8 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc
|
||||
}
|
||||
|
||||
final PersistableBundle carrierConfig = getCarrierConfigForSubId(subId);
|
||||
if ((carrierConfig == null)
|
||||
|| carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL)) {
|
||||
if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig) ||
|
||||
carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL)) {
|
||||
return CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ import com.android.settings.R
|
||||
import com.android.settings.flags.Flags
|
||||
import com.android.settings.network.SubscriptionUtil
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
||||
import com.android.settingslib.Utils
|
||||
|
||||
/** Preference controller for "Phone number" */
|
||||
class MobileNetworkPhoneNumberPreferenceController
|
||||
@@ -41,13 +43,14 @@ constructor(
|
||||
mSubId = subId
|
||||
}
|
||||
|
||||
override fun getAvailabilityStatus(subId: Int): Int =
|
||||
when {
|
||||
!Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE
|
||||
SubscriptionManager.isValidSubscriptionId(subId) &&
|
||||
SubscriptionUtil.isSimHardwareVisible(mContext) -> AVAILABLE
|
||||
else -> CONDITIONALLY_UNAVAILABLE
|
||||
}
|
||||
override fun getAvailabilityStatus(subId: Int): Int = when {
|
||||
!Flags.isDualSimOnboardingEnabled()
|
||||
|| !SubscriptionManager.isValidSubscriptionId(subId)
|
||||
|| !SubscriptionUtil.isSimHardwareVisible(mContext)
|
||||
|| Utils.isWifiOnly(mContext) -> CONDITIONALLY_UNAVAILABLE
|
||||
!mContext.userManager.isAdminUser -> DISABLED_FOR_USER
|
||||
else -> AVAILABLE
|
||||
}
|
||||
|
||||
override fun displayPreference(screen: PreferenceScreen) {
|
||||
super.displayPreference(screen)
|
||||
|
||||
@@ -59,7 +59,7 @@ abstract class AbstractZenModeHeaderController extends AbstractZenModePreference
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return Flags.modesApi() && Flags.modesUi();
|
||||
return Flags.modesUi();
|
||||
}
|
||||
|
||||
protected void setUpHeader(PreferenceScreen screen, int iconSizePx) {
|
||||
|
||||
@@ -43,7 +43,7 @@ class ZenSettingsObserver extends ContentObserver {
|
||||
}
|
||||
|
||||
void register() {
|
||||
if (Flags.modesApi() && Flags.modesUi()) {
|
||||
if (Flags.modesUi()) {
|
||||
mContext.getContentResolver().registerContentObserver(ZEN_MODE_URI, false, this);
|
||||
mContext.getContentResolver().registerContentObserver(ZEN_MODE_CONFIG_ETAG_URI, false,
|
||||
this);
|
||||
@@ -51,7 +51,7 @@ class ZenSettingsObserver extends ContentObserver {
|
||||
}
|
||||
|
||||
void unregister() {
|
||||
if (Flags.modesApi() && Flags.modesUi()) {
|
||||
if (Flags.modesUi()) {
|
||||
mContext.getContentResolver().unregisterContentObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
||||
mMetricsFeatureProvider.action(mContext,
|
||||
SettingsEnums.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
|
||||
AutomaticZenRule rule;
|
||||
if (Flags.modesApi() && Flags.modesUi()) {
|
||||
if (Flags.modesUi()) {
|
||||
rule = new AutomaticZenRule.Builder(ruleName, mRuleInfo.defaultConditionId)
|
||||
.setType(mRuleInfo.type)
|
||||
.setOwner(mRuleInfo.serviceComponent)
|
||||
|
||||
@@ -76,7 +76,7 @@ public class ZenAccessSettings extends EmptyTextSettings implements
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setEmptyText(Flags.modesApi() && Flags.modesUi()
|
||||
setEmptyText(Flags.modesUi()
|
||||
? R.string.zen_modes_access_empty_text
|
||||
: R.string.zen_access_empty_text);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public class ZenAccessSettings extends EmptyTextSettings implements
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
requireActivity().setTitle(Flags.modesApi() && Flags.modesUi()
|
||||
requireActivity().setTitle(Flags.modesUi()
|
||||
? R.string.manage_zen_modes_access_title
|
||||
: R.string.manage_zen_access_title);
|
||||
reloadList();
|
||||
@@ -145,7 +145,7 @@ public class ZenAccessSettings extends EmptyTextSettings implements
|
||||
pref.setOnPreferenceClickListener(preference -> {
|
||||
AppInfoBase.startAppInfoFragment(
|
||||
ZenAccessDetails.class /* fragment */,
|
||||
getString(Flags.modesApi() && Flags.modesUi()
|
||||
getString(Flags.modesUi()
|
||||
? R.string.manage_zen_modes_access_title
|
||||
: R.string.manage_zen_access_title),
|
||||
pkg,
|
||||
|
||||
@@ -95,32 +95,19 @@ public class ZenModeBackend {
|
||||
}
|
||||
|
||||
protected boolean updateZenRule(String id, AutomaticZenRule rule) {
|
||||
if (android.app.Flags.modesApi()) {
|
||||
return mNotificationManager.updateAutomaticZenRule(id, rule, /* fromUser= */ true);
|
||||
} else {
|
||||
return NotificationManager.from(mContext).updateAutomaticZenRule(id, rule);
|
||||
}
|
||||
return mNotificationManager.updateAutomaticZenRule(id, rule, /* fromUser= */ true);
|
||||
}
|
||||
|
||||
protected void setZenMode(int zenMode) {
|
||||
if (android.app.Flags.modesApi()) {
|
||||
mNotificationManager.setZenMode(zenMode, null, TAG, /* fromUser= */ true);
|
||||
} else {
|
||||
NotificationManager.from(mContext).setZenMode(zenMode, null, TAG);
|
||||
}
|
||||
mNotificationManager.setZenMode(zenMode, null, TAG, /* fromUser= */ true);
|
||||
mZenMode = getZenMode();
|
||||
}
|
||||
|
||||
protected void setZenModeForDuration(int minutes) {
|
||||
Uri conditionId = ZenModeConfig.toTimeCondition(mContext, minutes,
|
||||
ActivityManager.getCurrentUser(), true).id;
|
||||
if (android.app.Flags.modesApi()) {
|
||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
|
||||
conditionId, TAG, /* fromUser= */ true);
|
||||
} else {
|
||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
|
||||
conditionId, TAG);
|
||||
}
|
||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
|
||||
conditionId, TAG, /* fromUser= */ true);
|
||||
mZenMode = getZenMode();
|
||||
}
|
||||
|
||||
@@ -190,14 +177,9 @@ public class ZenModeBackend {
|
||||
int priorityConversationSenders) {
|
||||
mPolicy = new NotificationManager.Policy(priorityCategories, priorityCallSenders,
|
||||
priorityMessageSenders, suppressedVisualEffects, priorityConversationSenders);
|
||||
if (android.app.Flags.modesApi()) {
|
||||
mNotificationManager.setNotificationPolicy(mPolicy, /* fromUser= */ true);
|
||||
} else {
|
||||
mNotificationManager.setNotificationPolicy(mPolicy);
|
||||
}
|
||||
mNotificationManager.setNotificationPolicy(mPolicy, /* fromUser= */ true);
|
||||
}
|
||||
|
||||
|
||||
private int getNewSuppressedEffects(boolean suppress, int effectType) {
|
||||
int effects = mPolicy.suppressedVisualEffects;
|
||||
|
||||
@@ -373,11 +355,7 @@ public class ZenModeBackend {
|
||||
}
|
||||
|
||||
public boolean removeZenRule(String ruleId) {
|
||||
if (android.app.Flags.modesApi()) {
|
||||
return mNotificationManager.removeAutomaticZenRule(ruleId, /* fromUser= */ true);
|
||||
} else {
|
||||
return NotificationManager.from(mContext).removeAutomaticZenRule(ruleId);
|
||||
}
|
||||
return mNotificationManager.removeAutomaticZenRule(ruleId, /* fromUser= */ true);
|
||||
}
|
||||
|
||||
public NotificationManager.Policy getConsolidatedPolicy() {
|
||||
@@ -386,11 +364,7 @@ public class ZenModeBackend {
|
||||
|
||||
protected String addZenRule(AutomaticZenRule rule) {
|
||||
try {
|
||||
if (android.app.Flags.modesApi()) {
|
||||
return mNotificationManager.addAutomaticZenRule(rule, /* fromUser= */ true);
|
||||
} else {
|
||||
return NotificationManager.from(mContext).addAutomaticZenRule(rule);
|
||||
}
|
||||
return mNotificationManager.addAutomaticZenRule(rule, /* fromUser= */ true);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -104,16 +104,11 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(ZenCustomRuleSettings.RULE_ID, mId);
|
||||
|
||||
// When modes_api flag is on, we skip the radio button screen distinguishing
|
||||
// between "default" and "custom" and take users directly to the custom
|
||||
// settings screen.
|
||||
String destination = ZenCustomRuleSettings.class.getName();
|
||||
int sourceMetricsCategory = 0;
|
||||
if (Flags.modesApi()) {
|
||||
// From ZenRuleCustomPolicyPreferenceController#launchCustomSettings
|
||||
destination = ZenCustomRuleConfigSettings.class.getName();
|
||||
sourceMetricsCategory = SettingsEnums.ZEN_CUSTOM_RULE_SOUND_SETTINGS;
|
||||
}
|
||||
// Skip the radio button screen distinguishing between "default" and
|
||||
// "custom" and take users directly to the custom settings screen.
|
||||
// From ZenRuleCustomPolicyPreferenceController#launchCustomSettings
|
||||
String destination = ZenCustomRuleConfigSettings.class.getName();
|
||||
int sourceMetricsCategory = SettingsEnums.ZEN_CUSTOM_RULE_SOUND_SETTINGS;
|
||||
new SubSettingLauncher(mContext)
|
||||
.setDestination(destination)
|
||||
.setArguments(bundle)
|
||||
@@ -165,7 +160,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
|
||||
|
||||
protected void updateScheduleRule(ZenModeConfig.ScheduleInfo schedule) {
|
||||
mRule.setConditionId(ZenModeConfig.toScheduleConditionId(schedule));
|
||||
if (Flags.modesApi() && Flags.modesUi()) {
|
||||
if (Flags.modesUi()) {
|
||||
mRule.setTriggerDescription(
|
||||
SystemZenRules.getTriggerDescriptionForScheduleTime(mContext, schedule));
|
||||
}
|
||||
@@ -174,7 +169,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
|
||||
|
||||
protected void updateEventRule(ZenModeConfig.EventInfo event) {
|
||||
mRule.setConditionId(ZenModeConfig.toEventConditionId(event));
|
||||
if (Flags.modesApi() && Flags.modesUi()) {
|
||||
if (Flags.modesUi()) {
|
||||
mRule.setTriggerDescription(
|
||||
SystemZenRules.getTriggerDescriptionForScheduleEvent(mContext, event));
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.settings.notification.zen;
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.Flags;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.settings.SettingsEnums;
|
||||
@@ -117,12 +116,8 @@ public class ZenModeSliceBuilder {
|
||||
} else {
|
||||
zenMode = Settings.Global.ZEN_MODE_OFF;
|
||||
}
|
||||
if (Flags.modesApi()) {
|
||||
NotificationManager.from(context).setZenMode(zenMode, /* conditionId= */ null, TAG,
|
||||
/* fromUser= */ true);
|
||||
} else {
|
||||
NotificationManager.from(context).setZenMode(zenMode, null /* conditionId */, TAG);
|
||||
}
|
||||
NotificationManager.from(context).setZenMode(zenMode, /* conditionId= */ null, TAG,
|
||||
/* fromUser= */ true);
|
||||
// Do not notifyChange on Uri. The service takes longer to update the current value than it
|
||||
// does for the Slice to check the current value again. Let {@link SliceBroadcastRelay}
|
||||
// handle it.
|
||||
|
||||
@@ -19,19 +19,14 @@ package com.android.settings.notification.zen;
|
||||
import android.app.AutomaticZenRule;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.ActionButtonsPreference;
|
||||
|
||||
@@ -87,7 +82,6 @@ public class ZenRuleButtonsPreferenceController extends AbstractZenModePreferenc
|
||||
mMetricsFeatureProvider.action(mContext,
|
||||
SettingsEnums.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
|
||||
mRule.setName(ruleName);
|
||||
mRule.setModified(true);
|
||||
mBackend.updateZenRule(mId, mRule);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -143,8 +143,7 @@ public class ZenRulePreference extends PrimarySwitchPreference {
|
||||
|
||||
private String computeRuleSummary(AutomaticZenRule rule) {
|
||||
if (rule != null) {
|
||||
if (Flags.modesApi() && Flags.modesUi()
|
||||
&& !TextUtils.isEmpty(rule.getTriggerDescription())) {
|
||||
if (Flags.modesUi() && !TextUtils.isEmpty(rule.getTriggerDescription())) {
|
||||
return rule.getTriggerDescription();
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
|
||||
rt.title = mContext.getString(R.string.zen_schedule_rule_type_name);
|
||||
rt.packageName = ZenModeConfig.getEventConditionProvider().getPackageName();
|
||||
rt.defaultConditionId = ZenModeConfig.toScheduleConditionId(schedule);
|
||||
if (Flags.modesApi() && Flags.modesUi()) {
|
||||
if (Flags.modesUi()) {
|
||||
rt.type = AutomaticZenRule.TYPE_SCHEDULE_TIME;
|
||||
rt.defaultTriggerDescription = SystemZenRules.getTriggerDescriptionForScheduleTime(
|
||||
mContext, schedule);
|
||||
@@ -201,7 +201,7 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
|
||||
rt.title = mContext.getString(R.string.zen_event_rule_type_name);
|
||||
rt.packageName = ZenModeConfig.getScheduleConditionProvider().getPackageName();
|
||||
rt.defaultConditionId = ZenModeConfig.toEventConditionId(event);
|
||||
if (Flags.modesApi() && Flags.modesUi()) {
|
||||
if (Flags.modesUi()) {
|
||||
rt.type = AutomaticZenRule.TYPE_SCHEDULE_CALENDAR;
|
||||
rt.defaultTriggerDescription = SystemZenRules.getTriggerDescriptionForScheduleEvent(
|
||||
mContext, event);
|
||||
|
||||
@@ -560,6 +560,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
setupPasswordRequirementsView(headerLayout);
|
||||
|
||||
mPasswordRestrictionView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
mPasswordRestrictionView.setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE);
|
||||
mPasswordEntry = view.findViewById(R.id.password_entry);
|
||||
mPasswordEntry.setOnEditorActionListener(this);
|
||||
mPasswordEntry.addTextChangedListener(this);
|
||||
@@ -770,7 +771,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
// If the stage changed, announce the header for accessibility. This
|
||||
// is a no-op when accessibility is disabled.
|
||||
if (previousStage != stage) {
|
||||
mLayout.announceForAccessibility(mLayout.getHeaderText());
|
||||
getActivity().setTitle(mLayout.getHeaderText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -66,15 +66,20 @@ public class PasswordRequirementAdapter extends
|
||||
return mRequirements[position].hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(@NonNull PasswordRequirementViewHolder holder) {
|
||||
holder.mDescriptionText.announceForAccessibility(holder.mDescriptionText.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PasswordRequirementViewHolder holder, int position) {
|
||||
final int fontSize = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.password_requirement_font_size);
|
||||
|
||||
final String requirement = mRequirements[position];
|
||||
holder.mDescriptionText.setAccessibilityDelegate(new View.AccessibilityDelegate() {
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(host, info);
|
||||
holder.mDescriptionText.setStateDescription(requirement);
|
||||
}
|
||||
});
|
||||
|
||||
holder.mDescriptionText.setText(mRequirements[position]);
|
||||
if (mIsTooShortError) {
|
||||
holder.mDescriptionText.setTextAppearance(R.style.ScreenLockPasswordHintTextFontStyle);
|
||||
|
||||
@@ -32,7 +32,7 @@ public class ShortcutsUpdateReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
|
||||
if (!Flags.modesApi() || !Flags.modesUi()) {
|
||||
if (!Flags.modesUi()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public class ShortcutsUpdater {
|
||||
private static ComponentName maybeGetReplacingComponent(Context context, ComponentName cn) {
|
||||
// ZenModeSettingsActivity is replaced by ModesSettingsActivity and will be deleted
|
||||
// soon (so we shouldn't use ZenModeSettingsActivity.class).
|
||||
if (Flags.modesApi() && Flags.modesUi()
|
||||
if (Flags.modesUi()
|
||||
&& cn.getClassName().endsWith("Settings$ZenModeSettingsActivity")) {
|
||||
return new ComponentName(context, Settings.ModesSettingsActivity.class);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class TopLevelSoundPreferenceController extends BasePreferenceController
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
preference.setSummary(Flags.modesApi() && Flags.modesUi()
|
||||
preference.setSummary(Flags.modesUi()
|
||||
? R.string.sound_dashboard_summary
|
||||
: R.string.sound_dashboard_summary_with_dnd);
|
||||
}
|
||||
|
||||
@@ -68,9 +68,6 @@ public class ConnectedBluetoothDeviceUpdaterTest {
|
||||
|
||||
private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
|
||||
private static final String TEST_EXCLUSIVE_MANAGER = "com.test.manager";
|
||||
private static final String TEMP_BOND_METADATA =
|
||||
"<TEMP_BOND_TYPE>le_audio_sharing</TEMP_BOND_TYPE>";
|
||||
private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
@@ -408,22 +405,6 @@ public class ConnectedBluetoothDeviceUpdaterTest {
|
||||
verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI)
|
||||
public void update_temporaryBondDevice_removePreference() {
|
||||
setUpDeviceUpdaterWithAudioMode(AudioManager.MODE_NORMAL);
|
||||
when(mBluetoothDeviceUpdater
|
||||
.isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
|
||||
when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
|
||||
when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
|
||||
.thenReturn(TEMP_BOND_METADATA.getBytes());
|
||||
|
||||
mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
|
||||
|
||||
verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
|
||||
verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice);
|
||||
}
|
||||
|
||||
private void setUpDeviceUpdaterWithAudioMode(int audioMode) {
|
||||
mAudioManager.setMode(audioMode);
|
||||
mBluetoothDeviceUpdater = spy(new ConnectedBluetoothDeviceUpdater(mContext,
|
||||
|
||||
@@ -75,7 +75,6 @@ public class ConnectedDeviceDashboardFragmentTest {
|
||||
private static final String KEY_AUDIO_SHARING_SETTINGS =
|
||||
"connected_device_audio_sharing_settings";
|
||||
private static final String KEY_ADD_BT_DEVICES = "add_bt_devices";
|
||||
private static final String KEY_TEMPORARY_BOND_DEVICES = "temp_bond_device_list";
|
||||
private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
|
||||
private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui";
|
||||
private static final String SLICE_ACTION = "com.android.settings.SEARCH_RESULT_TRAMPOLINE";
|
||||
@@ -130,8 +129,7 @@ public class ConnectedDeviceDashboardFragmentTest {
|
||||
KEY_SAVED_DEVICE_SEE_ALL,
|
||||
KEY_FAST_PAIR_DEVICE_SEE_ALL,
|
||||
KEY_AUDIO_SHARING_DEVICES,
|
||||
KEY_AUDIO_SHARING_SETTINGS,
|
||||
KEY_TEMPORARY_BOND_DEVICES);
|
||||
KEY_AUDIO_SHARING_SETTINGS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -43,7 +43,6 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Looper;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
@@ -111,11 +110,8 @@ public class AudioSharingCallAudioPreferenceControllerTest {
|
||||
private static final String PREF_KEY = "calls_and_alarms";
|
||||
private static final String TEST_DEVICE_NAME1 = "test1";
|
||||
private static final String TEST_DEVICE_NAME2 = "test2";
|
||||
private static final String TEMP_BOND_METADATA =
|
||||
"<TEMP_BOND_TYPE>le_audio_sharing</TEMP_BOND_TYPE>";
|
||||
private static final int TEST_DEVICE_GROUP_ID1 = 1;
|
||||
private static final int TEST_DEVICE_GROUP_ID2 = 2;
|
||||
private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
|
||||
|
||||
private static final String TEST_SETTINGS_KEY =
|
||||
"bluetooth_le_broadcast_fallback_active_group_id";
|
||||
@@ -447,23 +443,6 @@ public class AudioSharingCallAudioPreferenceControllerTest {
|
||||
assertThat(mPreference.getSummary().toString()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI)
|
||||
public void displayPreference_hasTemporaryBondDevice_doNotShow() {
|
||||
Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1);
|
||||
when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true);
|
||||
when(mBroadcast.isEnabled(any())).thenReturn(true);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2));
|
||||
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
|
||||
when(mDevice2.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS)).thenReturn(
|
||||
TEMP_BOND_METADATA.getBytes());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
assertThat(mController.mGroupedConnectedDevices).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_clickToShowCorrectDialog() {
|
||||
AlertDialog latestAlertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
|
||||
@@ -93,8 +93,14 @@ public class AudioSharingDialogFragmentTest {
|
||||
private static final String METADATA_STR =
|
||||
"BLUETOOTH:UUID:184F;BN:VGVzdA==;AT:1;AD:00A1A1A1A1A1;BI:1E240;BC:VGVzdENvZGU=;"
|
||||
+ "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;";
|
||||
private static final String METADATA_STR_NO_PASSWORD =
|
||||
"BLUETOOTH:UUID:184F;BN:SG9ja2V5;AT:0;AD:AABBCC001122;BI:DE51E9;SQ:1;AS:1;PI:FFFF;"
|
||||
+ "NS:1;BS:1;NB:1;;";
|
||||
private static final BluetoothLeBroadcastMetadata METADATA =
|
||||
BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(METADATA_STR);
|
||||
private static final BluetoothLeBroadcastMetadata METADATA_NO_PASSWORD =
|
||||
BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(
|
||||
METADATA_STR_NO_PASSWORD);
|
||||
|
||||
private Fragment mParent;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
@@ -290,6 +296,50 @@ public class AudioSharingDialogFragmentTest {
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_noExtraConnectedDevice_hasMetadataNoPassword_showCancelButton() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AtomicBoolean isCancelBtnClicked = new AtomicBoolean(false);
|
||||
AudioSharingDialogFragment.show(
|
||||
mParent,
|
||||
new ArrayList<>(),
|
||||
METADATA_NO_PASSWORD,
|
||||
new AudioSharingDialogFragment.DialogEventListener() {
|
||||
@Override
|
||||
public void onCancelClick() {
|
||||
isCancelBtnClicked.set(true);
|
||||
}
|
||||
},
|
||||
TEST_EVENT_DATA_LIST);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
ImageView image = dialog.findViewById(R.id.description_image);
|
||||
assertThat(image).isNotNull();
|
||||
TextView text = dialog.findViewById(R.id.description_text);
|
||||
assertThat(text).isNotNull();
|
||||
assertThat(METADATA_NO_PASSWORD).isNotNull();
|
||||
assertThat(text.getText().toString()).isEqualTo(
|
||||
mParent.getString(R.string.audio_sharing_dialog_qr_code_content_no_password,
|
||||
METADATA_NO_PASSWORD.getBroadcastName()));
|
||||
TextView textBottom = dialog.findViewById(R.id.description_text_2);
|
||||
assertThat(textBottom).isNotNull();
|
||||
assertThat(textBottom.getText().toString()).isEqualTo(
|
||||
mParent.getString(R.string.audio_sharing_dialog_pair_new_device_content));
|
||||
Button cancelBtn = dialog.findViewById(R.id.negative_btn);
|
||||
assertThat(cancelBtn).isNotNull();
|
||||
cancelBtn.performClick();
|
||||
shadowMainLooper().idle();
|
||||
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(
|
||||
any(Context.class),
|
||||
eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
|
||||
eq(TEST_EVENT_DATA));
|
||||
assertThat(isCancelBtnClicked.get()).isTrue();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateDialog_flagOn_singleExtraConnectedDevice() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 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.connecteddevice.audiosharing;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothStatusCodes;
|
||||
import android.content.Context;
|
||||
import android.platform.test.annotations.RequiresFlagsDisabled;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.BluetoothCallback;
|
||||
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.flags.Flags;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
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;
|
||||
|
||||
/** Tests for {@link TemporaryBondDeviceGroupController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(
|
||||
shadows = {
|
||||
ShadowBluetoothAdapter.class,
|
||||
ShadowBluetoothUtils.class
|
||||
})
|
||||
public class TemporaryBondDeviceGroupControllerTest {
|
||||
private static final String KEY = "temp_bond_device_list";
|
||||
private static final String PREFERENCE_KEY_1 = "pref_key_1";
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
@Mock
|
||||
private TemporaryBondDeviceGroupUpdater mBluetoothDeviceUpdater;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceManager mPreferenceManager;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBtManager;
|
||||
@Mock
|
||||
private BluetoothEventManager mEventManager;
|
||||
@Mock private PreferenceScreen mScreen;
|
||||
|
||||
|
||||
private PreferenceGroup mPreferenceGroup;
|
||||
private Context mContext;
|
||||
private Preference mPreference;
|
||||
private TemporaryBondDeviceGroupController mTemporaryBondDeviceGroupController;
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Lifecycle mLifecycle;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
mPreference = new Preference(mContext);
|
||||
mPreference.setKey(PREFERENCE_KEY_1);
|
||||
mPreferenceGroup = spy(new PreferenceCategory(mContext));
|
||||
when(mPreferenceGroup.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
when(mScreen.getContext()).thenReturn(mContext);
|
||||
when(mScreen.findPreference(KEY)).thenReturn(mPreferenceGroup);
|
||||
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
|
||||
mLocalBtManager = Utils.getLocalBtManager(mContext);
|
||||
when(mLocalBtManager.getEventManager()).thenReturn(mEventManager);
|
||||
ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract(
|
||||
BluetoothAdapter.getDefaultAdapter());
|
||||
shadowBluetoothAdapter.setEnabled(true);
|
||||
shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
|
||||
mTemporaryBondDeviceGroupController = spy(new TemporaryBondDeviceGroupController(mContext));
|
||||
mTemporaryBondDeviceGroupController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater);
|
||||
mTemporaryBondDeviceGroupController.setPreferenceGroup(mPreferenceGroup);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI)
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
|
||||
public void onStart_flagOff_doNothing() {
|
||||
mTemporaryBondDeviceGroupController.onStart(mLifecycleOwner);
|
||||
|
||||
verify(mEventManager, never()).registerCallback(any(BluetoothCallback.class));
|
||||
verify(mBluetoothDeviceUpdater, never()).registerCallback();
|
||||
verify(mBluetoothDeviceUpdater, never()).refreshPreference();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI)
|
||||
public void onStart_audioSharingUINotAvailable_doNothing() {
|
||||
mTemporaryBondDeviceGroupController.onStart(mLifecycleOwner);
|
||||
|
||||
verify(mEventManager, never()).registerCallback(any(BluetoothCallback.class));
|
||||
verify(mBluetoothDeviceUpdater, never()).registerCallback();
|
||||
verify(mBluetoothDeviceUpdater, never()).refreshPreference();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI,
|
||||
Flags.FLAG_ENABLE_LE_AUDIO_SHARING})
|
||||
public void onStart_registerCallbacks() {
|
||||
mTemporaryBondDeviceGroupController.onStart(mLifecycleOwner);
|
||||
|
||||
verify(mEventManager).registerCallback(any(BluetoothCallback.class));
|
||||
verify(mBluetoothDeviceUpdater).registerCallback();
|
||||
verify(mBluetoothDeviceUpdater).refreshPreference();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI,
|
||||
Flags.FLAG_ENABLE_LE_AUDIO_SHARING})
|
||||
public void onStop_unregisterCallbacks() {
|
||||
mTemporaryBondDeviceGroupController.onStop(mLifecycleOwner);
|
||||
|
||||
verify(mEventManager).unregisterCallback(any(BluetoothCallback.class));
|
||||
verify(mBluetoothDeviceUpdater).unregisterCallback();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI)
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
|
||||
public void displayPreference_flagOff_doNothing() {
|
||||
mTemporaryBondDeviceGroupController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreferenceGroup.isVisible()).isFalse();
|
||||
verify(mBluetoothDeviceUpdater, never()).forceUpdate();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI)
|
||||
public void displayPreference_audioSharingUINotAvailable_doNothing() {
|
||||
mTemporaryBondDeviceGroupController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreferenceGroup.isVisible()).isFalse();
|
||||
verify(mBluetoothDeviceUpdater, never()).forceUpdate();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI,
|
||||
Flags.FLAG_ENABLE_LE_AUDIO_SHARING})
|
||||
public void displayPreference_updateDeviceList() {
|
||||
mTemporaryBondDeviceGroupController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreferenceGroup.isVisible()).isFalse();
|
||||
verify(mBluetoothDeviceUpdater).setPrefContext(mContext);
|
||||
verify(mBluetoothDeviceUpdater).forceUpdate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAdded_firstAdd_becomeVisibleAndPreferenceAdded() {
|
||||
mTemporaryBondDeviceGroupController.onDeviceAdded(mPreference);
|
||||
|
||||
assertThat(mPreferenceGroup.isVisible()).isTrue();
|
||||
assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceRemoved_lastRemove_becomeInvisibleAndPreferenceRemoved() {
|
||||
mPreferenceGroup.addPreference(mPreference);
|
||||
|
||||
mTemporaryBondDeviceGroupController.onDeviceRemoved(mPreference);
|
||||
|
||||
assertThat(mPreferenceGroup.isVisible()).isFalse();
|
||||
assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceRemoved_notLastRemove_stillVisible() {
|
||||
mPreferenceGroup.setVisible(true);
|
||||
mPreferenceGroup.addPreference(mPreference);
|
||||
mPreferenceGroup.addPreference(new Preference(mContext));
|
||||
|
||||
mTemporaryBondDeviceGroupController.onDeviceRemoved(mPreference);
|
||||
|
||||
assertThat(mPreferenceGroup.isVisible()).isTrue();
|
||||
assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPreferenceKey_returnsCorrectKey() {
|
||||
assertThat(mTemporaryBondDeviceGroupController.getPreferenceKey()).isEqualTo(KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI,
|
||||
Flags.FLAG_ENABLE_LE_AUDIO_SHARING})
|
||||
public void getAvailabilityStatus_returnsAvailable() {
|
||||
assertThat(mTemporaryBondDeviceGroupController.getAvailabilityStatus()).isEqualTo(
|
||||
AVAILABLE_UNSEARCHABLE);
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.connecteddevice.audiosharing;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothStatusCodes;
|
||||
import android.content.Context;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.flags.Flags;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/** Tests for {@link TemporaryBondDeviceGroupUpdater}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(
|
||||
shadows = {
|
||||
ShadowBluetoothAdapter.class,
|
||||
ShadowBluetoothUtils.class
|
||||
})
|
||||
public class TemporaryBondDeviceGroupUpdaterTest {
|
||||
private static final String TAG = "TemporaryBondDeviceGroupUpdater";
|
||||
private static final String PREF_KEY_PREFIX = "temp_bond_bt_";
|
||||
private static final String TEMP_BOND_METADATA =
|
||||
"<TEMP_BOND_TYPE>le_audio_sharing</TEMP_BOND_TYPE>";
|
||||
private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
@Mock
|
||||
private DevicePreferenceCallback mDevicePreferenceCallback;
|
||||
@Mock
|
||||
private CachedBluetoothDevice mCachedBluetoothDevice;
|
||||
@Mock
|
||||
private BluetoothDevice mBluetoothDevice;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBtManager;
|
||||
@Mock
|
||||
private CachedBluetoothDeviceManager mCachedDeviceManager;
|
||||
|
||||
private TemporaryBondDeviceGroupUpdater mDeviceUpdater;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract(
|
||||
BluetoothAdapter.getDefaultAdapter());
|
||||
shadowBluetoothAdapter.setEnabled(true);
|
||||
shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
|
||||
mLocalBtManager = Utils.getLocalBtManager(context);
|
||||
when(mLocalBtManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
|
||||
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
|
||||
Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
|
||||
cachedDevices.add(mCachedBluetoothDevice);
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
|
||||
mDeviceUpdater =
|
||||
spy(
|
||||
new TemporaryBondDeviceGroupUpdater(
|
||||
context, mDevicePreferenceCallback, /* metricsCategory= */ 0));
|
||||
mDeviceUpdater.setPrefContext(context);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowBluetoothUtils.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI,
|
||||
Flags.FLAG_ENABLE_LE_AUDIO_SHARING})
|
||||
public void isFilterMatched_isTemporaryBondDevice_returnsTrue() {
|
||||
when(mBluetoothDevice.isConnected()).thenReturn(true);
|
||||
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||
when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
|
||||
.thenReturn(TEMP_BOND_METADATA.getBytes());
|
||||
|
||||
assertThat(mDeviceUpdater.isFilterMatched(mCachedBluetoothDevice)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLogTag_returnsCorrectTag() {
|
||||
assertThat(mDeviceUpdater.getLogTag()).isEqualTo(TAG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPreferenceKey_returnsCorrectKey() {
|
||||
assertThat(mDeviceUpdater.getPreferenceKeyPrefix()).isEqualTo(PREF_KEY_PREFIX);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ import static android.bluetooth.BluetoothStatusCodes.FEATURE_SUPPORTED;
|
||||
|
||||
import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController
|
||||
.A2DP_OFFLOAD_DISABLED_PROPERTY;
|
||||
import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController
|
||||
.A2DP_OFFLOAD_SUPPORTED_PROPERTY;
|
||||
import static com.android.settings.development.BluetoothLeAudioHwOffloadPreferenceController
|
||||
.LE_AUDIO_OFFLOAD_DISABLED_PROPERTY;
|
||||
import static com.android.settings.development.BluetoothLeAudioHwOffloadPreferenceController
|
||||
@@ -120,4 +122,17 @@ public class BluetoothLeAudioHwOffloadPreferenceControllerTest {
|
||||
leAueioDisabled = SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, false);
|
||||
assertThat(leAueioDisabled).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asDisableDeveloperOption_ResetLEOffloadBasedOnA2dpLeAudioOffloadSupported() {
|
||||
SystemProperties.set(LE_AUDIO_OFFLOAD_SUPPORTED_PROPERTY, Boolean.toString(true));
|
||||
SystemProperties.set(A2DP_OFFLOAD_SUPPORTED_PROPERTY, Boolean.toString(true));
|
||||
|
||||
SystemProperties.set(
|
||||
LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(true));
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
boolean leAueioDisabled =
|
||||
SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, false);
|
||||
assertThat(leAueioDisabled).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,8 @@ public class DesktopExperiencePreferenceControllerTest {
|
||||
// Set desktop mode available
|
||||
when(mResources.getBoolean(com.android.internal.R.bool.config_isDesktopModeSupported))
|
||||
.thenReturn(true);
|
||||
when(mResources.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops))
|
||||
when(mResources
|
||||
.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops))
|
||||
.thenReturn(true);
|
||||
ShadowSystemProperties.override("persist.wm.debug.desktop_mode_enforce_device_restrictions",
|
||||
"false");
|
||||
|
||||
@@ -104,7 +104,8 @@ public class DesktopModePreferenceControllerTest {
|
||||
// Set desktop mode available
|
||||
when(mResources.getBoolean(R.bool.config_isDesktopModeSupported))
|
||||
.thenReturn(true);
|
||||
when(mResources.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops))
|
||||
when(mResources
|
||||
.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops))
|
||||
.thenReturn(true);
|
||||
ShadowSystemProperties.override("persist.wm.debug.desktop_mode_enforce_device_restrictions",
|
||||
"false");
|
||||
|
||||
@@ -97,7 +97,8 @@ public class DesktopModeSecondaryDisplayPreferenceControllerTest {
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
when(mResources.getBoolean(R.bool.config_isDesktopModeSupported)).thenReturn(false);
|
||||
when(mResources.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops))
|
||||
when(mResources
|
||||
.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops))
|
||||
.thenReturn(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ public class FreeformWindowsPreferenceControllerTest {
|
||||
doReturn(mFragmentManager).when(mActivity).getSupportFragmentManager();
|
||||
doReturn(mActivity).when(mFragment).getActivity();
|
||||
doReturn(true).when(mResources).getBoolean(R.bool.config_isDesktopModeSupported);
|
||||
doReturn(true).when(mResources).getBoolean(R.bool.config_canInternalDisplayHostDesktops);
|
||||
mController = new FreeformWindowsPreferenceController(mContext, mFragment);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
|
||||
@@ -99,9 +99,9 @@ public final class PowerUsageTimeControllerTest {
|
||||
/* anomalyHintText= */ null);
|
||||
|
||||
verifyOnePreferenceInvisible(mBackgroundTimePreference);
|
||||
verify(mScreenTimePreference).setTimeTitle("Screen time");
|
||||
verify(mScreenTimePreference).setTimeSummary("1 min");
|
||||
verify(mScreenTimePreference, never()).setAnomalyHint(anyString());
|
||||
verify(mScreenTimePreference).setTitle("Screen time");
|
||||
verify(mScreenTimePreference).setSummary("1 min");
|
||||
verify(mScreenTimePreference, never()).setHint(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -117,9 +117,9 @@ public final class PowerUsageTimeControllerTest {
|
||||
/* anomalyHintText= */ null);
|
||||
|
||||
verifyOnePreferenceInvisible(mScreenTimePreference);
|
||||
verify(mBackgroundTimePreference).setTimeTitle("Background time");
|
||||
verify(mBackgroundTimePreference).setTimeSummary("2 min");
|
||||
verify(mBackgroundTimePreference, never()).setAnomalyHint(anyString());
|
||||
verify(mBackgroundTimePreference).setTitle("Background time");
|
||||
verify(mBackgroundTimePreference).setSummary("2 min");
|
||||
verify(mBackgroundTimePreference, never()).setHint(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -135,12 +135,12 @@ public final class PowerUsageTimeControllerTest {
|
||||
/* anomalyHintText= */ null);
|
||||
|
||||
verifyAllPreferencesVisible(true);
|
||||
verify(mScreenTimePreference).setTimeTitle("Screen time");
|
||||
verify(mScreenTimePreference).setTimeSummary("1 min");
|
||||
verify(mScreenTimePreference, never()).setAnomalyHint(anyString());
|
||||
verify(mBackgroundTimePreference).setTimeTitle("Background time");
|
||||
verify(mBackgroundTimePreference).setTimeSummary("2 min");
|
||||
verify(mBackgroundTimePreference, never()).setAnomalyHint(anyString());
|
||||
verify(mScreenTimePreference).setTitle("Screen time");
|
||||
verify(mScreenTimePreference).setSummary("1 min");
|
||||
verify(mScreenTimePreference, never()).setHint(anyString());
|
||||
verify(mBackgroundTimePreference).setTitle("Background time");
|
||||
verify(mBackgroundTimePreference).setSummary("2 min");
|
||||
verify(mBackgroundTimePreference, never()).setHint(anyString());
|
||||
verify(mPowerUsageTimeCategory).setTitle("App usage for 12 am-2 am");
|
||||
}
|
||||
|
||||
@@ -173,8 +173,8 @@ public final class PowerUsageTimeControllerTest {
|
||||
/* anomalyHintText= */ null);
|
||||
|
||||
verifyAllPreferencesVisible(true);
|
||||
verify(mScreenTimePreference).setTimeSummary("1 min");
|
||||
verify(mBackgroundTimePreference).setTimeSummary("Less than a minute");
|
||||
verify(mScreenTimePreference).setSummary("1 min");
|
||||
verify(mBackgroundTimePreference).setSummary("Less than a minute");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -190,8 +190,8 @@ public final class PowerUsageTimeControllerTest {
|
||||
/* anomalyHintText= */ null);
|
||||
|
||||
verifyAllPreferencesVisible(true);
|
||||
verify(mScreenTimePreference).setTimeSummary("Less than a minute");
|
||||
verify(mBackgroundTimePreference).setTimeSummary("2 min");
|
||||
verify(mScreenTimePreference).setSummary("Less than a minute");
|
||||
verify(mBackgroundTimePreference).setSummary("2 min");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -207,8 +207,8 @@ public final class PowerUsageTimeControllerTest {
|
||||
/* anomalyHintText= */ null);
|
||||
|
||||
verifyAllPreferencesVisible(true);
|
||||
verify(mScreenTimePreference).setTimeSummary("Less than a minute");
|
||||
verify(mBackgroundTimePreference).setTimeSummary("Less than a minute");
|
||||
verify(mScreenTimePreference).setSummary("Less than a minute");
|
||||
verify(mBackgroundTimePreference).setSummary("Less than a minute");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -224,8 +224,8 @@ public final class PowerUsageTimeControllerTest {
|
||||
TEST_ANOMALY_HINT_TEXT);
|
||||
|
||||
verifyAllPreferencesVisible(true);
|
||||
verify(mScreenTimePreference).setAnomalyHint(TEST_ANOMALY_HINT_TEXT);
|
||||
verify(mBackgroundTimePreference, never()).setAnomalyHint(anyString());
|
||||
verify(mScreenTimePreference).setHint(TEST_ANOMALY_HINT_TEXT);
|
||||
verify(mBackgroundTimePreference, never()).setHint(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -241,8 +241,8 @@ public final class PowerUsageTimeControllerTest {
|
||||
TEST_ANOMALY_HINT_TEXT);
|
||||
|
||||
verifyAllPreferencesVisible(true);
|
||||
verify(mScreenTimePreference, never()).setAnomalyHint(anyString());
|
||||
verify(mBackgroundTimePreference).setAnomalyHint(TEST_ANOMALY_HINT_TEXT);
|
||||
verify(mScreenTimePreference, never()).setHint(anyString());
|
||||
verify(mBackgroundTimePreference).setHint(TEST_ANOMALY_HINT_TEXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -258,9 +258,9 @@ public final class PowerUsageTimeControllerTest {
|
||||
TEST_ANOMALY_HINT_TEXT);
|
||||
|
||||
verifyAllPreferencesVisible(true);
|
||||
verify(mScreenTimePreference).setTimeSummary("Less than a minute");
|
||||
verify(mScreenTimePreference).setAnomalyHint(TEST_ANOMALY_HINT_TEXT);
|
||||
verify(mBackgroundTimePreference, never()).setAnomalyHint(anyString());
|
||||
verify(mScreenTimePreference).setSummary("Less than a minute");
|
||||
verify(mScreenTimePreference).setHint(TEST_ANOMALY_HINT_TEXT);
|
||||
verify(mBackgroundTimePreference, never()).setHint(anyString());
|
||||
}
|
||||
|
||||
private void verifySetPrefToVisible(Preference pref, boolean isVisible) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public final class BatteryUsageBreakdownControllerTest {
|
||||
@Mock private PreferenceGroup mRootPreferenceGroup;
|
||||
@Mock private Drawable mDrawable;
|
||||
@Mock private BatteryHistEntry mBatteryHistEntry;
|
||||
@Mock private AnomalyAppItemPreference mAnomalyAppItemPreference;
|
||||
@Mock private PowerGaugePreference mPowerGaugePreference;
|
||||
|
||||
private Context mContext;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
@@ -131,13 +131,13 @@ public final class BatteryUsageBreakdownControllerTest {
|
||||
BatteryDiffEntry.sResourceCache.put(
|
||||
"fakeBatteryDiffEntryKey",
|
||||
new BatteryEntry.NameAndIcon("fakeName", /* icon= */ null, /* iconId= */ 1));
|
||||
doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).findPreference(PREF_KEY);
|
||||
doReturn(mPowerGaugePreference).when(mRootPreferenceGroup).findPreference(PREF_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDestroy_clearPreferenceCacheAndPreferenceGroupRemoveAll() {
|
||||
// Ensures the testing environment is correct.
|
||||
mBatteryUsageBreakdownController.mPreferenceCache.put(PREF_KEY, mAnomalyAppItemPreference);
|
||||
mBatteryUsageBreakdownController.mPreferenceCache.put(PREF_KEY, mPowerGaugePreference);
|
||||
assertThat(mBatteryUsageBreakdownController.mPreferenceCache).hasSize(1);
|
||||
|
||||
mBatteryUsageBreakdownController.onDestroy();
|
||||
@@ -204,25 +204,25 @@ public final class BatteryUsageBreakdownControllerTest {
|
||||
@Test
|
||||
public void removeAndCacheAllUnusedPreferences_removePref_buildCacheAndRemoveAllPreference() {
|
||||
doReturn(1).when(mRootPreferenceGroup).getPreferenceCount();
|
||||
doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).getPreference(0);
|
||||
doReturn(mPowerGaugePreference).when(mRootPreferenceGroup).getPreference(0);
|
||||
doReturn(PREF_KEY2).when(mBatteryHistEntry).getKey();
|
||||
doReturn(PREF_KEY).when(mAnomalyAppItemPreference).getKey();
|
||||
doReturn(PREF_KEY).when(mPowerGaugePreference).getKey();
|
||||
// Ensures the testing data is correct.
|
||||
assertThat(mBatteryUsageBreakdownController.mPreferenceCache).isEmpty();
|
||||
|
||||
mBatteryUsageBreakdownController.removeAndCacheAllUnusedPreferences();
|
||||
|
||||
assertThat(mBatteryUsageBreakdownController.mPreferenceCache.get(PREF_KEY))
|
||||
.isEqualTo(mAnomalyAppItemPreference);
|
||||
verify(mRootPreferenceGroup).removePreference(mAnomalyAppItemPreference);
|
||||
.isEqualTo(mPowerGaugePreference);
|
||||
verify(mRootPreferenceGroup).removePreference(mPowerGaugePreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeAndCacheAllUnusedPreferences_keepPref_KeepAllPreference() {
|
||||
doReturn(1).when(mRootPreferenceGroup).getPreferenceCount();
|
||||
doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).getPreference(0);
|
||||
doReturn(mPowerGaugePreference).when(mRootPreferenceGroup).getPreference(0);
|
||||
doReturn(PREF_KEY).when(mBatteryDiffEntry).getKey();
|
||||
doReturn(PREF_KEY).when(mAnomalyAppItemPreference).getKey();
|
||||
doReturn(PREF_KEY).when(mPowerGaugePreference).getKey();
|
||||
// Ensures the testing data is correct.
|
||||
assertThat(mBatteryUsageBreakdownController.mPreferenceCache).isEmpty();
|
||||
|
||||
@@ -246,11 +246,11 @@ public final class BatteryUsageBreakdownControllerTest {
|
||||
@Test
|
||||
public void handlePreferenceTreeClick_forAppEntry_returnTrue() {
|
||||
mBatteryDiffEntry.mConsumerType = ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY;
|
||||
doReturn(mBatteryDiffEntry).when(mAnomalyAppItemPreference).getBatteryDiffEntry();
|
||||
doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry();
|
||||
|
||||
assertThat(
|
||||
mBatteryUsageBreakdownController.handlePreferenceTreeClick(
|
||||
mAnomalyAppItemPreference))
|
||||
mPowerGaugePreference))
|
||||
.isTrue();
|
||||
verify(mMetricsFeatureProvider)
|
||||
.action(
|
||||
@@ -264,11 +264,11 @@ public final class BatteryUsageBreakdownControllerTest {
|
||||
@Test
|
||||
public void handlePreferenceTreeClick_forSystemEntry_returnTrue() {
|
||||
mBatteryDiffEntry.mConsumerType = ConvertUtils.CONSUMER_TYPE_UID_BATTERY;
|
||||
doReturn(mBatteryDiffEntry).when(mAnomalyAppItemPreference).getBatteryDiffEntry();
|
||||
doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry();
|
||||
|
||||
assertThat(
|
||||
mBatteryUsageBreakdownController.handlePreferenceTreeClick(
|
||||
mAnomalyAppItemPreference))
|
||||
mPowerGaugePreference))
|
||||
.isTrue();
|
||||
verify(mMetricsFeatureProvider)
|
||||
.action(
|
||||
|
||||
@@ -19,19 +19,20 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.VectorDrawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Space;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.widget.SettingsThemeHelper;
|
||||
|
||||
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;
|
||||
@@ -48,17 +49,17 @@ public class PowerGaugePreferenceTest {
|
||||
private View mWidgetView;
|
||||
private PreferenceViewHolder mPreferenceViewHolder;
|
||||
|
||||
@Mock Drawable mMockIcon;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPowerGaugePreference = new PowerGaugePreference(mContext);
|
||||
mRootView =
|
||||
LayoutInflater.from(mContext)
|
||||
.inflate(
|
||||
com.android.settingslib.widget.preference.app.R.layout
|
||||
.preference_app,
|
||||
null);
|
||||
.inflate(mPowerGaugePreference.getLayoutResource(), null);
|
||||
mWidgetView =
|
||||
LayoutInflater.from(mContext).inflate(R.layout.preference_widget_summary, null);
|
||||
final LinearLayout widgetFrame = mRootView.findViewById(android.R.id.widget_frame);
|
||||
@@ -66,31 +67,56 @@ public class PowerGaugePreferenceTest {
|
||||
widgetFrame.addView(mWidgetView);
|
||||
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
|
||||
|
||||
mPowerGaugePreference = new PowerGaugePreference(mContext);
|
||||
assertThat(mPowerGaugePreference.getLayoutResource())
|
||||
.isEqualTo(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
.isEqualTo(
|
||||
SettingsThemeHelper.isExpressiveTheme(mContext)
|
||||
? R.layout.expressive_warning_frame_preference
|
||||
: R.layout.warning_frame_preference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBindViewHolder_showAnomaly_bindAnomalyIcon() {
|
||||
mPowerGaugePreference.shouldShowAnomalyIcon(true);
|
||||
public void testOnBindViewHolder_showHint_hasHintChip() {
|
||||
mPowerGaugePreference.setHint("Hint Text");
|
||||
mPowerGaugePreference.setIcon(mMockIcon);
|
||||
mPowerGaugePreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
TextView widgetSummary = (TextView) mPreferenceViewHolder.findViewById(R.id.widget_summary);
|
||||
final Drawable[] drawables = widgetSummary.getCompoundDrawablesRelative();
|
||||
final LinearLayout warningChipFrame =
|
||||
(LinearLayout) mPreferenceViewHolder.findViewById(R.id.warning_chip_frame);
|
||||
final Space warningPaddingPlaceHolder =
|
||||
warningChipFrame.findViewById(R.id.warning_padding_placeholder);
|
||||
|
||||
assertThat(drawables[0]).isInstanceOf(VectorDrawable.class);
|
||||
assertThat(warningChipFrame.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(warningPaddingPlaceHolder.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBindViewHolder_notShowAnomaly_bindAnomalyIcon() {
|
||||
mPowerGaugePreference.shouldShowAnomalyIcon(false);
|
||||
public void testOnBindViewHolder_emptyHintText_withoutHintChip() {
|
||||
mPowerGaugePreference.setHint("");
|
||||
mPowerGaugePreference.setIcon(mMockIcon);
|
||||
mPowerGaugePreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
TextView widgetSummary = (TextView) mPreferenceViewHolder.findViewById(R.id.widget_summary);
|
||||
final Drawable[] drawables = widgetSummary.getCompoundDrawablesRelative();
|
||||
final LinearLayout warningChipFrame =
|
||||
(LinearLayout) mPreferenceViewHolder.findViewById(R.id.warning_chip_frame);
|
||||
final Space warningPaddingPlaceholder =
|
||||
warningChipFrame.findViewById(R.id.warning_padding_placeholder);
|
||||
|
||||
assertThat(drawables[0]).isNull();
|
||||
assertThat(warningChipFrame.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(warningPaddingPlaceholder.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBindViewHolder_noAppIconWithHintText_hasChipWithoutPaddingPlaceholder() {
|
||||
mPowerGaugePreference.setHint("Anomaly Hint Text");
|
||||
mPowerGaugePreference.setIcon(null);
|
||||
mPowerGaugePreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final LinearLayout warningChipFrame =
|
||||
(LinearLayout) mPreferenceViewHolder.findViewById(R.id.warning_chip_frame);
|
||||
final Space warningPaddingPlaceHolder =
|
||||
warningChipFrame.findViewById(R.id.warning_padding_placeholder);
|
||||
|
||||
assertThat(warningChipFrame.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(warningPaddingPlaceHolder.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -102,7 +102,7 @@ public class DndConditionalCardControllerTest {
|
||||
private ZenModeConfig getMutedAllConfig() {
|
||||
final ZenModeConfig config = new ZenModeConfig();
|
||||
config.applyNotificationPolicy(new NotificationManager.Policy(0, 0, 0));
|
||||
config.areChannelsBypassingDnd = false;
|
||||
config.hasPriorityChannels = false;
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.window.OnBackInvokedDispatcher;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
@@ -92,17 +92,17 @@ public class LocaleDialogFragmentTest {
|
||||
@Test
|
||||
public void onBackInvoked_dialogIsStillDisplaying() {
|
||||
mDialogFragment.setBackDispatcher(mOnBackInvokedDispatcher);
|
||||
AlertDialog alertDialog = (AlertDialog) mDialogFragment.onCreateDialog(null);
|
||||
alertDialog.show();
|
||||
assertThat(alertDialog).isNotNull();
|
||||
assertThat(alertDialog.isShowing()).isTrue();
|
||||
Dialog dialog = mDialogFragment.onCreateDialog(null);
|
||||
dialog.show();
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
|
||||
mOnBackInvokedDispatcher.registerOnBackInvokedCallback(
|
||||
eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any());
|
||||
|
||||
mDialogFragment.getBackInvokedCallback().onBackInvoked();
|
||||
|
||||
assertThat(alertDialog.isShowing()).isTrue();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.IActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -53,10 +54,10 @@ import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.internal.app.LocaleStore;
|
||||
@@ -78,6 +79,7 @@ import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowDialog;
|
||||
import org.robolectric.shadows.ShadowLooper;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@@ -87,6 +89,7 @@ import java.util.Locale;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowDialog.class,
|
||||
ShadowAlertDialogCompat.class,
|
||||
ShadowActivityManager.class,
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
@@ -143,6 +146,8 @@ public class LocaleListEditorTest {
|
||||
private ImageView mDragHandle;
|
||||
@Mock
|
||||
private NotificationController mNotificationController;
|
||||
@Mock
|
||||
private Preference mAddLanguagePreference;
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule =
|
||||
@@ -166,6 +171,8 @@ public class LocaleListEditorTest {
|
||||
context.getSystemService(Context.USER_SERVICE));
|
||||
ReflectionHelpers.setField(mLocaleListEditor, "mAdapter", mAdapter);
|
||||
ReflectionHelpers.setField(mLocaleListEditor, "mAddLanguage", mAddLanguage);
|
||||
ReflectionHelpers.setField(mLocaleListEditor, "mAddLanguagePreference",
|
||||
mAddLanguagePreference);
|
||||
ReflectionHelpers.setField(mLocaleListEditor, "mFragmentManager", mFragmentManager);
|
||||
ReflectionHelpers.setField(mLocaleListEditor, "mMetricsFeatureProvider",
|
||||
mMetricsFeatureProvider);
|
||||
@@ -178,7 +185,7 @@ public class LocaleListEditorTest {
|
||||
ReflectionHelpers.setField(mLocaleListEditor, "mRemoveMode", false);
|
||||
ReflectionHelpers.setField(mLocaleListEditor, "mShowingRemoveDialog", false);
|
||||
ReflectionHelpers.setField(mLocaleListEditor, "mLocaleAdditionMode", false);
|
||||
ShadowAlertDialogCompat.reset();
|
||||
ShadowDialog.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -209,14 +216,13 @@ public class LocaleListEditorTest {
|
||||
//launch dialog
|
||||
mLocaleListEditor.showRemoveLocaleWarningDialog();
|
||||
|
||||
final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
final Dialog dialog = ShadowDialog.getLatestDialog();
|
||||
|
||||
assertThat(dialog).isNotNull();
|
||||
|
||||
final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
|
||||
|
||||
assertThat(shadowDialog.getTitle()).isEqualTo(
|
||||
mContext.getString(R.string.dlg_remove_locales_error_title));
|
||||
TextView dialogTitle = dialog.findViewById(R.id.dialog_with_icon_title);
|
||||
assertThat(dialogTitle.getText().toString())
|
||||
.isEqualTo(mContext.getString(R.string.dlg_remove_locales_error_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -231,14 +237,13 @@ public class LocaleListEditorTest {
|
||||
//launch dialog
|
||||
mLocaleListEditor.showRemoveLocaleWarningDialog();
|
||||
|
||||
final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
final Dialog dialog = ShadowDialog.getLatestDialog();
|
||||
|
||||
assertThat(dialog).isNotNull();
|
||||
|
||||
final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
|
||||
|
||||
assertThat(shadowDialog.getMessage()).isEqualTo(
|
||||
mContext.getString(R.string.dlg_remove_locales_message));
|
||||
TextView dialogMessage = dialog.findViewById(R.id.dialog_with_icon_message);
|
||||
assertThat(dialogMessage.getText().toString())
|
||||
.isEqualTo(mContext.getString(R.string.dlg_remove_locales_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -253,13 +258,12 @@ public class LocaleListEditorTest {
|
||||
//launch dialog
|
||||
mLocaleListEditor.showRemoveLocaleWarningDialog();
|
||||
|
||||
final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
final Dialog dialog = ShadowDialog.getLatestDialog();
|
||||
|
||||
assertThat(dialog).isNotNull();
|
||||
|
||||
final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
|
||||
|
||||
assertThat(shadowDialog.getMessage()).isNull();
|
||||
TextView dialogMessage = dialog.findViewById(R.id.dialog_with_icon_message);
|
||||
assertThat(dialogMessage.getText().isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -280,12 +284,12 @@ public class LocaleListEditorTest {
|
||||
//launch the first dialog
|
||||
mLocaleListEditor.showRemoveLocaleWarningDialog();
|
||||
|
||||
final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
final Dialog dialog = ShadowDialog.getLatestDialog();
|
||||
|
||||
assertThat(dialog).isNotNull();
|
||||
|
||||
// click the remove button
|
||||
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
|
||||
dialog.findViewById(R.id.button_ok).performClick();
|
||||
ShadowLooper.idleMainLooper();
|
||||
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
|
||||
@@ -21,14 +21,12 @@ import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNI
|
||||
import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.net.ConnectivitySettingsManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -88,31 +86,31 @@ public class PrivateDnsModeDialogPreferenceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCheckedChanged_dnsModeOff_disableEditText() {
|
||||
public void onCheckedChanged_dnsModeOff_disableHostnameText() {
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_off);
|
||||
|
||||
assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_OFF);
|
||||
assertThat(mPreference.mEditText.isEnabled()).isFalse();
|
||||
assertThat(mPreference.mHostnameText.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCheckedChanged_dnsModeOpportunistic_disableEditText() {
|
||||
public void onCheckedChanged_dnsModeOpportunistic_disableHostnameText() {
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_opportunistic);
|
||||
|
||||
assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_OPPORTUNISTIC);
|
||||
assertThat(mPreference.mEditText.isEnabled()).isFalse();
|
||||
assertThat(mPreference.mHostnameText.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCheckedChanged_dnsModeProvider_enableEditText() {
|
||||
public void onCheckedChanged_dnsModeProvider_enableHostnameText() {
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider);
|
||||
|
||||
assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
|
||||
assertThat(mPreference.mEditText.isEnabled()).isTrue();
|
||||
assertThat(mPreference.mHostnameText.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBindDialogView_containsCorrectData() {
|
||||
public void onBindDialogView_containsCorrectData() {
|
||||
// Don't set settings to the default value ("opportunistic") as that
|
||||
// risks masking failure to read the mode from settings.
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OFF);
|
||||
@@ -123,57 +121,74 @@ public class PrivateDnsModeDialogPreferenceTest {
|
||||
new LinearLayout(mContext), false);
|
||||
mPreference.onBindDialogView(view);
|
||||
|
||||
assertThat(mPreference.mEditText.getText().toString()).isEqualTo(HOST_NAME);
|
||||
assertThat(mPreference.mHostnameText.getText().toString()).isEqualTo(HOST_NAME);
|
||||
assertThat(mPreference.mRadioGroup.getCheckedRadioButtonId()).isEqualTo(
|
||||
R.id.private_dns_mode_off);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCheckedChanged_switchMode_saveButtonHasCorrectState() {
|
||||
final String[] INVALID_HOST_NAMES = new String[] {
|
||||
INVALID_HOST_NAME,
|
||||
"2001:db8::53", // IPv6 string literal
|
||||
"192.168.1.1", // IPv4 string literal
|
||||
};
|
||||
public void doSaveButton_changeToOffMode_saveData() {
|
||||
// Set the default settings to OPPORTUNISTIC
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OPPORTUNISTIC);
|
||||
|
||||
for (String invalid : INVALID_HOST_NAMES) {
|
||||
// Set invalid hostname
|
||||
mPreference.mEditText.setText(invalid);
|
||||
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_off);
|
||||
assertWithMessage("off: " + invalid).that(mSaveButton.isEnabled()).isTrue();
|
||||
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_opportunistic);
|
||||
assertWithMessage("opportunistic: " + invalid).that(mSaveButton.isEnabled()).isTrue();
|
||||
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider);
|
||||
assertWithMessage("provider: " + invalid).that(mSaveButton.isEnabled()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClick_positiveButtonClicked_saveData() {
|
||||
// Set the default settings to OFF
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OFF);
|
||||
|
||||
mPreference.mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
||||
mPreference.onClick(null, DialogInterface.BUTTON_POSITIVE);
|
||||
mPreference.mMode = PRIVATE_DNS_MODE_OFF;
|
||||
mPreference.doSaveButton();
|
||||
|
||||
// Change to OPPORTUNISTIC
|
||||
assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext)).isEqualTo(
|
||||
PRIVATE_DNS_MODE_OPPORTUNISTIC);
|
||||
assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext))
|
||||
.isEqualTo(PRIVATE_DNS_MODE_OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClick_negativeButtonClicked_doNothing() {
|
||||
public void doSaveButton_changeToOpportunisticMode_saveData() {
|
||||
// Set the default settings to OFF
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OFF);
|
||||
|
||||
mPreference.mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
||||
mPreference.onClick(null, DialogInterface.BUTTON_NEGATIVE);
|
||||
mPreference.doSaveButton();
|
||||
|
||||
// Still equal to OFF
|
||||
assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext)).isEqualTo(
|
||||
PRIVATE_DNS_MODE_OFF);
|
||||
// Change to OPPORTUNISTIC
|
||||
assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext))
|
||||
.isEqualTo(PRIVATE_DNS_MODE_OPPORTUNISTIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doSaveButton_changeToProviderHostnameMode_saveData() {
|
||||
// Set the default settings to OFF
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OFF);
|
||||
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider);
|
||||
mPreference.mHostnameText.setText(HOST_NAME);
|
||||
mPreference.doSaveButton();
|
||||
|
||||
// Change to PROVIDER_HOSTNAME
|
||||
assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext))
|
||||
.isEqualTo(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
|
||||
assertThat(ConnectivitySettingsManager.getPrivateDnsHostname(mContext))
|
||||
.isEqualTo(HOST_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doSaveButton_providerHostnameIsEmpty_setHostnameError() {
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
|
||||
ConnectivitySettingsManager.setPrivateDnsHostname(mContext, HOST_NAME);
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider);
|
||||
|
||||
mPreference.mHostnameText.setText("");
|
||||
mPreference.doSaveButton();
|
||||
|
||||
assertThat(mPreference.mHostnameLayout.isErrorEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doSaveButton_providerHostnameIsInvalid_setHostnameError() {
|
||||
ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
|
||||
ConnectivitySettingsManager.setPrivateDnsHostname(mContext, HOST_NAME);
|
||||
mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider);
|
||||
|
||||
mPreference.mHostnameText.setText(INVALID_HOST_NAME);
|
||||
mPreference.doSaveButton();
|
||||
|
||||
assertThat(mPreference.mHostnameLayout.isErrorEnabled()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class ZenModeSetCalendarPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI})
|
||||
@EnableFlags(Flags.FLAG_MODES_UI)
|
||||
public void updateEventMode_updatesConditionAndTriggerDescription() {
|
||||
ZenMode mode = new TestModeBuilder()
|
||||
.setPackage(SystemZenRules.PACKAGE_ANDROID)
|
||||
|
||||
@@ -80,7 +80,7 @@ public class ZenModeSetSchedulePreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI})
|
||||
@EnableFlags(Flags.FLAG_MODES_UI)
|
||||
public void updateScheduleRule_updatesConditionAndTriggerDescription() {
|
||||
ZenMode mode = new TestModeBuilder()
|
||||
.setPackage(SystemZenRules.PACKAGE_ANDROID)
|
||||
|
||||
@@ -213,11 +213,7 @@ public class ZenModeBackendTest {
|
||||
mBackend.saveConversationSenders(CONVERSATION_SENDERS_NONE);
|
||||
|
||||
ArgumentCaptor<Policy> captor = ArgumentCaptor.forClass(Policy.class);
|
||||
if (android.app.Flags.modesApi()) {
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true));
|
||||
} else {
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture());
|
||||
}
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true));
|
||||
|
||||
Policy expected = new Policy(
|
||||
PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS,
|
||||
@@ -241,11 +237,7 @@ public class ZenModeBackendTest {
|
||||
mBackend.saveConversationSenders(CONVERSATION_SENDERS_ANYONE);
|
||||
|
||||
ArgumentCaptor<Policy> captor = ArgumentCaptor.forClass(Policy.class);
|
||||
if (android.app.Flags.modesApi()) {
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true));
|
||||
} else {
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture());
|
||||
}
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true));
|
||||
|
||||
Policy expected = new Policy(PRIORITY_CATEGORY_CONVERSATIONS
|
||||
| PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS,
|
||||
@@ -270,11 +262,7 @@ public class ZenModeBackendTest {
|
||||
mBackend.saveSenders(PRIORITY_CATEGORY_CALLS, PRIORITY_SENDERS_ANY);
|
||||
|
||||
ArgumentCaptor<Policy> captor = ArgumentCaptor.forClass(Policy.class);
|
||||
if (android.app.Flags.modesApi()) {
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true));
|
||||
} else {
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture());
|
||||
}
|
||||
verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true));
|
||||
|
||||
Policy expected = new Policy(PRIORITY_CATEGORY_CONVERSATIONS
|
||||
| PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS,
|
||||
|
||||
@@ -107,7 +107,7 @@ public class ZenModeEventRuleSettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI})
|
||||
@EnableFlags(Flags.FLAG_MODES_UI)
|
||||
public void updateEventRule_updatesConditionAndTriggerDescription() {
|
||||
mFragment.setBackend(mBackend);
|
||||
mFragment.mId = "id";
|
||||
|
||||
@@ -107,7 +107,7 @@ public class ZenModeScheduleRuleSettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI})
|
||||
@EnableFlags(Flags.FLAG_MODES_UI)
|
||||
public void updateScheduleRule_updatesConditionAndTriggerDescription() {
|
||||
mFragment.setBackend(mBackend);
|
||||
mFragment.mId = "id";
|
||||
|
||||
@@ -117,11 +117,7 @@ public class ZenModeSliceBuilderTest {
|
||||
|
||||
ZenModeSliceBuilder.handleUriChange(mContext, intent);
|
||||
|
||||
if (android.app.Flags.modesApi()) {
|
||||
verify(mNm).setZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), any(), any(), eq(true));
|
||||
} else {
|
||||
verify(mNm).setZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), any(), any());
|
||||
}
|
||||
verify(mNm).setZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), any(), any(), eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,10 +127,6 @@ public class ZenModeSliceBuilderTest {
|
||||
|
||||
ZenModeSliceBuilder.handleUriChange(mContext, intent);
|
||||
|
||||
if (android.app.Flags.modesApi()) {
|
||||
verify(mNm).setZenMode(eq(ZEN_MODE_OFF), any(), any(), eq(true));
|
||||
} else {
|
||||
verify(mNm).setZenMode(eq(ZEN_MODE_OFF), any(), any());
|
||||
}
|
||||
verify(mNm).setZenMode(eq(ZEN_MODE_OFF), any(), any(), eq(true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.deviceinfo
|
||||
|
||||
import android.content.Context
|
||||
import android.os.UserManager
|
||||
import android.telephony.SubscriptionInfo
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyManager
|
||||
@@ -25,30 +26,39 @@ import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.dx.mockito.inline.extended.ExtendedMockito
|
||||
import com.android.settings.R
|
||||
import com.android.settings.core.BasePreferenceController
|
||||
import com.android.settings.network.SubscriptionUtil
|
||||
import com.android.settingslib.Utils
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.MockitoSession
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.stub
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.whenever
|
||||
import org.mockito.quality.Strictness
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PhoneNumberPreferenceControllerTest {
|
||||
private lateinit var mockSession: MockitoSession
|
||||
|
||||
private val mockUserManager = mock<UserManager>()
|
||||
private val mockTelephonyManager = mock<TelephonyManager>()
|
||||
private val mockSubscriptionManager = mock<SubscriptionManager>()
|
||||
|
||||
private val context: Context =
|
||||
spy(ApplicationProvider.getApplicationContext()) {
|
||||
on { getSystemService(SubscriptionManager::class.java) } doReturn
|
||||
mockSubscriptionManager
|
||||
|
||||
on { getSystemService(SubscriptionManager::class.java) } doReturn mockSubscriptionManager
|
||||
on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
|
||||
on { getSystemService(UserManager::class.java) } doReturn mockUserManager
|
||||
}
|
||||
|
||||
private val subscriptionInfo = mock<SubscriptionInfo>()
|
||||
@@ -61,6 +71,20 @@ class PhoneNumberPreferenceControllerTest {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
mockSession =
|
||||
ExtendedMockito.mockitoSession()
|
||||
.mockStatic(SubscriptionUtil::class.java)
|
||||
.mockStatic(Utils::class.java)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.startMocking()
|
||||
|
||||
// By default, available
|
||||
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
|
||||
whenever(Utils.isWifiOnly(context)).thenReturn(false)
|
||||
mockUserManager.stub {
|
||||
on { isAdminUser } doReturn true
|
||||
}
|
||||
|
||||
preference.setKey(controller.preferenceKey)
|
||||
preference.isVisible = true
|
||||
preferenceScreen.addPreference(preference)
|
||||
@@ -70,6 +94,11 @@ class PhoneNumberPreferenceControllerTest {
|
||||
doReturn(secondPreference).whenever(controller).createNewPreference(context)
|
||||
}
|
||||
|
||||
@After
|
||||
fun teardown() {
|
||||
mockSession.finishMocking()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun displayPreference_multiSim_shouldAddSecondPreference() {
|
||||
whenever(mockTelephonyManager.phoneCount).thenReturn(2)
|
||||
@@ -132,4 +161,37 @@ class PhoneNumberPreferenceControllerTest {
|
||||
|
||||
verify(preference).summary = context.getString(R.string.device_info_not_available)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_simHardwareVisible_userAdmin_notWifiOnly_displayed() {
|
||||
// Use defaults from setup()
|
||||
val availabilityStatus = controller.availabilityStatus
|
||||
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_notSimHardwareVisible_userAdmin_notWifiOnly_notDisplayed() {
|
||||
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
|
||||
|
||||
val availabilityStatus = controller.availabilityStatus
|
||||
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_simHardwareVisible_notUserAdmin_notWifiOnly_notDisplayed() {
|
||||
mockUserManager.stub {
|
||||
on { isAdminUser } doReturn false
|
||||
}
|
||||
|
||||
val availabilityStatus = controller.availabilityStatus
|
||||
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.DISABLED_FOR_USER)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_simHardwareVisible_userAdmin_wifiOnly_notDisplayed() {
|
||||
whenever(Utils.isWifiOnly(context)).thenReturn(true)
|
||||
|
||||
val availabilityStatus = controller.availabilityStatus
|
||||
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.network.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.os.UserManager
|
||||
import androidx.lifecycle.testing.TestLifecycleOwner
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceManager
|
||||
@@ -26,6 +27,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito
|
||||
import com.android.settings.R
|
||||
import com.android.settings.core.BasePreferenceController
|
||||
import com.android.settings.network.SubscriptionUtil
|
||||
import com.android.settingslib.Utils
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
@@ -37,6 +39,7 @@ import org.junit.runner.RunWith
|
||||
import org.mockito.MockitoSession
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.stub
|
||||
import org.mockito.kotlin.whenever
|
||||
import org.mockito.quality.Strictness
|
||||
@@ -45,9 +48,14 @@ import org.mockito.quality.Strictness
|
||||
class MobileNetworkPhoneNumberPreferenceControllerTest {
|
||||
private lateinit var mockSession: MockitoSession
|
||||
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
private val mockUserManager = mock<UserManager>()
|
||||
private val mockSubscriptionRepository = mock<SubscriptionRepository>()
|
||||
|
||||
private val context: Context =
|
||||
spy(ApplicationProvider.getApplicationContext()) {
|
||||
on { getSystemService(UserManager::class.java) } doReturn mockUserManager
|
||||
}
|
||||
|
||||
private val controller =
|
||||
MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY, mockSubscriptionRepository)
|
||||
private val preference = Preference(context).apply { key = TEST_KEY }
|
||||
@@ -58,9 +66,17 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
|
||||
mockSession =
|
||||
ExtendedMockito.mockitoSession()
|
||||
.mockStatic(SubscriptionUtil::class.java)
|
||||
.mockStatic(Utils::class.java)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.startMocking()
|
||||
|
||||
// By default, available
|
||||
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
|
||||
whenever(Utils.isWifiOnly(context)).thenReturn(false)
|
||||
mockUserManager.stub {
|
||||
on { isAdminUser } doReturn true
|
||||
}
|
||||
|
||||
preferenceScreen.addPreference(preference)
|
||||
controller.init(SUB_ID)
|
||||
controller.displayPreference(preferenceScreen)
|
||||
@@ -73,7 +89,6 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
fun onViewCreated_cannotGetPhoneNumber_displayUnknown() = runBlocking {
|
||||
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
|
||||
mockSubscriptionRepository.stub {
|
||||
on { phoneNumberFlow(SUB_ID) } doReturn flowOf(null)
|
||||
}
|
||||
@@ -86,7 +101,6 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
fun onViewCreated_canGetPhoneNumber_displayPhoneNumber() = runBlocking {
|
||||
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
|
||||
mockSubscriptionRepository.stub {
|
||||
on { phoneNumberFlow(SUB_ID) } doReturn flowOf(PHONE_NUMBER)
|
||||
}
|
||||
@@ -98,11 +112,35 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_notSimHardwareVisible() {
|
||||
fun getAvailabilityStatus_simHardwareVisible_userAdmin_notWifiOnly_displayed() {
|
||||
// Use defaults from setup()
|
||||
val availabilityStatus = controller.availabilityStatus
|
||||
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_notSimHardwareVisible_userAdmin_notWifiOnly_notDisplayed() {
|
||||
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
|
||||
|
||||
val availabilityStatus = controller.availabilityStatus
|
||||
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_simHardwareVisible_notUserAdmin_notWifiOnly_notDisplayed() {
|
||||
mockUserManager.stub {
|
||||
on { isAdminUser } doReturn false
|
||||
}
|
||||
|
||||
val availabilityStatus = controller.availabilityStatus
|
||||
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.DISABLED_FOR_USER)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_simHardwareVisible_userAdmin_wifiOnly_notDisplayed() {
|
||||
whenever(Utils.isWifiOnly(context)).thenReturn(true)
|
||||
|
||||
val availabilityStatus = controller.availabilityStatus
|
||||
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,14 +28,12 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.Flags;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.annotations.RequiresFlagsDisabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
@@ -50,7 +48,6 @@ import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -188,7 +185,6 @@ public class ApprovalPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_MODES_API)
|
||||
public void disable() {
|
||||
when(mNm.isNotificationPolicyAccessGrantedForPackage(anyString())).thenReturn(false);
|
||||
mController.disable(mCn);
|
||||
|
||||
@@ -22,6 +22,8 @@ import static com.android.settings.connecteddevice.display.ExternalDisplayPrefer
|
||||
import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_SETTINGS_RESOURCE;
|
||||
import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE;
|
||||
import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.PREVIOUSLY_SHOWN_LIST_KEY;
|
||||
import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.displayListDisplayCategoryKey;
|
||||
import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.resolutionRotationPreferenceKey;
|
||||
import static com.android.settings.flags.Flags.FLAG_DISPLAY_SIZE_CONNECTED_DISPLAY_SETTING;
|
||||
import static com.android.settings.flags.Flags.FLAG_DISPLAY_TOPOLOGY_PANE_IN_DISPLAY_LIST;
|
||||
import static com.android.settingslib.widget.FooterPreference.KEY_FOOTER;
|
||||
@@ -79,6 +81,19 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
|
||||
assertThat(mPreferenceIdFromResource).isEqualTo(EXTERNAL_DISPLAY_SETTINGS_RESOURCE);
|
||||
}
|
||||
|
||||
private void assertDisplayList(boolean present, int displayId) {
|
||||
// In display list fragment, there is a combined resolution/rotation preference key.
|
||||
var category = mPreferenceScreen.findPreference(displayListDisplayCategoryKey(displayId));
|
||||
var pref = mPreferenceScreen.findPreference(resolutionRotationPreferenceKey(displayId));
|
||||
if (present) {
|
||||
assertThat(category).isNotNull();
|
||||
assertThat(pref).isNotNull();
|
||||
} else {
|
||||
assertThat(category).isNull();
|
||||
assertThat(pref).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testShowDisplayList() {
|
||||
@@ -89,19 +104,26 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
|
||||
fragment.onSaveInstanceStateCallback(outState);
|
||||
assertThat(outState.getBoolean(PREVIOUSLY_SHOWN_LIST_KEY)).isFalse();
|
||||
assertThat(mHandler.getPendingMessages().size()).isEqualTo(1);
|
||||
PreferenceCategory pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key);
|
||||
assertThat(pref).isNull();
|
||||
|
||||
// Combined resolution/refresh rate are not available in displays list because the pane is
|
||||
// disabled (v1 UI).
|
||||
assertDisplayList(false, EXTERNAL_DISPLAY_ID);
|
||||
assertDisplayList(false, OVERLAY_DISPLAY_ID);
|
||||
// Individual resolution preference is not available in displays list.
|
||||
assertThat(mPreferenceScreen.<Preference>findPreference(
|
||||
PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key))
|
||||
.isNull();
|
||||
|
||||
verify(mMockedInjector, never()).getAllDisplays();
|
||||
mHandler.flush();
|
||||
assertThat(mHandler.getPendingMessages().size()).isEqualTo(0);
|
||||
verify(mMockedInjector).getAllDisplays();
|
||||
pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key);
|
||||
assertThat(pref).isNotNull();
|
||||
assertThat(pref.getPreferenceCount()).isEqualTo(2);
|
||||
assertDisplayList(true, EXTERNAL_DISPLAY_ID);
|
||||
assertDisplayList(true, OVERLAY_DISPLAY_ID);
|
||||
fragment.onSaveInstanceStateCallback(outState);
|
||||
assertThat(outState.getBoolean(PREVIOUSLY_SHOWN_LIST_KEY)).isTrue();
|
||||
|
||||
pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAY_TOPOLOGY.key);
|
||||
Preference pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAY_TOPOLOGY.key);
|
||||
assertThat(pref).isNull();
|
||||
|
||||
pref = mPreferenceScreen.findPreference(PrefBasics.BUILTIN_DISPLAY_LIST.key);
|
||||
@@ -122,8 +144,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
|
||||
pref = mPreferenceScreen.findPreference(PrefBasics.MIRROR.key);
|
||||
assertThat(pref).isNotNull();
|
||||
|
||||
pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key);
|
||||
assertThat(pref).isNull();
|
||||
assertDisplayList(false, mDisplays[1].getDisplayId());
|
||||
|
||||
PreferenceCategory listPref =
|
||||
mPreferenceScreen.findPreference(PrefBasics.BUILTIN_DISPLAY_LIST.key);
|
||||
@@ -148,11 +169,10 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
|
||||
pref = mPreferenceScreen.findPreference(PrefBasics.MIRROR.key);
|
||||
assertThat(pref).isNull();
|
||||
|
||||
PreferenceCategory listPref =
|
||||
mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key);
|
||||
assertThat(listPref).isNull();
|
||||
assertDisplayList(false, EXTERNAL_DISPLAY_ID);
|
||||
assertDisplayList(false, OVERLAY_DISPLAY_ID);
|
||||
|
||||
listPref = mPreferenceScreen.findPreference(PrefBasics.BUILTIN_DISPLAY_LIST.key);
|
||||
var listPref = mPreferenceScreen.findPreference(PrefBasics.BUILTIN_DISPLAY_LIST.key);
|
||||
assertThat(listPref).isNull();
|
||||
}
|
||||
|
||||
@@ -161,19 +181,23 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
|
||||
public void testLaunchDisplaySettingFromList() {
|
||||
initFragment();
|
||||
mHandler.flush();
|
||||
PreferenceCategory pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key);
|
||||
assertThat(pref).isNotNull();
|
||||
var display1Category = (PreferenceCategory) pref.getPreference(0);
|
||||
assertDisplayList(true, EXTERNAL_DISPLAY_ID);
|
||||
assertDisplayList(true, OVERLAY_DISPLAY_ID);
|
||||
PreferenceCategory display1Category = mPreferenceScreen.findPreference(
|
||||
displayListDisplayCategoryKey(EXTERNAL_DISPLAY_ID));
|
||||
var display1Pref = (DisplayPreference) display1Category.getPreference(0);
|
||||
var display2Category = (PreferenceCategory) pref.getPreference(1);
|
||||
PreferenceCategory display2Category = mPreferenceScreen.findPreference(
|
||||
displayListDisplayCategoryKey(OVERLAY_DISPLAY_ID));
|
||||
var display2Pref = (DisplayPreference) display2Category.getPreference(0);
|
||||
assertThat(display1Pref.getKey()).isEqualTo("display_id_" + 1);
|
||||
assertThat(display1Pref.getKey()).isEqualTo(
|
||||
resolutionRotationPreferenceKey(EXTERNAL_DISPLAY_ID));
|
||||
assertThat("" + display1Category.getTitle()).isEqualTo("HDMI");
|
||||
assertThat("" + display1Pref.getSummary()).isEqualTo("1920 x 1080");
|
||||
display1Pref.onPreferenceClick(display1Pref);
|
||||
assertThat(mDisplayIdArg).isEqualTo(1);
|
||||
verify(mMockedMetricsLogger).writePreferenceClickMetric(display1Pref);
|
||||
assertThat(display2Pref.getKey()).isEqualTo("display_id_" + 2);
|
||||
assertThat(display2Pref.getKey()).isEqualTo(
|
||||
resolutionRotationPreferenceKey(OVERLAY_DISPLAY_ID));
|
||||
assertThat("" + display2Category.getTitle()).isEqualTo("Overlay #1");
|
||||
assertThat("" + display2Pref.getSummary()).isEqualTo("1240 x 780");
|
||||
display2Pref.onPreferenceClick(display2Pref);
|
||||
@@ -190,9 +214,12 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
|
||||
// Only one display available
|
||||
doReturn(new Display[] {mDisplays[1]}).when(mMockedInjector).getAllDisplays();
|
||||
mHandler.flush();
|
||||
PreferenceCategory pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key);
|
||||
assertThat(pref).isNotNull();
|
||||
assertThat(pref.getPreferenceCount()).isEqualTo(1);
|
||||
int attachedId = mDisplays[1].getDisplayId();
|
||||
assertDisplayList(true, attachedId);
|
||||
assertThat(mPreferenceScreen.<Preference>findPreference(
|
||||
resolutionRotationPreferenceKey(attachedId)))
|
||||
.isNotNull();
|
||||
assertDisplayList(false, mDisplays[2].getDisplayId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -205,8 +232,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
|
||||
// Init
|
||||
initFragment();
|
||||
mHandler.flush();
|
||||
PreferenceCategory list = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key);
|
||||
assertThat(list).isNull();
|
||||
assertDisplayList(false, mDisplays[1].getDisplayId());
|
||||
var pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key);
|
||||
assertThat(pref).isNotNull();
|
||||
pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
|
||||
@@ -227,8 +253,8 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
|
||||
// Init
|
||||
initFragment();
|
||||
mHandler.flush();
|
||||
PreferenceCategory list = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key);
|
||||
assertThat(list).isNull();
|
||||
assertDisplayList(false, mDisplays[1].getDisplayId());
|
||||
assertDisplayList(false, mDisplays[2].getDisplayId());
|
||||
var pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key);
|
||||
assertThat(pref).isNotNull();
|
||||
pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
|
||||
|
||||
@@ -49,6 +49,9 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
public class ExternalDisplayTestBase {
|
||||
static final int EXTERNAL_DISPLAY_ID = 1;
|
||||
static final int OVERLAY_DISPLAY_ID = 2;
|
||||
|
||||
@Mock
|
||||
ExternalDisplaySettingsConfiguration.Injector mMockedInjector;
|
||||
@Mock
|
||||
@@ -115,7 +118,7 @@ public class ExternalDisplayTestBase {
|
||||
}
|
||||
|
||||
Display createExternalDisplay() throws RemoteException {
|
||||
int displayId = 1;
|
||||
int displayId = EXTERNAL_DISPLAY_ID;
|
||||
var displayInfo = new DisplayInfo();
|
||||
doReturn(displayInfo).when(mMockedIDisplayManager).getDisplayInfo(displayId);
|
||||
displayInfo.displayId = displayId;
|
||||
@@ -134,7 +137,7 @@ public class ExternalDisplayTestBase {
|
||||
}
|
||||
|
||||
Display createOverlayDisplay() throws RemoteException {
|
||||
int displayId = 2;
|
||||
int displayId = OVERLAY_DISPLAY_ID;
|
||||
var displayInfo = new DisplayInfo();
|
||||
doReturn(displayInfo).when(mMockedIDisplayManager).getDisplayInfo(displayId);
|
||||
displayInfo.displayId = displayId;
|
||||
|
||||
@@ -35,6 +35,7 @@ import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.internal.app.LocaleStore;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
@@ -82,11 +83,9 @@ public class LocaleDialogFragmentTest {
|
||||
LocaleDialogFragment.LocaleDialogController.DialogContent dialogContent =
|
||||
controller.getDialogContent();
|
||||
|
||||
assertEquals(ResourcesUtils.getResourcesString(
|
||||
mContext, "button_label_confirmation_of_system_locale_change"),
|
||||
assertEquals(R.string.button_label_confirmation_of_system_locale_change,
|
||||
dialogContent.mPositiveButton);
|
||||
assertEquals(ResourcesUtils.getResourcesString(mContext, "cancel"),
|
||||
dialogContent.mNegativeButton);
|
||||
assertEquals(R.string.cancel, dialogContent.mNegativeButton);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,9 +98,8 @@ public class LocaleDialogFragmentTest {
|
||||
LocaleDialogFragment.LocaleDialogController.DialogContent dialogContent =
|
||||
controller.getDialogContent();
|
||||
|
||||
assertEquals(ResourcesUtils.getResourcesString(mContext, "okay"),
|
||||
dialogContent.mPositiveButton);
|
||||
assertTrue(dialogContent.mNegativeButton.isEmpty());
|
||||
assertEquals(R.string.okay, dialogContent.mPositiveButton);
|
||||
assertTrue(dialogContent.mNegativeButton == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user