diff --git a/res/layout/dialog_a11y_bounce_key.xml b/res/layout/dialog_a11y_bounce_key.xml index 7e236925e18..da3ebde933d 100644 --- a/res/layout/dialog_a11y_bounce_key.xml +++ b/res/layout/dialog_a11y_bounce_key.xml @@ -56,28 +56,79 @@ android:id="@+id/bounce_key_value_200" android:text="@string/bounce_keys_dialog_option_200" android:paddingStart="12dp" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" + android:layout_gravity="start|center_vertical" android:background="@null"/> + + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 5326fa5d7a9..97a7e232304 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4696,6 +4696,10 @@ Physical keyboard accessibility Sticky keys, Bounce keys, Mouse keys + + Repeat Keys + + Hold down a key to repeat its character until the key is released %s layout diff --git a/res/xml/physical_keyboard_settings.xml b/res/xml/physical_keyboard_settings.xml index 1527ff52866..5d2c5fcd99b 100644 --- a/res/xml/physical_keyboard_settings.xml +++ b/res/xml/physical_keyboard_settings.xml @@ -15,6 +15,7 @@ --> @@ -31,6 +32,14 @@ android:title="@string/modifier_keys_settings" android:summary="@string/modifier_keys_settings_summary" android:fragment="com.android.settings.inputmethod.ModifierKeysSettings" /> + + + + android:order="202" + settings:searchable="false"/> getRawDataToIndex(Context context, boolean enabled) { - final List rawData = new ArrayList<>(); + final List rawData = + super.getRawDataToIndex(context, enabled); + SearchIndexableRaw raw = new SearchIndexableRaw(context); raw.key = KEY_SHORTCUT_PREFERENCE; raw.title = context.getString( - R.string.accessibility_display_inversion_shortcut_title); + R.string.accessibility_display_inversion_shortcut_title); rawData.add(raw); + + if (Flags.fixA11ySettingsSearch()) { + SearchIndexableRaw mainPreferenceRaw = new SearchIndexableRaw(context); + mainPreferenceRaw.key = KEY_SWITCH_PREFERENCE; + mainPreferenceRaw.title = context.getString( + R.string.accessibility_display_inversion_switch_title); + rawData.add(mainPreferenceRaw); + } return rawData; } }; diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java index 86ddd71e262..747efaa60db 100644 --- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java @@ -25,6 +25,7 @@ import static com.android.settings.accessibility.DaltonizerPreferenceUtil.isSecu import android.app.settings.SettingsEnums; import android.content.ComponentName; +import android.content.Context; import android.os.Bundle; import android.provider.Settings; import android.view.LayoutInflater; @@ -38,6 +39,7 @@ import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltip import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SettingsMainSwitchPreference; import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.search.SearchIndexableRaw; import java.util.ArrayList; import java.util.List; @@ -53,6 +55,11 @@ public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceF private static final String KEY_PROTANOMALY = "daltonizer_mode_protanomaly"; private static final String KEY_TRITANOMEALY = "daltonizer_mode_tritanomaly"; private static final String KEY_GRAYSCALE = "daltonizer_mode_grayscale"; + + @VisibleForTesting + static final String KEY_SHORTCUT_PREFERENCE = "daltonizer_shortcut_key"; + @VisibleForTesting + static final String KEY_SWITCH_PREFERENCE = "daltonizer_switch_preference_key"; @VisibleForTesting static final String KEY_SATURATION = "daltonizer_saturation"; @@ -106,7 +113,7 @@ public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceF final List lists = new ArrayList<>(); lists.add(KEY_TOP_INTRO_PREFERENCE); lists.add(KEY_PREVIEW); - lists.add(KEY_USE_SERVICE_PREFERENCE); + lists.add(getUseServicePreferenceKey()); // Putting saturation level close to the preview so users can see what is changing. lists.add(KEY_SATURATION); lists.add(KEY_DEUTERANOMALY); @@ -170,6 +177,11 @@ public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceF switchPreference.setTitle(R.string.accessibility_daltonizer_primary_switch_title); } + @Override + protected String getUseServicePreferenceKey() { + return KEY_SWITCH_PREFERENCE; + } + @Override protected CharSequence getShortcutTitle() { return getText(R.string.accessibility_daltonizer_shortcut_title); @@ -203,5 +215,27 @@ public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceF } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings); + new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings) { + @Override + public List getRawDataToIndex(Context context, + boolean enabled) { + final List rawData = + super.getRawDataToIndex(context, enabled); + + if (Flags.fixA11ySettingsSearch()) { + SearchIndexableRaw shortcutRaw = new SearchIndexableRaw(context); + shortcutRaw.key = KEY_SHORTCUT_PREFERENCE; + shortcutRaw.title = context.getString( + R.string.accessibility_daltonizer_shortcut_title); + rawData.add(shortcutRaw); + + SearchIndexableRaw mainSwitchRaw = new SearchIndexableRaw(context); + mainSwitchRaw.key = KEY_SWITCH_PREFERENCE; + mainSwitchRaw.title = context.getString( + R.string.accessibility_daltonizer_primary_switch_title); + rawData.add(mainSwitchRaw); + } + return rawData; + } + }; } diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index 6649cf48354..a9f422e3749 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -83,7 +83,6 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment public static final String KEY_GENERAL_CATEGORY = "general_categories"; public static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference"; protected static final String KEY_TOP_INTRO_PREFERENCE = "top_intro"; - protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service"; protected static final String KEY_HTML_DESCRIPTION_PREFERENCE = "html_description"; protected static final String KEY_SAVED_QS_TOOLTIP_RESHOW = "qs_tooltip_reshow"; protected static final String KEY_SAVED_QS_TOOLTIP_TYPE = "qs_tooltip_type"; @@ -325,6 +324,10 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment switchPreference.setTitle(title); } + protected String getUseServicePreferenceKey() { + return "use_service"; + } + protected CharSequence getShortcutTitle() { return getString(R.string.accessibility_shortcut_title, mPackageName); } @@ -411,7 +414,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment final List lists = new ArrayList<>(); lists.add(KEY_TOP_INTRO_PREFERENCE); lists.add(KEY_ANIMATED_IMAGE); - lists.add(KEY_USE_SERVICE_PREFERENCE); + lists.add(getUseServicePreferenceKey()); lists.add(KEY_GENERAL_CATEGORY); lists.add(KEY_HTML_DESCRIPTION_PREFERENCE); return lists; @@ -476,7 +479,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment private void initToggleServiceSwitchPreference() { mToggleServiceSwitchPreference = new SettingsMainSwitchPreference(getPrefContext()); - mToggleServiceSwitchPreference.setKey(KEY_USE_SERVICE_PREFERENCE); + mToggleServiceSwitchPreference.setKey(getUseServicePreferenceKey()); if (getArguments().containsKey(AccessibilitySettings.EXTRA_CHECKED)) { final boolean enabled = getArguments().getBoolean(AccessibilitySettings.EXTRA_CHECKED); mToggleServiceSwitchPreference.setChecked(enabled); diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index bc14288f335..ee49450f82d 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -54,7 +54,6 @@ import androidx.annotation.StringRes; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.SwitchPreferenceCompat; -import androidx.preference.TwoStatePreference; import com.android.internal.accessibility.common.ShortcutConstants; import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType; @@ -64,7 +63,11 @@ import com.android.settings.DialogCreatable; import com.android.settings.R; import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType; import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment; +import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.search.Indexable; +import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.search.SearchIndexableRaw; import com.android.settingslib.widget.IllustrationPreference; import com.google.android.setupcompat.util.WizardManagerHelper; @@ -73,16 +76,20 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.StringJoiner; +import java.util.stream.Stream; /** * Fragment that shows the actual UI for providing basic magnification accessibility service setup * and does not have toggle bar to turn on service to use. */ +@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) public class ToggleScreenMagnificationPreferenceFragment extends ToggleFeaturePreferenceFragment implements MagnificationModePreferenceController.DialogHelper { private static final String TAG = "ToggleScreenMagnificationPreferenceFragment"; + @VisibleForTesting + static final String KEY_MAGNIFICATION_SHORTCUT_PREFERENCE = "magnification_shortcut_preference"; private static final char COMPONENT_NAME_SEPARATOR = ':'; private static final TextUtils.SimpleStringSplitter sStringColonSplitter = new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); @@ -181,38 +188,29 @@ public class ToggleScreenMagnificationPreferenceFragment extends } } + private static boolean isWindowMagnificationSupported(Context context) { + return context.getResources().getBoolean( + com.android.internal.R.bool.config_magnification_area) + && context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WINDOW_MAGNIFICATION); + } + @Override protected void initSettingsPreference() { // If the device doesn't support window magnification feature, it should hide the // settings preference. - final boolean supportWindowMagnification = - getContext().getResources().getBoolean( - com.android.internal.R.bool.config_magnification_area) - && getContext().getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WINDOW_MAGNIFICATION); - if (!supportWindowMagnification) { + if (!isWindowMagnificationSupported(getContext())) { return; } - mSettingsPreference = new Preference(getPrefContext()); - mSettingsPreference.setTitle(R.string.accessibility_magnification_mode_title); - mSettingsPreference.setKey(MagnificationModePreferenceController.PREF_KEY); - mSettingsPreference.setPersistent(false); final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY); - generalCategory.addPreference(mSettingsPreference); - - final MagnificationModePreferenceController magnificationModePreferenceController = - new MagnificationModePreferenceController(getContext(), - MagnificationModePreferenceController.PREF_KEY); - magnificationModePreferenceController.setDialogHelper(this); - getSettingsLifecycle().addObserver(magnificationModePreferenceController); - magnificationModePreferenceController.displayPreference(getPreferenceScreen()); - addPreferenceController(magnificationModePreferenceController); - + // LINT.IfChange(:preference_list) + addMagnificationModeSetting(generalCategory); addFollowTypingSetting(generalCategory); addOneFingerPanningSetting(generalCategory); addAlwaysOnSetting(generalCategory); addJoystickSetting(generalCategory); + // LINT.ThenChange(:search_data) } @Override @@ -233,22 +231,44 @@ public class ToggleScreenMagnificationPreferenceFragment extends && !Flags.enableMagnificationOneFingerPanningGesture()) { String summary = MessageFormat.format( context.getString(R.string.accessibility_screen_magnification_summary), - new Object[]{1, 2, 3, 4, 5}); + new Object[]{1, 2, 3, 4, 5}); arguments.putCharSequence(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, summary); } super.onProcessArguments(arguments); } + private static Preference createMagnificationModePreference(Context context) { + final Preference pref = new Preference(context); + pref.setTitle(R.string.accessibility_magnification_mode_title); + pref.setKey(MagnificationModePreferenceController.PREF_KEY); + pref.setPersistent(false); + return pref; + } + + private void addMagnificationModeSetting(PreferenceCategory generalCategory) { + mSettingsPreference = createMagnificationModePreference(getPrefContext()); + generalCategory.addPreference(mSettingsPreference); + + final MagnificationModePreferenceController magnificationModePreferenceController = + new MagnificationModePreferenceController(getContext(), + MagnificationModePreferenceController.PREF_KEY); + magnificationModePreferenceController.setDialogHelper(this); + getSettingsLifecycle().addObserver(magnificationModePreferenceController); + magnificationModePreferenceController.displayPreference(getPreferenceScreen()); + addPreferenceController(magnificationModePreferenceController); + } + + private static Preference createFollowTypingPreference(Context context) { + final Preference pref = new SwitchPreferenceCompat(context); + pref.setTitle(R.string.accessibility_screen_magnification_follow_typing_title); + pref.setSummary(R.string.accessibility_screen_magnification_follow_typing_summary); + pref.setKey(MagnificationFollowTypingPreferenceController.PREF_KEY); + return pref; + } + private void addFollowTypingSetting(PreferenceCategory generalCategory) { - var followingTypingSwitchPreference = new SwitchPreferenceCompat(getPrefContext()); - followingTypingSwitchPreference.setTitle( - R.string.accessibility_screen_magnification_follow_typing_title); - followingTypingSwitchPreference.setSummary( - R.string.accessibility_screen_magnification_follow_typing_summary); - followingTypingSwitchPreference.setKey( - MagnificationFollowTypingPreferenceController.PREF_KEY); - generalCategory.addPreference(followingTypingSwitchPreference); + generalCategory.addPreference(createFollowTypingPreference(getPrefContext())); var followTypingPreferenceController = new MagnificationFollowTypingPreferenceController( getContext(), MagnificationFollowTypingPreferenceController.PREF_KEY); @@ -257,8 +277,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends addPreferenceController(followTypingPreferenceController); } - private boolean isAlwaysOnSettingEnabled() { - final boolean defaultValue = getContext().getResources().getBoolean( + private static boolean isAlwaysOnSupported(Context context) { + final boolean defaultValue = context.getResources().getBoolean( com.android.internal.R.bool.config_magnification_always_on_enabled); return DeviceConfig.getBoolean( @@ -268,19 +288,21 @@ public class ToggleScreenMagnificationPreferenceFragment extends ); } + private static Preference createAlwaysOnPreference(Context context) { + final Preference pref = new SwitchPreferenceCompat(context); + pref.setTitle(R.string.accessibility_screen_magnification_always_on_title); + pref.setSummary(R.string.accessibility_screen_magnification_always_on_summary); + pref.setKey(MagnificationAlwaysOnPreferenceController.PREF_KEY); + return pref; + } + private void addAlwaysOnSetting(PreferenceCategory generalCategory) { - if (!isAlwaysOnSettingEnabled()) { + if (!isAlwaysOnSupported(getContext())) { return; } - var alwaysOnPreference = new SwitchPreferenceCompat(getPrefContext()); - alwaysOnPreference.setTitle( - R.string.accessibility_screen_magnification_always_on_title); - alwaysOnPreference.setSummary( - R.string.accessibility_screen_magnification_always_on_summary); - alwaysOnPreference.setKey( - MagnificationAlwaysOnPreferenceController.PREF_KEY); - generalCategory.addPreference(alwaysOnPreference); + final Preference pref = createAlwaysOnPreference(getPrefContext()); + generalCategory.addPreference(pref); var alwaysOnPreferenceController = new MagnificationAlwaysOnPreferenceController( getContext(), MagnificationAlwaysOnPreferenceController.PREF_KEY); @@ -290,17 +312,24 @@ public class ToggleScreenMagnificationPreferenceFragment extends addPreferenceController(alwaysOnPreferenceController); } + private static Preference createOneFingerPanningPreference(Context context) { + final Preference pref = new SwitchPreferenceCompat(context); + pref.setTitle(R.string.accessibility_magnification_one_finger_panning_title); + pref.setKey(MagnificationOneFingerPanningPreferenceController.PREF_KEY); + return pref; + } + + private static boolean isOneFingerPanningSupported() { + return Flags.enableMagnificationOneFingerPanningGesture(); + } + private void addOneFingerPanningSetting(PreferenceCategory generalCategory) { - if (!Flags.enableMagnificationOneFingerPanningGesture()) { + if (!isOneFingerPanningSupported()) { return; } - var oneFingerPanningPreference = new SwitchPreferenceCompat(getPrefContext()); - oneFingerPanningPreference.setTitle( - R.string.accessibility_magnification_one_finger_panning_title); - oneFingerPanningPreference.setKey( - MagnificationOneFingerPanningPreferenceController.PREF_KEY); - generalCategory.addPreference(oneFingerPanningPreference); + final Preference pref = createOneFingerPanningPreference(getPrefContext()); + generalCategory.addPreference(pref); mOneFingerPanningPreferenceController = new MagnificationOneFingerPanningPreferenceController(getContext()); @@ -310,23 +339,28 @@ public class ToggleScreenMagnificationPreferenceFragment extends addPreferenceController(mOneFingerPanningPreferenceController); } - private void addJoystickSetting(PreferenceCategory generalCategory) { - if (!DeviceConfig.getBoolean( + private static Preference createJoystickPreference(Context context) { + final Preference pref = new SwitchPreferenceCompat(context); + pref.setTitle(R.string.accessibility_screen_magnification_joystick_title); + pref.setSummary(R.string.accessibility_screen_magnification_joystick_summary); + pref.setKey(MagnificationJoystickPreferenceController.PREF_KEY); + return pref; + } + + private static boolean isJoystickSupported() { + return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_WINDOW_MANAGER, "MagnificationJoystick__enable_magnification_joystick", - false - )) { + false); + } + + private void addJoystickSetting(PreferenceCategory generalCategory) { + if (!isJoystickSupported()) { return; } - TwoStatePreference joystickPreference = new SwitchPreferenceCompat(getPrefContext()); - joystickPreference.setTitle( - R.string.accessibility_screen_magnification_joystick_title); - joystickPreference.setSummary( - R.string.accessibility_screen_magnification_joystick_summary); - joystickPreference.setKey( - MagnificationJoystickPreferenceController.PREF_KEY); - generalCategory.addPreference(joystickPreference); + final Preference pref = createJoystickPreference(getPrefContext()); + generalCategory.addPreference(pref); MagnificationJoystickPreferenceController joystickPreferenceController = new MagnificationJoystickPreferenceController( @@ -354,9 +388,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends super.registerKeysToObserverCallback(contentObserver); var keysToObserve = List.of( - Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED, - Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED, - Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED, + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED, + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED ); contentObserver.registerKeysToObserverCallback(keysToObserve, key -> updatePreferencesState()); @@ -409,7 +443,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends return getShortcutSummaryList(context, PreferredShortcuts.retrieveUserShortcutType(context, - MAGNIFICATION_CONTROLLER_NAME)); + MAGNIFICATION_CONTROLLER_NAME)); } @Override @@ -517,6 +551,11 @@ public class ToggleScreenMagnificationPreferenceFragment extends generalCategory.addPreference(mShortcutPreference); } + @Override + protected String getShortcutPreferenceKey() { + return KEY_MAGNIFICATION_SHORTCUT_PREFERENCE; + } + @Override protected CharSequence getShortcutTitle() { return getText(R.string.accessibility_screen_magnification_shortcut_title); @@ -777,8 +816,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends final int userShortcutType = getUserShortcutTypeFromSettings(context); final CharSequence featureState = (userShortcutType != DEFAULT) - ? context.getText(R.string.accessibility_summary_shortcut_enabled) - : context.getText(R.string.generic_accessibility_feature_shortcut_off); + ? context.getText(R.string.accessibility_summary_shortcut_enabled) + : context.getText(R.string.generic_accessibility_feature_shortcut_off); final CharSequence featureSummary = context.getText(R.string.magnification_feature_summary); return context.getString( com.android.settingslib.R.string.preference_summary_default_combination, @@ -790,4 +829,81 @@ public class ToggleScreenMagnificationPreferenceFragment extends return PreferredShortcuts.retrieveUserShortcutType( getPrefContext(), MAGNIFICATION_CONTROLLER_NAME); } + + public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + // LINT.IfChange(:search_data) + @Override + public List getRawDataToIndex(Context context, + boolean enabled) { + final List rawData = + super.getRawDataToIndex(context, enabled); + + if (!com.android.settings.accessibility.Flags.fixA11ySettingsSearch()) { + return rawData; + } + + rawData.add(createShortcutPreferenceSearchData(context)); + Stream.of( + createMagnificationModePreference(context), + createFollowTypingPreference(context), + createOneFingerPanningPreference(context), + createAlwaysOnPreference(context), + createJoystickPreference(context) + ) + .forEach(pref -> + rawData.add(createPreferenceSearchData(context, pref))); + return rawData; + } + + @Override + public List getNonIndexableKeys(Context context) { + final List niks = super.getNonIndexableKeys(context); + + if (!com.android.settings.accessibility.Flags.fixA11ySettingsSearch()) { + return niks; + } + + if (!isWindowMagnificationSupported(context)) { + niks.add(MagnificationModePreferenceController.PREF_KEY); + niks.add(MagnificationFollowTypingPreferenceController.PREF_KEY); + niks.add(MagnificationOneFingerPanningPreferenceController.PREF_KEY); + niks.add(MagnificationAlwaysOnPreferenceController.PREF_KEY); + niks.add(MagnificationJoystickPreferenceController.PREF_KEY); + } else { + if (!isAlwaysOnSupported(context) + // This preference's title "Keep on while switching apps" does not + // mention magnification so it may confuse users who search a term + // like "Keep on". + // So we hide it if the user has no magnification shortcut enabled. + || getUserShortcutTypeFromSettings(context) == DEFAULT) { + niks.add(MagnificationAlwaysOnPreferenceController.PREF_KEY); + } + if (!isOneFingerPanningSupported()) { + niks.add(MagnificationOneFingerPanningPreferenceController.PREF_KEY); + } + if (!isJoystickSupported()) { + niks.add(MagnificationJoystickPreferenceController.PREF_KEY); + } + } + return niks; + } + // LINT.ThenChange(:preference_list) + + private SearchIndexableRaw createPreferenceSearchData( + Context context, Preference pref) { + final SearchIndexableRaw raw = new SearchIndexableRaw(context); + raw.key = pref.getKey(); + raw.title = pref.getTitle().toString(); + return raw; + } + + private SearchIndexableRaw createShortcutPreferenceSearchData(Context context) { + final SearchIndexableRaw raw = new SearchIndexableRaw(context); + raw.key = KEY_MAGNIFICATION_SHORTCUT_PREFERENCE; + raw.title = context.getString( + R.string.accessibility_screen_magnification_shortcut_title); + return raw; + } + }; } diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java index 60a8a1329f7..6fd6f18bc24 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java @@ -16,7 +16,6 @@ package com.android.settings.connecteddevice.audiosharing; -import android.app.settings.SettingsEnums; import android.content.Context; import android.util.Log; @@ -30,6 +29,7 @@ import com.android.settings.connecteddevice.DevicePreferenceCallback; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.utils.ThreadUtils; public class AudioSharingBluetoothDeviceUpdater extends BluetoothDeviceUpdater implements Preference.OnPreferenceClickListener { @@ -73,7 +73,9 @@ public class AudioSharingBluetoothDeviceUpdater extends BluetoothDeviceUpdater @Override public boolean onPreferenceClick(Preference preference) { mMetricsFeatureProvider.logClickedPreference(preference, mMetricsCategory); - mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_DEVICE_CLICK); + var unused = + ThreadUtils.postOnBackgroundThread( + () -> mDevicePreferenceCallback.onDeviceClick(preference)); return true; } diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java index 8b4c7f267bb..db2c7b21b1b 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java @@ -16,6 +16,7 @@ package com.android.settings.connecteddevice.audiosharing; +import static com.android.settingslib.Utils.isAudioModeOngoingCall; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_BLUETOOTH_DEVICE; import android.app.settings.SettingsEnums; @@ -39,7 +40,9 @@ import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; +import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.bluetooth.BluetoothDevicePreference; import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.bluetooth.Utils; import com.android.settings.connecteddevice.DevicePreferenceCallback; @@ -91,6 +94,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro @Nullable private DashboardFragment mFragment; @Nullable private AudioSharingDialogHandler mDialogHandler; private AtomicBoolean mIntentHandled = new AtomicBoolean(false); + private AtomicBoolean mIsAudioModeOngoingCall = new AtomicBoolean(false); @VisibleForTesting BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = @@ -201,51 +205,57 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro @Override public void onStart(@NonNull LifecycleOwner owner) { - if (!isAvailable()) { - Log.d(TAG, "Skip onStart(), feature is not supported."); - return; - } - if (!AudioSharingUtils.isAudioSharingProfileReady(mProfileManager) - && mProfileManager != null) { - Log.d(TAG, "Register profile service listener"); - mProfileManager.addServiceListener(this); - } - if (mEventManager == null - || mAssistant == null - || mDialogHandler == null - || mBluetoothDeviceUpdater == null) { - Log.d(TAG, "Skip onStart(), profile is not ready."); - return; - } - Log.d(TAG, "onStart() Register callbacks."); - mEventManager.registerCallback(this); - mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); - mDialogHandler.registerCallbacks(mExecutor); - mBluetoothDeviceUpdater.registerCallback(); - mBluetoothDeviceUpdater.refreshPreference(); + var unused = ThreadUtils.postOnBackgroundThread(() -> { + if (!isAvailable()) { + Log.d(TAG, "Skip onStart(), feature is not supported."); + return; + } + if (!AudioSharingUtils.isAudioSharingProfileReady(mProfileManager) + && mProfileManager != null) { + Log.d(TAG, "Register profile service listener"); + mProfileManager.addServiceListener(this); + } + if (mEventManager == null + || mAssistant == null + || mDialogHandler == null + || mBluetoothDeviceUpdater == null) { + Log.d(TAG, "Skip onStart(), profile is not ready."); + return; + } + Log.d(TAG, "onStart() Register callbacks."); + mEventManager.registerCallback(this); + mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); + mDialogHandler.registerCallbacks(mExecutor); + mBluetoothDeviceUpdater.registerCallback(); + mBluetoothDeviceUpdater.refreshPreference(); + mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext)); + updateTitle(); + }); } @Override public void onStop(@NonNull LifecycleOwner owner) { - if (!isAvailable()) { - Log.d(TAG, "Skip onStop(), feature is not supported."); - return; - } - if (mProfileManager != null) { - mProfileManager.removeServiceListener(this); - } - if (mEventManager == null - || mAssistant == null - || mDialogHandler == null - || mBluetoothDeviceUpdater == null) { - Log.d(TAG, "Skip onStop(), profile is not ready."); - return; - } - Log.d(TAG, "onStop() Unregister callbacks."); - mEventManager.unregisterCallback(this); - mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback); - mDialogHandler.unregisterCallbacks(); - mBluetoothDeviceUpdater.unregisterCallback(); + var unused = ThreadUtils.postOnBackgroundThread(() -> { + if (!isAvailable()) { + Log.d(TAG, "Skip onStop(), feature is not supported."); + return; + } + if (mProfileManager != null) { + mProfileManager.removeServiceListener(this); + } + if (mEventManager == null + || mAssistant == null + || mDialogHandler == null + || mBluetoothDeviceUpdater == null) { + Log.d(TAG, "Skip onStop(), profile is not ready."); + return; + } + Log.d(TAG, "onStop() Unregister callbacks."); + mEventManager.unregisterCallback(this); + mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback); + mDialogHandler.unregisterCallbacks(); + mBluetoothDeviceUpdater.unregisterCallback(); + }); } @Override @@ -367,6 +377,25 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro handleOnProfileStateChanged(cachedDevice, bluetoothProfile); } + @Override + public void onAudioModeChanged() { + mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext)); + updateTitle(); + } + + @Override + public void onDeviceClick(@NonNull Preference preference) { + boolean isCallMode = mIsAudioModeOngoingCall.get(); + if (isCallMode) { + Log.d(TAG, "onDeviceClick, set active in call mode"); + CachedBluetoothDevice cachedDevice = + ((BluetoothDevicePreference) preference).getBluetoothDevice(); + cachedDevice.setActive(); + } + mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_DEVICE_CLICK, + isCallMode); + } + /** * Initialize the controller. * @@ -499,4 +528,22 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro mDialogHandler.handleDeviceConnected(cachedDevice, /* userTriggered= */ true); } } + + private void updateTitle() { + if (mPreferenceGroup == null) return; + int titleResId; + if (mIsAudioModeOngoingCall.get()) { + // in phone call + titleResId = R.string.connected_device_call_device_title; + } else { + // without phone call + titleResId = R.string.audio_sharing_device_group_title; + } + AudioSharingUtils.postOnMainThread(mContext, + () -> { + if (mPreferenceGroup != null) { + mPreferenceGroup.setTitle(titleResId); + } + }); + } } diff --git a/src/com/android/settings/development/DesktopModePreferenceController.java b/src/com/android/settings/development/DesktopModePreferenceController.java index f43e17cca86..492686ead65 100644 --- a/src/com/android/settings/development/DesktopModePreferenceController.java +++ b/src/com/android/settings/development/DesktopModePreferenceController.java @@ -17,14 +17,14 @@ package com.android.settings.development; import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES; -import static android.window.flags.DesktopModeFlags.ToggleOverride.fromSetting; -import static android.window.flags.DesktopModeFlags.ToggleOverride.OVERRIDE_OFF; -import static android.window.flags.DesktopModeFlags.ToggleOverride.OVERRIDE_ON; -import static android.window.flags.DesktopModeFlags.ToggleOverride.OVERRIDE_UNSET; +import static android.window.DesktopModeFlags.ToggleOverride.fromSetting; +import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_OFF; +import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_ON; +import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_UNSET; import android.content.Context; import android.provider.Settings; -import android.window.flags.DesktopModeFlags.ToggleOverride; +import android.window.DesktopModeFlags.ToggleOverride; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java index b5d50994ed7..fb5a9f36dbd 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java @@ -169,6 +169,7 @@ public class BatteryDiffData { } if (packageName != null && hideBackgroundUsageTimeSet.contains(packageName)) { entry.mBackgroundUsageTimeInMs = 0; + entry.mForegroundServiceUsageTimeInMs = 0; } } } diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java index 559b2e40fb0..1652f00d1e2 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java @@ -21,7 +21,11 @@ import android.hardware.input.InputSettings; import android.net.Uri; import android.provider.Settings; import android.text.TextUtils; +import android.view.View; +import android.widget.RadioButton; import android.widget.RadioGroup; +import android.widget.SeekBar; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -33,9 +37,13 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settingslib.PrimarySwitchPreference; +import java.util.concurrent.TimeUnit; + public class KeyboardAccessibilityBounceKeysController extends InputSettingPreferenceController implements LifecycleObserver { + private static final int CUSTOM_PROGRESS_INTERVAL = 100; + private static final long MILLISECOND_IN_SECONDS = TimeUnit.SECONDS.toMillis(1); public static final int BOUNCE_KEYS_THRESHOLD = 500; private AlertDialog mAlertDialog; @@ -62,7 +70,7 @@ public class KeyboardAccessibilityBounceKeysController extends } @Override - public boolean handlePreferenceTreeClick(Preference preference) { + public boolean handlePreferenceTreeClick(@NonNull Preference preference) { if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { return false; } @@ -105,23 +113,87 @@ public class KeyboardAccessibilityBounceKeysController extends (dialog, which) -> { RadioGroup radioGroup = mAlertDialog.findViewById(R.id.bounce_key_value_group); - int checkedRadioButtonId = radioGroup.getCheckedRadioButtonId(); - int threshold = checkedRadioButtonId == R.id.bounce_key_value_600 ? 600 - : checkedRadioButtonId == R.id.bounce_key_value_400 ? 400 - : checkedRadioButtonId == R.id.bounce_key_value_200 - ? 200 : 0; + SeekBar seekbar = mAlertDialog.findViewById( + R.id.bounce_key_value_custom_slider); + RadioButton customRadioButton = mAlertDialog.findViewById( + R.id.bounce_key_value_custom); + int threshold; + if (customRadioButton.isChecked()) { + threshold = seekbar.getProgress() * CUSTOM_PROGRESS_INTERVAL; + } else { + int checkedRadioButtonId = radioGroup.getCheckedRadioButtonId(); + threshold = checkedRadioButtonId == R.id.bounce_key_value_600 ? 600 + : checkedRadioButtonId == R.id.bounce_key_value_400 ? 400 + : checkedRadioButtonId == R.id.bounce_key_value_200 + ? 200 : 0; + } InputSettings.setAccessibilityBounceKeysThreshold(context, threshold); }) .setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss()) .create(); mAlertDialog.setOnShowListener(dialog -> { - RadioGroup radioGroup = mAlertDialog.findViewById(R.id.bounce_key_value_group); - int bounceKeysThreshold = InputSettings.getAccessibilityBounceKeysThreshold(context); - switch (bounceKeysThreshold) { - case 600 -> radioGroup.check(R.id.bounce_key_value_600); - case 400 -> radioGroup.check(R.id.bounce_key_value_400); - default -> radioGroup.check(R.id.bounce_key_value_200); - } + RadioGroup cannedValueRadioGroup = mAlertDialog.findViewById( + R.id.bounce_key_value_group); + RadioButton customRadioButton = mAlertDialog.findViewById(R.id.bounce_key_value_custom); + TextView customValueTextView = mAlertDialog.findViewById( + R.id.bounce_key_value_custom_value); + SeekBar customProgressBar = mAlertDialog.findViewById( + R.id.bounce_key_value_custom_slider); + customProgressBar.incrementProgressBy(CUSTOM_PROGRESS_INTERVAL); + customProgressBar.setProgress(1); + View customValueView = mAlertDialog.findViewById(R.id.custom_value_option); + customValueView.setOnClickListener(l -> customRadioButton.performClick()); + customRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked) { + cannedValueRadioGroup.clearCheck(); + } + customValueTextView.setVisibility(isChecked ? View.VISIBLE : View.GONE); + customValueTextView.setText( + progressToThresholdInSecond(customProgressBar.getProgress())); + customProgressBar.setVisibility(isChecked ? View.VISIBLE : View.GONE); + buttonView.setChecked(isChecked); + }); + cannedValueRadioGroup.setOnCheckedChangeListener( + (group, checkedId) -> customRadioButton.setChecked(false)); + customProgressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + customValueTextView.setText(progressToThresholdInSecond(progress)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + initStateBasedOnThreshold(cannedValueRadioGroup, customRadioButton, customValueTextView, + customProgressBar); }); } + + private static String progressToThresholdInSecond(int progress) { + return String.valueOf((double) progress * CUSTOM_PROGRESS_INTERVAL + / MILLISECOND_IN_SECONDS); + } + + private void initStateBasedOnThreshold(RadioGroup cannedValueRadioGroup, + RadioButton customRadioButton, TextView customValueTextView, + SeekBar customProgressBar) { + int bounceKeysThreshold = InputSettings.getAccessibilityBounceKeysThreshold(mContext); + switch (bounceKeysThreshold) { + case 600 -> cannedValueRadioGroup.check(R.id.bounce_key_value_600); + case 400 -> cannedValueRadioGroup.check(R.id.bounce_key_value_400); + case 0, 200 -> cannedValueRadioGroup.check(R.id.bounce_key_value_200); + default -> { + customValueTextView.setText( + String.valueOf( + (double) bounceKeysThreshold / MILLISECOND_IN_SECONDS)); + customProgressBar.setProgress(bounceKeysThreshold / CUSTOM_PROGRESS_INTERVAL); + customRadioButton.setChecked(true); + } + } + } } diff --git a/src/com/android/settings/inputmethod/KeyboardRepeatKeysController.java b/src/com/android/settings/inputmethod/KeyboardRepeatKeysController.java new file mode 100644 index 00000000000..a232098f696 --- /dev/null +++ b/src/com/android/settings/inputmethod/KeyboardRepeatKeysController.java @@ -0,0 +1,76 @@ +/* + * Copyright 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.inputmethod; + +import android.content.Context; +import android.hardware.input.InputSettings; +import android.net.Uri; +import android.provider.Settings; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.LifecycleObserver; +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreferenceCompat; + +public class KeyboardRepeatKeysController extends + InputSettingPreferenceController implements + LifecycleObserver { + + @Nullable + private SwitchPreferenceCompat mSwitchPreferenceCompat; + + public KeyboardRepeatKeysController(@NonNull Context context, + @NonNull String key) { + super(context, key); + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mSwitchPreferenceCompat = screen.findPreference(getPreferenceKey()); + } + + @Override + public int getAvailabilityStatus() { + return InputSettings.isRepeatKeysFeatureFlagEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } + + @Override + public boolean isChecked() { + return InputSettings.isRepeatKeysEnabled(mContext); + } + + @Override + public boolean setChecked(boolean isChecked) { + InputSettings.setRepeatKeysEnabled(mContext, isChecked); + return true; + } + + @Override + protected void onInputSettingUpdated() { + if (mSwitchPreferenceCompat != null) { + mSwitchPreferenceCompat.setChecked(InputSettings.isRepeatKeysEnabled(mContext)); + } + } + + @Override + protected Uri getSettingUri() { + return Settings.Secure.getUriFor( + Settings.Secure.KEY_REPEAT_ENABLED); + } +} diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java index a000f9ede5d..48100a3081d 100644 --- a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java +++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java @@ -48,8 +48,8 @@ import androidx.preference.TwoStatePreference; import com.android.internal.util.Preconditions; import com.android.settings.R; import com.android.settings.Settings; -import com.android.settings.SettingsPreferenceFragment; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.dashboard.DashboardFragment; import com.android.settings.keyboard.Flags; import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; @@ -65,7 +65,7 @@ import java.util.Objects; // TODO(b/327638540): Update implementation of preference here and reuse key preferences and // controllers between here and A11y Setting page. @SearchIndexable -public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment +public final class PhysicalKeyboardFragment extends DashboardFragment implements InputManager.InputDeviceListener, KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener { @@ -79,6 +79,7 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment private static final String KEYBOARD_SHORTCUTS_HELPER = "keyboard_shortcuts_helper"; private static final String MODIFIER_KEYS_SETTINGS = "modifier_keys_settings"; private static final String EXTRA_AUTO_SELECTION = "auto_selection"; + private static final String TAG = "KeyboardAndTouchA11yFragment"; private static final Uri sVirtualKeyboardSettingsUri = Secure.getUriFor( Secure.SHOW_IME_WITH_HARD_KEYBOARD); private static final Uri sAccessibilityBounceKeysUri = Secure.getUriFor( @@ -118,6 +119,16 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment static final String EXTRA_BT_ADDRESS = "extra_bt_address"; private String mBluetoothAddress; + @Override + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.physical_keyboard_settings; + } + @Override public void onSaveInstanceState(Bundle outState) { outState.putParcelable(EXTRA_AUTO_SELECTION, mAutoInputDeviceIdentifier); @@ -126,6 +137,7 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment @Override public void onCreatePreferences(Bundle bundle, String s) { + super.onCreatePreferences(bundle, s); Activity activity = Preconditions.checkNotNull(getActivity()); addPreferencesFromResource(R.xml.physical_keyboard_settings); mIm = Preconditions.checkNotNull(activity.getSystemService(InputManager.class)); diff --git a/src/com/android/settings/network/CellularSecurityPreferenceController.java b/src/com/android/settings/network/CellularSecurityPreferenceController.java index f43805ef83a..0b0c2a7e948 100644 --- a/src/com/android/settings/network/CellularSecurityPreferenceController.java +++ b/src/com/android/settings/network/CellularSecurityPreferenceController.java @@ -88,10 +88,10 @@ public class CellularSecurityPreferenceController extends BasePreferenceControll } catch (UnsupportedOperationException e) { Log.i(LOG_TAG, "Null cipher enablement is unsupported, hiding divider: " + e.getMessage()); - } catch (Exception e) { + } catch (IllegalStateException e) { Log.e(LOG_TAG, "Failed isNullCipherAndIntegrityEnabled. Setting availability to " - + "CONDITIONALLY_UNAVAILABLE. Exception: " + + "UNSUPPORTED_ON_DEVICE. Exception: " + e.getMessage()); } @@ -104,6 +104,12 @@ public class CellularSecurityPreferenceController extends BasePreferenceControll } catch (UnsupportedOperationException e) { Log.i(LOG_TAG, "Cellular security notifications are unsupported, hiding divider: " + e.getMessage()); + } catch (IllegalStateException e) { + Log.e(LOG_TAG, + "Failed isNullCipherNotificationsEnabled, " + + "isCellularIdentifierDisclosureNotificationsEnabled. " + + "Setting availability to UNSUPPORTED_ON_DEVICE. Exception: " + + e.getMessage()); } if (isNullCipherDisablementAvailable || areCellSecNotificationsAvailable) { diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java index a1f75bc63d2..28df8ed5989 100644 --- a/src/com/android/settings/nfc/PaymentSettings.java +++ b/src/com/android/settings/nfc/PaymentSettings.java @@ -30,6 +30,7 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; +import com.android.internal.hidden_from_bootclasspath.android.permission.flags.Flags; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; @@ -120,6 +121,9 @@ public class PaymentSettings extends DashboardFragment { @Override protected boolean isPageSearchEnabled(Context context) { + if (Flags.walletRoleEnabled()) { + return false; + } final UserManager userManager = context.getSystemService(UserManager.class); final UserInfo myUserInfo = userManager.getUserInfo(UserHandle.myUserId()); if (myUserInfo.isGuest()) { diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java index 31882408fd7..0881b29a3b3 100644 --- a/src/com/android/settings/users/UserSettings.java +++ b/src/com/android/settings/users/UserSettings.java @@ -1860,6 +1860,10 @@ public class UserSettings extends SettingsPreferenceFragment boolean suppressAllPage) { final List niks = super.getNonIndexableKeysFromXml(context, xmlResId, suppressAllPage); + if (TextUtils.isEmpty(context.getString( + com.android.internal.R.string.config_supervisedUserCreationPackage))) { + niks.add(KEY_ADD_SUPERVISED_USER); + } AddUserWhenLockedPreferenceController controller = new AddUserWhenLockedPreferenceController( context, KEY_ADD_USER_WHEN_LOCKED); diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragmentTest.java index 1a82a25b2f7..e9711864909 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragmentTest.java @@ -18,7 +18,8 @@ package com.android.settings.accessibility; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; -import static com.android.settings.accessibility.ToggleColorInversionPreferenceFragment.KEY_USE_SERVICE_PREFERENCE; +import static com.android.settings.accessibility.ToggleColorInversionPreferenceFragment.KEY_SHORTCUT_PREFERENCE; +import static com.android.settings.accessibility.ToggleColorInversionPreferenceFragment.KEY_SWITCH_PREFERENCE; import static com.google.common.truth.Truth.assertThat; @@ -32,12 +33,12 @@ import android.content.ComponentName; import android.content.Context; import android.os.Bundle; import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.accessibility.Flags; import android.widget.PopupWindow; import androidx.fragment.app.FragmentActivity; @@ -50,6 +51,7 @@ import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltip import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowFragment; import com.android.settings.widget.SettingsMainSwitchPreference; +import com.android.settingslib.search.SearchIndexableRaw; import org.junit.Before; import org.junit.Rule; @@ -63,6 +65,7 @@ import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowApplication; +import java.util.ArrayList; import java.util.List; /** Tests for {@link ToggleColorInversionPreferenceFragment} */ @@ -93,10 +96,10 @@ public class ToggleColorInversionPreferenceFragmentTest { when(mActivity.getContentResolver()).thenReturn(mContext.getContentResolver()); mScreen = spy(new PreferenceScreen(mContext, /* attrs= */ null)); - when(mScreen.findPreference(KEY_USE_SERVICE_PREFERENCE)) + when(mScreen.findPreference(mFragment.getUseServicePreferenceKey())) .thenReturn(mFragment.mToggleServiceSwitchPreference); doReturn(mScreen).when(mFragment).getPreferenceScreen(); - mSwitchPreference = mScreen.findPreference(KEY_USE_SERVICE_PREFERENCE); + mSwitchPreference = mScreen.findPreference(mFragment.getUseServicePreferenceKey()); } @Test @@ -137,7 +140,7 @@ public class ToggleColorInversionPreferenceFragmentTest { } @Test - @DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) public void onPreferenceToggled_colorCorrectDisabled_shouldReturnTrueAndShowTooltipView() { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, OFF); @@ -199,6 +202,41 @@ public class ToggleColorInversionPreferenceFragmentTest { assertThat(keys).containsAtLeastElementsIn(niks); } + @Test + @DisableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getRawDataToIndex_flagOff_returnShortcutIndexablePreferences() { + List rawData = ToggleColorInversionPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(mContext, /* enabled= */ true); + + assertThat(rawData).hasSize(1); + assertThat(rawData.get(0).key).isEqualTo(KEY_SHORTCUT_PREFERENCE); + assertThat(rawData.get(0).title).isEqualTo(mContext.getString( + R.string.accessibility_display_inversion_shortcut_title)); + + } + + @Test + @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getRawDataToIndex_flagOn_returnAllIndexablePreferences() { + String[] expectedKeys = {KEY_SHORTCUT_PREFERENCE, KEY_SWITCH_PREFERENCE}; + String[] expectedTitles = { + mContext.getString(R.string.accessibility_display_inversion_shortcut_title), + mContext.getString(R.string.accessibility_display_inversion_switch_title)}; + List keysResultList = new ArrayList<>(); + List titlesResultList = new ArrayList<>(); + List rawData = ToggleColorInversionPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(mContext, /* enabled= */ true); + + for (SearchIndexableRaw rawDataItem : rawData) { + keysResultList.add(rawDataItem.key); + titlesResultList.add(rawDataItem.title); + } + + assertThat(rawData).hasSize(2); + assertThat(keysResultList).containsExactly(expectedKeys); + assertThat(titlesResultList).containsExactly(expectedTitles); + } + private static PopupWindow getLatestPopupWindow() { final ShadowApplication shadowApplication = Shadow.extract(ApplicationProvider.getApplicationContext()); @@ -220,7 +258,7 @@ public class ToggleColorInversionPreferenceFragmentTest { mComponentName = PLACEHOLDER_COMPONENT_NAME; final SettingsMainSwitchPreference switchPreference = new SettingsMainSwitchPreference(context); - switchPreference.setKey(KEY_USE_SERVICE_PREFERENCE); + switchPreference.setKey(getUseServicePreferenceKey()); mToggleServiceSwitchPreference = switchPreference; setArguments(new Bundle()); } diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragmentTest.java index a5bfec2f0db..a33fefbb404 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragmentTest.java @@ -18,7 +18,8 @@ package com.android.settings.accessibility; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; -import static com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.KEY_USE_SERVICE_PREFERENCE; +import static com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.KEY_SHORTCUT_PREFERENCE; +import static com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.KEY_SWITCH_PREFERENCE; import static com.google.common.truth.Truth.assertThat; @@ -27,9 +28,9 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; -import android.view.accessibility.Flags; import android.widget.PopupWindow; import androidx.fragment.app.Fragment; @@ -39,6 +40,7 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.widget.SettingsMainSwitchPreference; +import com.android.settingslib.search.SearchIndexableRaw; import org.junit.Before; import org.junit.Rule; @@ -49,6 +51,7 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowApplication; +import java.util.ArrayList; import java.util.List; /** Tests for {@link ToggleDaltonizerPreferenceFragment} */ @@ -104,7 +107,7 @@ public class ToggleDaltonizerPreferenceFragmentTest { } @Test - @DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) public void onPreferenceToggled_colorCorrectDisabled_shouldReturnTrueAndShowTooltipView() { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF); @@ -169,6 +172,37 @@ public class ToggleDaltonizerPreferenceFragmentTest { assertThat(keys).containsAtLeastElementsIn(niks); } + @Test + @DisableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getRawDataToIndex_flagOff_returnEmptyData() { + List rawData = ToggleDaltonizerPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(mContext, /* enabled= */ true); + + assertThat(rawData).isEmpty(); + } + + @Test + @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getRawDataToIndex_flagOn_returnAllIndexablePreferences() { + String[] expectedKeys = {KEY_SHORTCUT_PREFERENCE, KEY_SWITCH_PREFERENCE}; + String[] expectedTitles = { + mContext.getString(R.string.accessibility_daltonizer_shortcut_title), + mContext.getString(R.string.accessibility_daltonizer_primary_switch_title)}; + List keysResultList = new ArrayList<>(); + List titlesResultList = new ArrayList<>(); + List rawData = ToggleDaltonizerPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(mContext, /* enabled= */ true); + + for (SearchIndexableRaw rawDataItem : rawData) { + keysResultList.add(rawDataItem.key); + titlesResultList.add(rawDataItem.title); + } + + assertThat(rawData).hasSize(2); + assertThat(keysResultList).containsExactly(expectedKeys); + assertThat(titlesResultList).containsExactly(expectedTitles); + } + private static PopupWindow getLatestPopupWindow() { final ShadowApplication shadowApplication = Shadow.extract(ApplicationProvider.getApplicationContext()); @@ -189,6 +223,6 @@ public class ToggleDaltonizerPreferenceFragmentTest { private SettingsMainSwitchPreference getMainFeatureToggle( ToggleDaltonizerPreferenceFragment fragment) { - return fragment.findPreference(KEY_USE_SERVICE_PREFERENCE); + return fragment.findPreference(fragment.getUseServicePreferenceKey()); } } diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java index 71855e023d0..844fabe2647 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java @@ -235,8 +235,7 @@ public class ToggleFeaturePreferenceFragmentTest { @Test @Config(shadows = ShadowFragment.class) public void onPreferenceToggledOnDisabledService_notShowTooltipView() { - mFragment.onPreferenceToggled( - ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ false); + mFragment.onPreferenceToggled(mFragment.getUseServicePreferenceKey(), /* enabled= */ false); assertThat(getLatestPopupWindow()).isNull(); } @@ -245,8 +244,7 @@ public class ToggleFeaturePreferenceFragmentTest { @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) @Config(shadows = ShadowFragment.class) public void onPreferenceToggledOnEnabledService_showTooltipView() { - mFragment.onPreferenceToggled( - ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ true); + mFragment.onPreferenceToggled(mFragment.getUseServicePreferenceKey(), /* enabled= */ true); assertThat(getLatestPopupWindow().isShowing()).isTrue(); } @@ -258,8 +256,7 @@ public class ToggleFeaturePreferenceFragmentTest { suwIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true); when(mActivity.getIntent()).thenReturn(suwIntent); - mFragment.onPreferenceToggled( - ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ true); + mFragment.onPreferenceToggled(mFragment.getUseServicePreferenceKey(), /* enabled= */ true); assertThat(getLatestPopupWindow()).isNull(); } @@ -268,12 +265,10 @@ public class ToggleFeaturePreferenceFragmentTest { @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) @Config(shadows = ShadowFragment.class) public void onPreferenceToggledOnEnabledService_tooltipViewShown_notShowTooltipView() { - mFragment.onPreferenceToggled( - ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ true); + mFragment.onPreferenceToggled(mFragment.getUseServicePreferenceKey(), /* enabled= */ true); getLatestPopupWindow().dismiss(); - mFragment.onPreferenceToggled( - ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ true); + mFragment.onPreferenceToggled(mFragment.getUseServicePreferenceKey(), /* enabled= */ true); assertThat(getLatestPopupWindow().isShowing()).isFalse(); } diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java index 038672fc198..87632ae8a64 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java @@ -24,6 +24,7 @@ import static com.android.internal.accessibility.common.ShortcutConstants.UserSh import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode; +import static com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment.KEY_MAGNIFICATION_SHORTCUT_PREFERENCE; import static com.google.common.truth.Truth.assertThat; @@ -70,6 +71,7 @@ import com.android.settings.testutils.shadow.ShadowDeviceConfig; import com.android.settings.testutils.shadow.ShadowStorageManager; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.search.SearchIndexableRaw; import com.google.common.truth.Correspondence; @@ -539,7 +541,7 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { @Test public void optInAllValuesToSettings_software_sizeValueIsNotNull_sizeValueIsNotChanged() { - for (int size : new int[] {FloatingMenuSizePreferenceController.Size.LARGE, + for (int size : new int[]{FloatingMenuSizePreferenceController.Size.LARGE, FloatingMenuSizePreferenceController.Size.SMALL}) { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size); @@ -557,7 +559,7 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { @Test public void optInAllValuesToSettings_hardware_sizeValueIsNotChanged() { - for (int size : new int[] {FloatingMenuSizePreferenceController.Size.UNKNOWN, + for (int size : new int[]{FloatingMenuSizePreferenceController.Size.UNKNOWN, FloatingMenuSizePreferenceController.Size.LARGE, FloatingMenuSizePreferenceController.Size.SMALL}) { Settings.Secure.putInt(mContext.getContentResolver(), @@ -575,7 +577,7 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { @Test public void optInAllValuesToSettings_tripletap_sizeValueIsNotChanged() { - for (int size : new int[] {FloatingMenuSizePreferenceController.Size.UNKNOWN, + for (int size : new int[]{FloatingMenuSizePreferenceController.Size.UNKNOWN, FloatingMenuSizePreferenceController.Size.LARGE, FloatingMenuSizePreferenceController.Size.SMALL}) { Settings.Secure.putInt(mContext.getContentResolver(), @@ -1025,6 +1027,107 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { .isEqualTo(collectionInfo.getImportantForAccessibilityItemCount() + 1); } + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getRawDataToIndex_returnsAllPreferenceKeys() { + List expectedSearchKeys = List.of( + KEY_MAGNIFICATION_SHORTCUT_PREFERENCE, + MagnificationModePreferenceController.PREF_KEY, + MagnificationFollowTypingPreferenceController.PREF_KEY, + MagnificationOneFingerPanningPreferenceController.PREF_KEY, + MagnificationAlwaysOnPreferenceController.PREF_KEY, + MagnificationJoystickPreferenceController.PREF_KEY); + + final List rawData = ToggleScreenMagnificationPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(mContext, true); + final List actualSearchKeys = rawData.stream().map(raw -> raw.key).toList(); + + assertThat(actualSearchKeys).containsExactlyElementsIn(expectedSearchKeys); + } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void + getNonIndexableKeys_windowMagnificationNotSupported_onlyShortcutPreferenceSearchable() { + setWindowMagnificationSupported(false, false); + + final List niks = ToggleScreenMagnificationPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + final List rawData = ToggleScreenMagnificationPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(mContext, true); + // Expect all search data, except the shortcut preference, to be in NIKs. + final List expectedNiks = rawData.stream().map(raw -> raw.key) + .filter(key -> !key.equals(KEY_MAGNIFICATION_SHORTCUT_PREFERENCE)).toList(); + + // In NonIndexableKeys == not searchable + assertThat(niks).containsExactlyElementsIn(expectedNiks); + } + + @Test + @EnableFlags({ + com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH, + Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE}) + public void getNonIndexableKeys_hasShortcutAndAllFeaturesEnabled_allItemsSearchable() { + setMagnificationTripleTapEnabled(true); + setAlwaysOnSupported(true); + setJoystickSupported(true); + + final List niks = ToggleScreenMagnificationPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + + // Empty NonIndexableKeys == all indexed items are searchable + assertThat(niks).isEmpty(); + } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getNonIndexableKeys_noShortcut_alwaysOnSupported_notSearchable() { + setMagnificationTripleTapEnabled(false); + setAlwaysOnSupported(true); + + final List niks = ToggleScreenMagnificationPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + + // In NonIndexableKeys == not searchable + assertThat(niks).contains(MagnificationAlwaysOnPreferenceController.PREF_KEY); + } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getNonIndexableKeys_hasShortcut_alwaysOnNotSupported_notSearchable() { + setMagnificationTripleTapEnabled(true); + setAlwaysOnSupported(false); + + final List niks = ToggleScreenMagnificationPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + + // In NonIndexableKeys == not searchable + assertThat(niks).contains(MagnificationAlwaysOnPreferenceController.PREF_KEY); + } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + @DisableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) + public void getNonIndexableKeys_oneFingerPanningNotSupported_notSearchable() { + final List niks = ToggleScreenMagnificationPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + + // In NonIndexableKeys == not searchable + assertThat(niks).contains(MagnificationOneFingerPanningPreferenceController.PREF_KEY); + } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getNonIndexableKeys_joystickNotSupported_notSearchable() { + setJoystickSupported(false); + + final List niks = ToggleScreenMagnificationPreferenceFragment + .SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + + // In NonIndexableKeys == not searchable + assertThat(niks).contains(MagnificationJoystickPreferenceController.PREF_KEY); + } + private void putStringIntoSettings(String key, String componentName) { Settings.Secure.putString(mContext.getContentResolver(), key, componentName); } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsCompanionAppsControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsCompanionAppsControllerTest.java index faea3d8ecb1..d9054a8bf77 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsCompanionAppsControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsCompanionAppsControllerTest.java @@ -115,7 +115,8 @@ public class BluetoothDetailsCompanionAppsControllerTest extends /* pending */ false, /* timeApprovedMs */ System.currentTimeMillis(), /* lastTimeConnected */ Long.MAX_VALUE, - /* systemDataSyncFlags */ -1); + /* systemDataSyncFlags */ -1, + /* deviceIcon */ null); mAssociations.add(association); showScreen(mController); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdaterTest.java index 879c6a4d0ab..11e31b6fa03 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdaterTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdaterTest.java @@ -28,7 +28,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; -import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastReceiveState; @@ -271,8 +270,9 @@ public class AudioSharingBluetoothDeviceUpdaterTest { public void onPreferenceClick_logClick() { Preference preference = new Preference(mContext); mDeviceUpdater.onPreferenceClick(preference); - verify(mFeatureFactory.metricsFeatureProvider) - .action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_DEVICE_CLICK); + shadowOf(Looper.getMainLooper()).idle(); + + verify(mDevicePreferenceCallback).onDeviceClick(preference); } private void setupPreferenceMapWithDevice() { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java index 03f13037d62..61bc8aaa055 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java @@ -25,6 +25,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -44,10 +45,14 @@ import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.media.AudioManager; import android.os.Bundle; import android.os.Looper; import android.platform.test.flag.junit.SetFlagsRule; +import android.util.Pair; +import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.LifecycleOwner; import androidx.preference.Preference; @@ -56,10 +61,13 @@ import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.bluetooth.BluetoothDevicePreference; import com.android.settings.bluetooth.Utils; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.ShadowAudioManager; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settings.testutils.shadow.ShadowFragment; @@ -99,14 +107,16 @@ import java.util.concurrent.Executor; @RunWith(RobolectricTestRunner.class) @Config( shadows = { - ShadowBluetoothAdapter.class, - ShadowBluetoothUtils.class, - ShadowFragment.class, + ShadowBluetoothAdapter.class, + ShadowBluetoothUtils.class, + ShadowFragment.class, + ShadowAudioManager.class, }) public class AudioSharingDevicePreferenceControllerTest { private static final String KEY = "audio_sharing_device_list"; private static final String KEY_AUDIO_SHARING_SETTINGS = "connected_device_audio_sharing_settings"; + private static final String TEST_DEVICE_NAME = "test"; @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @@ -140,6 +150,7 @@ public class AudioSharingDevicePreferenceControllerTest { private PreferenceCategory mPreferenceGroup; private Preference mAudioSharingPreference; private FakeFeatureFactory mFeatureFactory; + private AudioManager mAudioManager; @Before public void setUp() { @@ -153,6 +164,7 @@ public class AudioSharingDevicePreferenceControllerTest { mLifecycleOwner = () -> mLifecycle; mLifecycle = new Lifecycle(mLifecycleOwner); mFeatureFactory = FakeFeatureFactory.setupForTest(); + mAudioManager = mContext.getSystemService(AudioManager.class); ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager; mLocalBtManager = Utils.getLocalBtManager(mContext); when(mLocalBtManager.getEventManager()).thenReturn(mEventManager); @@ -571,4 +583,51 @@ public class AudioSharingDevicePreferenceControllerTest { verify(mBluetoothDeviceUpdater, never()).forceUpdate(); verifyNoMoreInteractions(mFeatureFactory.metricsFeatureProvider); } + + @Test + public void testInCallState_showCallStateTitleAndSetActiveOnDeviceClick() { + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + mController.displayPreference(mScreen); + + mAudioManager.setMode(AudioManager.MODE_IN_CALL); + mController.onAudioModeChanged(); + shadowOf(Looper.getMainLooper()).idle(); + + assertThat(mPreferenceGroup.getTitle().toString()) + .isEqualTo(mContext.getString(R.string.connected_device_call_device_title)); + + BluetoothDevicePreference preference = createBluetoothDevicePreference(); + mController.onDeviceClick(preference); + verify(mCachedDevice).setActive(); + } + + @Test + public void testInNormalState_showNormalStateTitleAndDoNothingOnDeviceClick() { + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + mController.displayPreference(mScreen); + + mAudioManager.setMode(AudioManager.MODE_NORMAL); + mController.onAudioModeChanged(); + shadowOf(Looper.getMainLooper()).idle(); + + assertThat(mPreferenceGroup.getTitle().toString()) + .isEqualTo(mContext.getString(R.string.audio_sharing_device_group_title)); + + BluetoothDevicePreference preference = createBluetoothDevicePreference(); + mController.onDeviceClick(preference); + + verify(mCachedDevice, never()).setActive(); + } + + @NonNull + private BluetoothDevicePreference createBluetoothDevicePreference() { + Drawable drawable = mock(Drawable.class); + Pair pairs = new Pair<>(drawable, TEST_DEVICE_NAME); + when(mCachedDevice.getDrawableWithDescription()).thenReturn(pairs); + return new BluetoothDevicePreference( + mContext, + mCachedDevice, + /* showDeviceWithoutNames= */ false, + BluetoothDevicePreference.SortType.TYPE_DEFAULT); + } } diff --git a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java index 7fe937729b6..b9f56215de1 100644 --- a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java @@ -17,9 +17,9 @@ package com.android.settings.development; import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES; -import static android.window.flags.DesktopModeFlags.ToggleOverride.OVERRIDE_ON; -import static android.window.flags.DesktopModeFlags.ToggleOverride.OVERRIDE_OFF; -import static android.window.flags.DesktopModeFlags.ToggleOverride.OVERRIDE_UNSET; +import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_ON; +import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_OFF; +import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_UNSET; import static com.google.common.truth.Truth.assertThat; diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java index ae4c56d035a..1f3067e81ce 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java @@ -903,6 +903,7 @@ public final class DataProcessorTest { ConvertUtils.CONSUMER_TYPE_UID_BATTERY, 0L, 0L, + 0L, false)), batteryHistoryKeys[1], Map.of( @@ -920,6 +921,7 @@ public final class DataProcessorTest { ConvertUtils.CONSUMER_TYPE_UID_BATTERY, 0L, 0L, + 0L, false)), batteryHistoryKeys[2], Map.of( @@ -937,6 +939,7 @@ public final class DataProcessorTest { ConvertUtils.CONSUMER_TYPE_UID_BATTERY, 0L, 0L, + 0L, false))); final BatteryLevelData batteryLevelData = generateBatteryLevelData(batteryHistoryKeys); final Map>>>> @@ -993,6 +996,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); // Adds the index = 0 data. @@ -1010,6 +1014,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 10L, + /* foregroundServiceUsageTimeInMs= */ 15L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1034,6 +1039,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 15L, + /* foregroundServiceUsageTimeInMs= */ 20L, /* backgroundUsageTimeInMs= */ 25L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1054,6 +1060,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 25L, + /* foregroundServiceUsageTimeInMs= */ 30L, /* backgroundUsageTimeInMs= */ 35L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1070,6 +1077,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY, /* foregroundUsageTimeInMs= */ 40L, + /* foregroundServiceUsageTimeInMs= */ 45L, /* backgroundUsageTimeInMs= */ 50L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1086,6 +1094,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 5L, + /* foregroundServiceUsageTimeInMs= */ 5L, /* backgroundUsageTimeInMs= */ 5L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1106,6 +1115,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 30L, + /* foregroundServiceUsageTimeInMs= */ 35L, /* backgroundUsageTimeInMs= */ 40L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1122,6 +1132,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY, /* foregroundUsageTimeInMs= */ 50L, + /* foregroundServiceUsageTimeInMs= */ 55L, /* backgroundUsageTimeInMs= */ 60L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1138,6 +1149,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 5L, + /* foregroundServiceUsageTimeInMs= */ 5L, /* backgroundUsageTimeInMs= */ 5L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1195,6 +1207,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 9, /* cachedUsageConsumePower= */ 8, /* foregroundUsageTimeInMs= */ 30, + /* foregroundServiceUsageTimeInMs= */ 35, /* backgroundUsageTimeInMs= */ 40, /* screenOnTimeInMs= */ 12); assertBatteryDiffEntry( @@ -1208,6 +1221,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 8, /* cachedUsageConsumePower= */ 8, /* foregroundUsageTimeInMs= */ 5, + /* foregroundServiceUsageTimeInMs= */ 5, /* backgroundUsageTimeInMs= */ 5, /* screenOnTimeInMs= */ 0); assertBatteryDiffEntry( @@ -1221,6 +1235,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 5, /* cachedUsageConsumePower= */ 5, /* foregroundUsageTimeInMs= */ 16, + /* foregroundServiceUsageTimeInMs= */ 55, /* backgroundUsageTimeInMs= */ 60, /* screenOnTimeInMs= */ 9); resultDiffData = resultMap.get(0).get(DataProcessor.SELECTED_INDEX_ALL); @@ -1235,6 +1250,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 5, /* cachedUsageConsumePower= */ 5, /* foregroundUsageTimeInMs= */ 15, + /* foregroundServiceUsageTimeInMs= */ 20, /* backgroundUsageTimeInMs= */ 25, /* screenOnTimeInMs= */ 5); resultDiffData = resultMap.get(1).get(DataProcessor.SELECTED_INDEX_ALL); @@ -1249,6 +1265,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 8, /* cachedUsageConsumePower= */ 8, /* foregroundUsageTimeInMs= */ 5, + /* foregroundServiceUsageTimeInMs= */ 5, /* backgroundUsageTimeInMs= */ 5, /* screenOnTimeInMs= */ 0); assertBatteryDiffEntry( @@ -1262,6 +1279,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 4, /* cachedUsageConsumePower= */ 3, /* foregroundUsageTimeInMs= */ 15, + /* foregroundServiceUsageTimeInMs= */ 15, /* backgroundUsageTimeInMs= */ 15, /* screenOnTimeInMs= */ 7); assertBatteryDiffEntry( @@ -1275,6 +1293,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 5, /* cachedUsageConsumePower= */ 5, /* foregroundUsageTimeInMs= */ 16, + /* foregroundServiceUsageTimeInMs= */ 55, /* backgroundUsageTimeInMs= */ 60, /* screenOnTimeInMs= */ 9); } @@ -1308,6 +1327,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 10L, + /* foregroundServiceUsageTimeInMs= */ 15L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1324,6 +1344,7 @@ public final class DataProcessorTest { currentUserId + 1, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 10L, + /* foregroundServiceUsageTimeInMs= */ 15L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1340,6 +1361,7 @@ public final class DataProcessorTest { currentUserId + 2, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 20L, + /* foregroundServiceUsageTimeInMs= */ 25L, /* backgroundUsageTimeInMs= */ 30L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1359,6 +1381,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 20L, + /* foregroundServiceUsageTimeInMs= */ 25L, /* backgroundUsageTimeInMs= */ 30L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1375,6 +1398,7 @@ public final class DataProcessorTest { currentUserId + 1, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 10L, + /* foregroundServiceUsageTimeInMs= */ 15L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1391,6 +1415,7 @@ public final class DataProcessorTest { currentUserId + 2, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 30L, + /* foregroundServiceUsageTimeInMs= */ 30L, /* backgroundUsageTimeInMs= */ 30L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1410,6 +1435,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 20L, + /* foregroundServiceUsageTimeInMs= */ 25L, /* backgroundUsageTimeInMs= */ 30L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1426,6 +1452,7 @@ public final class DataProcessorTest { currentUserId + 1, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 20L, + /* foregroundServiceUsageTimeInMs= */ 20L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1442,6 +1469,7 @@ public final class DataProcessorTest { currentUserId + 2, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 30L, + /* foregroundServiceUsageTimeInMs= */ 30L, /* backgroundUsageTimeInMs= */ 30L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1477,6 +1505,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 5, /* cachedUsageConsumePower= */ 5, /* foregroundUsageTimeInMs= */ 10, + /* foregroundServiceUsageTimeInMs= */ 10, /* backgroundUsageTimeInMs= */ 10, /* screenOnTimeInMs= */ 0); assertThat(resultDiffData.getSystemDiffEntryList()).isEmpty(); @@ -1509,6 +1538,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1528,6 +1558,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1547,6 +1578,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 3600000L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 7200000L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1587,6 +1619,7 @@ public final class DataProcessorTest { final BatteryDiffEntry resultEntry = resultDiffData.getAppDiffEntryList().get(0); assertThat(resultEntry.mForegroundUsageTimeInMs) .isEqualTo(Math.round(entry.mForegroundUsageTimeInMs * ratio)); + assertThat(resultEntry.mForegroundServiceUsageTimeInMs).isEqualTo(0); assertThat(resultEntry.mBackgroundUsageTimeInMs).isEqualTo(0); assertThat(resultEntry.mConsumePower).isEqualTo(entry.mConsumePower * ratio); assertThat(resultEntry.mForegroundUsageConsumePower) @@ -1627,6 +1660,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1643,6 +1677,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1662,6 +1697,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1678,6 +1714,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1697,6 +1734,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 10L, + /* foregroundServiceUsageTimeInMs= */ 15L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1713,6 +1751,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 10L, + /* foregroundServiceUsageTimeInMs= */ 15L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1748,6 +1787,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 5, /* cachedUsageConsumePower= */ 5, /* foregroundUsageTimeInMs= */ 10, + /* foregroundServiceUsageTimeInMs= */ 15, /* backgroundUsageTimeInMs= */ 20, /* screenOnTimeInMs= */ 0); } @@ -1777,6 +1817,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1793,6 +1834,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1812,6 +1854,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1828,6 +1871,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 0L, + /* foregroundServiceUsageTimeInMs= */ 0L, /* backgroundUsageTimeInMs= */ 0L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1847,6 +1891,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 10L, + /* foregroundServiceUsageTimeInMs= */ 15L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1863,6 +1908,7 @@ public final class DataProcessorTest { currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY, /* foregroundUsageTimeInMs= */ 10L, + /* foregroundServiceUsageTimeInMs= */ 15L, /* backgroundUsageTimeInMs= */ 20L, /* isHidden= */ false); entryMap.put(entry.getKey(), entry); @@ -1892,6 +1938,7 @@ public final class DataProcessorTest { assertThat(resultEntry.mBackgroundUsageTimeInMs).isEqualTo(20); resultEntry = resultDiffData.getAppDiffEntryList().get(1); assertThat(resultEntry.mBackgroundUsageTimeInMs).isEqualTo(0); + assertThat(resultEntry.mForegroundServiceUsageTimeInMs).isEqualTo(0); } @Test @@ -1921,6 +1968,7 @@ public final class DataProcessorTest { doReturn(0.0).when(mMockBatteryEntry1).getConsumedPowerInBackground(); doReturn(0.0).when(mMockBatteryEntry1).getConsumedPowerInCached(); doReturn(30L).when(mMockBatteryEntry1).getTimeInForegroundMs(); + doReturn(35L).when(mMockBatteryEntry1).getTimeInForegroundServiceMs(); doReturn(40L).when(mMockBatteryEntry1).getTimeInBackgroundMs(); doReturn(1).when(mMockBatteryEntry1).getUid(); doReturn(ConvertUtils.CONSUMER_TYPE_UID_BATTERY).when(mMockBatteryEntry1).getConsumerType(); @@ -1930,6 +1978,7 @@ public final class DataProcessorTest { doReturn(0.0).when(mMockBatteryEntry2).getConsumedPowerInBackground(); doReturn(0.0).when(mMockBatteryEntry2).getConsumedPowerInCached(); doReturn(20L).when(mMockBatteryEntry2).getTimeInForegroundMs(); + doReturn(20L).when(mMockBatteryEntry2).getTimeInForegroundServiceMs(); doReturn(20L).when(mMockBatteryEntry2).getTimeInBackgroundMs(); doReturn(2).when(mMockBatteryEntry2).getUid(); doReturn(ConvertUtils.CONSUMER_TYPE_UID_BATTERY).when(mMockBatteryEntry2).getConsumerType(); @@ -1939,6 +1988,7 @@ public final class DataProcessorTest { doReturn(0.0).when(mMockBatteryEntry3).getConsumedPowerInBackground(); doReturn(0.0).when(mMockBatteryEntry3).getConsumedPowerInCached(); doReturn(0L).when(mMockBatteryEntry3).getTimeInForegroundMs(); + doReturn(0L).when(mMockBatteryEntry3).getTimeInForegroundServiceMs(); doReturn(0L).when(mMockBatteryEntry3).getTimeInBackgroundMs(); doReturn(3).when(mMockBatteryEntry3).getUid(); doReturn(ConvertUtils.CONSUMER_TYPE_UID_BATTERY).when(mMockBatteryEntry3).getConsumerType(); @@ -1948,6 +1998,7 @@ public final class DataProcessorTest { doReturn(0.3).when(mMockBatteryEntry4).getConsumedPowerInBackground(); doReturn(0.1).when(mMockBatteryEntry4).getConsumedPowerInCached(); doReturn(10L).when(mMockBatteryEntry4).getTimeInForegroundMs(); + doReturn(10L).when(mMockBatteryEntry4).getTimeInForegroundServiceMs(); doReturn(10L).when(mMockBatteryEntry4).getTimeInBackgroundMs(); doReturn(4).when(mMockBatteryEntry4).getUid(); doReturn(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY) @@ -1978,6 +2029,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 0, /* cachedUsageConsumePower= */ 0, /* foregroundUsageTimeInMs= */ 20, + /* foregroundServiceUsageTimeInMs= */ 20, /* backgroundUsageTimeInMs= */ 20, /* screenOnTimeInMs= */ 0); assertBatteryDiffEntry( @@ -1991,6 +2043,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 0, /* cachedUsageConsumePower= */ 0, /* foregroundUsageTimeInMs= */ 30, + /* foregroundServiceUsageTimeInMs= */ 35, /* backgroundUsageTimeInMs= */ 40, /* screenOnTimeInMs= */ 0); assertBatteryDiffEntry( @@ -2004,6 +2057,7 @@ public final class DataProcessorTest { /* backgroundUsageConsumePower= */ 0.3, /* cachedUsageConsumePower= */ 0.1, /* foregroundUsageTimeInMs= */ 10, + /* foregroundServiceUsageTimeInMs= */ 10, /* backgroundUsageTimeInMs= */ 10, /* screenOnTimeInMs= */ 0); } @@ -2390,6 +2444,7 @@ public final class DataProcessorTest { final long userId, final int consumerType, final long foregroundUsageTimeInMs, + final long foregroundServiceUsageTimeInMs, final long backgroundUsageTimeInMs, final boolean isHidden) { // Only insert required fields. @@ -2402,6 +2457,7 @@ public final class DataProcessorTest { .setBackgroundUsageConsumePower(backgroundUsageConsumePower) .setCachedUsageConsumePower(cachedUsageConsumePower) .setForegroundUsageTimeInMs(foregroundUsageTimeInMs) + .setForegroundServiceUsageTimeInMs(foregroundServiceUsageTimeInMs) .setBackgroundUsageTimeInMs(backgroundUsageTimeInMs) .setIsHidden(isHidden) .build(); @@ -2531,6 +2587,7 @@ public final class DataProcessorTest { final double backgroundUsageConsumePower, final double cachedUsageConsumePower, final long foregroundUsageTimeInMs, + final long foregroundServiceUsageTimeInMs, final long backgroundUsageTimeInMs, final long screenOnTimeInMs) { assertThat(entry.mUserId).isEqualTo(userId); @@ -2543,6 +2600,8 @@ public final class DataProcessorTest { assertThat(entry.mBackgroundUsageConsumePower).isEqualTo(backgroundUsageConsumePower); assertThat(entry.mCachedUsageConsumePower).isEqualTo(cachedUsageConsumePower); assertThat(entry.mForegroundUsageTimeInMs).isEqualTo(foregroundUsageTimeInMs); + assertThat(entry.mForegroundServiceUsageTimeInMs) + .isEqualTo(foregroundServiceUsageTimeInMs); assertThat(entry.mBackgroundUsageTimeInMs).isEqualTo(backgroundUsageTimeInMs); assertThat(entry.mScreenOnTimeInMs).isEqualTo(screenOnTimeInMs); } diff --git a/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysControllerTest.java new file mode 100644 index 00000000000..e1b4ffdc068 --- /dev/null +++ b/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysControllerTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 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.inputmethod; + +import static com.android.input.flags.Flags.FLAG_KEYBOARD_REPEAT_KEYS; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.hardware.input.InputSettings; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; + +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +@Config(shadows = { + com.android.settings.testutils.shadow.ShadowFragment.class, +}) +public class KeyboardRepeatKeysControllerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private Context mContext; + + private KeyboardRepeatKeysController mKeyboardRepeatKeysController; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mKeyboardRepeatKeysController = new KeyboardRepeatKeysController(mContext, + "physical_keyboard_repeat_key"); + } + + @Test + @EnableFlags(FLAG_KEYBOARD_REPEAT_KEYS) + public void getAvailabilityStatus_flagIsEnabled_isAvailable() { + assertThat(mKeyboardRepeatKeysController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + @DisableFlags(FLAG_KEYBOARD_REPEAT_KEYS) + public void getAvailabilityStatus_flagIsDisabled_notSupport() { + assertThat(mKeyboardRepeatKeysController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + public void isChecked_sameWithInputSettingValue() { + boolean isRepeatKeysEnabled = InputSettings.isRepeatKeysEnabled(mContext); + assertThat(mKeyboardRepeatKeysController.isChecked()).isEqualTo(isRepeatKeysEnabled); + } + + @Test + public void setChecked_updatesInputSettingValue() { + mKeyboardRepeatKeysController.setChecked(false); + + assertThat(InputSettings.isRepeatKeysEnabled(mContext)).isEqualTo(false); + } +} diff --git a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java index 458bc93d38c..7380c6688e4 100644 --- a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java +++ b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java @@ -28,6 +28,10 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; 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 androidx.preference.Preference; import androidx.preference.PreferenceManager; @@ -36,6 +40,7 @@ import androidx.preference.PreferenceScreen; import com.android.settings.testutils.shadow.ShadowNfcAdapter; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -58,6 +63,9 @@ public class PaymentSettingsTest { private Context mContext; + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + @Mock private PackageManager mPackageManager; @@ -98,7 +106,19 @@ public class PaymentSettingsTest { } @Test - public void getNonIndexableKey_primaryUser_returnsTrue() { + @RequiresFlagsEnabled(android.permission.flags.Flags.FLAG_WALLET_ROLE_ENABLED) + public void getNonIndexableKey_primaryUser_returnsFalse_walletRoleEnabled() { + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); + + final List niks = + PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + + assertThat(niks).containsAtLeast(FOREGROUND_KEY, PAYMENT_KEY); + } + + @Test + @RequiresFlagsDisabled(android.permission.flags.Flags.FLAG_WALLET_ROLE_ENABLED) + public void getNonIndexableKey_primaryUser_returnsTrue_walletRoleDisabled() { when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); final List niks =