Loading core/java/android/provider/Settings.java +17 −1 Original line number Diff line number Diff line Loading @@ -5481,6 +5481,20 @@ public final class Settings { */ public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled"; /** * Setting specifying if the accessibility shortcut is enabled. * @hide */ public static final String ACCESSIBILITY_SHORTCUT_ENABLED = "accessibility_shortcut_enabled"; /** * Setting specifying if the accessibility shortcut is enabled. * @hide */ public static final String ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN = "accessibility_shortcut_on_lock_screen"; /** * Setting specifying if the accessibility shortcut dialog has been shown to this user. * @hide Loading @@ -5489,7 +5503,7 @@ public final class Settings { "accessibility_shortcut_dialog_shown"; /** * Setting specifying the the accessibility service to be toggled via the accessibility * Setting specifying the accessibility service to be toggled via the accessibility * shortcut. Must be its flattened {@link ComponentName}. * @hide */ Loading Loading @@ -6984,6 +6998,8 @@ public final class Settings { ACCESSIBILITY_ENABLED, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, ACCESSIBILITY_SHORTCUT_ENABLED, ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ACCESSIBILITY_SPEAK_PASSWORD, ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, ACCESSIBILITY_CAPTIONING_PRESET, Loading core/res/res/values/strings.xml +8 −6 Original line number Diff line number Diff line Loading @@ -3929,22 +3929,24 @@ <!-- Dialog title for dialog shown when the accessibility shortcut is activated, and we want to confirm that the user understands what's going to happen--> <string name="accessibility_shortcut_warning_dialog_title">Accessibility Shortcut is ON</string> <string name="accessibility_shortcut_warning_dialog_title">Use Accessibility Shortcut?</string> <!-- Message shown in dialog when user is in the process of enabling the accessibility service via the volume buttons shortcut for the first time. [CHAR LIMIT=none] --> <string name="accessibility_shortcut_toogle_warning"> Turn <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g> on or off by holding down both volume buttons for 3 seconds.\n\nYou can change the service in Settings > Accessibility. When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g>\n\n You can change the feature in Settings > Accessibility. </string> <!-- Text in button that turns off the accessibility shortcut --> <string name="disable_accessibility_shortcut">Turn Off Shortcut</string> <string name="disable_accessibility_shortcut">Turn off Shortcut</string> <!-- Text in button that closes the warning dialog about the accessibility shortcut, leaving the shortcut enabled.--> <string name="leave_accessibility_shortcut_on">Leave on</string> <string name="leave_accessibility_shortcut_on">Use Shortcut</string> <!-- Text in toast to alert the user that the accessibility shortcut turned on an accessibility service.--> Loading packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java +13 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,19 @@ public class AccessibilityUtils { return context.getString(R.string.config_defaultAccessibilityService); } /** * Check if the accessibility shortcut is enabled for a user * * @param context A valid context * @param userId The user of interest * @return {@code true} if the shortcut is enabled for the user. {@code false} otherwise. * Note that the shortcut may be enabled, but no action associated with it. */ public static boolean isShortcutEnabled(Context context, int userId) { return Settings.Secure.getIntForUser(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 1, userId) == 1; } private static Set<ComponentName> getInstalledServices(Context context) { final Set<ComponentName> installedServices = new HashSet<>(); installedServices.clear(); Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -1920,7 +1920,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } ComponentName componentNameToEnable = ComponentName.unflattenFromString(componentNameToEnableString); if (componentNameToEnable.equals(userState.mServiceToEnableWithShortcut)) { if ((componentNameToEnable != null) && componentNameToEnable.equals(userState.mServiceToEnableWithShortcut)) { return false; } userState.mServiceToEnableWithShortcut = componentNameToEnable; Loading Loading @@ -1948,7 +1949,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (!shortcutServiceIsInstalled) { userState.mServiceToEnableWithShortcut = null; Settings.Secure.putStringForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "", userState.mUserId); Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null, userState.mUserId); Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0, userState.mUserId); } } Loading services/core/java/com/android/server/policy/AccessibilityShortcutController.java +44 −19 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.database.ContentObserver; import android.media.AudioAttributes; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.os.Vibrator; Loading Loading @@ -58,6 +59,9 @@ public class AccessibilityShortcutController { private final Context mContext; private AlertDialog mAlertDialog; private boolean mIsShortcutEnabled; private boolean mEnabledOnLockScreen; private int mUserId; // Visible for testing public FrameworkObjectProvider mFrameworkObjectProvider = new FrameworkObjectProvider(); Loading @@ -72,29 +76,55 @@ public class AccessibilityShortcutController { return context.getString(R.string.config_defaultAccessibilityService); } public AccessibilityShortcutController(Context context, Handler handler) { public AccessibilityShortcutController(Context context, Handler handler, int initialUserId) { mContext = context; // Keep track of state of shortcut mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE), false, new ContentObserver(handler) { // Keep track of state of shortcut settings final ContentObserver co = new ContentObserver(handler) { @Override public void onChange(boolean selfChange) { public void onChange(boolean selfChange, Uri uri, int userId) { if (userId == mUserId) { onSettingsChanged(); } }, UserHandle.USER_ALL); updateShortcutEnabled(); } }; mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE), false, co, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED), false, co, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN), false, co, UserHandle.USER_ALL); setCurrentUser(mUserId); } public void setCurrentUser(int currentUserId) { mUserId = currentUserId; onSettingsChanged(); } public boolean isAccessibilityShortcutAvailable() { return mIsShortcutEnabled; /** * Check if the shortcut is available. * * @param onLockScreen Whether or not the phone is currently locked. * * @return {@code true} if the shortcut is available */ public boolean isAccessibilityShortcutAvailable(boolean phoneLocked) { return mIsShortcutEnabled && (!phoneLocked || mEnabledOnLockScreen); } public void onSettingsChanged() { updateShortcutEnabled(); final boolean haveValidService = !TextUtils.isEmpty(getTargetServiceComponentNameString(mContext, mUserId)); final ContentResolver cr = mContext.getContentResolver(); final boolean enabled = Settings.Secure.getIntForUser( cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 1, mUserId) == 1; mEnabledOnLockScreen = Settings.Secure.getIntForUser( cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, 0, mUserId) == 1; mIsShortcutEnabled = enabled && haveValidService; } /** Loading Loading @@ -171,11 +201,6 @@ public class AccessibilityShortcutController { } } private void updateShortcutEnabled() { mIsShortcutEnabled = !TextUtils.isEmpty(getTargetServiceComponentNameString( mContext, UserHandle.myUserId())); } private AlertDialog createShortcutWarningDialog(int userId) { final AccessibilityServiceInfo serviceInfo = getInfoForTargetService(); Loading Loading
core/java/android/provider/Settings.java +17 −1 Original line number Diff line number Diff line Loading @@ -5481,6 +5481,20 @@ public final class Settings { */ public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled"; /** * Setting specifying if the accessibility shortcut is enabled. * @hide */ public static final String ACCESSIBILITY_SHORTCUT_ENABLED = "accessibility_shortcut_enabled"; /** * Setting specifying if the accessibility shortcut is enabled. * @hide */ public static final String ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN = "accessibility_shortcut_on_lock_screen"; /** * Setting specifying if the accessibility shortcut dialog has been shown to this user. * @hide Loading @@ -5489,7 +5503,7 @@ public final class Settings { "accessibility_shortcut_dialog_shown"; /** * Setting specifying the the accessibility service to be toggled via the accessibility * Setting specifying the accessibility service to be toggled via the accessibility * shortcut. Must be its flattened {@link ComponentName}. * @hide */ Loading Loading @@ -6984,6 +6998,8 @@ public final class Settings { ACCESSIBILITY_ENABLED, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, ACCESSIBILITY_SHORTCUT_ENABLED, ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ACCESSIBILITY_SPEAK_PASSWORD, ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, ACCESSIBILITY_CAPTIONING_PRESET, Loading
core/res/res/values/strings.xml +8 −6 Original line number Diff line number Diff line Loading @@ -3929,22 +3929,24 @@ <!-- Dialog title for dialog shown when the accessibility shortcut is activated, and we want to confirm that the user understands what's going to happen--> <string name="accessibility_shortcut_warning_dialog_title">Accessibility Shortcut is ON</string> <string name="accessibility_shortcut_warning_dialog_title">Use Accessibility Shortcut?</string> <!-- Message shown in dialog when user is in the process of enabling the accessibility service via the volume buttons shortcut for the first time. [CHAR LIMIT=none] --> <string name="accessibility_shortcut_toogle_warning"> Turn <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g> on or off by holding down both volume buttons for 3 seconds.\n\nYou can change the service in Settings > Accessibility. When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g>\n\n You can change the feature in Settings > Accessibility. </string> <!-- Text in button that turns off the accessibility shortcut --> <string name="disable_accessibility_shortcut">Turn Off Shortcut</string> <string name="disable_accessibility_shortcut">Turn off Shortcut</string> <!-- Text in button that closes the warning dialog about the accessibility shortcut, leaving the shortcut enabled.--> <string name="leave_accessibility_shortcut_on">Leave on</string> <string name="leave_accessibility_shortcut_on">Use Shortcut</string> <!-- Text in toast to alert the user that the accessibility shortcut turned on an accessibility service.--> Loading
packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java +13 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,19 @@ public class AccessibilityUtils { return context.getString(R.string.config_defaultAccessibilityService); } /** * Check if the accessibility shortcut is enabled for a user * * @param context A valid context * @param userId The user of interest * @return {@code true} if the shortcut is enabled for the user. {@code false} otherwise. * Note that the shortcut may be enabled, but no action associated with it. */ public static boolean isShortcutEnabled(Context context, int userId) { return Settings.Secure.getIntForUser(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 1, userId) == 1; } private static Set<ComponentName> getInstalledServices(Context context) { final Set<ComponentName> installedServices = new HashSet<>(); installedServices.clear(); Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -1920,7 +1920,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } ComponentName componentNameToEnable = ComponentName.unflattenFromString(componentNameToEnableString); if (componentNameToEnable.equals(userState.mServiceToEnableWithShortcut)) { if ((componentNameToEnable != null) && componentNameToEnable.equals(userState.mServiceToEnableWithShortcut)) { return false; } userState.mServiceToEnableWithShortcut = componentNameToEnable; Loading Loading @@ -1948,7 +1949,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (!shortcutServiceIsInstalled) { userState.mServiceToEnableWithShortcut = null; Settings.Secure.putStringForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "", userState.mUserId); Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null, userState.mUserId); Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0, userState.mUserId); } } Loading
services/core/java/com/android/server/policy/AccessibilityShortcutController.java +44 −19 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.database.ContentObserver; import android.media.AudioAttributes; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.os.Vibrator; Loading Loading @@ -58,6 +59,9 @@ public class AccessibilityShortcutController { private final Context mContext; private AlertDialog mAlertDialog; private boolean mIsShortcutEnabled; private boolean mEnabledOnLockScreen; private int mUserId; // Visible for testing public FrameworkObjectProvider mFrameworkObjectProvider = new FrameworkObjectProvider(); Loading @@ -72,29 +76,55 @@ public class AccessibilityShortcutController { return context.getString(R.string.config_defaultAccessibilityService); } public AccessibilityShortcutController(Context context, Handler handler) { public AccessibilityShortcutController(Context context, Handler handler, int initialUserId) { mContext = context; // Keep track of state of shortcut mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE), false, new ContentObserver(handler) { // Keep track of state of shortcut settings final ContentObserver co = new ContentObserver(handler) { @Override public void onChange(boolean selfChange) { public void onChange(boolean selfChange, Uri uri, int userId) { if (userId == mUserId) { onSettingsChanged(); } }, UserHandle.USER_ALL); updateShortcutEnabled(); } }; mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE), false, co, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED), false, co, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN), false, co, UserHandle.USER_ALL); setCurrentUser(mUserId); } public void setCurrentUser(int currentUserId) { mUserId = currentUserId; onSettingsChanged(); } public boolean isAccessibilityShortcutAvailable() { return mIsShortcutEnabled; /** * Check if the shortcut is available. * * @param onLockScreen Whether or not the phone is currently locked. * * @return {@code true} if the shortcut is available */ public boolean isAccessibilityShortcutAvailable(boolean phoneLocked) { return mIsShortcutEnabled && (!phoneLocked || mEnabledOnLockScreen); } public void onSettingsChanged() { updateShortcutEnabled(); final boolean haveValidService = !TextUtils.isEmpty(getTargetServiceComponentNameString(mContext, mUserId)); final ContentResolver cr = mContext.getContentResolver(); final boolean enabled = Settings.Secure.getIntForUser( cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 1, mUserId) == 1; mEnabledOnLockScreen = Settings.Secure.getIntForUser( cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, 0, mUserId) == 1; mIsShortcutEnabled = enabled && haveValidService; } /** Loading Loading @@ -171,11 +201,6 @@ public class AccessibilityShortcutController { } } private void updateShortcutEnabled() { mIsShortcutEnabled = !TextUtils.isEmpty(getTargetServiceComponentNameString( mContext, UserHandle.myUserId())); } private AlertDialog createShortcutWarningDialog(int userId) { final AccessibilityServiceInfo serviceInfo = getInfoForTargetService(); Loading