Merge "Support vendor modes in color mode preference" into sc-dev
diff --git a/res/drawable/baseline_near_me.xml b/res/drawable/baseline_near_me.xml
deleted file mode 100644
index 343f970..0000000
--- a/res/drawable/baseline_near_me.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M21,3L3,10.53v0.98l6.84,2.65L12.48,21h0.98L21,3z"/>
-</vector>
diff --git a/res/layout/apps_filter_spinner.xml b/res/layout/apps_filter_spinner.xml
index 13d8078..1de5705 100644
--- a/res/layout/apps_filter_spinner.xml
+++ b/res/layout/apps_filter_spinner.xml
@@ -36,7 +36,7 @@
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginTop="12dp"
- android:layout_toRightOf="@id/filter_spinner"
+ android:layout_toEndOf="@id/filter_spinner"
android:contentDescription="@string/configure"
android:scaleType="center"
android:src="@drawable/ic_apps_filter_settings_24dp"
diff --git a/res/layout/settings_collapsing_base_layout.xml b/res/layout/settings_collapsing_base_layout.xml
deleted file mode 100644
index 97d249c..0000000
--- a/res/layout/settings_collapsing_base_layout.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<androidx.coordinatorlayout.widget.CoordinatorLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/content_parent"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fitsSystemWindows="true">
-
- <com.google.android.material.appbar.AppBarLayout
- android:id="@+id/app_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:fitsSystemWindows="true"
- android:outlineAmbientShadowColor="@android:color/transparent"
- android:outlineSpotShadowColor="@android:color/transparent"
- android:background="@android:color/transparent"
- android:theme="@style/Theme.CollapsingToolbar.Settings">
-
- <com.google.android.material.appbar.CollapsingToolbarLayout
- android:id="@+id/collapsing_toolbar"
- android:layout_width="match_parent"
- android:layout_height="@dimen/toolbar_one_line_height"
- android:clipToPadding="false"
- app:contentScrim="@color/color_surface_header"
- app:maxLines="3"
- app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
- app:scrimAnimationDuration="50"
- app:scrimVisibleHeightTrigger="@dimen/scrim_visible_height_trigger"
- app:statusBarScrim="@empty"
- app:titleCollapseMode="fade"
- app:collapsedTitleTextAppearance="@style/ToolbarText.Collapsed"
- app:expandedTitleTextAppearance="@style/ToolbarText.Expanded"
- app:expandedTitleMarginStart="@dimen/expanded_title_margin_start"
- app:expandedTitleMarginEnd="@dimen/expanded_title_margin_end"
- app:toolbarId="@id/action_bar">
-
- <Toolbar
- android:id="@+id/action_bar"
- android:layout_width="match_parent"
- android:layout_height="?attr/actionBarSize"
- android:theme="?android:attr/actionBarTheme"
- app:layout_collapseMode="pin"/>
-
- </com.google.android.material.appbar.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
-
- <FrameLayout
- android:id="@+id/content_frame"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 6047092..0aaf930 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -443,15 +443,7 @@
<!-- Battery usage chart view component -->
<dimen name="chartview_divider_width">1dp</dimen>
<dimen name="chartview_divider_height">4dp</dimen>
- <dimen name="chartview_trapezoid_radius">2dp</dimen>
+ <dimen name="chartview_trapezoid_radius">3dp</dimen>
<dimen name="chartview_trapezoid_margin_start">1dp</dimen>
<dimen name="chartview_trapezoid_margin_bottom">2dp</dimen>
-
- <!-- Collapsing toolbar layout dimensions -->
- <dimen name="toolbar_one_line_height">226dp</dimen>
- <dimen name="toolbar_two_lines_height">270dp</dimen>
- <dimen name="toolbar_three_lines_height">314dp</dimen>
- <dimen name="scrim_visible_height_trigger">174dp</dimen>
- <dimen name="expanded_title_margin_start">24dp</dimen>
- <dimen name="expanded_title_margin_end">24dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6134100..8586700 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -739,6 +739,8 @@
<string name="security_dashboard_summary">Screen lock, fingerprint</string>
<!-- Summary for Security settings when fingerprint is not supported [CHAR LIMIT=NONE]-->
<string name="security_dashboard_summary_no_fingerprint">Screen lock</string>
+ <!-- Summary for Security settings when biometric unlock is supported [CHAR LIMIT=NONE] -->
+ <string name="security_dashboard_summary_biometric">Screen lock, biometric unlock, app security</string>
<!-- Face enrollment and settings --><skip />
<!-- Message shown in summary field when face unlock is set up. [CHAR LIMIT=40] -->
@@ -4121,7 +4123,7 @@
<!-- Description text for Bluetooth always scanning -->
<string name="location_scanning_bluetooth_always_scanning_description">Allow apps and services to scan for nearby devices at any time, even when Bluetooth is off. This can be used, for example, to improve location-based features and services.</string>
<!-- [CHAR LIMIT=60] Location Services preference title -->
- <string name="location_services_preference_title">Manage location services</string>
+ <string name="location_services_preference_title">Location services</string>
<!-- [CHAR LIMIT=60] Location Services screen, screen title -->
<string name="location_services_screen_title">Location Services</string>
<!-- [CHAR LIMIT=50] Location settings screen, sub category for location services for managed profile -->
@@ -5691,15 +5693,54 @@
<!-- Title for the prompt shown as a placeholder if no accessibility services are installed. [CHAR LIMIT=50] -->
<string name="accessibility_no_services_installed">No services installed</string>
- <!-- Title for the acccessibility shortcut's summary if no service is selected for use with the shortcut. [CHAR LIMIT=50] -->
+ <!-- Title for the accessibility shortcut's summary if no service is selected for use with the shortcut. [CHAR LIMIT=50] -->
<string name="accessibility_no_service_selected">No service selected</string>
<!-- Default description for an accessibility service if the latter doesn't provide one. [CHAR LIMIT=NONE] -->
<string name="accessibility_service_default_description">No description provided.</string>
- <!-- Accessibility settings: button for lauching settings for an accessibility service -->
+ <!-- Accessibility settings: button for launching settings for an accessibility service -->
<string name="settings_button">Settings</string>
+ <!-- List of synonyms used in the settings search bar to find the “Extra Dim” setting, which dims your screen. Title name is located at strings/reduce_bright_colors_preference_title. [CHAR LIMIT=NONE] -->
+ <string name="keywords_reduce_bright_colors">light sensitivity, photophobia, dark theme, migraine, headache, reading mode, night mode, reduce brightness, white point</string>
+ <!-- List of synonyms used in the settings search bar to find the “Accessibility”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_accessibility">Ease of use, ease of access, assistance, assistive</string>
+ <!-- List of synonyms used in the settings search bar to find the “Magnification”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_magnification">Window Magnifier, Zoom, Magnification, Low vision, Enlarge, make bigger</string>
+ <!-- List of synonyms used in the settings search bar to find the “TalkBack”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_talkback">Screen reader, Voice Over, VoiceOver, Voice Assistance, Blind, Low Vision, TTS, text to speech, spoken feedback</string>
+ <!-- List of synonyms used in the settings search bar to find the “Live Caption”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_live_caption">Captions, closed captions, CC, Live Transcribe, hard of hearing, hearing loss, CART, speech to text, subtitle</string>
+ <!-- List of synonyms used in the settings search bar to find the “Live Transcribe”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_live_transcribe">Captions, closed captions, CC, Live Caption, hard of hearing, hearing loss, CART, speech to text, subtitle</string>
+ <!-- List of synonyms used in the settings search bar to find the “Sound Notifications”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_sound_notifications">Notifications, hard of hearing, hearing loss, notify</string>
+ <!-- List of synonyms used in the settings search bar to find the “Sound Amplifier”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_sound_amplifier">PSAP, amplify, sound amplification, hard of hearing, hearing loss, amplification</string>
+ <!-- List of synonyms used in the settings search bar to find the “Display size”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_display_size">screen size, large screen</string>
+ <!-- List of synonyms used in the settings search bar to find the “Bold text”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_bold_text">High contrast, low vision, bold font, bold face</string>
+ <!-- List of synonyms used in the settings search bar to find the “Select to Speak”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_select_to_speak">Hear text, read aloud, speak screen, screen reader</string>
+ <!-- List of synonyms used in the settings search bar to find the “Color correction”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_color_correction">adjust color </string>
+ <!-- List of synonyms used in the settings search bar to find the “Color inversion”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_color_inversion">turn screen dark, turn screen light</string>
+ <!-- List of synonyms used in the settings search bar to find the “Accessibility Menu”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_accessibility_menu">motor, quick menu, assistive menu, touch, dexterity</string>
+ <!-- List of synonyms used in the settings search bar to find the “Switch Access”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_switch_access">motor, switch, hand, AT, assistive technology, paralysis, ALS, scanning, step scanning</string>
+ <!-- List of synonyms used in the settings search bar to find the “Autoclick(dwell timing)”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_auto_click">motor, mouse</string>
+ <!-- List of synonyms used in the settings search bar to find the “Hearing aids”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_hearing_aids">hard of hearing, hearing loss</string>
+ <!-- List of synonyms used in the settings search bar to find the “Real-time text (RTT)”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_rtt">hard of hearing, hearing loss, captions, Teletype, tty</string>
+ <!-- List of synonyms used in the settings search bar to find the “Voice Access”. [CHAR LIMIT=NONE] -->
+ <string name="keywords_voice_access">voice, voice control, motor, hand, mic, microphone, dictation, talk, control</string>
+
<!-- Printing settings -->
<skip />
@@ -6255,8 +6296,39 @@
<string name ="battery_detail_info_title">Since full charge</string>
<!-- Title for the battery management group [CHAR LIMIT=40] -->
<string name ="battery_detail_manage_title">Manage battery usage</string>
+
<!-- Description for battery total and background usage time for an app, i.e. 1 hr 15 min total • 39 min background for past 24 hr. Note: ^1 and ^2 should be used in all translations [CHAR LIMIT=120] -->
<string name="battery_total_and_background_usage"><xliff:g id="time" example="1 hr 15 min">^1</xliff:g> total • <xliff:g id="time" example="39 min">^2</xliff:g> background for past 24 hr</string>
+ <!-- Description for battery total and background usage time in a time period for an app, i.e. 1 hr 15 min total • 39 min background for 12 am-2 am. Note: ^1, ^2 and ^3 should be used in all translations [CHAR LIMIT=120] -->
+ <string name="battery_total_and_background_usage_with_period"><xliff:g id="time" example="1 hr 15 min">^1</xliff:g> total • <xliff:g id="time" example="39 min">^2</xliff:g> background for <xliff:g id="time_period" example="12 am-2 am">^3</xliff:g></string>
+
+ <!-- Description for battery total usage time is less than a minute for an app [CHAR LIMIT=120] -->
+ <string name="battery_total_usage_less_minute">Total less than a minute for past 24 hr</string>
+ <!-- Description for battery total usage time is less than a minute in a time period for an app, i.e. Total less than a minute for 12 am-2 am. Note: ^1 should be used in all translations[CHAR LIMIT=120] -->
+ <string name="battery_total_usage_less_minute_with_period">Total less than a minute for <xliff:g id="time_period" example="12 am-2 am">^1</xliff:g></string>
+
+ <!-- Description for battery background usage time is less than a minute for an app [CHAR LIMIT=120] -->
+ <string name="battery_background_usage_less_minute">Background less than a minute for past 24 hr</string>
+ <!-- Description for battery background usage time is less than a minute in a time period for an app, i.e. Background less than a minute for 12 am-2 am. Note: ^1 should be used in all translations[CHAR LIMIT=120] -->
+ <string name="battery_background_usage_less_minute_with_period">Background less than a minute for <xliff:g id="time_period" example="12 am-2 am">^1</xliff:g></string>
+
+ <!-- Description for battery total usage time for an app, i.e. 1 hr 15 min total for past 24 hr. Note: ^1 should be used in all translations [CHAR LIMIT=120] -->
+ <string name="battery_total_usage"><xliff:g id="time" example="1 hr 15 min">^1</xliff:g> total for past 24 hr</string>
+ <!-- Description for battery total usage time in a time period for an app, i.e. 1 hr 15 min total for 12 am-2 am. Note: ^1 and ^2 should be used in all translations [CHAR LIMIT=120] -->
+ <string name="battery_total_usage_with_period"><xliff:g id="time" example="1 hr 15 min">^1</xliff:g> total for <xliff:g id="time_period" example="12 am-2 am">^2</xliff:g></string>
+
+ <!-- Description for battery background usage time for an app, i.e. 1 hr 15 min background for past 24 hr. Note: ^1 should be used in all translations [CHAR LIMIT=120] -->
+ <string name="battery_background_usage"><xliff:g id="time" example="1 hr 15 min">^1</xliff:g> background for past 24 hr</string>
+ <!-- Description for battery background usage time in a time period for an app, i.e. 1 hr 15 min background for 12 am-2 am. Note: ^1 and ^2 should be used in all translations [CHAR LIMIT=120] -->
+ <string name="battery_background_usage_with_period"><xliff:g id="time" example="1 hr 15 min">^1</xliff:g> background for <xliff:g id="time_period" example="12 am-2 am">^2</xliff:g></string>
+
+ <!-- Description for battery total usage with background usage time less than a minute for an app, i.e. 1 hr 15 min total • background less than a minute for past 24 hr. Note: ^1 should be used in all translations [CHAR LIMIT=120] -->
+ <string name="battery_total_usage_and_background_less_minute_usage"><xliff:g id="time" example="1 hr 15 min">^1</xliff:g> total • background less than a minute for past 24 hr</string>
+ <!-- Description for battery total usage with background usage time less than a minute in a time period for an app, i.e. 1 hr 15 min total • background less than a minute for 12 am-2 am. Note: ^1 and ^2 should be used in all translations [CHAR LIMIT=120] -->
+ <string name="battery_total_usage_and_background_less_minute_usage_with_period"><xliff:g id="time" example="1 hr 15 min">^1</xliff:g> total • background less than a minute for <xliff:g id="time_period" example="12 am-2 am">^2</xliff:g></string>
+
+ <!-- Description for no any battery usage for past 24 hr [CHAR LIMIT=120] -->
+ <string name="battery_not_usage">No usage for past 24 hr</string>
<!-- Graph subtext displayed to user when enhanced battery estimate is being used [CHAR LIMIT=120] -->
<string name="advanced_battery_graph_subtext">Battery left estimate is based on your device usage</string>
@@ -7950,7 +8022,7 @@
<string name="keywords_wifi_calling">wifi, wi-fi, call, calling</string>
<string name="keywords_display">screen, touchscreen</string>
<string name="keywords_display_brightness_level">dim screen, touchscreen, battery, bright</string>
- <string name="keywords_display_night_display">dim screen, night, tint, night shift, brightness, screen color, colour, color</string>
+ <string name="keywords_display_night_display">dim screen, night, tint, night shift, brightness, screen color, colour, color, light sensitivity, photophobia, make darker, darken, dark mode, migraine</string>
<string name="keywords_display_wallpaper">background, personalize, customize display</string>
<string name="keywords_display_font_size">text size</string>
<!-- Search keyword for "Cast" settings [CHAR_LIMIT=NONE]-->
@@ -8076,10 +8148,7 @@
<string name="keywords_add_language">add language, add a language</string>
<!-- List of synonyms for the font size, used to match in settings search [CHAR LIMIT=NONE] -->
- <string name="keywords_font_size">text size</string>
-
- <!-- List of synonyms used in the settings search bar to find the “Extra Dim” setting, which dims your screen. Title name is located at strings/reduce_bright_colors_preference_title. [CHAR LIMIT=NONE] -->
- <string name="keywords_reduce_bright_colors">light sensitivity, photophobia, dark theme, migraine, headache, reading mode, night mode, reduce brightness, white point</string>
+ <string name="keywords_font_size">text size, large print, large font, large text, low vision, make text bigger, font enlarger, font enlargement</string>
<!-- Option title for the default sound, context based on screen -->
<string name="default_sound">Default sound</string>
@@ -13187,4 +13256,13 @@
<!-- Label for button to not allow grant the permission for remote devices. [CHAR_LIMIT=50] -->
<string name="request_manage_bluetooth_permission_dont_allow">Don\u2019t allow</string>
+
+ <!-- Title for UWB preference [CHAR_LIMIT=60] -->
+ <string name="uwb_settings_title">Ultra-WideBand (UWB)</string>
+
+ <!-- Summary for UWB preference. [CHAR_LIMIT=NONE]-->
+ <string name="uwb_settings_summary">Helps identify the relative position of nearby devices that have UWB</string>
+
+ <!-- Summary for UWB preference when airplane mode is disabled. [CHAR_LIMIT=NONE]-->
+ <string name="uwb_settings_summary_airplane_mode">Turn off Airplane mode to use UWB. </string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e91ddcb..b27cc5d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -787,7 +787,7 @@
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
</style>
- <style name="HomepageTitleText" parent="ToolbarText.Expanded">
+ <style name="HomepageTitleText" parent="CollapsingToolbarTitle.Expanded">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginBottom">@dimen/homepage_title_margin_bottom</item>
@@ -879,8 +879,4 @@
<item name="android:textSize">16sp</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
-
- <style name="ToolbarText.Collapsed" parent="CollapsingToolbarTitle.Collapsed"/>
- <style name="ToolbarText.Expanded" parent="CollapsingToolbarTitle"/>
- <style name="ToolbarText.MoreThanTwoLines" parent="CollapsingToolbarTitle.MoreThanTwoLines"/>
</resources>
diff --git a/res/values/styles_preference.xml b/res/values/styles_preference.xml
index c162fc4..5ad553a 100644
--- a/res/values/styles_preference.xml
+++ b/res/values/styles_preference.xml
@@ -30,7 +30,6 @@
<style name="PreferenceTheme.SetupWizard" parent="@style/SettingsPreferenceTheme">
<item name="preferenceFragmentCompatStyle">@style/SetupWizardPreferenceFragmentStyle</item>
- <item name="preferenceStyle">@style/Preference.Material</item>
</style>
<style name="ApnPreference" parent="@style/Preference.Material">
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 02f94d2..0bd7c5b 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -272,5 +272,7 @@
<style name="Theme.NotificationHistory" parent="@android:style/Theme.DeviceDefault.DayNight">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
+ <item name="android:navigationBarColor">@android:color/transparent</item>
+ <item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml
index a801ae1..edf8cb9 100644
--- a/res/xml/app_notification_settings.xml
+++ b/res/xml/app_notification_settings.xml
@@ -26,7 +26,7 @@
<com.android.settings.widget.SettingsMainSwitchPreference
android:key="block" />
- <com.android.settings.notification.app.NotificationFooterPreference
+ <com.android.settingslib.widget.FooterPreference
android:key="block_desc" />
@@ -96,11 +96,11 @@
</PreferenceCategory>
- <com.android.settings.notification.app.NotificationFooterPreference
+ <com.android.settingslib.widget.FooterPreference
android:key="desc"
android:order="5000" />
- <com.android.settings.notification.app.NotificationFooterPreference
+ <com.android.settingslib.widget.FooterPreference
android:key="deleted"
android:order="8000" />
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index 95f7944..97dcc26 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -116,11 +116,11 @@
android:title="@string/app_settings_link"
settings:allowDividerAbove="true"/>
- <com.android.settings.notification.app.NotificationFooterPreference
+ <com.android.settingslib.widget.FooterPreference
android:key="desc"
android:order="100"/>
- <com.android.settings.notification.app.NotificationFooterPreference
+ <com.android.settingslib.widget.FooterPreference
android:key="block_desc"
android:order="110"
settings:allowDividerAbove="false"/>
diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml
index 3ff7d99..85e4a76 100644
--- a/res/xml/connected_devices_advanced.xml
+++ b/res/xml/connected_devices_advanced.xml
@@ -65,6 +65,13 @@
android:icon="@drawable/ic_folder_vd_theme_24"
android:title="@string/bluetooth_show_files_received_via_bluetooth"/>
+ <SwitchPreference
+ android:key="uwb_settings"
+ android:title="@string/uwb_settings_title"
+ android:order="100"
+ android:summary="@string/summary_placeholder"
+ settings:controller="com.android.settings.uwb.UwbPreferenceController"/>
+
<PreferenceCategory
android:key="dashboard_tile_placeholder"
android:order="-8"/>
diff --git a/res/xml/conversation_notification_settings.xml b/res/xml/conversation_notification_settings.xml
index ea555c2..7e475be 100644
--- a/res/xml/conversation_notification_settings.xml
+++ b/res/xml/conversation_notification_settings.xml
@@ -58,7 +58,7 @@
android:summary="@string/demote_conversation_summary"
settings:allowDividerAbove="true"/>
- <com.android.settings.notification.app.NotificationFooterPreference
+ <com.android.settingslib.widget.FooterPreference
android:key="block_desc"
settings:allowDividerAbove="false"/>
diff --git a/res/xml/date_time_prefs.xml b/res/xml/date_time_prefs.xml
index 6fc0b25..47056df 100644
--- a/res/xml/date_time_prefs.xml
+++ b/res/xml/date_time_prefs.xml
@@ -53,11 +53,10 @@
settings:keywords="@string/keywords_time_zone"/>
<!-- This preference gets removed if location-based time zone detection is not supported -->
- <com.android.settingslib.RestrictedSwitchPreference
+ <SwitchPreference
android:key="location_time_zone_detection"
android:title="@string/location_time_zone_detection_toggle_title"
settings:controller="com.android.settings.datetime.LocationTimeZoneDetectionPreferenceController"
- settings:userRestriction="no_config_date_time"
/>
<PreferenceCategory
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index cae128b..a950b3a 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -27,14 +27,6 @@
settings:controller=
"com.android.settings.location.RecentLocationAccessPreferenceController"/>
- <Preference
- android:key="recent_location_access_see_all_button"
- android:title="@string/location_recent_location_access_see_all"
- android:icon="@drawable/ic_chevron_right_24dp"
- android:fragment="com.android.settings.location.RecentLocationAccessSeeAllFragment"
- settings:controller="com.android.settings.location.RecentLocationAccessSeeAllButtonPreferenceController"
- settings:searchable="false"/>
-
<PreferenceCategory
android:key="location_advanced_settings"
android:layout="@layout/preference_category_no_label"
@@ -65,7 +57,7 @@
<Preference
android:fragment="com.android.settings.location.LocationServices"
android:key="location_services"
- android:icon="@drawable/baseline_near_me"
+ android:icon="@drawable/ic_chevron_right_24dp"
android:title="@string/location_services_preference_title"
settings:controller="com.android.settings.location.LocationServicesPreferenceController"/>
diff --git a/res/xml/location_settings_personal.xml b/res/xml/location_settings_personal.xml
index 726a96c..a798899 100644
--- a/res/xml/location_settings_personal.xml
+++ b/res/xml/location_settings_personal.xml
@@ -28,14 +28,6 @@
settings:controller=
"com.android.settings.location.RecentLocationAccessPreferenceController"/>
- <Preference
- android:key="recent_location_access_see_all_button"
- android:title="@string/location_recent_location_access_see_all"
- android:icon="@drawable/ic_chevron_right_24dp"
- android:fragment="com.android.settings.location.RecentLocationAccessSeeAllFragment"
- settings:controller="com.android.settings.location.RecentLocationAccessSeeAllButtonPreferenceController"
- settings:searchable="false"/>
-
<!-- This preference category gets removed if new_recent_location_ui is disabled -->
<Preference
android:key="app_level_permissions"
diff --git a/res/xml/location_settings_workprofile.xml b/res/xml/location_settings_workprofile.xml
index 99ccf14..62ec0cb 100644
--- a/res/xml/location_settings_workprofile.xml
+++ b/res/xml/location_settings_workprofile.xml
@@ -28,15 +28,6 @@
settings:controller=
"com.android.settings.location.RecentLocationAccessPreferenceController"/>
- <Preference
- android:key="recent_location_access_see_all_button"
- android:title="@string/location_recent_location_access_see_all"
- android:icon="@drawable/ic_chevron_right_24dp"
- android:fragment="com.android.settings.location.RecentLocationAccessSeeAllFragment"
- settings:controller="com.android.settings.location.RecentLocationAccessSeeAllButtonPreferenceController"
- settings:forWork="true"
- settings:searchable="false"/>
-
<com.android.settingslib.RestrictedSwitchPreference
android:key="managed_profile_location_switch"
android:title="@string/managed_profile_location_switch_title"
diff --git a/res/xml/notification_group_settings.xml b/res/xml/notification_group_settings.xml
index cbe23c6..e714759 100644
--- a/res/xml/notification_group_settings.xml
+++ b/res/xml/notification_group_settings.xml
@@ -31,9 +31,9 @@
android:title="@string/app_settings_link"
settings:allowDividerAbove="true"/>
- <com.android.settings.notification.NotificationFooterPreference
+ <com.android.settingslib.widget.FooterPreference
android:key="desc" />
- <com.android.settings.notification.NotificationFooterPreference
+ <com.android.settingslib.widget.FooterPreference
android:key="block_desc" />
</PreferenceScreen>
diff --git a/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java b/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
index 5402a9b..26c2313 100644
--- a/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
+++ b/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
@@ -26,6 +26,7 @@
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ImageSpan;
@@ -320,8 +321,13 @@
}
private static CharSequence retrieveSummary(Context context, int lineHeight) {
- return AccessibilityUtil.isFloatingMenuEnabled(context)
- ? getSummaryStringWithLink(context) : getSummaryStringWithIcon(context, lineHeight);
+ final SpannableStringBuilder sb = new SpannableStringBuilder();
+ if (!AccessibilityUtil.isFloatingMenuEnabled(context)) {
+ sb.append(getSummaryStringWithIcon(context, lineHeight));
+ sb.append("\n\n");
+ }
+ sb.append(getCustomizeAccessibilityButtonLink(context));
+ return sb;
}
private static int retrieveSoftwareShortcutImageResId(Context context) {
@@ -330,7 +336,7 @@
: R.drawable.accessibility_shortcut_type_software;
}
- private static CharSequence getSummaryStringWithLink(Context context) {
+ private static CharSequence getCustomizeAccessibilityButtonLink(Context context) {
final View.OnClickListener linkListener = v -> new SubSettingLauncher(context)
.setDestination(AccessibilityButtonFragment.class.getName())
.setSourceMetricsCategory(
diff --git a/src/com/android/settings/biometrics/BiometricEnrollActivity.java b/src/com/android/settings/biometrics/BiometricEnrollActivity.java
index cede6a0..0a2e5fe 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollActivity.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollActivity.java
@@ -16,6 +16,9 @@
package com.android.settings.biometrics;
+import static android.provider.Settings.ACTION_BIOMETRIC_ENROLL;
+import static android.provider.Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED;
+
import android.annotation.NonNull;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
@@ -24,6 +27,7 @@
import android.content.res.Resources;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricManager.Authenticators;
+import android.hardware.biometrics.BiometricManager.BiometricError;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
@@ -31,11 +35,11 @@
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
-import android.provider.Settings;
import android.util.Log;
import androidx.annotation.Nullable;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
@@ -68,12 +72,14 @@
public static final String EXTRA_SKIP_INTRO = "skip_intro";
private static final String SAVED_STATE_CONFIRMING_CREDENTIALS = "confirming_credentials";
+ private static final String SAVED_STATE_ENROLL_ACTION_LOGGED = "enroll_action_logged";
private static final String SAVED_STATE_GK_PW_HANDLE = "gk_pw_handle";
public static final class InternalActivity extends BiometricEnrollActivity {}
private int mUserId = UserHandle.myUserId();
private boolean mConfirmingCredentials;
+ private boolean mIsEnrollActionLogged;
private boolean mIsFaceEnrollable;
private boolean mIsFingerprintEnrollable;
@Nullable private Long mGkPwHandle;
@@ -91,15 +97,44 @@
}
if (savedInstanceState != null) {
- mConfirmingCredentials = savedInstanceState
- .getBoolean(SAVED_STATE_CONFIRMING_CREDENTIALS, false);
+ mConfirmingCredentials = savedInstanceState.getBoolean(
+ SAVED_STATE_CONFIRMING_CREDENTIALS, false);
+ mIsEnrollActionLogged = savedInstanceState.getBoolean(
+ SAVED_STATE_ENROLL_ACTION_LOGGED, false);
if (savedInstanceState.containsKey(SAVED_STATE_GK_PW_HANDLE)) {
mGkPwHandle = savedInstanceState.getLong(SAVED_STATE_GK_PW_HANDLE);
}
}
- // Put the theme in the intent so it gets propagated to other activities in the flow
+ // Log a framework stats event if this activity was launched via intent action.
final Intent intent = getIntent();
+ if (!mIsEnrollActionLogged && ACTION_BIOMETRIC_ENROLL.equals(intent.getAction())) {
+ mIsEnrollActionLogged = true;
+
+ // Get the current status for each authenticator type.
+ @BiometricError final int strongBiometricStatus;
+ @BiometricError final int weakBiometricStatus;
+ @BiometricError final int deviceCredentialStatus;
+ final BiometricManager bm = getSystemService(BiometricManager.class);
+ if (bm != null) {
+ strongBiometricStatus = bm.canAuthenticate(Authenticators.BIOMETRIC_STRONG);
+ weakBiometricStatus = bm.canAuthenticate(Authenticators.BIOMETRIC_WEAK);
+ deviceCredentialStatus = bm.canAuthenticate(Authenticators.DEVICE_CREDENTIAL);
+ } else {
+ strongBiometricStatus = BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE;
+ weakBiometricStatus = BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE;
+ deviceCredentialStatus = BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE;
+ }
+
+ FrameworkStatsLog.write(FrameworkStatsLog.AUTH_ENROLL_ACTION_INVOKED,
+ strongBiometricStatus == BiometricManager.BIOMETRIC_SUCCESS,
+ weakBiometricStatus == BiometricManager.BIOMETRIC_SUCCESS,
+ deviceCredentialStatus == BiometricManager.BIOMETRIC_SUCCESS,
+ intent.hasExtra(EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED),
+ intent.getIntExtra(EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, 0));
+ }
+
+ // Put the theme in the intent so it gets propagated to other activities in the flow
if (intent.getStringExtra(WizardManagerHelper.EXTRA_THEME) == null) {
intent.putExtra(
WizardManagerHelper.EXTRA_THEME,
@@ -108,7 +143,7 @@
// Default behavior is to enroll BIOMETRIC_WEAK or above. See ACTION_BIOMETRIC_ENROLL.
final int authenticators = intent.getIntExtra(
- Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, Authenticators.BIOMETRIC_WEAK);
+ EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, Authenticators.BIOMETRIC_WEAK);
Log.d(TAG, "Authenticators: " + authenticators);
@@ -132,7 +167,7 @@
} else {
// If the caller is not setup wizard, and the user has something enrolled, finish.
final BiometricManager bm = getSystemService(BiometricManager.class);
- final @BiometricManager.BiometricError int result = bm.canAuthenticate(authenticators);
+ final @BiometricError int result = bm.canAuthenticate(authenticators);
if (result != BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
Log.e(TAG, "Unexpected result: " + result);
finish();
@@ -159,6 +194,7 @@
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVED_STATE_CONFIRMING_CREDENTIALS, mConfirmingCredentials);
+ outState.putBoolean(SAVED_STATE_ENROLL_ACTION_LOGGED, mIsEnrollActionLogged);
if (mGkPwHandle != null) {
outState.putLong(SAVED_STATE_GK_PW_HANDLE, mGkPwHandle);
}
diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java
index 569e480..e0e41de 100644
--- a/src/com/android/settings/core/SettingsBaseActivity.java
+++ b/src/com/android/settings/core/SettingsBaseActivity.java
@@ -49,8 +49,6 @@
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.setupcompat.util.WizardManagerHelper;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -61,7 +59,6 @@
protected static final boolean DEBUG_TIMING = false;
private static final String TAG = "SettingsBaseActivity";
private static final String DATA_SCHEME_PKG = "package";
- private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
// Serves as a temporary list of tiles to ignore until we heard back from the PM that they
// are disabled.
@@ -95,7 +92,7 @@
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME)
&& isToolbarEnabled() && !isAnySetupWizard) {
- super.setContentView(R.layout.settings_collapsing_base_layout);
+ super.setContentView(R.layout.collapsing_toolbar_base_layout);
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
} else {
super.setContentView(R.layout.settings_base_layout);
@@ -108,7 +105,6 @@
return;
}
setActionBar(toolbar);
- initCollapsingToolbar();
if (DEBUG_TIMING) {
Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) + " ms");
@@ -207,50 +203,6 @@
return true;
}
- private void initCollapsingToolbar() {
- if (mCollapsingToolbarLayout == null) {
- return;
- }
- mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right, int bottom,
- int oldLeft, int oldTop, int oldRight, int oldBottom) {
- v.removeOnLayoutChangeListener(this);
- final int count = getLineCount();
- if (count > TOOLBAR_MAX_LINE_NUMBER) {
- ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
- lp.height = getResources()
- .getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
- mCollapsingToolbarLayout.setLayoutParams(lp);
- } else if (count == TOOLBAR_MAX_LINE_NUMBER) {
- ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
- lp.height =
- getResources().getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
- mCollapsingToolbarLayout.setLayoutParams(lp);
- }
- }
- });
- }
-
- private int getLineCount() {
- try {
- final Class<?> toolbarClazz = mCollapsingToolbarLayout.getClass();
- final Field textHelperField = toolbarClazz.getDeclaredField("collapsingTextHelper");
- textHelperField.setAccessible(true);
- final Object textHelperObj = textHelperField.get(mCollapsingToolbarLayout);
-
- final Field layoutField = textHelperObj.getClass().getDeclaredField("textLayout");
- layoutField.setAccessible(true);
- final Object layoutObj = layoutField.get(textHelperObj);
-
- final Method method = layoutObj.getClass().getDeclaredMethod("getLineCount");
- return (int) method.invoke(layoutObj);
- } catch (Exception e) {
- return 0;
- }
- }
-
-
private void onCategoriesChanged(Set<String> categories) {
final int N = mCategoryListeners.size();
for (int i = 0; i < N; i++) {
diff --git a/src/com/android/settings/development/qstile/DevelopmentTiles.java b/src/com/android/settings/development/qstile/DevelopmentTiles.java
index 16084c0..c55d0cb 100644
--- a/src/com/android/settings/development/qstile/DevelopmentTiles.java
+++ b/src/com/android/settings/development/qstile/DevelopmentTiles.java
@@ -371,7 +371,7 @@
mContext = getApplicationContext();
mSensorPrivacyManager = (SensorPrivacyManager) mContext.getSystemService(
Context.SENSOR_PRIVACY_SERVICE);
- mIsEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled();
+ mIsEnabled = mSensorPrivacyManager.isAllSensorPrivacyEnabled();
mMetricsFeatureProvider = FeatureFactory.getFactory(
mContext).getMetricsFeatureProvider();
mKeyguardManager = (KeyguardManager) mContext.getSystemService(
@@ -392,7 +392,7 @@
mMetricsFeatureProvider.action(getApplicationContext(), SettingsEnums.QS_SENSOR_PRIVACY,
isEnabled);
mIsEnabled = isEnabled;
- mSensorPrivacyManager.setSensorPrivacy(isEnabled);
+ mSensorPrivacyManager.setAllSensorPrivacy(isEnabled);
}
}
diff --git a/src/com/android/settings/display/AdaptiveSleepCameraStatePreferenceController.java b/src/com/android/settings/display/AdaptiveSleepCameraStatePreferenceController.java
index 72a1c66..ba7a3ab 100644
--- a/src/com/android/settings/display/AdaptiveSleepCameraStatePreferenceController.java
+++ b/src/com/android/settings/display/AdaptiveSleepCameraStatePreferenceController.java
@@ -43,7 +43,7 @@
mPreference.setPositiveButtonText(R.string.allow);
mPrivacyManager = SensorPrivacyManager.getInstance(context);
mPrivacyManager.addSensorPrivacyListener(CAMERA,
- enabled -> updateVisibility());
+ (sensor, enabled) -> updateVisibility());
mPreference.setPositiveButtonOnClickListener(p -> {
mPrivacyManager.setSensorPrivacy(CAMERA, false);
});
diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java
index 444f8ef8..27e1e1b 100644
--- a/src/com/android/settings/display/ScreenTimeoutSettings.java
+++ b/src/com/android/settings/display/ScreenTimeoutSettings.java
@@ -111,9 +111,7 @@
mPrivacyPreference.setLayoutResource(R.layout.preference_footer);
mPrivacyManager = SensorPrivacyManager.getInstance(context);
mPrivacyManager.addSensorPrivacyListener(CAMERA,
- enabled -> {
- mAdaptiveSleepController.updatePreference();
- });
+ (sensor, enabled) -> mAdaptiveSleepController.updatePreference());
}
@Override
diff --git a/src/com/android/settings/display/SmartAutoRotateCameraStateController.java b/src/com/android/settings/display/SmartAutoRotateCameraStateController.java
index 1480785..9e2a784 100644
--- a/src/com/android/settings/display/SmartAutoRotateCameraStateController.java
+++ b/src/com/android/settings/display/SmartAutoRotateCameraStateController.java
@@ -43,7 +43,7 @@
public SmartAutoRotateCameraStateController(Context context, String key) {
super(context, key);
mPrivacyManager = SensorPrivacyManager.getInstance(context);
- mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> {
+ mPrivacyManager.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> {
mPreference.setVisible(enabled);
updateState(mPreference);
});
diff --git a/src/com/android/settings/display/SmartAutoRotateController.java b/src/com/android/settings/display/SmartAutoRotateController.java
index e3b2665..cf2a9a6 100644
--- a/src/com/android/settings/display/SmartAutoRotateController.java
+++ b/src/com/android/settings/display/SmartAutoRotateController.java
@@ -52,7 +52,8 @@
super(context, preferenceKey);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mPrivacyManager = SensorPrivacyManager.getInstance(context);
- mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> updateState(mPreference));
+ mPrivacyManager
+ .addSensorPrivacyListener(CAMERA, (sensor, enabled) -> updateState(mPreference));
}
@Override
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 432224d..3ef7c45 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -27,6 +27,7 @@
import android.os.UserHandle;
import android.text.Html;
import android.text.TextUtils;
+import android.text.format.DateUtils;
import android.util.Log;
import android.view.View;
@@ -282,20 +283,8 @@
final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
- final long totalTimeMs = foregroundTimeMs + backgroundTimeMs;
- //TODO(b/178197718) Refine the layout
- controller.setSummary(TextUtils.expandTemplate(
- getText(R.string.battery_total_and_background_usage),
- StringUtil.formatElapsedTime(
- getContext(),
- totalTimeMs,
- /* withSeconds */ false,
- /* collapseTimeUnit */ false),
- StringUtil.formatElapsedTime(
- getContext(),
- backgroundTimeMs,
- /* withSeconds */ false,
- /* collapseTimeUnit */ false)));
+ //TODO(b/178197718) Update layout to support multiple lines
+ controller.setSummary(getAppActiveTime(foregroundTimeMs, backgroundTimeMs));
controller.done(context, true /* rebindActions */);
}
@@ -388,4 +377,53 @@
private void updatePreferenceState(RadioButtonPreference preference, String selectedKey) {
preference.setChecked(selectedKey.equals(preference.getKey()));
}
+
+ //TODO(b/178197718) Update method to support time period
+ private CharSequence getAppActiveTime(long foregroundTimeMs, long backgroundTimeMs) {
+ final long totalTimeMs = foregroundTimeMs + backgroundTimeMs;
+ final CharSequence usageTimeSummary;
+
+ if (totalTimeMs == 0) {
+ usageTimeSummary = getText(R.string.battery_not_usage);
+ // Shows background summary only if we don't have foreground usage time.
+ } else if (foregroundTimeMs == 0 && backgroundTimeMs != 0) {
+ usageTimeSummary = backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS ?
+ getText(R.string.battery_background_usage_less_minute) :
+ TextUtils.expandTemplate(getText(R.string.battery_background_usage),
+ StringUtil.formatElapsedTime(
+ getContext(),
+ backgroundTimeMs,
+ /* withSeconds */ false,
+ /* collapseTimeUnit */ false));
+ // Shows total usage summary only if total usage time is small.
+ } else if (totalTimeMs < DateUtils.MINUTE_IN_MILLIS) {
+ usageTimeSummary = getText(R.string.battery_total_usage_less_minute);
+ // Shows different total usage summary when background usage time is small.
+ } else if (backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS) {
+ usageTimeSummary = TextUtils.expandTemplate(
+ getText(backgroundTimeMs == 0 ?
+ R.string.battery_total_usage :
+ R.string.battery_total_usage_and_background_less_minute_usage),
+ StringUtil.formatElapsedTime(
+ getContext(),
+ totalTimeMs,
+ /* withSeconds */ false,
+ /* collapseTimeUnit */ false));
+ // Shows default summary.
+ } else {
+ usageTimeSummary = TextUtils.expandTemplate(
+ getText(R.string.battery_total_and_background_usage),
+ StringUtil.formatElapsedTime(
+ getContext(),
+ totalTimeMs,
+ /* withSeconds */ false,
+ /* collapseTimeUnit */ false),
+ StringUtil.formatElapsedTime(
+ getContext(),
+ backgroundTimeMs,
+ /* withSeconds */ false,
+ /* collapseTimeUnit */ false));
+ }
+ return usageTimeSummary;
+ }
}
diff --git a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
index f12de01..7131f28 100644
--- a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
@@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- *
*/
package com.android.settings.fuelgauge;
@@ -51,7 +50,7 @@
/** Controls the update for chart graph and the list items. */
public class BatteryChartPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnDestroy,
- BatteryChartView.OnSelectListener {
+ BatteryChartView.OnSelectListener, ExpandDividerPreference.OnExpandListener {
private static final String TAG = "BatteryChartPreferenceController";
private static final int CHART_KEY_ARRAY_SIZE = 25;
private static final int CHART_LEVEL_ARRAY_SIZE = 13;
@@ -65,6 +64,7 @@
@VisibleForTesting BatteryUtils mBatteryUtils;
@VisibleForTesting PreferenceGroup mAppListPrefGroup;
@VisibleForTesting BatteryChartView mBatteryChartView;
+ @VisibleForTesting ExpandDividerPreference mExpandDividerPreference;
@VisibleForTesting int[] mBatteryHistoryLevels;
@VisibleForTesting long[] mBatteryHistoryKeys;
@@ -76,9 +76,13 @@
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final CharSequence[] mNotAllowShowSummaryPackages;
+ private boolean mIsExpanded = false;
+
// Preference cache to avoid create new instance each time.
@VisibleForTesting
final Map<String, Preference> mPreferenceCache = new HashMap<>();
+ @VisibleForTesting
+ final List<BatteryDiffEntry> mSystemEntries = new ArrayList<>();
public BatteryChartPreferenceController(
Context context, String preferenceKey,
@@ -163,6 +167,12 @@
refreshUi(trapezoidIndex, /*isForce=*/ false);
}
+ @Override
+ public void onExpand(boolean isExpanded) {
+ mIsExpanded = isExpanded;
+ refreshExpandUi();
+ }
+
void setBatteryHistoryMap(
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
mHandler.post(() -> setBatteryHistoryMapInner(batteryHistoryMap));
@@ -266,10 +276,10 @@
}
// Separates data into two groups and sort them individually.
final List<BatteryDiffEntry> appEntries = new ArrayList<>();
- final List<BatteryDiffEntry> systemEntries = new ArrayList<>();
+ mSystemEntries.clear();
entries.forEach(entry -> {
if (entry.isSystemEntry()) {
- systemEntries.add(entry);
+ mSystemEntries.add(entry);
} else {
appEntries.add(entry);
}
@@ -279,11 +289,25 @@
}
});
Collections.sort(appEntries, BatteryDiffEntry.COMPARATOR);
- Collections.sort(systemEntries, BatteryDiffEntry.COMPARATOR);
+ Collections.sort(mSystemEntries, BatteryDiffEntry.COMPARATOR);
Log.d(TAG, String.format("addAllPreferences() app=%d system=%d",
- appEntries.size(), systemEntries.size()));
- addPreferenceToScreen(appEntries);
- addPreferenceToScreen(systemEntries);
+ appEntries.size(), mSystemEntries.size()));
+
+ // Adds app entries to the list if it is not empty.
+ if (!appEntries.isEmpty()) {
+ addPreferenceToScreen(appEntries);
+ }
+ // Adds the expabable divider if we have two sections data.
+ if (!appEntries.isEmpty() && !mSystemEntries.isEmpty()) {
+ if (mExpandDividerPreference == null) {
+ mExpandDividerPreference = new ExpandDividerPreference(mPrefContext);
+ mExpandDividerPreference.setOnExpandListener(this);
+ }
+ mExpandDividerPreference.setOrder(
+ mAppListPrefGroup.getPreferenceCount());
+ mAppListPrefGroup.addPreference(mExpandDividerPreference);
+ }
+ refreshExpandUi();
}
@VisibleForTesting
@@ -293,6 +317,7 @@
}
int prefIndex = mAppListPrefGroup.getPreferenceCount();
for (BatteryDiffEntry entry : entries) {
+ boolean isAdded = false;
final String appLabel = entry.getAppLabel();
final Drawable appIcon = entry.getAppIcon();
if (TextUtils.isEmpty(appLabel) || appIcon == null) {
@@ -300,8 +325,13 @@
continue;
}
final String prefKey = entry.mBatteryHistEntry.getKey();
- PowerGaugePreference pref =
- (PowerGaugePreference) mPreferenceCache.get(prefKey);
+ PowerGaugePreference pref = mAppListPrefGroup.findPreference(prefKey);
+ if (pref != null) {
+ isAdded = true;
+ Log.w(TAG, "preference should be removed for\n" + entry);
+ } else {
+ pref = (PowerGaugePreference) mPreferenceCache.get(prefKey);
+ }
// Creates new innstance if cached preference is not found.
if (pref == null) {
pref = new PowerGaugePreference(mPrefContext);
@@ -316,7 +346,9 @@
// Sets the BatteryDiffEntry to preference for launching detailed page.
pref.setBatteryDiffEntry(entry);
setPreferenceSummary(pref, entry);
- mAppListPrefGroup.addPreference(pref);
+ if (!isAdded) {
+ mAppListPrefGroup.addPreference(pref);
+ }
prefIndex++;
}
}
@@ -337,6 +369,22 @@
mAppListPrefGroup.removeAll();
}
+ private void refreshExpandUi() {
+ if (mIsExpanded) {
+ addPreferenceToScreen(mSystemEntries);
+ } else {
+ // Removes and recycles all system entries to hide all of them.
+ for (BatteryDiffEntry entry : mSystemEntries) {
+ final String prefKey = entry.mBatteryHistEntry.getKey();
+ final Preference pref = mAppListPrefGroup.findPreference(prefKey);
+ if (pref != null) {
+ mAppListPrefGroup.removePreference(pref);
+ mPreferenceCache.put(pref.getKey(), pref);
+ }
+ }
+ }
+ }
+
@VisibleForTesting
void setPreferenceSummary(
PowerGaugePreference preference, BatteryDiffEntry entry) {
diff --git a/src/com/android/settings/fuelgauge/BatteryChartView.java b/src/com/android/settings/fuelgauge/BatteryChartView.java
index 26eb3e4..f970072 100644
--- a/src/com/android/settings/fuelgauge/BatteryChartView.java
+++ b/src/com/android/settings/fuelgauge/BatteryChartView.java
@@ -97,8 +97,18 @@
public void setLevels(int[] levels) {
// We should provide trapezoid count + 1 data to draw all trapezoids.
mLevels = levels.length == mTrapezoidCount + 1 ? levels : null;
- setClickable(mLevels != null);
+ setClickable(false);
invalidate();
+ if (mLevels == null) {
+ return;
+ }
+ // Sets the chart is clickable if there is at least one valid item in it.
+ for (int index = 0; index < mLevels.length; index++) {
+ if (mLevels[index] != 0) {
+ setClickable(true);
+ break;
+ }
+ }
}
/** Sets the selected group index to draw highlight effect. */
diff --git a/src/com/android/settings/fuelgauge/ConvertUtils.java b/src/com/android/settings/fuelgauge/ConvertUtils.java
index 30982da..2e8726e 100644
--- a/src/com/android/settings/fuelgauge/ConvertUtils.java
+++ b/src/com/android/settings/fuelgauge/ConvertUtils.java
@@ -71,6 +71,7 @@
private static String sZoneId;
private static SimpleDateFormat sSimpleDateFormat;
+ private static SimpleDateFormat sSimpleDateFormatForHour;
private ConvertUtils() {}
@@ -139,10 +140,27 @@
sZoneId = currentZoneId;
sSimpleDateFormat =
new SimpleDateFormat("MMM dd,yyyy HH:mm:ss", Locale.ENGLISH);
+ sSimpleDateFormatForHour = null;
}
return sSimpleDateFormat.format(new Date(timestamp));
}
+ /** Converts UTC timestamp to local time hour data. */
+ public static int utcToLocalTimeHour(long timestamp) {
+ final String currentZoneId = TimeZone.getDefault().getID();
+ if (!currentZoneId.equals(sZoneId) || sSimpleDateFormatForHour == null) {
+ sZoneId = currentZoneId;
+ sSimpleDateFormat = null;
+ sSimpleDateFormatForHour = new SimpleDateFormat("HH", Locale.ENGLISH);
+ }
+ try {
+ return Integer.parseInt(
+ sSimpleDateFormatForHour.format(new Date(timestamp)));
+ } catch (NumberFormatException e) {
+ return Integer.MIN_VALUE;
+ }
+ }
+
/** Gets indexed battery usage data for each corresponding time slot. */
public static Map<Integer, List<BatteryDiffEntry>> getIndexedUsageMap(
final Context context,
diff --git a/src/com/android/settings/location/LocationPersonalSettings.java b/src/com/android/settings/location/LocationPersonalSettings.java
index 0553d96..ab392d6 100644
--- a/src/com/android/settings/location/LocationPersonalSettings.java
+++ b/src/com/android/settings/location/LocationPersonalSettings.java
@@ -51,7 +51,6 @@
use(AppLocationPermissionPreferenceController.class).init(this);
use(LocationSettingsFooterPreferenceController.class).init(this);
- use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this);
final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
final RecentLocationAccessPreferenceController controller = use(
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index fe3cf30..093dc85 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -83,7 +83,6 @@
use(AppLocationPermissionPreferenceController.class).init(this);
use(RecentLocationAccessPreferenceController.class).init(this);
- use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this);
use(LocationForWorkPreferenceController.class).init(this);
use(LocationSettingsFooterPreferenceController.class).init(this);
}
diff --git a/src/com/android/settings/location/LocationWorkProfileSettings.java b/src/com/android/settings/location/LocationWorkProfileSettings.java
index 24c44f3..f50ba90 100644
--- a/src/com/android/settings/location/LocationWorkProfileSettings.java
+++ b/src/com/android/settings/location/LocationWorkProfileSettings.java
@@ -51,7 +51,6 @@
use(AppLocationPermissionPreferenceController.class).init(this);
use(LocationForWorkPreferenceController.class).init(this);
- use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this);
use(LocationSettingsFooterPreferenceController.class).init(this);
final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
diff --git a/src/com/android/settings/location/RecentLocationAccessSeeAllButtonPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessSeeAllButtonPreferenceController.java
deleted file mode 100644
index 68cde63..0000000
--- a/src/com/android/settings/location/RecentLocationAccessSeeAllButtonPreferenceController.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.location;
-
-import android.content.Context;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-/**
- * Preference controller that handles the "See All" button for recent location access.
- */
-public class RecentLocationAccessSeeAllButtonPreferenceController extends
- LocationBasePreferenceController {
-
- private Preference mPreference;
-
- /**
- * Constructor of {@link RecentLocationAccessSeeAllButtonPreferenceController}.
- */
- public RecentLocationAccessSeeAllButtonPreferenceController(Context context, String key) {
- super(context, key);
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mPreference = screen.findPreference(getPreferenceKey());
- }
-
- @Override
- public void onLocationModeChanged(int mode, boolean restricted) {
- boolean enabled = mLocationEnabler.isEnabled(mode);
- mPreference.setVisible(enabled);
- }
-}
diff --git a/src/com/android/settings/network/telephony/Enable2gPreferenceController.java b/src/com/android/settings/network/telephony/Enable2gPreferenceController.java
index cf08d10..d336cb4 100644
--- a/src/com/android/settings/network/telephony/Enable2gPreferenceController.java
+++ b/src/com/android/settings/network/telephony/Enable2gPreferenceController.java
@@ -72,7 +72,7 @@
public int getAvailabilityStatus(int subId) {
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
boolean visible =
- subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ SubscriptionManager.isUsableSubscriptionId(subId)
&& carrierConfig != null
&& !carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENABLE_2G)
&& mTelephonyManager.isRadioInterfaceCapabilitySupported(
@@ -89,6 +89,9 @@
@Override
public boolean setChecked(boolean isChecked) {
+ if (!SubscriptionManager.isUsableSubscriptionId(mSubId)) {
+ return false;
+ }
long currentlyAllowedNetworkTypes = mTelephonyManager.getAllowedNetworkTypesForReason(
mTelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G);
boolean enabled = (currentlyAllowedNetworkTypes & BITMASK_2G) != 0;
diff --git a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
index 6237326..a46f164 100644
--- a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
+++ b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
@@ -77,11 +77,7 @@
protected void setNotificationAssistantGranted(ComponentName cn) {
if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.NAS_SETTINGS_UPDATED, 0, mUserId) == 0) {
- for (int profileId : mUserManager.getProfileIds(mUserId, false)) {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.NAS_SETTINGS_UPDATED, 1, profileId);
- }
- mNotificationBackend.resetDefaultNotificationAssistant(cn != null);
+ mNotificationBackend.setNASMigrationDoneAndResetDefault(mUserId, cn != null);
}
mNotificationBackend.setNotificationAssistantGranted(cn);
}
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index b08d02c..e448dda 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -570,9 +570,9 @@
}
}
- public void resetDefaultNotificationAssistant(boolean loadFromConfig) {
+ public void setNASMigrationDoneAndResetDefault(int userId, boolean loadFromConfig) {
try {
- sINM.resetDefaultNotificationAssistant(loadFromConfig);
+ sINM.setNASMigrationDoneAndResetDefault(userId, loadFromConfig);
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
}
diff --git a/src/com/android/settings/notification/app/NotificationFooterPreference.java b/src/com/android/settings/notification/app/NotificationFooterPreference.java
deleted file mode 100644
index 6f34cdd..0000000
--- a/src/com/android/settings/notification/app/NotificationFooterPreference.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification.app;
-
-import android.content.Context;
-import android.text.method.LinkMovementMethod;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import androidx.core.content.res.TypedArrayUtils;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settingslib.R;
-
-/**
- * FooterPreference that can have any key or ordering.
- */
-public class NotificationFooterPreference extends Preference {
-
- public NotificationFooterPreference(Context context, AttributeSet attrs) {
- super(context, attrs, TypedArrayUtils.getAttr(
- context, R.attr.footerPreferenceStyle, android.R.attr.preferenceStyle));
- init();
- }
-
- public NotificationFooterPreference(Context context) {
- this(context, null);
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
- super.onBindViewHolder(holder);
- TextView title = holder.itemView.findViewById(android.R.id.title);
- title.setMovementMethod(new LinkMovementMethod());
- title.setClickable(false);
- title.setLongClickable(false);
- }
-
- private void init() {
- setIcon(R.drawable.ic_info_outline_24dp);
- setSelectable(false);
- }
-}
diff --git a/src/com/android/settings/uwb/UwbPreferenceController.java b/src/com/android/settings/uwb/UwbPreferenceController.java
new file mode 100644
index 0000000..daadb63
--- /dev/null
+++ b/src/com/android/settings/uwb/UwbPreferenceController.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.uwb;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.uwb.UwbManager;
+import android.uwb.UwbManager.AdapterStateCallback;
+
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+/** Controller for "UWB" toggle. */
+public class UwbPreferenceController extends TogglePreferenceController implements
+ AdapterStateCallback, LifecycleObserver {
+ @VisibleForTesting
+ static final String KEY_UWB_SETTINGS = "uwb_settings";
+ @VisibleForTesting
+ UwbManager mUwbManager;
+ @VisibleForTesting
+ boolean mAirplaneModeOn;
+ @VisibleForTesting
+ private final BroadcastReceiver mAirplaneModeChangedReceiver;
+ private final Executor mExecutor;
+ private boolean mIsChecked = true;
+ boolean mRegisteredAdapterStateCallback = false;
+ private Preference mPreference;
+
+ public UwbPreferenceController(Context context, String key) {
+ super(context, key);
+ mExecutor = Executors.newSingleThreadExecutor();
+ mUwbManager = context.getSystemService(UwbManager.class);
+ mAirplaneModeOn = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
+ mAirplaneModeChangedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ updateState(mPreference);
+ }
+ };
+ }
+
+ @VisibleForTesting
+ boolean isUwbSupportedOnDevice() {
+ return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (!isUwbSupportedOnDevice()) {
+ return UNSUPPORTED_ON_DEVICE;
+ } else if (mAirplaneModeOn) {
+ return DISABLED_DEPENDENT_SETTING;
+ } else {
+ return AVAILABLE;
+ }
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ }
+
+ @Override
+ public boolean isChecked() {
+ //TODO(b/186075119): Update toggle state by assigning to the real value by default.
+ return mIsChecked;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ mIsChecked = isChecked;
+ mUwbManager.setUwbEnabled(isChecked);
+ return true;
+ }
+
+ @Override
+ public void onStateChanged(int state, int reason) {
+ // Only update toggle state from service the first time. Otherwise toggle state is
+ // changed from controller. For example, UWB is disabled if airplane mode is on but we do
+ // not want to change the preference for the user in this case.
+ if (!mRegisteredAdapterStateCallback) {
+ mIsChecked = state == STATE_ENABLED_ACTIVE || state == STATE_ENABLED_INACTIVE;
+ mRegisteredAdapterStateCallback = true;
+ }
+ }
+
+ /** Called when activity starts being displayed to user. */
+ @OnLifecycleEvent(ON_START)
+ public void onStart() {
+ if (isUwbSupportedOnDevice()) {
+ mUwbManager.registerAdapterStateCallback(mExecutor, this);
+ }
+ if (mAirplaneModeChangedReceiver != null) {
+ mContext.registerReceiver(mAirplaneModeChangedReceiver,
+ new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
+ }
+ refreshSummary(mPreference);
+ }
+
+ /** Called when activity stops being displayed to user. */
+ @OnLifecycleEvent(ON_STOP)
+ public void onStop() {
+ if (isUwbSupportedOnDevice()) {
+ mUwbManager.unregisterAdapterStateCallback(this);
+ }
+ if (mAirplaneModeChangedReceiver != null) {
+ mContext.unregisterReceiver(mAirplaneModeChangedReceiver);
+ }
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ mAirplaneModeOn = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
+ preference.setEnabled(!mAirplaneModeOn);
+ if (isUwbSupportedOnDevice()) {
+ if (mAirplaneModeOn) {
+ mUwbManager.setUwbEnabled(false);
+ } else {
+ mUwbManager.setUwbEnabled(mIsChecked);
+ }
+ }
+ refreshSummary(preference);
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ if (mAirplaneModeOn) {
+ return mContext.getResources().getString(R.string.uwb_settings_summary_airplane_mode);
+ } else {
+ return mContext.getResources().getString(R.string.uwb_settings_summary);
+ }
+ }
+}
+
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index a288c3a..dd10a9e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -249,14 +249,122 @@
}
@Test
- public void testInitHeader_hasCorrectSummary() {
- mFragment.mAppEntry = null;
+ public void testInitHeader_noUsageTime_hasCorrectSummary() {
+ Bundle bundle = new Bundle(2);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, /* value */ 0);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, /* value */ 0);
+ when(mFragment.getArguments()).thenReturn(bundle);
+
mFragment.initHeader();
ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
verify(mEntityHeaderController).setSummary(captor.capture());
assertThat(captor.getValue().toString())
- .isEqualTo("0 min total • 0 min background for past 24 hr");
+ .isEqualTo("No usage for past 24 hr");
+ }
+
+ @Test
+ public void testInitHeader_backgroundTwoMinutesForegroundZero_hasCorrectSummary() {
+ final long backgroundTimeTwoMinutes = 120000;
+ final long foregroundTimeZero = 0;
+ Bundle bundle = new Bundle(2);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeTwoMinutes);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeZero);
+ when(mFragment.getArguments()).thenReturn(bundle);
+
+ mFragment.initHeader();
+
+ ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
+ verify(mEntityHeaderController).setSummary(captor.capture());
+ assertThat(captor.getValue().toString())
+ .isEqualTo("2 min background for past 24 hr");
+ }
+
+ @Test
+ public void testInitHeader_backgroundLessThanAMinutesForegroundZero_hasCorrectSummary() {
+ final long backgroundTimeLessThanAMinute = 59999;
+ final long foregroundTimeZero = 0;
+ Bundle bundle = new Bundle(2);
+ bundle.putLong(
+ AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeLessThanAMinute);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeZero);
+ when(mFragment.getArguments()).thenReturn(bundle);
+
+ mFragment.initHeader();
+
+ ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
+ verify(mEntityHeaderController).setSummary(captor.capture());
+ assertThat(captor.getValue().toString())
+ .isEqualTo("Background less than a minute for past 24 hr");
+ }
+
+ @Test
+ public void testInitHeader_totalUsageLessThanAMinutes_hasCorrectSummary() {
+ final long backgroundTimeLessThanHalfMinute = 20000;
+ final long foregroundTimeLessThanHalfMinute = 20000;
+ Bundle bundle = new Bundle(2);
+ bundle.putLong(
+ AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeLessThanHalfMinute);
+ bundle.putLong(
+ AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeLessThanHalfMinute);
+ when(mFragment.getArguments()).thenReturn(bundle);
+
+ mFragment.initHeader();
+
+ ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
+ verify(mEntityHeaderController).setSummary(captor.capture());
+ assertThat(captor.getValue().toString())
+ .isEqualTo("Total less than a minute for past 24 hr");
+ }
+
+ @Test
+ public void testInitHeader_TotalAMinutesBackgroundLessThanAMinutes_hasCorrectSummary() {
+ final long backgroundTimeZero = 59999;
+ final long foregroundTimeTwoMinutes = 1;
+ Bundle bundle = new Bundle(2);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeZero);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeTwoMinutes);
+ when(mFragment.getArguments()).thenReturn(bundle);
+
+ mFragment.initHeader();
+
+ ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
+ verify(mEntityHeaderController).setSummary(captor.capture());
+ assertThat(captor.getValue().toString())
+ .isEqualTo("1 min total • background less than a minute for past 24 hr");
+ }
+
+ @Test
+ public void testInitHeader_TotalAMinutesBackgroundZero_hasCorrectSummary() {
+ final long backgroundTimeZero = 0;
+ final long foregroundTimeAMinutes = 60000;
+ Bundle bundle = new Bundle(2);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeZero);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeAMinutes);
+ when(mFragment.getArguments()).thenReturn(bundle);
+
+ mFragment.initHeader();
+
+ ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
+ verify(mEntityHeaderController).setSummary(captor.capture());
+ assertThat(captor.getValue().toString())
+ .isEqualTo("1 min total for past 24 hr");
+ }
+
+ @Test
+ public void testInitHeader_foregroundTwoMinutesBackgroundFourMinutes_hasCorrectSummary() {
+ final long backgroundTimeFourMinute = 240000;
+ final long foregroundTimeTwoMinutes = 120000;
+ Bundle bundle = new Bundle(2);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeFourMinute);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeTwoMinutes);
+ when(mFragment.getArguments()).thenReturn(bundle);
+ mFragment.initHeader();
+
+ ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
+ verify(mEntityHeaderController).setSummary(captor.capture());
+ assertThat(captor.getValue().toString())
+ .isEqualTo("6 min total • 4 min background for past 24 hr");
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
index c8bbba3..9f0ffb0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
@@ -43,6 +43,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@@ -56,6 +57,8 @@
@RunWith(RobolectricTestRunner.class)
public final class BatteryChartPreferenceControllerTest {
+ private static final String PREF_KEY = "pref_key";
+ private static final String PREF_SUMMARY = "fake preference summary";
@Mock private InstrumentedPreferenceFragment mFragment;
@Mock private SettingsActivity mSettingsActivity;
@@ -119,10 +122,9 @@
@Test
public void testOnDestroy_clearPreferenceCache() {
- final String prefKey = "preference fake key";
// Ensures the testing environment is correct.
mBatteryChartPreferenceController.mPreferenceCache.put(
- prefKey, mPowerGaugePreference);
+ PREF_KEY, mPowerGaugePreference);
assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1);
mBatteryChartPreferenceController.onDestroy();
@@ -230,17 +232,16 @@
@Test
public void testRemoveAndCacheAllPrefs_buildCacheAndRemoveAllPreference() {
final int trapezoidIndex = 1;
- final String prefKey = "preference fake key";
doReturn(1).when(mAppListGroup).getPreferenceCount();
doReturn(mPowerGaugePreference).when(mAppListGroup).getPreference(0);
- doReturn(prefKey).when(mPowerGaugePreference).getKey();
+ doReturn(PREF_KEY).when(mPowerGaugePreference).getKey();
// Ensures the testing data is correct.
assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
mBatteryChartPreferenceController.refreshUi(
trapezoidIndex, /*isForce=*/ true);
- assertThat(mBatteryChartPreferenceController.mPreferenceCache.get(prefKey))
+ assertThat(mBatteryChartPreferenceController.mPreferenceCache.get(PREF_KEY))
.isEqualTo(mPowerGaugePreference);
verify(mAppListGroup).removeAll();
}
@@ -254,12 +255,12 @@
@Test
public void testAddPreferenceToScreen_addPreferenceIntoScreen() {
- final String prefKey = "preference fake key";
final String appLabel = "fake app label";
doReturn(1).when(mAppListGroup).getPreferenceCount();
doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel();
- doReturn(prefKey).when(mBatteryHistEntry).getKey();
+ doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+ doReturn(null).when(mAppListGroup).findPreference(PREF_KEY);
mBatteryChartPreferenceController.addPreferenceToScreen(
Arrays.asList(mBatteryDiffEntry));
@@ -267,11 +268,11 @@
// Verifies the preference cache.
final PowerGaugePreference pref =
(PowerGaugePreference) mBatteryChartPreferenceController.mPreferenceCache
- .get(prefKey);
+ .get(PREF_KEY);
assertThat(pref).isNotNull();
// Verifies the added preference configuration.
verify(mAppListGroup).addPreference(pref);
- assertThat(pref.getKey()).isEqualTo(prefKey);
+ assertThat(pref.getKey()).isEqualTo(PREF_KEY);
assertThat(pref.getTitle()).isEqualTo(appLabel);
assertThat(pref.getIcon()).isEqualTo(mDrawable);
assertThat(pref.getOrder()).isEqualTo(1);
@@ -280,6 +281,21 @@
}
@Test
+ public void testAddPreferenceToScreen_alreadyInScreen_notAddPreferenceAgain() {
+ final String appLabel = "fake app label";
+ doReturn(1).when(mAppListGroup).getPreferenceCount();
+ doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
+ doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel();
+ doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+ doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(PREF_KEY);
+
+ mBatteryChartPreferenceController.addPreferenceToScreen(
+ Arrays.asList(mBatteryDiffEntry));
+
+ verify(mAppListGroup, never()).addPreference(any());
+ }
+
+ @Test
public void testHandlePreferenceTreeClick_notPowerGaugePreference_returnFalse() {
assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(mAppListGroup))
.isFalse();
@@ -309,7 +325,7 @@
@Test
public void testSetPreferenceSummary_setNullContentIfTotalUsageTimeIsZero() {
final PowerGaugePreference pref = new PowerGaugePreference(mContext);
- pref.setSummary("fake preference summary");
+ pref.setSummary(PREF_SUMMARY);
mBatteryChartPreferenceController.setPreferenceSummary(
pref, createBatteryDiffEntry(
@@ -321,7 +337,7 @@
@Test
public void testSetPreferenceSummary_setBackgroundUsageTimeOnly() {
final PowerGaugePreference pref = new PowerGaugePreference(mContext);
- pref.setSummary("fake preference summary");
+ pref.setSummary(PREF_SUMMARY);
mBatteryChartPreferenceController.setPreferenceSummary(
pref, createBatteryDiffEntry(
@@ -333,7 +349,7 @@
@Test
public void testSetPreferenceSummary_setTotalUsageTimeLessThanAMinute() {
final PowerGaugePreference pref = new PowerGaugePreference(mContext);
- pref.setSummary("fake preference summary");
+ pref.setSummary(PREF_SUMMARY);
mBatteryChartPreferenceController.setPreferenceSummary(
pref, createBatteryDiffEntry(
@@ -345,7 +361,7 @@
@Test
public void testSetPreferenceSummary_setTotalTimeIfBackgroundTimeLessThanAMinute() {
final PowerGaugePreference pref = new PowerGaugePreference(mContext);
- pref.setSummary("fake preference summary");
+ pref.setSummary(PREF_SUMMARY);
mBatteryChartPreferenceController.setPreferenceSummary(
pref, createBatteryDiffEntry(
@@ -357,7 +373,7 @@
@Test
public void testSetPreferenceSummary_setTotalAndBackgroundUsageTime() {
final PowerGaugePreference pref = new PowerGaugePreference(mContext);
- pref.setSummary("fake preference summary");
+ pref.setSummary(PREF_SUMMARY);
mBatteryChartPreferenceController.setPreferenceSummary(
pref, createBatteryDiffEntry(
@@ -369,7 +385,7 @@
@Test
public void testSetPreferenceSummary_notAllowShownPackage_setSummayAsNull() {
final PowerGaugePreference pref = new PowerGaugePreference(mContext);
- pref.setSummary("fake preference summary");
+ pref.setSummary(PREF_SUMMARY);
final BatteryDiffEntry batteryDiffEntry =
spy(createBatteryDiffEntry(
/*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS,
@@ -416,23 +432,54 @@
@Test
public void testValidateSlotTimestamp_returnExpectedResult() {
- final List<Long> slotTimestampList =
+ final ArrayList<Long> slotTimestampList = new ArrayList<Long>(
Arrays.asList(
Long.valueOf(0),
Long.valueOf(DateUtils.HOUR_IN_MILLIS),
Long.valueOf(DateUtils.HOUR_IN_MILLIS * 2 + DateUtils.MINUTE_IN_MILLIS),
- Long.valueOf(DateUtils.HOUR_IN_MILLIS * 3 + DateUtils.MINUTE_IN_MILLIS * 2));
+ Long.valueOf(DateUtils.HOUR_IN_MILLIS * 3 + DateUtils.MINUTE_IN_MILLIS * 2)));
// Verifies the testing data is correct before we added invalid data into it.
assertThat(BatteryChartPreferenceController.validateSlotTimestamp(slotTimestampList))
.isTrue();
// Insert invalid timestamp into the list.
slotTimestampList.add(
- Long.valueOf(DateUtils.HOUR_IN_MILLIS * 4 + DateUtils.MINUTE_IN_MILLIS * 3));
+ Long.valueOf(DateUtils.HOUR_IN_MILLIS * 4 + DateUtils.MINUTE_IN_MILLIS * 6));
assertThat(BatteryChartPreferenceController.validateSlotTimestamp(slotTimestampList))
.isFalse();
}
+ @Test
+ public void testOnExpand_expandedIsTrue_addSystemEntriesToPreferenceGroup() {
+ doReturn(1).when(mAppListGroup).getPreferenceCount();
+ mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry);
+ doReturn("label").when(mBatteryDiffEntry).getAppLabel();
+ doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
+ doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+
+ mBatteryChartPreferenceController.onExpand(/*isExpanded=*/ true);
+
+ final ArgumentCaptor<Preference> captor = ArgumentCaptor.forClass(Preference.class);
+ verify(mAppListGroup).addPreference(captor.capture());
+ // Verifies the added preference.
+ assertThat(captor.getValue().getKey()).isEqualTo(PREF_KEY);
+ }
+
+ @Test
+ public void testOnExpand_expandedIsFalse_removeSystemEntriesFromPreferenceGroup() {
+ doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+ doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(PREF_KEY);
+ mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry);
+ // Verifies the cache is empty first.
+ assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+
+ mBatteryChartPreferenceController.onExpand(/*isExpanded=*/ false);
+
+ verify(mAppListGroup).findPreference(PREF_KEY);
+ verify(mAppListGroup).removePreference(mPowerGaugePreference);
+ assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1);
+ }
+
private static Map<Long, List<BatteryHistEntry>> createBatteryHistoryMap(int size) {
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
for (int index = 0; index < size; index++) {
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
index f6b72d9..9b45a98 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
@@ -122,13 +122,13 @@
assertEquals(1, Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 10));
verify(mBackend, times(1))
- .resetDefaultNotificationAssistant(eq(true));
+ .setNASMigrationDoneAndResetDefault(eq(0), eq(true));
//Test user enable again, migration should not happen
mPreferenceController.setNotificationAssistantGranted(mNASComponent);
//Number of invocations should not increase
verify(mBackend, times(1))
- .resetDefaultNotificationAssistant(eq(true));
+ .setNASMigrationDoneAndResetDefault(eq(0), eq(true));
}
@Test
@@ -146,13 +146,13 @@
assertEquals(0, Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 20));
verify(mBackend, times(1))
- .resetDefaultNotificationAssistant(eq(true));
+ .setNASMigrationDoneAndResetDefault(eq(0), eq(true));
//Test user enable again, migration should not happen
mPreferenceController.setNotificationAssistantGranted(mNASComponent);
//Number of invocations should not increase
verify(mBackend, times(1))
- .resetDefaultNotificationAssistant(eq(true));
+ .setNASMigrationDoneAndResetDefault(eq(0), eq(true));
}
@Test
@@ -170,13 +170,13 @@
assertEquals(1, Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 10));
verify(mBackend, times(1))
- .resetDefaultNotificationAssistant(eq(false));
+ .setNASMigrationDoneAndResetDefault(eq(0), eq(false));
//Test user disable again, migration should not happen
mPreferenceController.setChecked(false);
//Number of invocations should not increase
verify(mBackend, times(1))
- .resetDefaultNotificationAssistant(eq(false));
+ .setNASMigrationDoneAndResetDefault(eq(0), eq(false));
}
}
diff --git a/tests/robotests/src/com/android/settings/uwb/UwbPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/uwb/UwbPreferenceControllerTest.java
new file mode 100644
index 0000000..00dc4df
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/uwb/UwbPreferenceControllerTest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.uwb;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.uwb.UwbManager;
+
+import com.android.settings.core.BasePreferenceController;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+/** Unit tests for UWB preference toggle. */
+@RunWith(RobolectricTestRunner.class)
+public class UwbPreferenceControllerTest {
+ @Rule
+ public MockitoRule rule = MockitoJUnit.rule();
+
+ private Context mContext;
+ private PackageManager mPackageManager;
+ private UwbPreferenceController mController;
+
+ @Mock
+ private UwbManager mUwbManager;
+
+ @Before
+ public void setUp() {
+ mContext = spy(RuntimeEnvironment.application);
+ mPackageManager = spy(mContext.getPackageManager());
+ mController = new UwbPreferenceController(mContext, "uwb_settings");
+ mController.mUwbManager = mUwbManager;
+ }
+
+ @Test
+ public void getAvailabilityStatus_uwbDisabled_shouldReturnDisabled() {
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(true).when(mPackageManager)
+ .hasSystemFeature(PackageManager.FEATURE_UWB);
+ mController.mAirplaneModeOn = true;
+
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING);
+ }
+
+ @Test
+ public void getAvailabilityStatus_uwbShown_shouldReturnAvailable() {
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(true).when(mPackageManager)
+ .hasSystemFeature(PackageManager.FEATURE_UWB);
+ mController.mAirplaneModeOn = false;
+
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_uwbNotShown_shouldReturnUnsupported() {
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(false).when(mPackageManager)
+ .hasSystemFeature(PackageManager.FEATURE_UWB);
+
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void onStateChanged_stateNotRegistered_shouldUpdate() {
+ mController.mRegisteredAdapterStateCallback = false;
+ mController.onStateChanged(UwbManager.AdapterStateCallback.STATE_DISABLED,
+ UwbManager.AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY);
+
+ assertThat(mController.isChecked()).isFalse();
+ }
+
+ @Test
+ public void onStateChanged_stateRegistered_shouldNotUpdate() {
+ mController.mRegisteredAdapterStateCallback = true;
+ mController.onStateChanged(UwbManager.AdapterStateCallback.STATE_ENABLED_INACTIVE,
+ UwbManager.AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY);
+
+ assertThat(mController.isChecked()).isTrue();
+ }
+
+ @Test
+ public void isChecked_uwbEnabledInactive_shouldReturnTrue() {
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(true).when(mPackageManager)
+ .hasSystemFeature(PackageManager.FEATURE_UWB);
+ mController.mRegisteredAdapterStateCallback = false;
+ mController.onStateChanged(UwbManager.AdapterStateCallback.STATE_ENABLED_INACTIVE,
+ UwbManager.AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY);
+
+ assertThat(mController.isChecked()).isTrue();
+ }
+
+ @Test
+ public void isChecked_uwbEnabledActive_shouldReturnTrue() {
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(true).when(mPackageManager)
+ .hasSystemFeature(PackageManager.FEATURE_UWB);
+ mController.mRegisteredAdapterStateCallback = false;
+ mController.onStateChanged(UwbManager.AdapterStateCallback.STATE_ENABLED_ACTIVE,
+ UwbManager.AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY);
+
+ assertThat(mController.isChecked()).isTrue();
+ }
+
+ @Test
+ public void isChecked_uwbDisabled_shouldReturnFalse() {
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(true).when(mPackageManager)
+ .hasSystemFeature(PackageManager.FEATURE_UWB);
+ mController.mRegisteredAdapterStateCallback = false;
+ mController.onStateChanged(UwbManager.AdapterStateCallback.STATE_DISABLED,
+ UwbManager.AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY);
+
+ assertThat(mController.isChecked()).isFalse();
+ }
+
+ @Test
+ public void setChecked_uwbDisabled_shouldEnableUwb() {
+ clearInvocations(mUwbManager);
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(true).when(mPackageManager)
+ .hasSystemFeature(PackageManager.FEATURE_UWB);
+
+ mController.setChecked(true);
+
+ verify(mUwbManager).setUwbEnabled(true);
+ verify(mUwbManager, never()).setUwbEnabled(false);
+ }
+
+ @Test
+ public void setChecked_uwbEnabled_shouldDisableUwb() {
+ clearInvocations(mUwbManager);
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(true).when(mPackageManager)
+ .hasSystemFeature(PackageManager.FEATURE_UWB);
+
+ mController.setChecked(false);
+
+ verify(mUwbManager).setUwbEnabled(false);
+ verify(mUwbManager, never()).setUwbEnabled(true);
+ }
+}
+
diff --git a/tests/unit/src/com/android/settings/network/telephony/Enable2gPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/Enable2gPreferenceControllerTest.java
index 293a19d..5ade979 100644
--- a/tests/unit/src/com/android/settings/network/telephony/Enable2gPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/Enable2gPreferenceControllerTest.java
@@ -48,6 +48,8 @@
@Mock
private TelephonyManager mTelephonyManager;
@Mock
+ private TelephonyManager mInvalidTelephonyManager;
+ @Mock
private CarrierConfigManager mCarrierConfigManager;
private PersistableBundle mPersistableBundle;
@@ -65,6 +67,8 @@
.thenReturn(mCarrierConfigManager);
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
+ doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mPersistableBundle = new PersistableBundle();
doReturn(mPersistableBundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
@@ -121,6 +125,18 @@
}
@Test
+ public void setChecked_invalidSubIdAndIsCheckedTrue_returnFalse() {
+ mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ assertThat(mController.setChecked(true)).isFalse();
+ }
+
+ @Test
+ public void setChecked_invalidSubIdAndIsCheckedFalse_returnFalse() {
+ mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ assertThat(mController.setChecked(false)).isFalse();
+ }
+
+ @Test
public void onPreferenceChange_update() {
// Set "Enable 2G" flag to "on"
when(mTelephonyManager.getAllowedNetworkTypesForReason(