Merge "Fixing backwards cmpatibility for enabling explore by touch"
This commit is contained in:
@@ -150,10 +150,18 @@ public class AccessibilityServiceInfo implements Parcelable {
|
|||||||
* flag does not guarantee that the device will not be in touch exploration
|
* flag does not guarantee that the device will not be in touch exploration
|
||||||
* mode since there may be another enabled service that requested it.
|
* mode since there may be another enabled service that requested it.
|
||||||
* <p>
|
* <p>
|
||||||
* Clients that want to set this flag have to request the
|
* 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
|
||||||
* {@link android.Manifest.permission#CAN_REQUEST_TOUCH_EXPLORATION_MODE}
|
* {@link android.Manifest.permission#CAN_REQUEST_TOUCH_EXPLORATION_MODE}
|
||||||
* permission or the flag will be ignored.
|
* permission or the flag will be ignored.
|
||||||
* </p>
|
* </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;
|
public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004;
|
||||||
|
|
||||||
|
|||||||
@@ -3351,7 +3351,6 @@ public final class Settings {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES =
|
public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES =
|
||||||
"touch_exploration_granted_accessibility_services";
|
"touch_exploration_granted_accessibility_services";
|
||||||
|
|
||||||
|
|||||||
@@ -950,8 +950,8 @@
|
|||||||
<string name="permlab_canRequestEnahncedWebAccessibility">request enhanced web accessibility</string>
|
<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. -->
|
<!-- 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
|
<string name="permdesc_canRequestEnahncedWebAccessibility">Allows the hoder to request
|
||||||
enabling of web accessibility enhancements. For example, installing scripts from
|
enabling of web accessibility enhancements. For example, installing scripts to make
|
||||||
Google to make app content more accessible.</string>
|
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. -->
|
<!-- 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>
|
<string name="permlab_bindTextService">bind to a text service</string>
|
||||||
@@ -2714,6 +2714,25 @@
|
|||||||
<!-- SearchView accessibility description for voice button [CHAR LIMIT=NONE] -->
|
<!-- SearchView accessibility description for voice button [CHAR LIMIT=NONE] -->
|
||||||
<string name="searchview_description_voice">Voice search</string>
|
<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 used to display the date. This is the string to say something happened 1 month ago. -->
|
||||||
<string name="oneMonthDurationPast">1 month ago</string>
|
<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. -->
|
<!-- String used to display the date. This is the string to say something happened more than 1 month ago. -->
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||||||
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
|
// 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
|
// is properly propagated through your change. Not doing so will result in a loss of user
|
||||||
// settings.
|
// settings.
|
||||||
private static final int DATABASE_VERSION = 97;
|
private static final int DATABASE_VERSION = 96;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private int mUserHandle;
|
private int mUserHandle;
|
||||||
@@ -1536,22 +1536,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||||||
upgradeVersion = 96;
|
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!
|
// *** Remember to update DATABASE_VERSION above!
|
||||||
|
|
||||||
if (upgradeVersion != currentVersion) {
|
if (upgradeVersion != currentVersion) {
|
||||||
|
|||||||
@@ -23,12 +23,15 @@ import android.accessibilityservice.AccessibilityService;
|
|||||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||||
import android.accessibilityservice.IAccessibilityServiceClient;
|
import android.accessibilityservice.IAccessibilityServiceClient;
|
||||||
import android.accessibilityservice.IAccessibilityServiceConnection;
|
import android.accessibilityservice.IAccessibilityServiceConnection;
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.StatusBarManager;
|
import android.app.StatusBarManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
@@ -67,6 +70,7 @@ import android.view.InputDevice;
|
|||||||
import android.view.KeyCharacterMap;
|
import android.view.KeyCharacterMap;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MagnificationSpec;
|
import android.view.MagnificationSpec;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.view.accessibility.AccessibilityInteractionClient;
|
import android.view.accessibility.AccessibilityInteractionClient;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
@@ -157,6 +161,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
|
|
||||||
private Service mQueryBridge;
|
private Service mQueryBridge;
|
||||||
|
|
||||||
|
private AlertDialog mEnableTouchExplorationDialog;
|
||||||
|
|
||||||
private AccessibilityInputFilter mInputFilter;
|
private AccessibilityInputFilter mInputFilter;
|
||||||
|
|
||||||
private boolean mHasInputFilter;
|
private boolean mHasInputFilter;
|
||||||
@@ -244,6 +250,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
persistComponentNamesToSettingLocked(
|
persistComponentNamesToSettingLocked(
|
||||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
|
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
|
||||||
state.mEnabledServices, userId);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,6 +570,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
userState.mIsDisplayMagnificationEnabled = false;
|
userState.mIsDisplayMagnificationEnabled = false;
|
||||||
userState.mEnabledServices.clear();
|
userState.mEnabledServices.clear();
|
||||||
userState.mEnabledServices.add(service);
|
userState.mEnabledServices.add(service);
|
||||||
|
userState.mTouchExplorationGrantedServices.clear();
|
||||||
|
userState.mTouchExplorationGrantedServices.add(service);
|
||||||
// Update the internal state.
|
// Update the internal state.
|
||||||
performServiceManagementLocked(userState);
|
performServiceManagementLocked(userState);
|
||||||
scheduleUpdateInputFilter(userState);
|
scheduleUpdateInputFilter(userState);
|
||||||
@@ -831,6 +845,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
userState.mEnabledServices);
|
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
|
* Performs {@link AccessibilityService}s delayed notification. The delay is configurable
|
||||||
* and denotes the period after the last event before notifying the service.
|
* and denotes the period after the last event before notifying the service.
|
||||||
@@ -1123,6 +1143,54 @@ 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) {
|
private int getClientState(UserState userState) {
|
||||||
int clientState = 0;
|
int clientState = 0;
|
||||||
if (userState.mIsAccessibilityEnabled) {
|
if (userState.mIsAccessibilityEnabled) {
|
||||||
@@ -1138,12 +1206,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
private void recreateInternalStateLocked(UserState userState) {
|
private void recreateInternalStateLocked(UserState userState) {
|
||||||
populateInstalledAccessibilityServiceLocked(userState);
|
populateInstalledAccessibilityServiceLocked(userState);
|
||||||
populateEnabledAccessibilityServicesLocked(userState);
|
populateEnabledAccessibilityServicesLocked(userState);
|
||||||
|
populateTouchExplorationGrantedAccessibilityServicesLocked(userState);
|
||||||
|
populatedEnhancedWebAccessibilityEnabledChangedLocked(userState);
|
||||||
|
|
||||||
handleTouchExplorationEnabledSettingChangedLocked(userState);
|
handleTouchExplorationEnabledSettingChangedLocked(userState);
|
||||||
handleDisplayMagnificationEnabledSettingChangedLocked(userState);
|
handleDisplayMagnificationEnabledSettingChangedLocked(userState);
|
||||||
handleAccessibilityEnabledSettingChangedLocked(userState);
|
handleAccessibilityEnabledSettingChangedLocked(userState);
|
||||||
|
handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState);
|
||||||
|
|
||||||
performServiceManagementLocked(userState);
|
performServiceManagementLocked(userState);
|
||||||
|
|
||||||
scheduleUpdateInputFilter(userState);
|
scheduleUpdateInputFilter(userState);
|
||||||
scheduleSendStateToClientsLocked(userState);
|
scheduleSendStateToClientsLocked(userState);
|
||||||
}
|
}
|
||||||
@@ -1175,14 +1247,61 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
0, userState.mUserId) == 1;
|
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) {
|
private void tryEnableTouchExplorationLocked(Service service) {
|
||||||
if (!service.mRequestTouchExplorationMode || !service.canReceiveEventsLocked()) {
|
if (!service.canReceiveEventsLocked() || !service.mRequestTouchExplorationMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UserState userState = getUserStateLocked(service.mUserId);
|
UserState userState = getUserStateLocked(service.mUserId);
|
||||||
if (!userState.mIsTouchExplorationEnabled) {
|
if (userState.mIsTouchExplorationEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// UI test automation service can always enable it.
|
||||||
|
if (service.mIsAutomation) {
|
||||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||||
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, userState.mUserId);
|
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) {
|
||||||
|
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||||
|
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1191,25 +1310,53 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UserState userState = getUserStateLocked(service.mUserId);
|
UserState userState = getUserStateLocked(service.mUserId);
|
||||||
if (userState.mIsTouchExplorationEnabled) {
|
if (!userState.mIsTouchExplorationEnabled) {
|
||||||
final int serviceCount = userState.mServices.size();
|
return;
|
||||||
for (int i = 0; i < serviceCount; i++) {
|
}
|
||||||
Service other = userState.mServices.get(i);
|
final int serviceCount = userState.mServices.size();
|
||||||
if (other != service && other.mRequestTouchExplorationMode) {
|
for (int i = 0; i < serviceCount; i++) {
|
||||||
return;
|
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.
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
|
||||||
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId);
|
|
||||||
}
|
}
|
||||||
|
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||||
|
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryEnableEnhancedWebAccessibilityLocked(Service service) {
|
private void tryEnableEnhancedWebAccessibilityLocked(Service service) {
|
||||||
if (!service.mRequestEnhancedWebAccessibility || !service.canReceiveEventsLocked()) {
|
if (!service.canReceiveEventsLocked() || !service.mRequestEnhancedWebAccessibility ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UserState userState = getUserStateLocked(service.mUserId);
|
UserState userState = getUserStateLocked(service.mUserId);
|
||||||
if (!userState.mIsEnhancedWebAccessibilityEnabled) {
|
if (userState.mIsEnhancedWebAccessibilityEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Requested and can enabled, do it.
|
||||||
|
if (service.mRequestEnhancedWebAccessibility
|
||||||
|
&& canEnabledEnhancedWebAccessibility(service)) {
|
||||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||||
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1, userState.mUserId);
|
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1, userState.mUserId);
|
||||||
}
|
}
|
||||||
@@ -1220,17 +1367,26 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UserState userState = getUserStateLocked(service.mUserId);
|
UserState userState = getUserStateLocked(service.mUserId);
|
||||||
if (userState.mIsEnhancedWebAccessibilityEnabled) {
|
if (!userState.mIsEnhancedWebAccessibilityEnabled) {
|
||||||
final int serviceCount = userState.mServices.size();
|
return;
|
||||||
for (int i = 0; i < serviceCount; i++) {
|
|
||||||
Service other = userState.mServices.get(i);
|
|
||||||
if (other != service && other.mRequestEnhancedWebAccessibility) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
|
||||||
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, userState.mUserId);
|
|
||||||
}
|
}
|
||||||
|
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.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||||
|
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, service.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
|
@Override
|
||||||
@@ -1355,7 +1511,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
} break;
|
} break;
|
||||||
case MSG_UPDATE_INPUT_FILTER: {
|
case MSG_UPDATE_INPUT_FILTER: {
|
||||||
UserState userState = (UserState) msg.obj;
|
UserState userState = (UserState) msg.obj;
|
||||||
updateInputFilter(userState);
|
updateInputFilter(userState);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1527,21 +1683,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS : 0;
|
AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS : 0;
|
||||||
|
|
||||||
if (mResolveInfo != null) {
|
if (mResolveInfo != null) {
|
||||||
String packageName = mResolveInfo.serviceInfo.packageName;
|
mRequestTouchExplorationMode = (info.flags
|
||||||
|
|
||||||
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;
|
& AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
|
||||||
}
|
mRequestEnhancedWebAccessibility = (info.flags
|
||||||
|
|
||||||
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;
|
& AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this service is up and running we may have to enable touch
|
// If this service is up and running we may have to enable touch
|
||||||
@@ -2453,6 +2598,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
|
|
||||||
public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
|
public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
|
||||||
|
|
||||||
|
public final Set<ComponentName> mTouchExplorationGrantedServices =
|
||||||
|
new HashSet<ComponentName>();
|
||||||
|
|
||||||
public final SparseArray<AccessibilityConnectionWrapper>
|
public final SparseArray<AccessibilityConnectionWrapper>
|
||||||
mInteractionConnections =
|
mInteractionConnections =
|
||||||
new SparseArray<AccessibilityConnectionWrapper>();
|
new SparseArray<AccessibilityConnectionWrapper>();
|
||||||
@@ -2490,6 +2638,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
mEnabledServices.clear();
|
mEnabledServices.clear();
|
||||||
mEnabledServices.addAll(userState.mEnabledServices);
|
mEnabledServices.addAll(userState.mEnabledServices);
|
||||||
mTouchExplorationGrantedServices.clear();
|
mTouchExplorationGrantedServices.clear();
|
||||||
|
mTouchExplorationGrantedServices.addAll(userState.mTouchExplorationGrantedServices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyTo(UserState userState) {
|
public void applyTo(UserState userState) {
|
||||||
@@ -2499,6 +2648,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
userState.mIsDisplayMagnificationEnabled = mIsDisplayMagnificationEnabled;
|
userState.mIsDisplayMagnificationEnabled = mIsDisplayMagnificationEnabled;
|
||||||
userState.mEnabledServices.clear();
|
userState.mEnabledServices.clear();
|
||||||
userState.mEnabledServices.addAll(mEnabledServices);
|
userState.mEnabledServices.addAll(mEnabledServices);
|
||||||
|
userState.mTouchExplorationGrantedServices.clear();
|
||||||
|
userState.mTouchExplorationGrantedServices.addAll(mTouchExplorationGrantedServices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
@@ -2526,6 +2677,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
private final Uri mEnabledAccessibilityServicesUri = Settings.Secure.getUriFor(
|
private final Uri mEnabledAccessibilityServicesUri = Settings.Secure.getUriFor(
|
||||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
|
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) {
|
public AccessibilityContentObserver(Handler handler) {
|
||||||
super(handler);
|
super(handler);
|
||||||
}
|
}
|
||||||
@@ -2539,6 +2696,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
false, this, UserHandle.USER_ALL);
|
false, this, UserHandle.USER_ALL);
|
||||||
contentResolver.registerContentObserver(mEnabledAccessibilityServicesUri,
|
contentResolver.registerContentObserver(mEnabledAccessibilityServicesUri,
|
||||||
false, this, UserHandle.USER_ALL);
|
false, this, UserHandle.USER_ALL);
|
||||||
|
contentResolver.registerContentObserver(
|
||||||
|
mTouchExplorationGrantedAccessibilityServicesUri,
|
||||||
|
false, this, UserHandle.USER_ALL);
|
||||||
|
contentResolver.registerContentObserver(mAccessibilityScriptInjectionUri,
|
||||||
|
false, this, UserHandle.USER_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2583,6 +2745,23 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
|||||||
manageServicesLocked(userState);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user