Accessibility shortcut secondary action - save and restore shortcut key
- Implement onCheckboxClicked() to save shortcut key - restore shortcut key when onViewCreated() - Use preferredShortcutType to handle settings key Bug: 142530063 Test: make -j52 RunSettingsRoboTests ROBOTEST_FILTER=AccessibilityUtilTest Change-Id: Iabe636641968d346e52becea19b6e201ea5bc1fb
This commit is contained in:
@@ -19,16 +19,20 @@ package com.android.settings.accessibility;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/** Provides utility methods to accessibility settings only. */
|
||||
final class AccessibilityUtil {
|
||||
@@ -56,6 +60,12 @@ final class AccessibilityUtil {
|
||||
int INTUITIVE = 2;
|
||||
}
|
||||
|
||||
// TODO(b/147021230): Will move common functions and variables to
|
||||
// android/internal/accessibility folder
|
||||
private static final char COMPONENT_NAME_SEPARATOR = ':';
|
||||
private static final TextUtils.SimpleStringSplitter sStringColonSplitter =
|
||||
new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
|
||||
|
||||
/**
|
||||
* Annotation for different shortcut type UI type.
|
||||
*
|
||||
@@ -69,14 +79,14 @@ final class AccessibilityUtil {
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
ShortcutType.DEFAULT,
|
||||
ShortcutType.SOFTWARE,
|
||||
ShortcutType.HARDWARE,
|
||||
ShortcutType.TRIPLETAP,
|
||||
PreferredShortcutType.DEFAULT,
|
||||
PreferredShortcutType.SOFTWARE,
|
||||
PreferredShortcutType.HARDWARE,
|
||||
PreferredShortcutType.TRIPLETAP,
|
||||
})
|
||||
|
||||
/** Denotes the shortcut type. */
|
||||
public @interface ShortcutType {
|
||||
public @interface PreferredShortcutType {
|
||||
int DEFAULT = 0;
|
||||
int SOFTWARE = 1; // 1 << 0
|
||||
int HARDWARE = 2; // 1 << 1
|
||||
@@ -129,7 +139,7 @@ final class AccessibilityUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the corresponding fragment type of a given accessibility service
|
||||
* Gets the corresponding fragment type of a given accessibility service.
|
||||
*
|
||||
* @param accessibilityServiceInfo The accessibilityService's info
|
||||
* @return int from {@link AccessibilityServiceFragmentType}
|
||||
@@ -148,4 +158,112 @@ final class AccessibilityUtil {
|
||||
? AccessibilityServiceFragmentType.INVISIBLE
|
||||
: AccessibilityServiceFragmentType.INTUITIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opts in 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 componentName The component name that need to be opted in Settings.
|
||||
*/
|
||||
static void optInValueToSettings(Context context, @PreferredShortcutType int shortcutType,
|
||||
@NonNull ComponentName componentName) {
|
||||
final String targetKey = convertKeyFromSettings(shortcutType);
|
||||
final String targetString = Settings.Secure.getString(context.getContentResolver(),
|
||||
targetKey);
|
||||
|
||||
if (TextUtils.isEmpty(targetString)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasValueInSettings(context, shortcutType, componentName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
|
||||
|
||||
joiner.add(targetString);
|
||||
joiner.add(componentName.flattenToString());
|
||||
|
||||
Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 componentName The component name that need to be opted out from Settings.
|
||||
*/
|
||||
static void optOutValueFromSettings(Context context, @PreferredShortcutType int shortcutType,
|
||||
@NonNull ComponentName componentName) {
|
||||
final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
|
||||
final String targetKey = convertKeyFromSettings(shortcutType);
|
||||
final String targetString = Settings.Secure.getString(context.getContentResolver(),
|
||||
targetKey);
|
||||
|
||||
if (TextUtils.isEmpty(targetString)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sStringColonSplitter.setString(targetString);
|
||||
while (sStringColonSplitter.hasNext()) {
|
||||
final String name = sStringColonSplitter.next();
|
||||
if (TextUtils.isEmpty(name) || (componentName.flattenToString()).equals(name)) {
|
||||
continue;
|
||||
}
|
||||
joiner.add(name);
|
||||
}
|
||||
|
||||
Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if component name existed in Settings.
|
||||
*
|
||||
* @param context The current context.
|
||||
* @param shortcutType The preferred shortcut type user selected.
|
||||
* @param componentName The component name that need to be checked existed in Settings.
|
||||
* @return {@code true} if componentName existed in Settings.
|
||||
*/
|
||||
static boolean hasValueInSettings(Context context, @PreferredShortcutType int shortcutType,
|
||||
@NonNull ComponentName componentName) {
|
||||
final String targetKey = 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 ((componentName.flattenToString()).equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts {@link PreferredShortcutType} to key in Settings.
|
||||
*
|
||||
* @param shortcutType The shortcut type.
|
||||
* @return Mapping key in Settings.
|
||||
*/
|
||||
static String convertKeyFromSettings(@PreferredShortcutType int shortcutType) {
|
||||
switch (shortcutType) {
|
||||
case PreferredShortcutType.SOFTWARE:
|
||||
return Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT;
|
||||
case PreferredShortcutType.HARDWARE:
|
||||
return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
|
||||
case PreferredShortcutType.TRIPLETAP:
|
||||
return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported preferredShortcutType " + shortcutType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user