Show QS shortcut option if the a11y feature provides a tile.
Bug: 314852953 Test: atest com.android.settings.accessibility Test: atest com.android.settings.accessibility.shortcuts Test: manual Flag: ACONFIG android.view.accessibility.a11y_qs_shortcut STAGING Change-Id: Id7a6b3adfd4c4f3cb2b9f7fe15269b57a3d00543
This commit is contained in:
@@ -414,7 +414,7 @@ public final class AccessibilityGestureNavigationTutorial {
|
||||
|
||||
private static TutorialPage createTwoFingerTripleTapTutorialPage(@NonNull Context context) {
|
||||
// TODO(b/308088945): Update tutorial string and image when UX provides them
|
||||
final int type = UserShortcutType.TWOFINGERTRIPLETAP;
|
||||
final int type = UserShortcutType.TWOFINGER_DOUBLETAP;
|
||||
final CharSequence title =
|
||||
context.getText(R.string.accessibility_tutorial_dialog_title_two_finger_double);
|
||||
final View image =
|
||||
@@ -429,10 +429,32 @@ public final class AccessibilityGestureNavigationTutorial {
|
||||
return new TutorialPage(type, title, image, indicatorIcon, instruction);
|
||||
}
|
||||
|
||||
private static TutorialPage createQuickSettingTutorialPage(@NonNull Context context) {
|
||||
final int type = UserShortcutType.QUICK_SETTINGS;
|
||||
final CharSequence title =
|
||||
context.getText(R.string.accessibility_tutorial_dialog_title_quick_setting);
|
||||
final View image =
|
||||
createIllustrationView(context,
|
||||
R.drawable.a11y_shortcut_type_quick_settings);
|
||||
final CharSequence instruction =
|
||||
context.getText(R.string.accessibility_tutorial_dialog_message_quick_setting);
|
||||
final ImageView indicatorIcon =
|
||||
createImageView(context, R.drawable.ic_accessibility_page_indicator);
|
||||
indicatorIcon.setEnabled(false);
|
||||
|
||||
return new TutorialPage(type, title, image, indicatorIcon, instruction);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static List<TutorialPage> createShortcutTutorialPages(@NonNull Context context,
|
||||
int shortcutTypes) {
|
||||
final List<TutorialPage> tutorialPages = new ArrayList<>();
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
if ((shortcutTypes & UserShortcutType.QUICK_SETTINGS)
|
||||
== UserShortcutType.QUICK_SETTINGS) {
|
||||
tutorialPages.add(createQuickSettingTutorialPage(context));
|
||||
}
|
||||
}
|
||||
if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) {
|
||||
tutorialPages.add(createSoftwareTutorialPage(context));
|
||||
}
|
||||
@@ -446,8 +468,8 @@ public final class AccessibilityGestureNavigationTutorial {
|
||||
}
|
||||
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if ((shortcutTypes & UserShortcutType.TWOFINGERTRIPLETAP)
|
||||
== UserShortcutType.TWOFINGERTRIPLETAP) {
|
||||
if ((shortcutTypes & UserShortcutType.TWOFINGER_DOUBLETAP)
|
||||
== UserShortcutType.TWOFINGER_DOUBLETAP) {
|
||||
tutorialPages.add(createTwoFingerTripleTapTutorialPage(context));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,7 +452,13 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted
|
||||
getComponentName().flattenToString());
|
||||
|
||||
final List<CharSequence> list = new ArrayList<>();
|
||||
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
if (hasShortcutType(shortcutTypes, AccessibilityUtil.UserShortcutType.QUICK_SETTINGS)) {
|
||||
final CharSequence qsTitle = context.getText(
|
||||
R.string.accessibility_feature_shortcut_setting_summary_quick_settings);
|
||||
list.add(qsTitle);
|
||||
}
|
||||
}
|
||||
if (hasShortcutType(shortcutTypes, AccessibilityUtil.UserShortcutType.SOFTWARE)) {
|
||||
list.add(getSoftwareShortcutTypeSummary(context));
|
||||
}
|
||||
@@ -538,6 +544,10 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted
|
||||
}
|
||||
|
||||
private void showQuickSettingsTooltipIfNeeded() {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
// Don't show Quick Settings tooltip
|
||||
return;
|
||||
}
|
||||
final ComponentName tileComponentName = getTileComponentName();
|
||||
if (tileComponentName == null) {
|
||||
// Returns if no tile service assigned.
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.content.res.Resources;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
@@ -40,8 +41,11 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.accessibility.util.ShortcutUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/** Provides utility methods to accessibility settings only. */
|
||||
@@ -87,6 +91,10 @@ public final class AccessibilityUtil {
|
||||
* choose accessibility shortcut as preferred shortcut.
|
||||
* {@code TRIPLETAP} for displaying specifying magnification to be toggled via quickly
|
||||
* tapping screen 3 times as preferred shortcut.
|
||||
* {@code TWOFINGER_DOUBLETAP} for displaying specifying magnification to be toggled via
|
||||
* quickly tapping screen 2 times with two fingers as preferred shortcut.
|
||||
* {@code QUICK_SETTINGS} for displaying specifying the accessibility services or features which
|
||||
* choose Quick Settings as preferred shortcut.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
@@ -94,16 +102,18 @@ public final class AccessibilityUtil {
|
||||
UserShortcutType.SOFTWARE,
|
||||
UserShortcutType.HARDWARE,
|
||||
UserShortcutType.TRIPLETAP,
|
||||
UserShortcutType.TWOFINGERTRIPLETAP,
|
||||
UserShortcutType.TWOFINGER_DOUBLETAP,
|
||||
UserShortcutType.QUICK_SETTINGS,
|
||||
})
|
||||
|
||||
/** Denotes the user shortcut type. */
|
||||
public @interface UserShortcutType {
|
||||
int EMPTY = 0;
|
||||
int SOFTWARE = 1; // 1 << 0
|
||||
int HARDWARE = 2; // 1 << 1
|
||||
int TRIPLETAP = 4; // 1 << 2
|
||||
int TWOFINGERTRIPLETAP = 8; // 1 << 3
|
||||
int SOFTWARE = 1;
|
||||
int HARDWARE = 1 << 1;
|
||||
int TRIPLETAP = 1 << 2;
|
||||
int TWOFINGER_DOUBLETAP = 1 << 3;
|
||||
int QUICK_SETTINGS = 1 << 4;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,12 +210,26 @@ public final class AccessibilityUtil {
|
||||
* Opts in component name into multiple {@code shortcutTypes} colon-separated string in
|
||||
* Settings.
|
||||
*
|
||||
* @param context The current context.
|
||||
* @param shortcutTypes A combination of {@link UserShortcutType}.
|
||||
* @param context The current context.
|
||||
* @param shortcutTypes A combination of {@link UserShortcutType}.
|
||||
* @param componentName The component name that need to be opted in Settings.
|
||||
*/
|
||||
static void optInAllValuesToSettings(Context context, int shortcutTypes,
|
||||
@NonNull ComponentName componentName) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
|
||||
if (a11yManager != null) {
|
||||
a11yManager.enableShortcutsForTargets(
|
||||
/* enable= */ true,
|
||||
shortcutTypes,
|
||||
Set.of(componentName.flattenToString()),
|
||||
UserHandle.myUserId()
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) {
|
||||
optInValueToSettings(context, UserShortcutType.SOFTWARE, componentName);
|
||||
}
|
||||
@@ -217,13 +241,26 @@ public final class AccessibilityUtil {
|
||||
/**
|
||||
* Opts in component name into {@code shortcutType} colon-separated string in Settings.
|
||||
*
|
||||
* @param context The current context.
|
||||
* @param shortcutType The preferred shortcut type user selected.
|
||||
* @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.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static void optInValueToSettings(Context context, @UserShortcutType int shortcutType,
|
||||
@NonNull ComponentName componentName) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
|
||||
if (a11yManager != null) {
|
||||
a11yManager.enableShortcutsForTargets(
|
||||
/* enable= */ true,
|
||||
shortcutType,
|
||||
Set.of(componentName.flattenToString()),
|
||||
UserHandle.myUserId()
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final String targetKey = convertKeyFromSettings(shortcutType);
|
||||
final String targetString = Settings.Secure.getString(context.getContentResolver(),
|
||||
targetKey);
|
||||
@@ -245,12 +282,25 @@ public final class AccessibilityUtil {
|
||||
* Opts out component name into multiple {@code shortcutTypes} colon-separated string in
|
||||
* Settings.
|
||||
*
|
||||
* @param context The current context.
|
||||
* @param context The current context.
|
||||
* @param shortcutTypes A combination of {@link UserShortcutType}.
|
||||
* @param componentName The component name that need to be opted out from Settings.
|
||||
*/
|
||||
static void optOutAllValuesFromSettings(Context context, int shortcutTypes,
|
||||
@NonNull ComponentName componentName) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
|
||||
if (a11yManager != null) {
|
||||
a11yManager.enableShortcutsForTargets(
|
||||
/* enable= */ false,
|
||||
shortcutTypes,
|
||||
Set.of(componentName.flattenToString()),
|
||||
UserHandle.myUserId()
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) {
|
||||
optOutValueFromSettings(context, UserShortcutType.SOFTWARE, componentName);
|
||||
}
|
||||
@@ -262,13 +312,26 @@ public final class AccessibilityUtil {
|
||||
/**
|
||||
* Opts out component name into {@code shortcutType} colon-separated string in Settings.
|
||||
*
|
||||
* @param context The current context.
|
||||
* @param shortcutType The preferred shortcut type user selected.
|
||||
* @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.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static void optOutValueFromSettings(Context context, @UserShortcutType int shortcutType,
|
||||
@NonNull ComponentName componentName) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
|
||||
if (a11yManager != null) {
|
||||
a11yManager.enableShortcutsForTargets(
|
||||
/* enable= */ false,
|
||||
shortcutType,
|
||||
Set.of(componentName.flattenToString()),
|
||||
UserHandle.myUserId()
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
|
||||
final String targetKey = convertKeyFromSettings(shortcutType);
|
||||
final String targetString = Settings.Secure.getString(context.getContentResolver(),
|
||||
@@ -307,6 +370,14 @@ public final class AccessibilityUtil {
|
||||
if (((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE)) {
|
||||
exist |= hasValueInSettings(context, UserShortcutType.HARDWARE, componentName);
|
||||
}
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
if ((shortcutTypes & UserShortcutType.QUICK_SETTINGS)
|
||||
== UserShortcutType.QUICK_SETTINGS) {
|
||||
exist |= hasValueInSettings(context, UserShortcutType.QUICK_SETTINGS,
|
||||
componentName);
|
||||
}
|
||||
}
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
@@ -321,6 +392,12 @@ public final class AccessibilityUtil {
|
||||
@VisibleForTesting
|
||||
static boolean hasValueInSettings(Context context, @UserShortcutType int shortcutType,
|
||||
@NonNull ComponentName componentName) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
return ShortcutUtils.getShortcutTargetsFromSettings(
|
||||
context, shortcutType, UserHandle.myUserId()
|
||||
).contains(componentName.flattenToString());
|
||||
}
|
||||
|
||||
final String targetKey = convertKeyFromSettings(shortcutType);
|
||||
final String targetString = Settings.Secure.getString(context.getContentResolver(),
|
||||
targetKey);
|
||||
@@ -357,6 +434,12 @@ public final class AccessibilityUtil {
|
||||
if (hasValuesInSettings(context, UserShortcutType.HARDWARE, componentName)) {
|
||||
shortcutTypes |= UserShortcutType.HARDWARE;
|
||||
}
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
if (hasValuesInSettings(context, UserShortcutType.QUICK_SETTINGS, componentName)) {
|
||||
shortcutTypes |= UserShortcutType.QUICK_SETTINGS;
|
||||
}
|
||||
}
|
||||
|
||||
return shortcutTypes;
|
||||
}
|
||||
|
||||
@@ -367,6 +450,10 @@ public final class AccessibilityUtil {
|
||||
* @return Mapping key in Settings.
|
||||
*/
|
||||
static String convertKeyFromSettings(@UserShortcutType int shortcutType) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
return ShortcutUtils.convertToKey(shortcutType);
|
||||
}
|
||||
|
||||
switch (shortcutType) {
|
||||
case UserShortcutType.SOFTWARE:
|
||||
return Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
|
||||
|
||||
@@ -21,8 +21,10 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.accessibility.Flags;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.accessibility.common.ShortcutConstants;
|
||||
import com.android.internal.accessibility.util.ShortcutUtils;
|
||||
@@ -98,6 +100,11 @@ public final class PreferredShortcuts {
|
||||
@NonNull Context context, @NonNull Set<String> components) {
|
||||
final Map<Integer, Set<String>> shortcutTypeToTargets = new ArrayMap<>();
|
||||
for (int shortcutType : ShortcutConstants.USER_SHORTCUT_TYPES) {
|
||||
if (!Flags.a11yQsShortcut()
|
||||
&& shortcutType == ShortcutConstants.UserShortcutType.QUICK_SETTINGS) {
|
||||
// Skip saving quick setting as preferred shortcut option when flag is not enabled
|
||||
continue;
|
||||
}
|
||||
shortcutTypeToTargets.put(
|
||||
shortcutType,
|
||||
ShortcutUtils.getShortcutTargetsFromSettings(
|
||||
@@ -138,6 +145,11 @@ public final class PreferredShortcuts {
|
||||
return context.getSharedPreferences(ACCESSIBILITY_PERF, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
static void clearPreferredShortcuts(Context context) {
|
||||
getSharedPreferences(context).edit().clear().apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default shortcut types for the given accessibility feature.
|
||||
*/
|
||||
|
||||
@@ -711,6 +711,13 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
|
||||
mComponentName.flattenToString());
|
||||
|
||||
final List<CharSequence> list = new ArrayList<>();
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.QUICK_SETTINGS)) {
|
||||
final CharSequence qsTitle = context.getText(
|
||||
R.string.accessibility_feature_shortcut_setting_summary_quick_settings);
|
||||
list.add(qsTitle);
|
||||
}
|
||||
}
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.SOFTWARE)) {
|
||||
list.add(getSoftwareShortcutTypeSummary(context));
|
||||
}
|
||||
@@ -906,6 +913,10 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
|
||||
}
|
||||
|
||||
private void showQuickSettingsTooltipIfNeeded() {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
// Don't show Quick Settings tooltip
|
||||
return;
|
||||
}
|
||||
final ComponentName tileComponentName = getTileComponentName();
|
||||
if (tileComponentName == null) {
|
||||
// Returns if no tile service assigned.
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.icu.text.CaseMap;
|
||||
import android.icu.text.MessageFormat;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
@@ -65,6 +66,7 @@ import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
@@ -357,7 +359,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
}
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (mTwoFingerTripleTapTypeCheckBox.isChecked()) {
|
||||
value |= UserShortcutType.TWOFINGERTRIPLETAP;
|
||||
value |= UserShortcutType.TWOFINGER_DOUBLETAP;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
@@ -419,7 +421,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
hasShortcutType(value, UserShortcutType.TRIPLETAP));
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
mTwoFingerTripleTapTypeCheckBox.setChecked(
|
||||
hasShortcutType(value, UserShortcutType.TWOFINGERTRIPLETAP));
|
||||
hasShortcutType(value, UserShortcutType.TWOFINGER_DOUBLETAP));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,6 +485,13 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
MAGNIFICATION_CONTROLLER_NAME);
|
||||
|
||||
final List<CharSequence> list = new ArrayList<>();
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.QUICK_SETTINGS)) {
|
||||
final CharSequence qsTitle = context.getText(
|
||||
R.string.accessibility_feature_shortcut_setting_summary_quick_settings);
|
||||
list.add(qsTitle);
|
||||
}
|
||||
}
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.SOFTWARE)) {
|
||||
list.add(getSoftwareShortcutTypeSummary(context));
|
||||
}
|
||||
@@ -497,7 +506,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
list.add(tripleTapTitle);
|
||||
}
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.TWOFINGERTRIPLETAP)) {
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.TWOFINGER_DOUBLETAP)) {
|
||||
final CharSequence twoFingerTripleTapTitle = context.getText(
|
||||
R.string.accessibility_shortcut_two_finger_double_tap_keyword);
|
||||
list.add(twoFingerTripleTapTitle);
|
||||
@@ -678,15 +687,34 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
optInMagnificationValueToSettings(context, UserShortcutType.TRIPLETAP);
|
||||
}
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (((shortcutTypes & UserShortcutType.TWOFINGERTRIPLETAP)
|
||||
== UserShortcutType.TWOFINGERTRIPLETAP)) {
|
||||
optInMagnificationValueToSettings(context, UserShortcutType.TWOFINGERTRIPLETAP);
|
||||
if (((shortcutTypes & UserShortcutType.TWOFINGER_DOUBLETAP)
|
||||
== UserShortcutType.TWOFINGER_DOUBLETAP)) {
|
||||
optInMagnificationValueToSettings(context, UserShortcutType.TWOFINGER_DOUBLETAP);
|
||||
}
|
||||
}
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
if (((shortcutTypes & UserShortcutType.QUICK_SETTINGS)
|
||||
== UserShortcutType.QUICK_SETTINGS)) {
|
||||
optInMagnificationValueToSettings(context, UserShortcutType.QUICK_SETTINGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void optInMagnificationValueToSettings(Context context,
|
||||
@UserShortcutType int shortcutType) {
|
||||
private static void optInMagnificationValueToSettings(
|
||||
Context context, @UserShortcutType int shortcutType) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
|
||||
if (a11yManager != null) {
|
||||
a11yManager.enableShortcutsForTargets(
|
||||
/* enable= */ true,
|
||||
shortcutType,
|
||||
Set.of(MAGNIFICATION_CONTROLLER_NAME),
|
||||
UserHandle.myUserId()
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (shortcutType == UserShortcutType.TRIPLETAP) {
|
||||
Settings.Secure.putInt(context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON);
|
||||
@@ -694,8 +722,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
}
|
||||
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (shortcutType == UserShortcutType.TWOFINGERTRIPLETAP) {
|
||||
Settings.Secure.putInt(context.getContentResolver(),
|
||||
if (shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP) {
|
||||
Settings.Secure.putInt(
|
||||
context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
|
||||
ON);
|
||||
return;
|
||||
@@ -743,15 +772,34 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
optOutMagnificationValueFromSettings(context, UserShortcutType.TRIPLETAP);
|
||||
}
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (((shortcutTypes & UserShortcutType.TWOFINGERTRIPLETAP)
|
||||
== UserShortcutType.TWOFINGERTRIPLETAP)) {
|
||||
optOutMagnificationValueFromSettings(context, UserShortcutType.TWOFINGERTRIPLETAP);
|
||||
if (((shortcutTypes & UserShortcutType.TWOFINGER_DOUBLETAP)
|
||||
== UserShortcutType.TWOFINGER_DOUBLETAP)) {
|
||||
optOutMagnificationValueFromSettings(context, UserShortcutType.TWOFINGER_DOUBLETAP);
|
||||
}
|
||||
}
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
if (((shortcutTypes & UserShortcutType.QUICK_SETTINGS)
|
||||
== UserShortcutType.QUICK_SETTINGS)) {
|
||||
optOutMagnificationValueFromSettings(context, UserShortcutType.QUICK_SETTINGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void optOutMagnificationValueFromSettings(Context context,
|
||||
@UserShortcutType int shortcutType) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
|
||||
if (a11yManager != null) {
|
||||
a11yManager.enableShortcutsForTargets(
|
||||
/* enable= */ false,
|
||||
shortcutType,
|
||||
Set.of(MAGNIFICATION_CONTROLLER_NAME),
|
||||
UserHandle.myUserId()
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (shortcutType == UserShortcutType.TRIPLETAP) {
|
||||
Settings.Secure.putInt(context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF);
|
||||
@@ -759,8 +807,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
}
|
||||
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (shortcutType == UserShortcutType.TWOFINGERTRIPLETAP) {
|
||||
Settings.Secure.putInt(context.getContentResolver(),
|
||||
if (shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP) {
|
||||
Settings.Secure.putInt(
|
||||
context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
|
||||
OFF);
|
||||
return;
|
||||
@@ -803,10 +852,10 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
exist |= hasMagnificationValueInSettings(context, UserShortcutType.TRIPLETAP);
|
||||
}
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (((shortcutTypes & UserShortcutType.TWOFINGERTRIPLETAP)
|
||||
== UserShortcutType.TWOFINGERTRIPLETAP)) {
|
||||
if (((shortcutTypes & UserShortcutType.TWOFINGER_DOUBLETAP)
|
||||
== UserShortcutType.TWOFINGER_DOUBLETAP)) {
|
||||
exist |= hasMagnificationValueInSettings(context,
|
||||
UserShortcutType.TWOFINGERTRIPLETAP);
|
||||
UserShortcutType.TWOFINGER_DOUBLETAP);
|
||||
}
|
||||
}
|
||||
return exist;
|
||||
@@ -820,7 +869,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
}
|
||||
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (shortcutType == UserShortcutType.TWOFINGERTRIPLETAP) {
|
||||
if (shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP) {
|
||||
return Settings.Secure.getInt(context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
|
||||
OFF) == ON;
|
||||
@@ -857,8 +906,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
shortcutTypes |= UserShortcutType.TRIPLETAP;
|
||||
}
|
||||
if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
|
||||
if (hasMagnificationValuesInSettings(context, UserShortcutType.TWOFINGERTRIPLETAP)) {
|
||||
shortcutTypes |= UserShortcutType.TWOFINGERTRIPLETAP;
|
||||
if (hasMagnificationValuesInSettings(context, UserShortcutType.TWOFINGER_DOUBLETAP)) {
|
||||
shortcutTypes |= UserShortcutType.TWOFINGER_DOUBLETAP;
|
||||
}
|
||||
}
|
||||
return shortcutTypes;
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_QS_TARGETS;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
|
||||
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
|
||||
@@ -98,6 +99,9 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment {
|
||||
private static final Uri TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING =
|
||||
Settings.Secure.getUriFor(ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED);
|
||||
|
||||
private static final Uri QUICK_SETTINGS_SHORTCUT_SETTING =
|
||||
Settings.Secure.getUriFor(ACCESSIBILITY_QS_TARGETS);
|
||||
|
||||
@VisibleForTesting
|
||||
static final Uri[] SHORTCUT_SETTINGS = {
|
||||
VOLUME_KEYS_SHORTCUT_SETTING,
|
||||
@@ -105,6 +109,7 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment {
|
||||
BUTTON_SHORTCUT_SETTING,
|
||||
TRIPLE_TAP_SHORTCUT_SETTING,
|
||||
TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING,
|
||||
QUICK_SETTINGS_SHORTCUT_SETTING,
|
||||
};
|
||||
|
||||
private Set<String> mShortcutTargets;
|
||||
@@ -171,7 +176,9 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment {
|
||||
} else if (TRIPLE_TAP_SHORTCUT_SETTING.equals(uri)) {
|
||||
refreshPreferenceController(TripleTapShortcutOptionController.class);
|
||||
} else if (TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING.equals(uri)) {
|
||||
refreshPreferenceController(TwoFingersDoubleTapShortcutOptionController.class);
|
||||
refreshPreferenceController(TwoFingerDoubleTapShortcutOptionController.class);
|
||||
} else if (QUICK_SETTINGS_SHORTCUT_SETTING.equals(uri)) {
|
||||
refreshPreferenceController(QuickSettingsShortcutOptionController.class);
|
||||
}
|
||||
|
||||
PreferredShortcuts.updatePreferredShortcutsFromSettings(
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.accessibility.shortcuts;
|
||||
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType.INVISIBLE_TOGGLE;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.service.quicksettings.TileService;
|
||||
import android.util.ArraySet;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.accessibility.Flags;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.accessibility.common.ShortcutConstants;
|
||||
import com.android.internal.accessibility.util.AccessibilityUtils;
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A controller handles displaying the quick settings shortcut option preference and
|
||||
* configuring the shortcut.
|
||||
*/
|
||||
public class QuickSettingsShortcutOptionController extends ShortcutOptionPreferenceController {
|
||||
public QuickSettingsShortcutOptionController(
|
||||
@NonNull Context context, @NonNull String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@ShortcutConstants.UserShortcutType
|
||||
@Override
|
||||
protected int getShortcutType() {
|
||||
return ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(@NonNull PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
final Preference preference = screen.findPreference(getPreferenceKey());
|
||||
if (preference instanceof ShortcutOptionPreference shortcutOptionPreference) {
|
||||
shortcutOptionPreference.setTitle(
|
||||
R.string.accessibility_shortcut_edit_dialog_title_quick_settings);
|
||||
shortcutOptionPreference.setSummary(
|
||||
R.string.accessibility_shortcut_edit_dialog_summary_quick_settings);
|
||||
shortcutOptionPreference.setIntroImageResId(
|
||||
R.drawable.a11y_shortcut_type_quick_settings);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isShortcutAvailable() {
|
||||
return Flags.a11yQsShortcut()
|
||||
&& TileService.isQuickSettingsSupported()
|
||||
&& allTargetsHasQsTile()
|
||||
&& allTargetsHasValidQsTileUseCase();
|
||||
}
|
||||
|
||||
private boolean allTargetsHasQsTile() {
|
||||
AccessibilityManager accessibilityManager = mContext.getSystemService(
|
||||
AccessibilityManager.class);
|
||||
if (accessibilityManager == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<ComponentName, ComponentName> a11yFeatureToTileMap =
|
||||
accessibilityManager.getA11yFeatureToTileMap(UserHandle.myUserId());
|
||||
if (a11yFeatureToTileMap.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (String target : getShortcutTargets()) {
|
||||
ComponentName targetComponentName = ComponentName.unflattenFromString(target);
|
||||
if (!a11yFeatureToTileMap.containsKey(targetComponentName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all targets have valid QS Tile shortcut use case.
|
||||
*
|
||||
* <p>
|
||||
* Note: We don't want to promote the qs option in the edit shortcuts screen for
|
||||
* a standard AccessibilityService, because the Tile is provided by the owner of the
|
||||
* AccessibilityService, and they don't have control to enable the A11yService themselves
|
||||
* which makes the TileService not acting as the other a11y shortcut like FAB where the user
|
||||
* can turn on/off the feature by toggling the shortcut.
|
||||
*
|
||||
* A standard AccessibilityService normally won't create a TileService because the
|
||||
* above mentioned reason. In any case where the standard AccessibilityService provides a tile,
|
||||
* we'll hide it from the Setting's UI.
|
||||
* </p>
|
||||
*/
|
||||
private boolean allTargetsHasValidQsTileUseCase() {
|
||||
AccessibilityManager accessibilityManager = mContext.getSystemService(
|
||||
AccessibilityManager.class);
|
||||
if (accessibilityManager == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<AccessibilityServiceInfo> installedServices =
|
||||
accessibilityManager.getInstalledAccessibilityServiceList();
|
||||
final Set<String> standardA11yServices = new ArraySet<>();
|
||||
for (AccessibilityServiceInfo serviceInfo : installedServices) {
|
||||
if (AccessibilityUtils.getAccessibilityServiceFragmentType(serviceInfo)
|
||||
!= INVISIBLE_TOGGLE) {
|
||||
standardA11yServices.add(serviceInfo.getComponentName().flattenToString());
|
||||
}
|
||||
}
|
||||
|
||||
for (String target : getShortcutTargets()) {
|
||||
if (standardA11yServices.contains(target)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@ package com.android.settings.accessibility.shortcuts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.accessibility.Flags;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.Preference;
|
||||
@@ -116,6 +118,16 @@ public abstract class ShortcutOptionPreferenceController extends BasePreferenceC
|
||||
Set<String> shortcutTargets = getShortcutTargets();
|
||||
@ShortcutConstants.UserShortcutType int shortcutType = getShortcutType();
|
||||
|
||||
if (Flags.a11yQsShortcut()) {
|
||||
AccessibilityManager a11yManager = mContext.getSystemService(
|
||||
AccessibilityManager.class);
|
||||
if (a11yManager != null) {
|
||||
a11yManager.enableShortcutsForTargets(enable, shortcutType, shortcutTargets,
|
||||
UserHandle.myUserId());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
for (String target : shortcutTargets) {
|
||||
ShortcutUtils.optInValueToSettings(mContext, shortcutType, target);
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.internal.accessibility.AccessibilityShortcutController
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.Flags;
|
||||
|
||||
import com.android.internal.accessibility.common.ShortcutConstants;
|
||||
import com.android.settings.R;
|
||||
@@ -65,6 +66,9 @@ public abstract class SoftwareShortcutOptionPreferenceController
|
||||
@Override
|
||||
protected void enableShortcutForTargets(boolean enable) {
|
||||
super.enableShortcutForTargets(enable);
|
||||
if (Flags.a11yQsShortcut()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
// Update the A11y FAB size to large when the Magnification shortcut is enabled
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.internal.accessibility.AccessibilityShortcutController
|
||||
import android.content.Context;
|
||||
import android.icu.text.MessageFormat;
|
||||
import android.provider.Settings;
|
||||
import android.view.accessibility.Flags;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
@@ -105,6 +106,11 @@ public class TripleTapShortcutOptionController extends ShortcutOptionPreferenceC
|
||||
|
||||
@Override
|
||||
protected void enableShortcutForTargets(boolean enable) {
|
||||
if (Flags.a11yQsShortcut()) {
|
||||
super.enableShortcutForTargets(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
Settings.Secure.putInt(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
|
||||
|
||||
@@ -36,17 +36,17 @@ import java.util.Set;
|
||||
* A controller handles displaying the two fingers double tap shortcut option preference and
|
||||
* configuring the shortcut.
|
||||
*/
|
||||
public class TwoFingersDoubleTapShortcutOptionController
|
||||
public class TwoFingerDoubleTapShortcutOptionController
|
||||
extends ShortcutOptionPreferenceController {
|
||||
|
||||
public TwoFingersDoubleTapShortcutOptionController(Context context, String preferenceKey) {
|
||||
public TwoFingerDoubleTapShortcutOptionController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@ShortcutConstants.UserShortcutType
|
||||
@Override
|
||||
protected int getShortcutType() {
|
||||
return ShortcutConstants.UserShortcutType.TRIPLETAP;
|
||||
return ShortcutConstants.UserShortcutType.TWOFINGER_DOUBLETAP;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,6 +90,10 @@ public class TwoFingersDoubleTapShortcutOptionController
|
||||
|
||||
@Override
|
||||
protected void enableShortcutForTargets(boolean enable) {
|
||||
if (android.view.accessibility.Flags.a11yQsShortcut()) {
|
||||
super.enableShortcutForTargets(enable);
|
||||
return;
|
||||
}
|
||||
Settings.Secure.putInt(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.accessibility.shortcuts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.accessibility.Flags;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
@@ -64,6 +65,10 @@ public class VolumeKeysShortcutOptionController extends ShortcutOptionPreference
|
||||
@Override
|
||||
protected void enableShortcutForTargets(boolean enable) {
|
||||
super.enableShortcutForTargets(enable);
|
||||
if (Flags.a11yQsShortcut()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
AccessibilityUtil.skipVolumeShortcutDialogTimeoutRestriction(mContext);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user