Loading core/java/com/android/internal/accessibility/common/ShortcutConstants.java 0 → 100644 +123 −0 Original line number Diff line number Diff line /* * 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.internal.accessibility.common; import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Collection of common constants for accessibility shortcut. */ public final class ShortcutConstants { private ShortcutConstants() {} public static final char SERVICES_SEPARATOR = ':'; public static final float DISABLED_ALPHA = 0.5f; public static final float ENABLED_ALPHA = 1.0f; /** * Annotation for different user shortcut type UI type. * * {@code DEFAULT} for displaying default value. * {@code SOFTWARE} for displaying specifying the accessibility services or features which * choose accessibility button in the navigation bar as preferred shortcut. * {@code HARDWARE} for displaying specifying the accessibility services or features which * choose accessibility shortcut as preferred shortcut. * {@code TRIPLETAP} for displaying specifying magnification to be toggled via quickly * tapping screen 3 times as preferred shortcut. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ UserShortcutType.DEFAULT, UserShortcutType.SOFTWARE, UserShortcutType.HARDWARE, UserShortcutType.TRIPLETAP, }) public @interface UserShortcutType { int DEFAULT = 0; int SOFTWARE = 1; // 1 << 0 int HARDWARE = 2; // 1 << 1 int TRIPLETAP = 4; // 1 << 2 } /** * Annotation for different accessibilityService fragment UI type. * * {@code LEGACY} for displaying appearance aligned with sdk version Q accessibility service * page, but only hardware shortcut allowed and under service in version Q or early. * {@code INVISIBLE} for displaying appearance without switch bar. * {@code INTUITIVE} for displaying appearance with version R accessibility design. * {@code BOUNCE} for displaying appearance with pop-up action. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ AccessibilityServiceFragmentType.LEGACY, AccessibilityServiceFragmentType.INVISIBLE, AccessibilityServiceFragmentType.INTUITIVE, AccessibilityServiceFragmentType.BOUNCE, }) public @interface AccessibilityServiceFragmentType { int LEGACY = 0; int INVISIBLE = 1; int INTUITIVE = 2; int BOUNCE = 3; } /** * Annotation for different shortcut menu mode. * * {@code LAUNCH} for clicking list item to trigger the service callback. * {@code EDIT} for clicking list item and save button to disable the service. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ ShortcutMenuMode.LAUNCH, ShortcutMenuMode.EDIT, }) public @interface ShortcutMenuMode { int LAUNCH = 0; int EDIT = 1; } /** * Annotation for align the element index of white listing feature * {@code WHITE_LISTING_FEATURES}. * * {@code COMPONENT_ID} is to get the service component name. * {@code LABEL_ID} is to get the service label text. * {@code ICON_ID} is to get the service icon. * {@code FRAGMENT_TYPE} is to get the service fragment type. * {@code SETTINGS_KEY} is to get the service settings key. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ WhiteListingFeatureElementIndex.COMPONENT_ID, WhiteListingFeatureElementIndex.LABEL_ID, WhiteListingFeatureElementIndex.ICON_ID, WhiteListingFeatureElementIndex.FRAGMENT_TYPE, WhiteListingFeatureElementIndex.SETTINGS_KEY, }) public @interface WhiteListingFeatureElementIndex { int COMPONENT_ID = 0; int LABEL_ID = 1; int ICON_ID = 2; int FRAGMENT_TYPE = 3; int SETTINGS_KEY = 4; } } core/java/com/android/internal/accessibility/util/AccessibilityUtils.java 0 → 100644 +131 −0 Original line number Diff line number Diff line /* * 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.internal.accessibility.util; import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityServiceFragmentType; import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR; import android.accessibilityservice.AccessibilityServiceInfo; import android.content.ComponentName; import android.content.Context; import android.os.Build; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.ArraySet; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Collection of utilities for accessibility service. */ public final class AccessibilityUtils { private AccessibilityUtils() {} /** * Returns the set of enabled accessibility services for userId. If there are no * services, it returns the unmodifiable {@link Collections#emptySet()}. */ public static Set<ComponentName> getEnabledServicesFromSettings(Context context, int userId) { final String enabledServicesSetting = Settings.Secure.getStringForUser( context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userId); if (TextUtils.isEmpty(enabledServicesSetting)) { return Collections.emptySet(); } final Set<ComponentName> enabledServices = new HashSet<>(); final TextUtils.StringSplitter colonSplitter = new TextUtils.SimpleStringSplitter(SERVICES_SEPARATOR); colonSplitter.setString(enabledServicesSetting); for (String componentNameString : colonSplitter) { final ComponentName enabledService = ComponentName.unflattenFromString( componentNameString); if (enabledService != null) { enabledServices.add(enabledService); } } return enabledServices; } /** * Changes an accessibility component's state. */ public static void setAccessibilityServiceState(Context context, ComponentName componentName, boolean enabled) { setAccessibilityServiceState(context, componentName, enabled, UserHandle.myUserId()); } /** * Changes an accessibility component's state for {@param userId}. */ public static void setAccessibilityServiceState(Context context, ComponentName componentName, boolean enabled, int userId) { Set<ComponentName> enabledServices = getEnabledServicesFromSettings( context, userId); if (enabledServices.isEmpty()) { enabledServices = new ArraySet<>(/* capacity= */ 1); } if (enabled) { enabledServices.add(componentName); } else { enabledServices.remove(componentName); } final StringBuilder enabledServicesBuilder = new StringBuilder(); for (ComponentName enabledService : enabledServices) { enabledServicesBuilder.append(enabledService.flattenToString()); enabledServicesBuilder.append( SERVICES_SEPARATOR); } final int enabledServicesBuilderLength = enabledServicesBuilder.length(); if (enabledServicesBuilderLength > 0) { enabledServicesBuilder.deleteCharAt(enabledServicesBuilderLength - 1); } Settings.Secure.putStringForUser(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServicesBuilder.toString(), userId); } /** * Gets the corresponding fragment type of a given accessibility service. * * @param accessibilityServiceInfo The accessibilityService's info. * @return int from {@link AccessibilityServiceFragmentType}. */ public static @AccessibilityServiceFragmentType int getAccessibilityServiceFragmentType( AccessibilityServiceInfo accessibilityServiceInfo) { final int targetSdk = accessibilityServiceInfo.getResolveInfo() .serviceInfo.applicationInfo.targetSdkVersion; final boolean requestA11yButton = (accessibilityServiceInfo.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0; if (targetSdk <= Build.VERSION_CODES.Q) { return AccessibilityServiceFragmentType.LEGACY; } return requestA11yButton ? AccessibilityServiceFragmentType.INVISIBLE : AccessibilityServiceFragmentType.INTUITIVE; } } core/java/com/android/internal/accessibility/util/ShortcutUtils.java 0 → 100644 +158 −0 Original line number Diff line number Diff line /* * 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.internal.accessibility.util; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY; import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType; import android.annotation.NonNull; import android.content.Context; import android.provider.Settings; import android.text.TextUtils; import android.view.accessibility.AccessibilityManager.ShortcutType; import java.util.StringJoiner; /** * Collection of utilities for accessibility shortcut. */ public final class ShortcutUtils { private ShortcutUtils() {} private static final TextUtils.SimpleStringSplitter sStringColonSplitter = new TextUtils.SimpleStringSplitter(SERVICES_SEPARATOR); /** * Opts out component name into colon-separated {@code shortcutType} key's string in Settings. * * @param context The current context. * @param shortcutType The preferred shortcut type user selected. * @param componentId The component id that need to be opted out from Settings. */ public static void optOutValueFromSettings( Context context, @UserShortcutType int shortcutType, String componentId) { final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR)); final String targetsKey = convertToKey(shortcutType); final String targetsValue = Settings.Secure.getString(context.getContentResolver(), targetsKey); if (TextUtils.isEmpty(targetsValue)) { return; } sStringColonSplitter.setString(targetsValue); while (sStringColonSplitter.hasNext()) { final String id = sStringColonSplitter.next(); if (TextUtils.isEmpty(id) || componentId.equals(id)) { continue; } joiner.add(id); } Settings.Secure.putString(context.getContentResolver(), targetsKey, joiner.toString()); } /** * Returns if component name existed in one of {@code shortcutTypes} string in Settings. * * @param context The current context. * @param shortcutTypes A combination of {@link UserShortcutType}. * @param componentId The component name that need to be checked existed in Settings. * @return {@code true} if componentName existed in Settings. */ public static boolean hasValuesInSettings(Context context, int shortcutTypes, @NonNull String componentId) { boolean exist = false; if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { exist = hasValueInSettings(context, UserShortcutType.SOFTWARE, componentId); } if (((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE)) { exist |= hasValueInSettings(context, UserShortcutType.HARDWARE, componentId); } return exist; } /** * Returns if component name existed in Settings. * * @param context The current context. * @param shortcutType The preferred shortcut type user selected. * @param componentId The component id that need to be checked existed in Settings. * @return {@code true} if componentName existed in Settings. */ public static boolean hasValueInSettings(Context context, @UserShortcutType int shortcutType, @NonNull String componentId) { final String targetKey = convertToKey(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), targetKey); if (TextUtils.isEmpty(targetString)) { return false; } sStringColonSplitter.setString(targetString); while (sStringColonSplitter.hasNext()) { final String id = sStringColonSplitter.next(); if (componentId.equals(id)) { return true; } } return false; } /** * Converts {@link UserShortcutType} to key in Settings. * * @param type The shortcut type. * @return Mapping key in Settings. */ public static String convertToKey(@UserShortcutType int type) { switch (type) { case UserShortcutType.SOFTWARE: return Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT; case UserShortcutType.HARDWARE: return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; case UserShortcutType.TRIPLETAP: return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED; default: throw new IllegalArgumentException( "Unsupported user shortcut type: " + type); } } /** * Converts {@link ShortcutType} to {@link UserShortcutType}. * * @param type The shortcut type. * @return {@link UserShortcutType}. */ public static @UserShortcutType int convertToUserType(@ShortcutType int type) { switch (type) { case ACCESSIBILITY_BUTTON: return UserShortcutType.SOFTWARE; case ACCESSIBILITY_SHORTCUT_KEY: return UserShortcutType.HARDWARE; default: throw new IllegalArgumentException( "Unsupported shortcut type:" + type); } } } core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java +25 −315 File changed.Preview size limit exceeded, changes collapsed. Show changes core/res/res/layout/accessibility_button_chooser_item.xml +3 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,9 @@ android:layout_height="wrap_content" android:layout_marginStart="14dp" android:layout_weight="1" android:textColor="?attr/textColorPrimary"/> android:textSize="20sp" android:textColor="?attr/textColorPrimary" android:fontFamily="sans-serif-medium"/> <FrameLayout android:id="@+id/accessibility_button_target_item_container" Loading Loading
core/java/com/android/internal/accessibility/common/ShortcutConstants.java 0 → 100644 +123 −0 Original line number Diff line number Diff line /* * 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.internal.accessibility.common; import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Collection of common constants for accessibility shortcut. */ public final class ShortcutConstants { private ShortcutConstants() {} public static final char SERVICES_SEPARATOR = ':'; public static final float DISABLED_ALPHA = 0.5f; public static final float ENABLED_ALPHA = 1.0f; /** * Annotation for different user shortcut type UI type. * * {@code DEFAULT} for displaying default value. * {@code SOFTWARE} for displaying specifying the accessibility services or features which * choose accessibility button in the navigation bar as preferred shortcut. * {@code HARDWARE} for displaying specifying the accessibility services or features which * choose accessibility shortcut as preferred shortcut. * {@code TRIPLETAP} for displaying specifying magnification to be toggled via quickly * tapping screen 3 times as preferred shortcut. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ UserShortcutType.DEFAULT, UserShortcutType.SOFTWARE, UserShortcutType.HARDWARE, UserShortcutType.TRIPLETAP, }) public @interface UserShortcutType { int DEFAULT = 0; int SOFTWARE = 1; // 1 << 0 int HARDWARE = 2; // 1 << 1 int TRIPLETAP = 4; // 1 << 2 } /** * Annotation for different accessibilityService fragment UI type. * * {@code LEGACY} for displaying appearance aligned with sdk version Q accessibility service * page, but only hardware shortcut allowed and under service in version Q or early. * {@code INVISIBLE} for displaying appearance without switch bar. * {@code INTUITIVE} for displaying appearance with version R accessibility design. * {@code BOUNCE} for displaying appearance with pop-up action. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ AccessibilityServiceFragmentType.LEGACY, AccessibilityServiceFragmentType.INVISIBLE, AccessibilityServiceFragmentType.INTUITIVE, AccessibilityServiceFragmentType.BOUNCE, }) public @interface AccessibilityServiceFragmentType { int LEGACY = 0; int INVISIBLE = 1; int INTUITIVE = 2; int BOUNCE = 3; } /** * Annotation for different shortcut menu mode. * * {@code LAUNCH} for clicking list item to trigger the service callback. * {@code EDIT} for clicking list item and save button to disable the service. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ ShortcutMenuMode.LAUNCH, ShortcutMenuMode.EDIT, }) public @interface ShortcutMenuMode { int LAUNCH = 0; int EDIT = 1; } /** * Annotation for align the element index of white listing feature * {@code WHITE_LISTING_FEATURES}. * * {@code COMPONENT_ID} is to get the service component name. * {@code LABEL_ID} is to get the service label text. * {@code ICON_ID} is to get the service icon. * {@code FRAGMENT_TYPE} is to get the service fragment type. * {@code SETTINGS_KEY} is to get the service settings key. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ WhiteListingFeatureElementIndex.COMPONENT_ID, WhiteListingFeatureElementIndex.LABEL_ID, WhiteListingFeatureElementIndex.ICON_ID, WhiteListingFeatureElementIndex.FRAGMENT_TYPE, WhiteListingFeatureElementIndex.SETTINGS_KEY, }) public @interface WhiteListingFeatureElementIndex { int COMPONENT_ID = 0; int LABEL_ID = 1; int ICON_ID = 2; int FRAGMENT_TYPE = 3; int SETTINGS_KEY = 4; } }
core/java/com/android/internal/accessibility/util/AccessibilityUtils.java 0 → 100644 +131 −0 Original line number Diff line number Diff line /* * 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.internal.accessibility.util; import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityServiceFragmentType; import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR; import android.accessibilityservice.AccessibilityServiceInfo; import android.content.ComponentName; import android.content.Context; import android.os.Build; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.ArraySet; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Collection of utilities for accessibility service. */ public final class AccessibilityUtils { private AccessibilityUtils() {} /** * Returns the set of enabled accessibility services for userId. If there are no * services, it returns the unmodifiable {@link Collections#emptySet()}. */ public static Set<ComponentName> getEnabledServicesFromSettings(Context context, int userId) { final String enabledServicesSetting = Settings.Secure.getStringForUser( context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userId); if (TextUtils.isEmpty(enabledServicesSetting)) { return Collections.emptySet(); } final Set<ComponentName> enabledServices = new HashSet<>(); final TextUtils.StringSplitter colonSplitter = new TextUtils.SimpleStringSplitter(SERVICES_SEPARATOR); colonSplitter.setString(enabledServicesSetting); for (String componentNameString : colonSplitter) { final ComponentName enabledService = ComponentName.unflattenFromString( componentNameString); if (enabledService != null) { enabledServices.add(enabledService); } } return enabledServices; } /** * Changes an accessibility component's state. */ public static void setAccessibilityServiceState(Context context, ComponentName componentName, boolean enabled) { setAccessibilityServiceState(context, componentName, enabled, UserHandle.myUserId()); } /** * Changes an accessibility component's state for {@param userId}. */ public static void setAccessibilityServiceState(Context context, ComponentName componentName, boolean enabled, int userId) { Set<ComponentName> enabledServices = getEnabledServicesFromSettings( context, userId); if (enabledServices.isEmpty()) { enabledServices = new ArraySet<>(/* capacity= */ 1); } if (enabled) { enabledServices.add(componentName); } else { enabledServices.remove(componentName); } final StringBuilder enabledServicesBuilder = new StringBuilder(); for (ComponentName enabledService : enabledServices) { enabledServicesBuilder.append(enabledService.flattenToString()); enabledServicesBuilder.append( SERVICES_SEPARATOR); } final int enabledServicesBuilderLength = enabledServicesBuilder.length(); if (enabledServicesBuilderLength > 0) { enabledServicesBuilder.deleteCharAt(enabledServicesBuilderLength - 1); } Settings.Secure.putStringForUser(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServicesBuilder.toString(), userId); } /** * Gets the corresponding fragment type of a given accessibility service. * * @param accessibilityServiceInfo The accessibilityService's info. * @return int from {@link AccessibilityServiceFragmentType}. */ public static @AccessibilityServiceFragmentType int getAccessibilityServiceFragmentType( AccessibilityServiceInfo accessibilityServiceInfo) { final int targetSdk = accessibilityServiceInfo.getResolveInfo() .serviceInfo.applicationInfo.targetSdkVersion; final boolean requestA11yButton = (accessibilityServiceInfo.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0; if (targetSdk <= Build.VERSION_CODES.Q) { return AccessibilityServiceFragmentType.LEGACY; } return requestA11yButton ? AccessibilityServiceFragmentType.INVISIBLE : AccessibilityServiceFragmentType.INTUITIVE; } }
core/java/com/android/internal/accessibility/util/ShortcutUtils.java 0 → 100644 +158 −0 Original line number Diff line number Diff line /* * 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.internal.accessibility.util; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY; import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType; import android.annotation.NonNull; import android.content.Context; import android.provider.Settings; import android.text.TextUtils; import android.view.accessibility.AccessibilityManager.ShortcutType; import java.util.StringJoiner; /** * Collection of utilities for accessibility shortcut. */ public final class ShortcutUtils { private ShortcutUtils() {} private static final TextUtils.SimpleStringSplitter sStringColonSplitter = new TextUtils.SimpleStringSplitter(SERVICES_SEPARATOR); /** * Opts out component name into colon-separated {@code shortcutType} key's string in Settings. * * @param context The current context. * @param shortcutType The preferred shortcut type user selected. * @param componentId The component id that need to be opted out from Settings. */ public static void optOutValueFromSettings( Context context, @UserShortcutType int shortcutType, String componentId) { final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR)); final String targetsKey = convertToKey(shortcutType); final String targetsValue = Settings.Secure.getString(context.getContentResolver(), targetsKey); if (TextUtils.isEmpty(targetsValue)) { return; } sStringColonSplitter.setString(targetsValue); while (sStringColonSplitter.hasNext()) { final String id = sStringColonSplitter.next(); if (TextUtils.isEmpty(id) || componentId.equals(id)) { continue; } joiner.add(id); } Settings.Secure.putString(context.getContentResolver(), targetsKey, joiner.toString()); } /** * Returns if component name existed in one of {@code shortcutTypes} string in Settings. * * @param context The current context. * @param shortcutTypes A combination of {@link UserShortcutType}. * @param componentId The component name that need to be checked existed in Settings. * @return {@code true} if componentName existed in Settings. */ public static boolean hasValuesInSettings(Context context, int shortcutTypes, @NonNull String componentId) { boolean exist = false; if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { exist = hasValueInSettings(context, UserShortcutType.SOFTWARE, componentId); } if (((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE)) { exist |= hasValueInSettings(context, UserShortcutType.HARDWARE, componentId); } return exist; } /** * Returns if component name existed in Settings. * * @param context The current context. * @param shortcutType The preferred shortcut type user selected. * @param componentId The component id that need to be checked existed in Settings. * @return {@code true} if componentName existed in Settings. */ public static boolean hasValueInSettings(Context context, @UserShortcutType int shortcutType, @NonNull String componentId) { final String targetKey = convertToKey(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), targetKey); if (TextUtils.isEmpty(targetString)) { return false; } sStringColonSplitter.setString(targetString); while (sStringColonSplitter.hasNext()) { final String id = sStringColonSplitter.next(); if (componentId.equals(id)) { return true; } } return false; } /** * Converts {@link UserShortcutType} to key in Settings. * * @param type The shortcut type. * @return Mapping key in Settings. */ public static String convertToKey(@UserShortcutType int type) { switch (type) { case UserShortcutType.SOFTWARE: return Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT; case UserShortcutType.HARDWARE: return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; case UserShortcutType.TRIPLETAP: return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED; default: throw new IllegalArgumentException( "Unsupported user shortcut type: " + type); } } /** * Converts {@link ShortcutType} to {@link UserShortcutType}. * * @param type The shortcut type. * @return {@link UserShortcutType}. */ public static @UserShortcutType int convertToUserType(@ShortcutType int type) { switch (type) { case ACCESSIBILITY_BUTTON: return UserShortcutType.SOFTWARE; case ACCESSIBILITY_SHORTCUT_KEY: return UserShortcutType.HARDWARE; default: throw new IllegalArgumentException( "Unsupported shortcut type:" + type); } } }
core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java +25 −315 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/res/res/layout/accessibility_button_chooser_item.xml +3 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,9 @@ android:layout_height="wrap_content" android:layout_marginStart="14dp" android:layout_weight="1" android:textColor="?attr/textColorPrimary"/> android:textSize="20sp" android:textColor="?attr/textColorPrimary" android:fontFamily="sans-serif-medium"/> <FrameLayout android:id="@+id/accessibility_button_target_item_container" Loading