Loading core/java/android/accessibilityservice/AccessibilityServiceInfo.java +1 −9 Original line number Diff line number Diff line Loading @@ -150,18 +150,10 @@ public class AccessibilityServiceInfo implements Parcelable { * flag does not guarantee that the device will not be in touch exploration * mode since there may be another enabled service that requested it. * <p> * For accessibility services targeting API version higher than * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set * this flag have to request the * Clients that want to set this flag have to request the * {@link android.Manifest.permission#CAN_REQUEST_TOUCH_EXPLORATION_MODE} * permission or the flag will be ignored. * </p> * <p> * Services targeting API version equal to or lower than * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e. * the first time they are run, if this flag is specified, a dialog is * shown to the user to confirm enabling explore by touch. * </p> */ public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004; Loading core/java/android/provider/Settings.java +1 −0 Original line number Diff line number Diff line Loading @@ -3351,6 +3351,7 @@ public final class Settings { * * @hide */ @Deprecated public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES = "touch_exploration_granted_accessibility_services"; Loading core/res/res/values/strings.xml +2 −21 Original line number Diff line number Diff line Loading @@ -950,8 +950,8 @@ <string name="permlab_canRequestEnahncedWebAccessibility">request enhanced web accessibility</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_canRequestEnahncedWebAccessibility">Allows the hoder to request enabling of web accessibility enhancements. For example, installing scripts to make app content more accessible.</string> enabling of web accessibility enhancements. For example, installing scripts from Google to make app content more accessible.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_bindTextService">bind to a text service</string> Loading Loading @@ -2714,25 +2714,6 @@ <!-- SearchView accessibility description for voice button [CHAR LIMIT=NONE] --> <string name="searchview_description_voice">Voice search</string> <!-- Title for a warning message about the interaction model changes after allowing an accessibility service to put the device into explore by touch mode, displayed as a dialog message when the user selects to enables the service. (default). [CHAR LIMIT=45] --> <string name="enable_explore_by_touch_warning_title">Enable Explore by Touch?</string> <!-- Summary for a warning message about the interaction model changes after allowing an accessibility service to put the device into explore by touch mode, displayed as a dialog message when the user selects to enables the service. (tablet). [CHAR LIMIT=NONE] --> <string name="enable_explore_by_touch_warning_message" product="tablet"> <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the tablet.</string> <!-- Summary for a warning message about the interaction model changes after allowing an accessibility service to put the device into explore by touch mode, displayed as a dialog message when the user selects to enables the service. (default). [CHAR LIMIT=NONE] --> <string name="enable_explore_by_touch_warning_message" product="default"> <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the phone.</string> <!-- String used to display the date. This is the string to say something happened 1 month ago. --> <string name="oneMonthDurationPast">1 month ago</string> <!-- String used to display the date. This is the string to say something happened more than 1 month ago. --> Loading packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +17 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' // is properly propagated through your change. Not doing so will result in a loss of user // settings. private static final int DATABASE_VERSION = 96; private static final int DATABASE_VERSION = 97; private Context mContext; private int mUserHandle; Loading Loading @@ -1536,6 +1536,22 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 96; } if (upgradeVersion == 96) { // Remove Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES if (mUserHandle == UserHandle.USER_OWNER) { db.beginTransaction(); try { db.execSQL("DELETE FROM system WHERE name='" + Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES + "'"); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } upgradeVersion = 97; } // *** Remember to update DATABASE_VERSION above! if (upgradeVersion != currentVersion) { Loading services/java/com/android/server/accessibility/AccessibilityManagerService.java +36 −215 Original line number Diff line number Diff line Loading @@ -23,15 +23,12 @@ import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.accessibilityservice.IAccessibilityServiceConnection; import android.app.AlertDialog; import android.app.PendingIntent; import android.app.StatusBarManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; Loading Loading @@ -70,7 +67,6 @@ import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MagnificationSpec; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityManager; Loading Loading @@ -161,8 +157,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private Service mQueryBridge; private AlertDialog mEnableTouchExplorationDialog; private AccessibilityInputFilter mInputFilter; private boolean mHasInputFilter; Loading Loading @@ -250,12 +244,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { persistComponentNamesToSettingLocked( Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, state.mEnabledServices, userId); // Update the touch exploration granted services setting. state.mTouchExplorationGrantedServices.remove(comp); persistComponentNamesToSettingLocked( Settings.Secure. TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, state.mEnabledServices, userId); return; } } Loading Loading @@ -570,8 +558,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { userState.mIsDisplayMagnificationEnabled = false; userState.mEnabledServices.clear(); userState.mEnabledServices.add(service); userState.mTouchExplorationGrantedServices.clear(); userState.mTouchExplorationGrantedServices.add(service); // Update the internal state. performServiceManagementLocked(userState); scheduleUpdateInputFilter(userState); Loading Loading @@ -845,12 +831,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { userState.mEnabledServices); } private void populateTouchExplorationGrantedAccessibilityServicesLocked(UserState userState) { populateComponentNamesFromSettingLocked( Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, userState.mUserId, userState.mTouchExplorationGrantedServices); } /** * Performs {@link AccessibilityService}s delayed notification. The delay is configurable * and denotes the period after the last event before notifying the service. Loading Loading @@ -1143,54 +1123,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } private void showEnableTouchExplorationDialog(final Service service) { String label = service.mResolveInfo.loadLabel( mContext.getPackageManager()).toString(); synchronized (mLock) { final UserState state = getCurrentUserStateLocked(); if (state.mIsTouchExplorationEnabled) { return; } if (mEnableTouchExplorationDialog != null && mEnableTouchExplorationDialog.isShowing()) { return; } mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext) .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // The user allowed the service to toggle touch exploration. state.mTouchExplorationGrantedServices.add(service.mComponentName); persistComponentNamesToSettingLocked( Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, state.mTouchExplorationGrantedServices, state.mUserId); // Enable touch exploration. Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId); } }) .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_SYSTEM_ALERT); mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true); mEnableTouchExplorationDialog.show(); } } private int getClientState(UserState userState) { int clientState = 0; if (userState.mIsAccessibilityEnabled) { Loading @@ -1206,16 +1138,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private void recreateInternalStateLocked(UserState userState) { populateInstalledAccessibilityServiceLocked(userState); populateEnabledAccessibilityServicesLocked(userState); populateTouchExplorationGrantedAccessibilityServicesLocked(userState); populatedEnhancedWebAccessibilityEnabledChangedLocked(userState); handleTouchExplorationEnabledSettingChangedLocked(userState); handleDisplayMagnificationEnabledSettingChangedLocked(userState); handleAccessibilityEnabledSettingChangedLocked(userState); handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState); performServiceManagementLocked(userState); scheduleUpdateInputFilter(userState); scheduleSendStateToClientsLocked(userState); } Loading Loading @@ -1247,61 +1175,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { 0, userState.mUserId) == 1; } private void handleTouchExplorationGrantedAccessibilityServicesChangedLocked( UserState userState) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId); final int serviceCount = userState.mServices.size(); for (int i = 0; i < serviceCount; i++) { Service service = userState.mServices.get(i); tryEnableTouchExplorationLocked(service); } } private void populatedEnhancedWebAccessibilityEnabledChangedLocked(UserState userState) { userState.mIsEnhancedWebAccessibilityEnabled = Settings.Secure.getIntForUser( mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, userState.mUserId) == 1; } private void tryEnableTouchExplorationLocked(Service service) { if (!service.canReceiveEventsLocked() || !service.mRequestTouchExplorationMode) { if (!service.mRequestTouchExplorationMode || !service.canReceiveEventsLocked()) { return; } UserState userState = getUserStateLocked(service.mUserId); if (userState.mIsTouchExplorationEnabled) { return; } // UI test automation service can always enable it. if (service.mIsAutomation) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId); return; } if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1) { // Up to JB-MR1 we had a white list with services that can enable touch // exploration. When a service is first started we show a dialog to the // use to get a permission to white list the service. if (!userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) { if (mEnableTouchExplorationDialog == null || (mEnableTouchExplorationDialog != null && !mEnableTouchExplorationDialog.isShowing())) { showEnableTouchExplorationDialog(service); } } else { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId); } } else { // Starting in JB-MR2 we request a permission to allow a service to enable // touch exploration and do not care if the service is in the white list. if (mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE, service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED) { if (!userState.mIsTouchExplorationEnabled) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId); } Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, userState.mUserId); } } Loading @@ -1310,53 +1191,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return; } UserState userState = getUserStateLocked(service.mUserId); if (!userState.mIsTouchExplorationEnabled) { return; } if (userState.mIsTouchExplorationEnabled) { final int serviceCount = userState.mServices.size(); for (int i = 0; i < serviceCount; i++) { Service other = userState.mServices.get(i); if (other != service) { if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1) { // Up to JB-MR1 we had a white list with services that can enable touch // exploration. When a service is first started we show a dialog to the // use to get a permission to white list the service. if (other.mRequestTouchExplorationMode && userState.mTouchExplorationGrantedServices.contains( service.mComponentName)) { // A white-listed service wants touch exploration, do not disable. return; } } else { // Starting in JB-MR2 we request a permission to allow a service to enable // touch exploration and do not care if the service is in the white list. if (other.mRequestTouchExplorationMode && (service.mIsAutomation || mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE, service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED)) { // A service with permission wants touch exploration, do not disable. if (other != service && other.mRequestTouchExplorationMode) { return; } } } } Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId); } } private void tryEnableEnhancedWebAccessibilityLocked(Service service) { if (!service.canReceiveEventsLocked() || !service.mRequestEnhancedWebAccessibility ) { if (!service.mRequestEnhancedWebAccessibility || !service.canReceiveEventsLocked()) { return; } UserState userState = getUserStateLocked(service.mUserId); if (userState.mIsEnhancedWebAccessibilityEnabled) { return; } // Requested and can enabled, do it. if (service.mRequestEnhancedWebAccessibility && canEnabledEnhancedWebAccessibility(service)) { if (!userState.mIsEnhancedWebAccessibilityEnabled) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1, userState.mUserId); } Loading @@ -1367,26 +1220,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return; } UserState userState = getUserStateLocked(service.mUserId); if (!userState.mIsEnhancedWebAccessibilityEnabled) { return; } if (userState.mIsEnhancedWebAccessibilityEnabled) { final int serviceCount = userState.mServices.size(); for (int i = 0; i < serviceCount; i++) { Service other = userState.mServices.get(i); if (other != service && other.mRequestEnhancedWebAccessibility && canEnabledEnhancedWebAccessibility(other)) { // One service requests the feature, do not disable. if (other != service && other.mRequestEnhancedWebAccessibility) { return; } } Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, service.mUserId); Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, userState.mUserId); } private boolean canEnabledEnhancedWebAccessibility(Service service) { return (service.mIsAutomation || mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY, service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED); } @Override Loading Loading @@ -1683,11 +1527,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS : 0; if (mResolveInfo != null) { String packageName = mResolveInfo.serviceInfo.packageName; if (mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE, packageName) == PackageManager.PERMISSION_GRANTED) { mRequestTouchExplorationMode = (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0; } if (mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY, packageName) == PackageManager.PERMISSION_GRANTED) { mRequestEnhancedWebAccessibility = (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0; } } // If this service is up and running we may have to enable touch // exploration or enhanced web accessibility, otherwise this will Loading Loading @@ -2598,9 +2453,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>(); public final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<ComponentName>(); public final SparseArray<AccessibilityConnectionWrapper> mInteractionConnections = new SparseArray<AccessibilityConnectionWrapper>(); Loading Loading @@ -2638,7 +2490,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { mEnabledServices.clear(); mEnabledServices.addAll(userState.mEnabledServices); mTouchExplorationGrantedServices.clear(); mTouchExplorationGrantedServices.addAll(userState.mTouchExplorationGrantedServices); } public void applyTo(UserState userState) { Loading @@ -2648,8 +2499,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { userState.mIsDisplayMagnificationEnabled = mIsDisplayMagnificationEnabled; userState.mEnabledServices.clear(); userState.mEnabledServices.addAll(mEnabledServices); userState.mTouchExplorationGrantedServices.clear(); userState.mTouchExplorationGrantedServices.addAll(mTouchExplorationGrantedServices); } public void clear() { Loading Loading @@ -2677,12 +2526,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final Uri mEnabledAccessibilityServicesUri = Settings.Secure.getUriFor( Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES); private final Uri mAccessibilityScriptInjectionUri = Settings.Secure .getUriFor(Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION); public AccessibilityContentObserver(Handler handler) { super(handler); } Loading @@ -2696,11 +2539,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { false, this, UserHandle.USER_ALL); contentResolver.registerContentObserver(mEnabledAccessibilityServicesUri, false, this, UserHandle.USER_ALL); contentResolver.registerContentObserver( mTouchExplorationGrantedAccessibilityServicesUri, false, this, UserHandle.USER_ALL); contentResolver.registerContentObserver(mAccessibilityScriptInjectionUri, false, this, UserHandle.USER_ALL); } @Override Loading Loading @@ -2745,23 +2583,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { manageServicesLocked(userState); } } } else if (mTouchExplorationGrantedAccessibilityServicesUri.equals(uri)) { synchronized (mLock) { // We will update when the automation service dies. if (mUiAutomationService == null) { UserState userState = getCurrentUserStateLocked(); populateTouchExplorationGrantedAccessibilityServicesLocked(userState); handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState); } } } else if (mAccessibilityScriptInjectionUri.equals(uri)) { synchronized (mLock) { // We will update when the automation service dies. if (mUiAutomationService == null) { UserState userState = getCurrentUserStateLocked(); populatedEnhancedWebAccessibilityEnabledChangedLocked(userState); } } } } } Loading Loading
core/java/android/accessibilityservice/AccessibilityServiceInfo.java +1 −9 Original line number Diff line number Diff line Loading @@ -150,18 +150,10 @@ public class AccessibilityServiceInfo implements Parcelable { * flag does not guarantee that the device will not be in touch exploration * mode since there may be another enabled service that requested it. * <p> * For accessibility services targeting API version higher than * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set * this flag have to request the * Clients that want to set this flag have to request the * {@link android.Manifest.permission#CAN_REQUEST_TOUCH_EXPLORATION_MODE} * permission or the flag will be ignored. * </p> * <p> * Services targeting API version equal to or lower than * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e. * the first time they are run, if this flag is specified, a dialog is * shown to the user to confirm enabling explore by touch. * </p> */ public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004; Loading
core/java/android/provider/Settings.java +1 −0 Original line number Diff line number Diff line Loading @@ -3351,6 +3351,7 @@ public final class Settings { * * @hide */ @Deprecated public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES = "touch_exploration_granted_accessibility_services"; Loading
core/res/res/values/strings.xml +2 −21 Original line number Diff line number Diff line Loading @@ -950,8 +950,8 @@ <string name="permlab_canRequestEnahncedWebAccessibility">request enhanced web accessibility</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_canRequestEnahncedWebAccessibility">Allows the hoder to request enabling of web accessibility enhancements. For example, installing scripts to make app content more accessible.</string> enabling of web accessibility enhancements. For example, installing scripts from Google to make app content more accessible.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_bindTextService">bind to a text service</string> Loading Loading @@ -2714,25 +2714,6 @@ <!-- SearchView accessibility description for voice button [CHAR LIMIT=NONE] --> <string name="searchview_description_voice">Voice search</string> <!-- Title for a warning message about the interaction model changes after allowing an accessibility service to put the device into explore by touch mode, displayed as a dialog message when the user selects to enables the service. (default). [CHAR LIMIT=45] --> <string name="enable_explore_by_touch_warning_title">Enable Explore by Touch?</string> <!-- Summary for a warning message about the interaction model changes after allowing an accessibility service to put the device into explore by touch mode, displayed as a dialog message when the user selects to enables the service. (tablet). [CHAR LIMIT=NONE] --> <string name="enable_explore_by_touch_warning_message" product="tablet"> <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the tablet.</string> <!-- Summary for a warning message about the interaction model changes after allowing an accessibility service to put the device into explore by touch mode, displayed as a dialog message when the user selects to enables the service. (default). [CHAR LIMIT=NONE] --> <string name="enable_explore_by_touch_warning_message" product="default"> <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the phone.</string> <!-- String used to display the date. This is the string to say something happened 1 month ago. --> <string name="oneMonthDurationPast">1 month ago</string> <!-- String used to display the date. This is the string to say something happened more than 1 month ago. --> Loading
packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +17 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' // is properly propagated through your change. Not doing so will result in a loss of user // settings. private static final int DATABASE_VERSION = 96; private static final int DATABASE_VERSION = 97; private Context mContext; private int mUserHandle; Loading Loading @@ -1536,6 +1536,22 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 96; } if (upgradeVersion == 96) { // Remove Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES if (mUserHandle == UserHandle.USER_OWNER) { db.beginTransaction(); try { db.execSQL("DELETE FROM system WHERE name='" + Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES + "'"); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } upgradeVersion = 97; } // *** Remember to update DATABASE_VERSION above! if (upgradeVersion != currentVersion) { Loading
services/java/com/android/server/accessibility/AccessibilityManagerService.java +36 −215 Original line number Diff line number Diff line Loading @@ -23,15 +23,12 @@ import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.accessibilityservice.IAccessibilityServiceConnection; import android.app.AlertDialog; import android.app.PendingIntent; import android.app.StatusBarManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; Loading Loading @@ -70,7 +67,6 @@ import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MagnificationSpec; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityManager; Loading Loading @@ -161,8 +157,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private Service mQueryBridge; private AlertDialog mEnableTouchExplorationDialog; private AccessibilityInputFilter mInputFilter; private boolean mHasInputFilter; Loading Loading @@ -250,12 +244,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { persistComponentNamesToSettingLocked( Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, state.mEnabledServices, userId); // Update the touch exploration granted services setting. state.mTouchExplorationGrantedServices.remove(comp); persistComponentNamesToSettingLocked( Settings.Secure. TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, state.mEnabledServices, userId); return; } } Loading Loading @@ -570,8 +558,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { userState.mIsDisplayMagnificationEnabled = false; userState.mEnabledServices.clear(); userState.mEnabledServices.add(service); userState.mTouchExplorationGrantedServices.clear(); userState.mTouchExplorationGrantedServices.add(service); // Update the internal state. performServiceManagementLocked(userState); scheduleUpdateInputFilter(userState); Loading Loading @@ -845,12 +831,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { userState.mEnabledServices); } private void populateTouchExplorationGrantedAccessibilityServicesLocked(UserState userState) { populateComponentNamesFromSettingLocked( Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, userState.mUserId, userState.mTouchExplorationGrantedServices); } /** * Performs {@link AccessibilityService}s delayed notification. The delay is configurable * and denotes the period after the last event before notifying the service. Loading Loading @@ -1143,54 +1123,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } private void showEnableTouchExplorationDialog(final Service service) { String label = service.mResolveInfo.loadLabel( mContext.getPackageManager()).toString(); synchronized (mLock) { final UserState state = getCurrentUserStateLocked(); if (state.mIsTouchExplorationEnabled) { return; } if (mEnableTouchExplorationDialog != null && mEnableTouchExplorationDialog.isShowing()) { return; } mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext) .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // The user allowed the service to toggle touch exploration. state.mTouchExplorationGrantedServices.add(service.mComponentName); persistComponentNamesToSettingLocked( Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, state.mTouchExplorationGrantedServices, state.mUserId); // Enable touch exploration. Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId); } }) .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_SYSTEM_ALERT); mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true); mEnableTouchExplorationDialog.show(); } } private int getClientState(UserState userState) { int clientState = 0; if (userState.mIsAccessibilityEnabled) { Loading @@ -1206,16 +1138,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private void recreateInternalStateLocked(UserState userState) { populateInstalledAccessibilityServiceLocked(userState); populateEnabledAccessibilityServicesLocked(userState); populateTouchExplorationGrantedAccessibilityServicesLocked(userState); populatedEnhancedWebAccessibilityEnabledChangedLocked(userState); handleTouchExplorationEnabledSettingChangedLocked(userState); handleDisplayMagnificationEnabledSettingChangedLocked(userState); handleAccessibilityEnabledSettingChangedLocked(userState); handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState); performServiceManagementLocked(userState); scheduleUpdateInputFilter(userState); scheduleSendStateToClientsLocked(userState); } Loading Loading @@ -1247,61 +1175,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { 0, userState.mUserId) == 1; } private void handleTouchExplorationGrantedAccessibilityServicesChangedLocked( UserState userState) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId); final int serviceCount = userState.mServices.size(); for (int i = 0; i < serviceCount; i++) { Service service = userState.mServices.get(i); tryEnableTouchExplorationLocked(service); } } private void populatedEnhancedWebAccessibilityEnabledChangedLocked(UserState userState) { userState.mIsEnhancedWebAccessibilityEnabled = Settings.Secure.getIntForUser( mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, userState.mUserId) == 1; } private void tryEnableTouchExplorationLocked(Service service) { if (!service.canReceiveEventsLocked() || !service.mRequestTouchExplorationMode) { if (!service.mRequestTouchExplorationMode || !service.canReceiveEventsLocked()) { return; } UserState userState = getUserStateLocked(service.mUserId); if (userState.mIsTouchExplorationEnabled) { return; } // UI test automation service can always enable it. if (service.mIsAutomation) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId); return; } if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1) { // Up to JB-MR1 we had a white list with services that can enable touch // exploration. When a service is first started we show a dialog to the // use to get a permission to white list the service. if (!userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) { if (mEnableTouchExplorationDialog == null || (mEnableTouchExplorationDialog != null && !mEnableTouchExplorationDialog.isShowing())) { showEnableTouchExplorationDialog(service); } } else { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId); } } else { // Starting in JB-MR2 we request a permission to allow a service to enable // touch exploration and do not care if the service is in the white list. if (mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE, service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED) { if (!userState.mIsTouchExplorationEnabled) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId); } Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, userState.mUserId); } } Loading @@ -1310,53 +1191,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return; } UserState userState = getUserStateLocked(service.mUserId); if (!userState.mIsTouchExplorationEnabled) { return; } if (userState.mIsTouchExplorationEnabled) { final int serviceCount = userState.mServices.size(); for (int i = 0; i < serviceCount; i++) { Service other = userState.mServices.get(i); if (other != service) { if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1) { // Up to JB-MR1 we had a white list with services that can enable touch // exploration. When a service is first started we show a dialog to the // use to get a permission to white list the service. if (other.mRequestTouchExplorationMode && userState.mTouchExplorationGrantedServices.contains( service.mComponentName)) { // A white-listed service wants touch exploration, do not disable. return; } } else { // Starting in JB-MR2 we request a permission to allow a service to enable // touch exploration and do not care if the service is in the white list. if (other.mRequestTouchExplorationMode && (service.mIsAutomation || mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE, service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED)) { // A service with permission wants touch exploration, do not disable. if (other != service && other.mRequestTouchExplorationMode) { return; } } } } Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId); } } private void tryEnableEnhancedWebAccessibilityLocked(Service service) { if (!service.canReceiveEventsLocked() || !service.mRequestEnhancedWebAccessibility ) { if (!service.mRequestEnhancedWebAccessibility || !service.canReceiveEventsLocked()) { return; } UserState userState = getUserStateLocked(service.mUserId); if (userState.mIsEnhancedWebAccessibilityEnabled) { return; } // Requested and can enabled, do it. if (service.mRequestEnhancedWebAccessibility && canEnabledEnhancedWebAccessibility(service)) { if (!userState.mIsEnhancedWebAccessibilityEnabled) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1, userState.mUserId); } Loading @@ -1367,26 +1220,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return; } UserState userState = getUserStateLocked(service.mUserId); if (!userState.mIsEnhancedWebAccessibilityEnabled) { return; } if (userState.mIsEnhancedWebAccessibilityEnabled) { final int serviceCount = userState.mServices.size(); for (int i = 0; i < serviceCount; i++) { Service other = userState.mServices.get(i); if (other != service && other.mRequestEnhancedWebAccessibility && canEnabledEnhancedWebAccessibility(other)) { // One service requests the feature, do not disable. if (other != service && other.mRequestEnhancedWebAccessibility) { return; } } Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, service.mUserId); Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, userState.mUserId); } private boolean canEnabledEnhancedWebAccessibility(Service service) { return (service.mIsAutomation || mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY, service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED); } @Override Loading Loading @@ -1683,11 +1527,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS : 0; if (mResolveInfo != null) { String packageName = mResolveInfo.serviceInfo.packageName; if (mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE, packageName) == PackageManager.PERMISSION_GRANTED) { mRequestTouchExplorationMode = (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0; } if (mContext.getPackageManager().checkPermission( android.Manifest.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY, packageName) == PackageManager.PERMISSION_GRANTED) { mRequestEnhancedWebAccessibility = (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0; } } // If this service is up and running we may have to enable touch // exploration or enhanced web accessibility, otherwise this will Loading Loading @@ -2598,9 +2453,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>(); public final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<ComponentName>(); public final SparseArray<AccessibilityConnectionWrapper> mInteractionConnections = new SparseArray<AccessibilityConnectionWrapper>(); Loading Loading @@ -2638,7 +2490,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { mEnabledServices.clear(); mEnabledServices.addAll(userState.mEnabledServices); mTouchExplorationGrantedServices.clear(); mTouchExplorationGrantedServices.addAll(userState.mTouchExplorationGrantedServices); } public void applyTo(UserState userState) { Loading @@ -2648,8 +2499,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { userState.mIsDisplayMagnificationEnabled = mIsDisplayMagnificationEnabled; userState.mEnabledServices.clear(); userState.mEnabledServices.addAll(mEnabledServices); userState.mTouchExplorationGrantedServices.clear(); userState.mTouchExplorationGrantedServices.addAll(mTouchExplorationGrantedServices); } public void clear() { Loading Loading @@ -2677,12 +2526,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final Uri mEnabledAccessibilityServicesUri = Settings.Secure.getUriFor( Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES); private final Uri mAccessibilityScriptInjectionUri = Settings.Secure .getUriFor(Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION); public AccessibilityContentObserver(Handler handler) { super(handler); } Loading @@ -2696,11 +2539,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { false, this, UserHandle.USER_ALL); contentResolver.registerContentObserver(mEnabledAccessibilityServicesUri, false, this, UserHandle.USER_ALL); contentResolver.registerContentObserver( mTouchExplorationGrantedAccessibilityServicesUri, false, this, UserHandle.USER_ALL); contentResolver.registerContentObserver(mAccessibilityScriptInjectionUri, false, this, UserHandle.USER_ALL); } @Override Loading Loading @@ -2745,23 +2583,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { manageServicesLocked(userState); } } } else if (mTouchExplorationGrantedAccessibilityServicesUri.equals(uri)) { synchronized (mLock) { // We will update when the automation service dies. if (mUiAutomationService == null) { UserState userState = getCurrentUserStateLocked(); populateTouchExplorationGrantedAccessibilityServicesLocked(userState); handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState); } } } else if (mAccessibilityScriptInjectionUri.equals(uri)) { synchronized (mLock) { // We will update when the automation service dies. if (mUiAutomationService == null) { UserState userState = getCurrentUserStateLocked(); populatedEnhancedWebAccessibilityEnabledChangedLocked(userState); } } } } } Loading