Merge "Update color correction red-green options text" into main
diff --git a/Android.bp b/Android.bp
index 4c472c8..8ca60b9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -82,12 +82,10 @@
"android.hardware.dumpstate-V1-java",
"android.hardware.dumpstate-V1.0-java",
"android.hardware.dumpstate-V1.1-java",
- "android.view.accessibility.flags-aconfig-java",
"com_android_server_accessibility_flags_lib",
"net-utils-framework-common",
"notification_flags_lib",
"securebox",
- "android.os.flags-aconfig-java",
"//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
"WindowManager-Shell-shared-desktopMode",
@@ -103,12 +101,9 @@
"contextualcards",
"development_settings_flag_lib",
"factory_reset_flags_lib",
- "fuelgauge-log-protos-lite",
+ "settings-protos-lite",
"fuelgauge-protos-lite",
- "settings-contextual-card-protos-lite",
- "settings-log-bridge-protos-lite",
"settings-logtags",
- "settings-telephony-protos-lite",
"statslog-settings",
"telephony_flags_core_java_lib",
"setupdesign-lottie-loading-layout",
diff --git a/aconfig/accessibility/accessibility_flags.aconfig b/aconfig/accessibility/accessibility_flags.aconfig
index 3092b8f..0338ed8 100644
--- a/aconfig/accessibility/accessibility_flags.aconfig
+++ b/aconfig/accessibility/accessibility_flags.aconfig
@@ -52,6 +52,16 @@
}
flag {
+ name: "fix_a11y_settings_search"
+ namespace: "accessibility"
+ description: "Fix the a11y related search items in Settings app"
+ bug: "333437173"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "hide_magnification_always_on_toggle_when_window_mode_only"
namespace: "accessibility"
description: "Decides whether to hide the magnification always on setting when capabilities is window mode only."
diff --git a/protos/Android.bp b/protos/Android.bp
index 560851a..4ab96a7 100644
--- a/protos/Android.bp
+++ b/protos/Android.bp
@@ -1,44 +1,12 @@
package {
default_team: "trendy_team_android_settings_app",
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "packages_apps_Settings_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["packages_apps_Settings_license"],
}
-java_library_static {
- name: "settings-contextual-card-protos-lite",
- host_supported: true,
- proto: {
- type: "lite",
- },
- srcs: ["contextual_card_list.proto"],
-}
-
-java_library_static {
- name: "settings-log-bridge-protos-lite",
- host_supported: true,
- proto: {
- type: "lite",
- },
- srcs: ["settings_log_bridge.proto"],
-}
-
-java_library_static {
- name: "settings-telephony-protos-lite",
- host_supported: true,
- proto: {
- type: "lite",
- },
- srcs: ["network_mode_choices.proto"],
-}
-
java_library {
- name: "fuelgauge-log-protos-lite",
+ name: "settings-protos-lite",
proto: {
type: "lite",
},
- srcs: ["fuelgauge_log.proto"],
+ srcs: ["*.proto"],
}
diff --git a/protos/spa_search_landing.proto b/protos/spa_search_landing.proto
new file mode 100644
index 0000000..02cca79
--- /dev/null
+++ b/protos/spa_search_landing.proto
@@ -0,0 +1,34 @@
+syntax = "proto2";
+
+package com.android.settings.spa;
+
+message SpaSearchLandingKey {
+ oneof page {
+ SpaSearchLandingSpaPage spa_page = 1;
+ SpaSearchLandingFragment fragment = 2;
+ }
+}
+
+message SpaSearchLandingSpaPage {
+ /** The destination of SPA page. */
+ optional string destination = 1;
+}
+
+message SpaSearchLandingFragment {
+ /** The fragment class name. */
+ optional string fragment_name = 1;
+
+ /** The key of the preference to highlight the item. */
+ optional string preference_key = 2;
+
+ /** The arguments passed to the page. */
+ map<string, BundleValue> arguments = 3;
+}
+
+/** A value in an Android Bundle. */
+message BundleValue {
+ oneof value {
+ /** A 32-bit signed integer value. */
+ int32 int_value = 1;
+ }
+}
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 4680936..d0422af 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1530,12 +1530,23 @@
<item>@*android:drawable/ic_zen_mode_type_bedtime</item>
<item>@*android:drawable/ic_zen_mode_type_driving</item>
<item>@*android:drawable/ic_zen_mode_type_immersive</item>
- <item>@*android:drawable/ic_zen_mode_type_managed</item>
- <item>@*android:drawable/ic_zen_mode_type_other</item>
<item>@*android:drawable/ic_zen_mode_type_schedule_calendar</item>
<item>@*android:drawable/ic_zen_mode_type_schedule_time</item>
+ <item>@*android:drawable/ic_zen_mode_icon_beach</item>
+ <item>@*android:drawable/ic_zen_mode_icon_camping</item>
<item>@*android:drawable/ic_zen_mode_type_theater</item>
+ <item>@*android:drawable/ic_zen_mode_icon_gaming</item>
+ <item>@*android:drawable/ic_zen_mode_icon_gym</item>
+ <item>@*android:drawable/ic_zen_mode_icon_ball_sports</item>
+ <item>@*android:drawable/ic_zen_mode_icon_martial_arts</item>
+ <item>@*android:drawable/ic_zen_mode_icon_swimming</item>
+ <item>@*android:drawable/ic_zen_mode_icon_hiking</item>
+ <item>@*android:drawable/ic_zen_mode_icon_golf</item>
+ <item>@*android:drawable/ic_zen_mode_icon_workshop</item>
+ <item>@*android:drawable/ic_zen_mode_icon_work</item>
+ <item>@*android:drawable/ic_zen_mode_type_other</item>
<item>@*android:drawable/ic_zen_mode_type_unknown</item>
+ <item>@*android:drawable/ic_zen_mode_type_managed</item>
</array>
<!-- TODO: b/333901673 - Complete list -->
@@ -1545,12 +1556,23 @@
<item>Bedtime</item>
<item>Driving</item>
<item>Immersive</item>
- <item>Managed</item>
- <item>Star</item>
<item>Calendar</item>
<item>Time</item>
+ <item>Beach</item>
+ <item>Camping</item>
<item>Theater</item>
- <item>Flower</item>
+ <item>Gaming</item>
+ <item>Gym</item>
+ <item>Ball sports</item>
+ <item>Martial arts</item>
+ <item>Swimming</item>
+ <item>Hiking</item>
+ <item>Golf</item>
+ <item>Workshop</item>
+ <item>Work</item>
+ <item>Star</item>
+ <item>Zen</item>
+ <item>Managed</item>
</string-array>
<!-- Packages that will not show Display over other apps permission -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6b4e79e..66b3b8c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7955,24 +7955,28 @@
<!-- Zen Modes: Title for the Modes option and associated settings page. [CHAR LIMIT=50]-->
<string name="zen_modes_list_title">Priority Modes</string>
+ <!-- Zen Modes: Intro text describing the feature. [CHAR LIMIT=NONE]-->
+ <string name="zen_modes_list_intro">Minimize distractions and take control of your attention with modes for sleep, work, driving, and everything in between.</string>
+
<!-- Zen Modes: Caption of the "add a mode" item in the modes list -->
- <string name="zen_modes_add_mode">Add a mode</string>
+ <string name="zen_modes_add_mode">Create your own mode</string>
<!-- Zen Modes: Summary for the Do not Disturb option and associated settings page. [CHAR LIMIT=240]-->
<string name="zen_mode_settings_summary">Only get notified by important people and apps</string>
<!-- Zen Modes: Option to add an automatic schedule for a mode. [CHAR_LIMIT=40] -->
- <string name="zen_mode_select_schedule">Select activation type</string>
+ <string name="zen_mode_select_schedule">Set a schedule</string>
+
+ <!-- Priority Modes: Title of the dialog used to choose an automatic schedule for a mode. [CHAR_LIMIT=40] -->
+ <string name="zen_mode_select_schedule_title">Schedule based on</string>
<!-- Priority Modes: Option to choose a time-based schedule for a mode. [CHAR_LIMIT=40] -->
- <string name="zen_mode_select_schedule_time">Time</string>
+ <string name="zen_mode_select_schedule_time">Day and time</string>
<!-- Priority Modes: Example text for the option to choose a time-based schedule for a mode. [CHAR_LIMIT=60] -->
- <string name="zen_mode_select_schedule_time_example">Ex. \"9:30 – 5:00 PM\"</string>
+ <string name="zen_mode_select_schedule_time_example">\"9 AM - 5 PM weekdays\"</string>
<!-- Priority Modes: Option to choose a calendar-events-based schedule for a mode. [CHAR_LIMIT=40] -->
- <string name="zen_mode_select_schedule_calendar">Calendar</string>
- <!-- Priority Modes: Example text for the option to choose a calendar-events-based schedule for a mode. [CHAR_LIMIT=60] -->
- <string name="zen_mode_select_schedule_calendar_example">Ex. \"Personal calendar\"</string>
+ <string name="zen_mode_select_schedule_calendar">Calendar events</string>
<!-- Priority Modes: Short text that indicates that a mode is currently on (active). [CHAR_LIMIT=10] -->
<string name="zen_mode_active_text">ON</string>
@@ -7992,6 +7996,15 @@
<!-- Priority Modes: Option to add a "custom" mode in the "Add a mode" dialog. [CHAR_LIMIT=20] -->
<string name="zen_mode_new_option_custom">Custom</string>
+ <!-- Priority Modes: Caption of the button to turn on a mode [CHAR LIMIT=20] -->
+ <string name="zen_mode_action_activate">Turn on now</string>
+
+ <!-- Priority Modes: Caption of the button to turn off a currently active mode [CHAR LIMIT=20] -->
+ <string name="zen_mode_action_deactivate">Turn off</string>
+
+ <!-- Priority Modes: Text to display if a mode isn't found [CHAR LIMIT=40] -->
+ <string name="zen_mode_not_found_text">Mode not found</string>
+
<!-- Subtitle for the Do not Disturb slice. [CHAR LIMIT=50]-->
<string name="zen_mode_slice_subtitle">Limit interruptions</string>
@@ -8029,19 +8042,17 @@
<string name="zen_mode_automatic_rule_settings_page_title">Schedule</string>
<!-- Do not disturb: Title for settings section describing when the rule turns on automatically [CHAR LIMIT=30] -->
- <string name="zen_mode_automatic_trigger_title">Turn on automatically</string>
+ <string name="zen_mode_automatic_trigger_title">When to turn on automatically</string>
- <!-- Do not disturb: Title prompting a user to choose a calendar to use for an automatic rule [CHAR LIMIT=30] -->
- <string name="zen_mode_set_calendar_title">Add a calendar</string>
-
- <!-- Do not disturb: Link text prompting a user to click through to setting a calendar [CHAR LIMIT=40] -->
- <string name="zen_mode_set_calendar_link">Use your calendar</string>
-
- <!-- Do not disturb: Title on the page where users choose a calendar to determine the schedule for an automatically-triggered DND rule. [CHAR LIMIT=30] -->
- <string name="zen_mode_set_calendar_category_title">Schedule</string>
+ <!-- Priority Modes: Title prompting a user to choose a calendar to use for an automatic rule [CHAR LIMIT=30] -->
+ <string name="zen_mode_set_calendar_title">Event schedule</string>
+ <!-- Priority Modes: Title prompting a user to choose a calendar to use for an automatic rule [CHAR LIMIT=30] -->
+ <string name="zen_mode_set_calendar_which_calendar">Turn on during events for</string>
+ <!-- Priority Modes: Title prompting a user to choose a calendar to use for an automatic rule [CHAR LIMIT=30] -->
+ <string name="zen_mode_set_calendar_which_reply">Where invite reply is</string>
<!-- Do not disturb: Title prompting a user to set a time-based schedule to use for an automatic rule [CHAR LIMIT=30] -->
- <string name="zen_mode_set_schedule_title">Set a schedule</string>
+ <string name="zen_mode_set_schedule_title">Time schedule</string>
<!-- Do not disturb: Link text prompting a user to click through to setting a time-based schedule [CHAR LIMIT=40] -->
<string name="zen_mode_set_schedule_link">Schedule</string>
@@ -8049,9 +8060,6 @@
<!-- Duration in hours and minutes for the length of a Do Not Disturb schedule. For example "1 hr, 22 min" -->
<string name="zen_mode_schedule_duration"><xliff:g example="10" id="hours">%1$d</xliff:g> hr, <xliff:g example="20" id="minutes">%2$d</xliff:g> min</string>
- <!-- Priority Modes: Label for switch to enable/disable a rule turning on automatically; links to an app-provided configuration page [CHAR LIMIT=40] -->
- <string name="zen_mode_configuration_link_title">Turn on automatically</string>
-
<!-- Do not disturb: Title do not disturb settings representing automatic (scheduled) do not disturb rules. [CHAR LIMIT=30] -->
<string name="zen_mode_schedule_category_title">Schedule</string>
@@ -8080,9 +8088,9 @@
<string name="zen_mode_visual_signals_settings_subtitle">Allow visual signals</string>
<!-- Priority Modes: mode page section title [CHAR LIMIT=80] -->
- <string name="mode_interruption_filter_title">Stay focused</string>
+ <string name="mode_interruption_filter_title">Notification filters</string>
<!-- Priority Modes: mode page section title [CHAR LIMIT=80] -->
- <string name="mode_device_effects_title">Additional actions</string>
+ <string name="mode_device_effects_title">More settings</string>
<!-- Summary for the Sound Do not Disturb option when DND isn't currently on. [CHAR LIMIT=NONE]-->
<string name="modes_sound_summary_off">
@@ -8133,7 +8141,7 @@
}
</string>
<!-- Modes: setting for whether the mode should filter (silence/hide) notifications/volume streams -->
- <string name="mode_notification_filter_title">Filter interruptions</string>
+ <string name="mode_notification_filter_title">Limit what can notify you</string>
<!-- Modes: subtext when a mode is not filtering (silence/hide) notifications/volume streams -->
<string name="mode_no_notification_filter">No interruptions are filtered</string>
@@ -9430,7 +9438,7 @@
<string name="zen_mode_rename_title">Edit mode</string>
<!-- Priority Modes: Title for the "add mode" screen [CHAR LIMIT=20] -->
- <string name="zen_mode_new_custom_title">Add mode</string>
+ <string name="zen_mode_new_custom_title">Create a mode</string>
<!-- Priority Modes: Default name for new custom modes [CHAR LIMIT=30] -->
<string name="zen_mode_new_custom_default_name">Custom mode</string>
@@ -9441,26 +9449,26 @@
<!-- Priority Modes: Trigger title for modes of type SCHEDULE_CALENDAR. [CHAR LIMIT=30] -->
<string name="zen_mode_trigger_title_schedule_calendar">Calendar events</string>
<!-- Priority Modes: Trigger title for modes of type BEDTIME. [CHAR LIMIT=30] -->
- <string name="zen_mode_trigger_title_bedtime">Sleep schedule</string>
+ <string name="zen_mode_trigger_title_bedtime">Bedtime routine</string>
<!-- Priority Modes: Trigger title for modes of type DRIVING. [CHAR LIMIT=30] -->
<string name="zen_mode_trigger_title_driving">While driving</string>
<!-- Priority Modes: Generic trigger title for modes of other types [CHAR LIMIT=30] -->
- <string name="zen_mode_trigger_title_generic">Linked to app</string>
+ <string name="zen_mode_trigger_title_generic">App settings</string>
<!-- Priority Modes: Generic trigger summary for modes where the owner app did not provide a triggerDescription but did provide a configurationActivity to call [CHAR LIMIT=60] -->
<string name="zen_mode_trigger_summary_settings_in_app">Info and settings in <xliff:g id="app_name" example="The Awesome App">%1$s</xliff:g></string>
<!-- Priority Modes: Generic trigger summary for modes where the owner app did not provide neither a triggerDescription nor a configurationActivity to call [CHAR LIMIT=60] -->
<string name="zen_mode_trigger_summary_managed_by_app">Managed by <xliff:g id="app_name" example="The Awesome App">%1$s</xliff:g></string>
- <!-- Priority Modes: Title of the confirmation dialog for disabling an enabled mode [CHAR LIMIT=30] -->
- <string name="zen_mode_confirm_disable_title">Disable Mode</string>
+ <!-- Priority Modes: Title of the confirmation dialog for disabling an enabled mode [CHAR LIMIT=20] -->
+ <string name="zen_mode_confirm_disable_mode_title">Disable <xliff:g id="mode_name" example="Driving Mode">%1$s</xliff:g>?</string>
<!-- Priority Modes: Message body of the confirmation dialog for disabling an enabled mode [CHAR LIMIT=NONE] -->
- <string name="zen_mode_confirm_disable_message">If you disable this feature, the mode will no longer work as intended and its settings will be hidden.</string>
+ <string name="zen_mode_confirm_disable_message">This mode will never turn on when disabled</string>
<!-- Priority Modes: Button to disable a mode [CHAR LIMIT=20] -->
<string name="zen_mode_action_disable">Disable</string>
- <!-- Priority Modes: Title of the confirmation dialog for enabling a disabled mode [CHAR LIMIT=30] -->
- <string name="zen_mode_confirm_enable_title">Enable Mode</string>
+ <!-- Priority Modes: Title of the confirmation dialog for enabling a disabled mode [CHAR LIMIT=20] -->
+ <string name="zen_mode_confirm_enable_mode_title">Enable <xliff:g id="mode_name" example="Driving Mode">%1$s</xliff:g>?</string>
<!-- Priority Modes: Message body of the confirmation dialog for enabling a disabled mode [CHAR LIMIT=NONE] -->
- <string name="zen_mode_confirm_enable_message">If you enable this feature, the mode will activate automatically according to its schedule.</string>
+ <string name="zen_mode_confirm_enable_message">This mode may turn on automatically based on its settings</string>
<!-- Priority Modes: Button to disable a mode [CHAR LIMIT=20] -->
<string name="zen_mode_action_enable">Enable</string>
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index 51cbbe6..bed6de8 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -112,10 +112,12 @@
android:selectable="false"
settings:searchable="false"/>
+ <!-- Settings search is handled by MmsMessageSearchItem. -->
<SwitchPreferenceCompat
android:key="mms_message"
android:title="@string/mms_message_title"
android:summary="@string/mms_message_summary"
+ settings:searchable="false"
settings:controller="com.android.settings.network.telephony.MmsMessagePreferenceController"/>
<SwitchPreferenceCompat
diff --git a/res/xml/modes_calls_settings.xml b/res/xml/modes_calls_settings.xml
index f2ba7f1..b564020 100644
--- a/res/xml/modes_calls_settings.xml
+++ b/res/xml/modes_calls_settings.xml
@@ -24,14 +24,21 @@
<PreferenceCategory
android:key="zen_mode_settings_category_calls"
- android:title="@string/zen_mode_calls_header"
- settings:allowDividerBelow="true">
+ android:title="@string/zen_mode_calls_header">
</PreferenceCategory>
+ <com.android.settings.applications.SpacePreference
+ android:key="hearing_aid_space_layout"
+ android:layout_height="16dp"/>
+
<!-- Repeat callers -->
<SwitchPreferenceCompat
android:key="zen_mode_repeat_callers"
- android:title="@string/zen_mode_repeat_callers_title"
- settings:allowDividerAbove="true"/>
+ android:title="@string/zen_mode_repeat_callers_title" />
+ <com.android.settingslib.widget.FooterPreference
+ android:key="info_footer"
+ android:title="@string/zen_mode_calls_footer"
+ android:selectable="false"
+ settings:searchable="false"/>
</PreferenceScreen>
diff --git a/res/xml/modes_list_settings.xml b/res/xml/modes_list_settings.xml
index 8207af0..5c67218 100644
--- a/res/xml/modes_list_settings.xml
+++ b/res/xml/modes_list_settings.xml
@@ -20,11 +20,12 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/zen_modes_list_title">
- <!-- TODO: b/333682392 - add strings for summary as appropriate -->
+ <com.android.settingslib.widget.TopIntroPreference
+ android:title="@string/zen_modes_list_intro" />
<PreferenceCategory
android:key="zen_modes_list">
- <!-- Preferences leading to rules are added in this PreferenceCategory. -->
+ <!-- Preferences leading to individual mode pages are added in this PreferenceCategory. -->
</PreferenceCategory>
<Preference
diff --git a/res/xml/modes_messages_settings.xml b/res/xml/modes_messages_settings.xml
index d4aee3d..b87de0b 100644
--- a/res/xml/modes_messages_settings.xml
+++ b/res/xml/modes_messages_settings.xml
@@ -26,4 +26,10 @@
android:key="zen_mode_settings_category_messages"
android:title="@string/zen_mode_messages_header">
</PreferenceCategory>
+
+ <com.android.settingslib.widget.FooterPreference
+ android:key="info_footer"
+ android:title="@string/zen_mode_messages_footer"
+ android:selectable="false"
+ settings:searchable="false"/>
</PreferenceScreen>
diff --git a/res/xml/modes_people_settings.xml b/res/xml/modes_people_settings.xml
index d58b2d7..af292ad 100644
--- a/res/xml/modes_people_settings.xml
+++ b/res/xml/modes_people_settings.xml
@@ -17,6 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/zen_category_people" >
<!-- Calls & Messages -->
@@ -34,4 +35,10 @@
android:title="@string/zen_mode_calls_title"
android:icon="@drawable/ic_zen_mode_people_calls" />
</PreferenceCategory>
+
+ <com.android.settingslib.widget.FooterPreference
+ android:key="info_footer"
+ android:title="@string/zen_mode_people_footer"
+ android:selectable="false"
+ settings:searchable="false"/>
</PreferenceScreen>
diff --git a/res/xml/modes_set_calendar.xml b/res/xml/modes_set_calendar.xml
index 02eb26e..be094f2 100644
--- a/res/xml/modes_set_calendar.xml
+++ b/res/xml/modes_set_calendar.xml
@@ -23,20 +23,18 @@
android:title="@string/zen_mode_set_calendar_title">
<PreferenceCategory
- android:key="zen_mode_event_category"
- android:title="@string/zen_mode_set_calendar_category_title">
+ android:key="zen_mode_event_category">
- <!-- TODO: b/333682392 - use correct strings for below two prefs -->
<!-- During events for -->
<DropDownPreference
android:key="calendar"
- android:title="@string/zen_mode_event_rule_calendar"
+ android:title="@string/zen_mode_set_calendar_which_calendar"
android:summary="%s" />
<!-- Where reply is -->
<DropDownPreference
android:key="reply"
- android:title="@string/zen_mode_event_rule_reply"
+ android:title="@string/zen_mode_set_calendar_which_reply"
android:summary="%s" />
</PreferenceCategory>
diff --git a/res/xml/more_security_privacy_settings.xml b/res/xml/more_security_privacy_settings.xml
index 799ff1e..f200493 100644
--- a/res/xml/more_security_privacy_settings.xml
+++ b/res/xml/more_security_privacy_settings.xml
@@ -92,7 +92,7 @@
"com.android.settings.sound.MediaControlsLockScreenPreferenceController" />
<!-- Allow software fallback for camera extensions -->
- <SwitchPreference
+ <SwitchPreferenceCompat
android:key="privacy_camera_extensions_fallback"
android:title="@string/camera_extensions_fallback_title"
android:summary="@string/camera_extensions_fallback_description"
diff --git a/res/xml/security_settings_fingerprint_limbo.xml b/res/xml/security_settings_fingerprint_limbo.xml
index 02a3dfb..8b97c83 100644
--- a/res/xml/security_settings_fingerprint_limbo.xml
+++ b/res/xml/security_settings_fingerprint_limbo.xml
@@ -18,7 +18,8 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
- android:title="@string/security_settings_fingerprint_preference_title">
+ android:title="@string/security_settings_fingerprint_preference_title"
+ settings:searchable="false">
<PreferenceCategory
android:key="security_settings_fingerprints_enrolled"
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 92bf125..f3eab93 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -613,7 +613,7 @@
}
}
- private boolean isAnyHardKeyboardsExist() {
+ static boolean isAnyHardKeyboardsExist() {
for (int deviceId : InputDevice.getDeviceIds()) {
final InputDevice device = InputDevice.getDevice(deviceId);
if (device != null && !device.isVirtual() && device.isFullKeyboard()) {
diff --git a/src/com/android/settings/accessibility/KeyboardBounceKeyPreferenceController.java b/src/com/android/settings/accessibility/KeyboardBounceKeyPreferenceController.java
index 6d988ac..840caa6 100644
--- a/src/com/android/settings/accessibility/KeyboardBounceKeyPreferenceController.java
+++ b/src/com/android/settings/accessibility/KeyboardBounceKeyPreferenceController.java
@@ -19,16 +19,21 @@
import android.content.Context;
import android.hardware.input.InputSettings;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
+import java.util.List;
+
/**
* A toggle preference controller for keyboard bounce key.
*/
public class KeyboardBounceKeyPreferenceController extends TogglePreferenceController {
-
+ private static final String TAG = "BounceKeyPrefController";
static final String PREF_KEY = "toggle_keyboard_bounce_keys";
public KeyboardBounceKeyPreferenceController(Context context, String preferenceKey) {
@@ -58,4 +63,17 @@
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
+
+ @Override
+ public void updateNonIndexableKeys(@NonNull List<String> keys) {
+ super.updateNonIndexableKeys(keys);
+
+ if (Flags.fixA11ySettingsSearch() && !AccessibilitySettings.isAnyHardKeyboardsExist()) {
+ if (keys.contains(getPreferenceKey())) {
+ Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list.");
+ return;
+ }
+ keys.add(getPreferenceKey());
+ }
+ }
}
diff --git a/src/com/android/settings/accessibility/KeyboardSlowKeyPreferenceController.java b/src/com/android/settings/accessibility/KeyboardSlowKeyPreferenceController.java
index 8bd2316..bb9d950 100644
--- a/src/com/android/settings/accessibility/KeyboardSlowKeyPreferenceController.java
+++ b/src/com/android/settings/accessibility/KeyboardSlowKeyPreferenceController.java
@@ -19,15 +19,21 @@
import android.content.Context;
import android.hardware.input.InputSettings;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
+import java.util.List;
+
/**
* A toggle preference controller for keyboard slow key.
*/
public class KeyboardSlowKeyPreferenceController extends TogglePreferenceController {
+ private static final String TAG = "SlowKeyPrefController";
static final String PREF_KEY = "toggle_keyboard_slow_keys";
@@ -58,4 +64,17 @@
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
+
+ @Override
+ public void updateNonIndexableKeys(@NonNull List<String> keys) {
+ super.updateNonIndexableKeys(keys);
+
+ if (Flags.fixA11ySettingsSearch() && !AccessibilitySettings.isAnyHardKeyboardsExist()) {
+ if (keys.contains(getPreferenceKey())) {
+ Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list.");
+ return;
+ }
+ keys.add(getPreferenceKey());
+ }
+ }
}
diff --git a/src/com/android/settings/accessibility/KeyboardStickyKeyPreferenceController.java b/src/com/android/settings/accessibility/KeyboardStickyKeyPreferenceController.java
index ee5559d..c896c9c 100644
--- a/src/com/android/settings/accessibility/KeyboardStickyKeyPreferenceController.java
+++ b/src/com/android/settings/accessibility/KeyboardStickyKeyPreferenceController.java
@@ -19,15 +19,20 @@
import android.content.Context;
import android.hardware.input.InputSettings;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
+import java.util.List;
+
/**
* A toggle preference controller for keyboard sticky key.
*/
public class KeyboardStickyKeyPreferenceController extends TogglePreferenceController {
-
+ private static final String TAG = "StickyKeyPrefController";
static final String PREF_KEY = "toggle_keyboard_sticky_keys";
public KeyboardStickyKeyPreferenceController(Context context, String preferenceKey) {
@@ -55,4 +60,17 @@
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
+
+ @Override
+ public void updateNonIndexableKeys(@NonNull List<String> keys) {
+ super.updateNonIndexableKeys(keys);
+
+ if (Flags.fixA11ySettingsSearch() && !AccessibilitySettings.isAnyHardKeyboardsExist()) {
+ if (keys.contains(getPreferenceKey())) {
+ Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list.");
+ return;
+ }
+ keys.add(getPreferenceKey());
+ }
+ }
}
diff --git a/src/com/android/settings/activityembedding/EmbeddedDeepLinkUtils.kt b/src/com/android/settings/activityembedding/EmbeddedDeepLinkUtils.kt
index ab32fc1..9bbb723 100644
--- a/src/com/android/settings/activityembedding/EmbeddedDeepLinkUtils.kt
+++ b/src/com/android/settings/activityembedding/EmbeddedDeepLinkUtils.kt
@@ -34,7 +34,7 @@
private const val TAG = "EmbeddedDeepLinkUtils"
@JvmStatic
- fun Activity.tryStartMultiPaneDeepLink(
+ fun Context.tryStartMultiPaneDeepLink(
intent: Intent,
highlightMenuKey: String? = null,
): Boolean {
diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
index d40a075..5df5914 100644
--- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
+++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
@@ -72,9 +72,9 @@
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.widget.LayoutPreference;
-import java.util.Collections;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.Optional;
-import java.util.Set;
public class InteractAcrossProfilesDetails extends AppInfoBase
implements Preference.OnPreferenceClickListener {
@@ -571,8 +571,8 @@
String disallowedPackagesString = Settings.Global.getString(getContentResolver(),
CONNECTED_APPS_DISALLOWED_PACKAGES);
- Set<String> allowedPackagesSet = getSetFromString(allowedPackagesString);
- Set<String> disallowedPackagesSet = getSetFromString(disallowedPackagesString);
+ HashSet<String> allowedPackagesSet = getSetFromString(allowedPackagesString);
+ HashSet<String> disallowedPackagesSet = getSetFromString(disallowedPackagesString);
if (enabled) {
allowedPackagesSet.add(crossProfilePackage);
@@ -592,9 +592,9 @@
String.join(",", disallowedPackagesSet));
}
- private Set<String> getSetFromString(String packages) {
+ private HashSet<String> getSetFromString(String packages) {
return Optional.ofNullable(packages)
- .map(pkg -> Set.of(pkg.split(",")))
- .orElse(Collections.emptySet());
+ .map(pkg -> new HashSet<>(Arrays.asList(pkg.split(","))))
+ .orElseGet(HashSet::new);
}
}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index 9cda327..65d9366 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -159,11 +159,27 @@
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.security_settings_fingerprint) {
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return super.isPageSearchEnabled(context) &&
+ hasEnrolledFingerprints(context);
+ }
+
@Override
public List<AbstractPreferenceController>
createPreferenceControllers(Context context) {
return createThePreferenceControllers(context);
}
+
+ private boolean hasEnrolledFingerprints(Context context) {
+ final FingerprintManager fingerprintManager =
+ Utils.getFingerprintManagerOrNull(context);
+ if (fingerprintManager != null) {
+ return fingerprintManager.hasEnrolledTemplates(UserHandle.myUserId());
+ }
+ return false;
+ }
};
private static List<AbstractPreferenceController> createThePreferenceControllers(Context
diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
index 183de7f..bb56c50 100644
--- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
@@ -23,7 +23,6 @@
import androidx.preference.Preference;
import com.android.settings.connecteddevice.DevicePreferenceCallback;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -77,7 +76,7 @@
// It would show in Available Devices group if the audio sharing flag is disabled or
// the device is not in the audio sharing session.
if (cachedDevice.isConnectedLeAudioDevice()) {
- if (AudioSharingUtils.isFeatureEnabled()
+ if (BluetoothUtils.isAudioSharingEnabled()
&& BluetoothUtils.hasConnectedBroadcastSource(
cachedDevice, mLocalBtManager)) {
Log.d(
diff --git a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
index 420fb97..c67995a 100644
--- a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
@@ -45,7 +45,6 @@
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
import com.android.settings.bluetooth.Utils;
import com.android.settings.connecteddevice.audiosharing.AudioSharingDialogHandler;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory;
@@ -180,7 +179,7 @@
super(context, KEY);
mBtManager = Utils.getLocalBtManager(mContext);
mExecutor = Executors.newSingleThreadExecutor();
- if (AudioSharingUtils.isFeatureEnabled()) {
+ if (BluetoothUtils.isAudioSharingEnabled()) {
mBroadcast =
mBtManager == null
? null
@@ -201,7 +200,7 @@
Log.d(TAG, "onStart() Bluetooth is not supported on this device");
return;
}
- if (AudioSharingUtils.isFeatureEnabled()) {
+ if (BluetoothUtils.isAudioSharingEnabled()) {
registerAudioSharingCallbacks();
}
mBtManager.getEventManager().registerCallback(this);
@@ -217,7 +216,7 @@
Log.d(TAG, "onStop() Bluetooth is not supported on this device");
return;
}
- if (AudioSharingUtils.isFeatureEnabled()) {
+ if (BluetoothUtils.isAudioSharingEnabled()) {
unregisterAudioSharingCallbacks();
}
if (mBluetoothDeviceUpdater != null) {
@@ -279,7 +278,7 @@
public void onDeviceClick(Preference preference) {
final CachedBluetoothDevice cachedDevice =
((BluetoothDevicePreference) preference).getBluetoothDevice();
- if (AudioSharingUtils.isFeatureEnabled() && mDialogHandler != null) {
+ if (BluetoothUtils.isAudioSharingEnabled() && mDialogHandler != null) {
mDialogHandler.handleDeviceConnected(cachedDevice, /* userTriggered= */ true);
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
.action(mContext, SettingsEnums.ACTION_MEDIA_DEVICE_CLICK);
@@ -295,7 +294,7 @@
fragment.getContext(),
AvailableMediaDeviceGroupController.this,
fragment.getMetricsCategory());
- if (AudioSharingUtils.isFeatureEnabled()) {
+ if (BluetoothUtils.isAudioSharingEnabled()) {
mDialogHandler = new AudioSharingDialogHandler(mContext, fragment);
}
}
@@ -342,8 +341,8 @@
if (isAudioModeOngoingCall(mContext)) {
// in phone call
titleResId = R.string.connected_device_call_device_title;
- } else if (AudioSharingUtils.isFeatureEnabled()
- && AudioSharingUtils.isBroadcasting(mBtManager)) {
+ } else if (BluetoothUtils.isAudioSharingEnabled()
+ && BluetoothUtils.isBroadcasting(mBtManager)) {
// without phone call, in audio sharing
titleResId = R.string.audio_sharing_media_device_group_title;
} else {
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
index 27001d6..5184176 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
@@ -28,13 +28,13 @@
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.connecteddevice.audiosharing.AudioSharingDevicePreferenceController;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
import com.android.settings.core.SettingsUIDeviceConfig;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.overlay.SurveyFeatureProvider;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.slices.SlicePreferenceController;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.HearingAidStatsLogUtils;
import com.android.settingslib.search.SearchIndexable;
@@ -87,7 +87,7 @@
+ ", action : "
+ action);
}
- if (AudioSharingUtils.isFeatureEnabled()) {
+ if (BluetoothUtils.isAudioSharingEnabled()) {
use(AudioSharingDevicePreferenceController.class).init(this);
}
use(AvailableMediaDeviceGroupController.class).init(this);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingActivity.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingActivity.java
index 1ec53f9..08b21a1 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingActivity.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingActivity.java
@@ -19,12 +19,13 @@
import android.os.Bundle;
import com.android.settings.SettingsActivity;
+import com.android.settingslib.bluetooth.BluetoothUtils;
public class AudioSharingActivity extends SettingsActivity {
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
- if (!AudioSharingUtils.isFeatureEnabled()) {
+ if (!BluetoothUtils.isAudioSharingEnabled()) {
finish();
}
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
index e933e41..96c5d45 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
@@ -29,6 +29,7 @@
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -54,7 +55,7 @@
@Override
public int getAvailabilityStatus() {
- return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return BluetoothUtils.isAudioSharingEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java
index 21eb4d1..60a8a13 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java
@@ -55,7 +55,7 @@
if (isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)) {
// If device is LE audio device and has a broadcast source,
// it would show in audio sharing devices group.
- if (AudioSharingUtils.isFeatureEnabled()
+ if (BluetoothUtils.isAudioSharingEnabled()
&& cachedDevice.isConnectedLeAudioDevice()
&& BluetoothUtils.hasConnectedBroadcastSource(cachedDevice, mLocalBtManager)) {
isFilterMatched = true;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragment.java
index 5e0ec07..fa9f94d 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragment.java
@@ -29,6 +29,7 @@
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import java.util.List;
@@ -36,6 +37,7 @@
public class AudioSharingCallAudioDialogFragment extends InstrumentedDialogFragment {
private static final String TAG = "CallsAndAlarmsDialog";
private static final String BUNDLE_KEY_DEVICE_ITEMS = "bundle_key_device_items";
+ private static final String BUNDLE_KEY_CHECKED_ITEM_INDEX = "bundle_key_checked_index";
// The host creates an instance of this dialog fragment must implement this interface to receive
// event callbacks.
@@ -65,8 +67,9 @@
public static void show(
@NonNull Fragment host,
@NonNull List<AudioSharingDeviceItem> deviceItems,
+ int checkedItemIndex,
@NonNull DialogEventListener listener) {
- if (!AudioSharingUtils.isFeatureEnabled()) return;
+ if (!BluetoothUtils.isAudioSharingEnabled()) return;
final FragmentManager manager;
try {
manager = host.getChildFragmentManager();
@@ -78,6 +81,7 @@
if (manager.findFragmentByTag(TAG) == null) {
final Bundle bundle = new Bundle();
bundle.putParcelableList(BUNDLE_KEY_DEVICE_ITEMS, deviceItems);
+ bundle.putInt(BUNDLE_KEY_CHECKED_ITEM_INDEX, checkedItemIndex);
final AudioSharingCallAudioDialogFragment dialog =
new AudioSharingCallAudioDialogFragment();
dialog.setArguments(bundle);
@@ -91,6 +95,7 @@
Bundle arguments = requireArguments();
List<AudioSharingDeviceItem> deviceItems =
arguments.getParcelable(BUNDLE_KEY_DEVICE_ITEMS, List.class);
+ int checkedItemIndex = arguments.getInt(BUNDLE_KEY_CHECKED_ITEM_INDEX, -1);
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity())
.setTitle(R.string.audio_sharing_call_audio_title);
@@ -98,18 +103,11 @@
Log.d(TAG, "Create dialog error: null deviceItems");
return builder.create();
}
- int checkedItem = -1;
- for (AudioSharingDeviceItem item : deviceItems) {
- int fallbackActiveGroupId = AudioSharingUtils.getFallbackActiveGroupId(getContext());
- if (item.getGroupId() == fallbackActiveGroupId) {
- checkedItem = deviceItems.indexOf(item);
- }
- }
String[] choices =
deviceItems.stream().map(AudioSharingDeviceItem::getName).toArray(String[]::new);
builder.setSingleChoiceItems(
choices,
- checkedItem,
+ checkedItemIndex,
(dialog, which) -> {
if (sListener != null) {
sListener.onItemClick(deviceItems.get(which));
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
index 6ba7183..33c1a6c 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
@@ -16,8 +16,6 @@
package com.android.settings.connecteddevice.audiosharing;
-import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID;
-
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothCsipSetCoordinator;
@@ -197,13 +195,15 @@
}
updateDeviceItemsInSharingSession();
if (!mDeviceItemsInSharingSession.isEmpty()) {
+ int checkedItemIndex = getActiveItemIndex(mDeviceItemsInSharingSession);
AudioSharingCallAudioDialogFragment.show(
mFragment,
mDeviceItemsInSharingSession,
+ checkedItemIndex,
(AudioSharingDeviceItem item) -> {
int currentGroupId =
- AudioSharingUtils.getFallbackActiveGroupId(
- mContext);
+ BluetoothUtils.getPrimaryGroupIdForBroadcast(
+ mContext.getContentResolver());
if (item.getGroupId() == currentGroupId) {
Log.d(
TAG,
@@ -220,7 +220,7 @@
TAG,
"Set fallback active device: "
+ lead.getDevice()
- .getAnonymizedAddress());
+ .getAnonymizedAddress());
lead.setActive();
logCallAudioDeviceChange(currentGroupId, lead);
} else {
@@ -300,7 +300,7 @@
Log.d(TAG, "registerCallbacks()");
mEventManager.registerCallback(this);
mContentResolver.registerContentObserver(
- Settings.Secure.getUriFor(SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID),
+ Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mSettingsObserver);
mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
@@ -347,7 +347,8 @@
*/
private void updateSummary() {
updateDeviceItemsInSharingSession();
- int fallbackActiveGroupId = AudioSharingUtils.getFallbackActiveGroupId(mContext);
+ int fallbackActiveGroupId = BluetoothUtils.getPrimaryGroupIdForBroadcast(
+ mContext.getContentResolver());
if (fallbackActiveGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
for (AudioSharingDeviceItem item : mDeviceItemsInSharingSession) {
if (item.getGroupId() == fallbackActiveGroupId) {
@@ -386,6 +387,18 @@
mBtManager, mGroupedConnectedDevices, /* filterByInSharing= */ true);
}
+ private int getActiveItemIndex(List<AudioSharingDeviceItem> deviceItems) {
+ int checkedItemIndex = -1;
+ int fallbackActiveGroupId =
+ BluetoothUtils.getPrimaryGroupIdForBroadcast(mContext.getContentResolver());
+ for (AudioSharingDeviceItem item : deviceItems) {
+ if (item.getGroupId() == fallbackActiveGroupId) {
+ return deviceItems.indexOf(item);
+ }
+ }
+ return checkedItemIndex;
+ }
+
@VisibleForTesting
void logCallAudioDeviceChange(int currentGroupId, CachedBluetoothDevice target) {
var unused =
@@ -393,7 +406,7 @@
() -> {
ChangeCallAudioType type = ChangeCallAudioType.UNKNOWN;
if (mCacheManager != null) {
- int targetDeviceGroupId = AudioSharingUtils.getGroupId(target);
+ int targetDeviceGroupId = BluetoothUtils.getGroupId(target);
List<BluetoothDevice> mostRecentDevices =
BluetoothAdapter.getDefaultAdapter()
.getMostRecentlyConnectedDevices();
@@ -405,7 +418,7 @@
mCacheManager.findDevice(device);
int groupId =
cachedDevice != null
- ? AudioSharingUtils.getGroupId(cachedDevice)
+ ? BluetoothUtils.getGroupId(cachedDevice)
: BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
if (groupId == targetDeviceGroupId) {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCompatibilityPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCompatibilityPreferenceController.java
index 42a9038..52df1d3 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCompatibilityPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCompatibilityPreferenceController.java
@@ -34,6 +34,7 @@
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -154,7 +155,7 @@
@Override
public int getAvailabilityStatus() {
- return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return BluetoothUtils.isAudioSharingEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -242,7 +243,7 @@
var unused =
ThreadUtils.postOnBackgroundThread(
() -> {
- boolean isBroadcasting = AudioSharingUtils.isBroadcasting(mBtManager);
+ boolean isBroadcasting = BluetoothUtils.isBroadcasting(mBtManager);
AudioSharingUtils.postOnMainThread(
mContext,
() -> {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingConfirmDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingConfirmDialogFragment.java
index 61b1df1..3750cf1 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingConfirmDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingConfirmDialogFragment.java
@@ -29,6 +29,7 @@
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.bluetooth.BluetoothUtils;
public class AudioSharingConfirmDialogFragment extends InstrumentedDialogFragment {
private static final String TAG = "AudioSharingConfirmDialog";
@@ -44,7 +45,7 @@
* @param host The Fragment this dialog will be hosted.
*/
public static void show(Fragment host) {
- if (!AudioSharingUtils.isFeatureEnabled()) return;
+ if (!BluetoothUtils.isAudioSharingEnabled()) return;
final FragmentManager manager;
try {
manager = host.getChildFragmentManager();
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
index cc883fe..a0c0b44 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
@@ -296,7 +296,7 @@
@Override
public int getAvailabilityStatus() {
- return AudioSharingUtils.isFeatureEnabled() && mBluetoothDeviceUpdater != null
+ return BluetoothUtils.isAudioSharingEnabled() && mBluetoothDeviceUpdater != null
? AVAILABLE_UNSEARCHABLE
: UNSUPPORTED_ON_DEVICE;
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
index 0fbb892..2e93539 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
@@ -67,7 +67,7 @@
// If device is LE audio device and in a sharing session on current sharing device,
// it would show in volume control group.
if (cachedDevice.isConnectedLeAudioDevice()
- && AudioSharingUtils.isBroadcasting(mBtManager)
+ && BluetoothUtils.isBroadcasting(mBtManager)
&& BluetoothUtils.hasConnectedBroadcastSource(cachedDevice, mBtManager)) {
isFilterMatched = true;
}
@@ -103,11 +103,11 @@
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress();
- int groupId = AudioSharingUtils.getGroupId(cachedDevice);
+ int groupId = BluetoothUtils.getGroupId(cachedDevice);
if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
&& groupId
- == AudioSharingUtils.getFallbackActiveGroupId(
- mContext)) {
+ == BluetoothUtils.getPrimaryGroupIdForBroadcast(
+ mContext.getContentResolver())) {
// Set media stream volume for primary buds, audio manager will
// update all buds volume in the audio sharing.
setAudioManagerStreamVolume(progress);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
index ee2ba7b..48b04b4 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
@@ -16,8 +16,6 @@
package com.android.settings.connecteddevice.audiosharing;
-import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID;
-
import android.annotation.IntRange;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
@@ -91,11 +89,11 @@
? null
: mBtManager.getCachedDeviceManager().findDevice(device);
if (cachedDevice == null) return;
- int groupId = AudioSharingUtils.getGroupId(cachedDevice);
+ int groupId = BluetoothUtils.getGroupId(cachedDevice);
mValueMap.put(groupId, volume);
for (AudioSharingDeviceVolumePreference preference : mVolumePreferences) {
if (preference.getCachedDevice() != null
- && AudioSharingUtils.getGroupId(preference.getCachedDevice())
+ && BluetoothUtils.getGroupId(preference.getCachedDevice())
== groupId) {
// If the callback return invalid volume, try to
// get the volume from AudioManager.STREAM_MUSIC
@@ -256,7 +254,7 @@
volumePref.setOrder(getPreferenceOrderForDevice(cachedDevice));
mVolumePreferences.add(volumePref);
if (volumePref.getProgress() > 0) return;
- int volume = mValueMap.getOrDefault(AudioSharingUtils.getGroupId(cachedDevice), -1);
+ int volume = mValueMap.getOrDefault(BluetoothUtils.getGroupId(cachedDevice), -1);
// If the volume is invalid, try to get the volume from AudioManager.STREAM_MUSIC
int finalVolume = getAudioVolumeIfNeeded(volume);
Log.d(
@@ -369,7 +367,7 @@
mVolumeControl.registerCallback(mExecutor, mVolumeControlCallback);
mBluetoothDeviceUpdater.registerCallback();
mContentResolver.registerContentObserver(
- Settings.Secure.getUriFor(SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID),
+ Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mSettingsObserver);
mCallbacksRegistered.set(true);
@@ -415,10 +413,10 @@
}
private int getPreferenceOrderForDevice(@NonNull CachedBluetoothDevice cachedDevice) {
- int groupId = AudioSharingUtils.getGroupId(cachedDevice);
+ int groupId = BluetoothUtils.getGroupId(cachedDevice);
// The fallback device rank first among the audio sharing device list.
return (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
- && groupId == AudioSharingUtils.getFallbackActiveGroupId(mContext))
+ && groupId == BluetoothUtils.getPrimaryGroupIdForBroadcast(mContentResolver))
? 0
: 1;
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
index f00cf73..6f62ed9 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
@@ -31,6 +31,7 @@
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.google.common.collect.Iterables;
@@ -76,7 +77,7 @@
@NonNull List<AudioSharingDeviceItem> deviceItems,
@NonNull DialogEventListener listener,
@NonNull Pair<Integer, Object>[] eventData) {
- if (!AudioSharingUtils.isFeatureEnabled()) return;
+ if (!BluetoothUtils.isAudioSharingEnabled()) return;
final FragmentManager manager;
try {
manager = host.getChildFragmentManager();
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
index 81d7979..472cb44 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
@@ -263,7 +263,7 @@
if (isBroadcasting) {
// If another device within the same is already in the sharing session, add source to
// the device automatically.
- int groupId = AudioSharingUtils.getGroupId(cachedDevice);
+ int groupId = BluetoothUtils.getGroupId(cachedDevice);
if (groupedDevices.containsKey(groupId)
&& groupedDevices.get(groupId).stream()
.anyMatch(
@@ -355,8 +355,8 @@
for (List<CachedBluetoothDevice> devices : groupedDevices.values()) {
// Use random device in the group within the sharing session to represent the group.
CachedBluetoothDevice device = devices.get(0);
- if (AudioSharingUtils.getGroupId(device)
- == AudioSharingUtils.getGroupId(cachedDevice)) {
+ if (BluetoothUtils.getGroupId(device)
+ == BluetoothUtils.getGroupId(cachedDevice)) {
continue;
}
deviceItems.add(AudioSharingUtils.buildAudioSharingDeviceItem(device));
@@ -435,7 +435,7 @@
/** Close opening dialogs for le audio device */
public void closeOpeningDialogsForLeaDevice(@NonNull CachedBluetoothDevice cachedDevice) {
if (mHostFragment == null) return;
- int groupId = AudioSharingUtils.getGroupId(cachedDevice);
+ int groupId = BluetoothUtils.getGroupId(cachedDevice);
List<Fragment> fragments;
try {
fragments = mHostFragment.getChildFragmentManager().getFragments();
@@ -447,7 +447,7 @@
CachedBluetoothDevice device = getCachedBluetoothDeviceFromDialog(fragment);
if (device != null
&& groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
- && AudioSharingUtils.getGroupId(device) == groupId) {
+ && BluetoothUtils.getGroupId(device) == groupId) {
Log.d(TAG, "Remove staled opening dialog for group " + groupId);
((DialogFragment) fragment).dismiss();
logDialogDismissEvent(fragment);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
index 66e327b..7d91644 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
@@ -32,6 +32,7 @@
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.utils.ThreadUtils;
@@ -83,7 +84,7 @@
@NonNull CachedBluetoothDevice newDevice,
@NonNull DialogEventListener listener,
@NonNull Pair<Integer, Object>[] eventData) {
- if (!AudioSharingUtils.isFeatureEnabled()) return;
+ if (!BluetoothUtils.isAudioSharingEnabled()) return;
final FragmentManager manager;
try {
manager = host.getChildFragmentManager();
@@ -93,8 +94,8 @@
}
AlertDialog dialog = AudioSharingDialogHelper.getDialogIfShowing(manager, TAG);
if (dialog != null) {
- int newGroupId = AudioSharingUtils.getGroupId(newDevice);
- if (sNewDevice != null && newGroupId == AudioSharingUtils.getGroupId(sNewDevice)) {
+ int newGroupId = BluetoothUtils.getGroupId(newDevice);
+ if (sNewDevice != null && newGroupId == BluetoothUtils.getGroupId(sNewDevice)) {
Log.d(
TAG,
String.format(
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
index 9afa186..9571241 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
@@ -32,6 +32,7 @@
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import java.util.List;
@@ -58,7 +59,7 @@
@Override
public int getMetricsCategory() {
- return AudioSharingUtils.isBroadcasting(Utils.getLocalBtManager(getContext()))
+ return BluetoothUtils.isBroadcasting(Utils.getLocalBtManager(getContext()))
? SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE
: SettingsEnums.DIALOG_START_AUDIO_SHARING;
}
@@ -80,7 +81,7 @@
@NonNull CachedBluetoothDevice newDevice,
@NonNull DialogEventListener listener,
@NonNull Pair<Integer, Object>[] eventData) {
- if (!AudioSharingUtils.isFeatureEnabled()) return;
+ if (!BluetoothUtils.isAudioSharingEnabled()) return;
final FragmentManager manager;
try {
manager = host.getChildFragmentManager();
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreferenceController.java
index 894ba48..a1a9698 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreferenceController.java
@@ -16,7 +16,7 @@
package com.android.settings.connecteddevice.audiosharing;
-import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.isBroadcasting;
+import static com.android.settingslib.bluetooth.BluetoothUtils.isBroadcasting;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothLeBroadcast;
@@ -174,7 +174,7 @@
@Override
public int getAvailabilityStatus() {
- return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return BluetoothUtils.isAudioSharingEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPasswordPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPasswordPreferenceController.java
index 14930e1..9a27a93 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPasswordPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPasswordPreferenceController.java
@@ -16,7 +16,7 @@
package com.android.settings.connecteddevice.audiosharing;
-import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.isBroadcasting;
+import static com.android.settingslib.bluetooth.BluetoothUtils.isBroadcasting;
import android.app.settings.SettingsEnums;
import android.content.ContentResolver;
@@ -39,6 +39,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.ValidatedEditTextPreference;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -112,7 +113,7 @@
@Override
public int getAvailabilityStatus() {
- return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return BluetoothUtils.isAudioSharingEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPlaySoundPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPlaySoundPreferenceController.java
index 11b195c..59494db 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPlaySoundPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPlaySoundPreferenceController.java
@@ -33,6 +33,7 @@
import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class AudioSharingPlaySoundPreferenceController
@@ -56,7 +57,7 @@
@Override
public int getAvailabilityStatus() {
- return (mRingtone != null && AudioSharingUtils.isFeatureEnabled())
+ return (mRingtone != null && BluetoothUtils.isAudioSharingEnabled())
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPreferenceController.java
index 0244889..3c078ef 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPreferenceController.java
@@ -34,6 +34,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.BluetoothEventManager;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.utils.ThreadUtils;
@@ -134,12 +135,12 @@
@Override
public int getAvailabilityStatus() {
- return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return BluetoothUtils.isAudioSharingEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
public CharSequence getSummary() {
- return AudioSharingUtils.isBroadcasting(mBtManager)
+ return BluetoothUtils.isBroadcasting(mBtManager)
? mContext.getString(R.string.audio_sharing_summary_on)
: mContext.getString(R.string.audio_sharing_summary_off);
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java
index 2b976d2..b43a544 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java
@@ -32,6 +32,7 @@
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -48,7 +49,7 @@
@Override
public void onReceive(Context context, Intent intent) {
- if (!AudioSharingUtils.isFeatureEnabled()) {
+ if (!BluetoothUtils.isAudioSharingEnabled()) {
Log.w(TAG, "Skip handling received intent, flag is off.");
return;
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
index d026fa7..5b71f51 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
@@ -32,6 +32,7 @@
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.utils.ThreadUtils;
@@ -80,7 +81,7 @@
@NonNull CachedBluetoothDevice newDevice,
@NonNull DialogEventListener listener,
@NonNull Pair<Integer, Object>[] eventData) {
- if (!AudioSharingUtils.isFeatureEnabled()) return;
+ if (!BluetoothUtils.isAudioSharingEnabled()) return;
final FragmentManager manager;
try {
manager = host.getChildFragmentManager();
@@ -90,9 +91,9 @@
}
AlertDialog dialog = AudioSharingDialogHelper.getDialogIfShowing(manager, TAG);
if (dialog != null) {
- int newGroupId = AudioSharingUtils.getGroupId(newDevice);
+ int newGroupId = BluetoothUtils.getGroupId(newDevice);
if (sCachedDevice != null
- && newGroupId == AudioSharingUtils.getGroupId(sCachedDevice)) {
+ && newGroupId == BluetoothUtils.getGroupId(sCachedDevice)) {
Log.d(
TAG,
String.format(
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
index 9705566..60b2ee5 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
@@ -23,7 +23,6 @@
import android.bluetooth.BluetoothLeBroadcastAssistant;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
-import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -45,6 +44,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.SettingsMainSwitchBar;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
@@ -327,7 +327,7 @@
return;
}
mSwitchBar.setEnabled(false);
- boolean isBroadcasting = AudioSharingUtils.isBroadcasting(mBtManager);
+ boolean isBroadcasting = BluetoothUtils.isBroadcasting(mBtManager);
if (isChecked) {
if (isBroadcasting) {
Log.d(TAG, "Skip startAudioSharing, already broadcasting.");
@@ -339,10 +339,7 @@
if (FeatureFlagUtils.isEnabled(
mContext,
FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST)
- && mAssistant
- .getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED})
- .isEmpty()) {
+ && mAssistant.getAllConnectedDevices().isEmpty()) {
// Pop up dialog to ask users to connect at least one lea buds before audio sharing.
AudioSharingUtils.postOnMainThread(
mContext,
@@ -368,7 +365,7 @@
@Override
public int getAvailabilityStatus() {
- return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return BluetoothUtils.isAudioSharingEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -483,7 +480,7 @@
var unused =
ThreadUtils.postOnBackgroundThread(
() -> {
- boolean isBroadcasting = AudioSharingUtils.isBroadcasting(mBtManager);
+ boolean isBroadcasting = BluetoothUtils.isBroadcasting(mBtManager);
boolean isStateReady =
isBluetoothOn()
&& AudioSharingUtils.isAudioSharingProfileReady(
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
index 29f605c..50f9c9a 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
@@ -22,14 +22,10 @@
import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID;
import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED;
-import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastMetadata;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
-import android.provider.Settings;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;
@@ -44,10 +40,8 @@
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.bluetooth.VolumeControlProfile;
-import com.android.settingslib.flags.Flags;
import java.util.ArrayList;
import java.util.HashMap;
@@ -56,8 +50,6 @@
import java.util.stream.Collectors;
public class AudioSharingUtils {
- public static final String SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID =
- "bluetooth_le_broadcast_fallback_active_group_id";
private static final String TAG = "AudioSharingUtils";
private static final boolean DEBUG = BluetoothUtils.D;
@@ -89,9 +81,7 @@
Log.d(TAG, "Skip fetchConnectedDevicesByGroupId due to assistant profile is null");
return groupedDevices;
}
- List<BluetoothDevice> connectedDevices =
- assistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED});
+ List<BluetoothDevice> connectedDevices = assistant.getAllConnectedDevices();
CachedBluetoothDeviceManager cacheManager = localBtManager.getCachedDeviceManager();
for (BluetoothDevice device : connectedDevices) {
CachedBluetoothDevice cachedDevice = cacheManager.findDevice(device);
@@ -99,7 +89,7 @@
Log.d(TAG, "Skip device due to not being cached: " + device.getAnonymizedAddress());
continue;
}
- int groupId = getGroupId(cachedDevice);
+ int groupId = BluetoothUtils.getGroupId(cachedDevice);
if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
Log.d(
TAG,
@@ -230,7 +220,7 @@
CachedBluetoothDevice cachedDevice) {
return new AudioSharingDeviceItem(
cachedDevice.getName(),
- getGroupId(cachedDevice),
+ BluetoothUtils.getGroupId(cachedDevice),
isActiveLeAudioDevice(cachedDevice));
}
@@ -250,16 +240,6 @@
.execute(() -> Toast.makeText(context, message, Toast.LENGTH_LONG).show());
}
- /** Returns if the le audio sharing is enabled. */
- public static boolean isFeatureEnabled() {
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- return Flags.enableLeAudioSharing()
- && adapter.isLeAudioBroadcastSourceSupported()
- == BluetoothStatusCodes.FEATURE_SUPPORTED
- && adapter.isLeAudioBroadcastAssistantSupported()
- == BluetoothStatusCodes.FEATURE_SUPPORTED;
- }
-
/** Add source to target sinks. */
public static void addSourceToTargetSinks(
List<BluetoothDevice> sinks, @Nullable LocalBluetoothManager localBtManager) {
@@ -289,9 +269,7 @@
Log.d(TAG, "skip addSourceToTargetDevices: There is no broadcastMetadata.");
return;
}
- List<BluetoothDevice> connectedDevices =
- assistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED});
+ List<BluetoothDevice> connectedDevices = assistant.getAllConnectedDevices();
for (BluetoothDevice sink : sinks) {
if (connectedDevices.contains(sink)) {
Log.d(
@@ -312,14 +290,6 @@
}
}
- /** Returns if the broadcast is on-going. */
- public static boolean isBroadcasting(@Nullable LocalBluetoothManager manager) {
- if (manager == null) return false;
- LocalBluetoothLeBroadcast broadcast =
- manager.getProfileManager().getLeAudioBroadcastProfile();
- return broadcast != null && broadcast.isEnabled(null);
- }
-
/** Stops the latest broadcast. */
public static void stopBroadcasting(@Nullable LocalBluetoothManager manager) {
if (manager == null) {
@@ -335,37 +305,6 @@
}
}
- /**
- * Get CSIP group id for {@link CachedBluetoothDevice}.
- *
- * <p>If CachedBluetoothDevice#getGroupId is invalid, fetch group id from
- * LeAudioProfile#getGroupId.
- */
- public static int getGroupId(CachedBluetoothDevice cachedDevice) {
- int groupId = cachedDevice.getGroupId();
- String anonymizedAddress = cachedDevice.getDevice().getAnonymizedAddress();
- if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- Log.d(TAG, "getGroupId by CSIP profile for device: " + anonymizedAddress);
- return groupId;
- }
- for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) {
- if (profile instanceof LeAudioProfile) {
- Log.d(TAG, "getGroupId by LEA profile for device: " + anonymizedAddress);
- return ((LeAudioProfile) profile).getGroupId(cachedDevice.getDevice());
- }
- }
- Log.d(TAG, "getGroupId return invalid id for device: " + anonymizedAddress);
- return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
- }
-
- /** Get the fallback active group id from SettingsProvider. */
- public static int getFallbackActiveGroupId(@NonNull Context context) {
- return Settings.Secure.getInt(
- context.getContentResolver(),
- SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID,
- BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
- }
-
/** Post the runnable to main thread. */
public static void postOnMainThread(@NonNull Context context, @NonNull Runnable runnable) {
context.getMainExecutor().execute(runnable);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/StreamSettingsCategoryController.java b/src/com/android/settings/connecteddevice/audiosharing/StreamSettingsCategoryController.java
index e9953a5..40f86d0 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/StreamSettingsCategoryController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/StreamSettingsCategoryController.java
@@ -33,6 +33,7 @@
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -90,7 +91,7 @@
@Override
public int getAvailabilityStatus() {
- return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return BluetoothUtils.isAudioSharingEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java
index 148c776..4c17a7c 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java
@@ -23,7 +23,6 @@
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastMetadata;
-import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -36,10 +35,10 @@
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
public class AudioStreamConfirmDialog extends InstrumentedDialogFragment {
@@ -211,7 +210,7 @@
}
private int getDialogId(boolean hasMetadata, boolean hasConnectedDevice) {
- if (!AudioSharingUtils.isFeatureEnabled()) {
+ if (!BluetoothUtils.isAudioSharingEnabled()) {
return SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_FEATURE_UNSUPPORTED;
}
if (!hasConnectedDevice) {
@@ -233,9 +232,7 @@
if (assistant == null) {
return null;
}
- var devices =
- assistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED});
+ var devices = assistant.getAllConnectedDevices();
return devices.isEmpty() ? null : devices.get(0);
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogActivity.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogActivity.java
index 88e2322..3437524 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogActivity.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogActivity.java
@@ -25,6 +25,7 @@
import com.android.settings.SettingsActivity;
import com.android.settings.bluetooth.Utils;
import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
public class AudioStreamConfirmDialogActivity extends SettingsActivity
@@ -49,7 +50,7 @@
@Override
protected void createUiFromIntent(@Nullable Bundle savedState, Intent intent) {
- if (AudioSharingUtils.isFeatureEnabled()
+ if (BluetoothUtils.isAudioSharingEnabled()
&& !AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
Log.d(TAG, "createUiFromIntent() : supported but not ready, skip createUiFromIntent");
mSavedState = savedState;
@@ -66,7 +67,7 @@
@Override
public void onStart() {
- if (AudioSharingUtils.isFeatureEnabled()
+ if (BluetoothUtils.isAudioSharingEnabled()
&& !AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
Log.d(TAG, "onStart() : supported but not ready, listen to service ready");
if (mProfileManager != null) {
@@ -86,7 +87,7 @@
@Override
public void onServiceConnected() {
- if (AudioSharingUtils.isFeatureEnabled()
+ if (BluetoothUtils.isAudioSharingEnabled()
&& AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
if (mProfileManager != null) {
mProfileManager.removeServiceListener(this);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
index ad358ed..d5be2bb 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
@@ -43,9 +43,9 @@
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
@@ -122,7 +122,7 @@
@Override
public void onCreate() {
- if (!AudioSharingUtils.isFeatureEnabled()) {
+ if (!BluetoothUtils.isAudioSharingEnabled()) {
return;
}
@@ -172,7 +172,7 @@
public void onDestroy() {
Log.d(TAG, "onDestroy()");
super.onDestroy();
- if (!AudioSharingUtils.isFeatureEnabled()) {
+ if (!BluetoothUtils.isAudioSharingEnabled()) {
return;
}
if (mLocalBtManager != null) {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelper.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelper.java
index 6e335a0..215b677 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelper.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelper.java
@@ -26,7 +26,6 @@
import android.bluetooth.BluetoothLeAudioContentMetadata;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
-import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
@@ -277,9 +276,7 @@
Log.w(TAG, "getConnectedBluetoothDevices(): LeBroadcastAssistant is null!");
return emptyList();
}
- List<BluetoothDevice> connectedDevices =
- leBroadcastAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED});
+ List<BluetoothDevice> connectedDevices = leBroadcastAssistant.getAllConnectedDevices();
Optional<CachedBluetoothDevice> cachedBluetoothDevice =
inSharingOnly
? getCachedBluetoothDeviceInSharing(manager)
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 0389b45..db50676 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -16,6 +16,7 @@
package com.android.settings.development;
+import static android.app.Activity.RESULT_OK;
import static android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED;
import static android.service.quicksettings.TileService.ACTION_QS_TILE_PREFERENCES;
import static android.view.flags.Flags.sensitiveContentAppProtectionApi;
@@ -100,11 +101,13 @@
NfcRebootDialog.OnNfcRebootDialogConfirmedListener, BluetoothSnoopLogHost {
private static final String TAG = "DevSettingsDashboard";
+ @VisibleForTesting static final int REQUEST_BIOMETRIC_PROMPT = 100;
private final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore =
new BluetoothA2dpConfigStore();
private boolean mIsAvailable = true;
+ private boolean mIsBiometricsAuthenticated;
private SettingsMainSwitchBar mSwitchBar;
private DevelopmentSwitchBarController mSwitchBarController;
private List<AbstractPreferenceController> mPreferenceControllers = new ArrayList<>();
@@ -216,6 +219,7 @@
public void onStart() {
super.onStart();
final ContentResolver cr = getContext().getContentResolver();
+ mIsBiometricsAuthenticated = false;
cr.registerContentObserver(mDevelopEnabled, false, mDeveloperSettingsObserver);
// Restore UI state based on whether developer options is enabled
@@ -360,7 +364,18 @@
DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext());
if (isChecked != developmentEnabledState) {
if (isChecked) {
- EnableDevelopmentSettingWarningDialog.show(this /* host */);
+ final int userId = getContext().getUserId();
+ if (Utils.requestBiometricAuthenticationForMandatoryBiometrics(getContext(),
+ mIsBiometricsAuthenticated,
+ false /* biometricsAuthenticationRequested */, userId)) {
+ mSwitchBar.setChecked(false);
+ Utils.launchBiometricPromptForMandatoryBiometrics(this,
+ REQUEST_BIOMETRIC_PROMPT, userId, false /* hideBackground */);
+ } else {
+ //Reset biometrics once enable dialog is shown
+ mIsBiometricsAuthenticated = false;
+ EnableDevelopmentSettingWarningDialog.show(this /* host */);
+ }
} else {
final BluetoothA2dpHwOffloadPreferenceController a2dpController =
getDevelopmentOptionsController(
@@ -534,6 +549,12 @@
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
boolean handledResult = false;
+ if (requestCode == REQUEST_BIOMETRIC_PROMPT) {
+ if (resultCode == RESULT_OK) {
+ mIsBiometricsAuthenticated = true;
+ mSwitchBar.setChecked(true);
+ }
+ }
for (AbstractPreferenceController controller : mPreferenceControllers) {
if (controller instanceof OnActivityResultListener) {
// We do not break early because it is possible for multiple controllers to
diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
index 6fe3ca4..cf6b3e3 100644
--- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -55,6 +55,7 @@
static final int TAPS_TO_BE_A_DEVELOPER = 7;
static final int REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF = 100;
+ static final int REQUEST_IDENTITY_CHECK_FOR_DEV_PREF = 101;
private Activity mActivity;
private InstrumentedPreferenceFragment mFragment;
@@ -217,10 +218,24 @@
* @return if activity result is handled.
*/
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode != REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF) {
+ if (requestCode != REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF
+ && requestCode != REQUEST_IDENTITY_CHECK_FOR_DEV_PREF) {
return false;
}
- if (resultCode == Activity.RESULT_OK) {
+ if (requestCode == REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF
+ && resultCode == Activity.RESULT_OK) {
+ final int userId = mContext.getUserId();
+ if (Utils.requestBiometricAuthenticationForMandatoryBiometrics(mContext,
+ false /* biometricsSuccessfullyAuthenticated */,
+ false /* biometricsAuthenticationRequested */,
+ userId)) {
+ Utils.launchBiometricPromptForMandatoryBiometrics(mFragment,
+ REQUEST_IDENTITY_CHECK_FOR_DEV_PREF, userId, false /* hideBackground */);
+ } else {
+ enableDevelopmentSettings();
+ }
+ } else if (requestCode == REQUEST_IDENTITY_CHECK_FOR_DEV_PREF
+ && resultCode == Activity.RESULT_OK) {
enableDevelopmentSettings();
}
mProcessingLastDevHit = false;
diff --git a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt
index 445597f..c929d5c 100644
--- a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt
+++ b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt
@@ -22,46 +22,38 @@
import android.telephony.data.ApnSetting
import androidx.lifecycle.LifecycleOwner
import androidx.preference.PreferenceScreen
+import com.android.settings.R
+import com.android.settings.Settings.MobileNetworkActivity.EXTRA_MMS_MESSAGE
+import com.android.settings.core.TogglePreferenceController
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import kotlinx.coroutines.flow.combine
-/**
- * Preference controller for "MMS messages"
- */
-class MmsMessagePreferenceController @JvmOverloads constructor(
+/** Preference controller for "MMS messages" */
+class MmsMessagePreferenceController
+@JvmOverloads
+constructor(
context: Context,
key: String,
private val getDefaultDataSubId: () -> Int = {
SubscriptionManager.getDefaultDataSubscriptionId()
},
-) : TelephonyTogglePreferenceController(context, key) {
+) : TogglePreferenceController(context, key) {
- private lateinit var telephonyManager: TelephonyManager
+ private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ private var telephonyManager: TelephonyManager =
+ context.getSystemService(TelephonyManager::class.java)!!
private var preferenceScreen: PreferenceScreen? = null
fun init(subId: Int) {
- mSubId = subId
- telephonyManager = mContext.getSystemService(TelephonyManager::class.java)!!
- .createForSubscriptionId(subId)
+ this.subId = subId
+ telephonyManager = telephonyManager.createForSubscriptionId(subId)
}
- override fun getAvailabilityStatus(subId: Int) =
- if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
- this::telephonyManager.isInitialized &&
- !telephonyManager.isDataEnabled &&
- telephonyManager.isApnMetered(ApnSetting.TYPE_MMS) &&
- !isFallbackDataEnabled()
- ) AVAILABLE else CONDITIONALLY_UNAVAILABLE
-
- private fun isFallbackDataEnabled(): Boolean {
- val defaultDataSubId = getDefaultDataSubId()
- return defaultDataSubId != mSubId &&
- telephonyManager.createForSubscriptionId(defaultDataSubId).isDataEnabled &&
- telephonyManager.isMobileDataPolicyEnabled(
- TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH
- )
- }
+ override fun getAvailabilityStatus() =
+ if (getAvailabilityStatus(telephonyManager, subId, getDefaultDataSubId)) AVAILABLE
+ else CONDITIONALLY_UNAVAILABLE
override fun displayPreference(screen: PreferenceScreen) {
super.displayPreference(screen)
@@ -70,16 +62,20 @@
override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
combine(
- MobileDataRepository(mContext).mobileDataEnabledChangedFlow(mSubId),
- mContext.subscriptionsChangedFlow(), // Capture isMobileDataPolicyEnabled() changes
- ) { _, _ -> }.collectLatestWithLifecycle(viewLifecycleOwner) {
- preferenceScreen?.let { super.displayPreference(it) }
- }
+ MobileDataRepository(mContext).mobileDataEnabledChangedFlow(subId),
+ mContext.subscriptionsChangedFlow(), // Capture isMobileDataPolicyEnabled() changes
+ ) { _, _ ->
+ }
+ .collectLatestWithLifecycle(viewLifecycleOwner) {
+ preferenceScreen?.let { super.displayPreference(it) }
+ }
}
- override fun isChecked(): Boolean = telephonyManager.isMobileDataPolicyEnabled(
- TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED
- )
+ override fun getSliceHighlightMenuRes() = NO_RES
+
+ override fun isChecked(): Boolean =
+ telephonyManager.isMobileDataPolicyEnabled(
+ TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED)
override fun setChecked(isChecked: Boolean): Boolean {
telephonyManager.setMobileDataPolicyEnabled(
@@ -88,4 +84,45 @@
)
return true
}
+
+ companion object {
+ private fun getAvailabilityStatus(
+ telephonyManager: TelephonyManager,
+ subId: Int,
+ getDefaultDataSubId: () -> Int,
+ ): Boolean {
+ return SubscriptionManager.isValidSubscriptionId(subId) &&
+ !telephonyManager.isDataEnabled &&
+ telephonyManager.isApnMetered(ApnSetting.TYPE_MMS) &&
+ !isFallbackDataEnabled(telephonyManager, subId, getDefaultDataSubId())
+ }
+
+ private fun isFallbackDataEnabled(
+ telephonyManager: TelephonyManager,
+ subId: Int,
+ defaultDataSubId: Int,
+ ): Boolean {
+ return defaultDataSubId != subId &&
+ telephonyManager.createForSubscriptionId(defaultDataSubId).isDataEnabled &&
+ telephonyManager.isMobileDataPolicyEnabled(
+ TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
+ }
+
+ class MmsMessageSearchItem(
+ context: Context,
+ private val getDefaultDataSubId: () -> Int = {
+ SubscriptionManager.getDefaultDataSubscriptionId()
+ },
+ ) : MobileNetworkSettingsSearchItem {
+ private var telephonyManager: TelephonyManager =
+ context.getSystemService(TelephonyManager::class.java)!!
+
+ override val key: String = EXTRA_MMS_MESSAGE
+ override val title: String = context.getString(R.string.mms_message_title)
+
+ override fun isAvailable(subId: Int): Boolean =
+ getAvailabilityStatus(
+ telephonyManager.createForSubscriptionId(subId), subId, getDefaultDataSubId)
+ }
+ }
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 9db5af2..ee1485e 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -467,14 +467,10 @@
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.mobile_network_settings) {
-
- /** suppress full page if user is not admin */
@Override
protected boolean isPageSearchEnabled(Context context) {
- boolean isAirplaneOff = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.AIRPLANE_MODE_ON, 0) == 0;
- return isAirplaneOff && SubscriptionUtil.isSimHardwareVisible(context)
- && context.getSystemService(UserManager.class).isAdminUser();
+ return MobileNetworkSettingsSearchIndex
+ .isMobileNetworkSettingsSearchable(context);
}
};
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
new file mode 100644
index 0000000..85ba382
--- /dev/null
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2024 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 android.content.Context
+import android.provider.Settings
+import android.telephony.SubscriptionInfo
+import com.android.settings.R
+import com.android.settings.network.SubscriptionUtil
+import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
+import com.android.settings.spa.SpaSearchLanding.BundleValue
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
+import com.android.settings.spa.search.SpaSearchRepository.Companion.createSearchIndexableRaw
+import com.android.settings.spa.search.SpaSearchRepository.Companion.searchIndexProviderOf
+import com.android.settingslib.search.SearchIndexableData
+import com.android.settingslib.search.SearchIndexableRaw
+import com.android.settingslib.spaprivileged.framework.common.userManager
+import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
+
+class MobileNetworkSettingsSearchIndex(
+ private val searchItemsFactory: (context: Context) -> List<MobileNetworkSettingsSearchItem> =
+ ::createSearchItems,
+) {
+ interface MobileNetworkSettingsSearchItem {
+ val key: String
+
+ val title: String
+
+ fun isAvailable(subId: Int): Boolean
+ }
+
+ fun createSearchIndexableData(): SearchIndexableData {
+ val searchIndexProvider = searchIndexProviderOf { context ->
+ if (!isMobileNetworkSettingsSearchable(context)) {
+ return@searchIndexProviderOf emptyList()
+ }
+ val subInfos = context.requireSubscriptionManager().activeSubscriptionInfoList
+ if (subInfos.isNullOrEmpty()) {
+ return@searchIndexProviderOf emptyList()
+ }
+ searchItemsFactory(context).flatMap { searchItem ->
+ searchIndexableRawList(context, searchItem, subInfos)
+ }
+ }
+ return SearchIndexableData(MobileNetworkSettings::class.java, searchIndexProvider)
+ }
+
+ private fun searchIndexableRawList(
+ context: Context,
+ searchItem: MobileNetworkSettingsSearchItem,
+ subInfos: List<SubscriptionInfo>
+ ): List<SearchIndexableRaw> =
+ subInfos
+ .filter { searchItem.isAvailable(it.subscriptionId) }
+ .map { subInfo -> searchIndexableRaw(context, searchItem, subInfo) }
+
+ private fun searchIndexableRaw(
+ context: Context,
+ searchItem: MobileNetworkSettingsSearchItem,
+ subInfo: SubscriptionInfo,
+ ): SearchIndexableRaw {
+ val key =
+ SpaSearchLandingKey.newBuilder()
+ .setFragment(
+ SpaSearchLandingFragment.newBuilder()
+ .setFragmentName(MobileNetworkSettings::class.java.name)
+ .setPreferenceKey(searchItem.key)
+ .putArguments(
+ Settings.EXTRA_SUB_ID,
+ BundleValue.newBuilder().setIntValue(subInfo.subscriptionId).build()))
+ .build()
+ val simsTitle = context.getString(R.string.provider_network_settings_title)
+ return createSearchIndexableRaw(
+ context = context,
+ spaSearchLandingKey = key,
+ itemTitle = searchItem.title,
+ indexableClass = MobileNetworkSettings::class.java,
+ pageTitle = "$simsTitle > ${subInfo.displayName}",
+ )
+ }
+
+ companion object {
+ /** suppress full page if user is not admin */
+ @JvmStatic
+ fun isMobileNetworkSettingsSearchable(context: Context): Boolean {
+ val isAirplaneMode by context.settingsGlobalBoolean(Settings.Global.AIRPLANE_MODE_ON)
+ return SubscriptionUtil.isSimHardwareVisible(context) &&
+ !isAirplaneMode &&
+ context.userManager.isAdminUser
+ }
+
+ fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
+ listOf(
+ MmsMessageSearchItem(context),
+ )
+ }
+}
diff --git a/src/com/android/settings/notification/modes/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeButtonPreferenceController.java
index 998b596..bb9d23c 100644
--- a/src/com/android/settings/notification/modes/ZenModeButtonPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeButtonPreferenceController.java
@@ -84,9 +84,9 @@
}
});
if (zenMode.isActive()) {
- mZenButton.setText(R.string.zen_mode_button_turn_off);
+ mZenButton.setText(R.string.zen_mode_action_deactivate);
} else {
- mZenButton.setText(R.string.zen_mode_button_turn_on);
+ mZenButton.setText(R.string.zen_mode_action_activate);
}
}
}
diff --git a/src/com/android/settings/notification/modes/ZenModeFragmentBase.java b/src/com/android/settings/notification/modes/ZenModeFragmentBase.java
index c63b3a8..ed3a71c 100644
--- a/src/com/android/settings/notification/modes/ZenModeFragmentBase.java
+++ b/src/com/android/settings/notification/modes/ZenModeFragmentBase.java
@@ -131,7 +131,7 @@
}
private void toastAndFinish() {
- Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
+ Toast.makeText(mContext, R.string.zen_mode_not_found_text, Toast.LENGTH_SHORT)
.show();
this.finish();
}
diff --git a/src/com/android/settings/notification/modes/ZenModeScheduleChooserDialog.java b/src/com/android/settings/notification/modes/ZenModeScheduleChooserDialog.java
index 14264b7..6202648 100644
--- a/src/com/android/settings/notification/modes/ZenModeScheduleChooserDialog.java
+++ b/src/com/android/settings/notification/modes/ZenModeScheduleChooserDialog.java
@@ -50,15 +50,16 @@
static final int OPTION_TIME = 0;
static final int OPTION_CALENDAR = 1;
- private record ScheduleOption(@StringRes int nameResId, @StringRes int exampleResId,
- @DrawableRes int iconResId) {}
+ private record ScheduleOption(@StringRes int nameResId,
+ @Nullable @StringRes Integer exampleResId,
+ @DrawableRes int iconResId) { }
private static final ImmutableList<ScheduleOption> SCHEDULE_OPTIONS = ImmutableList.of(
new ScheduleOption(R.string.zen_mode_select_schedule_time,
R.string.zen_mode_select_schedule_time_example,
com.android.internal.R.drawable.ic_zen_mode_type_schedule_time),
new ScheduleOption(R.string.zen_mode_select_schedule_calendar,
- R.string.zen_mode_select_schedule_calendar_example,
+ null,
com.android.internal.R.drawable.ic_zen_mode_type_schedule_calendar));
private OnScheduleOptionListener mOptionListener;
@@ -85,7 +86,7 @@
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
checkState(getContext() != null);
return new AlertDialog.Builder(getContext())
- .setTitle(R.string.zen_mode_choose_rule_type)
+ .setTitle(R.string.zen_mode_select_schedule_title)
.setAdapter(new OptionsAdapter(getContext()),
(dialog, which) -> onScheduleTypeSelected(which))
.setNegativeButton(R.string.cancel, null)
@@ -115,7 +116,12 @@
ScheduleOption option = checkNotNull(getItem(position));
imageView.setImageResource(option.iconResId());
title.setText(option.nameResId());
- subtitle.setText(option.exampleResId());
+ if (option.exampleResId() != null) {
+ subtitle.setVisibility(View.VISIBLE);
+ subtitle.setText(option.exampleResId());
+ } else {
+ subtitle.setVisibility(View.GONE);
+ }
return convertView;
}
diff --git a/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java b/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
index 3ee6d94..885c4db 100644
--- a/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
@@ -53,6 +53,8 @@
private final ConfigurationActivityHelper mConfigurationActivityHelper;
private final ZenServiceListing mServiceListing;
+ private String mModeName;
+
ZenModeTriggerUpdatePreferenceController(Context context, String key,
ZenModesBackend backend) {
this(context, key, backend, context.getPackageManager(),
@@ -82,6 +84,7 @@
return;
}
+ mModeName = zenMode.getName();
PrimarySwitchPreference triggerPref = (PrimarySwitchPreference) preference;
triggerPref.setChecked(zenMode.getRule().isEnabled());
triggerPref.setOnPreferenceChangeListener(mSwitchChangeListener);
@@ -189,15 +192,15 @@
};
private void confirmChangeEnabled(Preference preference, boolean enabled) {
- @StringRes int title = enabled ? R.string.zen_mode_confirm_enable_title
- : R.string.zen_mode_confirm_disable_title;
+ @StringRes int titleFormat = enabled ? R.string.zen_mode_confirm_enable_mode_title
+ : R.string.zen_mode_confirm_disable_mode_title;
@StringRes int message = enabled ? R.string.zen_mode_confirm_enable_message
: R.string.zen_mode_confirm_disable_message;
@StringRes int confirmButton = enabled ? R.string.zen_mode_action_enable
: R.string.zen_mode_action_disable;
new AlertDialog.Builder(mContext)
- .setTitle(title)
+ .setTitle(mContext.getString(titleFormat, mModeName))
.setMessage(message)
.setPositiveButton(confirmButton,
(dialog, which) -> setModeEnabled(enabled))
diff --git a/src/com/android/settings/notification/modes/ZenModesListFragment.java b/src/com/android/settings/notification/modes/ZenModesListFragment.java
index a45ca17..cab0209 100644
--- a/src/com/android/settings/notification/modes/ZenModesListFragment.java
+++ b/src/com/android/settings/notification/modes/ZenModesListFragment.java
@@ -49,15 +49,11 @@
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
- return buildPreferenceControllers(context, this::onAvailableModeTypesForAdd);
+ return buildPreferenceControllers(context, mBackend, this::onAvailableModeTypesForAdd);
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
- OnAddModeListener onAddModeListener) {
- // We need to redefine ZenModesBackend here even though mBackend exists so that this method
- // can be static; it must be static to be able to be used in SEARCH_INDEX_DATA_PROVIDER.
- ZenModesBackend backend = ZenModesBackend.getInstance(context);
-
+ ZenModesBackend backend, OnAddModeListener onAddModeListener) {
return ImmutableList.of(
new ZenModesListPreferenceController(context, backend),
new ZenModesListAddModePreferenceController(context, onAddModeListener)
@@ -150,7 +146,10 @@
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
- return buildPreferenceControllers(context, ignoredType -> {});
+ // We need to redefine ZenModesBackend here even though mBackend exists so that
+ // SEARCH_INDEX_DATA_PROVIDER can be static.
+ return buildPreferenceControllers(context, ZenModesBackend.getInstance(context),
+ ignoredType -> {});
}
};
}
diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java
index cc05270..b6a9167 100644
--- a/src/com/android/settings/search/BaseSearchIndexProvider.java
+++ b/src/com/android/settings/search/BaseSearchIndexProvider.java
@@ -21,9 +21,11 @@
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_INCLUDE_PREF_SCREEN;
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_KEY;
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_SEARCHABLE;
+import static com.android.settings.search.SettingsSearchIndexablesProvider.SYSPROP_CRASH_ON_ERROR;
import android.annotation.XmlRes;
import android.content.Context;
+import android.os.Build;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.util.Log;
@@ -131,24 +133,48 @@
return nonIndexableKeys;
}
nonIndexableKeys.addAll(getNonIndexableKeysFromXml(context, false /* suppressAllPage */));
+ updateNonIndexableKeysFromControllers(context, nonIndexableKeys);
+ return nonIndexableKeys;
+ }
+
+ private void updateNonIndexableKeysFromControllers(
+ Context context, List<String> nonIndexableKeys) {
final List<AbstractPreferenceController> controllers = getPreferenceControllers(context);
- if (controllers != null && !controllers.isEmpty()) {
+ if (controllers != null) {
for (AbstractPreferenceController controller : controllers) {
- if (controller instanceof PreferenceControllerMixin) {
- ((PreferenceControllerMixin) controller)
- .updateNonIndexableKeys(nonIndexableKeys);
- } else if (controller instanceof BasePreferenceController) {
- ((BasePreferenceController) controller).updateNonIndexableKeys(
- nonIndexableKeys);
- } else {
- Log.e(TAG, controller.getClass().getName()
- + " must implement " + PreferenceControllerMixin.class.getName()
- + " treating the key non-indexable");
- nonIndexableKeys.add(controller.getPreferenceKey());
- }
+ updateNonIndexableKeysFromController(nonIndexableKeys, controller);
}
}
- return nonIndexableKeys;
+ }
+
+ private static void updateNonIndexableKeysFromController(
+ List<String> nonIndexableKeys, AbstractPreferenceController controller) {
+ try {
+ if (controller instanceof PreferenceControllerMixin controllerMixin) {
+ controllerMixin.updateNonIndexableKeys(nonIndexableKeys);
+ } else if (controller instanceof BasePreferenceController basePreferenceController) {
+ basePreferenceController.updateNonIndexableKeys(nonIndexableKeys);
+ } else {
+ Log.e(TAG, controller.getClass().getName()
+ + " must implement " + PreferenceControllerMixin.class.getName()
+ + " treating the key non-indexable");
+ nonIndexableKeys.add(controller.getPreferenceKey());
+ }
+ } catch (Exception e) {
+ String msg = "Error trying to get non-indexable keys from: " + controller;
+ // Catch a generic crash. In the absence of the catch, the background thread will
+ // silently fail anyway, so we aren't losing information by catching the exception.
+ // We crash on debuggable build or when the system property exists, so that we can test
+ // if crashes need to be fixed.
+ // The gain is that if there is a crash in a specific controller, we don't lose all
+ // non-indexable keys, but we can still find specific crashes in development.
+ if (Build.IS_DEBUGGABLE || System.getProperty(SYSPROP_CRASH_ON_ERROR) != null) {
+ throw new RuntimeException(msg, e);
+ }
+ Log.e(TAG, msg, e);
+ // When there is an error, treat the key as non-indexable.
+ nonIndexableKeys.add(controller.getPreferenceKey());
+ }
}
public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
index 3b04186..cdcb323 100644
--- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
+++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
@@ -50,6 +50,7 @@
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
+import android.os.Build;
import android.provider.SearchIndexableResource;
import android.provider.SearchIndexablesContract;
import android.provider.SearchIndexablesProvider;
@@ -283,17 +284,16 @@
try {
providerNonIndexableKeys = provider.getNonIndexableKeys(context);
} catch (Exception e) {
+ String msg = "Error trying to get non-indexable keys from: "
+ + bundle.getTargetClass().getName();
// Catch a generic crash. In the absence of the catch, the background thread will
// silently fail anyway, so we aren't losing information by catching the exception.
- // We crash when the system property exists so that we can test if crashes need to
- // be fixed.
- // The gain is that if there is a crash in a specific controller, we don't lose all
- // non-indexable keys, but we can still find specific crashes in development.
- if (System.getProperty(SYSPROP_CRASH_ON_ERROR) != null) {
- throw new RuntimeException(e);
+ // We crash on debuggable build or when the system property exists, so that we can
+ // test if crashes need to be fixed.
+ if (Build.IS_DEBUGGABLE || System.getProperty(SYSPROP_CRASH_ON_ERROR) != null) {
+ throw new RuntimeException(msg, e);
}
- Log.e(TAG, "Error trying to get non-indexable keys from: "
- + bundle.getTargetClass().getName(), e);
+ Log.e(TAG, msg, e);
continue;
}
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index 6d987f3..797d3ec 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -15,10 +15,15 @@
*/
package com.android.settings.security;
+import static com.android.settings.biometrics.face.FaceSettings.isFaceHardwareDetected;
+import static com.android.settings.biometrics.fingerprint.FingerprintSettings.isFingerprintHardwareDetected;
+
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
+import androidx.annotation.VisibleForTesting;
+
import com.android.settings.R;
import com.android.settings.biometrics.combination.CombinedBiometricStatusPreferenceController;
import com.android.settings.biometrics.face.FaceStatusPreferenceController;
@@ -45,6 +50,10 @@
public static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
public static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
public static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
+ @VisibleForTesting
+ static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings";
+ @VisibleForTesting
+ static final String KEY_FACE_SETTINGS = "face_settings";
@Override
public int getMetricsCategory() {
@@ -131,6 +140,18 @@
.hasAlternativeSecuritySettingsFragment()
&& !SafetyCenterManagerWrapper.get().isEnabled(context);
}
+
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ final List<String> keys = super.getNonIndexableKeys(context);
+ if (!isFingerprintHardwareDetected(context)) {
+ keys.add(KEY_FINGERPRINT_SETTINGS);
+ }
+ if (!isFaceHardwareDetected(context)) {
+ keys.add(KEY_FACE_SETTINGS);
+ }
+ return keys;
+ }
};
@Override
diff --git a/src/com/android/settings/spa/SpaDestination.kt b/src/com/android/settings/spa/SpaDestination.kt
index cb20c37..158028a 100644
--- a/src/com/android/settings/spa/SpaDestination.kt
+++ b/src/com/android/settings/spa/SpaDestination.kt
@@ -16,7 +16,7 @@
package com.android.settings.spa
-import android.app.Activity
+import android.content.Context
import android.content.Intent
import com.android.settings.activityembedding.ActivityEmbeddingUtils
import com.android.settings.activityembedding.EmbeddedDeepLinkUtils.tryStartMultiPaneDeepLink
@@ -27,16 +27,16 @@
val destination: String,
val highlightMenuKey: String?,
) {
- fun startFromExportedActivity(activity: Activity) {
- val intent = Intent(activity, SpaActivity::class.java)
+ fun startFromExportedActivity(context: Context) {
+ val intent = Intent(context, SpaActivity::class.java)
.appendSpaParams(
destination = destination,
sessionName = SESSION_EXTERNAL,
)
- if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(activity) ||
- !activity.tryStartMultiPaneDeepLink(intent, highlightMenuKey)
+ if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(context) ||
+ !context.tryStartMultiPaneDeepLink(intent, highlightMenuKey)
) {
- activity.startActivity(intent)
+ context.startActivity(intent)
}
}
}
diff --git a/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt b/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt
index b9a375c..f76bba4 100644
--- a/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt
+++ b/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt
@@ -197,6 +197,9 @@
// Do nothing
}
+ override fun getPageTitleForSearch(context: Context): String =
+ context.getString(R.string.provider_network_settings_title)
+
override fun getSearchableTitles(context: Context): List<String> {
if (!isPageSearchable(context)) return emptyList()
return buildList {
diff --git a/src/com/android/settings/spa/search/SearchablePage.kt b/src/com/android/settings/spa/search/SearchablePage.kt
index 2364514..f4a8795 100644
--- a/src/com/android/settings/spa/search/SearchablePage.kt
+++ b/src/com/android/settings/spa/search/SearchablePage.kt
@@ -20,6 +20,9 @@
interface SearchablePage {
- /** Gets the searchable titles at the current moment. */
+ /** Gets the title of the page. */
+ fun getPageTitleForSearch(context: Context): String = ""
+
+ /** Gets the titles of the searchable items at the current moment. */
fun getSearchableTitles(context: Context): List<String>
}
diff --git a/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt b/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt
index 8c2bc37..cb5f745 100644
--- a/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt
+++ b/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt
@@ -17,26 +17,68 @@
package com.android.settings.spa.search
import android.app.Activity
+import android.app.settings.SettingsEnums
+import android.content.Context
import android.os.Bundle
+import android.util.Log
+import androidx.annotation.VisibleForTesting
import com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY
+import com.android.settings.core.SubSettingLauncher
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
import com.android.settings.password.PasswordUtils
import com.android.settings.spa.SpaDestination
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
+import com.google.protobuf.ByteString
+import com.google.protobuf.InvalidProtocolBufferException
class SpaSearchLandingActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- if (!isValidCall()) return
-
- val destination = intent.getStringExtra(EXTRA_FRAGMENT_ARG_KEY)
- if (destination.isNullOrBlank()) return
-
- SpaDestination(destination = destination, highlightMenuKey = null)
- .startFromExportedActivity(this)
+ val keyString = intent.getStringExtra(EXTRA_FRAGMENT_ARG_KEY)
+ if (!keyString.isNullOrEmpty() && isValidCall()) {
+ tryLaunch(this, keyString)
+ }
finish()
}
private fun isValidCall() =
PasswordUtils.getCallingAppPackageName(activityToken) ==
featureFactory.searchFeatureProvider.getSettingsIntelligencePkgName(this)
+
+ companion object {
+ @VisibleForTesting
+ fun tryLaunch(context: Context, keyString: String) {
+ val key =
+ try {
+ SpaSearchLandingKey.parseFrom(ByteString.copyFromUtf8(keyString))
+ } catch (e: InvalidProtocolBufferException) {
+ Log.w(TAG, "arg key ($keyString) invalid", e)
+ return
+ }
+
+ if (key.hasSpaPage()) {
+ val destination = key.spaPage.destination
+ if (destination.isNotEmpty()) {
+ SpaDestination(destination = destination, highlightMenuKey = null)
+ .startFromExportedActivity(context)
+ }
+ }
+ if (key.hasFragment()) {
+ val arguments =
+ Bundle().apply {
+ key.fragment.argumentsMap.forEach { (k, v) ->
+ if (v.hasIntValue()) putInt(k, v.intValue)
+ }
+ putString(EXTRA_FRAGMENT_ARG_KEY, key.fragment.preferenceKey)
+ }
+ SubSettingLauncher(context)
+ .setDestination(key.fragment.fragmentName)
+ .setArguments(arguments)
+ .setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
+ .launch()
+ }
+ }
+
+ private const val TAG = "SpaSearchLandingActivity"
+ }
}
diff --git a/src/com/android/settings/spa/search/SpaSearchRepository.kt b/src/com/android/settings/spa/search/SpaSearchRepository.kt
index d37c50c..0efcb70 100644
--- a/src/com/android/settings/spa/search/SpaSearchRepository.kt
+++ b/src/com/android/settings/spa/search/SpaSearchRepository.kt
@@ -20,6 +20,9 @@
import android.provider.SearchIndexableResource
import android.util.Log
import androidx.annotation.VisibleForTesting
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingSpaPage
import com.android.settingslib.search.Indexable
import com.android.settingslib.search.SearchIndexableData
import com.android.settingslib.search.SearchIndexableRaw
@@ -34,9 +37,10 @@
Log.d(TAG, "getSearchIndexableDataList")
return spaEnvironment.pageProviderRepository.value.getAllProviders().mapNotNull { page ->
if (page is SearchablePage) {
- page.createSearchIndexableData(page::getSearchableTitles)
+ page.createSearchIndexableData(
+ page::getPageTitleForSearch, page::getSearchableTitles)
} else null
- }
+ } + MobileNetworkSettingsSearchIndex().createSearchIndexableData()
}
companion object {
@@ -44,40 +48,60 @@
@VisibleForTesting
fun SettingsPageProvider.createSearchIndexableData(
+ getPageTitleForSearch: (context: Context) -> String,
titlesProvider: (context: Context) -> List<String>,
): SearchIndexableData {
- val searchIndexProvider =
- object : Indexable.SearchIndexProvider {
- override fun getXmlResourcesToIndex(
- context: Context,
- enabled: Boolean,
- ): List<SearchIndexableResource> = emptyList()
-
- override fun getRawDataToIndex(
- context: Context,
- enabled: Boolean,
- ): List<SearchIndexableRaw> = emptyList()
-
- override fun getDynamicRawDataToIndex(
- context: Context,
- enabled: Boolean,
- ): List<SearchIndexableRaw> =
- titlesProvider(context).map { title ->
- createSearchIndexableRaw(context, title)
- }
-
- override fun getNonIndexableKeys(context: Context): List<String> = emptyList()
+ val key =
+ SpaSearchLandingKey.newBuilder()
+ .setSpaPage(SpaSearchLandingSpaPage.newBuilder().setDestination(name))
+ .build()
+ val indexableClass = this::class.java
+ val searchIndexProvider = searchIndexProviderOf { context ->
+ val pageTitle = getPageTitleForSearch(context)
+ titlesProvider(context).map { itemTitle ->
+ createSearchIndexableRaw(context, key, itemTitle, indexableClass, pageTitle)
}
- return SearchIndexableData(this::class.java, searchIndexProvider)
+ }
+ return SearchIndexableData(indexableClass, searchIndexProvider)
}
- private fun SettingsPageProvider.createSearchIndexableRaw(context: Context, title: String) =
+ fun searchIndexProviderOf(
+ getDynamicRawDataToIndex: (context: Context) -> List<SearchIndexableRaw>,
+ ) =
+ object : Indexable.SearchIndexProvider {
+ override fun getXmlResourcesToIndex(
+ context: Context,
+ enabled: Boolean,
+ ): List<SearchIndexableResource> = emptyList()
+
+ override fun getRawDataToIndex(
+ context: Context,
+ enabled: Boolean,
+ ): List<SearchIndexableRaw> = emptyList()
+
+ override fun getDynamicRawDataToIndex(
+ context: Context,
+ enabled: Boolean,
+ ): List<SearchIndexableRaw> = getDynamicRawDataToIndex(context)
+
+ override fun getNonIndexableKeys(context: Context): List<String> = emptyList()
+ }
+
+ fun createSearchIndexableRaw(
+ context: Context,
+ spaSearchLandingKey: SpaSearchLandingKey,
+ itemTitle: String,
+ indexableClass: Class<*>,
+ pageTitle: String,
+ ) =
SearchIndexableRaw(context).apply {
- key = name
- this.title = title
+ key = spaSearchLandingKey.toByteString().toStringUtf8()
+ title = itemTitle
intentAction = SEARCH_LANDING_ACTION
+ intentTargetClass = SpaSearchLandingActivity::class.qualifiedName
packageName = context.packageName
- className = SpaSearchLandingActivity::class.qualifiedName
+ className = indexableClass.name
+ screenTitle = pageTitle
}
private const val SEARCH_LANDING_ACTION = "android.settings.SPA_SEARCH_LANDING"
diff --git a/src/com/android/settings/users/MultiUserSwitchBarController.java b/src/com/android/settings/users/MultiUserSwitchBarController.java
index 641ae51..07c03d7 100644
--- a/src/com/android/settings/users/MultiUserSwitchBarController.java
+++ b/src/com/android/settings/users/MultiUserSwitchBarController.java
@@ -17,6 +17,7 @@
package com.android.settings.users;
import android.content.Context;
+import android.multiuser.Flags;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -25,6 +26,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.settings.widget.SwitchWidgetController;
+import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -53,12 +55,24 @@
mUserCapabilities = UserCapabilities.create(context);
mSwitchBar.setChecked(mUserCapabilities.mUserSwitcherEnabled);
- if (mUserCapabilities.mDisallowSwitchUser) {
- mSwitchBar.setDisabledByAdmin(RestrictedLockUtilsInternal
+ if (Flags.fixDisablingOfMuToggleWhenRestrictionApplied()) {
+ RestrictedLockUtils.EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
.checkIfRestrictionEnforced(mContext, UserManager.DISALLOW_USER_SWITCH,
- UserHandle.myUserId()));
+ UserHandle.myUserId());
+ if (enforcedAdmin != null) {
+ mSwitchBar.setDisabledByAdmin(enforcedAdmin);
+ } else {
+ mSwitchBar.setEnabled(mUserCapabilities.mIsMain
+ && !mUserCapabilities.mDisallowSwitchUser);
+ }
} else {
- mSwitchBar.setEnabled(mUserCapabilities.mIsMain);
+ if (mUserCapabilities.mDisallowSwitchUser) {
+ mSwitchBar.setDisabledByAdmin(RestrictedLockUtilsInternal
+ .checkIfRestrictionEnforced(mContext, UserManager.DISALLOW_USER_SWITCH,
+ UserHandle.myUserId()));
+ } else {
+ mSwitchBar.setEnabled(mUserCapabilities.mIsMain);
+ }
}
mSwitchBar.setListener(this);
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/KeyboardBounceKeyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/KeyboardBounceKeyPreferenceControllerTest.java
index 96beb43..bf6efd0 100644
--- a/tests/robotests/src/com/android/settings/accessibility/KeyboardBounceKeyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/KeyboardBounceKeyPreferenceControllerTest.java
@@ -25,6 +25,8 @@
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
@@ -34,19 +36,24 @@
import com.android.settings.core.BasePreferenceController;
+import org.junit.Assume;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
+import java.util.ArrayList;
+import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class KeyboardBounceKeyPreferenceControllerTest {
-
private static final String KEY_ACCESSIBILITY_BOUNCE_KEYS =
Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS;
private static final int UNKNOWN = -1;
+ @Rule
+ public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
private final KeyboardBounceKeyPreferenceController mController =
@@ -131,4 +138,26 @@
mContext.getContentResolver(), KEY_ACCESSIBILITY_BOUNCE_KEYS,
UNKNOWN)).isNotEqualTo(OFF);
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
+ public void updateNonIndexableKeys_physicalKeyboardExists_returnEmptyList() {
+ Assume.assumeTrue(AccessibilitySettings.isAnyHardKeyboardsExist());
+
+ List<String> nonIndexableKeys = new ArrayList<>();
+ mController.updateNonIndexableKeys(nonIndexableKeys);
+
+ assertThat(nonIndexableKeys).isEmpty();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
+ public void updateNonIndexableKeys_noPhysicalKeyboard_returnPreKey() {
+ Assume.assumeFalse(AccessibilitySettings.isAnyHardKeyboardsExist());
+
+ List<String> nonIndexableKeys = new ArrayList<>();
+ mController.updateNonIndexableKeys(nonIndexableKeys);
+
+ assertThat(nonIndexableKeys).contains(mController.getPreferenceKey());
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/KeyboardSlowKeyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/KeyboardSlowKeyPreferenceControllerTest.java
index 321b69f..2721a64 100644
--- a/tests/robotests/src/com/android/settings/accessibility/KeyboardSlowKeyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/KeyboardSlowKeyPreferenceControllerTest.java
@@ -25,6 +25,8 @@
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
@@ -34,19 +36,24 @@
import com.android.settings.core.BasePreferenceController;
+import org.junit.Assume;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
+import java.util.ArrayList;
+import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class KeyboardSlowKeyPreferenceControllerTest {
-
private static final String KEY_ACCESSIBILITY_SLOW_KEYS =
Settings.Secure.ACCESSIBILITY_SLOW_KEYS;
private static final int UNKNOWN = -1;
+ @Rule
+ public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
private final KeyboardSlowKeyPreferenceController mController =
@@ -131,4 +138,26 @@
mContext.getContentResolver(), KEY_ACCESSIBILITY_SLOW_KEYS, UNKNOWN)).isNotEqualTo(
OFF);
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
+ public void updateNonIndexableKeys_physicalKeyboardExists_returnEmptyList() {
+ Assume.assumeTrue(AccessibilitySettings.isAnyHardKeyboardsExist());
+
+ List<String> nonIndexableKeys = new ArrayList<>();
+ mController.updateNonIndexableKeys(nonIndexableKeys);
+
+ assertThat(nonIndexableKeys).isEmpty();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
+ public void updateNonIndexableKeys_noPhysicalKeyboard_returnPreKey() {
+ Assume.assumeFalse(AccessibilitySettings.isAnyHardKeyboardsExist());
+
+ List<String> nonIndexableKeys = new ArrayList<>();
+ mController.updateNonIndexableKeys(nonIndexableKeys);
+
+ assertThat(nonIndexableKeys).contains(mController.getPreferenceKey());
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/KeyboardStickyKeyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/KeyboardStickyKeyPreferenceControllerTest.java
index 31d46b7..0001e85 100644
--- a/tests/robotests/src/com/android/settings/accessibility/KeyboardStickyKeyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/KeyboardStickyKeyPreferenceControllerTest.java
@@ -25,6 +25,8 @@
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
@@ -34,19 +36,24 @@
import com.android.settings.core.BasePreferenceController;
+import org.junit.Assume;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
+import java.util.ArrayList;
+import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class KeyboardStickyKeyPreferenceControllerTest {
-
private static final String KEY_ACCESSIBILITY_STICKY_KEYS =
Settings.Secure.ACCESSIBILITY_STICKY_KEYS;
private static final int UNKNOWN = -1;
+ @Rule
+ public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
private final KeyboardStickyKeyPreferenceController mController =
@@ -129,4 +136,26 @@
assertThat(Settings.Secure.getInt(
mContext.getContentResolver(), KEY_ACCESSIBILITY_STICKY_KEYS, UNKNOWN)).isEqualTo(ON);
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
+ public void updateNonIndexableKeys_physicalKeyboardExists_returnEmptyList() {
+ Assume.assumeTrue(AccessibilitySettings.isAnyHardKeyboardsExist());
+
+ List<String> nonIndexableKeys = new ArrayList<>();
+ mController.updateNonIndexableKeys(nonIndexableKeys);
+
+ assertThat(nonIndexableKeys).isEmpty();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
+ public void updateNonIndexableKeys_noPhysicalKeyboard_returnPreKey() {
+ Assume.assumeFalse(AccessibilitySettings.isAnyHardKeyboardsExist());
+
+ List<String> nonIndexableKeys = new ArrayList<>();
+ mController.updateNonIndexableKeys(nonIndexableKeys);
+
+ assertThat(nonIndexableKeys).contains(mController.getPreferenceKey());
+ }
}
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
index 29b2961..b3e1c5d 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
@@ -40,6 +40,7 @@
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.ComponentInfoInternal;
@@ -67,6 +68,7 @@
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmDeviceCredentialActivity;
+import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
@@ -114,6 +116,8 @@
@Mock
private FragmentTransaction mFragmentTransaction;
@Mock
+ private PackageManager mPackageManager;
+ @Mock
private BiometricManager mBiometricManager;
@Captor
@@ -283,6 +287,16 @@
assertThat(mFragment.isVisible()).isTrue();
}
+ @Test
+ public void testNotIndexable_whenDisabled() {
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(false)
+ .when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
+
+ final BaseSearchIndexProvider provider = FingerprintSettingsFragment.SEARCH_INDEX_DATA_PROVIDER;
+ assertThat(provider.getDynamicRawDataToIndex(mContext, true)).isEmpty();
+ }
+
@Ignore("b/353726774")
@Test
public void testAddButtonWorksAfterRemovalError() {
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragmentTest.java
index 51ed899..ceafcf0 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragmentTest.java
@@ -99,7 +99,7 @@
mParent = new Fragment();
FragmentController.setupFragment(
mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
- AudioSharingCallAudioDialogFragment.show(mParent, new ArrayList<>(), (item) -> {});
+ AudioSharingCallAudioDialogFragment.show(mParent, new ArrayList<>(), -1, (item) -> {});
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNull();
@@ -109,7 +109,7 @@
public void onCreateDialog_unattachedFragment_dialogNotExist() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mParent = new Fragment();
- AudioSharingCallAudioDialogFragment.show(mParent, new ArrayList<>(), (item) -> {});
+ AudioSharingCallAudioDialogFragment.show(mParent, new ArrayList<>(), -1, (item) -> {});
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNull();
@@ -138,7 +138,7 @@
ArrayList<AudioSharingDeviceItem> deviceItemList = new ArrayList<>();
deviceItemList.add(TEST_DEVICE_ITEM1);
deviceItemList.add(TEST_DEVICE_ITEM2);
- AudioSharingCallAudioDialogFragment.show(mParent, deviceItemList, (item) -> {});
+ AudioSharingCallAudioDialogFragment.show(mParent, deviceItemList, 0, (item) -> {});
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
index c72b5a5..87ae3d5 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
@@ -16,7 +16,6 @@
package com.android.settings.connecteddevice.audiosharing;
-import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
@@ -64,6 +63,7 @@
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settings.testutils.shadow.ShadowThreadUtils;
import com.android.settingslib.bluetooth.BluetoothEventManager;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
@@ -197,7 +197,8 @@
verify(mBtEventManager, never()).registerCallback(mController);
verify(mContentResolver, never())
.registerContentObserver(
- Settings.Secure.getUriFor(SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID),
+ Settings.Secure.getUriFor(
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mContentObserver);
verify(mAssistant, never())
@@ -211,7 +212,8 @@
verify(mBtEventManager).registerCallback(mController);
verify(mContentResolver)
.registerContentObserver(
- Settings.Secure.getUriFor(SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID),
+ Settings.Secure.getUriFor(
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mContentObserver);
verify(mAssistant)
@@ -319,9 +321,7 @@
public void onProfileConnectionStateChanged_noDeviceInSharing_updateSummary() {
Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1);
when(mBroadcast.isEnabled(any())).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of());
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
mController.displayPreference(mScreen);
mPreference.setSummary("test");
mController.onProfileConnectionStateChanged(
@@ -340,9 +340,7 @@
when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1);
when(mBroadcast.isEnabled(any())).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice1));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1));
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mController.displayPreference(mScreen);
mContentObserver.onChange(true);
@@ -369,8 +367,7 @@
when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2);
when(mCacheManager.findDevice(mDevice3)).thenReturn(mCachedDevice3);
when(mBroadcast.isEnabled(any())).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
+ when(mAssistant.getAllConnectedDevices())
.thenReturn(ImmutableList.of(mDevice1, mDevice2, mDevice3));
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mController.displayPreference(mScreen);
@@ -389,9 +386,7 @@
when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1);
when(mBroadcast.isEnabled(any())).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice1));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1));
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
@@ -403,9 +398,7 @@
Settings.Secure.putInt(
mContentResolver, TEST_SETTINGS_KEY, BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
when(mBroadcast.isEnabled(any())).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of());
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
@@ -429,9 +422,7 @@
when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2);
mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(List.of(mDevice1, mDevice2));
when(mBroadcast.isEnabled(any())).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice1, mDevice2));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2));
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mController.init(mParentFragment);
mController.displayPreference(mScreen);
@@ -521,18 +512,14 @@
Settings.Secure.putInt(
mContentResolver, TEST_SETTINGS_KEY, BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
when(mBroadcast.isEnabled(any())).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of());
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
// onReceiveStateChanged will update summary
Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice1));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1));
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mController.mBroadcastAssistantCallback.onReceiveStateChanged(
mDevice1, /* sourceId= */ 1, mState);
@@ -552,17 +539,13 @@
Settings.Secure.putInt(
mContentResolver, TEST_SETTINGS_KEY, BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
when(mBroadcast.isEnabled(any())).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of());
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice1));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1));
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1);
mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java
index f2f0a2f..d8c663f 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java
@@ -16,8 +16,6 @@
package com.android.settings.connecteddevice.audiosharing;
-import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -59,6 +57,7 @@
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settings.testutils.shadow.ShadowThreadUtils;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
@@ -208,7 +207,8 @@
.registerCallback(any(Executor.class), any(BluetoothVolumeControl.Callback.class));
verify(mContentResolver, never())
.registerContentObserver(
- Settings.Secure.getUriFor(SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID),
+ Settings.Secure.getUriFor(
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mContentObserver);
}
@@ -223,11 +223,9 @@
verify(mDeviceUpdater).registerCallback();
verify(mVolumeControl)
.registerCallback(any(Executor.class), any(BluetoothVolumeControl.Callback.class));
- verify(mContentResolver)
- .registerContentObserver(
- Settings.Secure.getUriFor(SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID),
- false,
- mContentObserver);
+ verify(mContentResolver).registerContentObserver(
+ Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast()), false,
+ mContentObserver);
}
@Test
@@ -242,7 +240,8 @@
.registerCallback(any(Executor.class), any(BluetoothVolumeControl.Callback.class));
verify(mContentResolver)
.registerContentObserver(
- Settings.Secure.getUriFor(SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID),
+ Settings.Secure.getUriFor(
+ BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mContentObserver);
}
@@ -317,7 +316,8 @@
@Test
public void onDeviceAdded_rankFallbackDeviceOnTop() {
Settings.Secure.putInt(
- mContentResolver, SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID, TEST_DEVICE_GROUP_ID2);
+ mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_DEVICE_GROUP_ID2);
when(mPreference1.getProgress()).thenReturn(TEST_VOLUME_VALUE);
when(mPreference2.getProgress()).thenReturn(TEST_VOLUME_VALUE);
mController.setPreferenceGroup(mPreferenceGroup);
@@ -427,7 +427,8 @@
@Test
public void settingsObserverOnChange_updatePreferenceOrder() {
Settings.Secure.putInt(
- mContentResolver, SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID, TEST_DEVICE_GROUP_ID2);
+ mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_DEVICE_GROUP_ID2);
when(mPreference1.getProgress()).thenReturn(TEST_VOLUME_VALUE);
when(mPreference2.getProgress()).thenReturn(TEST_VOLUME_VALUE);
mController.setPreferenceGroup(mPreferenceGroup);
@@ -435,8 +436,8 @@
mController.onDeviceAdded(mPreference2);
shadowOf(Looper.getMainLooper()).idle();
- Settings.Secure.putInt(
- mContentResolver, SETTINGS_KEY_FALLBACK_DEVICE_GROUP_ID, TEST_DEVICE_GROUP_ID1);
+ Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+ TEST_DEVICE_GROUP_ID1);
mContentObserver.onChange(true);
shadowOf(Looper.getMainLooper()).idle();
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
index e71e876..1bff78b 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
@@ -35,7 +35,6 @@
import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
-import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
import android.os.Looper;
@@ -187,9 +186,7 @@
public void handleUserTriggeredNonLeaDeviceConnected_noSharing_setActive() {
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice2);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -200,9 +197,7 @@
public void handleUserTriggeredNonLeaDeviceConnected_sharing_showStopDialog() {
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice2);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -239,9 +234,7 @@
public void handleUserTriggeredLeaDeviceConnected_noSharingNoTwoLeaDevices_setActive() {
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -254,9 +247,7 @@
when(mCachedDevice1.getGroupId()).thenReturn(-1);
when(mLeAudioProfile.getGroupId(mDevice1)).thenReturn(-1);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -269,9 +260,7 @@
public void handleUserTriggeredLeaDeviceConnected_noSharingTwoLeaDevices_showJoinDialog() {
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -314,9 +303,7 @@
public void handleUserTriggeredLeaDeviceConnected_sharing_showJoinDialog() {
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(mDevice1)).thenReturn(ImmutableList.of());
when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
@@ -361,9 +348,7 @@
handleUserTriggeredLeaDeviceConnected_sharingWithTwoLeaDevices_showDisconnectDialog() {
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3, mDevice4);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(mDevice1)).thenReturn(ImmutableList.of());
when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState));
when(mAssistant.getAllSources(mDevice4)).thenReturn(ImmutableList.of(mState));
@@ -407,9 +392,7 @@
public void handleNonLeaDeviceConnected_noSharing_doNothing() {
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice2);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
@@ -420,9 +403,7 @@
public void handleNonLeaDeviceConnected_sharing_showStopDialog() {
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
@@ -459,9 +440,7 @@
public void handleLeaDeviceConnected_noSharingNoTwoLeaDevices_doNothing() {
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
@@ -474,9 +453,7 @@
when(mCachedDevice1.getGroupId()).thenReturn(-1);
when(mLeAudioProfile.getGroupId(mDevice1)).thenReturn(-1);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
@@ -489,9 +466,7 @@
public void handleLeaDeviceConnected_noSharingTwoLeaDevices_showJoinDialog() {
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
@@ -534,9 +509,7 @@
public void handleLeaDeviceConnected_sharing_showJoinDialog() {
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(mDevice1)).thenReturn(ImmutableList.of());
when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
@@ -580,9 +553,7 @@
public void handleLeaDeviceConnected_sharingWithTwoLeaDevices_showDisconnectDialog() {
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3, mDevice4);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(mDevice1)).thenReturn(ImmutableList.of());
when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState));
when(mAssistant.getAllSources(mDevice4)).thenReturn(ImmutableList.of(mState));
@@ -627,9 +598,7 @@
// Show join dialog
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -661,9 +630,7 @@
// Show disconnect dialog
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3, mDevice4);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(mDevice1)).thenReturn(ImmutableList.of());
when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState));
when(mAssistant.getAllSources(mDevice4)).thenReturn(ImmutableList.of(mState));
@@ -697,9 +664,7 @@
// Show stop dialog
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -721,9 +686,7 @@
public void closeOpeningDialogsOtherThan() {
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -733,9 +696,7 @@
.containsExactly(AudioSharingStopDialogFragment.tag());
deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(mDevice1)).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
@@ -769,9 +730,7 @@
public void onBroadcastStartFailed_logAction() {
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
@@ -797,9 +756,7 @@
public void onPlaybackStarted_addSource() {
setUpBroadcast(false);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
@@ -825,9 +782,7 @@
public void onBroadcastStopFailed_logAction() {
setUpBroadcast(true);
ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(deviceList);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java
index d68b68b..bfb4f2f 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java
@@ -378,9 +378,7 @@
FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
when(mBtnView.isEnabled()).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of());
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
doNothing().when(mBroadcast).startPrivateBroadcast();
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
assertThat(mSwitchBar.isChecked()).isFalse();
@@ -392,9 +390,7 @@
FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, false);
when(mBtnView.isEnabled()).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of());
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
doNothing().when(mBroadcast).startPrivateBroadcast();
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
verify(mBroadcast).startPrivateBroadcast();
@@ -405,9 +401,7 @@
FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
when(mBtnView.isEnabled()).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice1));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1));
doNothing().when(mBroadcast).startPrivateBroadcast();
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
verify(mBroadcast).startPrivateBroadcast();
@@ -437,9 +431,7 @@
FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
when(mBtnView.isEnabled()).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice2, mDevice1));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
doNothing().when(mBroadcast).startPrivateBroadcast();
mController =
new AudioSharingSwitchBarController(
@@ -469,9 +461,7 @@
FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
when(mBtnView.isEnabled()).thenReturn(true);
- when(mAssistant.getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice2, mDevice1));
+ when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
doNothing().when(mBroadcast).startPrivateBroadcast();
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
verify(mBroadcast).startPrivateBroadcast();
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogTest.java
index 601c432..e00a146 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogTest.java
@@ -219,7 +219,7 @@
public void showDialog_noMetadata() {
List<BluetoothDevice> devices = new ArrayList<>();
devices.add(mBluetoothDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
when(mBluetoothDevice.getAlias()).thenReturn(DEVICE_NAME);
FragmentController.setupFragment(
@@ -267,7 +267,7 @@
public void showDialog_invalidMetadata() {
List<BluetoothDevice> devices = new ArrayList<>();
devices.add(mBluetoothDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
when(mBluetoothDevice.getAlias()).thenReturn(DEVICE_NAME);
Intent intent = new Intent();
@@ -318,7 +318,7 @@
public void showDialog_confirmListen() {
List<BluetoothDevice> devices = new ArrayList<>();
devices.add(mBluetoothDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
when(mBluetoothDevice.getAlias()).thenReturn("");
Intent intent = new Intent();
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelperTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelperTest.java
index 66ef5fb..b91866b 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelperTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelperTest.java
@@ -91,7 +91,7 @@
@Test
public void addSource_noDevice_doNothing() {
- when(mAssistant.getDevicesMatchingConnectionStates(any()))
+ when(mAssistant.getAllConnectedDevices())
.thenReturn(Collections.emptyList());
mHelper.addSource(mMetadata);
@@ -102,7 +102,7 @@
public void addSource_hasDevice() {
List<BluetoothDevice> devices = new ArrayList<>();
devices.add(mDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
when(mCachedDevice.getDevice()).thenReturn(mDevice);
when(mCachedDevice.getGroupId()).thenReturn(GROUP_ID);
@@ -114,7 +114,7 @@
@Test
public void removeSource_noDevice_doNothing() {
- when(mAssistant.getDevicesMatchingConnectionStates(any()))
+ when(mAssistant.getAllConnectedDevices())
.thenReturn(Collections.emptyList());
mHelper.removeSource(BROADCAST_ID_1);
@@ -125,7 +125,7 @@
public void removeSource_noConnectedSource_doNothing() {
List<BluetoothDevice> devices = new ArrayList<>();
devices.add(mDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_2);
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
@@ -142,7 +142,7 @@
public void removeSource_hasConnectedSource() {
List<BluetoothDevice> devices = new ArrayList<>();
devices.add(mDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_2);
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
@@ -164,7 +164,7 @@
var memberDevice = mock(BluetoothDevice.class);
devices.add(mDevice);
devices.add(memberDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_2);
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
@@ -196,7 +196,7 @@
public void getAllConnectedSources_returnSource() {
List<BluetoothDevice> devices = new ArrayList<>();
devices.add(mDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
when(mCachedDevice.getDevice()).thenReturn(mDevice);
@@ -222,7 +222,7 @@
public void startMediaService_hasDevice() {
List<BluetoothDevice> devices = new ArrayList<>();
devices.add(mDevice);
- when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
+ when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
when(mCachedDevice.getDevice()).thenReturn(mDevice);
diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
index 37a4aea..9f45edb 100644
--- a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
@@ -18,13 +18,21 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
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.app.Activity;
import android.content.Context;
+import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.Flags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
@@ -42,6 +50,7 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
@@ -51,6 +60,7 @@
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowBiometricManager;
import org.robolectric.shadows.androidx.fragment.FragmentController;
import org.robolectric.util.ReflectionHelpers;
@@ -61,22 +71,34 @@
ShadowAlertDialogCompat.class,
ShadowUserManager.class,
ShadowUserManager.class,
+ ShadowBiometricManager.class,
})
public class DevelopmentSettingsDashboardFragmentTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext;
private ShadowUserManager mShadowUserManager;
+ private ShadowBiometricManager mShadowBiometricManager;
private DevelopmentSettingsDashboardFragment mDashboard;
+ private SettingsMainSwitchBar mSwitchBar;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- SettingsMainSwitchBar switchBar = new SettingsMainSwitchBar(mContext);
+ mSwitchBar = new SettingsMainSwitchBar(mContext);
mDashboard = spy(new DevelopmentSettingsDashboardFragment());
- ReflectionHelpers.setField(mDashboard, "mSwitchBar", switchBar);
+ ReflectionHelpers.setField(mDashboard, "mSwitchBar", mSwitchBar);
mShadowUserManager = Shadow.extract(mContext.getSystemService(Context.USER_SERVICE));
mShadowUserManager.setIsAdminUser(true);
+ mShadowBiometricManager = Shadow.extract(mContext.getSystemService(
+ Context.BIOMETRIC_SERVICE));
+ mShadowBiometricManager.setCanAuthenticate(false);
+ //TODO(b/352603684): Should be Authenticators.MANDATORY_BIOMETRICS,
+ // but it is not supported by ShadowBiometricManager
+ mShadowBiometricManager.setAuthenticatorType(
+ BiometricManager.Authenticators.BIOMETRIC_STRONG);
}
@After
@@ -177,6 +199,41 @@
}
@Test
+ @Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class)
+ @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void onSwitchChanged_turnOn_shouldLaunchBiometricPromptIfMandatoryBiometricsEffective() {
+ when(mDashboard.getContext()).thenReturn(mContext);
+ doNothing().when(mDashboard).startActivityForResult(any(),
+ eq(DevelopmentSettingsDashboardFragment.REQUEST_BIOMETRIC_PROMPT));
+
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+ mShadowBiometricManager.setCanAuthenticate(true);
+ mDashboard.onCheckedChanged(null, true /* isChecked */);
+
+ assertThat(mSwitchBar.isChecked()).isFalse();
+ verify(mDashboard).startActivityForResult(any(),
+ eq(DevelopmentSettingsDashboardFragment.REQUEST_BIOMETRIC_PROMPT));
+ assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isFalse();
+ }
+
+ @Test
+ @Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class)
+ @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void onActivityResult_requestBiometricPrompt_shouldShowWarningDialog() {
+ when(mDashboard.getContext()).thenReturn(mContext);
+
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+ mDashboard.onActivityResult(DevelopmentSettingsDashboardFragment.REQUEST_BIOMETRIC_PROMPT,
+ Activity.RESULT_OK, null);
+ mDashboard.onCheckedChanged(null, true /* isChecked */);
+
+ assertThat(mSwitchBar.isChecked()).isTrue();
+ assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isTrue();
+ }
+
+ @Test
@Ignore
@Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class)
public void onSwitchChanged_turnOff_shouldTurnOff() {
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
index 297815b..835985e 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
@@ -29,18 +29,14 @@
import android.app.Activity;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
-import android.content.res.Resources;
import android.net.NetworkPolicyManager;
import android.os.Bundle;
-import android.os.UserManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import androidx.fragment.app.FragmentActivity;
-import com.android.settings.R;
import com.android.settings.datausage.DataUsageSummaryPreferenceController;
-import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -53,7 +49,6 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.util.ReflectionHelpers;
import java.util.List;
@@ -73,7 +68,6 @@
private FragmentActivity mActivity;
private Context mContext;
- private Resources mResources;
private MobileNetworkSettings mFragment;
@Before
@@ -81,10 +75,6 @@
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
- mResources = spy(mContext.getResources());
- when(mContext.getResources()).thenReturn(mResources);
- when(mResources.getBoolean(R.bool.config_show_sim_info)).thenReturn(true);
-
when(mActivity.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
@@ -123,34 +113,4 @@
mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, Activity.RESULT_OK, null);
verify(mActivity).finish();
}
-
- @Test
- public void isPageSearchEnabled_adminUser_shouldReturnTrue() {
- final UserManager userManager = mock(UserManager.class);
- when(mContext.getSystemService(UserManager.class)).thenReturn(userManager);
- when(userManager.isAdminUser()).thenReturn(true);
- final BaseSearchIndexProvider provider =
- (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
-
- final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
- ReflectionHelpers.ClassParameter.from(Context.class, mContext));
- final boolean isEnabled = (Boolean) obj;
-
- assertThat(isEnabled).isTrue();
- }
-
- @Test
- public void isPageSearchEnabled_nonAdminUser_shouldReturnFalse() {
- final UserManager userManager = mock(UserManager.class);
- when(mContext.getSystemService(UserManager.class)).thenReturn(userManager);
- when(userManager.isAdminUser()).thenReturn(false);
- final BaseSearchIndexProvider provider =
- (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
-
- final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
- ReflectionHelpers.ClassParameter.from(Context.class, mContext));
- final boolean isEnabled = (Boolean) obj;
-
- assertThat(isEnabled).isFalse();
- }
}
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ConfigurationActivityHelperTest.java b/tests/robotests/src/com/android/settings/notification/modes/ConfigurationActivityHelperTest.java
index 47291a0..5a40c7f 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ConfigurationActivityHelperTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ConfigurationActivityHelperTest.java
@@ -25,6 +25,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;
+import android.app.Flags;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -32,12 +33,15 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.ConditionProviderService;
import com.android.settingslib.notification.modes.TestModeBuilder;
import com.android.settingslib.notification.modes.ZenMode;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -50,7 +54,10 @@
import java.util.function.Function;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ConfigurationActivityHelperTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext;
private ConfigurationActivityHelper mHelper;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/IconOptionsProviderImplTest.java b/tests/robotests/src/com/android/settings/notification/modes/IconOptionsProviderImplTest.java
index d5430b1..a9bbb47 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/IconOptionsProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/IconOptionsProviderImplTest.java
@@ -34,7 +34,7 @@
@RunWith(RobolectricTestRunner.class)
public class IconOptionsProviderImplTest {
- private static final int EXPECTED_NUMBER_OF_ICON_OPTIONS = 9;
+ private static final int EXPECTED_NUMBER_OF_ICON_OPTIONS = 20;
@Test
public void iconResources_correctResources() {
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ManualDurationHelperTest.java b/tests/robotests/src/com/android/settings/notification/modes/ManualDurationHelperTest.java
index 18ee2cf..c90f337 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ManualDurationHelperTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ManualDurationHelperTest.java
@@ -18,13 +18,17 @@
import static com.google.common.truth.Truth.assertThat;
+import android.app.Flags;
import android.content.ContentResolver;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import com.android.settings.R;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
@@ -32,7 +36,12 @@
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ManualDurationHelperTest {
+
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private Context mContext;
private ContentResolver mContentResolver;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAddBypassingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAddBypassingAppsPreferenceControllerTest.java
index bca1ccf..c524ab9 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAddBypassingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAddBypassingAppsPreferenceControllerTest.java
@@ -24,10 +24,13 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Flags;
import android.app.NotificationChannel;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ParceledListSlice;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
@@ -37,6 +40,7 @@
import com.android.settingslib.applications.ApplicationsState;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -50,8 +54,12 @@
import java.util.List;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeAddBypassingAppsPreferenceControllerTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Mock
private NotificationBackend mBackend;
@Mock
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceControllerTest.java
index 3114a2d..a7d52b1 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceControllerTest.java
@@ -27,10 +27,13 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Flags;
import android.app.NotificationChannel;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ParceledListSlice;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
@@ -40,6 +43,7 @@
import com.android.settingslib.applications.ApplicationsState;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -52,7 +56,12 @@
import java.util.List;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeAllBypassingAppsPreferenceControllerTest {
+
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private ZenModeAllBypassingAppsPreferenceController mController;
private Context mContext;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
index 29350f6..7cf0109 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
@@ -41,6 +41,7 @@
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public final class ZenModeDisplayLinkPreferenceControllerTest {
private ZenModeDisplayLinkPreferenceController mController;
@@ -75,7 +76,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_MODES_UI)
public void testHasSummary() {
Preference pref = mock(Preference.class);
mController.updateZenMode(pref, TestModeBuilder.EXAMPLE);
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditDonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditDonePreferenceControllerTest.java
index b15d4d6..74328be 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditDonePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditDonePreferenceControllerTest.java
@@ -21,7 +21,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.app.Flags;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.widget.Button;
import androidx.preference.PreferenceManager;
@@ -33,6 +36,7 @@
import com.android.settingslib.widget.LayoutPreference;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -41,8 +45,12 @@
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeEditDonePreferenceControllerTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private ZenModeEditDonePreferenceController mController;
private LayoutPreference mPreference;
private Button mButton;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentTest.java
index 2441803..cb853bb 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentTest.java
@@ -27,7 +27,10 @@
import static org.mockito.Mockito.when;
import android.app.Activity;
+import android.app.Flags;
import android.os.Bundle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.annotation.Nullable;
import androidx.fragment.app.testing.FragmentScenario;
@@ -40,6 +43,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -48,8 +52,12 @@
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeEditNameIconFragmentTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private static final ZenMode MODE = new TestModeBuilder().setId("id").setName("Mode").build();
private Activity mActivity;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java
index b54727c..795de50 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java
@@ -21,7 +21,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.app.Flags;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.widget.EditText;
import androidx.preference.PreferenceManager;
@@ -33,6 +36,7 @@
import com.android.settingslib.widget.LayoutPreference;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -43,14 +47,17 @@
import java.util.function.Consumer;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeEditNamePreferenceControllerTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private ZenModeEditNamePreferenceController mController;
private LayoutPreference mPreference;
private EditText mEditText;
@Mock private Consumer<String> mNameSetter;
-
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceControllerTest.java
index 4c8db07..3efa5f0 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeExitAtAlarmPreferenceControllerTest.java
@@ -21,7 +21,10 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import android.app.Flags;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.ZenModeConfig;
import androidx.preference.TwoStatePreference;
@@ -32,6 +35,7 @@
import com.android.settingslib.notification.modes.ZenModesBackend;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -42,7 +46,11 @@
import java.util.Calendar;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeExitAtAlarmPreferenceControllerTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private Context mContext;
@Mock
private ZenModesBackend mBackend;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java
index 1904734..eae606b 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java
@@ -22,7 +22,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Flags;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -39,6 +42,7 @@
import com.google.common.collect.ImmutableList;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -47,7 +51,10 @@
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeIconPickerListPreferenceControllerTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext;
private ZenModeIconPickerListPreferenceController mController;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeMessagesLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeMessagesLinkPreferenceControllerTest.java
index 100ff43..fad4f2a 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeMessagesLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeMessagesLinkPreferenceControllerTest.java
@@ -39,6 +39,7 @@
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public final class ZenModeMessagesLinkPreferenceControllerTest {
private ZenModeMessagesLinkPreferenceController mController;
@@ -60,7 +61,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_MODES_UI)
public void testHasSummary() {
Preference pref = mock(Preference.class);
mController.updateZenMode(pref, TestModeBuilder.EXAMPLE);
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeNewCustomFragmentTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeNewCustomFragmentTest.java
index dd2b49b..9aa42ea 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeNewCustomFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeNewCustomFragmentTest.java
@@ -30,8 +30,11 @@
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Flags;
import android.content.Intent;
import android.os.Bundle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.fragment.app.testing.EmptyFragmentActivity;
import androidx.fragment.app.testing.FragmentScenario;
@@ -53,9 +56,13 @@
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeNewCustomFragmentTest {
@Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ @Rule
public ActivityScenarioRule<EmptyFragmentActivity> mActivityScenario =
new ActivityScenarioRule<>(EmptyFragmentActivity.class);
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceControllerTest.java
index a3fe57e..80d314c 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceControllerTest.java
@@ -47,6 +47,7 @@
import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.SystemZenRules;
import android.service.notification.ZenModeConfig;
+import android.widget.TextView;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
@@ -174,18 +175,21 @@
@Test
public void onPreferenceChange_toggleOn_enablesModeAfterConfirmation() {
// Start with a disabled mode
- ZenMode zenMode = new TestModeBuilder().setEnabled(false).build();
+ ZenMode zenMode = new TestModeBuilder().setName("The mode").setEnabled(false).build();
mController.updateZenMode(mPreference, zenMode);
// Flip the switch
mPreference.callChangeListener(true);
verify(mBackend, never()).updateMode(any());
+ AlertDialog confirmDialog = ShadowAlertDialog.getLatestAlertDialog();
+ assertThat(confirmDialog).isNotNull();
+ assertThat(confirmDialog.isShowing()).isTrue();
+ assertThat(((TextView) confirmDialog.findViewById(com.android.internal.R.id.alertTitle))
+ .getText()).isEqualTo("Enable The mode?");
+
// Oh wait, I forgot to confirm! Let's do that
- assertThat(ShadowAlertDialog.getLatestAlertDialog()).isNotNull();
- assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isTrue();
- ShadowAlertDialog.getLatestAlertDialog()
- .getButton(AlertDialog.BUTTON_POSITIVE).performClick();
+ confirmDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
shadowOf(Looper.getMainLooper()).idle();
// Verify the backend got asked to update the mode to be enabled
@@ -198,18 +202,21 @@
@Test
public void onPreferenceChange_toggleOff_disablesModeAfterConfirmation() {
// Start with an enabled mode
- ZenMode zenMode = new TestModeBuilder().setEnabled(true).build();
+ ZenMode zenMode = new TestModeBuilder().setName("The mode").setEnabled(true).build();
mController.updateZenMode(mPreference, zenMode);
// Flip the switch
mPreference.callChangeListener(false);
verify(mBackend, never()).updateMode(any());
+ AlertDialog confirmDialog = ShadowAlertDialog.getLatestAlertDialog();
+ assertThat(confirmDialog).isNotNull();
+ assertThat(confirmDialog.isShowing()).isTrue();
+ assertThat(((TextView) confirmDialog.findViewById(com.android.internal.R.id.alertTitle))
+ .getText()).isEqualTo("Disable The mode?");
+
// Oh wait, I forgot to confirm! Let's do that
- assertThat(ShadowAlertDialog.getLatestAlertDialog()).isNotNull();
- assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isTrue();
- ShadowAlertDialog.getLatestAlertDialog()
- .getButton(AlertDialog.BUTTON_POSITIVE).performClick();
+ confirmDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
shadowOf(Looper.getMainLooper()).idle();
// Verify the backend got asked to update the mode to be disabled
@@ -314,7 +321,7 @@
mController.updateState(mPreference, mode);
assertThat(mPreference.isVisible()).isTrue();
- assertThat(mPreference.getTitle()).isEqualTo("Linked to app");
+ assertThat(mPreference.getTitle()).isEqualTo("App settings");
assertThat(mPreference.getSummary()).isEqualTo("When The Music's Over");
assertThat(mPreference.getIntent()).isEqualTo(configurationIntent);
}
@@ -331,7 +338,7 @@
mController.updateState(mPreference, mode);
assertThat(mPreference.isVisible()).isTrue();
- assertThat(mPreference.getTitle()).isEqualTo("Linked to app");
+ assertThat(mPreference.getTitle()).isEqualTo("App settings");
assertThat(mPreference.getSummary()).isEqualTo("When the saints go marching in");
assertThat(mPreference.getIntent()).isNull();
}
@@ -349,7 +356,7 @@
mController.updateState(mPreference, mode);
assertThat(mPreference.isVisible()).isTrue();
- assertThat(mPreference.getTitle()).isEqualTo("Linked to app");
+ assertThat(mPreference.getTitle()).isEqualTo("App settings");
assertThat(mPreference.getSummary()).isEqualTo("Info and settings in The App Name");
}
@@ -365,7 +372,7 @@
mController.updateState(mPreference, mode);
assertThat(mPreference.isVisible()).isTrue();
- assertThat(mPreference.getTitle()).isEqualTo("Linked to app");
+ assertThat(mPreference.getTitle()).isEqualTo("App settings");
assertThat(mPreference.getSummary()).isEqualTo("Managed by The App Name");
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListAddModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListAddModePreferenceControllerTest.java
index fe530c1..2db9171 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListAddModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListAddModePreferenceControllerTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Flags;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
@@ -37,6 +38,8 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import com.android.settings.notification.modes.ZenModesListAddModePreferenceController.ModeType;
@@ -44,6 +47,7 @@
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -58,8 +62,12 @@
import java.util.function.Function;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModesListAddModePreferenceControllerTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private Context mContext;
private ZenModesListAddModePreferenceController mController;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListFragmentTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListFragmentTest.java
index e105641..5bf7f05 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListFragmentTest.java
@@ -27,10 +27,13 @@
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Flags;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.testing.EmptyFragmentActivity;
@@ -53,8 +56,12 @@
import org.robolectric.shadows.ShadowActivity.IntentForResult;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModesListFragmentTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private static final ModeType APP_PROVIDED_MODE_TYPE = new ModeType("Mode", new ColorDrawable(),
"Details", new Intent().setComponent(new ComponentName("pkg", "configActivity")));
@@ -77,14 +84,14 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ ZenModesBackend.setInstance(mBackend);
+
mFragment = new ZenModesListFragment();
mActivityScenario.getScenario().onActivity(activity -> {
activity.getSupportFragmentManager().beginTransaction()
.add(mFragment, "tag").commitNow();
mActivity = activity;
});
-
- mFragment.setBackend(mBackend); // after onAttach()
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java
index dafcee7..ea45a71 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java
@@ -18,13 +18,17 @@
import static com.google.common.truth.Truth.assertThat;
+import android.app.Flags;
import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.ZenModeConfig;
import com.android.settingslib.notification.modes.TestModeBuilder;
import com.android.settingslib.notification.modes.ZenMode;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
@@ -33,7 +37,10 @@
import org.robolectric.shadows.ShadowLooper;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModesListItemPreferenceTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext;
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePreferenceControllerTest.java
index 8d551e5..e7d42d8 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePreferenceControllerTest.java
@@ -19,10 +19,10 @@
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -40,8 +40,6 @@
import androidx.preference.Preference;
-import com.android.settings.notification.modes.ZenModesListFragment;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -85,7 +83,14 @@
}
@Test
- public void isAvailable_unsearchable() {
+ @EnableFlags(Flags.FLAG_MODES_UI)
+ public void isAvailable_modesUi_unavailable() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_MODES_UI)
+ public void isAvailable_notModesUi_unsearchable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
diff --git a/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java
index bfab257..58288a5 100644
--- a/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java
@@ -23,28 +23,40 @@
import android.content.Context;
import android.content.pm.UserInfo;
+import android.multiuser.Flags;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.widget.SwitchWidgetController;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import java.util.ArrayList;
+import java.util.List;
+
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowUserManager.class})
+@Config(shadows = {ShadowUserManager.class, ShadowDevicePolicyManager.class})
public class MultiUserSwitchBarControllerTest {
private Context mContext;
private ShadowUserManager mUserManager;
private SwitchWidgetController mSwitchWidgetController;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Before
public void setUp() {
@@ -60,6 +72,7 @@
}
@Test
+ @RequiresFlagsDisabled({Flags.FLAG_FIX_DISABLING_OF_MU_TOGGLE_WHEN_RESTRICTION_APPLIED})
public void onStart_disallowUserSwitch_shouldSetDisabledByAdmin() {
mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
UserManager.DISALLOW_USER_SWITCH, true);
@@ -71,6 +84,48 @@
}
@Test
+ @RequiresFlagsEnabled({Flags.FLAG_FIX_DISABLING_OF_MU_TOGGLE_WHEN_RESTRICTION_APPLIED})
+ public void onStart_disallowUserSwitchEnforcedByAdmin_shouldSetDisabledByAdminUnchecked() {
+ int userId = UserHandle.myUserId();
+ List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
+ enforcingUsers.add(new UserManager.EnforcingUser(userId,
+ UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
+ // Ensure that RestrictedLockUtils.checkIfRestrictionEnforced doesn't return null.
+ ShadowUserManager.getShadow().setUserRestrictionSources(
+ UserManager.DISALLOW_USER_SWITCH,
+ UserHandle.of(userId),
+ enforcingUsers);
+
+ new MultiUserSwitchBarController(mContext, mSwitchWidgetController, null);
+ verify(mSwitchWidgetController).setChecked(false);
+ verify(mSwitchWidgetController).setDisabledByAdmin(any());
+ }
+
+ @Test
+ @RequiresFlagsEnabled({Flags.FLAG_FIX_DISABLING_OF_MU_TOGGLE_WHEN_RESTRICTION_APPLIED})
+ public void onStart_disallowUserSwitch_userNotMain_shouldSetDisabledUnchecked() {
+ mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
+ UserManager.DISALLOW_USER_SWITCH, true);
+ new MultiUserSwitchBarController(mContext, mSwitchWidgetController, null);
+
+ verify(mSwitchWidgetController).setChecked(false);
+ verify(mSwitchWidgetController).setEnabled(false);
+ verify(mSwitchWidgetController, never()).setDisabledByAdmin(any());
+ }
+
+ @Test
+ @RequiresFlagsEnabled({Flags.FLAG_FIX_DISABLING_OF_MU_TOGGLE_WHEN_RESTRICTION_APPLIED})
+ public void onStart_allowUserSwitch_notMainUser_shouldSetDisabled() {
+ mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
+ UserManager.DISALLOW_USER_SWITCH, false);
+ mUserManager.addUser(10, "Test", UserInfo.FLAG_ADMIN);
+ mUserManager.switchUser(10);
+ new MultiUserSwitchBarController(mContext, mSwitchWidgetController, null);
+
+ verify(mSwitchWidgetController).setEnabled(false);
+ }
+
+ @Test
public void onStart_allowUserSwitch_shouldNotSetDisabledByAdmin() {
mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
UserManager.DISALLOW_USER_SWITCH, false);
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.kt
index a2f635d..4d53260 100644
--- a/tests/spa_unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.kt
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.kt
@@ -24,6 +24,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.core.BasePreferenceController.AVAILABLE
import com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE
+import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -60,13 +61,13 @@
context = context,
key = KEY,
getDefaultDataSubId = { defaultDataSubId },
- ).apply { init(SUB_2_ID) }
+ )
@Test
fun getAvailabilityStatus_invalidSubscription_unavailable() {
controller.init(INVALID_SUBSCRIPTION_ID)
- val availabilityStatus = controller.getAvailabilityStatus(INVALID_SUBSCRIPTION_ID)
+ val availabilityStatus = controller.getAvailabilityStatus()
assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE)
}
@@ -76,8 +77,9 @@
mockTelephonyManager2.stub {
on { isDataEnabled } doReturn true
}
+ controller.init(SUB_2_ID)
- val availabilityStatus = controller.getAvailabilityStatus(SUB_2_ID)
+ val availabilityStatus = controller.getAvailabilityStatus()
assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE)
}
@@ -87,8 +89,9 @@
mockTelephonyManager2.stub {
on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn false
}
+ controller.init(SUB_2_ID)
- val availabilityStatus = controller.getAvailabilityStatus(SUB_2_ID)
+ val availabilityStatus = controller.getAvailabilityStatus()
assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE)
}
@@ -102,8 +105,9 @@
isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
} doReturn true
}
+ controller.init(SUB_2_ID)
- val availabilityStatus = controller.getAvailabilityStatus(SUB_2_ID)
+ val availabilityStatus = controller.getAvailabilityStatus()
assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE)
}
@@ -117,14 +121,16 @@
isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
} doReturn true
}
+ controller.init(SUB_2_ID)
- val availabilityStatus = controller.getAvailabilityStatus(SUB_2_ID)
+ val availabilityStatus = controller.getAvailabilityStatus()
assertThat(availabilityStatus).isEqualTo(AVAILABLE)
}
@Test
- fun getAvailabilityStatus_defaultDataOnAndAutoDataSwitchOn_unavailable() {
+ fun getAvailabilityStatus_notDefaultDataAndDataOnAndAutoDataSwitchOn_unavailable() {
+ defaultDataSubId = SUB_1_ID
mockTelephonyManager1.stub {
on { isDataEnabled } doReturn true
}
@@ -133,14 +139,16 @@
isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
} doReturn true
}
+ controller.init(SUB_2_ID)
- val availabilityStatus = controller.getAvailabilityStatus(SUB_2_ID)
+ val availabilityStatus = controller.getAvailabilityStatus()
assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE)
}
@Test
- fun getAvailabilityStatus_defaultDataOffAndAutoDataSwitchOn_available() {
+ fun getAvailabilityStatus_notDefaultDataAndDataOffAndAutoDataSwitchOn_available() {
+ defaultDataSubId = SUB_1_ID
mockTelephonyManager1.stub {
on { isDataEnabled } doReturn false
}
@@ -149,19 +157,57 @@
isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
} doReturn true
}
+ controller.init(SUB_2_ID)
- val availabilityStatus = controller.getAvailabilityStatus(SUB_2_ID)
+ val availabilityStatus = controller.getAvailabilityStatus()
assertThat(availabilityStatus).isEqualTo(AVAILABLE)
}
@Test
+ fun searchIsAvailable_notDefaultDataAndDataOnAndAutoDataSwitchOn_unavailable() {
+ mockTelephonyManager1.stub {
+ on { isDataEnabled } doReturn true
+ }
+ mockTelephonyManager2.stub {
+ on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn true
+ on {
+ isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
+ } doReturn true
+ }
+ val mmsMessageSearchItem = MmsMessageSearchItem(context) { SUB_1_ID }
+
+ val isAvailable = mmsMessageSearchItem.isAvailable(SUB_2_ID)
+
+ assertThat(isAvailable).isFalse()
+ }
+
+ @Test
+ fun searchIsAvailable_notDefaultDataAndDataOffAndAutoDataSwitchOn_available() {
+ mockTelephonyManager1.stub {
+ on { isDataEnabled } doReturn false
+ }
+ mockTelephonyManager2.stub {
+ on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn true
+ on {
+ isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
+ } doReturn true
+ }
+ val mmsMessageSearchItem = MmsMessageSearchItem(context) { SUB_1_ID }
+
+ val isAvailable = mmsMessageSearchItem.isAvailable(SUB_2_ID)
+
+ assertThat(isAvailable).isTrue()
+ }
+
+ @Test
fun isChecked_whenMmsNotAlwaysAllowed_returnFalse() {
mockTelephonyManager2.stub {
on {
isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED)
} doReturn false
}
+ controller.init(SUB_2_ID)
val isChecked = controller.isChecked()
@@ -175,6 +221,7 @@
isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED)
} doReturn true
}
+ controller.init(SUB_2_ID)
val isChecked = controller.isChecked()
@@ -183,6 +230,8 @@
@Test
fun setChecked_setTrue_setDataIntoSubscriptionManager() {
+ controller.init(SUB_2_ID)
+
controller.setChecked(true)
verify(mockTelephonyManager2).setMobileDataPolicyEnabled(
@@ -192,6 +241,8 @@
@Test
fun setChecked_setFalse_setDataIntoSubscriptionManager() {
+ controller.init(SUB_2_ID)
+
controller.setChecked(false)
verify(mockTelephonyManager2).setMobileDataPolicyEnabled(
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndexTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndexTest.kt
new file mode 100644
index 0000000..5e7e83c
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndexTest.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2024 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 android.content.Context
+import android.os.UserManager
+import android.provider.Settings
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.R
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.Companion.isMobileNetworkSettingsSearchable
+import com.android.settings.spa.SpaSearchLanding.BundleValue
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
+import com.android.settings.spa.search.SpaSearchLandingActivity
+import com.google.common.truth.Truth.assertThat
+import com.google.protobuf.ByteString
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+
+@RunWith(AndroidJUnit4::class)
+class MobileNetworkSettingsSearchIndexTest {
+
+ private val mockUserManager = mock<UserManager> { on { isAdminUser } doReturn true }
+
+ private val mockSubscriptionManager =
+ mock<SubscriptionManager> {
+ on { activeSubscriptionInfoList } doReturn listOf(SUB_INFO_1, SUB_INFO_2)
+ }
+
+ private val context: Context =
+ spy(ApplicationProvider.getApplicationContext()) {
+ on { getSystemService(UserManager::class.java) } doReturn mockUserManager
+ on { getSystemService(SubscriptionManager::class.java) } doReturn
+ mockSubscriptionManager
+ }
+
+ private val resources =
+ spy(context.resources) { on { getBoolean(R.bool.config_show_sim_info) } doReturn true }
+
+ private val mobileNetworkSettingsSearchIndex = MobileNetworkSettingsSearchIndex {
+ listOf(
+ object : MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem {
+ override val key = KEY
+ override val title = TITLE
+
+ override fun isAvailable(subId: Int) = subId == SUB_ID_1
+ })
+ }
+
+ @Before
+ fun setUp() {
+ context.stub { on { resources } doReturn resources }
+ }
+
+ @Test
+ fun isMobileNetworkSettingsSearchable_adminUser_returnTrue() {
+ mockUserManager.stub { on { isAdminUser } doReturn true }
+
+ val isSearchable = isMobileNetworkSettingsSearchable(context)
+
+ assertThat(isSearchable).isTrue()
+ }
+
+ @Test
+ fun isMobileNetworkSettingsSearchable_nonAdminUser_returnFalse() {
+ mockUserManager.stub { on { isAdminUser } doReturn false }
+
+ val isSearchable = isMobileNetworkSettingsSearchable(context)
+
+ assertThat(isSearchable).isFalse()
+ }
+
+ @Test
+ fun createSearchIndexableData() {
+ val searchIndexableData = mobileNetworkSettingsSearchIndex.createSearchIndexableData()
+
+ assertThat(searchIndexableData.targetClass).isEqualTo(MobileNetworkSettings::class.java)
+ val dynamicRawDataToIndex =
+ searchIndexableData.searchIndexProvider.getDynamicRawDataToIndex(context, true)
+ assertThat(dynamicRawDataToIndex).hasSize(1)
+ val rawData = dynamicRawDataToIndex[0]
+ val key = SpaSearchLandingKey.parseFrom(ByteString.copyFromUtf8(rawData.key))
+ assertThat(key)
+ .isEqualTo(
+ SpaSearchLandingKey.newBuilder()
+ .setFragment(
+ SpaSearchLandingFragment.newBuilder()
+ .setFragmentName(MobileNetworkSettings::class.java.name)
+ .setPreferenceKey(KEY)
+ .putArguments(
+ Settings.EXTRA_SUB_ID,
+ BundleValue.newBuilder().setIntValue(SUB_ID_1).build()))
+ .build())
+ assertThat(rawData.title).isEqualTo(TITLE)
+ assertThat(rawData.intentAction).isEqualTo("android.settings.SPA_SEARCH_LANDING")
+ assertThat(rawData.intentTargetClass)
+ .isEqualTo(SpaSearchLandingActivity::class.qualifiedName)
+ assertThat(rawData.className).isEqualTo(MobileNetworkSettings::class.java.name)
+ assertThat(rawData.screenTitle).isEqualTo("SIMs > $SUB_DISPLAY_NAME_1")
+ }
+
+ private companion object {
+ const val KEY = "key"
+ const val TITLE = "Title"
+ const val SUB_ID_1 = 1
+ const val SUB_ID_2 = 2
+ const val SUB_DISPLAY_NAME_1 = "Sub 1"
+ const val SUB_DISPLAY_NAME_2 = "Sub 2"
+
+ val SUB_INFO_1: SubscriptionInfo =
+ SubscriptionInfo.Builder()
+ .apply {
+ setId(SUB_ID_1)
+ setDisplayName(SUB_DISPLAY_NAME_1)
+ }
+ .build()
+
+ val SUB_INFO_2: SubscriptionInfo =
+ SubscriptionInfo.Builder()
+ .apply {
+ setId(SUB_ID_2)
+ setDisplayName(SUB_DISPLAY_NAME_2)
+ }
+ .build()
+ }
+}
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/InstantAppDomainsPreferenceTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/InstantAppDomainsPreferenceTest.kt
index 1a78c49..e5f8fb0 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/InstantAppDomainsPreferenceTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/InstantAppDomainsPreferenceTest.kt
@@ -24,6 +24,7 @@
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsEnabled
import androidx.compose.ui.test.assertIsNotDisplayed
+import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
@@ -35,42 +36,41 @@
import com.android.settings.Utils
import com.android.settingslib.spa.testutils.delay
import com.android.settingslib.spa.testutils.onDialogText
+import com.android.settingslib.spa.testutils.waitUntilExists
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.Mockito.any
-import org.mockito.Mockito.anyInt
import org.mockito.MockitoSession
-import org.mockito.Spy
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
-import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidJUnit4::class)
class InstantAppDomainsPreferenceTest {
- @get:Rule
- val composeTestRule = createComposeRule()
+ @get:Rule val composeTestRule = createComposeRule()
private lateinit var mockSession: MockitoSession
- @Spy
- private val context: Context = ApplicationProvider.getApplicationContext()
+ private val packageManager = mock<PackageManager>()
- @Mock
- private lateinit var packageManager: PackageManager
+ private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+ on { packageManager } doReturn packageManager
+ doReturn(mock).whenever(mock).createContextAsUser(any(), any())
+ }
@Before
fun setUp() {
- mockSession = ExtendedMockito.mockitoSession()
- .initMocks(this)
- .mockStatic(Utils::class.java)
- .strictness(Strictness.LENIENT)
- .startMocking()
- whenever(context.packageManager).thenReturn(packageManager)
- Mockito.doReturn(context).`when`(context).createContextAsUser(any(), anyInt())
+ mockSession =
+ ExtendedMockito.mockitoSession()
+ .mockStatic(Utils::class.java)
+ .strictness(Strictness.LENIENT)
+ .startMocking()
+
mockDomains(emptySet())
}
@@ -108,8 +108,8 @@
setContent()
- composeTestRule.onNodeWithText(context.getString(R.string.domain_urls_summary_none))
- .assertIsDisplayed()
+ composeTestRule.waitUntilExists(
+ hasText(context.getString(R.string.domain_urls_summary_none)))
}
@Test
@@ -138,9 +138,9 @@
composeTestRule.onRoot().performClick()
composeTestRule.delay()
- composeTestRule.onDialogText(
- context.getString(R.string.app_launch_supported_domain_urls_title)
- ).assertIsDisplayed()
+ composeTestRule
+ .onDialogText(context.getString(R.string.app_launch_supported_domain_urls_title))
+ .assertIsDisplayed()
composeTestRule.onDialogText("abc").assertIsDisplayed()
composeTestRule.onDialogText("def").assertIsDisplayed()
}
@@ -157,10 +157,11 @@
const val PACKAGE_NAME = "package.name"
const val UID = 123
- val INSTANT_APP = ApplicationInfo().apply {
- packageName = PACKAGE_NAME
- uid = UID
- privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT
- }
+ val INSTANT_APP =
+ ApplicationInfo().apply {
+ packageName = PACKAGE_NAME
+ uid = UID
+ privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT
+ }
}
}
diff --git a/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchLandingActivityTest.kt b/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchLandingActivityTest.kt
new file mode 100644
index 0000000..7410bb4
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchLandingActivityTest.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 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.spa.search
+
+import android.content.Context
+import android.content.Intent
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.SettingsActivity
+import com.android.settings.spa.SpaSearchLanding.BundleValue
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingSpaPage
+import com.android.settingslib.spa.framework.util.KEY_DESTINATION
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doNothing
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@RunWith(AndroidJUnit4::class)
+class SpaSearchLandingActivityTest {
+
+ private val context: Context =
+ spy(ApplicationProvider.getApplicationContext()) {
+ doNothing().whenever(mock).startActivity(any())
+ }
+
+ @Test
+ fun tryLaunch_spaPage() {
+ val key =
+ SpaSearchLandingKey.newBuilder()
+ .setSpaPage(SpaSearchLandingSpaPage.newBuilder().setDestination(DESTINATION))
+ .build()
+
+ SpaSearchLandingActivity.tryLaunch(context, key.toByteString().toStringUtf8())
+
+ verify(context).startActivity(argThat { getStringExtra(KEY_DESTINATION) == DESTINATION })
+ }
+
+ @Test
+ fun tryLaunch_fragment() {
+ val key =
+ SpaSearchLandingKey.newBuilder()
+ .setFragment(
+ SpaSearchLandingFragment.newBuilder()
+ .setFragmentName(DESTINATION)
+ .setPreferenceKey(PREFERENCE_KEY)
+ .putArguments(
+ ARGUMENT_KEY,
+ BundleValue.newBuilder().setIntValue(ARGUMENT_VALUE).build()))
+ .build()
+
+ SpaSearchLandingActivity.tryLaunch(context, key.toByteString().toStringUtf8())
+
+ val intent = argumentCaptor<Intent> { verify(context).startActivity(capture()) }.firstValue
+ assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+ .isEqualTo(DESTINATION)
+ val fragmentArguments =
+ intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)!!
+ assertThat(fragmentArguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY))
+ .isEqualTo(PREFERENCE_KEY)
+ assertThat(fragmentArguments.getInt(ARGUMENT_KEY)).isEqualTo(ARGUMENT_VALUE)
+ }
+
+ private companion object {
+ const val DESTINATION = "Destination"
+ const val PREFERENCE_KEY = "preference_key"
+ const val ARGUMENT_KEY = "argument_key"
+ const val ARGUMENT_VALUE = 123
+ }
+}
diff --git a/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchRepositoryTest.kt
index 911dfd2..c38f22f 100644
--- a/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchRepositoryTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchRepositoryTest.kt
@@ -18,9 +18,12 @@
import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
+import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingSpaPage
import com.android.settings.spa.search.SpaSearchRepository.Companion.createSearchIndexableData
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.google.common.truth.Truth.assertThat
+import com.google.protobuf.ByteString
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
@@ -35,17 +38,31 @@
override val name = PAGE_NAME
}
- val searchIndexableData = pageProvider.createSearchIndexableData { listOf(TITLE) }
+ val searchIndexableData =
+ pageProvider.createSearchIndexableData({ PAGE_TITLE }) { listOf(ITEM_TITLE) }
val dynamicRawDataToIndex =
searchIndexableData.searchIndexProvider.getDynamicRawDataToIndex(mock<Context>(), true)
assertThat(searchIndexableData.targetClass).isEqualTo(pageProvider::class.java)
assertThat(dynamicRawDataToIndex).hasSize(1)
- assertThat(dynamicRawDataToIndex[0].title).isEqualTo(TITLE)
+ val rawData = dynamicRawDataToIndex[0]
+ val key = SpaSearchLandingKey.parseFrom(ByteString.copyFromUtf8(rawData.key))
+ assertThat(key)
+ .isEqualTo(
+ SpaSearchLandingKey.newBuilder()
+ .setSpaPage(SpaSearchLandingSpaPage.newBuilder().setDestination(PAGE_NAME))
+ .build())
+ assertThat(rawData.title).isEqualTo(ITEM_TITLE)
+ assertThat(rawData.intentAction).isEqualTo("android.settings.SPA_SEARCH_LANDING")
+ assertThat(rawData.intentTargetClass)
+ .isEqualTo(SpaSearchLandingActivity::class.qualifiedName)
+ assertThat(rawData.className).isEqualTo(pageProvider::class.java.name)
+ assertThat(rawData.screenTitle).isEqualTo(PAGE_TITLE)
}
private companion object {
const val PAGE_NAME = "PageName"
- const val TITLE = "Title"
+ const val PAGE_TITLE = "Page Title"
+ const val ITEM_TITLE = "Item Title"
}
}
diff --git a/tests/spa_unit/src/com/android/settings/system/DeveloperOptionsControllerTest.kt b/tests/spa_unit/src/com/android/settings/system/DeveloperOptionsControllerTest.kt
index ad2fbae..4631aa8 100644
--- a/tests/spa_unit/src/com/android/settings/system/DeveloperOptionsControllerTest.kt
+++ b/tests/spa_unit/src/com/android/settings/system/DeveloperOptionsControllerTest.kt
@@ -28,6 +28,7 @@
import com.android.settings.SettingsActivity
import com.android.settings.core.BasePreferenceController
import com.android.settings.development.DevelopmentSettingsDashboardFragment
+import com.android.settingslib.spa.testutils.delay
import com.android.settingslib.spaprivileged.framework.common.userManager
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
@@ -99,6 +100,7 @@
composeTestRule.onNodeWithText(
context.getString(com.android.settingslib.R.string.development_settings_title)
).performClick()
+ composeTestRule.delay()
val intent = argumentCaptor<Intent> {
verify(context).startActivity(capture())
diff --git a/tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
index 237786b..326627a 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
@@ -28,8 +28,13 @@
import android.app.Activity;
import android.content.Context;
+import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.Flags;
import android.os.Looper;
import android.os.UserManager;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
@@ -45,6 +50,7 @@
import com.android.settingslib.development.DevelopmentSettingsEnabler;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
@@ -53,6 +59,9 @@
@RunWith(AndroidJUnit4.class)
public class BuildNumberPreferenceControllerTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
private static final String KEY_BUILD_NUMBER = "build_number";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -60,6 +69,7 @@
private Context mContext;
private UserManager mUserManager;
+ private BiometricManager mBiometricManager;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private FakeFeatureFactory mFactory;
@@ -76,7 +86,13 @@
mContext = spy(ApplicationProvider.getApplicationContext());
mUserManager = (UserManager) spy(mContext.getSystemService(Context.USER_SERVICE));
+ mBiometricManager = spy(mContext.getSystemService(BiometricManager.class));
+
doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
+ when(mContext.getSystemService(BiometricManager.class)).thenReturn(mBiometricManager);
+ when(mBiometricManager.canAuthenticate(mContext.getUserId(),
+ BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
+ .thenReturn(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE);
mFactory = FakeFeatureFactory.setupForTest();
mLifecycleOwner = () -> mLifecycle;
@@ -156,7 +172,7 @@
@Test
public void onActivityResult_notConfirmPasswordRequest_doNothing() {
final boolean activityResultHandled = mController.onActivityResult(
- BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF + 1,
+ BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF + 2,
Activity.RESULT_OK,
null);
@@ -188,4 +204,38 @@
assertThat(activityResultHandled).isTrue();
assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isTrue();
}
+
+ @Test
+ @UiThreadTest
+ @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void onActivityResult_confirmPasswordRequestCompleted_launchBiometricPrompt() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ when(mBiometricManager.canAuthenticate(mContext.getUserId(),
+ BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
+ .thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
+
+ final boolean activityResultHandled = mController.onActivityResult(
+ BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
+ Activity.RESULT_OK,
+ null);
+
+ assertThat(activityResultHandled).isTrue();
+ assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isFalse();
+ verify(mFragment).startActivityForResult(any(),
+ eq(BuildNumberPreferenceController.REQUEST_IDENTITY_CHECK_FOR_DEV_PREF));
+ }
+
+ @Test
+ public void onActivityResult_confirmBiometricAuthentication_enableDevPref() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+
+ Looper.prepare();
+ final boolean activityResultHandled = mController.onActivityResult(
+ BuildNumberPreferenceController.REQUEST_IDENTITY_CHECK_FOR_DEV_PREF,
+ Activity.RESULT_OK,
+ null);
+
+ assertThat(activityResultHandled).isTrue();
+ assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isTrue();
+ }
}
diff --git a/tests/unit/src/com/android/settings/security/SecuritySettingsTest.java b/tests/unit/src/com/android/settings/security/SecuritySettingsTest.java
index dee90b4..61ca6e5 100644
--- a/tests/unit/src/com/android/settings/security/SecuritySettingsTest.java
+++ b/tests/unit/src/com/android/settings/security/SecuritySettingsTest.java
@@ -339,6 +339,30 @@
assertThat(mPreferenceCombined.isVisible()).isFalse();
}
+ @Test
+ public void noFace_isNotIndexable() throws Exception {
+ when(mFaceManager.isHardwareDetected()).thenReturn(false);
+ final BaseSearchIndexProvider indexProvider = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER;
+
+ final List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);
+ final List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext);
+ allXmlKeys.removeAll(nonIndexableKeys);
+
+ assertThat(allXmlKeys).doesNotContain(SecuritySettings.KEY_FACE_SETTINGS);
+ }
+
+ @Test
+ public void noFingerprint_isNotIndexable() throws Exception {
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
+ final BaseSearchIndexProvider indexProvider = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER;
+
+ final List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);
+ final List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext);
+ allXmlKeys.removeAll(nonIndexableKeys);
+
+ assertThat(allXmlKeys).doesNotContain(SecuritySettings.KEY_FINGERPRINT_SETTINGS);
+ }
+
boolean isFacePrefAvailable(List<AbstractPreferenceController> controllers) {
return controllers.stream().filter(
controller -> controller instanceof FaceStatusPreferenceController