diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 2dfa8cdd3db9e..286f5f7c1bf9b 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -353,7 +353,18 @@ public final class AccessibilityManager { return; } if (!mIsEnabled) { - throw new IllegalStateException("Accessibility off. Did you forget to check that?"); + Looper myLooper = Looper.myLooper(); + if (myLooper == Looper.getMainLooper()) { + throw new IllegalStateException( + "Accessibility off. Did you forget to check that?"); + } else { + // If we're not running on the thread with the main looper, it's possible for + // the state of accessibility to change between checking isEnabled and + // calling this method. So just log the error rather than throwing the + // exception. + Log.e(LOG_TAG, "Interrupt called with accessibility disabled"); + return; + } } userId = mUserId; } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 58bb5f3793127..34ccb7b82c87c 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -538,7 +538,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { @Override public void interrupt(int userId) { - CopyOnWriteArrayList services; + List interfacesToInterrupt; synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -549,15 +549,24 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (resolvedUserId != mCurrentUserId) { return; } - services = getUserStateLocked(resolvedUserId).mBoundServices; + List services = getUserStateLocked(resolvedUserId).mBoundServices; + int numServices = services.size(); + interfacesToInterrupt = new ArrayList<>(numServices); + for (int i = 0; i < numServices; i++) { + Service service = services.get(i); + IBinder a11yServiceBinder = service.mService; + IAccessibilityServiceClient a11yServiceInterface = service.mServiceInterface; + if ((a11yServiceBinder != null) && (a11yServiceInterface != null)) { + interfacesToInterrupt.add(a11yServiceInterface); + } + } } - for (int i = 0, count = services.size(); i < count; i++) { - Service service = services.get(i); + for (int i = 0, count = interfacesToInterrupt.size(); i < count; i++) { try { - service.mServiceInterface.onInterrupt(); + interfacesToInterrupt.get(i).onInterrupt(); } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error during sending interrupt request to " - + service.mService, re); + Slog.e(LOG_TAG, "Error sending interrupt request to " + + interfacesToInterrupt.get(i), re); } } }