Snap for 5289249 from 175b7b9256 to qt-release
Change-Id: I383863d634137a3a802541cd4e0aeb19b96234e8
This commit is contained in:
@@ -1246,6 +1246,17 @@
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<activity android:name="Settings$PrivacyDashboardActivity"
|
||||
android:label="@string/privacy_dashboard_title"
|
||||
android:icon="@drawable/ic_settings_privacy">
|
||||
<intent-filter>
|
||||
<action android:name="android.settings.PRIVACY_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.privacy.PrivacyDashboardFragment" />
|
||||
</activity>
|
||||
|
||||
<activity android:name="SetFullBackupPassword"
|
||||
android:label="@string/local_backup_password_title"
|
||||
android:exported="false" />
|
||||
@@ -2792,10 +2803,6 @@
|
||||
<activity android:name=".backup.UserBackupSettingsActivity"
|
||||
android:label="@string/privacy_settings_title"
|
||||
android:icon="@drawable/ic_settings_backup">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.PRIVACY_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
109
res/layout/preference_balance_slider.xml
Normal file
109
res/layout/preference_balance_slider.xml
Normal file
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2019 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:clickable="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/icon_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="56dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp">
|
||||
<com.android.internal.widget.PreferenceImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@*android:style/TextAppearance.Material.Subhead"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
<LinearLayout
|
||||
android:id="@android:id/widget_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.android.settings.accessibility.BalanceSeekBar
|
||||
android:id="@*android:id/seekbar"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/left_text"
|
||||
android:text="@string/accessibility_toggle_master_balance_left_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="1"
|
||||
android:textAlignment="viewStart" />
|
||||
<TextView
|
||||
android:id="@+id/right_text"
|
||||
android:text="@string/accessibility_toggle_master_balance_right_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="1"
|
||||
android:textAlignment="viewEnd" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,191 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2009 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- Whether or not the dock settings are to be displayed for this device when docked -->
|
||||
<bool name="has_dock_settings">false</bool>
|
||||
<!-- Whether there is a boot sounds checkbox -->
|
||||
<bool name="has_boot_sounds">false</bool>
|
||||
<!-- Whether there is a silent mode checkbox -->
|
||||
<bool name="has_silent_mode">true</bool>
|
||||
|
||||
<!-- Display additional System Update menu if true -->
|
||||
<bool name="config_additional_system_update_setting_enable">false</bool>
|
||||
|
||||
<!-- Whether the bluetooth activation confirmation dialogs should be auto dismissed.
|
||||
Can be overridden for specific product builds. -->
|
||||
<bool name="auto_confirm_bluetooth_activation_dialog">false</bool>
|
||||
|
||||
<!-- Whether the device name is shown in About device or not -->
|
||||
<bool name="config_show_device_name">true</bool>
|
||||
|
||||
<!-- Whether to show a preference item for the manual in About phone -->
|
||||
<bool name="config_show_manual">false</bool>
|
||||
<!-- Whether to show a preference item for regulatory information in About phone -->
|
||||
<bool name="config_show_regulatory_info">false</bool>
|
||||
|
||||
<!-- Whether to show a preference item for mobile plan -->
|
||||
<bool name="config_show_mobile_plan">true</bool>
|
||||
|
||||
<!-- Whether none security option is hide or not (country specific). -->
|
||||
<bool name="config_hide_none_security_option">false</bool>
|
||||
|
||||
<!-- Whether swipe security option is hidden or not -->
|
||||
<bool name="config_hide_swipe_security_option">false</bool>
|
||||
|
||||
<!--Whether help links are defined. -->
|
||||
<bool name="config_has_help">false</bool>
|
||||
|
||||
<!-- Whether Wi-Fi settings should be shown or not.
|
||||
This also controls whether Wi-fi related sub-settings (e.g. Wi-Fi preferences) will
|
||||
surface in search results or not.-->
|
||||
<bool name="config_show_wifi_settings">true</bool>
|
||||
|
||||
<!-- Whether toggle_airplane is available or not. -->
|
||||
<bool name="config_show_toggle_airplane">true</bool>
|
||||
|
||||
<!-- Whether private_dns_settings is available or not. -->
|
||||
<bool name="config_show_private_dns_settings">true</bool>
|
||||
|
||||
<!-- Whether memory from app_info_settings is available or not. -->
|
||||
<bool name="config_show_app_info_settings_memory">false</bool>
|
||||
|
||||
<!-- Whether battery from app_info_settings is available or not. -->
|
||||
<bool name="config_show_app_info_settings_battery">true</bool>
|
||||
|
||||
<!-- Whether location mode is available or not. -->
|
||||
<bool name="config_location_mode_available">true</bool>
|
||||
|
||||
<!-- Whether location scanning is available or not. -->
|
||||
<bool name="config_show_location_scanning">true</bool>
|
||||
|
||||
<!-- Whether high_power_apps should be shown or not. -->
|
||||
<bool name="config_show_high_power_apps">true</bool>
|
||||
|
||||
<!-- Whether media_volume should be shown or not. -->
|
||||
<bool name="config_show_media_volume">true</bool>
|
||||
|
||||
<!-- Whether alarm_volume should be shown or not. -->
|
||||
<bool name="config_show_alarm_volume">true</bool>
|
||||
|
||||
<!-- Whether call_volume should be shown or not. -->
|
||||
<bool name="config_show_call_volume">true</bool>
|
||||
|
||||
<!-- Whether notification_volume should be shown or not. -->
|
||||
<bool name="config_show_notification_volume">true</bool>
|
||||
|
||||
<!-- Whether notification_ringtone should be shown or not. -->
|
||||
<bool name="config_show_notification_ringtone">true</bool>
|
||||
|
||||
<!-- Whether screen_locking_sounds should be shown or not. -->
|
||||
<bool name="config_show_screen_locking_sounds">true</bool>
|
||||
|
||||
<!-- Whether charging_sounds should be shown or not. -->
|
||||
<bool name="config_show_charging_sounds">true</bool>
|
||||
|
||||
<!-- Whether touch_sounds should be shown or not. -->
|
||||
<bool name="config_show_touch_sounds">true</bool>
|
||||
|
||||
<!-- Whether encryption_and_credentials_encryption_status should be shown or not. -->
|
||||
<bool name="config_show_encryption_and_credentials_encryption_status">true</bool>
|
||||
|
||||
<!-- Whether premium_sms should be shown or not. -->
|
||||
<bool name="config_show_premium_sms">true</bool>
|
||||
|
||||
<!-- Whether data_saver should be shown or not. -->
|
||||
<bool name="config_show_data_saver">true</bool>
|
||||
|
||||
<!-- Whether enabled_vr_listeners should be shown or not. -->
|
||||
<bool name="config_show_enabled_vr_listeners">true</bool>
|
||||
|
||||
<!-- Whether phone_language should be shown or not. -->
|
||||
<bool name="config_show_phone_language">true</bool>
|
||||
|
||||
<!-- Whether virtual_keyboard_pref should be shown or not. -->
|
||||
<bool name="config_show_virtual_keyboard_pref">true</bool>
|
||||
|
||||
<!-- Whether physical_keyboard_pref should be shown or not. -->
|
||||
<bool name="config_show_physical_keyboard_pref">true</bool>
|
||||
|
||||
<!-- Whether spellcheckers_settings should be shown or not. -->
|
||||
<bool name="config_show_spellcheckers_settings">true</bool>
|
||||
|
||||
<!-- Whether tts_settings_summary should be shown or not. -->
|
||||
<bool name="config_show_tts_settings_summary">true</bool>
|
||||
|
||||
<!-- Whether pointer_speed should be shown or not. -->
|
||||
<bool name="config_show_pointer_speed">true</bool>
|
||||
|
||||
<!-- Whether vibrate_input_devices should be shown or not. -->
|
||||
<bool name="config_show_vibrate_input_devices">true</bool>
|
||||
|
||||
<!-- Whether manage_device_admin should be shown or not. -->
|
||||
<bool name="config_show_manage_device_admin">true</bool>
|
||||
|
||||
<!-- Whether unlock_set_or_change should be shown or not. -->
|
||||
<bool name="config_show_unlock_set_or_change">true</bool>
|
||||
|
||||
<!-- Whether screen_pinning_settings should be shown or not. -->
|
||||
<bool name="config_show_screen_pinning_settings">true</bool>
|
||||
|
||||
<!-- Whether manage_trust_agents should be shown or not. -->
|
||||
<bool name="config_show_manage_trust_agents">true</bool>
|
||||
|
||||
<!-- Whether show_password should be shown or not. -->
|
||||
<bool name="config_show_show_password">true</bool>
|
||||
|
||||
<!-- Whether trust_agent_click_intent should be shown or not. -->
|
||||
<bool name="config_show_trust_agent_click_intent">true</bool>
|
||||
|
||||
<!-- Whether wallpaper attribution should be shown or not. -->
|
||||
<bool name="config_show_wallpaper_attribution">true</bool>
|
||||
|
||||
<!-- Whether default_home should be shown or not. -->
|
||||
<bool name="config_show_default_home">true</bool>
|
||||
|
||||
<!-- Whether assist_and_voice_input should be shown or not. -->
|
||||
<bool name="config_show_assist_and_voice_input">true</bool>
|
||||
|
||||
<!-- Whether reset_dashboard should be shown or not. -->
|
||||
<bool name="config_show_reset_dashboard">true</bool>
|
||||
|
||||
<!-- Whether system_update_settings should be shown or not. -->
|
||||
<bool name="config_show_system_update_settings">true</bool>
|
||||
|
||||
<!-- Whether device_model should be shown or not. -->
|
||||
<bool name="config_show_device_model">true</bool>
|
||||
|
||||
<!-- Whether top_level_battery should be shown or not. -->
|
||||
<bool name="config_show_top_level_battery">true</bool>
|
||||
|
||||
<!-- Whether top_level_connected_devices should be shown or not. -->
|
||||
<bool name="config_show_top_level_connected_devices">true</bool>
|
||||
|
||||
<!-- Whether top_level_display should be shown or not. -->
|
||||
<bool name="config_show_top_level_display">true</bool>
|
||||
|
||||
<!-- Whether wifi_ip_address should be shown or not. -->
|
||||
<bool name="config_show_wifi_ip_address">true</bool>
|
||||
|
||||
<!-- Whether wifi_mac_address should be shown or not. -->
|
||||
<bool name="config_show_wifi_mac_address">true</bool>
|
||||
|
||||
<!-- Whether to disable "Uninstall Updates" menu item for System apps or not. -->
|
||||
<bool name="config_disable_uninstall_update">false</bool>
|
||||
|
||||
<!-- Whether or not extra preview panels should be used for screen zoom setting. -->
|
||||
<bool name="config_enable_extra_screen_zoom_preview">true</bool>
|
||||
</resources>
|
||||
@@ -15,9 +15,6 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<color name="black">#000</color>
|
||||
<color name="red">#F00</color>
|
||||
<color name="blue">#00F</color>
|
||||
|
||||
<color name="bluetooth_dialog_text_color">#8a000000</color>
|
||||
|
||||
|
||||
@@ -179,4 +179,178 @@
|
||||
|
||||
<!-- App intent -->
|
||||
<string name="config_account_intent_uri" translatable="false"></string>
|
||||
|
||||
<!-- Whether or not the dock settings are to be displayed for this device when docked -->
|
||||
<bool name="has_dock_settings">false</bool>
|
||||
<!-- Whether there is a boot sounds checkbox -->
|
||||
<bool name="has_boot_sounds">false</bool>
|
||||
<!-- Whether there is a silent mode checkbox -->
|
||||
<bool name="has_silent_mode">true</bool>
|
||||
|
||||
<!-- Display additional System Update menu if true -->
|
||||
<bool name="config_additional_system_update_setting_enable">false</bool>
|
||||
|
||||
<!-- Whether the bluetooth activation confirmation dialogs should be auto dismissed.
|
||||
Can be overridden for specific product builds. -->
|
||||
<bool name="auto_confirm_bluetooth_activation_dialog">false</bool>
|
||||
|
||||
<!-- Whether the device name is shown in About device or not -->
|
||||
<bool name="config_show_device_name">true</bool>
|
||||
|
||||
<!-- Whether to show a preference item for the manual in About phone -->
|
||||
<bool name="config_show_manual">false</bool>
|
||||
<!-- Whether to show a preference item for regulatory information in About phone -->
|
||||
<bool name="config_show_regulatory_info">false</bool>
|
||||
|
||||
<!-- Whether to show a preference item for mobile plan -->
|
||||
<bool name="config_show_mobile_plan">true</bool>
|
||||
|
||||
<!-- Whether none security option is hide or not (country specific). -->
|
||||
<bool name="config_hide_none_security_option">false</bool>
|
||||
|
||||
<!-- Whether swipe security option is hidden or not -->
|
||||
<bool name="config_hide_swipe_security_option">false</bool>
|
||||
|
||||
<!--Whether help links are defined. -->
|
||||
<bool name="config_has_help">false</bool>
|
||||
|
||||
<!-- Whether Wi-Fi settings should be shown or not.
|
||||
This also controls whether Wi-fi related sub-settings (e.g. Wi-Fi preferences) will
|
||||
surface in search results or not.-->
|
||||
<bool name="config_show_wifi_settings">true</bool>
|
||||
|
||||
<!-- Whether toggle_airplane is available or not. -->
|
||||
<bool name="config_show_toggle_airplane">true</bool>
|
||||
|
||||
<!-- Whether private_dns_settings is available or not. -->
|
||||
<bool name="config_show_private_dns_settings">true</bool>
|
||||
|
||||
<!-- Whether memory from app_info_settings is available or not. -->
|
||||
<bool name="config_show_app_info_settings_memory">false</bool>
|
||||
|
||||
<!-- Whether battery from app_info_settings is available or not. -->
|
||||
<bool name="config_show_app_info_settings_battery">true</bool>
|
||||
|
||||
<!-- Whether location mode is available or not. -->
|
||||
<bool name="config_location_mode_available">true</bool>
|
||||
|
||||
<!-- Whether location scanning is available or not. -->
|
||||
<bool name="config_show_location_scanning">true</bool>
|
||||
|
||||
<!-- Whether high_power_apps should be shown or not. -->
|
||||
<bool name="config_show_high_power_apps">true</bool>
|
||||
|
||||
<!-- Whether media_volume should be shown or not. -->
|
||||
<bool name="config_show_media_volume">true</bool>
|
||||
|
||||
<!-- Whether alarm_volume should be shown or not. -->
|
||||
<bool name="config_show_alarm_volume">true</bool>
|
||||
|
||||
<!-- Whether call_volume should be shown or not. -->
|
||||
<bool name="config_show_call_volume">true</bool>
|
||||
|
||||
<!-- Whether notification_volume should be shown or not. -->
|
||||
<bool name="config_show_notification_volume">true</bool>
|
||||
|
||||
<!-- Whether notification_ringtone should be shown or not. -->
|
||||
<bool name="config_show_notification_ringtone">true</bool>
|
||||
|
||||
<!-- Whether screen_locking_sounds should be shown or not. -->
|
||||
<bool name="config_show_screen_locking_sounds">true</bool>
|
||||
|
||||
<!-- Whether charging_sounds should be shown or not. -->
|
||||
<bool name="config_show_charging_sounds">true</bool>
|
||||
|
||||
<!-- Whether touch_sounds should be shown or not. -->
|
||||
<bool name="config_show_touch_sounds">true</bool>
|
||||
|
||||
<!-- Whether encryption_and_credentials_encryption_status should be shown or not. -->
|
||||
<bool name="config_show_encryption_and_credentials_encryption_status">true</bool>
|
||||
|
||||
<!-- Whether premium_sms should be shown or not. -->
|
||||
<bool name="config_show_premium_sms">true</bool>
|
||||
|
||||
<!-- Whether data_saver should be shown or not. -->
|
||||
<bool name="config_show_data_saver">true</bool>
|
||||
|
||||
<!-- Whether enabled_vr_listeners should be shown or not. -->
|
||||
<bool name="config_show_enabled_vr_listeners">true</bool>
|
||||
|
||||
<!-- Whether phone_language should be shown or not. -->
|
||||
<bool name="config_show_phone_language">true</bool>
|
||||
|
||||
<!-- Whether virtual_keyboard_pref should be shown or not. -->
|
||||
<bool name="config_show_virtual_keyboard_pref">true</bool>
|
||||
|
||||
<!-- Whether physical_keyboard_pref should be shown or not. -->
|
||||
<bool name="config_show_physical_keyboard_pref">true</bool>
|
||||
|
||||
<!-- Whether spellcheckers_settings should be shown or not. -->
|
||||
<bool name="config_show_spellcheckers_settings">true</bool>
|
||||
|
||||
<!-- Whether tts_settings_summary should be shown or not. -->
|
||||
<bool name="config_show_tts_settings_summary">true</bool>
|
||||
|
||||
<!-- Whether pointer_speed should be shown or not. -->
|
||||
<bool name="config_show_pointer_speed">true</bool>
|
||||
|
||||
<!-- Whether vibrate_input_devices should be shown or not. -->
|
||||
<bool name="config_show_vibrate_input_devices">true</bool>
|
||||
|
||||
<!-- Whether manage_device_admin should be shown or not. -->
|
||||
<bool name="config_show_manage_device_admin">true</bool>
|
||||
|
||||
<!-- Whether unlock_set_or_change should be shown or not. -->
|
||||
<bool name="config_show_unlock_set_or_change">true</bool>
|
||||
|
||||
<!-- Whether screen_pinning_settings should be shown or not. -->
|
||||
<bool name="config_show_screen_pinning_settings">true</bool>
|
||||
|
||||
<!-- Whether manage_trust_agents should be shown or not. -->
|
||||
<bool name="config_show_manage_trust_agents">true</bool>
|
||||
|
||||
<!-- Whether show_password should be shown or not. -->
|
||||
<bool name="config_show_show_password">true</bool>
|
||||
|
||||
<!-- Whether trust_agent_click_intent should be shown or not. -->
|
||||
<bool name="config_show_trust_agent_click_intent">true</bool>
|
||||
|
||||
<!-- Whether wallpaper attribution should be shown or not. -->
|
||||
<bool name="config_show_wallpaper_attribution">true</bool>
|
||||
|
||||
<!-- Whether default_home should be shown or not. -->
|
||||
<bool name="config_show_default_home">true</bool>
|
||||
|
||||
<!-- Whether assist_and_voice_input should be shown or not. -->
|
||||
<bool name="config_show_assist_and_voice_input">true</bool>
|
||||
|
||||
<!-- Whether reset_dashboard should be shown or not. -->
|
||||
<bool name="config_show_reset_dashboard">true</bool>
|
||||
|
||||
<!-- Whether system_update_settings should be shown or not. -->
|
||||
<bool name="config_show_system_update_settings">true</bool>
|
||||
|
||||
<!-- Whether device_model should be shown or not. -->
|
||||
<bool name="config_show_device_model">true</bool>
|
||||
|
||||
<!-- Whether top_level_battery should be shown or not. -->
|
||||
<bool name="config_show_top_level_battery">true</bool>
|
||||
|
||||
<!-- Whether top_level_connected_devices should be shown or not. -->
|
||||
<bool name="config_show_top_level_connected_devices">true</bool>
|
||||
|
||||
<!-- Whether top_level_display should be shown or not. -->
|
||||
<bool name="config_show_top_level_display">true</bool>
|
||||
|
||||
<!-- Whether wifi_ip_address should be shown or not. -->
|
||||
<bool name="config_show_wifi_ip_address">true</bool>
|
||||
|
||||
<!-- Whether wifi_mac_address should be shown or not. -->
|
||||
<bool name="config_show_wifi_mac_address">true</bool>
|
||||
|
||||
<!-- Whether to disable "Uninstall Updates" menu item for System apps or not. -->
|
||||
<bool name="config_disable_uninstall_update">false</bool>
|
||||
|
||||
<!-- Whether or not extra preview panels should be used for screen zoom setting. -->
|
||||
<bool name="config_enable_extra_screen_zoom_preview">true</bool>
|
||||
</resources>
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
|
||||
<dimen name="volume_seekbar_side_margin">8dip</dimen>
|
||||
|
||||
<dimen name="balance_seekbar_center_marker_height">14dp</dimen>
|
||||
<dimen name="balance_seekbar_center_marker_width">1dp</dimen>
|
||||
|
||||
<dimen name="crypt_clock_size">100sp</dimen>
|
||||
|
||||
<dimen name="divider_height">3dip</dimen>
|
||||
|
||||
@@ -33,8 +33,4 @@
|
||||
<item>@string/input_method_selector_always_show_value</item>
|
||||
<item>@string/input_method_selector_always_hide_value</item>
|
||||
</string-array>
|
||||
<string name="category_key_wireless">com.android.settings.category.wireless</string>
|
||||
<string name="category_key_device">com.android.settings.category.device</string>
|
||||
<string name="category_key_personal">com.android.settings.category.personal</string>
|
||||
<string name="category_key_system">com.android.settings.category.system</string>
|
||||
</resources>
|
||||
|
||||
@@ -4487,8 +4487,8 @@
|
||||
<string name="keyboard_shortcuts_helper">Keyboard shortcuts helper</string>
|
||||
<!-- Summary text for the 'keyboard shortcuts helper' dialog. [CHAR LIMIT=100] -->
|
||||
<string name="keyboard_shortcuts_helper_summary">Display available shortcuts</string>
|
||||
<!-- Title for the 'Work profile' preference category inside Languages and inputs'. [CHAR LIMIT=45] -->
|
||||
<string name="language_and_input_for_work_category_title">Work profile</string>
|
||||
<!-- Title for the 'Work profile input & assistance' preference category inside Languages and inputs'. [CHAR LIMIT=50] -->
|
||||
<string name="language_and_input_for_work_category_title">Work profile input & assistance</string>
|
||||
<!-- Title for the 'Virtual keyboards for work' preference. [CHAR LIMIT=45] -->
|
||||
<string name="virtual_keyboards_for_work_title">Virtual keyboard for work</string>
|
||||
|
||||
@@ -4717,6 +4717,12 @@
|
||||
<string name="accessibility_toggle_master_mono_title">Mono audio</string>
|
||||
<!-- Summary for the accessibility preference for master mono. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_toggle_master_mono_summary">Combine channels when playing audio</string>
|
||||
<!-- Title for the accessibility preference for master balance. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_toggle_master_balance_title">Audio balance</string>
|
||||
<!-- 'Left' balance text for the accessibility preference for master balance. [CHAR LIMIT=20] -->
|
||||
<string name="accessibility_toggle_master_balance_left_label">Left</string>
|
||||
<!-- 'Right' balance text for the accessibility preference for master balance. [CHAR LIMIT=20] -->
|
||||
<string name="accessibility_toggle_master_balance_right_label">Right</string>
|
||||
|
||||
<!-- Option heading to leave the timeout requirement for accessibility users at its default level. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_timeout_default">Default</string>
|
||||
@@ -5851,9 +5857,9 @@
|
||||
<!-- Summary for whether to enable SMS access restriction [CHAR LIMIT=NONE]-->
|
||||
<string name="sms_access_restriction_enabled_summary">Only default phone and messaging apps have SMS & call log permissions</string>
|
||||
<!-- Title for the new device identifier access restrictions [CHAR LIMIT=50]-->
|
||||
<string name="device_identifier_access_restrictions_title">Enable device identifier restrictions</string>
|
||||
<string name="device_identifier_access_restrictions_title">Disable device identifier restrictions</string>
|
||||
<!-- Summary for the new device identifier access restrictions [CHAR LIMIT=NONE]-->
|
||||
<string name="device_identifier_access_restrictions_summary">Enable the new access restrictions for device identifiers.</string>
|
||||
<string name="device_identifier_access_restrictions_summary">Disable the new access restrictions for device identifiers</string>
|
||||
|
||||
|
||||
<!-- Message when there are no available trust agents to display -->
|
||||
@@ -7621,6 +7627,9 @@
|
||||
<!-- Configure Notifications: Title for the notification badging option. [CHAR LIMIT=30 BACKUP_MESSAGE_ID=5125022693565388760] -->
|
||||
<string name="notification_badging_title">Allow notification dots</string>
|
||||
|
||||
<!-- Configure Notifications: Title for the notification bubbles option. [CHAR LIMIT=60] -->
|
||||
<string name="notification_bubbles_title">Allow notification bubbles</string>
|
||||
|
||||
<!-- Configure Notifications: Title for the pulse notification light option. [CHAR LIMIT=30] -->
|
||||
<string name="notification_pulse_title">Blink light</string>
|
||||
|
||||
@@ -10470,6 +10479,12 @@
|
||||
<!-- Label on the confirmation button of a dialog that lets a user set the display name of a
|
||||
mobile network subscription [CHAR LIMIT=20] -->
|
||||
<string name="mobile_network_sim_name_rename">Rename</string>
|
||||
<!-- Label for the on position of a switch on the mobile network details page which allows
|
||||
disabling/enabling a SIM. The SIM is enabled in this state. [CHAR LIMIT=40] -->
|
||||
<string name="mobile_network_use_sim_on">Use SIM</string>
|
||||
<!-- Label for the off position of a switch on the mobile network details page which allows
|
||||
disabling/enabling a SIM. The SIM is disabled in this state. [CHAR LIMIT=40] -->
|
||||
<string name="mobile_network_use_sim_off">Off</string>
|
||||
|
||||
<!-- Title for preferred network type [CHAR LIMIT=NONE] -->
|
||||
<string name="preferred_network_mode_title">Preferred network type</string>
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
<item name="android:layout_marginBottom">@dimen/homepage_card_vertical_margin</item>
|
||||
<item name="android:layout_marginStart">@dimen/homepage_card_side_margin</item>
|
||||
<item name="android:layout_marginEnd">@dimen/homepage_card_side_margin</item>
|
||||
<item name="cardCornerRadius">8dp</item>
|
||||
<item name="cardCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
|
||||
<item name="cardElevation">0dp</item>
|
||||
<item name="strokeColor">@color/homepage_card_stroke_color</item>
|
||||
<item name="strokeWidth">1dp</item>
|
||||
|
||||
@@ -130,6 +130,10 @@
|
||||
android:summary="@string/accessibility_toggle_master_mono_summary"
|
||||
android:persistent="false"/>
|
||||
|
||||
<com.android.settings.accessibility.BalanceSeekBarPreference
|
||||
android:key="seekbar_master_balance"
|
||||
android:title="@string/accessibility_toggle_master_balance_title" />
|
||||
|
||||
<Preference
|
||||
android:key="hearing_aid_preference"
|
||||
android:summary="@string/accessibility_hearingaid_not_connected_summary"
|
||||
|
||||
@@ -60,9 +60,14 @@
|
||||
settings:useAdditionalSummary="true"
|
||||
android:order="1001"
|
||||
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="bubble"
|
||||
android:title="@string/notification_bubbles_title"
|
||||
android:order="1002"
|
||||
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
|
||||
<Preference
|
||||
android:key="app_link"
|
||||
android:order="1002"
|
||||
android:order="1003"
|
||||
android:title="@string/app_settings_link" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
@@ -86,17 +86,23 @@
|
||||
settings:useAdditionalSummary="true"
|
||||
settings:restrictedSwitchSummary="@string/enabled_by_admin"/>
|
||||
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="bubble"
|
||||
android:title="@string/notification_bubbles_title"
|
||||
android:order="16"
|
||||
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
|
||||
|
||||
<!-- Bypass DND -->
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="bypass_dnd"
|
||||
android:order="16"
|
||||
android:order="17"
|
||||
android:title="@string/app_notification_override_dnd_title"
|
||||
android:summary="@string/app_notification_override_dnd_summary"
|
||||
settings:useAdditionalSummary="true"/>
|
||||
|
||||
<Preference
|
||||
android:key="app_link"
|
||||
android:order="17"
|
||||
android:order="18"
|
||||
android:title="@string/app_settings_link"
|
||||
settings:allowDividerAbove="true"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
@@ -38,6 +38,12 @@
|
||||
android:title="@string/notification_badging_title"
|
||||
settings:controller="com.android.settings.notification.BadgingNotificationPreferenceController"/>
|
||||
|
||||
<!-- Notification bubbles -->
|
||||
<SwitchPreference
|
||||
android:key="notification_bubbles"
|
||||
android:title="@string/notification_bubbles_title"
|
||||
settings:controller="com.android.settings.notification.BubbleNotificationPreferenceController"/>
|
||||
|
||||
<!-- Pulse notification light -->
|
||||
<SwitchPreference
|
||||
android:key="notification_pulse"
|
||||
|
||||
@@ -17,7 +17,12 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="mobile_network_pref_screen"
|
||||
settings:initialExpandedChildrenCount="7">
|
||||
settings:initialExpandedChildrenCount="8">
|
||||
|
||||
<com.android.settingslib.widget.LayoutPreference
|
||||
android:key="use_sim_switch"
|
||||
android:layout="@layout/styled_switch_bar"
|
||||
settings:controller="com.android.settings.network.telephony.MobileNetworkSwitchController"/>
|
||||
|
||||
<com.android.settings.datausage.DataUsageSummaryPreference
|
||||
android:key="status_header"
|
||||
|
||||
@@ -71,6 +71,7 @@ public class Settings extends SettingsActivity {
|
||||
public static class AppUsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class LocationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class ScanningSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class PrivacyDashboardActivity extends SettingsActivity { /* empty */ }
|
||||
public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class FactoryResetActivity extends SettingsActivity { /* empty */ }
|
||||
public static class RunningServicesActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
152
src/com/android/settings/accessibility/BalanceSeekBar.java
Normal file
152
src/com/android/settings/accessibility/BalanceSeekBar.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
/**
|
||||
* A custom seekbar for the balance setting.
|
||||
*
|
||||
* Adds a center line indicator between left and right, which snaps to if close.
|
||||
* Updates Settings.System for balance on progress changed.
|
||||
*/
|
||||
public class BalanceSeekBar extends SeekBar {
|
||||
private static final String TAG = "BalanceSeekBar";
|
||||
private final Context mContext;
|
||||
private final Object mListenerLock = new Object();
|
||||
private OnSeekBarChangeListener mOnSeekBarChangeListener;
|
||||
private final OnSeekBarChangeListener mProxySeekBarListener = new OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
synchronized(mListenerLock) {
|
||||
if (mOnSeekBarChangeListener != null) {
|
||||
mOnSeekBarChangeListener.onStopTrackingTouch(seekBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
synchronized(mListenerLock) {
|
||||
if (mOnSeekBarChangeListener != null) {
|
||||
mOnSeekBarChangeListener.onStartTrackingTouch(seekBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
// Snap to centre when within the specified threshold
|
||||
if (progress != mCenter
|
||||
&& progress > mCenter - mSnapThreshold
|
||||
&& progress < mCenter + mSnapThreshold) {
|
||||
progress = mCenter;
|
||||
seekBar.setProgress(progress); // direct update (fromUser becomes false)
|
||||
}
|
||||
final float balance = (progress - mCenter) * 0.01f;
|
||||
Settings.System.putFloatForUser(mContext.getContentResolver(),
|
||||
Settings.System.MASTER_BALANCE, balance, UserHandle.USER_CURRENT);
|
||||
}
|
||||
// If fromUser is false, the call is a set from the framework on creation or on
|
||||
// internal update. The progress may be zero, ignore (don't change system settings).
|
||||
|
||||
// after adjusting the seekbar, notify downstream listener.
|
||||
// note that progress may have been adjusted in the code above to mCenter.
|
||||
synchronized(mListenerLock) {
|
||||
if (mOnSeekBarChangeListener != null) {
|
||||
mOnSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Percentage of max to be used as a snap to threshold
|
||||
private static final float SNAP_TO_PERCENTAGE = 0.03f;
|
||||
private final Paint mCenterMarkerPaint;
|
||||
private final Rect mCenterMarkerRect;
|
||||
// changed in setMax()
|
||||
private float mSnapThreshold;
|
||||
private int mCenter;
|
||||
|
||||
public BalanceSeekBar(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, com.android.internal.R.attr.seekBarStyle);
|
||||
}
|
||||
|
||||
public BalanceSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0 /* defStyleRes */);
|
||||
}
|
||||
|
||||
public BalanceSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
mContext = context;
|
||||
Resources res = getResources();
|
||||
mCenterMarkerRect = new Rect(0 /* left */, 0 /* top */,
|
||||
res.getDimensionPixelSize(R.dimen.balance_seekbar_center_marker_width),
|
||||
res.getDimensionPixelSize(R.dimen.balance_seekbar_center_marker_height));
|
||||
mCenterMarkerPaint = new Paint();
|
||||
// TODO use a more suitable colour?
|
||||
mCenterMarkerPaint.setColor(Color.BLACK);
|
||||
mCenterMarkerPaint.setStyle(Paint.Style.FILL);
|
||||
// Remove the progress colour
|
||||
setProgressTintList(ColorStateList.valueOf(Color.TRANSPARENT));
|
||||
|
||||
super.setOnSeekBarChangeListener(mProxySeekBarListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {
|
||||
synchronized(mListenerLock) {
|
||||
mOnSeekBarChangeListener = listener;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: the superclass AbsSeekBar.setMax is synchronized.
|
||||
@Override
|
||||
public synchronized void setMax(int max) {
|
||||
super.setMax(max);
|
||||
// update snap to threshold
|
||||
mCenter = max / 2;
|
||||
mSnapThreshold = max * SNAP_TO_PERCENTAGE;
|
||||
}
|
||||
|
||||
// Note: the superclass AbsSeekBar.onDraw is synchronized.
|
||||
@Override
|
||||
protected synchronized void onDraw(Canvas canvas) {
|
||||
// Draw a vertical line at 50% that represents centred balance
|
||||
int seekBarCenter = (canvas.getHeight() - getPaddingBottom()) / 2;
|
||||
canvas.save();
|
||||
canvas.translate((canvas.getWidth() - mCenterMarkerRect.right) / 2,
|
||||
seekBarCenter - (mCenterMarkerRect.bottom / 2));
|
||||
canvas.drawRect(mCenterMarkerRect, mCenterMarkerPaint);
|
||||
canvas.restore();
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioSystem;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import androidx.core.content.res.TypedArrayUtils;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.widget.SeekBarPreference;
|
||||
|
||||
/** A slider preference that directly controls audio balance **/
|
||||
public class BalanceSeekBarPreference extends SeekBarPreference {
|
||||
private static final String TAG = "BalanceSeekBarPreference";
|
||||
private final Context mContext;
|
||||
private BalanceSeekBar mSeekBar;
|
||||
private ImageView mIconView;
|
||||
|
||||
public BalanceSeekBarPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs, TypedArrayUtils.getAttr(context,
|
||||
R.attr.preferenceStyle,
|
||||
android.R.attr.preferenceStyle));
|
||||
mContext = context;
|
||||
setLayoutResource(R.layout.preference_balance_slider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
mSeekBar = (BalanceSeekBar) view.findViewById(com.android.internal.R.id.seekbar);
|
||||
mIconView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
if (mSeekBar == null) {
|
||||
return;
|
||||
}
|
||||
final float balance = Settings.System.getFloatForUser(
|
||||
mContext.getContentResolver(), Settings.System.MASTER_BALANCE,
|
||||
0.f /* default */, UserHandle.USER_CURRENT);
|
||||
// Rescale balance to range 0-200 centered at 100.
|
||||
mSeekBar.setMax(200);
|
||||
mSeekBar.setProgress((int)(balance * 100.f) + 100);
|
||||
mSeekBar.setEnabled(isEnabled());
|
||||
}
|
||||
}
|
||||
@@ -274,6 +274,7 @@ public class SettingsGateway {
|
||||
Settings.StorageDashboardActivity.class.getName(),
|
||||
Settings.PowerUsageSummaryActivity.class.getName(),
|
||||
Settings.AccountDashboardActivity.class.getName(),
|
||||
Settings.PrivacySettingsActivity.class.getName(),
|
||||
Settings.SecurityDashboardActivity.class.getName(),
|
||||
Settings.AccessibilitySettingsActivity.class.getName(),
|
||||
Settings.SystemDashboardActivity.class.getName(),
|
||||
|
||||
@@ -50,12 +50,12 @@ public class DeviceIdentifierAccessRestrictionsPreferenceController
|
||||
private void writeSetting(boolean isEnabled) {
|
||||
DeviceConfig.setProperty(DeviceConfig.Privacy.NAMESPACE,
|
||||
DeviceConfig.Privacy.PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED,
|
||||
String.valueOf(!isEnabled), false);
|
||||
String.valueOf(isEnabled), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
boolean isEnabled = !Boolean.parseBoolean(
|
||||
boolean isEnabled = Boolean.parseBoolean(
|
||||
DeviceConfig.getProperty(DeviceConfig.Privacy.NAMESPACE,
|
||||
DeviceConfig.Privacy.PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED));
|
||||
((SwitchPreference) mPreference).setChecked(isEnabled);
|
||||
@@ -64,7 +64,7 @@ public class DeviceIdentifierAccessRestrictionsPreferenceController
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
writeSetting(true);
|
||||
writeSetting(false);
|
||||
((SwitchPreference) mPreference).setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ public class MobileNetworkSettings extends RestrictedDashboardFragment {
|
||||
if (FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2)) {
|
||||
use(CallsDefaultSubscriptionController.class).init(getLifecycle());
|
||||
use(SmsDefaultSubscriptionController.class).init(getLifecycle());
|
||||
use(MobileNetworkSwitchController.class).init(getLifecycle(), mSubId);
|
||||
}
|
||||
use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
|
||||
use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.network.telephony;
|
||||
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.development.featureflags.FeatureFlagPersistent;
|
||||
import com.android.settings.network.SubscriptionUtil;
|
||||
import com.android.settings.network.SubscriptionsChangeListener;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
/** This controls a switch to allow enabling/disabling a mobile network */
|
||||
public class MobileNetworkSwitchController extends BasePreferenceController implements
|
||||
SubscriptionsChangeListener.SubscriptionsChangeListenerClient, LifecycleObserver {
|
||||
private static final String TAG = "MobileNetworkSwitchCtrl";
|
||||
private SwitchBar mSwitchBar;
|
||||
private int mSubId;
|
||||
private SubscriptionsChangeListener mChangeListener;
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
|
||||
public MobileNetworkSwitchController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
|
||||
mChangeListener = new SubscriptionsChangeListener(context, this);
|
||||
}
|
||||
|
||||
public void init(Lifecycle lifecycle, int subId) {
|
||||
lifecycle.addObserver(this);
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(ON_RESUME)
|
||||
public void onResume() {
|
||||
mChangeListener.start();
|
||||
update();
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(ON_PAUSE)
|
||||
public void onPause() {
|
||||
mChangeListener.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
final LayoutPreference pref = screen.findPreference(mPreferenceKey);
|
||||
mSwitchBar = pref.findViewById(R.id.switch_bar);
|
||||
mSwitchBar.setSwitchBarText(R.string.mobile_network_use_sim_on,
|
||||
R.string.mobile_network_use_sim_off);
|
||||
|
||||
mSwitchBar.addOnSwitchChangeListener((switchView, isChecked) -> {
|
||||
if (mSubscriptionManager.isSubscriptionEnabled(mSubId) != isChecked) {
|
||||
mSubscriptionManager.setSubscriptionEnabled(mSubId, isChecked);
|
||||
}
|
||||
});
|
||||
update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (mSwitchBar == null) {
|
||||
return;
|
||||
}
|
||||
final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
|
||||
mSubscriptionManager);
|
||||
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || subs.size() < 2) {
|
||||
mSwitchBar.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
for (SubscriptionInfo info : subs) {
|
||||
if (info.getSubscriptionId() == mSubId) {
|
||||
mSwitchBar.show();
|
||||
mSwitchBar.setChecked(mSubscriptionManager.isSubscriptionEnabled(mSubId));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// This subscription was not found in the available list.
|
||||
mSwitchBar.hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (FeatureFlagPersistent.isEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2)) {
|
||||
return AVAILABLE_UNSEARCHABLE;
|
||||
} else {
|
||||
return CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAirplaneModeChanged(boolean airplaneModeEnabled) {}
|
||||
|
||||
@Override
|
||||
public void onSubscriptionsChanged() {
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -152,6 +152,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
||||
mControllers.add(new DescriptionPreferenceController(context));
|
||||
mControllers.add(new NotificationsOffPreferenceController(context));
|
||||
mControllers.add(new DeletedChannelsPreferenceController(context, mBackend));
|
||||
mControllers.add(new BubblePreferenceController(context, mBackend));
|
||||
return new ArrayList<>(mControllers);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class BadgePreferenceController extends NotificationPreferenceController
|
||||
if (isDefaultChannel()) {
|
||||
return true;
|
||||
} else {
|
||||
return mAppRow.showBadge;
|
||||
return mAppRow == null ? false : mAppRow.showBadge;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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;
|
||||
|
||||
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
|
||||
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
public class BubbleNotificationPreferenceController extends TogglePreferenceController
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
|
||||
LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
private static final String TAG = "BubbleNotifPrefContr";
|
||||
@VisibleForTesting
|
||||
static final int ON = 1;
|
||||
@VisibleForTesting
|
||||
static final int OFF = 0;
|
||||
|
||||
private SettingObserver mSettingObserver;
|
||||
|
||||
public BubbleNotificationPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
Preference preference = screen.findPreference(NOTIFICATION_BUBBLES);
|
||||
if (preference != null) {
|
||||
mSettingObserver = new SettingObserver(preference);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
if (mSettingObserver != null) {
|
||||
mSettingObserver.register(mContext.getContentResolver(), true /* register */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (mSettingObserver != null) {
|
||||
mSettingObserver.register(mContext.getContentResolver(), false /* register */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
NOTIFICATION_BUBBLES, ON) == ON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
return Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
NOTIFICATION_BUBBLES, isChecked ? ON : OFF);
|
||||
}
|
||||
|
||||
class SettingObserver extends ContentObserver {
|
||||
|
||||
private final Uri NOTIFICATION_BUBBLES_URI =
|
||||
Settings.Secure.getUriFor(NOTIFICATION_BUBBLES);
|
||||
|
||||
private final Preference mPreference;
|
||||
|
||||
public SettingObserver(Preference preference) {
|
||||
super(new Handler());
|
||||
mPreference = preference;
|
||||
}
|
||||
|
||||
public void register(ContentResolver cr, boolean register) {
|
||||
if (register) {
|
||||
cr.registerContentObserver(NOTIFICATION_BUBBLES_URI, false, this);
|
||||
} else {
|
||||
cr.unregisterContentObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
super.onChange(selfChange, uri);
|
||||
if (NOTIFICATION_BUBBLES_URI.equals(uri)) {
|
||||
updateState(mPreference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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;
|
||||
|
||||
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
public class BubblePreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String TAG = "BubblePrefContr";
|
||||
private static final String KEY = "bubble";
|
||||
private static final int SYSTEM_WIDE_ON = 1;
|
||||
private static final int SYSTEM_WIDE_OFF = 0;
|
||||
|
||||
public BubblePreferenceController(Context context, NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
if (mAppRow == null && mChannel == null) {
|
||||
return false;
|
||||
}
|
||||
if (Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_OFF) {
|
||||
return false;
|
||||
}
|
||||
if (mChannel != null) {
|
||||
if (isDefaultChannel()) {
|
||||
return true;
|
||||
} else {
|
||||
return mAppRow == null ? false : mAppRow.allowBubbles;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
if (mAppRow != null) {
|
||||
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
|
||||
pref.setDisabledByAdmin(mAdmin);
|
||||
if (mChannel != null) {
|
||||
pref.setChecked(mChannel.canBubble());
|
||||
pref.setEnabled(isChannelConfigurable() && !pref.isDisabledByAdmin());
|
||||
} else {
|
||||
pref.setChecked(mAppRow.allowBubbles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean value = (Boolean) newValue;
|
||||
if (mChannel != null) {
|
||||
mChannel.setAllowBubbles(value);
|
||||
saveChannel();
|
||||
} else if (mAppRow != null){
|
||||
mAppRow.allowBubbles = value;
|
||||
mBackend.setAllowBubbles(mAppRow.pkg, mAppRow.uid, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -110,6 +110,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
||||
mControllers.add(new BadgePreferenceController(context, mBackend));
|
||||
mControllers.add(new DndPreferenceController(context, mBackend));
|
||||
mControllers.add(new NotificationsOffPreferenceController(context));
|
||||
mControllers.add(new BubblePreferenceController(context, mBackend));
|
||||
return new ArrayList<>(mControllers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ public class NotificationBackend {
|
||||
row.icon = IconDrawableFactory.newInstance(context).getBadgedIcon(app);
|
||||
row.banned = getNotificationsBanned(row.pkg, row.uid);
|
||||
row.showBadge = canShowBadge(row.pkg, row.uid);
|
||||
row.allowBubbles = canBubble(row.pkg, row.uid);
|
||||
row.userId = UserHandle.getUserId(row.uid);
|
||||
row.blockedChannelCount = getBlockedChannelCount(row.pkg, row.uid);
|
||||
row.channelCount = getChannelCount(row.pkg, row.uid);
|
||||
@@ -175,6 +176,26 @@ public class NotificationBackend {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canBubble(String pkg, int uid) {
|
||||
try {
|
||||
return sINM.areBubblesAllowedForPackage(pkg, uid);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calling NoMan", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setAllowBubbles(String pkg, int uid, boolean allow) {
|
||||
try {
|
||||
sINM.setBubblesAllowed(pkg, uid, allow);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calling NoMan", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public NotificationChannel getChannel(String pkg, int uid, String channelId) {
|
||||
if (channelId == null) {
|
||||
return null;
|
||||
@@ -416,6 +437,7 @@ public class NotificationBackend {
|
||||
public boolean lockedImportance;
|
||||
public String lockedChannelId;
|
||||
public boolean showBadge;
|
||||
public boolean allowBubbles;
|
||||
public int userId;
|
||||
public int blockedChannelCount;
|
||||
public int channelCount;
|
||||
|
||||
@@ -157,7 +157,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
||||
boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction());
|
||||
|
||||
mUserId = UserHandle.myUserId();
|
||||
final int effectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
|
||||
if (isInternalActivity()) {
|
||||
try {
|
||||
mUserId = Utils.getUserIdFromBundle(this, intent.getExtras());
|
||||
@@ -165,6 +164,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
||||
Log.e(TAG, "Invalid intent extra", se);
|
||||
}
|
||||
}
|
||||
final int effectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
|
||||
final boolean isManagedProfile = UserManager.get(this).isManagedProfile(mUserId);
|
||||
// if the client app did not hand in a title and we are about to show the work challenge,
|
||||
// check whether there is a policy setting the organization name and use that as title
|
||||
|
||||
@@ -31,16 +31,13 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -57,8 +54,6 @@ import org.robolectric.shadows.ShadowUserManager;
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = BackupSettingsHelperTest.ShadowBackupManagerStub.class)
|
||||
public class BackupSettingsHelperTest {
|
||||
private static final String DEFAULT_SETTINGS_CLASSNAME =
|
||||
"com.android.settings.Settings$PrivacySettingsActivity";
|
||||
|
||||
private static final int DEFAULT_SUMMARY_RESOURCE =
|
||||
R.string.backup_configure_account_default_summary;
|
||||
@@ -294,16 +289,6 @@ public class BackupSettingsHelperTest {
|
||||
assertThat(backupIntent).isEqualTo(intent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIntentForBackupSettings_WithoutIntentFromTransport() throws Exception {
|
||||
when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(null);
|
||||
|
||||
Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();
|
||||
|
||||
assertThat(backupIntent.getComponent().getClassName())
|
||||
.isEqualTo(DEFAULT_SETTINGS_CLASSNAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLabelForBackupSettings_WithLabelFromTransport() throws Exception {
|
||||
String label = "test_label";
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.network.telephony;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.network.SubscriptionUtil;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class MobileNetworkSwitchControllerTest {
|
||||
@Mock
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private LayoutPreference mLayoutPreference;
|
||||
@Mock
|
||||
private SubscriptionInfo mSubscription;
|
||||
|
||||
private Context mContext;
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Lifecycle mLifecycle;
|
||||
private MobileNetworkSwitchController mController;
|
||||
private SwitchBar mSwitchBar;
|
||||
private int mSubId = 123;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
|
||||
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
|
||||
when(mSubscription.getSubscriptionId()).thenReturn(mSubId);
|
||||
// Most tests want to have 2 available subscriptions so that the switch bar will show.
|
||||
SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
|
||||
when(sub2.getSubscriptionId()).thenReturn(456);
|
||||
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(mSubscription, sub2));
|
||||
|
||||
String key = "prefKey";
|
||||
mController = new MobileNetworkSwitchController(mContext, key);
|
||||
mController.init(mLifecycle, mSubscription.getSubscriptionId());
|
||||
|
||||
mSwitchBar = new SwitchBar(mContext);
|
||||
when(mScreen.findPreference(key)).thenReturn(mLayoutPreference);
|
||||
when(mLayoutPreference.findViewById(R.id.switch_bar)).thenReturn(mSwitchBar);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_onlyOneSubscription_switchBarHidden() {
|
||||
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(mSubscription));
|
||||
mController.displayPreference(mScreen);
|
||||
assertThat(mSwitchBar.isShowing()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_subscriptionEnabled_switchIsOn() {
|
||||
when(mSubscriptionManager.isSubscriptionEnabled(mSubId)).thenReturn(true);
|
||||
mController.displayPreference(mScreen);
|
||||
assertThat(mSwitchBar.isShowing()).isTrue();
|
||||
assertThat(mSwitchBar.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_subscriptionDisabled_switchIsOff() {
|
||||
when(mSubscriptionManager.isSubscriptionEnabled(mSubId)).thenReturn(false);
|
||||
mController.displayPreference(mScreen);
|
||||
assertThat(mSwitchBar.isShowing()).isTrue();
|
||||
assertThat(mSwitchBar.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void switchChangeListener_fromEnabledToDisabled_setSubscriptionEnabledCalledCorrectly() {
|
||||
when(mSubscriptionManager.isSubscriptionEnabled(mSubId)).thenReturn(true);
|
||||
mController.displayPreference(mScreen);
|
||||
assertThat(mSwitchBar.isShowing()).isTrue();
|
||||
assertThat(mSwitchBar.isChecked()).isTrue();
|
||||
mSwitchBar.setChecked(false);
|
||||
verify(mSubscriptionManager).setSubscriptionEnabled(eq(mSubId), eq(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void switchChangeListener_fromDisabledToEnabled_setSubscriptionEnabledCalledCorrectly() {
|
||||
when(mSubscriptionManager.isSubscriptionEnabled(mSubId)).thenReturn(false);
|
||||
mController.displayPreference(mScreen);
|
||||
assertThat(mSwitchBar.isShowing()).isTrue();
|
||||
assertThat(mSwitchBar.isChecked()).isFalse();
|
||||
mSwitchBar.setChecked(true);
|
||||
verify(mSubscriptionManager).setSubscriptionEnabled(eq(mSubId), eq(true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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;
|
||||
|
||||
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
|
||||
|
||||
import static com.android.settings.notification.BadgingNotificationPreferenceController.OFF;
|
||||
import static com.android.settings.notification.BadgingNotificationPreferenceController.ON;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.TwoStatePreference;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BubbleNotificationPreferenceControllerTest {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Context mContext;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
private BubbleNotificationPreferenceController mController;
|
||||
private Preference mPreference;
|
||||
|
||||
private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mController = new BubbleNotificationPreferenceController(mContext,
|
||||
KEY_NOTIFICATION_BUBBLES);
|
||||
mPreference = new Preference(RuntimeEnvironment.application);
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void display_shouldDisplay() {
|
||||
assertThat(mPreference.isVisible()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_preferenceSetCheckedWhenSettingIsOn() {
|
||||
final TwoStatePreference preference = mock(TwoStatePreference.class);
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
Settings.Secure.putInt(context.getContentResolver(), NOTIFICATION_BUBBLES, ON);
|
||||
|
||||
mController.updateState(preference);
|
||||
|
||||
verify(preference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_preferenceSetUncheckedWhenSettingIsOff() {
|
||||
final TwoStatePreference preference = mock(TwoStatePreference.class);
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
Settings.Secure.putInt(context.getContentResolver(), NOTIFICATION_BUBBLES, OFF);
|
||||
|
||||
mController.updateState(preference);
|
||||
|
||||
verify(preference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_settingIsOff_shouldReturnFalse() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF);
|
||||
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_settingIsOn_shouldReturnTrue() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON);
|
||||
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_setFalse_disablesSetting() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON);
|
||||
|
||||
mController.setChecked(false);
|
||||
int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
NOTIFICATION_BUBBLES, -1);
|
||||
|
||||
assertThat(updatedValue).isEqualTo(OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_setTrue_enablesSetting() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF);
|
||||
|
||||
mController.setChecked(true);
|
||||
int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
NOTIFICATION_BUBBLES, -1);
|
||||
|
||||
assertThat(updatedValue).isEqualTo(ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSliceable_returnsFalse() {
|
||||
assertThat(mController.isSliceable()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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;
|
||||
|
||||
import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
|
||||
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
||||
import static android.app.NotificationManager.IMPORTANCE_LOW;
|
||||
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
||||
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BubblePreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private NotificationBackend mBackend;
|
||||
@Mock
|
||||
private NotificationManager mNm;
|
||||
@Mock
|
||||
private UserManager mUm;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
private BubblePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
ShadowApplication shadowApplication = ShadowApplication.getInstance();
|
||||
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
|
||||
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = spy(new BubblePreferenceController(mContext, mBackend));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoCrashIfNoOnResume() {
|
||||
mController.isAvailable();
|
||||
mController.updateState(mock(RestrictedSwitchPreference.class));
|
||||
mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfAppBlocked() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.banned = true;
|
||||
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfChannelBlocked() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_channel_notIfAppOff() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = false;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_notIfOffGlobally() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
|
||||
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
mController.onResume(appRow, null, null, null);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
|
||||
|
||||
assertTrue(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_defaultChannel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = true;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
|
||||
|
||||
assertTrue(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = true;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
|
||||
|
||||
assertTrue(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_channelAppOff() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = false;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
|
||||
|
||||
assertFalse(mController.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_disabledByAdmin() {
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getId()).thenReturn("something");
|
||||
mController.onResume(new NotificationBackend.AppRow(), channel, null,
|
||||
mock(RestrictedLockUtils.EnforcedAdmin.class));
|
||||
|
||||
Preference pref = new RestrictedSwitchPreference(mContext);
|
||||
mController.updateState(pref);
|
||||
|
||||
assertFalse(pref.isEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_channelNotConfigurable() {
|
||||
String lockedId = "locked";
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.lockedChannelId = lockedId;
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.getId()).thenReturn(lockedId);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
|
||||
Preference pref = new RestrictedSwitchPreference(mContext);
|
||||
mController.updateState(pref);
|
||||
|
||||
assertFalse(pref.isEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.lockedChannelId = "a";
|
||||
NotificationChannel channel = mock(NotificationChannel.class);
|
||||
when(channel.canBubble()).thenReturn(true);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
mController.updateState(pref);
|
||||
|
||||
assertTrue(pref.isChecked());
|
||||
|
||||
when(channel.canBubble()).thenReturn(false);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
mController.updateState(pref);
|
||||
|
||||
assertFalse(pref.isChecked());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = true;
|
||||
mController.onResume(appRow, null, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
mController.updateState(pref);
|
||||
assertTrue(pref.isChecked());
|
||||
|
||||
appRow.allowBubbles = false;
|
||||
mController.onResume(appRow, null, null, null);
|
||||
|
||||
mController.updateState(pref);
|
||||
assertFalse(pref.isChecked());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_on_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = true;
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
|
||||
channel.setAllowBubbles(false);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.updateState(pref);
|
||||
|
||||
mController.onPreferenceChange(pref, true);
|
||||
assertTrue(channel.canBubble());
|
||||
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_off_channel() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = true;
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
|
||||
channel.setAllowBubbles(true);
|
||||
mController.onResume(appRow, channel, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.updateState(pref);
|
||||
|
||||
mController.onPreferenceChange(pref, false);
|
||||
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
|
||||
assertFalse(channel.canBubble());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_on_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = false;
|
||||
mController.onResume(appRow, null, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.updateState(pref);
|
||||
|
||||
mController.onPreferenceChange(pref, true);
|
||||
|
||||
assertTrue(appRow.allowBubbles);
|
||||
verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPreferenceChange_off_app() {
|
||||
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
|
||||
appRow.allowBubbles = true;
|
||||
mController.onResume(appRow, null, null, null);
|
||||
|
||||
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.updateState(pref);
|
||||
|
||||
mController.onPreferenceChange(pref, false);
|
||||
|
||||
assertFalse(appRow.allowBubbles);
|
||||
verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(false));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user