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:
jasonwshsu
2019-12-26 18:39:27 +08:00
parent 8b47bd8665
commit 8ef01d25fb
6 changed files with 542 additions and 154 deletions

View File

@@ -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);
}
}
}