diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2012-05-30 14:06:32 -0700 |
---|---|---|
committer | Svetoslav Ganov <svetoslavganov@google.com> | 2012-05-30 18:41:08 -0700 |
commit | 9a4c5cd19106c3021eeead27fbc2aa05ad7d0d18 (patch) | |
tree | 2bb45fef9711f8d360bdd36b87907ef3c0c45fed | |
parent | 5ab6e12b450d13c8eb501001c7a8669826b86ea4 (diff) | |
download | frameworks_base-9a4c5cd19106c3021eeead27fbc2aa05ad7d0d18.zip frameworks_base-9a4c5cd19106c3021eeead27fbc2aa05ad7d0d18.tar.gz frameworks_base-9a4c5cd19106c3021eeead27fbc2aa05ad7d0d18.tar.bz2 |
Ask to enable touch exploration only the first time it enables the feature.
1. Now we are asking the user to grant permission to the service to enable
touch exploration only the first time this service is enabled. If the
service was uninstalled and then later installed we ask the user again.
This avoids the scenario in which rebooting the device or upgrading an
accessibility service leaves the device in a state in which the user
cannot interact with.
bug:6582088
Change-Id: I51d24e4892b3b48c9fb11dfb09ec1118502ba526
3 files changed, 163 insertions, 69 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 8b7ee0e..8630204 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2886,6 +2886,15 @@ public final class Settings { "enabled_accessibility_services"; /** + * List of the accessibility services to which the user has graned + * permission to put the device into touch exploration mode. + * + * @hide + */ + public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES = + "touch_exploration_granted_accessibility_services"; + + /** * Whether to speak passwords while in accessibility mode. */ public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password"; @@ -4292,6 +4301,7 @@ public final class Settings { ACCESSIBILITY_SCRIPT_INJECTION, BACKUP_AUTO_RESTORE, ENABLED_ACCESSIBILITY_SERVICES, + TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, TOUCH_EXPLORATION_ENABLED, ACCESSIBILITY_ENABLED, ACCESSIBILITY_SPEAK_PASSWORD, diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 039efbd..3e8f512 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -104,10 +104,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE = "registerUiTestAutomationService"; + private static final char COMPONENT_NAME_SEPARATOR = ':'; + private static final int OWN_PROCESS_ID = android.os.Process.myPid(); private static final int MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG = 1; + private static final int MSG_TOGGLE_TOUCH_EXPLORATION = 2; + private static int sIdCounter = 0; private static int sNextWindowId; @@ -127,12 +131,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>(); + private final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<ComponentName>(); + private final SparseArray<AccessibilityConnectionWrapper> mWindowIdToInteractionConnectionWrapperMap = new SparseArray<AccessibilityConnectionWrapper>(); private final SparseArray<IBinder> mWindowIdToWindowTokenMap = new SparseArray<IBinder>(); - private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(':'); + private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); private final Rect mTempRect = new Rect(); @@ -164,6 +170,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private boolean mTouchExplorationGestureStarted; + private AlertDialog mEnableTouchExplorationDialog; + /** * Creates a new instance. * @@ -208,7 +216,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { String compPkg = comp.getPackageName(); if (compPkg.equals(packageName)) { it.remove(); - updateEnabledAccessibilitySerivcesSettingLocked(mEnabledServices); + // Update the enabled services setting. + persistComponentNamesToSettingLocked( + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, + mEnabledServices); + // Update the touch exploration granted services setting. + mTouchExplorationGrantedServices.remove(comp); + persistComponentNamesToSettingLocked( + Settings.Secure. + TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, + mEnabledServices); return; } } @@ -219,7 +236,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { synchronized (mLock) { - boolean changed = false; Iterator<ComponentName> it = mEnabledServices.iterator(); while (it.hasNext()) { ComponentName comp = it.next(); @@ -230,13 +246,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return true; } it.remove(); - changed = true; + persistComponentNamesToSettingLocked( + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, + mEnabledServices); } } } - if (changed) { - updateEnabledAccessibilitySerivcesSettingLocked(mEnabledServices); - } return false; } } @@ -248,33 +263,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // We will update when the automation service dies. if (mUiAutomationService == null) { populateAccessibilityServiceListLocked(); + populateEnabledAccessibilityServicesLocked(); + populateTouchExplorationGrantedAccessibilityServicesLocked(); handleAccessibilityEnabledSettingChangedLocked(); handleTouchExplorationEnabledSettingChangedLocked(); updateInputFilterLocked(); sendStateToClientsLocked(); } } - return; } super.onReceive(context, intent); } - - private void updateEnabledAccessibilitySerivcesSettingLocked( - Set<ComponentName> enabledServices) { - Iterator<ComponentName> it = enabledServices.iterator(); - StringBuilder str = new StringBuilder(); - while (it.hasNext()) { - if (str.length() > 0) { - str.append(':'); - } - str.append(it.next().flattenToShortString()); - } - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, - str.toString()); - } }; // package changes @@ -338,6 +339,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { synchronized (mLock) { // We will update when the automation service dies. if (mUiAutomationService == null) { + populateEnabledAccessibilityServicesLocked(); + manageServicesLocked(); + } + } + } + }); + + Uri touchExplorationGrantedServicesUri = Settings.Secure.getUriFor( + Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES); + contentResolver.registerContentObserver(touchExplorationGrantedServicesUri, false, + new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + synchronized (mLock) { + // We will update when the automation service dies. + if (mUiAutomationService == null) { + populateTouchExplorationGrantedAccessibilityServicesLocked(); + unbindAllServicesLocked(); manageServicesLocked(); } } @@ -647,6 +667,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } + private void populateEnabledAccessibilityServicesLocked() { + populateComponentNamesFromSettingLocked( + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, + mEnabledServices); + } + + private void populateTouchExplorationGrantedAccessibilityServicesLocked() { + populateComponentNamesFromSettingLocked( + Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, + mTouchExplorationGrantedServices); + } + /** * Performs {@link AccessibilityService}s delayed notification. The delay is configurable * and denotes the period after the last event before notifying the service. @@ -689,7 +721,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { mServices.add(service); mComponentNameToServiceMap.put(service.mComponentName, service); updateInputFilterLocked(); - tryEnableTouchExploration(service); + tryEnableTouchExplorationLocked(service); } catch (RemoteException e) { /* do nothing */ } @@ -710,7 +742,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { service.unlinkToOwnDeath(); service.dispose(); updateInputFilterLocked(); - tryDisableTouchExploration(service); + tryDisableTouchExplorationLocked(service); return removed; } @@ -762,7 +794,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { * Manages services by starting enabled ones and stopping disabled ones. */ private void manageServicesLocked() { - populateEnabledServicesLocked(mEnabledServices); final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices, mEnabledServices); // No enabled installed services => disable accessibility to avoid @@ -789,20 +820,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } /** - * Populates a list with the {@link ComponentName}s of all enabled - * {@link AccessibilityService}s. + * Populates a set with the {@link ComponentName}s stored in a colon + * separated value setting. * - * @param enabledServices The list. + * @param settingName The setting to parse. + * @param outComponentNames The output component names. */ - private void populateEnabledServicesLocked(Set<ComponentName> enabledServices) { - enabledServices.clear(); + private void populateComponentNamesFromSettingLocked(String settingName, + Set<ComponentName> outComponentNames) { + outComponentNames.clear(); - String servicesValue = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + String settingValue = Settings.Secure.getString(mContext.getContentResolver(), settingName); - if (servicesValue != null) { + if (settingValue != null) { TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; - splitter.setString(servicesValue); + splitter.setString(settingValue); while (splitter.hasNext()) { String str = splitter.next(); if (str == null || str.length() <= 0) { @@ -810,13 +842,32 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } ComponentName enabledService = ComponentName.unflattenFromString(str); if (enabledService != null) { - enabledServices.add(enabledService); + outComponentNames.add(enabledService); } } } } /** + * Persists the component names in the specified setting in a + * colon separated fashion. + * + * @param settingName The setting name. + * @param componentNames The component names. + */ + private void persistComponentNamesToSettingLocked(String settingName, + Set<ComponentName> componentNames) { + StringBuilder builder = new StringBuilder(); + for (ComponentName componentName : componentNames) { + if (builder.length() > 0) { + builder.append(COMPONENT_NAME_SEPARATOR); + } + builder.append(componentName.flattenToShortString()); + } + Settings.Secure.putString(mContext.getContentResolver(), settingName, builder.toString()); + } + + /** * Updates the state of each service by starting (or keeping running) enabled ones and * stopping the rest. * @@ -935,20 +986,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1; } - private void tryEnableTouchExploration(final Service service) { + private void tryEnableTouchExplorationLocked(final Service service) { if (!mIsTouchExplorationEnabled && service.mRequestTouchExplorationMode) { - if (!service.mIsAutomation) { + final boolean canToggleTouchExploration = mTouchExplorationGrantedServices.contains( + service.mComponentName); + if (!service.mIsAutomation && !canToggleTouchExploration) { mMainHandler.obtainMessage(MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG, service).sendToTarget(); } else { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1); + mMainHandler.obtainMessage(MSG_TOGGLE_TOUCH_EXPLORATION, 1, 0).sendToTarget(); } } } - private void tryDisableTouchExploration(Service service) { - if (mIsTouchExplorationEnabled && service.mReqeustTouchExplorationMode) { + private void tryDisableTouchExplorationLocked(Service service) { + if (mIsTouchExplorationEnabled) { synchronized (mLock) { final int serviceCount = mServices.size(); for (int i = 0; i < serviceCount; i++) { @@ -957,8 +1009,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return; } } - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0); + mMainHandler.obtainMessage(MSG_TOGGLE_TOUCH_EXPLORATION, 0, 0).sendToTarget(); } } } @@ -995,32 +1046,54 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public void handleMessage(Message msg) { final int type = msg.what; switch (type) { + case MSG_TOGGLE_TOUCH_EXPLORATION: { + final int value = msg.arg1; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.TOUCH_EXPLORATION_ENABLED, value); + } break; case MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG: { - Service service = (Service) msg.obj; + final Service service = (Service) msg.obj; String label = service.mResolveInfo.loadLabel( mContext.getPackageManager()).toString(); - final AlertDialog dialog = new AlertDialog.Builder(mContext) - .setIcon(android.R.drawable.ic_dialog_alert) - .setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1); - } - }) - .setNegativeButton(android.R.string.cancel, new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }) - .setTitle(R.string.enable_explore_by_touch_warning_title) - .setMessage(mContext.getString( - R.string.enable_explore_by_touch_warning_message, label)) - .create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG); - dialog.setCanceledOnTouchOutside(true); - dialog.show(); + synchronized (mLock) { + if (mIsTouchExplorationEnabled) { + return; + } + if (mEnableTouchExplorationDialog != null + && mEnableTouchExplorationDialog.isShowing()) { + return; + } + mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(android.R.string.ok, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // The user allowed the service to toggle touch exploration. + mTouchExplorationGrantedServices.add(service.mComponentName); + persistComponentNamesToSettingLocked( + Settings.Secure. + TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, + mTouchExplorationGrantedServices); + // Enable touch exploration. + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1); + } + }) + .setNegativeButton(android.R.string.cancel, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .setTitle(R.string.enable_explore_by_touch_warning_title) + .setMessage(mContext.getString( + R.string.enable_explore_by_touch_warning_message, label)) + .create(); + mEnableTouchExplorationDialog.getWindow().setType( + WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG); + mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true); + mEnableTouchExplorationDialog.show(); + } } } } @@ -1143,8 +1216,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { mRequestTouchExplorationMode = (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0; + // If this service is up and running we may have to enable touch + // exploration, otherwise this will happen when the service connects. synchronized (mLock) { - tryAddServiceLocked(this); + if (isConfigured()) { + if (mRequestTouchExplorationMode) { + tryEnableTouchExplorationLocked(this); + } else { + tryDisableTouchExplorationLocked(this); + } + } } } @@ -1496,6 +1577,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (mIsAutomation) { mUiAutomationService = null; + populateEnabledAccessibilityServicesLocked(); + populateTouchExplorationGrantedAccessibilityServicesLocked(); + handleAccessibilityEnabledSettingChangedLocked(); sendStateToClientsLocked(); diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java index b0b2b8d..4c38ab9 100644 --- a/services/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/java/com/android/server/accessibility/TouchExplorer.java @@ -1532,7 +1532,7 @@ public class TouchExplorer { */ public ReceivedPointerTracker(Context context) { mThresholdActivePointer = - ViewConfiguration.get(context).getScaledTouchSlop() * COEFFICIENT_ACTIVE_POINTER; + ViewConfiguration.get(context).getScaledTouchSlop() * COEFFICIENT_ACTIVE_POINTER;//Heie govna } /** |