Snap for 7306623 from 16f3036c4b to sc-release
Change-Id: Ib9280871b9dc7888d76c97769c089da0cae19209
This commit is contained in:
@@ -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>
|
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:layout_toRightOf="@id/filter_spinner"
|
android:layout_toEndOf="@id/filter_spinner"
|
||||||
android:contentDescription="@string/configure"
|
android:contentDescription="@string/configure"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:src="@drawable/ic_apps_filter_settings_24dp"
|
android:src="@drawable/ic_apps_filter_settings_24dp"
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -446,12 +446,4 @@
|
|||||||
<dimen name="chartview_trapezoid_radius">2dp</dimen>
|
<dimen name="chartview_trapezoid_radius">2dp</dimen>
|
||||||
<dimen name="chartview_trapezoid_margin_start">1dp</dimen>
|
<dimen name="chartview_trapezoid_margin_start">1dp</dimen>
|
||||||
<dimen name="chartview_trapezoid_margin_bottom">2dp</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>
|
</resources>
|
||||||
|
|||||||
@@ -4121,7 +4121,7 @@
|
|||||||
<!-- Description text for Bluetooth always scanning -->
|
<!-- 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>
|
<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 -->
|
<!-- [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 -->
|
<!-- [CHAR LIMIT=60] Location Services screen, screen title -->
|
||||||
<string name="location_services_screen_title">Location Services</string>
|
<string name="location_services_screen_title">Location Services</string>
|
||||||
<!-- [CHAR LIMIT=50] Location settings screen, sub category for location services for managed profile -->
|
<!-- [CHAR LIMIT=50] Location settings screen, sub category for location services for managed profile -->
|
||||||
@@ -6255,8 +6255,39 @@
|
|||||||
<string name ="battery_detail_info_title">Since full charge</string>
|
<string name ="battery_detail_info_title">Since full charge</string>
|
||||||
<!-- Title for the battery management group [CHAR LIMIT=40] -->
|
<!-- Title for the battery management group [CHAR LIMIT=40] -->
|
||||||
<string name ="battery_detail_manage_title">Manage battery usage</string>
|
<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] -->
|
<!-- 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>
|
<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] -->
|
<!-- 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>
|
<string name="advanced_battery_graph_subtext">Battery left estimate is based on your device usage</string>
|
||||||
@@ -13187,4 +13218,13 @@
|
|||||||
|
|
||||||
<!-- Label for button to not allow grant the permission for remote devices. [CHAR_LIMIT=50] -->
|
<!-- 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>
|
<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>
|
</resources>
|
||||||
|
|||||||
@@ -787,7 +787,7 @@
|
|||||||
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
|
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
|
||||||
</style>
|
</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_width">wrap_content</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
<item name="android:layout_marginBottom">@dimen/homepage_title_margin_bottom</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:textSize">16sp</item>
|
||||||
<item name="android:textColor">?android:attr/textColorSecondary</item>
|
<item name="android:textColor">?android:attr/textColorSecondary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ToolbarText.Collapsed" parent="CollapsingToolbarTitle.Collapsed"/>
|
|
||||||
<style name="ToolbarText.Expanded" parent="CollapsingToolbarTitle"/>
|
|
||||||
<style name="ToolbarText.MoreThanTwoLines" parent="CollapsingToolbarTitle.MoreThanTwoLines"/>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
|
|
||||||
<style name="PreferenceTheme.SetupWizard" parent="@style/SettingsPreferenceTheme">
|
<style name="PreferenceTheme.SetupWizard" parent="@style/SettingsPreferenceTheme">
|
||||||
<item name="preferenceFragmentCompatStyle">@style/SetupWizardPreferenceFragmentStyle</item>
|
<item name="preferenceFragmentCompatStyle">@style/SetupWizardPreferenceFragmentStyle</item>
|
||||||
<item name="preferenceStyle">@style/Preference.Material</item>
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ApnPreference" parent="@style/Preference.Material">
|
<style name="ApnPreference" parent="@style/Preference.Material">
|
||||||
|
|||||||
@@ -272,5 +272,7 @@
|
|||||||
<style name="Theme.NotificationHistory" parent="@android:style/Theme.DeviceDefault.DayNight">
|
<style name="Theme.NotificationHistory" parent="@android:style/Theme.DeviceDefault.DayNight">
|
||||||
<item name="android:windowActionBar">false</item>
|
<item name="android:windowActionBar">false</item>
|
||||||
<item name="android:windowNoTitle">true</item>
|
<item name="android:windowNoTitle">true</item>
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<com.android.settings.widget.SettingsMainSwitchPreference
|
<com.android.settings.widget.SettingsMainSwitchPreference
|
||||||
android:key="block" />
|
android:key="block" />
|
||||||
|
|
||||||
<com.android.settings.notification.app.NotificationFooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:key="block_desc" />
|
android:key="block_desc" />
|
||||||
|
|
||||||
|
|
||||||
@@ -96,11 +96,11 @@
|
|||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<com.android.settings.notification.app.NotificationFooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:key="desc"
|
android:key="desc"
|
||||||
android:order="5000" />
|
android:order="5000" />
|
||||||
|
|
||||||
<com.android.settings.notification.app.NotificationFooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:key="deleted"
|
android:key="deleted"
|
||||||
android:order="8000" />
|
android:order="8000" />
|
||||||
|
|
||||||
|
|||||||
@@ -116,11 +116,11 @@
|
|||||||
android:title="@string/app_settings_link"
|
android:title="@string/app_settings_link"
|
||||||
settings:allowDividerAbove="true"/>
|
settings:allowDividerAbove="true"/>
|
||||||
|
|
||||||
<com.android.settings.notification.app.NotificationFooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:key="desc"
|
android:key="desc"
|
||||||
android:order="100"/>
|
android:order="100"/>
|
||||||
|
|
||||||
<com.android.settings.notification.app.NotificationFooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:key="block_desc"
|
android:key="block_desc"
|
||||||
android:order="110"
|
android:order="110"
|
||||||
settings:allowDividerAbove="false"/>
|
settings:allowDividerAbove="false"/>
|
||||||
|
|||||||
@@ -65,6 +65,13 @@
|
|||||||
android:icon="@drawable/ic_folder_vd_theme_24"
|
android:icon="@drawable/ic_folder_vd_theme_24"
|
||||||
android:title="@string/bluetooth_show_files_received_via_bluetooth"/>
|
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
|
<PreferenceCategory
|
||||||
android:key="dashboard_tile_placeholder"
|
android:key="dashboard_tile_placeholder"
|
||||||
android:order="-8"/>
|
android:order="-8"/>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
android:summary="@string/demote_conversation_summary"
|
android:summary="@string/demote_conversation_summary"
|
||||||
settings:allowDividerAbove="true"/>
|
settings:allowDividerAbove="true"/>
|
||||||
|
|
||||||
<com.android.settings.notification.app.NotificationFooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:key="block_desc"
|
android:key="block_desc"
|
||||||
settings:allowDividerAbove="false"/>
|
settings:allowDividerAbove="false"/>
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
<Preference
|
<Preference
|
||||||
android:fragment="com.android.settings.location.LocationServices"
|
android:fragment="com.android.settings.location.LocationServices"
|
||||||
android:key="location_services"
|
android:key="location_services"
|
||||||
android:icon="@drawable/baseline_near_me"
|
android:icon="@drawable/ic_chevron_right_24dp"
|
||||||
android:title="@string/location_services_preference_title"
|
android:title="@string/location_services_preference_title"
|
||||||
settings:controller="com.android.settings.location.LocationServicesPreferenceController"/>
|
settings:controller="com.android.settings.location.LocationServicesPreferenceController"/>
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,9 @@
|
|||||||
android:title="@string/app_settings_link"
|
android:title="@string/app_settings_link"
|
||||||
settings:allowDividerAbove="true"/>
|
settings:allowDividerAbove="true"/>
|
||||||
|
|
||||||
<com.android.settings.notification.NotificationFooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:key="desc" />
|
android:key="desc" />
|
||||||
|
|
||||||
<com.android.settings.notification.NotificationFooterPreference
|
<com.android.settingslib.widget.FooterPreference
|
||||||
android:key="block_desc" />
|
android:key="block_desc" />
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import android.content.res.TypedArray;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.text.style.ImageSpan;
|
import android.text.style.ImageSpan;
|
||||||
@@ -320,8 +321,13 @@ public class AccessibilityEditDialogUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static CharSequence retrieveSummary(Context context, int lineHeight) {
|
private static CharSequence retrieveSummary(Context context, int lineHeight) {
|
||||||
return AccessibilityUtil.isFloatingMenuEnabled(context)
|
final SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||||
? getSummaryStringWithLink(context) : getSummaryStringWithIcon(context, lineHeight);
|
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) {
|
private static int retrieveSoftwareShortcutImageResId(Context context) {
|
||||||
@@ -330,7 +336,7 @@ public class AccessibilityEditDialogUtils {
|
|||||||
: R.drawable.accessibility_shortcut_type_software;
|
: 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)
|
final View.OnClickListener linkListener = v -> new SubSettingLauncher(context)
|
||||||
.setDestination(AccessibilityButtonFragment.class.getName())
|
.setDestination(AccessibilityButtonFragment.class.getName())
|
||||||
.setSourceMetricsCategory(
|
.setSourceMetricsCategory(
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package com.android.settings.biometrics;
|
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.annotation.NonNull;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
@@ -24,6 +27,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.hardware.biometrics.BiometricManager;
|
import android.hardware.biometrics.BiometricManager;
|
||||||
import android.hardware.biometrics.BiometricManager.Authenticators;
|
import android.hardware.biometrics.BiometricManager.Authenticators;
|
||||||
|
import android.hardware.biometrics.BiometricManager.BiometricError;
|
||||||
import android.hardware.face.FaceManager;
|
import android.hardware.face.FaceManager;
|
||||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||||
import android.hardware.fingerprint.FingerprintManager;
|
import android.hardware.fingerprint.FingerprintManager;
|
||||||
@@ -31,11 +35,11 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SetupWizardUtils;
|
import com.android.settings.SetupWizardUtils;
|
||||||
@@ -68,12 +72,14 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
|||||||
public static final String EXTRA_SKIP_INTRO = "skip_intro";
|
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_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";
|
private static final String SAVED_STATE_GK_PW_HANDLE = "gk_pw_handle";
|
||||||
|
|
||||||
public static final class InternalActivity extends BiometricEnrollActivity {}
|
public static final class InternalActivity extends BiometricEnrollActivity {}
|
||||||
|
|
||||||
private int mUserId = UserHandle.myUserId();
|
private int mUserId = UserHandle.myUserId();
|
||||||
private boolean mConfirmingCredentials;
|
private boolean mConfirmingCredentials;
|
||||||
|
private boolean mIsEnrollActionLogged;
|
||||||
private boolean mIsFaceEnrollable;
|
private boolean mIsFaceEnrollable;
|
||||||
private boolean mIsFingerprintEnrollable;
|
private boolean mIsFingerprintEnrollable;
|
||||||
@Nullable private Long mGkPwHandle;
|
@Nullable private Long mGkPwHandle;
|
||||||
@@ -91,15 +97,44 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
mConfirmingCredentials = savedInstanceState
|
mConfirmingCredentials = savedInstanceState.getBoolean(
|
||||||
.getBoolean(SAVED_STATE_CONFIRMING_CREDENTIALS, false);
|
SAVED_STATE_CONFIRMING_CREDENTIALS, false);
|
||||||
|
mIsEnrollActionLogged = savedInstanceState.getBoolean(
|
||||||
|
SAVED_STATE_ENROLL_ACTION_LOGGED, false);
|
||||||
if (savedInstanceState.containsKey(SAVED_STATE_GK_PW_HANDLE)) {
|
if (savedInstanceState.containsKey(SAVED_STATE_GK_PW_HANDLE)) {
|
||||||
mGkPwHandle = savedInstanceState.getLong(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();
|
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) {
|
if (intent.getStringExtra(WizardManagerHelper.EXTRA_THEME) == null) {
|
||||||
intent.putExtra(
|
intent.putExtra(
|
||||||
WizardManagerHelper.EXTRA_THEME,
|
WizardManagerHelper.EXTRA_THEME,
|
||||||
@@ -108,7 +143,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
|||||||
|
|
||||||
// Default behavior is to enroll BIOMETRIC_WEAK or above. See ACTION_BIOMETRIC_ENROLL.
|
// Default behavior is to enroll BIOMETRIC_WEAK or above. See ACTION_BIOMETRIC_ENROLL.
|
||||||
final int authenticators = intent.getIntExtra(
|
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);
|
Log.d(TAG, "Authenticators: " + authenticators);
|
||||||
|
|
||||||
@@ -132,7 +167,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
|||||||
} else {
|
} else {
|
||||||
// If the caller is not setup wizard, and the user has something enrolled, finish.
|
// If the caller is not setup wizard, and the user has something enrolled, finish.
|
||||||
final BiometricManager bm = getSystemService(BiometricManager.class);
|
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) {
|
if (result != BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
|
||||||
Log.e(TAG, "Unexpected result: " + result);
|
Log.e(TAG, "Unexpected result: " + result);
|
||||||
finish();
|
finish();
|
||||||
@@ -159,6 +194,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
|||||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
outState.putBoolean(SAVED_STATE_CONFIRMING_CREDENTIALS, mConfirmingCredentials);
|
outState.putBoolean(SAVED_STATE_CONFIRMING_CREDENTIALS, mConfirmingCredentials);
|
||||||
|
outState.putBoolean(SAVED_STATE_ENROLL_ACTION_LOGGED, mIsEnrollActionLogged);
|
||||||
if (mGkPwHandle != null) {
|
if (mGkPwHandle != null) {
|
||||||
outState.putLong(SAVED_STATE_GK_PW_HANDLE, mGkPwHandle);
|
outState.putLong(SAVED_STATE_GK_PW_HANDLE, mGkPwHandle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ import com.android.settingslib.drawer.Tile;
|
|||||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -61,7 +59,6 @@ public class SettingsBaseActivity extends FragmentActivity {
|
|||||||
protected static final boolean DEBUG_TIMING = false;
|
protected static final boolean DEBUG_TIMING = false;
|
||||||
private static final String TAG = "SettingsBaseActivity";
|
private static final String TAG = "SettingsBaseActivity";
|
||||||
private static final String DATA_SCHEME_PKG = "package";
|
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
|
// Serves as a temporary list of tiles to ignore until we heard back from the PM that they
|
||||||
// are disabled.
|
// are disabled.
|
||||||
@@ -95,7 +92,7 @@ public class SettingsBaseActivity extends FragmentActivity {
|
|||||||
|
|
||||||
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME)
|
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME)
|
||||||
&& isToolbarEnabled() && !isAnySetupWizard) {
|
&& isToolbarEnabled() && !isAnySetupWizard) {
|
||||||
super.setContentView(R.layout.settings_collapsing_base_layout);
|
super.setContentView(R.layout.collapsing_toolbar_base_layout);
|
||||||
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
|
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
|
||||||
} else {
|
} else {
|
||||||
super.setContentView(R.layout.settings_base_layout);
|
super.setContentView(R.layout.settings_base_layout);
|
||||||
@@ -108,7 +105,6 @@ public class SettingsBaseActivity extends FragmentActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setActionBar(toolbar);
|
setActionBar(toolbar);
|
||||||
initCollapsingToolbar();
|
|
||||||
|
|
||||||
if (DEBUG_TIMING) {
|
if (DEBUG_TIMING) {
|
||||||
Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) + " ms");
|
Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) + " ms");
|
||||||
@@ -207,50 +203,6 @@ public class SettingsBaseActivity extends FragmentActivity {
|
|||||||
return true;
|
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) {
|
private void onCategoriesChanged(Set<String> categories) {
|
||||||
final int N = mCategoryListeners.size();
|
final int N = mCategoryListeners.size();
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ public abstract class DevelopmentTiles extends TileService {
|
|||||||
mContext = getApplicationContext();
|
mContext = getApplicationContext();
|
||||||
mSensorPrivacyManager = (SensorPrivacyManager) mContext.getSystemService(
|
mSensorPrivacyManager = (SensorPrivacyManager) mContext.getSystemService(
|
||||||
Context.SENSOR_PRIVACY_SERVICE);
|
Context.SENSOR_PRIVACY_SERVICE);
|
||||||
mIsEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled();
|
mIsEnabled = mSensorPrivacyManager.isAllSensorPrivacyEnabled();
|
||||||
mMetricsFeatureProvider = FeatureFactory.getFactory(
|
mMetricsFeatureProvider = FeatureFactory.getFactory(
|
||||||
mContext).getMetricsFeatureProvider();
|
mContext).getMetricsFeatureProvider();
|
||||||
mKeyguardManager = (KeyguardManager) mContext.getSystemService(
|
mKeyguardManager = (KeyguardManager) mContext.getSystemService(
|
||||||
@@ -392,7 +392,7 @@ public abstract class DevelopmentTiles extends TileService {
|
|||||||
mMetricsFeatureProvider.action(getApplicationContext(), SettingsEnums.QS_SENSOR_PRIVACY,
|
mMetricsFeatureProvider.action(getApplicationContext(), SettingsEnums.QS_SENSOR_PRIVACY,
|
||||||
isEnabled);
|
isEnabled);
|
||||||
mIsEnabled = isEnabled;
|
mIsEnabled = isEnabled;
|
||||||
mSensorPrivacyManager.setSensorPrivacy(isEnabled);
|
mSensorPrivacyManager.setAllSensorPrivacy(isEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class AdaptiveSleepCameraStatePreferenceController {
|
|||||||
mPreference.setPositiveButtonText(R.string.allow);
|
mPreference.setPositiveButtonText(R.string.allow);
|
||||||
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
||||||
mPrivacyManager.addSensorPrivacyListener(CAMERA,
|
mPrivacyManager.addSensorPrivacyListener(CAMERA,
|
||||||
enabled -> updateVisibility());
|
(sensor, enabled) -> updateVisibility());
|
||||||
mPreference.setPositiveButtonOnClickListener(p -> {
|
mPreference.setPositiveButtonOnClickListener(p -> {
|
||||||
mPrivacyManager.setSensorPrivacy(CAMERA, false);
|
mPrivacyManager.setSensorPrivacy(CAMERA, false);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -111,9 +111,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
|||||||
mPrivacyPreference.setLayoutResource(R.layout.preference_footer);
|
mPrivacyPreference.setLayoutResource(R.layout.preference_footer);
|
||||||
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
||||||
mPrivacyManager.addSensorPrivacyListener(CAMERA,
|
mPrivacyManager.addSensorPrivacyListener(CAMERA,
|
||||||
enabled -> {
|
(sensor, enabled) -> mAdaptiveSleepController.updatePreference());
|
||||||
mAdaptiveSleepController.updatePreference();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class SmartAutoRotateCameraStateController extends BasePreferenceControll
|
|||||||
public SmartAutoRotateCameraStateController(Context context, String key) {
|
public SmartAutoRotateCameraStateController(Context context, String key) {
|
||||||
super(context, key);
|
super(context, key);
|
||||||
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
||||||
mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> {
|
mPrivacyManager.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> {
|
||||||
mPreference.setVisible(enabled);
|
mPreference.setVisible(enabled);
|
||||||
updateState(mPreference);
|
updateState(mPreference);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
|
|||||||
super(context, preferenceKey);
|
super(context, preferenceKey);
|
||||||
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||||
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
||||||
mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> updateState(mPreference));
|
mPrivacyManager
|
||||||
|
.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> updateState(mPreference));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.os.Bundle;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.text.format.DateUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
@@ -282,20 +283,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
|
|
||||||
final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
|
final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
|
||||||
final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
|
final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
|
||||||
final long totalTimeMs = foregroundTimeMs + backgroundTimeMs;
|
//TODO(b/178197718) Update layout to support multiple lines
|
||||||
//TODO(b/178197718) Refine the layout
|
controller.setSummary(getAppActiveTime(foregroundTimeMs, backgroundTimeMs));
|
||||||
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)));
|
|
||||||
|
|
||||||
controller.done(context, true /* rebindActions */);
|
controller.done(context, true /* rebindActions */);
|
||||||
}
|
}
|
||||||
@@ -388,4 +377,53 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
private void updatePreferenceState(RadioButtonPreference preference, String selectedKey) {
|
private void updatePreferenceState(RadioButtonPreference preference, String selectedKey) {
|
||||||
preference.setChecked(selectedKey.equals(preference.getKey()));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.fuelgauge;
|
package com.android.settings.fuelgauge;
|
||||||
@@ -51,7 +50,7 @@ import java.util.Map;
|
|||||||
/** Controls the update for chart graph and the list items. */
|
/** Controls the update for chart graph and the list items. */
|
||||||
public class BatteryChartPreferenceController extends AbstractPreferenceController
|
public class BatteryChartPreferenceController extends AbstractPreferenceController
|
||||||
implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnDestroy,
|
implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnDestroy,
|
||||||
BatteryChartView.OnSelectListener {
|
BatteryChartView.OnSelectListener, ExpandDividerPreference.OnExpandListener {
|
||||||
private static final String TAG = "BatteryChartPreferenceController";
|
private static final String TAG = "BatteryChartPreferenceController";
|
||||||
private static final int CHART_KEY_ARRAY_SIZE = 25;
|
private static final int CHART_KEY_ARRAY_SIZE = 25;
|
||||||
private static final int CHART_LEVEL_ARRAY_SIZE = 13;
|
private static final int CHART_LEVEL_ARRAY_SIZE = 13;
|
||||||
@@ -65,6 +64,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
@VisibleForTesting BatteryUtils mBatteryUtils;
|
@VisibleForTesting BatteryUtils mBatteryUtils;
|
||||||
@VisibleForTesting PreferenceGroup mAppListPrefGroup;
|
@VisibleForTesting PreferenceGroup mAppListPrefGroup;
|
||||||
@VisibleForTesting BatteryChartView mBatteryChartView;
|
@VisibleForTesting BatteryChartView mBatteryChartView;
|
||||||
|
@VisibleForTesting ExpandDividerPreference mExpandDividerPreference;
|
||||||
|
|
||||||
@VisibleForTesting int[] mBatteryHistoryLevels;
|
@VisibleForTesting int[] mBatteryHistoryLevels;
|
||||||
@VisibleForTesting long[] mBatteryHistoryKeys;
|
@VisibleForTesting long[] mBatteryHistoryKeys;
|
||||||
@@ -76,9 +76,13 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||||
private final CharSequence[] mNotAllowShowSummaryPackages;
|
private final CharSequence[] mNotAllowShowSummaryPackages;
|
||||||
|
|
||||||
|
private boolean mIsExpanded = false;
|
||||||
|
|
||||||
// Preference cache to avoid create new instance each time.
|
// Preference cache to avoid create new instance each time.
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final Map<String, Preference> mPreferenceCache = new HashMap<>();
|
final Map<String, Preference> mPreferenceCache = new HashMap<>();
|
||||||
|
@VisibleForTesting
|
||||||
|
final List<BatteryDiffEntry> mSystemEntries = new ArrayList<>();
|
||||||
|
|
||||||
public BatteryChartPreferenceController(
|
public BatteryChartPreferenceController(
|
||||||
Context context, String preferenceKey,
|
Context context, String preferenceKey,
|
||||||
@@ -163,6 +167,12 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
refreshUi(trapezoidIndex, /*isForce=*/ false);
|
refreshUi(trapezoidIndex, /*isForce=*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExpand(boolean isExpanded) {
|
||||||
|
mIsExpanded = isExpanded;
|
||||||
|
refreshExpandUi();
|
||||||
|
}
|
||||||
|
|
||||||
void setBatteryHistoryMap(
|
void setBatteryHistoryMap(
|
||||||
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
|
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
|
||||||
mHandler.post(() -> setBatteryHistoryMapInner(batteryHistoryMap));
|
mHandler.post(() -> setBatteryHistoryMapInner(batteryHistoryMap));
|
||||||
@@ -266,10 +276,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
}
|
}
|
||||||
// Separates data into two groups and sort them individually.
|
// Separates data into two groups and sort them individually.
|
||||||
final List<BatteryDiffEntry> appEntries = new ArrayList<>();
|
final List<BatteryDiffEntry> appEntries = new ArrayList<>();
|
||||||
final List<BatteryDiffEntry> systemEntries = new ArrayList<>();
|
mSystemEntries.clear();
|
||||||
entries.forEach(entry -> {
|
entries.forEach(entry -> {
|
||||||
if (entry.isSystemEntry()) {
|
if (entry.isSystemEntry()) {
|
||||||
systemEntries.add(entry);
|
mSystemEntries.add(entry);
|
||||||
} else {
|
} else {
|
||||||
appEntries.add(entry);
|
appEntries.add(entry);
|
||||||
}
|
}
|
||||||
@@ -279,11 +289,25 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
Collections.sort(appEntries, BatteryDiffEntry.COMPARATOR);
|
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",
|
Log.d(TAG, String.format("addAllPreferences() app=%d system=%d",
|
||||||
appEntries.size(), systemEntries.size()));
|
appEntries.size(), mSystemEntries.size()));
|
||||||
addPreferenceToScreen(appEntries);
|
|
||||||
addPreferenceToScreen(systemEntries);
|
// 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
|
@VisibleForTesting
|
||||||
@@ -337,6 +361,22 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
|||||||
mAppListPrefGroup.removeAll();
|
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
|
@VisibleForTesting
|
||||||
void setPreferenceSummary(
|
void setPreferenceSummary(
|
||||||
PowerGaugePreference preference, BatteryDiffEntry entry) {
|
PowerGaugePreference preference, BatteryDiffEntry entry) {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class Enable2gPreferenceController extends TelephonyTogglePreferenceContr
|
|||||||
public int getAvailabilityStatus(int subId) {
|
public int getAvailabilityStatus(int subId) {
|
||||||
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
|
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
|
||||||
boolean visible =
|
boolean visible =
|
||||||
subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
SubscriptionManager.isUsableSubscriptionId(subId)
|
||||||
&& carrierConfig != null
|
&& carrierConfig != null
|
||||||
&& !carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENABLE_2G)
|
&& !carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENABLE_2G)
|
||||||
&& mTelephonyManager.isRadioInterfaceCapabilitySupported(
|
&& mTelephonyManager.isRadioInterfaceCapabilitySupported(
|
||||||
@@ -89,6 +89,9 @@ public class Enable2gPreferenceController extends TelephonyTogglePreferenceContr
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setChecked(boolean isChecked) {
|
public boolean setChecked(boolean isChecked) {
|
||||||
|
if (!SubscriptionManager.isUsableSubscriptionId(mSubId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
long currentlyAllowedNetworkTypes = mTelephonyManager.getAllowedNetworkTypesForReason(
|
long currentlyAllowedNetworkTypes = mTelephonyManager.getAllowedNetworkTypesForReason(
|
||||||
mTelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G);
|
mTelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G);
|
||||||
boolean enabled = (currentlyAllowedNetworkTypes & BITMASK_2G) != 0;
|
boolean enabled = (currentlyAllowedNetworkTypes & BITMASK_2G) != 0;
|
||||||
|
|||||||
@@ -77,11 +77,7 @@ public class NotificationAssistantPreferenceController extends TogglePreferenceC
|
|||||||
protected void setNotificationAssistantGranted(ComponentName cn) {
|
protected void setNotificationAssistantGranted(ComponentName cn) {
|
||||||
if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||||
Settings.Secure.NAS_SETTINGS_UPDATED, 0, mUserId) == 0) {
|
Settings.Secure.NAS_SETTINGS_UPDATED, 0, mUserId) == 0) {
|
||||||
for (int profileId : mUserManager.getProfileIds(mUserId, false)) {
|
mNotificationBackend.setNASMigrationDoneAndResetDefault(mUserId, cn != null);
|
||||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
|
||||||
Settings.Secure.NAS_SETTINGS_UPDATED, 1, profileId);
|
|
||||||
}
|
|
||||||
mNotificationBackend.resetDefaultNotificationAssistant(cn != null);
|
|
||||||
}
|
}
|
||||||
mNotificationBackend.setNotificationAssistantGranted(cn);
|
mNotificationBackend.setNotificationAssistantGranted(cn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -570,9 +570,9 @@ public class NotificationBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetDefaultNotificationAssistant(boolean loadFromConfig) {
|
public void setNASMigrationDoneAndResetDefault(int userId, boolean loadFromConfig) {
|
||||||
try {
|
try {
|
||||||
sINM.resetDefaultNotificationAssistant(loadFromConfig);
|
sINM.setNASMigrationDoneAndResetDefault(userId, loadFromConfig);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(TAG, "Error calling NoMan", e);
|
Log.w(TAG, "Error calling NoMan", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
168
src/com/android/settings/uwb/UwbPreferenceController.java
Normal file
168
src/com/android/settings/uwb/UwbPreferenceController.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -249,14 +249,122 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInitHeader_hasCorrectSummary() {
|
public void testInitHeader_noUsageTime_hasCorrectSummary() {
|
||||||
mFragment.mAppEntry = null;
|
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();
|
mFragment.initHeader();
|
||||||
|
|
||||||
ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
|
ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
|
||||||
verify(mEntityHeaderController).setSummary(captor.capture());
|
verify(mEntityHeaderController).setSummary(captor.capture());
|
||||||
assertThat(captor.getValue().toString())
|
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
|
@Test
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import com.android.settings.testutils.FakeFeatureFactory;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
@@ -416,23 +417,56 @@ public final class BatteryChartPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateSlotTimestamp_returnExpectedResult() {
|
public void testValidateSlotTimestamp_returnExpectedResult() {
|
||||||
final List<Long> slotTimestampList =
|
final ArrayList<Long> slotTimestampList = new ArrayList<Long>(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
Long.valueOf(0),
|
Long.valueOf(0),
|
||||||
Long.valueOf(DateUtils.HOUR_IN_MILLIS),
|
Long.valueOf(DateUtils.HOUR_IN_MILLIS),
|
||||||
Long.valueOf(DateUtils.HOUR_IN_MILLIS * 2 + DateUtils.MINUTE_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.
|
// Verifies the testing data is correct before we added invalid data into it.
|
||||||
assertThat(BatteryChartPreferenceController.validateSlotTimestamp(slotTimestampList))
|
assertThat(BatteryChartPreferenceController.validateSlotTimestamp(slotTimestampList))
|
||||||
.isTrue();
|
.isTrue();
|
||||||
|
|
||||||
// Insert invalid timestamp into the list.
|
// Insert invalid timestamp into the list.
|
||||||
slotTimestampList.add(
|
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))
|
assertThat(BatteryChartPreferenceController.validateSlotTimestamp(slotTimestampList))
|
||||||
.isFalse();
|
.isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnExpand_expandedIsTrue_addSystemEntriesToPreferenceGroup() {
|
||||||
|
final String prefKey = "preference_key";
|
||||||
|
doReturn(1).when(mAppListGroup).getPreferenceCount();
|
||||||
|
mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry);
|
||||||
|
doReturn("label").when(mBatteryDiffEntry).getAppLabel();
|
||||||
|
doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
|
||||||
|
doReturn(prefKey).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(prefKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnExpand_expandedIsFalse_removeSystemEntriesFromPreferenceGroup() {
|
||||||
|
final String prefKey = "preference_key";
|
||||||
|
doReturn(prefKey).when(mBatteryHistEntry).getKey();
|
||||||
|
doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(prefKey);
|
||||||
|
mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry);
|
||||||
|
// Verifies the cache is empty first.
|
||||||
|
assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
|
||||||
|
|
||||||
|
mBatteryChartPreferenceController.onExpand(/*isExpanded=*/ false);
|
||||||
|
|
||||||
|
verify(mAppListGroup).findPreference(prefKey);
|
||||||
|
verify(mAppListGroup).removePreference(mPowerGaugePreference);
|
||||||
|
assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
private static Map<Long, List<BatteryHistEntry>> createBatteryHistoryMap(int size) {
|
private static Map<Long, List<BatteryHistEntry>> createBatteryHistoryMap(int size) {
|
||||||
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
|
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
|
||||||
for (int index = 0; index < size; index++) {
|
for (int index = 0; index < size; index++) {
|
||||||
|
|||||||
@@ -122,13 +122,13 @@ public class NotificationAssistantPreferenceControllerTest {
|
|||||||
assertEquals(1, Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
assertEquals(1, Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||||
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 10));
|
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 10));
|
||||||
verify(mBackend, times(1))
|
verify(mBackend, times(1))
|
||||||
.resetDefaultNotificationAssistant(eq(true));
|
.setNASMigrationDoneAndResetDefault(eq(0), eq(true));
|
||||||
|
|
||||||
//Test user enable again, migration should not happen
|
//Test user enable again, migration should not happen
|
||||||
mPreferenceController.setNotificationAssistantGranted(mNASComponent);
|
mPreferenceController.setNotificationAssistantGranted(mNASComponent);
|
||||||
//Number of invocations should not increase
|
//Number of invocations should not increase
|
||||||
verify(mBackend, times(1))
|
verify(mBackend, times(1))
|
||||||
.resetDefaultNotificationAssistant(eq(true));
|
.setNASMigrationDoneAndResetDefault(eq(0), eq(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -146,13 +146,13 @@ public class NotificationAssistantPreferenceControllerTest {
|
|||||||
assertEquals(0, Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
assertEquals(0, Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||||
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 20));
|
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 20));
|
||||||
verify(mBackend, times(1))
|
verify(mBackend, times(1))
|
||||||
.resetDefaultNotificationAssistant(eq(true));
|
.setNASMigrationDoneAndResetDefault(eq(0), eq(true));
|
||||||
|
|
||||||
//Test user enable again, migration should not happen
|
//Test user enable again, migration should not happen
|
||||||
mPreferenceController.setNotificationAssistantGranted(mNASComponent);
|
mPreferenceController.setNotificationAssistantGranted(mNASComponent);
|
||||||
//Number of invocations should not increase
|
//Number of invocations should not increase
|
||||||
verify(mBackend, times(1))
|
verify(mBackend, times(1))
|
||||||
.resetDefaultNotificationAssistant(eq(true));
|
.setNASMigrationDoneAndResetDefault(eq(0), eq(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -170,13 +170,13 @@ public class NotificationAssistantPreferenceControllerTest {
|
|||||||
assertEquals(1, Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
assertEquals(1, Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||||
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 10));
|
Settings.Secure.NAS_SETTINGS_UPDATED, 0, 10));
|
||||||
verify(mBackend, times(1))
|
verify(mBackend, times(1))
|
||||||
.resetDefaultNotificationAssistant(eq(false));
|
.setNASMigrationDoneAndResetDefault(eq(0), eq(false));
|
||||||
|
|
||||||
//Test user disable again, migration should not happen
|
//Test user disable again, migration should not happen
|
||||||
mPreferenceController.setChecked(false);
|
mPreferenceController.setChecked(false);
|
||||||
//Number of invocations should not increase
|
//Number of invocations should not increase
|
||||||
verify(mBackend, times(1))
|
verify(mBackend, times(1))
|
||||||
.resetDefaultNotificationAssistant(eq(false));
|
.setNASMigrationDoneAndResetDefault(eq(0), eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -48,6 +48,8 @@ public final class Enable2gPreferenceControllerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private TelephonyManager mTelephonyManager;
|
private TelephonyManager mTelephonyManager;
|
||||||
@Mock
|
@Mock
|
||||||
|
private TelephonyManager mInvalidTelephonyManager;
|
||||||
|
@Mock
|
||||||
private CarrierConfigManager mCarrierConfigManager;
|
private CarrierConfigManager mCarrierConfigManager;
|
||||||
|
|
||||||
private PersistableBundle mPersistableBundle;
|
private PersistableBundle mPersistableBundle;
|
||||||
@@ -65,6 +67,8 @@ public final class Enable2gPreferenceControllerTest {
|
|||||||
.thenReturn(mCarrierConfigManager);
|
.thenReturn(mCarrierConfigManager);
|
||||||
|
|
||||||
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
|
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
|
||||||
|
doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
|
||||||
|
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||||
|
|
||||||
mPersistableBundle = new PersistableBundle();
|
mPersistableBundle = new PersistableBundle();
|
||||||
doReturn(mPersistableBundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
|
doReturn(mPersistableBundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
|
||||||
@@ -120,6 +124,18 @@ public final class Enable2gPreferenceControllerTest {
|
|||||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void onPreferenceChange_update() {
|
public void onPreferenceChange_update() {
|
||||||
// Set "Enable 2G" flag to "on"
|
// Set "Enable 2G" flag to "on"
|
||||||
|
|||||||
Reference in New Issue
Block a user