Snap for 12955189 from 9707e4039f to 25Q2-release

Change-Id: Ic565ed1b3b998d056399611b2479239856fd71f7
This commit is contained in:
Android Build Coastguard Worker
2025-01-22 16:18:53 -08:00
90 changed files with 899 additions and 1035 deletions

View File

@@ -6,7 +6,7 @@ package {
aconfig_declarations { aconfig_declarations {
name: "aconfig_settings_flags", name: "aconfig_settings_flags",
package: "com.android.settings.flags", package: "com.android.settings.flags",
container: "system", container: "system_ext",
srcs: [ srcs: [
"*.aconfig", "*.aconfig",
"catalyst/*.aconfig", "catalyst/*.aconfig",
@@ -21,7 +21,7 @@ java_aconfig_library {
aconfig_declarations { aconfig_declarations {
name: "factory_reset_flags", name: "factory_reset_flags",
package: "com.android.settings.factory_reset", package: "com.android.settings.factory_reset",
container: "system", container: "system_ext",
srcs: ["factory_reset/*.aconfig"], srcs: ["factory_reset/*.aconfig"],
} }
@@ -33,7 +33,7 @@ java_aconfig_library {
aconfig_declarations { aconfig_declarations {
name: "media_drm_flags", name: "media_drm_flags",
package: "com.android.settings.media_drm", package: "com.android.settings.media_drm",
container: "system", container: "system_ext",
srcs: ["media_drm/*.aconfig"], srcs: ["media_drm/*.aconfig"],
} }
@@ -45,7 +45,7 @@ java_aconfig_library {
aconfig_declarations { aconfig_declarations {
name: "accessibility_flags", name: "accessibility_flags",
package: "com.android.settings.accessibility", package: "com.android.settings.accessibility",
container: "system", container: "system_ext",
srcs: ["accessibility/*.aconfig"], srcs: ["accessibility/*.aconfig"],
} }
@@ -57,7 +57,7 @@ java_aconfig_library {
aconfig_declarations { aconfig_declarations {
name: "development_settings_flags", name: "development_settings_flags",
package: "com.android.settings.development", package: "com.android.settings.development",
container: "system", container: "system_ext",
srcs: [ srcs: [
"development/**/*.aconfig", "development/**/*.aconfig",
], ],
@@ -71,7 +71,7 @@ java_aconfig_library {
aconfig_declarations { aconfig_declarations {
name: "keyboard_flags", name: "keyboard_flags",
package: "com.android.settings.keyboard", package: "com.android.settings.keyboard",
container: "system", container: "system_ext",
srcs: ["keyboard/*.aconfig"], srcs: ["keyboard/*.aconfig"],
} }

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.accessibility" package: "com.android.settings.accessibility"
container: "system" container: "system_ext"
# NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors. # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_legal_information" name: "catalyst_legal_information"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_accessibility_color_and_motion" name: "catalyst_accessibility_color_and_motion"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_power_usage_summary_screen" name: "catalyst_power_usage_summary_screen"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_bluetooth_switchbar_screen" name: "catalyst_bluetooth_switchbar_screen"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_display_settings_screen" name: "catalyst_display_settings_screen"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_location_settings" name: "catalyst_location_settings"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_lockscreen_from_display_settings" name: "catalyst_lockscreen_from_display_settings"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_network_provider_and_internet_screen" name: "catalyst_network_provider_and_internet_screen"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_sound_screen" name: "catalyst_sound_screen"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "catalyst_language_setting" name: "catalyst_language_setting"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.development" package: "com.android.settings.development"
container: "system" container: "system_ext"
flag { flag {
name: "deprecate_list_activity" name: "deprecate_list_activity"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.factory_reset" package: "com.android.settings.factory_reset"
container: "system" container: "system_ext"
flag { flag {
name: "enable_factory_reset_wizard" name: "enable_factory_reset_wizard"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.keyboard" package: "com.android.settings.keyboard"
container: "system" container: "system_ext"
flag { flag {
name: "keyboard_layout_picker_activity_enabled" name: "keyboard_layout_picker_activity_enabled"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.keyboard" package: "com.android.settings.keyboard"
container: "system" container: "system_ext"
flag { flag {
name: "keyboard_and_touchpad_a11y_new_page_enabled" name: "keyboard_and_touchpad_a11y_new_page_enabled"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.media_drm" package: "com.android.settings.media_drm"
container: "system" container: "system_ext"
flag { flag {
name: "force_l3_enabled" name: "force_l3_enabled"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
# NOTE: Don't add new accessibility flags here, since the package name doesn't follow # NOTE: Don't add new accessibility flags here, since the package name doesn't follow
# the best practice for setting's feature flag go/settings-trunk-stable # the best practice for setting's feature flag go/settings-trunk-stable

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "biometric_settings_provider" name: "biometric_settings_provider"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "sfps_enroll_refinement" name: "sfps_enroll_refinement"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "enable_offload_bluetooth_operations_to_background_thread" name: "enable_offload_bluetooth_operations_to_background_thread"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "rotation_connected_display_setting" name: "rotation_connected_display_setting"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "enable_contacts_default_account_in_settings" name: "enable_contacts_default_account_in_settings"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "datetime_feedback" name: "datetime_feedback"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
# NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors. # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "enable_device_diagnostics_in_settings" name: "enable_device_diagnostics_in_settings"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "protect_screen_timeout_with_auth" name: "protect_screen_timeout_with_auth"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "new_apn_page_enabled" name: "new_apn_page_enabled"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "show_factory_reset_cancel_button" name: "show_factory_reset_cancel_button"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "terms_of_address_enabled" name: "terms_of_address_enabled"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "dedupe_dnd_settings_channels" name: "dedupe_dnd_settings_channels"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "enable_sound_backup" name: "enable_sound_backup"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "enable_perform_backup_tasks_in_settings" name: "enable_perform_backup_tasks_in_settings"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "protect_lock_after_timeout_with_auth" name: "protect_lock_after_timeout_with_auth"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "remove_key_hide_enable_2g" name: "remove_key_hide_enable_2g"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "thread_settings_enabled" name: "thread_settings_enabled"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
flag { flag {
name: "enable_voice_activation_apps_in_settings" name: "enable_voice_activation_apps_in_settings"

View File

@@ -1,5 +1,5 @@
package: "com.android.settings.flags" package: "com.android.settings.flags"
container: "system" container: "system_ext"
# NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors. # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.

View File

@@ -5521,10 +5521,6 @@
screen magnification on app transitions</string> screen magnification on app transitions</string>
<!-- Title for the accessibility preference to power button to end a call. [CHAR LIMIT=35] --> <!-- Title for the accessibility preference to power button to end a call. [CHAR LIMIT=35] -->
<string name="accessibility_power_button_ends_call_prerefence_title">Power button ends call</string> <string name="accessibility_power_button_ends_call_prerefence_title">Power button ends call</string>
<!-- Title for the accessibility preference for enabling/disabling large icons for mouse/trackpad pointers. [CHAR LIMIT=35] -->
<string name="accessibility_toggle_large_pointer_icon_title">Large mouse pointer</string>
<!-- Summary for the accessibility preference for enabling/disabling large icons for mouse/trackpad pointers. [CHAR LIMIT=60] -->
<string name="accessibility_toggle_large_pointer_icon_summary">Make the mouse pointer more noticeable</string>
<!-- Title for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=35] --> <!-- Title for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=35] -->
<string name="accessibility_force_invert_title">Make more apps dark</string> <string name="accessibility_force_invert_title">Make more apps dark</string>
<!-- Summary for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=100] --> <!-- Summary for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=100] -->

View File

@@ -58,13 +58,6 @@
android:title="@string/accessibility_disable_animations" android:title="@string/accessibility_disable_animations"
settings:controller="com.android.settings.accessibility.DisableAnimationsPreferenceController"/> settings:controller="com.android.settings.accessibility.DisableAnimationsPreferenceController"/>
<SwitchPreferenceCompat
android:key="toggle_large_pointer_icon"
android:persistent="false"
android:summary="@string/accessibility_toggle_large_pointer_icon_summary"
android:title="@string/accessibility_toggle_large_pointer_icon_title"
settings:controller="com.android.settings.accessibility.LargePointerIconPreferenceController"/>
<PreferenceCategory <PreferenceCategory
android:key="experimental_category" android:key="experimental_category"
android:persistent="false" android:persistent="false"

View File

@@ -30,13 +30,6 @@
android:key="audio_sharing_device_list" android:key="audio_sharing_device_list"
android:title="@string/audio_sharing_device_group_title" android:title="@string/audio_sharing_device_group_title"
settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingDevicePreferenceController"> settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingDevicePreferenceController">
<Preference
android:fragment="com.android.settings.connecteddevice.audiosharing.AudioSharingDashboardFragment"
android:icon="@drawable/ic_bt_le_audio_sharing"
android:key="connected_device_audio_sharing_settings"
android:order="100"
android:title="@string/audio_sharing_title"
settings:searchable="false" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
@@ -44,6 +37,14 @@
android:title="@string/connected_device_temp_bond_device_title" android:title="@string/connected_device_temp_bond_device_title"
settings:controller="com.android.settings.connecteddevice.audiosharing.TemporaryBondDeviceGroupController" /> settings:controller="com.android.settings.connecteddevice.audiosharing.TemporaryBondDeviceGroupController" />
<Preference
android:fragment="com.android.settings.connecteddevice.audiosharing.AudioSharingDashboardFragment"
android:icon="@drawable/ic_bt_le_audio_sharing"
android:key="connected_device_audio_sharing_settings"
android:title="@string/audio_sharing_title"
settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingPreferenceController"
settings:searchable="false" />
<PreferenceCategory <PreferenceCategory
android:key="available_device_list" android:key="available_device_list"
android:title="@string/connected_device_media_device_title" android:title="@string/connected_device_media_device_title"

View File

@@ -67,9 +67,45 @@
android:title="@string/biometrics_unlock_skip_biometrics" android:title="@string/biometrics_unlock_skip_biometrics"
android:persistent="false"/> android:persistent="false"/>
<PreferenceCategory
android:key="unlock_settings"
android:title="@string/security_settings_fingerprint_settings_preferences_category"
settings:isPreferenceVisible="false">
<!-- available in pattern -->
<SwitchPreferenceCompat
android:key="visiblepattern"
android:title="@string/lockpattern_settings_enable_visible_pattern_title" />
<!-- available in pin -->
<SwitchPreferenceCompat
android:key="auto_pin_confirm"
android:title="@string/lock_screen_auto_pin_confirm_title"
android:summary="@string/lock_screen_auto_pin_confirm_summary" />
<SwitchPreferenceCompat
android:key="enhancedPinPrivacy"
android:title="@string/lockpattern_settings_enhanced_pin_privacy_title"
android:summary="@string/lockpattern_settings_enhanced_pin_privacy_summary" />
<!-- available in pin/pattern/password -->
<com.android.settings.security.screenlock.ProtectedTimeoutListPreference
android:key="lock_after_timeout"
android:title="@string/lock_after_timeout"
android:summary="@string/summary_placeholder"
android:entries="@array/lock_after_timeout_entries"
android:entryValues="@array/lock_after_timeout_values" />
<!-- available in pin/pattern/password -->
<SwitchPreferenceCompat
android:key="power_button_instantly_locks"
android:title="@string/lockpattern_settings_enable_power_button_instantly_locks" />
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference <com.android.settingslib.widget.FooterPreference
android:key="lock_settings_footer" android:key="lock_settings_footer"
android:selectable="false" android:selectable="false"
settings:searchable="false"/> settings:searchable="false"/>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -19,9 +19,9 @@ package com.android.settings
import android.content.Context import android.content.Context
import com.android.settings.overlay.FeatureFactory import com.android.settings.overlay.FeatureFactory
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider import com.android.settingslib.core.instrumentation.MetricsFeatureProvider
import com.android.settingslib.metadata.PreferenceUiActionMetricsLogger
import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceScreenMetadata import com.android.settingslib.metadata.PreferenceScreenMetadata
import com.android.settingslib.metadata.PreferenceUiActionMetricsLogger
/** Provides metrics for preference action. */ /** Provides metrics for preference action. */
interface PreferenceActionMetricsProvider { interface PreferenceActionMetricsProvider {

View File

@@ -16,11 +16,9 @@
package com.android.settings package com.android.settings
import android.app.Application
import android.content.Intent import android.content.Intent
import com.android.settings.flags.Flags import com.android.settings.flags.Flags
import com.android.settingslib.graph.PreferenceGetterRequest import com.android.settings.metrics.SettingsRemoteOpMetricsLogger
import com.android.settingslib.graph.PreferenceSetterRequest
import com.android.settingslib.ipc.ApiPermissionChecker import com.android.settingslib.ipc.ApiPermissionChecker
import com.android.settingslib.service.PreferenceService import com.android.settingslib.service.PreferenceService
@@ -28,32 +26,11 @@ import com.android.settingslib.service.PreferenceService
class SettingsService : class SettingsService :
PreferenceService( PreferenceService(
graphPermissionChecker = ApiPermissionChecker.alwaysAllow(), graphPermissionChecker = ApiPermissionChecker.alwaysAllow(),
setterPermissionChecker = SetterPermissionChecker(), setterPermissionChecker = ApiPermissionChecker.alwaysAllow(),
getterPermissionChecker = GetterPermissionChecker(), getterPermissionChecker = ApiPermissionChecker.alwaysAllow(),
metricsLogger = SettingsRemoteOpMetricsLogger(),
) { ) {
override fun onBind(intent: Intent) = override fun onBind(intent: Intent) =
if (Flags.catalystService()) super.onBind(intent) else null if (Flags.catalystService()) super.onBind(intent) else null
} }
/** Permission checker for external setter API. */
private class SetterPermissionChecker : ApiPermissionChecker<PreferenceSetterRequest> {
override fun hasPermission(
application: Application,
callingPid: Int,
callingUid: Int,
request: PreferenceSetterRequest,
) = true
}
/** Permission checker for external getter API. */
private class GetterPermissionChecker : ApiPermissionChecker<PreferenceGetterRequest> {
override fun hasPermission(
application: Application,
callingPid: Int,
callingUid: Int,
request: PreferenceGetterRequest,
) = true
}

View File

@@ -218,22 +218,6 @@ public final class AccessibilityUtil {
return shortcutTypes; return shortcutTypes;
} }
/**
* Converts {@link UserShortcutType} to key in Settings.
*
* @param shortcutType The shortcut type.
* @return Mapping key in Settings.
*
* @deprecated use
* {@link ShortcutUtils#convertToKey(int)} instead.
*
* (TODO 367414968: finish removal.)
*/
@Deprecated
static String convertKeyFromSettings(@UserShortcutType int shortcutType) {
return ShortcutUtils.convertToKey(shortcutType);
}
/** /**
* Gets the width of the screen. * Gets the width of the screen.
* *

View File

@@ -48,11 +48,9 @@ public class ColorAndMotionFragment extends DashboardFragment {
// Preferences // Preferences
private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN = "daltonizer_preference"; private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN = "daltonizer_preference";
private static final String TOGGLE_LARGE_POINTER_ICON = "toggle_large_pointer_icon";
private Preference mDisplayDaltonizerPreferenceScreen; private Preference mDisplayDaltonizerPreferenceScreen;
private TwoStatePreference mToggleDisableAnimationsPreference; private TwoStatePreference mToggleDisableAnimationsPreference;
private TwoStatePreference mToggleLargePointerIconPreference;
private AccessibilitySettingsContentObserver mSettingsContentObserver; private AccessibilitySettingsContentObserver mSettingsContentObserver;
private final List<String> mShortcutFeatureKeys = new ArrayList<>(); private final List<String> mShortcutFeatureKeys = new ArrayList<>();
@@ -116,9 +114,6 @@ public class ColorAndMotionFragment extends DashboardFragment {
// Disable animation. // Disable animation.
mToggleDisableAnimationsPreference = findPreference(RemoveAnimationsPreference.KEY); mToggleDisableAnimationsPreference = findPreference(RemoveAnimationsPreference.KEY);
// Large pointer icon.
mToggleLargePointerIconPreference = findPreference(TOGGLE_LARGE_POINTER_ICON);
} }
/** /**
@@ -134,10 +129,8 @@ public class ColorAndMotionFragment extends DashboardFragment {
// hardware-accelerated color transform. // hardware-accelerated color transform.
getPreferenceScreen().removePreference(mDisplayDaltonizerPreferenceScreen); getPreferenceScreen().removePreference(mDisplayDaltonizerPreferenceScreen);
getPreferenceScreen().removePreference(mToggleDisableAnimationsPreference); getPreferenceScreen().removePreference(mToggleDisableAnimationsPreference);
getPreferenceScreen().removePreference(mToggleLargePointerIconPreference);
experimentalCategory.addPreference(mDisplayDaltonizerPreferenceScreen); experimentalCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
experimentalCategory.addPreference(mToggleDisableAnimationsPreference); experimentalCategory.addPreference(mToggleDisableAnimationsPreference);
experimentalCategory.addPreference(mToggleLargePointerIconPreference);
} }
} }

View File

@@ -1,60 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accessibility;
import android.content.Context;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
public class LargePointerIconPreferenceController extends TogglePreferenceController {
@VisibleForTesting
static final int ON = 1;
@VisibleForTesting
static final int OFF = 0;
public LargePointerIconPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public boolean isChecked() {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, OFF) != OFF;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, isChecked ? ON : OFF);
}
@Override
public int getAvailabilityStatus() {
return android.view.flags.Flags.enableVectorCursorA11ySettings() ? CONDITIONALLY_UNAVAILABLE
: AVAILABLE;
}
@Override
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
}

View File

@@ -41,7 +41,6 @@ import androidx.annotation.Nullable;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -116,24 +115,6 @@ public class LaunchAccessibilityActivityPreferenceFragment extends ToggleFeature
return mTileComponentName; return mTileComponentName;
} }
@Override
CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
final ComponentName componentName = getTileComponentName();
if (componentName == null) {
return null;
}
final CharSequence tileName = loadTileLabel(getPrefContext(), componentName);
if (tileName == null) {
return null;
}
final int titleResId = type == QuickSettingsTooltipType.GUIDE_TO_EDIT
? R.string.accessibility_service_qs_tooltip_content
: R.string.accessibility_service_auto_added_qs_tooltip_content;
return getString(titleResId, tileName);
}
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Do not call super. We don't want to see the "Help & feedback" option on this page so as // Do not call super. We don't want to see the "Help & feedback" option on this page so as

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accessibility
import android.content.Context
import com.android.settings.R
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.preference.PreferenceBinding
internal class TextReadingDisplaySizePreference : PreferenceMetadata, PreferenceBinding {
override val key: String
get() = KEY
override val title: Int
get() = R.string.screen_zoom_title
override val summary: Int
get() = R.string.screen_zoom_short_summary
override val keywords: Int
get() = R.string.keywords_display_size
override fun createWidget(context: Context) =
AccessibilitySeekBarPreference(context, /* attrs= */ null).apply {
setIconStart(R.drawable.ic_remove_24dp)
setIconStartContentDescription(R.string.screen_zoom_make_smaller_desc)
setIconEnd(R.drawable.ic_add_24dp)
setIconEndContentDescription(R.string.screen_zoom_make_larger_desc)
}
companion object {
const val KEY = "display_size"
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accessibility
import android.content.Context
import android.provider.Settings.System.FONT_SCALE
import com.android.settings.R
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.preference.PreferenceBinding
internal class TextReadingFontSizePreference : PreferenceMetadata, PreferenceBinding {
override val key: String
get() = KEY
override val title: Int
get() = R.string.title_font_size
override val summary: Int
get() = R.string.short_summary_font_size
override val keywords: Int
get() = R.string.keywords_font_size
override fun createWidget(context: Context) =
AccessibilitySeekBarPreference(context, /* attrs= */ null).apply {
setIconStart(R.drawable.ic_remove_24dp)
setIconStartContentDescription(R.string.font_size_make_smaller_desc)
setIconEnd(R.drawable.ic_add_24dp)
setIconEndContentDescription(R.string.font_size_make_larger_desc)
}
companion object {
const val KEY = FONT_SCALE
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accessibility
import android.content.Context
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.preference.PreferenceBinding
internal class TextReadingPreview : PreferenceMetadata, PreferenceBinding {
override val key: String
get() = KEY
override fun createWidget(context: Context) =
TextReadingPreviewPreference(context).apply { isSelectable = false }
companion object {
const val KEY = "preview"
}
}

View File

@@ -18,11 +18,10 @@ package com.android.settings.accessibility
import android.content.Context import android.content.Context
import com.android.settings.R import com.android.settings.R
import com.android.settings.flags.Flags import com.android.settings.flags.Flags
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.preferenceHierarchy import com.android.settingslib.metadata.preferenceHierarchy
import com.android.settingslib.preference.PreferenceScreenCreator import com.android.settingslib.preference.PreferenceScreenCreator
@ProvidePreferenceScreen(TextReadingScreen.KEY) // @ProvidePreferenceScreen(TextReadingScreen.KEY)
class TextReadingScreen : PreferenceScreenCreator { class TextReadingScreen : PreferenceScreenCreator {
override val key: String override val key: String
get() = KEY get() = KEY
@@ -34,9 +33,12 @@ class TextReadingScreen : PreferenceScreenCreator {
override fun fragmentClass() = TextReadingPreferenceFragment::class.java override fun fragmentClass() = TextReadingPreferenceFragment::class.java
override fun hasCompleteHierarchy() = false override fun getPreferenceHierarchy(context: Context) =
preferenceHierarchy(context, this) {
override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) {} +TextReadingPreview()
+TextReadingFontSizePreference()
+TextReadingDisplaySizePreference()
}
companion object { companion object {
const val KEY = "text_reading_screen" const val KEY = "text_reading_screen"

View File

@@ -48,7 +48,6 @@ import androidx.annotation.Nullable;
import com.android.internal.accessibility.common.ShortcutConstants; import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment; import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment;
import com.android.settingslib.accessibility.AccessibilityUtils; import com.android.settingslib.accessibility.AccessibilityUtils;
@@ -245,24 +244,6 @@ public class ToggleAccessibilityServicePreferenceFragment extends
return mTileComponentName; return mTileComponentName;
} }
@Override
CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
final ComponentName componentName = getTileComponentName();
if (componentName == null) {
return null;
}
final CharSequence tileName = loadTileLabel(getPrefContext(), componentName);
if (tileName == null) {
return null;
}
final int titleResId = type == QuickSettingsTooltipType.GUIDE_TO_EDIT
? R.string.accessibility_service_qs_tooltip_content
: R.string.accessibility_service_auto_added_qs_tooltip_content;
return getString(titleResId, tileName);
}
@Override @Override
protected void updateSwitchBarToggleSwitch() { protected void updateSwitchBarToggleSwitch() {
final boolean checked = isAccessibilityServiceEnabled(); final boolean checked = isAccessibilityServiceEnabled();

View File

@@ -36,7 +36,6 @@ import android.view.ViewGroup;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SettingsMainSwitchPreference; import com.android.settings.widget.SettingsMainSwitchPreference;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
@@ -179,13 +178,6 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere
return COLOR_INVERSION_TILE_COMPONENT_NAME; return COLOR_INVERSION_TILE_COMPONENT_NAME;
} }
@Override
CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
return getText(type == QuickSettingsTooltipType.GUIDE_TO_EDIT
? R.string.accessibility_color_inversion_qs_tooltip_content
: R.string.accessibility_color_inversion_auto_added_qs_tooltip_content);
}
@Override @Override
protected void updateSwitchBarToggleSwitch() { protected void updateSwitchBarToggleSwitch() {
final boolean checked = Settings.Secure.getInt(getContentResolver(), ENABLED, OFF) == ON; final boolean checked = Settings.Secure.getInt(getContentResolver(), ENABLED, OFF) == ON;

View File

@@ -35,7 +35,6 @@ import android.view.ViewGroup;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SettingsMainSwitchPreference; import com.android.settings.widget.SettingsMainSwitchPreference;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
@@ -194,13 +193,6 @@ public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceF
return DALTONIZER_TILE_COMPONENT_NAME; return DALTONIZER_TILE_COMPONENT_NAME;
} }
@Override
CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
return getText(type == QuickSettingsTooltipType.GUIDE_TO_EDIT
? R.string.accessibility_color_correction_qs_tooltip_content
: R.string.accessibility_color_correction_auto_added_qs_tooltip_content);
}
@Override @Override
protected void updateSwitchBarToggleSwitch() { protected void updateSwitchBarToggleSwitch() {
final boolean checked = Settings.Secure.getInt(getContentResolver(), ENABLED, OFF) == ON; final boolean checked = Settings.Secure.getInt(getContentResolver(), ENABLED, OFF) == ON;

View File

@@ -59,7 +59,6 @@ import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.util.ShortcutUtils; import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment; import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.flags.Flags; import com.android.settings.flags.Flags;
@@ -274,14 +273,6 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
/** Returns the accessibility tile component name. */ /** Returns the accessibility tile component name. */
abstract ComponentName getTileComponentName(); abstract ComponentName getTileComponentName();
/** Returns the accessibility tile component name.
*
* @deprecated unused, as this class no longer displays tile tooltips.
*
* (TODO 367414968: finish removal.)*/
@Deprecated
abstract CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type);
protected void updateToggleServiceTitle(SettingsMainSwitchPreference switchPreference) { protected void updateToggleServiceTitle(SettingsMainSwitchPreference switchPreference) {
final CharSequence title = final CharSequence title =
getString(R.string.accessibility_service_primary_switch_title, mFeatureName); getString(R.string.accessibility_service_primary_switch_title, mFeatureName);

View File

@@ -37,7 +37,6 @@ import androidx.preference.PreferenceCategory;
import androidx.preference.TwoStatePreference; import androidx.preference.TwoStatePreference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SeekBarPreference; import com.android.settings.widget.SeekBarPreference;
import com.android.settings.widget.SettingsMainSwitchPreference; import com.android.settings.widget.SettingsMainSwitchPreference;
@@ -181,13 +180,6 @@ public class ToggleReduceBrightColorsPreferenceFragment extends ToggleFeaturePre
return REDUCE_BRIGHT_COLORS_TILE_SERVICE_COMPONENT_NAME; return REDUCE_BRIGHT_COLORS_TILE_SERVICE_COMPONENT_NAME;
} }
@Override
CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
return getText(type == QuickSettingsTooltipType.GUIDE_TO_EDIT
? R.string.accessibility_reduce_bright_colors_qs_tooltip_content
: R.string.accessibility_reduce_bright_colors_auto_added_qs_tooltip_content);
}
@Override @Override
protected void updateSwitchBarToggleSwitch() { protected void updateSwitchBarToggleSwitch() {
final boolean checked = mColorDisplayManager.isReduceBrightColorsActivated(); final boolean checked = mColorDisplayManager.isReduceBrightColorsActivated();

View File

@@ -19,12 +19,6 @@ package com.android.settings.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.DEFAULT; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.DEFAULT;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TRIPLETAP;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TWOFINGER_DOUBLETAP;
import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums; import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
@@ -39,7 +33,6 @@ import android.content.pm.PackageManager;
import android.icu.text.MessageFormat; import android.icu.text.MessageFormat;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils; import android.text.TextUtils;
@@ -55,13 +48,11 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceCategory;
import androidx.preference.SwitchPreferenceCompat; import androidx.preference.SwitchPreferenceCompat;
import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
import com.android.internal.accessibility.util.ShortcutUtils; import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.server.accessibility.Flags; import com.android.server.accessibility.Flags;
import com.android.settings.DialogCreatable; import com.android.settings.DialogCreatable;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment; import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
@@ -498,7 +489,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
int getUserShortcutTypes() { int getUserShortcutTypes() {
return getUserShortcutTypeFromSettings(getPrefContext()); return ShortcutUtils.getEnabledShortcutTypes(
getPrefContext(), MAGNIFICATION_CONTROLLER_NAME);
} }
@Override @Override
@@ -506,11 +498,6 @@ public class ToggleScreenMagnificationPreferenceFragment extends
return null; return null;
} }
@Override
CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
return null;
}
@Override @Override
protected void onPreferenceToggled(String preferenceKey, boolean enabled) { protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
if (enabled && TextUtils.equals( if (enabled && TextUtils.equals(
@@ -529,11 +516,12 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
public void onToggleClicked(ShortcutPreference preference) { public void onToggleClicked(ShortcutPreference preference) {
final int shortcutTypes = getUserPreferredShortcutTypes(); final int shortcutTypes = getUserPreferredShortcutTypes();
getPrefContext().getSystemService(AccessibilityManager.class).enableShortcutsForTargets(
preference.isChecked(), shortcutTypes,
Set.of(MAGNIFICATION_CONTROLLER_NAME), getPrefContext().getUserId()
);
if (preference.isChecked()) { if (preference.isChecked()) {
optInAllMagnificationValuesToSettings(getPrefContext(), shortcutTypes);
showDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL); showDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
} else {
optOutAllMagnificationValuesFromSettings(getPrefContext(), shortcutTypes);
} }
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
} }
@@ -550,7 +538,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
protected void updateShortcutPreferenceData() { protected void updateShortcutPreferenceData() {
final int shortcutTypes = getUserShortcutTypeFromSettings(getPrefContext()); final int shortcutTypes = ShortcutUtils.getEnabledShortcutTypes(
getPrefContext(), MAGNIFICATION_CONTROLLER_NAME);
if (shortcutTypes != DEFAULT) { if (shortcutTypes != DEFAULT) {
final PreferredShortcut shortcut = new PreferredShortcut( final PreferredShortcut shortcut = new PreferredShortcut(
MAGNIFICATION_CONTROLLER_NAME, shortcutTypes); MAGNIFICATION_CONTROLLER_NAME, shortcutTypes);
@@ -583,174 +572,10 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
protected void updateShortcutPreference() { protected void updateShortcutPreference() {
final int shortcutTypes = getUserPreferredShortcutTypes(); mShortcutPreference.setChecked(getUserShortcutTypes() != DEFAULT);
mShortcutPreference.setChecked(
hasMagnificationValuesInSettings(getPrefContext(), shortcutTypes));
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
} }
@VisibleForTesting
static void optInAllMagnificationValuesToSettings(Context context, int shortcutTypes) {
if ((shortcutTypes & SOFTWARE) == SOFTWARE) {
optInMagnificationValueToSettings(context, SOFTWARE);
}
if (((shortcutTypes & HARDWARE) == HARDWARE)) {
optInMagnificationValueToSettings(context, HARDWARE);
}
if (((shortcutTypes & TRIPLETAP) == TRIPLETAP)) {
optInMagnificationValueToSettings(context, TRIPLETAP);
}
if (((shortcutTypes & GESTURE) == GESTURE)) {
optInMagnificationValueToSettings(context, GESTURE);
}
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
if (((shortcutTypes & TWOFINGER_DOUBLETAP)
== TWOFINGER_DOUBLETAP)) {
optInMagnificationValueToSettings(context, TWOFINGER_DOUBLETAP);
}
}
if (((shortcutTypes & QUICK_SETTINGS)
== QUICK_SETTINGS)) {
optInMagnificationValueToSettings(context, QUICK_SETTINGS);
}
}
/**
* @deprecated use
* {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)} instead.
*
* (TODO 367414968: finish removal.)
*/
@Deprecated
private static void optInMagnificationValueToSettings(
Context context, @UserShortcutType int shortcutType) {
AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
if (a11yManager != null) {
a11yManager.enableShortcutsForTargets(
/* enable= */ true,
shortcutType,
Set.of(MAGNIFICATION_CONTROLLER_NAME),
UserHandle.myUserId()
);
}
}
@VisibleForTesting
static void optOutAllMagnificationValuesFromSettings(Context context,
int shortcutTypes) {
if ((shortcutTypes & SOFTWARE) == SOFTWARE) {
optOutMagnificationValueFromSettings(context, SOFTWARE);
}
if (((shortcutTypes & HARDWARE) == HARDWARE)) {
optOutMagnificationValueFromSettings(context, HARDWARE);
}
if (((shortcutTypes & TRIPLETAP) == TRIPLETAP)) {
optOutMagnificationValueFromSettings(context, TRIPLETAP);
}
if (((shortcutTypes & GESTURE) == GESTURE)) {
optOutMagnificationValueFromSettings(context, GESTURE);
}
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
if (((shortcutTypes & TWOFINGER_DOUBLETAP)
== TWOFINGER_DOUBLETAP)) {
optOutMagnificationValueFromSettings(context, TWOFINGER_DOUBLETAP);
}
}
if (((shortcutTypes & QUICK_SETTINGS)
== QUICK_SETTINGS)) {
optOutMagnificationValueFromSettings(context, QUICK_SETTINGS);
}
}
/**
* @deprecated use
* {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)} instead.
*
* (TODO 367414968: finish removal.)
*/
@Deprecated
private static void optOutMagnificationValueFromSettings(Context context,
@UserShortcutType int shortcutType) {
AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
if (a11yManager != null) {
a11yManager.enableShortcutsForTargets(
/* enable= */ false,
shortcutType,
Set.of(MAGNIFICATION_CONTROLLER_NAME),
UserHandle.myUserId()
);
}
}
@VisibleForTesting
static boolean hasMagnificationValuesInSettings(Context context, int shortcutTypes) {
for (int shortcutType : AccessibilityUtil.SHORTCUTS_ORDER_IN_UI) {
if ((shortcutTypes & shortcutType) == 0) {
continue;
}
if (((shortcutType & TWOFINGER_DOUBLETAP)
== TWOFINGER_DOUBLETAP)
&& !Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
continue;
}
if (hasMagnificationValueInSettings(context, shortcutType)) {
return true;
}
}
return false;
}
private static boolean hasMagnificationValueInSettings(Context context,
@UserShortcutType int shortcutType) {
if (shortcutType == TRIPLETAP) {
return Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON;
}
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
if (shortcutType == TWOFINGER_DOUBLETAP) {
return Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
OFF) == ON;
}
}
final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType);
final String targetString = Settings.Secure.getString(context.getContentResolver(),
targetKey);
if (TextUtils.isEmpty(targetString)) {
return false;
}
sStringColonSplitter.setString(targetString);
while (sStringColonSplitter.hasNext()) {
final String name = sStringColonSplitter.next();
if (MAGNIFICATION_CONTROLLER_NAME.equals(name)) {
return true;
}
}
return false;
}
/**
* @deprecated use
* {@link ShortcutUtils#getEnabledShortcutTypes(Context, String)} instead.
*
* (TODO 367414968: finish removal.)
*/
@Deprecated
private static int getUserShortcutTypeFromSettings(Context context) {
int shortcutTypes = DEFAULT;
for (int shortcutType : AccessibilityUtil.SHORTCUTS_ORDER_IN_UI) {
if (hasMagnificationValueInSettings(context, shortcutType)) {
shortcutTypes |= shortcutType;
}
}
return shortcutTypes;
}
/** /**
* Gets the service summary of magnification. * Gets the service summary of magnification.
* *
@@ -758,7 +583,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
*/ */
public static CharSequence getServiceSummary(Context context) { public static CharSequence getServiceSummary(Context context) {
// Get the user shortcut type from settings provider. // Get the user shortcut type from settings provider.
final int userShortcutType = getUserShortcutTypeFromSettings(context); final int userShortcutType = ShortcutUtils.getEnabledShortcutTypes(
context, MAGNIFICATION_CONTROLLER_NAME);
final CharSequence featureState = final CharSequence featureState =
(userShortcutType != DEFAULT) (userShortcutType != DEFAULT)
? context.getText(R.string.accessibility_summary_shortcut_enabled) ? context.getText(R.string.accessibility_summary_shortcut_enabled)
@@ -822,7 +648,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
// mention magnification so it may confuse users who search a term // mention magnification so it may confuse users who search a term
// like "Keep on". // like "Keep on".
// So we hide it if the user has no magnification shortcut enabled. // So we hide it if the user has no magnification shortcut enabled.
|| getUserShortcutTypeFromSettings(context) == DEFAULT) { || ShortcutUtils.getEnabledShortcutTypes(
context, MAGNIFICATION_CONTROLLER_NAME) == DEFAULT) {
niks.add(MagnificationAlwaysOnPreferenceController.PREF_KEY); niks.add(MagnificationAlwaysOnPreferenceController.PREF_KEY);
} }
if (!isOneFingerPanningSupported()) { if (!isOneFingerPanningSupported()) {

View File

@@ -113,13 +113,7 @@ public abstract class ShortcutOptionPreferenceController extends BasePreferenceC
/** /**
* Enable or disable the shortcut for the given accessibility features. * Enable or disable the shortcut for the given accessibility features.
*
* @deprecated use
* {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)} instead.
*
* (TODO 367414968: finish removal.)
*/ */
@Deprecated
protected void enableShortcutForTargets(boolean enable) { protected void enableShortcutForTargets(boolean enable) {
Set<String> shortcutTargets = getShortcutTargets(); Set<String> shortcutTargets = getShortcutTargets();
@ShortcutConstants.UserShortcutType int shortcutType = getShortcutType(); @ShortcutConstants.UserShortcutType int shortcutType = getShortcutType();

View File

@@ -681,15 +681,10 @@ public class FingerprintSettings extends SubSettings {
return false; return false;
} }
private boolean isUltrasnoicUdfps() { private boolean isScreenOffUnlcokSupported() {
mFingerprintManager = Utils.getFingerprintManagerOrNull(getActivity()); if (isUdfps()) {
if (mFingerprintManager != null) { return getContext().getResources().getBoolean(
mSensorProperties = mFingerprintManager.getSensorPropertiesInternal(); com.android.internal.R.bool.config_screen_off_udfps_enabled);
for (FingerprintSensorPropertiesInternal prop : mSensorProperties) {
if (prop.isUltrasonicUdfps()) {
return true;
}
}
} }
return false; return false;
} }
@@ -736,7 +731,7 @@ public class FingerprintSettings extends SubSettings {
// This needs to be after setting ids, otherwise // This needs to be after setting ids, otherwise
// |mRequireScreenOnToAuthPreferenceController.isChecked| is always checking the primary // |mRequireScreenOnToAuthPreferenceController.isChecked| is always checking the primary
// user instead of the user with |mUserId|. // user instead of the user with |mUserId|.
if (isSfps() || (screenOffUnlockUdfps() && isUltrasnoicUdfps())) { if (isSfps() || (screenOffUnlockUdfps() && isScreenOffUnlcokSupported())) {
scrollToPreference(fpPrefKey); scrollToPreference(fpPrefKey);
addFingerprintUnlockCategory(); addFingerprintUnlockCategory();
} }
@@ -836,7 +831,7 @@ public class FingerprintSettings extends SubSettings {
restToUnlockPreference.getOnPreferenceChangeListener()); restToUnlockPreference.getOnPreferenceChangeListener());
} }
setupFingerprintUnlockCategoryPreferencesForScreenOnToAuth(); setupFingerprintUnlockCategoryPreferencesForScreenOnToAuth();
} else if (screenOffUnlockUdfps() && isUltrasnoicUdfps()) { } else if (screenOffUnlockUdfps() && isScreenOffUnlcokSupported()) {
setupFingerprintUnlockCategoryPreferencesForScreenOffUnlock(); setupFingerprintUnlockCategoryPreferencesForScreenOffUnlock();
} }
setupExtFingerprintPreferences(); setupExtFingerprintPreferences();
@@ -905,7 +900,7 @@ public class FingerprintSettings extends SubSettings {
private void updatePreferencesAfterFingerprintRemoved() { private void updatePreferencesAfterFingerprintRemoved() {
updateAddPreference(); updateAddPreference();
if (isSfps() || (screenOffUnlockUdfps() && isUltrasnoicUdfps())) { if (isSfps() || (screenOffUnlockUdfps() && isScreenOffUnlcokSupported())) {
updateFingerprintUnlockCategoryVisibility(); updateFingerprintUnlockCategoryVisibility();
} }
updatePreferences(); updatePreferences();
@@ -1181,7 +1176,7 @@ public class FingerprintSettings extends SubSettings {
} }
} }
} else if (screenOffUnlockUdfps() && isUltrasnoicUdfps()) { } else if (screenOffUnlockUdfps() && isScreenOffUnlcokSupported()) {
for (AbstractPreferenceController controller : controllers) { for (AbstractPreferenceController controller : controllers) {
if (controller.getPreferenceKey() == KEY_FINGERPRINT_UNLOCK_CATEGORY) { if (controller.getPreferenceKey() == KEY_FINGERPRINT_UNLOCK_CATEGORY) {
mFingerprintUnlockCategoryPreferenceController = mFingerprintUnlockCategoryPreferenceController =

View File

@@ -59,7 +59,7 @@ public class FingerprintSettingsScreenOffUnlockUdfpsPreferenceController
return false; return false;
} }
final boolean defEnabled = mContext.getResources().getBoolean( final boolean defEnabled = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_screen_off_udfps_enabled); com.android.internal.R.bool.config_screen_off_udfps_default_on);
final int value = Settings.Secure.getIntForUser( final int value = Settings.Secure.getIntForUser(
mContext.getContentResolver(), mContext.getContentResolver(),
Settings.Secure.SCREEN_OFF_UNLOCK_UDFPS_ENABLED, Settings.Secure.SCREEN_OFF_UNLOCK_UDFPS_ENABLED,

View File

@@ -91,6 +91,7 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
private static final String ESTIMATE_READY = "estimate_ready"; private static final String ESTIMATE_READY = "estimate_ready";
private static final String DATABASE_ID = "id"; private static final String DATABASE_ID = "id";
private static final String DATABASE_BLUETOOTH = "Bluetooth"; private static final String DATABASE_BLUETOOTH = "Bluetooth";
private static final String TAG_BATT = "BATT";
private static final long TIME_OF_HOUR = TimeUnit.SECONDS.toMillis(3600); private static final long TIME_OF_HOUR = TimeUnit.SECONDS.toMillis(3600);
private static final long TIME_OF_MINUTE = TimeUnit.SECONDS.toMillis(60); private static final long TIME_OF_MINUTE = TimeUnit.SECONDS.toMillis(60);
private static final int LEFT_DEVICE_ID = 1; private static final int LEFT_DEVICE_ID = 1;
@@ -268,6 +269,30 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
BluetoothDevice.METADATA_MAIN_BATTERY) BluetoothDevice.METADATA_MAIN_BATTERY)
!= BluetoothUtils.META_INT_ERROR); != BluetoothUtils.META_INT_ERROR);
}); });
Supplier<Boolean> isBattEnabled =
Suppliers.memoize(
() ->
Boolean.valueOf(
BluetoothUtils.getFastPairCustomizedField(
mCachedDevice.getDevice(), TAG_BATT)));
Supplier<Integer> leftBatteryLevel =
Suppliers.memoize(
() ->
BluetoothUtils.getIntMetaData(
mCachedDevice.getDevice(),
BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY));
Supplier<Integer> rightBatteryLevel =
Suppliers.memoize(
() ->
BluetoothUtils.getIntMetaData(
mCachedDevice.getDevice(),
BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY));
Supplier<Integer> caseBatteryLevel =
Suppliers.memoize(
() ->
BluetoothUtils.getIntMetaData(
mCachedDevice.getDevice(),
BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY));
preloadAndRun( preloadAndRun(
List.of(deviceName, disconnected, isUntetheredHeadset, summaryText), List.of(deviceName, disconnected, isUntetheredHeadset, summaryText),
() -> { () -> {
@@ -277,7 +302,16 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
final TextView summary = final TextView summary =
mLayoutPreference.findViewById(R.id.entity_header_summary); mLayoutPreference.findViewById(R.id.entity_header_summary);
if (disconnected.get()) { final boolean isBatteryLevelAvailable =
Flags.enableBatteryLevelDisplay()
&& isBattEnabled.get()
&& (leftBatteryLevel.get() > BluetoothUtils.META_INT_ERROR
|| rightBatteryLevel.get()
> BluetoothUtils.META_INT_ERROR
|| caseBatteryLevel.get()
> BluetoothUtils.META_INT_ERROR);
if (disconnected.get() && !isBatteryLevelAvailable) {
summary.setText(summaryText.get()); summary.setText(summaryText.get());
updateDisconnectLayout(); updateDisconnectLayout();
return; return;

View File

@@ -78,8 +78,6 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
private static final String TAG = "AudioSharingDevicePrefController"; private static final String TAG = "AudioSharingDevicePrefController";
private static final String KEY = "audio_sharing_device_list"; private static final String KEY = "audio_sharing_device_list";
private static final String KEY_AUDIO_SHARING_SETTINGS =
"connected_device_audio_sharing_settings";
@Nullable private final LocalBluetoothManager mBtManager; @Nullable private final LocalBluetoothManager mBtManager;
@Nullable private final CachedBluetoothDeviceManager mDeviceManager; @Nullable private final CachedBluetoothDeviceManager mDeviceManager;
@@ -89,7 +87,6 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
private final Executor mExecutor; private final Executor mExecutor;
private final MetricsFeatureProvider mMetricsFeatureProvider; private final MetricsFeatureProvider mMetricsFeatureProvider;
@Nullable private PreferenceGroup mPreferenceGroup; @Nullable private PreferenceGroup mPreferenceGroup;
@Nullable private Preference mAudioSharingSettingsPreference;
@Nullable private BluetoothDeviceUpdater mBluetoothDeviceUpdater; @Nullable private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
@Nullable private DashboardFragment mFragment; @Nullable private DashboardFragment mFragment;
@Nullable private AudioSharingDialogHandler mDialogHandler; @Nullable private AudioSharingDialogHandler mDialogHandler;
@@ -280,13 +277,8 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
super.displayPreference(screen); super.displayPreference(screen);
mPreferenceGroup = screen.findPreference(KEY); mPreferenceGroup = screen.findPreference(KEY);
if (mPreferenceGroup != null) { if (mPreferenceGroup != null) {
mAudioSharingSettingsPreference =
mPreferenceGroup.findPreference(KEY_AUDIO_SHARING_SETTINGS);
mPreferenceGroup.setVisible(false); mPreferenceGroup.setVisible(false);
} }
if (mAudioSharingSettingsPreference != null) {
mAudioSharingSettingsPreference.setVisible(false);
}
if (isAvailable()) { if (isAvailable()) {
if (mBluetoothDeviceUpdater != null) { if (mBluetoothDeviceUpdater != null) {
@@ -320,11 +312,8 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
@Override @Override
public void onDeviceAdded(Preference preference) { public void onDeviceAdded(Preference preference) {
if (mPreferenceGroup != null) { if (mPreferenceGroup != null) {
if (mPreferenceGroup.getPreferenceCount() == 1) { if (mPreferenceGroup.getPreferenceCount() == 0) {
mPreferenceGroup.setVisible(true); mPreferenceGroup.setVisible(true);
if (mAudioSharingSettingsPreference != null) {
mAudioSharingSettingsPreference.setVisible(true);
}
} }
mPreferenceGroup.addPreference(preference); mPreferenceGroup.addPreference(preference);
} }
@@ -334,11 +323,8 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
public void onDeviceRemoved(Preference preference) { public void onDeviceRemoved(Preference preference) {
if (mPreferenceGroup != null) { if (mPreferenceGroup != null) {
mPreferenceGroup.removePreference(preference); mPreferenceGroup.removePreference(preference);
if (mPreferenceGroup.getPreferenceCount() == 1) { if (mPreferenceGroup.getPreferenceCount() == 0) {
mPreferenceGroup.setVisible(false); mPreferenceGroup.setVisible(false);
if (mAudioSharingSettingsPreference != null) {
mAudioSharingSettingsPreference.setVisible(false);
}
} }
} }
} }

View File

@@ -45,6 +45,9 @@ import java.util.concurrent.Executors;
public class AudioSharingPreferenceController extends BasePreferenceController public class AudioSharingPreferenceController extends BasePreferenceController
implements DefaultLifecycleObserver, BluetoothCallback { implements DefaultLifecycleObserver, BluetoothCallback {
private static final String TAG = "AudioSharingPreferenceController"; private static final String TAG = "AudioSharingPreferenceController";
private static final String CONNECTED_DEVICES_PREF_KEY =
"connected_device_audio_sharing_settings";
private static final String CONNECTION_PREFERENCES_PREF_KEY = "audio_sharing_settings";
@Nullable private final LocalBluetoothManager mBtManager; @Nullable private final LocalBluetoothManager mBtManager;
@Nullable private final BluetoothEventManager mEventManager; @Nullable private final BluetoothEventManager mEventManager;
@@ -57,7 +60,7 @@ public class AudioSharingPreferenceController extends BasePreferenceController
new BluetoothLeBroadcast.Callback() { new BluetoothLeBroadcast.Callback() {
@Override @Override
public void onBroadcastStarted(int reason, int broadcastId) { public void onBroadcastStarted(int reason, int broadcastId) {
refreshSummary(); refreshPreference();
} }
@Override @Override
@@ -69,7 +72,7 @@ public class AudioSharingPreferenceController extends BasePreferenceController
@Override @Override
public void onBroadcastStopped(int reason, int broadcastId) { public void onBroadcastStopped(int reason, int broadcastId) {
refreshSummary(); refreshPreference();
} }
@Override @Override
@@ -111,6 +114,7 @@ public class AudioSharingPreferenceController extends BasePreferenceController
} }
mEventManager.registerCallback(this); mEventManager.registerCallback(this);
mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback); mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback);
updateVisibility();
} }
@Override @Override
@@ -131,6 +135,13 @@ public class AudioSharingPreferenceController extends BasePreferenceController
public void displayPreference(@NonNull PreferenceScreen screen) { public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey()); mPreference = screen.findPreference(getPreferenceKey());
// super.displayPreference set the visibility based on isAvailable()
// immediately set the preference invisible on Connected devices page to avoid the audio
// sharing entrance being shown before updateVisibility(need binder call) take effects.
if (mPreference != null && CONNECTED_DEVICES_PREF_KEY.equals(getPreferenceKey())) {
mPreference.setVisible(false);
}
updateVisibility();
} }
@Override @Override
@@ -141,14 +152,51 @@ public class AudioSharingPreferenceController extends BasePreferenceController
@Override @Override
public CharSequence getSummary() { public CharSequence getSummary() {
return BluetoothUtils.isBroadcasting(mBtManager) return switch (getPreferenceKey()) {
? mContext.getString(R.string.audio_sharing_summary_on) case CONNECTION_PREFERENCES_PREF_KEY -> BluetoothUtils.isBroadcasting(mBtManager)
: mContext.getString(R.string.audio_sharing_summary_off); ? mContext.getString(R.string.audio_sharing_summary_on)
: mContext.getString(R.string.audio_sharing_summary_off);
default -> "";
};
} }
@Override @Override
public void onBluetoothStateChanged(@AdapterState int bluetoothState) { public void onBluetoothStateChanged(@AdapterState int bluetoothState) {
refreshSummary(); refreshPreference();
}
private void refreshPreference() {
switch (getPreferenceKey()) {
// Audio sharing entrance on Connected devices page has no summary, but its visibility
// will change based on audio sharing state
case CONNECTED_DEVICES_PREF_KEY -> updateVisibility();
// Audio sharing entrance on Connection preferences page always show up, but its summary
// will change based on audio sharing state
case CONNECTION_PREFERENCES_PREF_KEY -> refreshSummary();
}
}
private void updateVisibility() {
if (mPreference == null) {
return;
}
switch (getPreferenceKey()) {
case CONNECTED_DEVICES_PREF_KEY -> {
var unused =
ThreadUtils.postOnBackgroundThread(
() -> {
boolean visible = BluetoothUtils.isBroadcasting(mBtManager);
AudioSharingUtils.postOnMainThread(
mContext,
() -> {
// Check nullability to pass NullAway check
if (mPreference != null) {
mPreference.setVisible(visible);
}
});
});
}
}
} }
private void refreshSummary() { private void refreshSummary() {

View File

@@ -128,6 +128,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
// join the audio sharing, we will wait for the process complete for this list of sinks and then // join the audio sharing, we will wait for the process complete for this list of sinks and then
// popup audio sharing dialog with options to pair new device. // popup audio sharing dialog with options to pair new device.
private CopyOnWriteArrayList<BluetoothDevice> mSinksToWaitFor = new CopyOnWriteArrayList<>(); private CopyOnWriteArrayList<BluetoothDevice> mSinksToWaitFor = new CopyOnWriteArrayList<>();
private AtomicBoolean mStartingSharing = new AtomicBoolean(false);
private AtomicBoolean mStoppingSharing = new AtomicBoolean(false); private AtomicBoolean mStoppingSharing = new AtomicBoolean(false);
@VisibleForTesting @VisibleForTesting
@@ -160,6 +161,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
@Override @Override
public void onBroadcastStartFailed(int reason) { public void onBroadcastStartFailed(int reason) {
Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason); Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
mStartingSharing.compareAndSet(true, false);
updateSwitch(); updateSwitch();
showErrorDialog(); showErrorDialog();
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
@@ -177,16 +179,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
+ broadcastId + broadcastId
+ ", metadata = " + ", metadata = "
+ metadata.getBroadcastName()); + metadata.getBroadcastName());
if (mAssistant == null if (!mStartingSharing.compareAndSet(true, false)) {
|| mAssistant.getAllConnectedDevices().stream() Log.d(TAG, "Skip handleOnBroadcastReady, not in starting process");
.anyMatch(
device -> BluetoothUtils
.hasActiveLocalBroadcastSourceForBtDevice(
device, mBtManager))) {
Log.d(
TAG,
"Skip handleOnBroadcastReady: null assistant or "
+ "sink has active local source.");
return; return;
} }
handleOnBroadcastReady(); handleOnBroadcastReady();
@@ -213,6 +207,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
@Override @Override
public void onBroadcastStopFailed(int reason) { public void onBroadcastStopFailed(int reason) {
Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason); Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason);
mStoppingSharing.compareAndSet(true, false);
updateSwitch(); updateSwitch();
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
mContext, mContext,
@@ -565,6 +560,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
mDeviceItemsForSharing.remove(0); mDeviceItemsForSharing.remove(0);
} }
if (mBroadcast != null) { if (mBroadcast != null) {
mStartingSharing.set(true);
mBroadcast.startPrivateBroadcast(); mBroadcast.startPrivateBroadcast();
mSinksInAdding.clear(); mSinksInAdding.clear();
AudioSharingUtils.postOnMainThread(mContext, AudioSharingUtils.postOnMainThread(mContext,
@@ -583,7 +579,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
int broadcastId = mBroadcast.getLatestBroadcastId(); int broadcastId = mBroadcast.getLatestBroadcastId();
if (broadcastId != -1) { if (broadcastId != -1) {
mBroadcast.stopBroadcast(broadcastId); mBroadcast.stopBroadcast(broadcastId);
mStoppingSharing.compareAndSet(false, true); mStoppingSharing.set(true);
mSinksInAdding.clear(); mSinksInAdding.clear();
mSinksToWaitFor.clear(); mSinksToWaitFor.clear();
} }

View File

@@ -403,10 +403,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
* Displays resource based tiles. * Displays resource based tiles.
*/ */
private void displayResourceTiles() { private void displayResourceTiles() {
final int resId = getPreferenceScreenResId();
if (resId <= 0) {
return;
}
PreferenceScreen screen; PreferenceScreen screen;
PreferenceScreenCreator preferenceScreenCreator = getPreferenceScreenCreator(); PreferenceScreenCreator preferenceScreenCreator = getPreferenceScreenCreator();
if (preferenceScreenCreator != null) { if (preferenceScreenCreator != null) {
@@ -416,6 +412,10 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
} }
setPreferenceScreen(screen); setPreferenceScreen(screen);
} else { } else {
final int resId = getPreferenceScreenResId();
if (resId <= 0) {
return;
}
addPreferencesFromResource(resId); addPreferencesFromResource(resId);
screen = getPreferenceScreen(); screen = getPreferenceScreen();
} }

View File

@@ -111,7 +111,7 @@ public class LocalePickerWithRegionActivity extends SettingsBaseActivity
@Override @Override
public void onLocaleSelected(LocaleStore.LocaleInfo locale) { public void onLocaleSelected(LocaleStore.LocaleInfo locale) {
if (Flags.regionalPreferencesApiEnabled()) { if (Flags.regionalPreferencesApiEnabled()) {
if (sameLanguageAndScript(locale.getLocale(), Locale.getDefault())) { if (sameLanguageAndScript(locale.getLocale(), LocaleList.getDefault().get(0))) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt(ARG_DIALOG_TYPE, DIALOG_CHANGE_LOCALE_REGION); args.putInt(ARG_DIALOG_TYPE, DIALOG_CHANGE_LOCALE_REGION);
args.putSerializable(ARG_TARGET_LOCALE, locale); args.putSerializable(ARG_TARGET_LOCALE, locale);

View File

@@ -0,0 +1,159 @@
/*
* Copyright (C) 2025 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.metrics
import android.app.settings.SettingsEnums
import android.content.Context
import com.android.settings.PreferenceActionMetricsProvider
import com.android.settings.core.instrumentation.SettingsStatsLog
import com.android.settingslib.graph.PreferenceGetterErrorCode
import com.android.settingslib.graph.PreferenceSetterResult
import com.android.settingslib.metadata.PreferenceCoordinate
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceRemoteOpMetricsLogger
import com.android.settingslib.metadata.PreferenceScreenMetadata
/** Metrics logger for settings remote operations. */
class SettingsRemoteOpMetricsLogger : PreferenceRemoteOpMetricsLogger {
override fun logGetterApi(
context: Context,
callingUid: Int,
preferenceCoordinate: PreferenceCoordinate,
screen: PreferenceScreenMetadata?,
preference: PreferenceMetadata?,
errorCode: Int,
latencyMs: Long,
) =
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_READ.log(
context,
callingUid,
preferenceCoordinate,
preference,
errorCode,
latencyMs,
Int::convertGetterErrorCode,
)
override fun logSetterApi(
context: Context,
callingUid: Int,
preferenceCoordinate: PreferenceCoordinate,
screen: PreferenceScreenMetadata?,
preference: PreferenceMetadata?,
errorCode: Int,
latencyMs: Long,
) =
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_WRITE.log(
context,
callingUid,
preferenceCoordinate,
preference,
errorCode,
latencyMs,
Int::convertSetterErrorCode,
)
private fun Int.log(
context: Context,
callingUid: Int,
preferenceCoordinate: PreferenceCoordinate,
preference: PreferenceMetadata?,
errorCode: Int,
latencyMs: Long,
errorCodeToMetricsResult: (Int) -> Int,
) {
if (preference is PreferenceActionMetricsProvider) {
SettingsStatsLog.write(
SettingsStatsLog.SETTINGS_EXTAPI_REPORTED,
context.packageNameOfUid(callingUid),
"",
this,
errorCodeToMetricsResult(errorCode),
latencyMs,
preference.preferenceActionMetrics,
)
} else {
SettingsStatsLog.write(
SettingsStatsLog.SETTINGS_EXTAPI_REPORTED,
context.packageNameOfUid(callingUid),
preferenceCoordinate.settingsId,
this,
errorCodeToMetricsResult(errorCode),
latencyMs,
SettingsEnums.ACTION_UNKNOWN,
)
}
}
override fun logGraphApi(context: Context, callingUid: Int, success: Boolean, latencyMs: Long) {
val result =
if (success) {
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_OK
} else {
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INTERNAL_ERROR
}
SettingsStatsLog.write(
SettingsStatsLog.SETTINGS_EXTAPI_REPORTED,
context.packageNameOfUid(callingUid),
"",
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_GET_METADATA,
result,
latencyMs,
SettingsEnums.ACTION_UNKNOWN,
)
}
}
private fun Context.packageNameOfUid(uid: Int) = packageManager.getNameForUid(uid) ?: ""
private val PreferenceCoordinate.settingsId: String
get() = "$screenKey/$key"
private fun Int.convertGetterErrorCode() =
when (this) {
PreferenceGetterErrorCode.OK ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_OK
PreferenceGetterErrorCode.NOT_FOUND ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNSUPPORTED
PreferenceGetterErrorCode.DISALLOW ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_DISALLOW
else -> SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INTERNAL_ERROR
}
private fun Int.convertSetterErrorCode() =
when (this) {
PreferenceSetterResult.OK -> SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_OK
PreferenceSetterResult.UNSUPPORTED ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNSUPPORTED
PreferenceSetterResult.DISABLED ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_DISABLED
PreferenceSetterResult.RESTRICTED ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_RESTRICTED
PreferenceSetterResult.UNAVAILABLE ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNAVAILABLE
PreferenceSetterResult.REQUIRE_APP_PERMISSION ->
SettingsStatsLog
.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_REQUIRE_APP_PERMISSION
PreferenceSetterResult.REQUIRE_USER_AGREEMENT ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_REQUIRE_USER_CONSENT
PreferenceSetterResult.DISALLOW ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_DISALLOW
PreferenceSetterResult.INVALID_REQUEST ->
SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INVALID_REQUEST
else -> SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INTERNAL_ERROR
}

View File

@@ -71,6 +71,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
@@ -87,13 +88,22 @@ import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog; import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog;
import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.flags.Flags;
import com.android.settings.safetycenter.LockScreenSafetySource; import com.android.settings.safetycenter.LockScreenSafetySource;
import com.android.settings.search.SearchFeatureProvider; import com.android.settings.search.SearchFeatureProvider;
import com.android.settings.security.screenlock.AutoPinConfirmPreferenceController;
import com.android.settings.security.screenlock.LockAfterTimeoutPreferenceController;
import com.android.settings.security.screenlock.PatternVisiblePreferenceController;
import com.android.settings.security.screenlock.PinPrivacyPreferenceController;
import com.android.settings.security.screenlock.PowerButtonInstantLockPreferenceController;
import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.FooterPreference;
import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupcompat.util.WizardManagerHelper;
import java.util.ArrayList;
/** /**
* Activity class that provides a generic implementation for displaying options to choose a lock * Activity class that provides a generic implementation for displaying options to choose a lock
* type, either for setting up a new lock or updating an existing lock. * type, either for setting up a new lock or updating an existing lock.
@@ -131,6 +141,8 @@ public class ChooseLockGeneric extends SettingsActivity {
private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation"; private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
public static final String HIDE_INSECURE_OPTIONS = "hide_insecure_options"; public static final String HIDE_INSECURE_OPTIONS = "hide_insecure_options";
public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog"; public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog";
public static final String KEY_LOCK_SETTINGS = "unlock_settings";
public static final String KEY_LOCK_SETTINGS_FOOTER ="lock_settings_footer"; public static final String KEY_LOCK_SETTINGS_FOOTER ="lock_settings_footer";
/** /**
@@ -214,6 +226,9 @@ public class ChooseLockGeneric extends SettingsActivity {
private boolean mWaitingForBiometricEnrollment = false; private boolean mWaitingForBiometricEnrollment = false;
private boolean mEnrollFingerPrintOnly = false; private boolean mEnrollFingerPrintOnly = false;
private final ArrayList<AbstractPreferenceController> mUnlockSettingsControllers =
new ArrayList<>();
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return SettingsEnums.CHOOSE_LOCK_GENERIC; return SettingsEnums.CHOOSE_LOCK_GENERIC;
@@ -652,6 +667,12 @@ public class ChooseLockGeneric extends SettingsActivity {
footer.setVisible(false); footer.setVisible(false);
} }
if (Flags.biometricsOnboardingEducation()
&& !WizardManagerHelper.isAnySetupWizard(getIntent())) {
buildUnlockSettingsPreferenceControllers();
setUpUnlockSettingsPreference();
}
// Used for testing purposes // Used for testing purposes
findPreference(ScreenLockType.NONE.preferenceKey).setViewId(R.id.lock_none); findPreference(ScreenLockType.NONE.preferenceKey).setViewId(R.id.lock_none);
findPreference(KEY_SKIP_FINGERPRINT).setViewId(R.id.lock_none); findPreference(KEY_SKIP_FINGERPRINT).setViewId(R.id.lock_none);
@@ -661,6 +682,37 @@ public class ChooseLockGeneric extends SettingsActivity {
findPreference(ScreenLockType.PASSWORD.preferenceKey).setViewId(R.id.lock_password); findPreference(ScreenLockType.PASSWORD.preferenceKey).setViewId(R.id.lock_password);
} }
private void buildUnlockSettingsPreferenceControllers() {
mUnlockSettingsControllers.add(new PatternVisiblePreferenceController(
getContext(), mUserId, mLockPatternUtils));
mUnlockSettingsControllers.add(new PinPrivacyPreferenceController(
getContext(), mUserId, mLockPatternUtils));
mUnlockSettingsControllers.add(new PowerButtonInstantLockPreferenceController(
getContext(), mUserId, mLockPatternUtils));
mUnlockSettingsControllers.add(new LockAfterTimeoutPreferenceController(
getContext(), mUserId, mLockPatternUtils));
mUnlockSettingsControllers.add(new AutoPinConfirmPreferenceController(
getContext(), mUserId, mLockPatternUtils, this));
}
private void setUpUnlockSettingsPreference() {
boolean showUnlockSettingsCategory = false;
for (AbstractPreferenceController controller : mUnlockSettingsControllers) {
final boolean isAvailable = controller.isAvailable();
final Preference preference = findPreference(controller.getPreferenceKey());
preference.setVisible(isAvailable);
if (!isAvailable) {
continue;
}
preference.setOnPreferenceChangeListener(
(Preference.OnPreferenceChangeListener) controller);
controller.updateState(preference);
showUnlockSettingsCategory = true;
}
final PreferenceCategory unlockSettingsCategory = findPreference(KEY_LOCK_SETTINGS);
unlockSettingsCategory.setVisible(showUnlockSettingsCategory);
}
private String getFooterString() { private String getFooterString() {
@StringRes int stringId; @StringRes int stringId;
switch (mController.getAggregatedPasswordComplexity()) { switch (mController.getAggregatedPasswordComplexity()) {

View File

@@ -16,8 +16,6 @@
package com.android.settings.password; package com.android.settings.password;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
import android.content.Context; import android.content.Context;
@@ -138,17 +136,10 @@ public class SetupChooseLockPattern extends ChooseLockPattern {
protected void updateStage(Stage stage) { protected void updateStage(Stage stage) {
super.updateStage(stage); super.updateStage(stage);
if (!showMinimalUi() && mOptionsButton != null) { if (!showMinimalUi() && mOptionsButton != null) {
// In landscape, keep view stub to avoid pattern view shifting, but in portrait the
// header title and description could become multiple lines in confirm stage,
// gone the button view to reserve more room for growth height of header.
@View.Visibility
final int hideOrGone =
getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE
? View.INVISIBLE : View.GONE;
mOptionsButton.setVisibility( mOptionsButton.setVisibility(
(stage == Stage.Introduction || stage == Stage.HelpScreen || (stage == Stage.Introduction || stage == Stage.HelpScreen ||
stage == Stage.ChoiceTooShort || stage == Stage.FirstChoiceValid) stage == Stage.ChoiceTooShort || stage == Stage.FirstChoiceValid)
? View.VISIBLE : hideOrGone); ? View.VISIBLE : View.INVISIBLE);
} }
if (stage.leftMode == LeftButtonMode.Gone && stage == Stage.Introduction) { if (stage.leftMode == LeftButtonMode.Gone && stage == Stage.Introduction) {

View File

@@ -18,6 +18,7 @@ package com.android.settings.regionalpreferences;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.LocaleList;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -91,7 +92,7 @@ public abstract class RegionPickerBaseListPreferenceController extends BasePrefe
? getSuggestedLocaleList() ? getSuggestedLocaleList()
: getSupportedLocaleList(); : getSupportedLocaleList();
if (getPreferenceCategoryKey().contains(KEY_SUGGESTED)) { if (getPreferenceCategoryKey().contains(KEY_SUGGESTED)) {
Locale systemLocale = Locale.getDefault(); Locale systemLocale = LocaleList.getDefault().get(0);
LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(systemLocale); LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(systemLocale);
result.add(localeInfo); result.add(localeInfo);
} }
@@ -105,7 +106,7 @@ public abstract class RegionPickerBaseListPreferenceController extends BasePrefe
mPreferenceCategory.addPreference(pref); mPreferenceCategory.addPreference(pref);
pref.setTitle(locale.getFullCountryNameNative()); pref.setTitle(locale.getFullCountryNameNative());
pref.setKey(locale.toString()); pref.setKey(locale.toString());
if (locale.getLocale().equals(Locale.getDefault())) { if (locale.getLocale().equals(LocaleList.getDefault().get(0))) {
pref.setChecked(true); pref.setChecked(true);
} else { } else {
pref.setChecked(false); pref.setChecked(false);

View File

@@ -19,6 +19,7 @@ package com.android.settings.regionalpreferences;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.LocaleList;
import android.provider.Settings; import android.provider.Settings;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -83,7 +84,7 @@ public class RegionPickerFragment extends DashboardFragment{
private List<AbstractPreferenceController> buildPreferenceControllers( private List<AbstractPreferenceController> buildPreferenceControllers(
@NonNull Context context) { @NonNull Context context) {
Locale parentLocale = LocaleStore.getLocaleInfo(Locale.getDefault()).getParent(); Locale parentLocale = LocaleStore.getLocaleInfo(LocaleList.getDefault().get(0)).getParent();
LocaleStore.LocaleInfo parentLocaleInfo = LocaleStore.getLocaleInfo(parentLocale); LocaleStore.LocaleInfo parentLocaleInfo = LocaleStore.getLocaleInfo(parentLocale);
SystemRegionSuggestedListPreferenceController mSuggestedListPreferenceController = SystemRegionSuggestedListPreferenceController mSuggestedListPreferenceController =
new SystemRegionSuggestedListPreferenceController( new SystemRegionSuggestedListPreferenceController(

View File

@@ -17,6 +17,7 @@
package com.android.settings.regionalpreferences; package com.android.settings.regionalpreferences;
import android.content.Context; import android.content.Context;
import android.os.LocaleList;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.preference.Preference; import androidx.preference.Preference;
@@ -26,8 +27,6 @@ import com.android.internal.app.LocaleStore;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settings.flags.Flags; import com.android.settings.flags.Flags;
import java.util.Locale;
/** A controller for the entry of region picker page */ /** A controller for the entry of region picker page */
public class RegionPreferenceController extends BasePreferenceController { public class RegionPreferenceController extends BasePreferenceController {
@@ -39,7 +38,8 @@ public class RegionPreferenceController extends BasePreferenceController {
public void displayPreference(@NonNull PreferenceScreen screen) { public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
Preference preference = screen.findPreference(getPreferenceKey()); Preference preference = screen.findPreference(getPreferenceKey());
LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(Locale.getDefault()); LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(
LocaleList.getDefault().get(0));
preference.setSummary(localeInfo.getFullCountryNameNative()); preference.setSummary(localeInfo.getFullCountryNameNative());
} }

View File

@@ -92,7 +92,8 @@ public class ScreenLockPreferenceDetailsUtils {
* Returns whether the Gear Menu should be shown. * Returns whether the Gear Menu should be shown.
*/ */
public boolean shouldShowGearMenu() { public boolean shouldShowGearMenu() {
return isLockPatternSecure(); return !com.android.settings.flags.Flags.biometricsOnboardingEducation()
&& isLockPatternSecure();
} }
/** /**

View File

@@ -16,7 +16,6 @@
package com.android.settings.service package com.android.settings.service
import android.app.Application
import android.os.Binder import android.os.Binder
import android.os.OutcomeReceiver import android.os.OutcomeReceiver
import android.service.settings.preferences.GetValueRequest import android.service.settings.preferences.GetValueRequest
@@ -26,6 +25,7 @@ import android.service.settings.preferences.MetadataResult
import android.service.settings.preferences.SetValueRequest import android.service.settings.preferences.SetValueRequest
import android.service.settings.preferences.SetValueResult import android.service.settings.preferences.SetValueResult
import android.service.settings.preferences.SettingsPreferenceService import android.service.settings.preferences.SettingsPreferenceService
import com.android.settings.metrics.SettingsRemoteOpMetricsLogger
import com.android.settingslib.graph.GetPreferenceGraphApiHandler import com.android.settingslib.graph.GetPreferenceGraphApiHandler
import com.android.settingslib.graph.GetPreferenceGraphRequest import com.android.settingslib.graph.GetPreferenceGraphRequest
import com.android.settingslib.graph.PreferenceGetterApiHandler import com.android.settingslib.graph.PreferenceGetterApiHandler
@@ -41,9 +41,19 @@ class PreferenceService : SettingsPreferenceService() {
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val getApiHandler = PreferenceGetterApiHandler(1, ApiPermissionChecker.alwaysAllow()) private val getApiHandler: PreferenceGetterApiHandler
private val setApiHandler = PreferenceSetterApiHandler(2, ApiPermissionChecker.alwaysAllow()) private val setApiHandler: PreferenceSetterApiHandler
private val graphApi = GraphProvider(3) private val graphApi: GetPreferenceGraphApiHandler
init {
val metricsLogger = SettingsRemoteOpMetricsLogger()
getApiHandler =
PreferenceGetterApiHandler(1, ApiPermissionChecker.alwaysAllow(), metricsLogger)
setApiHandler =
PreferenceSetterApiHandler(2, ApiPermissionChecker.alwaysAllow(), metricsLogger)
graphApi =
GetPreferenceGraphApiHandler(3, ApiPermissionChecker.alwaysAllow(), metricsLogger)
}
override fun onGetAllPreferenceMetadata( override fun onGetAllPreferenceMetadata(
request: MetadataRequest, request: MetadataRequest,
@@ -58,9 +68,7 @@ class PreferenceService : SettingsPreferenceService() {
application, application,
callingPid, callingPid,
callingUid, callingUid,
GetPreferenceGraphRequest( GetPreferenceGraphRequest(flags = PreferenceGetterFlags.METADATA),
flags = PreferenceGetterFlags.METADATA,
),
) )
val result = transformCatalystGetMetadataResponse(this@PreferenceService, graphProto) val result = transformCatalystGetMetadataResponse(this@PreferenceService, graphProto)
callback.onResult(result) callback.onResult(result)
@@ -107,14 +115,4 @@ class PreferenceService : SettingsPreferenceService() {
} }
} }
} }
// Basic implementation - we already have permission to access Graph for Metadata via superclass
private class GraphProvider(override val id: Int) : GetPreferenceGraphApiHandler(emptySet()) {
override fun hasPermission(
application: Application,
callingPid: Int,
callingUid: Int,
request: GetPreferenceGraphRequest,
) = true
}
} }

View File

@@ -29,7 +29,7 @@ import com.android.settings.dashboard.DashboardFragment
*/ */
class SupervisionDashboardFragment : DashboardFragment() { class SupervisionDashboardFragment : DashboardFragment() {
override fun getPreferenceScreenResId() = R.xml.placeholder_preference_screen override fun getPreferenceScreenResId() = 0
override fun getMetricsCategory() = SettingsEnums.SUPERVISION_DASHBOARD override fun getMetricsCategory() = SettingsEnums.SUPERVISION_DASHBOARD

View File

@@ -21,16 +21,8 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TRIPLETAP;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TWOFINGER_DOUBLETAP;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
@@ -61,7 +53,6 @@ public final class AccessibilityUtilTest {
private static final String SECURE_TEST_KEY = "secure_test_key"; private static final String SECURE_TEST_KEY = "secure_test_key";
private static final String MOCK_PACKAGE_NAME = "com.mock.example"; private static final String MOCK_PACKAGE_NAME = "com.mock.example";
private static final String MOCK_CLASS_NAME = MOCK_PACKAGE_NAME + ".mock_a11y_service"; private static final String MOCK_CLASS_NAME = MOCK_PACKAGE_NAME + ".mock_a11y_service";
private static final String MOCK_CLASS_NAME2 = MOCK_PACKAGE_NAME + ".mock_a11y_service2";
private static final ComponentName MOCK_COMPONENT_NAME = new ComponentName(MOCK_PACKAGE_NAME, private static final ComponentName MOCK_COMPONENT_NAME = new ComponentName(MOCK_PACKAGE_NAME,
MOCK_CLASS_NAME); MOCK_CLASS_NAME);
@Rule @Rule
@@ -71,7 +62,7 @@ public final class AccessibilityUtilTest {
@Before @Before
public void setUp() { public void setUp() {
mContext = spy(ApplicationProvider.getApplicationContext()); mContext = ApplicationProvider.getApplicationContext();
} }
@Test @Test
@@ -148,37 +139,6 @@ public final class AccessibilityUtilTest {
AccessibilityUtil.AccessibilityServiceFragmentType.TOGGLE); AccessibilityUtil.AccessibilityServiceFragmentType.TOGGLE);
} }
@Test
public void convertKeyFromSettings_shortcutTypeSoftware() {
assertThat(AccessibilityUtil.convertKeyFromSettings(SOFTWARE))
.isEqualTo(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
}
@Test
public void convertKeyFromSettings_shortcutTypeHardware() {
assertThat(AccessibilityUtil.convertKeyFromSettings(HARDWARE))
.isEqualTo(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
}
@Test
public void convertKeyFromSettings_shortcutTypeTripleTap() {
assertThat(AccessibilityUtil.convertKeyFromSettings(TRIPLETAP))
.isEqualTo(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
}
@Test
public void convertKeyFromSettings_shortcutTypeMultiFingersMultiTap() {
assertThat(AccessibilityUtil.convertKeyFromSettings(TWOFINGER_DOUBLETAP))
.isEqualTo(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED);
}
@Test
public void convertKeyFromSettings_shortcutTypeQuickSettings() {
assertThat(AccessibilityUtil.convertKeyFromSettings(QUICK_SETTINGS))
.isEqualTo(Settings.Secure.ACCESSIBILITY_QS_TARGETS);
}
@Test @Test
@EnableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) @EnableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
public void getSoftwareShortcutSummary_returnsSoftwareSummary() { public void getSoftwareShortcutSummary_returnsSoftwareSummary() {

View File

@@ -16,8 +16,6 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -34,11 +32,7 @@ import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import org.junit.Before; import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Answers; import org.mockito.Answers;
import org.mockito.Mock; import org.mockito.Mock;
@@ -83,72 +77,6 @@ public class LaunchAccessibilityActivityPreferenceFragmentTest {
doReturn(mScreen).when(mFragment).getPreferenceScreen(); doReturn(mScreen).when(mFragment).getPreferenceScreen();
} }
@Test
public void getTileTooltipContent_noTileServiceAssigned_returnNull() {
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_EDIT);
assertThat(tileTooltipContent).isNull();
}
@Test
public void getTileTooltipContent_hasOneTileService_guideToEdit_haveMatchString() {
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME,
PLACEHOLDER_TILE_NAME);
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_EDIT);
final CharSequence tileName =
mFragment.loadTileLabel(mContext, mFragment.getTileComponentName());
assertThat(tileTooltipContent.toString()).isEqualTo(
mContext.getString(R.string.accessibility_service_qs_tooltip_content, tileName));
}
@Test
public void getTileTooltipContent_hasOneTileService_guideToDirectUse_haveMatchString() {
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME,
PLACEHOLDER_TILE_NAME);
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
final CharSequence tileName =
mFragment.loadTileLabel(mContext, mFragment.getTileComponentName());
assertThat(tileTooltipContent.toString()).isEqualTo(
mContext.getString(
R.string.accessibility_service_auto_added_qs_tooltip_content, tileName));
}
@Test
public void getTileTooltipContent_hasTwoTileServices_guideToEdit_haveMatchString() {
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME,
PLACEHOLDER_TILE_NAME);
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME2,
PLACEHOLDER_TILE_NAME2);
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_EDIT);
final CharSequence tileName =
mFragment.loadTileLabel(mContext, mFragment.getTileComponentName());
assertThat(tileTooltipContent.toString()).isEqualTo(
mContext.getString(R.string.accessibility_service_qs_tooltip_content, tileName));
}
@Test
public void getTileTooltipContent_hasTwoTileServices_guideToDirectUse_haveMatchString() {
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME,
PLACEHOLDER_TILE_NAME);
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME2,
PLACEHOLDER_TILE_NAME2);
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
final CharSequence tileName =
mFragment.loadTileLabel(mContext, mFragment.getTileComponentName());
assertThat(tileTooltipContent.toString()).isEqualTo(
mContext.getString(
R.string.accessibility_service_auto_added_qs_tooltip_content, tileName));
}
private void setupTileService(String packageName, String name, String tileName) { private void setupTileService(String packageName, String name, String tileName) {
final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE); final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE);
final ResolveInfo info = new ResolveInfo(); final ResolveInfo info = new ResolveInfo();

View File

@@ -43,9 +43,7 @@ import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.internal.accessibility.common.ShortcutConstants; import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment; import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment;
import com.android.settings.widget.SettingsMainSwitchPreference; import com.android.settings.widget.SettingsMainSwitchPreference;
@@ -111,72 +109,6 @@ public class ToggleAccessibilityServicePreferenceFragmentTest {
mShadowAccessibilityManager = Shadow.extract(AccessibilityManager.getInstance(mContext)); mShadowAccessibilityManager = Shadow.extract(AccessibilityManager.getInstance(mContext));
} }
@Test
public void getTileTooltipContent_noTileServiceAssigned_returnNull() {
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_EDIT);
assertThat(tileTooltipContent).isNull();
}
@Test
public void getTileTooltipContent_hasOneTileService_guideToEdit_haveMatchString() {
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME,
PLACEHOLDER_TILE_NAME);
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_EDIT);
final CharSequence tileName =
mFragment.loadTileLabel(mContext, mFragment.getTileComponentName());
assertThat(tileTooltipContent.toString()).isEqualTo(
mContext.getString(R.string.accessibility_service_qs_tooltip_content, tileName));
}
@Test
public void getTileTooltipContent_hasOneTileService_guideToDirectUse_haveMatchString() {
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME,
PLACEHOLDER_TILE_NAME);
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
final CharSequence tileName =
mFragment.loadTileLabel(mContext, mFragment.getTileComponentName());
assertThat(tileTooltipContent.toString()).isEqualTo(
mContext.getString(
R.string.accessibility_service_auto_added_qs_tooltip_content, tileName));
}
@Test
public void getTileTooltipContent_hasTwoTileServices_guideToEdit_haveMatchString() {
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME,
PLACEHOLDER_TILE_NAME);
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME2,
PLACEHOLDER_TILE_NAME2);
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_EDIT);
final CharSequence tileName =
mFragment.loadTileLabel(mContext, mFragment.getTileComponentName());
assertThat(tileTooltipContent.toString()).isEqualTo(
mContext.getString(R.string.accessibility_service_qs_tooltip_content, tileName));
}
@Test
public void getTileTooltipContent_hasTwoTileServices_guideToDirectUse_haveMatchString() {
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME,
PLACEHOLDER_TILE_NAME);
setupTileService(PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME2,
PLACEHOLDER_TILE_NAME2);
final CharSequence tileTooltipContent =
mFragment.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
final CharSequence tileName =
mFragment.loadTileLabel(mContext, mFragment.getTileComponentName());
assertThat(tileTooltipContent.toString()).isEqualTo(
mContext.getString(
R.string.accessibility_service_auto_added_qs_tooltip_content, tileName));
}
@Test @Test
public void getAccessibilityServiceInfo() throws Throwable { public void getAccessibilityServiceInfo() throws Throwable {
final AccessibilityServiceInfo info1 = getFakeAccessibilityServiceInfo( final AccessibilityServiceInfo info1 = getFakeAccessibilityServiceInfo(

View File

@@ -47,7 +47,6 @@ import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowFragment; import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.widget.SettingsMainSwitchPreference; import com.android.settings.widget.SettingsMainSwitchPreference;
@@ -265,11 +264,6 @@ public class ToggleColorInversionPreferenceFragmentTest {
return PLACEHOLDER_COMPONENT_NAME; return PLACEHOLDER_COMPONENT_NAME;
} }
@Override
protected CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
return PLACEHOLDER_TILE_TOOLTIP_CONTENT;
}
@Override @Override
public View getView() { public View getView() {
return mock(View.class); return mock(View.class);

View File

@@ -53,7 +53,6 @@ import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.flags.Flags; import com.android.settings.flags.Flags;
import com.android.settings.testutils.shadow.ShadowAccessibilityManager; import com.android.settings.testutils.shadow.ShadowAccessibilityManager;
import com.android.settings.testutils.shadow.ShadowFragment; import com.android.settings.testutils.shadow.ShadowFragment;
@@ -378,11 +377,6 @@ public class ToggleFeaturePreferenceFragmentTest {
return PLACEHOLDER_TILE_COMPONENT_NAME; return PLACEHOLDER_TILE_COMPONENT_NAME;
} }
@Override
protected CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
return PLACEHOLDER_TILE_TOOLTIP_CONTENT;
}
@Override @Override
public int getPreferenceScreenResId() { public int getPreferenceScreenResId() {
return R.xml.placeholder_prefs; return R.xml.placeholder_prefs;

View File

@@ -35,7 +35,6 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
@@ -47,7 +46,6 @@ import android.database.ContentObserver;
import android.icu.text.CaseMap; import android.icu.text.CaseMap;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.flag.junit.SetFlagsRule;
@@ -66,7 +64,7 @@ import com.android.server.accessibility.Flags;
import com.android.settings.DialogCreatable; import com.android.settings.DialogCreatable;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.testutils.AccessibilityTestUtils; import com.android.settings.testutils.shadow.ShadowAccessibilityManager;
import com.android.settings.testutils.shadow.ShadowDeviceConfig; import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settings.testutils.shadow.ShadowStorageManager; import com.android.settings.testutils.shadow.ShadowStorageManager;
import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUserManager;
@@ -83,6 +81,7 @@ import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows; import org.robolectric.Shadows;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowContentResolver; import org.robolectric.shadows.ShadowContentResolver;
import org.robolectric.shadows.ShadowPackageManager; import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.shadows.ShadowSettings; import org.robolectric.shadows.ShadowSettings;
@@ -92,7 +91,6 @@ import org.robolectric.util.ReflectionHelpers;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set;
/** Tests for {@link ToggleScreenMagnificationPreferenceFragment}. */ /** Tests for {@link ToggleScreenMagnificationPreferenceFragment}. */
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@@ -101,6 +99,7 @@ import java.util.Set;
ShadowStorageManager.class, ShadowStorageManager.class,
ShadowSettings.ShadowSecure.class, ShadowSettings.ShadowSecure.class,
ShadowDeviceConfig.class, ShadowDeviceConfig.class,
ShadowAccessibilityManager.class,
}) })
public class ToggleScreenMagnificationPreferenceFragmentTest { public class ToggleScreenMagnificationPreferenceFragmentTest {
@@ -137,15 +136,15 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
private FragmentController<ToggleScreenMagnificationPreferenceFragment> mFragController; private FragmentController<ToggleScreenMagnificationPreferenceFragment> mFragController;
private Context mContext; private Context mContext;
private AccessibilityManager mAccessibilityManager;
private Resources mSpyResources; private Resources mSpyResources;
private ShadowPackageManager mShadowPackageManager; private ShadowPackageManager mShadowPackageManager;
private ShadowAccessibilityManager mShadowAccessibilityManager;
@Before @Before
public void setUpTestFragment() { public void setUpTestFragment() {
mContext = spy(ApplicationProvider.getApplicationContext()); mContext = spy(ApplicationProvider.getApplicationContext());
mAccessibilityManager = AccessibilityTestUtils.setupMockAccessibilityManager(mContext); mShadowAccessibilityManager = Shadow.extract(
mContext.getSystemService(AccessibilityManager.class));
// Set up the fragment that support window magnification feature // Set up the fragment that support window magnification feature
mSpyResources = spy(mContext.getResources()); mSpyResources = spy(mContext.getResources());
@@ -420,137 +419,6 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
assertThat(shadowContentResolver.getContentObservers(observedUri)).isEmpty(); assertThat(shadowContentResolver.getContentObservers(observedUri)).isEmpty();
} }
@Test
public void hasValueInSettings_putValue_hasValue() {
setMagnificationTripleTapEnabled(/* enabled= */ true);
assertThat(ToggleScreenMagnificationPreferenceFragment.hasMagnificationValuesInSettings(
mContext, TRIPLETAP)).isTrue();
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
public void hasMagnificationValuesInSettings_twoFingerTripleTapIsOn_isTrue() {
Settings.Secure.putInt(
mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, ON);
assertThat(ToggleScreenMagnificationPreferenceFragment.hasMagnificationValuesInSettings(
mContext, TWOFINGER_DOUBLETAP)).isTrue();
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
public void hasMagnificationValuesInSettings_twoFingerTripleTapIsOff_isFalse() {
Settings.Secure.putInt(
mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, OFF);
assertThat(ToggleScreenMagnificationPreferenceFragment.hasMagnificationValuesInSettings(
mContext, TWOFINGER_DOUBLETAP)).isFalse();
}
@Test
public void optInAllValuesToSettings_optInValue_callA11yManager() {
int shortcutTypes =
SOFTWARE | TRIPLETAP | HARDWARE
| QUICK_SETTINGS;
Set<String> shortcutTargets = Set.of(MAGNIFICATION_CONTROLLER_NAME);
ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(mContext,
shortcutTypes);
verify(mAccessibilityManager).enableShortcutsForTargets(
/* enable= */ true, SOFTWARE,
shortcutTargets, UserHandle.myUserId());
verify(mAccessibilityManager).enableShortcutsForTargets(
/* enable= */ true, HARDWARE,
shortcutTargets, UserHandle.myUserId());
verify(mAccessibilityManager).enableShortcutsForTargets(
/* enable= */ true, QUICK_SETTINGS,
shortcutTargets, UserHandle.myUserId());
verify(mAccessibilityManager).enableShortcutsForTargets(
/* enable= */ true, TRIPLETAP,
shortcutTargets, UserHandle.myUserId());
verifyNoMoreInteractions(mAccessibilityManager);
}
@Test
public void optInAllValuesToSettings_software_sizeValueIsNotNull_sizeValueIsNotChanged() {
for (int size : new int[]{FloatingMenuSizePreferenceController.Size.LARGE,
FloatingMenuSizePreferenceController.Size.SMALL}) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size);
ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(
mContext,
SOFTWARE);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
FloatingMenuSizePreferenceController.Size.UNKNOWN)).isEqualTo(
size);
}
}
@Test
public void optInAllValuesToSettings_hardware_sizeValueIsNotChanged() {
for (int size : new int[]{FloatingMenuSizePreferenceController.Size.UNKNOWN,
FloatingMenuSizePreferenceController.Size.LARGE,
FloatingMenuSizePreferenceController.Size.SMALL}) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size);
ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(
mContext,
HARDWARE);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size + 1)).isEqualTo(
size);
}
}
@Test
public void optInAllValuesToSettings_tripletap_sizeValueIsNotChanged() {
for (int size : new int[]{FloatingMenuSizePreferenceController.Size.UNKNOWN,
FloatingMenuSizePreferenceController.Size.LARGE,
FloatingMenuSizePreferenceController.Size.SMALL}) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size);
ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(
mContext,
TRIPLETAP);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size + 1)).isEqualTo(
size);
}
}
@Test
public void optOutAllValuesToSettings_optOutValue_callA11yManager() {
Set<String> shortcutTargets = Set.of(MAGNIFICATION_CONTROLLER_NAME);
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME);
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME);
setMagnificationTripleTapEnabled(/* enabled= */ true);
int shortcutTypes =
SOFTWARE | HARDWARE | TRIPLETAP;
ToggleScreenMagnificationPreferenceFragment.optOutAllMagnificationValuesFromSettings(
mContext, shortcutTypes);
verify(mAccessibilityManager).enableShortcutsForTargets(
/* enable= */ false, SOFTWARE,
shortcutTargets, UserHandle.myUserId());
verify(mAccessibilityManager).enableShortcutsForTargets(
/* enable= */ false, HARDWARE,
shortcutTargets, UserHandle.myUserId());
verify(mAccessibilityManager).enableShortcutsForTargets(
/* enable= */ false, TRIPLETAP,
shortcutTargets, UserHandle.myUserId());
verifyNoMoreInteractions(mAccessibilityManager);
}
@Test @Test
public void updateShortcutPreferenceData_assignDefaultValueToVariable() { public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
@@ -565,8 +433,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() { public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME); mShadowAccessibilityManager.setAccessibilityShortcutTargets(
setMagnificationTripleTapEnabled(/* enabled= */ true); TRIPLETAP | SOFTWARE, List.of(MAGNIFICATION_CONTROLLER_NAME));
mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
mFragController.get().updateShortcutPreferenceData(); mFragController.get().updateShortcutPreferenceData();
@@ -593,8 +461,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
public void updateShortcutPreferenceData_hasTwoFingerTripleTapInSettings_assignToVariable() { public void updateShortcutPreferenceData_hasTwoFingerTripleTapInSettings_assignToVariable() {
Settings.Secure.putInt( mShadowAccessibilityManager.setAccessibilityShortcutTargets(
mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, ON); TWOFINGER_DOUBLETAP, List.of(MAGNIFICATION_CONTROLLER_NAME));
mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
mFragController.get().updateShortcutPreferenceData(); mFragController.get().updateShortcutPreferenceData();
@@ -802,7 +670,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
public void getSummary_magnificationEnabled_returnShortcutOnWithSummary() { public void getSummary_magnificationEnabled_returnShortcutOnWithSummary() {
setMagnificationTripleTapEnabled(true); mShadowAccessibilityManager.setAccessibilityShortcutTargets(
TRIPLETAP, List.of(MAGNIFICATION_CONTROLLER_NAME));
assertThat( assertThat(
ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString()) ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString())
@@ -816,7 +685,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
public void getSummary_magnificationDisabled_returnShortcutOffWithSummary() { public void getSummary_magnificationDisabled_returnShortcutOffWithSummary() {
setMagnificationTripleTapEnabled(false); mShadowAccessibilityManager.setAccessibilityShortcutTargets(
TRIPLETAP, List.of());
assertThat( assertThat(
ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString()) ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString())
@@ -832,8 +702,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
public void getSummary_magnificationGestureEnabled_returnShortcutOnWithSummary() { public void getSummary_magnificationGestureEnabled_returnShortcutOnWithSummary() {
Settings.Secure.putInt( mShadowAccessibilityManager.setAccessibilityShortcutTargets(
mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, ON); TWOFINGER_DOUBLETAP, List.of(MAGNIFICATION_CONTROLLER_NAME));
assertThat( assertThat(
ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString()) ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString())
@@ -848,8 +718,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
public void getSummary_magnificationGestureDisabled_returnShortcutOffWithSummary() { public void getSummary_magnificationGestureDisabled_returnShortcutOffWithSummary() {
Settings.Secure.putInt( mShadowAccessibilityManager.setAccessibilityShortcutTargets(
mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, OFF); TRIPLETAP | TWOFINGER_DOUBLETAP, List.of());
assertThat( assertThat(
ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString()) ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString())
@@ -977,7 +847,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE, Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE,
Flags.FLAG_ENABLE_LOW_VISION_HATS}) Flags.FLAG_ENABLE_LOW_VISION_HATS})
public void getNonIndexableKeys_hasShortcutAndAllFeaturesEnabled_allItemsSearchable() { public void getNonIndexableKeys_hasShortcutAndAllFeaturesEnabled_allItemsSearchable() {
setMagnificationTripleTapEnabled(true); mShadowAccessibilityManager.setAccessibilityShortcutTargets(
TRIPLETAP, List.of(MAGNIFICATION_CONTROLLER_NAME));
setAlwaysOnSupported(true); setAlwaysOnSupported(true);
setJoystickSupported(true); setJoystickSupported(true);
@@ -991,7 +862,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
@EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getNonIndexableKeys_noShortcut_alwaysOnSupported_notSearchable() { public void getNonIndexableKeys_noShortcut_alwaysOnSupported_notSearchable() {
setMagnificationTripleTapEnabled(false); mShadowAccessibilityManager.setAccessibilityShortcutTargets(
TRIPLETAP, List.of());
setAlwaysOnSupported(true); setAlwaysOnSupported(true);
final List<String> niks = ToggleScreenMagnificationPreferenceFragment final List<String> niks = ToggleScreenMagnificationPreferenceFragment
@@ -1004,7 +876,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
@EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getNonIndexableKeys_hasShortcut_alwaysOnNotSupported_notSearchable() { public void getNonIndexableKeys_hasShortcut_alwaysOnNotSupported_notSearchable() {
setMagnificationTripleTapEnabled(true); mShadowAccessibilityManager.setAccessibilityShortcutTargets(
TRIPLETAP, List.of(MAGNIFICATION_CONTROLLER_NAME));
setAlwaysOnSupported(false); setAlwaysOnSupported(false);
final List<String> niks = ToggleScreenMagnificationPreferenceFragment final List<String> niks = ToggleScreenMagnificationPreferenceFragment
@@ -1056,11 +929,6 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
PreferredShortcuts.saveUserShortcutType(context, shortcut); PreferredShortcuts.saveUserShortcutType(context, shortcut);
} }
private void setMagnificationTripleTapEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(), TRIPLETAP_SHORTCUT_KEY,
enabled ? ON : OFF);
}
private void setKeyMagnificationMode(@MagnificationMode int mode) { private void setKeyMagnificationMode(@MagnificationMode int mode) {
MagnificationCapabilities.setCapabilities(mContext, mode); MagnificationCapabilities.setCapabilities(mContext, mode);
} }

View File

@@ -28,6 +28,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.flag.junit.SetFlagsRule;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -551,6 +552,104 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
assertThat(button.getVisibility()).isEqualTo(View.GONE); assertThat(button.getVisibility()).isEqualTo(View.GONE);
} }
@Test
@EnableFlags(Flags.FLAG_ENABLE_BATTERY_LEVEL_DISPLAY)
public void enableBatt_budsDisconnected_batteryLevelShown() {
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE))
.thenReturn(BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET.getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
.thenReturn(String.valueOf(false).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_LEFT).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_RIGHT).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_MAIN).getBytes());
when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
.thenReturn("<BATT>true</BATT>".getBytes());
when(mCachedDevice.isConnected()).thenReturn(false);
mController.refresh();
assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_left), BATTERY_LEVEL_LEFT);
assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_right), BATTERY_LEVEL_RIGHT);
assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_middle), BATTERY_LEVEL_MAIN);
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_BATTERY_LEVEL_DISPLAY)
public void disableBatt_budsDisconnected_batteryLevelNotShown() {
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE))
.thenReturn(BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET.getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
.thenReturn(String.valueOf(false).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_LEFT).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_RIGHT).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_MAIN).getBytes());
when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
.thenReturn("<BATT>true</BATT>".getBytes());
when(mCachedDevice.isConnected()).thenReturn(false);
mController.refresh();
assertThat(mLayoutPreference.findViewById(R.id.layout_left).getVisibility())
.isNotEqualTo(View.VISIBLE);
assertThat(mLayoutPreference.findViewById(R.id.layout_right).getVisibility())
.isNotEqualTo(View.VISIBLE);
assertThat(
mLayoutPreference
.findViewById(R.id.layout_middle)
.findViewById(R.id.bt_battery_summary)
.getVisibility())
.isNotEqualTo(View.VISIBLE);
assertThat(
mLayoutPreference
.findViewById(R.id.layout_middle)
.findViewById(R.id.bt_battery_icon)
.getVisibility())
.isNotEqualTo(View.VISIBLE);
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_BATTERY_LEVEL_DISPLAY)
public void disableFastPairBatt_budsDisconnected_batteryLevelNotShown() {
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE))
.thenReturn(BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET.getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
.thenReturn(String.valueOf(false).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_LEFT).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_RIGHT).getBytes());
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY))
.thenReturn(String.valueOf(BATTERY_LEVEL_MAIN).getBytes());
when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
.thenReturn("<BATT>false</BATT>".getBytes());
when(mCachedDevice.isConnected()).thenReturn(false);
mController.refresh();
assertThat(mLayoutPreference.findViewById(R.id.layout_left).getVisibility())
.isNotEqualTo(View.VISIBLE);
assertThat(mLayoutPreference.findViewById(R.id.layout_right).getVisibility())
.isNotEqualTo(View.VISIBLE);
assertThat(
mLayoutPreference
.findViewById(R.id.layout_middle)
.findViewById(R.id.bt_battery_summary)
.getVisibility())
.isNotEqualTo(View.VISIBLE);
assertThat(
mLayoutPreference
.findViewById(R.id.layout_middle)
.findViewById(R.id.bt_battery_icon)
.getVisibility())
.isNotEqualTo(View.VISIBLE);
}
private void assertBatteryPredictionVisible(LinearLayout linearLayout, int visible) { private void assertBatteryPredictionVisible(LinearLayout linearLayout, int visible) {
final TextView textView = linearLayout.findViewById(R.id.bt_battery_prediction); final TextView textView = linearLayout.findViewById(R.id.bt_battery_prediction);
assertThat(textView.getVisibility()).isEqualTo(visible); assertThat(textView.getVisibility()).isEqualTo(visible);

View File

@@ -117,8 +117,6 @@ import java.util.concurrent.Executor;
}) })
public class AudioSharingDevicePreferenceControllerTest { public class AudioSharingDevicePreferenceControllerTest {
private static final String KEY = "audio_sharing_device_list"; 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"; private static final String TEST_DEVICE_NAME = "test";
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@@ -151,7 +149,6 @@ public class AudioSharingDevicePreferenceControllerTest {
private Lifecycle mLifecycle; private Lifecycle mLifecycle;
private LifecycleOwner mLifecycleOwner; private LifecycleOwner mLifecycleOwner;
private PreferenceCategory mPreferenceGroup; private PreferenceCategory mPreferenceGroup;
private Preference mAudioSharingPreference;
private FakeFeatureFactory mFeatureFactory; private FakeFeatureFactory mFeatureFactory;
private AudioManager mAudioManager; private AudioManager mAudioManager;
@@ -189,10 +186,6 @@ public class AudioSharingDevicePreferenceControllerTest {
when(mScreen.getContext()).thenReturn(mContext); when(mScreen.getContext()).thenReturn(mContext);
mPreferenceGroup = spy(new PreferenceCategory(mContext)); mPreferenceGroup = spy(new PreferenceCategory(mContext));
doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager(); doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager();
mAudioSharingPreference = new Preference(mContext);
mPreferenceGroup.addPreference(mAudioSharingPreference);
when(mPreferenceGroup.findPreference(KEY_AUDIO_SHARING_SETTINGS))
.thenReturn(mAudioSharingPreference);
when(mScreen.findPreference(KEY)).thenReturn(mPreferenceGroup); when(mScreen.findPreference(KEY)).thenReturn(mPreferenceGroup);
mController = new AudioSharingDevicePreferenceController(mContext); mController = new AudioSharingDevicePreferenceController(mContext);
mController.init(mFragment); mController.init(mFragment);
@@ -260,7 +253,6 @@ public class AudioSharingDevicePreferenceControllerTest {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
assertThat(mPreferenceGroup.isVisible()).isFalse(); assertThat(mPreferenceGroup.isVisible()).isFalse();
assertThat(mAudioSharingPreference.isVisible()).isFalse();
verify(mBluetoothDeviceUpdater, never()).forceUpdate(); verify(mBluetoothDeviceUpdater, never()).forceUpdate();
} }
@@ -269,7 +261,6 @@ public class AudioSharingDevicePreferenceControllerTest {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
assertThat(mPreferenceGroup.isVisible()).isFalse(); assertThat(mPreferenceGroup.isVisible()).isFalse();
assertThat(mAudioSharingPreference.isVisible()).isFalse();
verify(mBluetoothDeviceUpdater).setPrefContext(mContext); verify(mBluetoothDeviceUpdater).setPrefContext(mContext);
verify(mBluetoothDeviceUpdater).forceUpdate(); verify(mBluetoothDeviceUpdater).forceUpdate();
} }
@@ -299,8 +290,7 @@ public class AudioSharingDevicePreferenceControllerTest {
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreferenceGroup.isVisible()).isTrue(); assertThat(mPreferenceGroup.isVisible()).isTrue();
assertThat(mAudioSharingPreference.isVisible()).isTrue(); assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1);
assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(2);
} }
@Test @Test
@@ -312,8 +302,7 @@ public class AudioSharingDevicePreferenceControllerTest {
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreferenceGroup.isVisible()).isFalse(); assertThat(mPreferenceGroup.isVisible()).isFalse();
assertThat(mAudioSharingPreference.isVisible()).isFalse(); assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(0);
assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1);
} }
@Test @Test

View File

@@ -25,8 +25,10 @@ import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf; import static org.robolectric.Shadows.shadowOf;
@@ -77,7 +79,8 @@ import org.robolectric.shadow.api.Shadow;
ShadowThreadUtils.class ShadowThreadUtils.class
}) })
public class AudioSharingPreferenceControllerTest { public class AudioSharingPreferenceControllerTest {
private static final String PREF_KEY = "audio_sharing_settings"; private static final String PREF_KEY1 = "audio_sharing_settings";
private static final String PREF_KEY2 = "connected_device_audio_sharing_settings";
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -110,9 +113,6 @@ public class AudioSharingPreferenceControllerTest {
when(localBluetoothManager.getEventManager()).thenReturn(mBtEventManager); when(localBluetoothManager.getEventManager()).thenReturn(mBtEventManager);
when(localBluetoothManager.getProfileManager()).thenReturn(mLocalBtProfileManager); when(localBluetoothManager.getProfileManager()).thenReturn(mLocalBtProfileManager);
when(mLocalBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast); when(mLocalBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
mController = new AudioSharingPreferenceController(mContext, PREF_KEY);
mPreference = spy(new Preference(mContext));
when(mScreen.findPreference(PREF_KEY)).thenReturn(mPreference);
} }
@After @After
@@ -124,6 +124,7 @@ public class AudioSharingPreferenceControllerTest {
@Test @Test
public void onStart_flagOn_registerCallback() { public void onStart_flagOn_registerCallback() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
setupControllerWithKey(PREF_KEY1);
mController.onStart(mLifecycleOwner); mController.onStart(mLifecycleOwner);
verify(mBtEventManager).registerCallback(mController); verify(mBtEventManager).registerCallback(mController);
verify(mBroadcast).registerServiceCallBack(any(), any(BluetoothLeBroadcast.Callback.class)); verify(mBroadcast).registerServiceCallBack(any(), any(BluetoothLeBroadcast.Callback.class));
@@ -132,6 +133,7 @@ public class AudioSharingPreferenceControllerTest {
@Test @Test
public void onStart_flagOff_skipRegisterCallback() { public void onStart_flagOff_skipRegisterCallback() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
setupControllerWithKey(PREF_KEY1);
mController.onStart(mLifecycleOwner); mController.onStart(mLifecycleOwner);
verify(mBtEventManager, never()).registerCallback(mController); verify(mBtEventManager, never()).registerCallback(mController);
verify(mBroadcast, never()) verify(mBroadcast, never())
@@ -141,6 +143,7 @@ public class AudioSharingPreferenceControllerTest {
@Test @Test
public void onStop_flagOn_unregisterCallback() { public void onStop_flagOn_unregisterCallback() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
setupControllerWithKey(PREF_KEY1);
mController.onStop(mLifecycleOwner); mController.onStop(mLifecycleOwner);
verify(mBtEventManager).unregisterCallback(mController); verify(mBtEventManager).unregisterCallback(mController);
verify(mBroadcast).unregisterServiceCallBack(any(BluetoothLeBroadcast.Callback.class)); verify(mBroadcast).unregisterServiceCallBack(any(BluetoothLeBroadcast.Callback.class));
@@ -149,6 +152,7 @@ public class AudioSharingPreferenceControllerTest {
@Test @Test
public void onStop_flagOff_skipUnregisterCallback() { public void onStop_flagOff_skipUnregisterCallback() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
setupControllerWithKey(PREF_KEY1);
mController.onStop(mLifecycleOwner); mController.onStop(mLifecycleOwner);
verify(mBtEventManager, never()).unregisterCallback(mController); verify(mBtEventManager, never()).unregisterCallback(mController);
verify(mBroadcast, never()) verify(mBroadcast, never())
@@ -158,65 +162,147 @@ public class AudioSharingPreferenceControllerTest {
@Test @Test
public void getAvailabilityStatus_flagOn() { public void getAvailabilityStatus_flagOn() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
setupControllerWithKey(PREF_KEY1);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
} }
@Test @Test
public void getAvailabilityStatus_flagOff() { public void getAvailabilityStatus_flagOff() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
setupControllerWithKey(PREF_KEY1);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
} }
@Test @Test
public void getSummary_broadcastOn() { public void getSummary_connectionPreference_broadcastOn() {
when(mBroadcast.isEnabled(any())).thenReturn(true); when(mBroadcast.isEnabled(any())).thenReturn(true);
setupControllerWithKey(PREF_KEY1);
assertThat(mController.getSummary().toString()) assertThat(mController.getSummary().toString())
.isEqualTo(mContext.getString(R.string.audio_sharing_summary_on)); .isEqualTo(mContext.getString(R.string.audio_sharing_summary_on));
} }
@Test @Test
public void getSummary_broadcastOff() { public void getSummary_connectionPreference_broadcastOff() {
when(mBroadcast.isEnabled(any())).thenReturn(false); when(mBroadcast.isEnabled(any())).thenReturn(false);
setupControllerWithKey(PREF_KEY1);
assertThat(mController.getSummary().toString()) assertThat(mController.getSummary().toString())
.isEqualTo(mContext.getString(R.string.audio_sharing_summary_off)); .isEqualTo(mContext.getString(R.string.audio_sharing_summary_off));
} }
@Test
public void getSummary_connectedDevices_broadcastOn() {
when(mBroadcast.isEnabled(any())).thenReturn(true);
setupControllerWithKey(PREF_KEY2);
assertThat(mController.getSummary().toString()).isEmpty();
}
@Test
public void getSummary_connectedDevices_broadcastOff() {
when(mBroadcast.isEnabled(any())).thenReturn(false);
setupControllerWithKey(PREF_KEY2);
assertThat(mController.getSummary().toString()).isEmpty();
}
@Test @Test
public void onBluetoothStateChanged_refreshSummary() { public void onBluetoothStateChanged_refreshSummary() {
setupControllerWithKey(PREF_KEY1);
mController.updateState(mPreference);
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString())
.isEqualTo(mContext.getString(R.string.audio_sharing_summary_off));
assertThat(mPreference.isVisible()).isTrue();
when(mBroadcast.isEnabled(any())).thenReturn(true); when(mBroadcast.isEnabled(any())).thenReturn(true);
mController.onBluetoothStateChanged(STATE_ON); mController.onBluetoothStateChanged(STATE_ON);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()) assertThat(mPreference.getSummary().toString())
.isEqualTo(mContext.getString(R.string.audio_sharing_summary_on)); .isEqualTo(mContext.getString(R.string.audio_sharing_summary_on));
assertThat(mPreference.isVisible()).isTrue();
when(mBroadcast.isEnabled(any())).thenReturn(false); when(mBroadcast.isEnabled(any())).thenReturn(false);
mController.onBluetoothStateChanged(STATE_OFF); mController.onBluetoothStateChanged(STATE_OFF);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()) assertThat(mPreference.getSummary().toString())
.isEqualTo(mContext.getString(R.string.audio_sharing_summary_off)); .isEqualTo(mContext.getString(R.string.audio_sharing_summary_off));
assertThat(mPreference.isVisible()).isTrue();
}
@Test
public void onBluetoothStateChanged_refreshVisibility() {
setupControllerWithKey(PREF_KEY2);
mController.updateState(mPreference);
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
assertThat(mPreference.isVisible()).isFalse();
when(mBroadcast.isEnabled(any())).thenReturn(true);
mController.onBluetoothStateChanged(STATE_ON);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
assertThat(mPreference.isVisible()).isTrue();
when(mBroadcast.isEnabled(any())).thenReturn(false);
mController.onBluetoothStateChanged(STATE_OFF);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
assertThat(mPreference.isVisible()).isFalse();
} }
@Test @Test
public void testBluetoothLeBroadcastCallbacks_refreshSummary() { public void testBluetoothLeBroadcastCallbacks_refreshSummary() {
setupControllerWithKey(PREF_KEY1);
mController.updateState(mPreference);
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString())
.isEqualTo(mContext.getString(R.string.audio_sharing_summary_off));
assertThat(mPreference.isVisible()).isTrue();
when(mBroadcast.isEnabled(any())).thenReturn(true); when(mBroadcast.isEnabled(any())).thenReturn(true);
mController.mBroadcastCallback.onBroadcastStarted(/* reason= */ 1, /* broadcastId= */ 1); mController.mBroadcastCallback.onBroadcastStarted(/* reason= */ 1, /* broadcastId= */ 1);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()) assertThat(mPreference.getSummary().toString())
.isEqualTo(mContext.getString(R.string.audio_sharing_summary_on)); .isEqualTo(mContext.getString(R.string.audio_sharing_summary_on));
assertThat(mPreference.isVisible()).isTrue();
when(mBroadcast.isEnabled(any())).thenReturn(false); when(mBroadcast.isEnabled(any())).thenReturn(false);
mController.mBroadcastCallback.onBroadcastStopped(/* reason= */ 1, /* broadcastId= */ 1); mController.mBroadcastCallback.onBroadcastStopped(/* reason= */ 1, /* broadcastId= */ 1);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()) assertThat(mPreference.getSummary().toString())
.isEqualTo(mContext.getString(R.string.audio_sharing_summary_off)); .isEqualTo(mContext.getString(R.string.audio_sharing_summary_off));
assertThat(mPreference.isVisible()).isTrue();
}
@Test
public void testBluetoothLeBroadcastCallbacks_refreshVisibility() {
setupControllerWithKey(PREF_KEY2);
mController.updateState(mPreference);
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
assertThat(mPreference.isVisible()).isFalse();
when(mBroadcast.isEnabled(any())).thenReturn(true);
mController.mBroadcastCallback.onBroadcastStarted(/* reason= */ 1, /* broadcastId= */ 1);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
assertThat(mPreference.isVisible()).isTrue();
when(mBroadcast.isEnabled(any())).thenReturn(false);
mController.mBroadcastCallback.onBroadcastStopped(/* reason= */ 1, /* broadcastId= */ 1);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.getSummary().toString()).isEmpty();
assertThat(mPreference.isVisible()).isFalse();
} }
@Test @Test
public void testBluetoothLeBroadcastCallbacks_doNothing() { public void testBluetoothLeBroadcastCallbacks_doNothing() {
setupControllerWithKey(PREF_KEY1);
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
verify(mPreference).setVisible(anyBoolean());
mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata);
verify(mPreference, never()).setSummary(any()); verify(mPreference, never()).setSummary(any());
@@ -233,5 +319,34 @@ public class AudioSharingPreferenceControllerTest {
mController.mBroadcastCallback.onBroadcastUpdateFailed( mController.mBroadcastCallback.onBroadcastUpdateFailed(
/* reason= */ 1, /* broadcastId= */ 1); /* reason= */ 1, /* broadcastId= */ 1);
verify(mPreference, never()).setSummary(any()); verify(mPreference, never()).setSummary(any());
verify(mPreference).setVisible(anyBoolean());
setupControllerWithKey(PREF_KEY2);
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
verify(mPreference, times(3)).setVisible(anyBoolean());
mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata);
verify(mPreference, never()).setSummary(any());
mController.mBroadcastCallback.onBroadcastUpdated(/* reason= */ 1, /* broadcastId= */ 1);
verify(mPreference, never()).setSummary(any());
mController.mBroadcastCallback.onPlaybackStarted(/* reason= */ 1, /* broadcastId= */ 1);
verify(mPreference, never()).setSummary(any());
mController.mBroadcastCallback.onPlaybackStopped(/* reason= */ 1, /* broadcastId= */ 1);
verify(mPreference, never()).setSummary(any());
mController.mBroadcastCallback.onBroadcastStartFailed(/* reason= */ 1);
verify(mPreference, never()).setSummary(any());
mController.mBroadcastCallback.onBroadcastStopFailed(/* reason= */ 1);
verify(mPreference, never()).setSummary(any());
mController.mBroadcastCallback.onBroadcastUpdateFailed(
/* reason= */ 1, /* broadcastId= */ 1);
verify(mPreference, never()).setSummary(any());
verify(mPreference, times(3)).setVisible(anyBoolean());
}
private void setupControllerWithKey(String preferenceKey) {
mController = new AudioSharingPreferenceController(mContext, preferenceKey);
mPreference = spy(new Preference(mContext));
when(mScreen.findPreference(preferenceKey)).thenReturn(mPreference);
} }
} }

View File

@@ -515,23 +515,14 @@ public class AudioSharingSwitchBarControllerTest {
} }
@Test @Test
public void onBroadcastMetadataChanged_hasLocalSource_noDialog() { public void onBroadcastMetadataChanged_notTriggeredHere_noDialog() {
FeatureFlagUtils.setEnabled( FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
when(mBtnView.isEnabled()).thenReturn(true); when(mBtnView.isEnabled()).thenReturn(true);
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1)); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
when(mState.getBroadcastId()).thenReturn(1); when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
when(mBroadcast.getLatestBroadcastId()).thenReturn(1);
when(mAssistant.getAllSources(mDevice2)).thenReturn(ImmutableList.of(mState));
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
doNothing().when(mBroadcast).startPrivateBroadcast(); doNothing().when(mBroadcast).startPrivateBroadcast();
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
shadowOf(Looper.getMainLooper()).idle();
verify(mBroadcast).startPrivateBroadcast();
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
AudioSharingProgressDialogFragment.class.getName());
mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
@@ -540,7 +531,7 @@ public class AudioSharingSwitchBarControllerTest {
verify(mFeatureFactory.metricsFeatureProvider, never()) verify(mFeatureFactory.metricsFeatureProvider, never())
.action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING)); .action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING));
childFragments = mParentFragment.getChildFragmentManager().getFragments(); List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
// No audio sharing dialog. // No audio sharing dialog.
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).doesNotContain( assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).doesNotContain(
AudioSharingDialogFragment.class.getName()); AudioSharingDialogFragment.class.getName());
@@ -613,7 +604,7 @@ public class AudioSharingSwitchBarControllerTest {
} }
@Test @Test
public void onBroadcastMetadataChanged_oneActiveOnConnected_showJoinAudioSharingDialog() { public void onBroadcastMetadataChanged_oneActiveOneConnected_showJoinAudioSharingDialog() {
FeatureFlagUtils.setEnabled( FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
when(mBtnView.isEnabled()).thenReturn(true); when(mBtnView.isEnabled()).thenReturn(true);
@@ -681,7 +672,7 @@ public class AudioSharingSwitchBarControllerTest {
} }
@Test @Test
public void onBroadcastMetadataChanged_oneActiveOnConnected_clickShareBtnOnDialog_addSource() { public void onBroadcastMetadataChanged_oneActiveOneConnected_clickShareBtnOnDialog_addSource() {
FeatureFlagUtils.setEnabled( FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
when(mBtnView.isEnabled()).thenReturn(true); when(mBtnView.isEnabled()).thenReturn(true);
@@ -722,7 +713,7 @@ public class AudioSharingSwitchBarControllerTest {
} }
@Test @Test
public void onBroadcastMetadataChanged_oneActiveOnConnected_clickCancelBtnOnDialog_doNothing() { public void onBroadcastMetadataChanged_oneActiveOneConnected_clickCancelBtnOnDlg_doNothing() {
FeatureFlagUtils.setEnabled( FeatureFlagUtils.setEnabled(
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
when(mBtnView.isEnabled()).thenReturn(true); when(mBtnView.isEnabled()).thenReturn(true);

View File

@@ -29,7 +29,9 @@ import static org.mockito.Mockito.verify;
import android.app.Activity; import android.app.Activity;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.app.supervision.SupervisionManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.os.Process; import android.os.Process;
import android.os.UserHandle; import android.os.UserHandle;
@@ -49,14 +51,19 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric; import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows; import org.robolectric.Shadows;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow; import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowContextImpl;
import org.robolectric.shadows.ShadowProcess; import org.robolectric.shadows.ShadowProcess;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@@ -66,19 +73,24 @@ import org.robolectric.shadows.ShadowProcess;
ShadowActivity.class ShadowActivity.class
}) })
public class ActionDisabledByAdminDialogHelperTest { public class ActionDisabledByAdminDialogHelperTest {
@Rule public final MockitoRule mMocks = MockitoJUnit.rule();
private static final ComponentName ADMIN_COMPONENT = private static final ComponentName ADMIN_COMPONENT =
new ComponentName("some.package.name", "some.package.name.SomeClass"); new ComponentName("some.package.name", "some.package.name.SomeClass");
private static final int USER_ID = 123; private static final int USER_ID = 123;
private static final EnforcedAdmin ENFORCED_ADMIN = private static final EnforcedAdmin ENFORCED_ADMIN =
new EnforcedAdmin(ADMIN_COMPONENT, new UserHandle(USER_ID)); new EnforcedAdmin(ADMIN_COMPONENT, new UserHandle(USER_ID));
@Mock private SupervisionManager mSupervisionManager;
private ActionDisabledByAdminDialogHelper mHelper; private ActionDisabledByAdminDialogHelper mHelper;
private Activity mActivity; private Activity mActivity;
private org.robolectric.shadows.ShadowActivity mActivityShadow;
@Before @Before
public void setUp() { public void setUp() {
mActivity = Robolectric.setupActivity(CustomActivity.class); mActivity = Robolectric.setupActivity(CustomActivity.class);
mActivityShadow = Shadow.extract(mActivity); ShadowContextImpl shadowContext = Shadow.extract(mActivity.getBaseContext());
shadowContext.setSystemService(Context.SUPERVISION_SERVICE, mSupervisionManager);
mHelper = new ActionDisabledByAdminDialogHelper(mActivity); mHelper = new ActionDisabledByAdminDialogHelper(mActivity);
} }

View File

@@ -26,6 +26,7 @@ import android.content.Context;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType; import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implementation;
@@ -96,8 +97,11 @@ public class ShadowAccessibilityManager extends org.robolectric.shadows.ShadowAc
/** /**
* Used by tests to easily write directly to a shortcut targets value * Used by tests to easily write directly to a shortcut targets value
*/ */
public void setAccessibilityShortcutTargets( public void setAccessibilityShortcutTargets(int shortcutTypes, List<String> targets) {
@UserShortcutType int shortcutType, List<String> targets) { for (int type : ShortcutConstants.USER_SHORTCUT_TYPES) {
mShortcutTargets.put(shortcutType, targets); if ((type & shortcutTypes) == type) {
mShortcutTargets.put(type, List.copyOf(targets));
}
}
} }
} }

View File

@@ -1,114 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accessibility;
import static android.view.flags.Flags.FLAG_ENABLE_VECTOR_CURSOR_A11Y_SETTINGS;
import static com.android.settings.accessibility.LargePointerIconPreferenceController.OFF;
import static com.android.settings.accessibility.LargePointerIconPreferenceController.ON;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
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 android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class LargePointerIconPreferenceControllerTest {
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
private static final int UNKNOWN = -1;
private Context mContext;
private SwitchPreference mPreference;
private LargePointerIconPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mPreference = new SwitchPreference(mContext);
mController = new LargePointerIconPreferenceController(mContext, "large_pointer");
}
@Test
@RequiresFlagsDisabled(FLAG_ENABLE_VECTOR_CURSOR_A11Y_SETTINGS)
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
@RequiresFlagsEnabled(FLAG_ENABLE_VECTOR_CURSOR_A11Y_SETTINGS)
public void getAvailabilityStatus_shouldReturnConditionallyUnavailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
@Test
public void isChecked_enabledLargePointer_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, ON);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void isChecked_disabledLargePointer_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, OFF);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_enabled_shouldEnableLargePointer() {
mController.setChecked(true);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, UNKNOWN)).isEqualTo(ON);
}
@Test
public void setChecked_disabled_shouldDisableLargePointer() {
mController.setChecked(false);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, UNKNOWN)).isEqualTo(OFF);
}
}

View File

@@ -32,12 +32,17 @@ import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.UserManager; import android.os.UserManager;
import android.os.storage.StorageManager; import android.os.storage.StorageManager;
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.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.flags.Flags;
import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.security.screenlock.ScreenLockSettings; import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
@@ -46,6 +51,7 @@ import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@@ -58,6 +64,8 @@ public class ScreenLockPreferenceDetailsUtilsTest {
private static final int SOURCE_METRICS_CATEGORY = 10; private static final int SOURCE_METRICS_CATEGORY = 10;
private static final int USER_ID = 11; private static final int USER_ID = 11;
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock @Mock
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
@Mock @Mock
@@ -267,14 +275,32 @@ public class ScreenLockPreferenceDetailsUtilsTest {
} }
@Test @Test
public void shouldShowGearMenu_patternIsSecure_shouldReturnTrue() { @RequiresFlagsEnabled(Flags.FLAG_BIOMETRIC_ONBOARDING_EDUCATION)
public void shouldShowGearMenu_patternIsSecure_flagOn_shouldReturnFalse() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isFalse();
}
@Test
@RequiresFlagsDisabled(Flags.FLAG_BIOMETRIC_ONBOARDING_EDUCATION)
public void shouldShowGearMenu_patternIsNotSecure_flagOff_shouldReturnFalse() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isFalse();
}
@Test
@RequiresFlagsDisabled(Flags.FLAG_BIOMETRIC_ONBOARDING_EDUCATION)
public void shouldShowGearMenu_patternIsSecure_flagOff_shouldReturnTrue() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isTrue(); assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isTrue();
} }
@Test @Test
public void shouldShowGearMenu_patternIsNotSecure_shouldReturnFalse() { @RequiresFlagsEnabled(Flags.FLAG_BIOMETRIC_ONBOARDING_EDUCATION)
public void shouldShowGearMenu_patternIsNotSecure_flagOn_shouldReturnFalse() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false); when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isFalse(); assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isFalse();