diff options
| author | 2019-10-17 06:21:10 +0000 | |
|---|---|---|
| committer | 2019-10-17 06:21:10 +0000 | |
| commit | 41c5b259e81fce6d6e403048948cc09a5cac1033 (patch) | |
| tree | 1b6d8a12c0b7f0e035b12ed27d56a5eaac5a1b43 | |
| parent | a59833d6455666268310e7e4e0fe06c42f07bc8e (diff) | |
| parent | fbac83822e8598a9d89118ef9dc48733443d64ea (diff) | |
Merge "Allow restarting of crashed a11y services"
7 files changed, 87 insertions, 26 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 8e1690f7b622..e738b19f420a 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -438,7 +438,7 @@ public class AccessibilityServiceInfo implements Parcelable { /** * Whether or not the service has crashed and is awaiting restart. Only valid from {@link - * android.view.accessibility.AccessibilityManager#getEnabledAccessibilityServiceList(int)}, + * android.view.accessibility.AccessibilityManager#getInstalledAccessibilityServiceList()}, * because that is populated from the internal list of running services. * * @hide diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 0817452718b5..cc2884075c39 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -707,10 +707,10 @@ public final class AccessibilityManager { try { services = service.getEnabledAccessibilityServiceList(feedbackTypeFlags, userId); if (DEBUG) { - Log.i(LOG_TAG, "Installed AccessibilityServices " + services); + Log.i(LOG_TAG, "Enabled AccessibilityServices " + services); } } catch (RemoteException re) { - Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re); + Log.e(LOG_TAG, "Error while obtaining the enabled AccessibilityServices. ", re); } if (mAccessibilityPolicy != null) { services = mAccessibilityPolicy.getEnabledAccessibilityServiceList( diff --git a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java index a18600abf788..2b841967d4a8 100644 --- a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java @@ -48,11 +48,21 @@ public class AccessibilityUtils { return getEnabledServicesFromSettings(context, UserHandle.myUserId()); } + /** + * Check if the accessibility service is crashed + * + * @param packageName The package name to check + * @param serviceName The service name to check + * @param installedServiceInfos The list of installed accessibility service + * @return {@code true} if the accessibility service is crashed for the user. + * {@code false} otherwise. + */ public static boolean hasServiceCrashed(String packageName, String serviceName, - List<AccessibilityServiceInfo> enabledServiceInfos) { - for (int i = 0; i < enabledServiceInfos.size(); i++) { - AccessibilityServiceInfo accessibilityServiceInfo = enabledServiceInfos.get(i); - final ServiceInfo serviceInfo = enabledServiceInfos.get(i).getResolveInfo().serviceInfo; + List<AccessibilityServiceInfo> installedServiceInfos) { + for (int i = 0; i < installedServiceInfos.size(); i++) { + final AccessibilityServiceInfo accessibilityServiceInfo = installedServiceInfos.get(i); + final ServiceInfo serviceInfo = + installedServiceInfos.get(i).getResolveInfo().serviceInfo; if (TextUtils.equals(serviceInfo.packageName, packageName) && TextUtils.equals(serviceInfo.name, serviceName)) { return accessibilityServiceInfo.crashed; diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index e909e7a828c3..68e11df32d79 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -366,9 +366,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (userId != mCurrentUserId) { return; } - AccessibilityUserState userState = getUserStateLocked(userId); - boolean reboundAService = userState.getBindingServicesLocked().removeIf( + final AccessibilityUserState userState = getUserStateLocked(userId); + final boolean reboundAService = userState.getBindingServicesLocked().removeIf( component -> component != null + && component.getPackageName().equals(packageName)) + || userState.mCrashedServices.removeIf(component -> component != null && component.getPackageName().equals(packageName)); if (reboundAService) { onUserStateChangedLocked(userState); @@ -393,6 +395,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (compPkg.equals(packageName)) { it.remove(); userState.getBindingServicesLocked().remove(comp); + userState.getCrashedServicesLocked().remove(comp); // Update the enabled services setting. persistComponentNamesToSettingLocked( Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, @@ -753,6 +756,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub userState.mEnabledServices.clear(); userState.mEnabledServices.add(service); userState.getBindingServicesLocked().clear(); + userState.getCrashedServicesLocked().clear(); userState.mTouchExplorationGrantedServices.clear(); userState.mTouchExplorationGrantedServices.add(service); @@ -1178,6 +1182,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub AccessibilityServiceInfo accessibilityServiceInfo; try { accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext); + if (userState.mCrashedServices.contains(serviceInfo.getComponentName())) { + // Restore the crashed attribute. + accessibilityServiceInfo.crashed = true; + } mTempAccessibilityServiceInfoList.add(accessibilityServiceInfo); } catch (XmlPullParserException | IOException xppe) { Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe); @@ -1418,8 +1426,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub continue; } - // Wait for the binding if it is in process. - if (userState.getBindingServicesLocked().contains(componentName)) { + // Skip the component since it may be in process or crashed. + if (userState.getBindingServicesLocked().contains(componentName) + || userState.getCrashedServicesLocked().contains(componentName)) { continue; } if (userState.mEnabledServices.contains(componentName) @@ -2687,6 +2696,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } else if (mEnabledAccessibilityServicesUri.equals(uri)) { if (readEnabledAccessibilityServicesLocked(userState)) { + userState.updateCrashedServicesIfNeededLocked(); onUserStateChangedLocked(userState); } } else if (mTouchExplorationGrantedAccessibilityServicesUri.equals(uri)) { diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java index d154060d0b73..a0a755a30cb3 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java @@ -62,9 +62,6 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect private final Handler mMainHandler; - private boolean mWasConnectedAndDied; - - AccessibilityServiceConnection(AccessibilityUserState userState, Context context, ComponentName componentName, AccessibilityServiceInfo accessibilityServiceInfo, int id, Handler mainHandler, @@ -168,8 +165,6 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect @Override public AccessibilityServiceInfo getServiceInfo() { - // Update crashed data - mAccessibilityServiceInfo.crashed = mWasConnectedAndDied; return mAccessibilityServiceInfo; } @@ -178,10 +173,13 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect synchronized (mLock) { AccessibilityUserState userState = mUserStateWeakReference.get(); if (userState == null) return; - Set<ComponentName> bindingServices = userState.getBindingServicesLocked(); - if (bindingServices.contains(mComponentName) || mWasConnectedAndDied) { + final Set<ComponentName> bindingServices = userState.getBindingServicesLocked(); + final Set<ComponentName> crashedServices = userState.getCrashedServicesLocked(); + if (bindingServices.contains(mComponentName) + || crashedServices.contains(mComponentName)) { bindingServices.remove(mComponentName); - mWasConnectedAndDied = false; + crashedServices.remove(mComponentName); + mAccessibilityServiceInfo.crashed = false; serviceInterface = mServiceInterface; } // There's a chance that service is removed from enabled_accessibility_services setting @@ -271,7 +269,7 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect if (!isConnectedLocked()) { return; } - mWasConnectedAndDied = true; + mAccessibilityServiceInfo.crashed = true; AccessibilityUserState userState = mUserStateWeakReference.get(); if (userState != null) { userState.serviceDisconnectedLocked(this); diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java index 69f1e0e41aad..a0b9866e24d2 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java @@ -73,6 +73,8 @@ class AccessibilityUserState { final Set<ComponentName> mBindingServices = new HashSet<>(); + final Set<ComponentName> mCrashedServices = new HashSet<>(); + final Set<ComponentName> mEnabledServices = new HashSet<>(); final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<>(); @@ -127,6 +129,7 @@ class AccessibilityUserState { // Clear service management state. mBoundServices.clear(); mBindingServices.clear(); + mCrashedServices.clear(); // Clear event management state. mLastSentClientState = -1; @@ -184,15 +187,16 @@ class AccessibilityUserState { /** * Make sure a services disconnected but still 'on' state is reflected in AccessibilityUserState - * There are three states to a service here: off, bound, and binding. - * This drops a service from a bound state, to the binding state. - * The binding state describes the situation where a service is on, but not bound. + * There are four states to a service here: off, bound, and binding, and crashed. + * This drops a service from a bound state, to the crashed state. + * The crashed state describes the situation where a service used to be bound, but no longer is + * despite still being enabled. * * @param serviceConnection The service. */ void serviceDisconnectedLocked(AccessibilityServiceConnection serviceConnection) { removeServiceLocked(serviceConnection); - mBindingServices.add(serviceConnection.getComponentName()); + mCrashedServices.add(serviceConnection.getComponentName()); } /** @@ -289,17 +293,44 @@ class AccessibilityUserState { mBindInstantServiceAllowed = allowed; } + /** + * Returns binding service list. + */ Set<ComponentName> getBindingServicesLocked() { return mBindingServices; } /** + * Returns crashed service list. + */ + Set<ComponentName> getCrashedServicesLocked() { + return mCrashedServices; + } + + /** * Returns enabled service list. */ Set<ComponentName> getEnabledServicesLocked() { return mEnabledServices; } + /** + * Remove service from crashed service list if users disable it. + */ + void updateCrashedServicesIfNeededLocked() { + for (int i = 0, count = mInstalledServices.size(); i < count; i++) { + final AccessibilityServiceInfo installedService = mInstalledServices.get(i); + final ComponentName componentName = ComponentName.unflattenFromString( + installedService.getId()); + + if (mCrashedServices.contains(componentName) + && !mEnabledServices.contains(componentName)) { + // Remove it from mCrashedServices since users toggle the switch bar to retry. + mCrashedServices.remove(componentName); + } + } + } + List<AccessibilityServiceConnection> getBoundServicesLocked() { return mBoundServices; } @@ -439,6 +470,18 @@ class AccessibilityUserState { pw.append(componentName.toShortString()); } } + pw.println("}"); + pw.append(" Crashed services:{"); + it = mCrashedServices.iterator(); + if (it.hasNext()) { + ComponentName componentName = it.next(); + pw.append(componentName.toShortString()); + while (it.hasNext()) { + componentName = it.next(); + pw.append(", "); + pw.append(componentName.toShortString()); + } + } pw.println("}]"); } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java index 918005437e96..d70e1648f719 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java @@ -207,14 +207,14 @@ public class AccessibilityUserStateTest { } @Test - public void serviceDisconnected_removeServiceAndAddToBinding() { + public void serviceDisconnected_removeServiceAndAddToCrashed() { when(mMockConnection.getComponentName()).thenReturn(COMPONENT_NAME); mUserState.addServiceLocked(mMockConnection); mUserState.serviceDisconnectedLocked(mMockConnection); assertFalse(mUserState.getBoundServicesLocked().contains(mMockConnection)); - assertTrue(mUserState.getBindingServicesLocked().contains(COMPONENT_NAME)); + assertTrue(mUserState.getCrashedServicesLocked().contains(COMPONENT_NAME)); } @Test |