diff options
4 files changed, 32 insertions, 3 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 99005a463f73..4d4d09b3e6c3 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2961,6 +2961,7 @@ package android.view.accessibility { public final class AccessibilityManager { method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public java.util.List<java.lang.String> getAccessibilityShortcutTargets(int); + method public boolean hasAnyDirectConnection(); } public class AccessibilityNodeInfo implements android.os.Parcelable { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index b6f775d3e536..c6adc2e53e58 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -10499,6 +10499,8 @@ public final class ViewRootImpl implements ViewParent, if (mDirectConnectionId == AccessibilityNodeInfo.UNDEFINED_CONNECTION_ID) { mDirectConnectionId = AccessibilityInteractionClient.addDirectConnection( new AccessibilityInteractionConnection(ViewRootImpl.this)); + // Notify listeners in the app process. + mAccessibilityManager.notifyAccessibilityStateChanged(); } return mDirectConnectionId; } @@ -10507,6 +10509,8 @@ public final class ViewRootImpl implements ViewParent, if (mDirectConnectionId != AccessibilityNodeInfo.UNDEFINED_CONNECTION_ID) { AccessibilityInteractionClient.removeConnection(mDirectConnectionId); mDirectConnectionId = AccessibilityNodeInfo.UNDEFINED_CONNECTION_ID; + // Notify listeners in the app process. + mAccessibilityManager.notifyAccessibilityStateChanged(); } } } diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index 227a8ef6fd60..e3ffc9dcbbde 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -117,6 +117,7 @@ public final class AccessibilityInteractionClient // Used to generate connection ids for direct app-process connections. Start sufficiently far // enough from the connection ids generated by AccessibilityManagerService. private static int sDirectConnectionIdCounter = 1 << 30; + private static int sDirectConnectionCount = 0; /** List of timestamps which indicate the latest time an a11y service receives a scroll event from a window, mapping from windowId -> timestamp. */ @@ -272,12 +273,18 @@ public final class AccessibilityInteractionClient DirectAccessibilityConnection directAccessibilityConnection = new DirectAccessibilityConnection(connection); sConnectionCache.put(connectionId, directAccessibilityConnection); + sDirectConnectionCount++; // Do not use AccessibilityCache for this connection, since there is no corresponding // AccessibilityService to handle cache invalidation events. return connectionId; } } + /** Check if any {@link DirectAccessibilityConnection} is currently in the connection cache. */ + public static boolean hasAnyDirectConnection() { + return sDirectConnectionCount > 0; + } + /** * Gets a cached associated with the connection id if available. * @@ -295,6 +302,9 @@ public final class AccessibilityInteractionClient */ public static void removeConnection(int connectionId) { synchronized (sConnectionCache) { + if (getConnection(connectionId) instanceof DirectAccessibilityConnection) { + sDirectConnectionCount--; + } sConnectionCache.remove(connectionId); sCaches.remove(connectionId); } diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 7528e2a66926..5433fa08ac18 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -602,12 +602,21 @@ public final class AccessibilityManager { */ public boolean isEnabled() { synchronized (mLock) { - return mIsEnabled || (mAccessibilityPolicy != null - && mAccessibilityPolicy.isEnabled(mIsEnabled)); + return mIsEnabled || hasAnyDirectConnection() + || (mAccessibilityPolicy != null && mAccessibilityPolicy.isEnabled(mIsEnabled)); } } /** + * @see AccessibilityInteractionClient#hasAnyDirectConnection + * @hide + */ + @TestApi + public boolean hasAnyDirectConnection() { + return AccessibilityInteractionClient.hasAnyDirectConnection(); + } + + /** * Returns if the touch exploration in the system is enabled. * <p> * <b>Note:</b> This query is used for dispatching hover events, such as @@ -1942,8 +1951,13 @@ public final class AccessibilityManager { /** * Notifies the registered {@link AccessibilityStateChangeListener}s. + * + * Note: this method notifies only the listeners of this single instance. + * AccessibilityManagerService is responsible for calling this method on all of + * its AccessibilityManager clients in order to notify all listeners. + * @hide */ - private void notifyAccessibilityStateChanged() { + public void notifyAccessibilityStateChanged() { final boolean isEnabled; final ArrayMap<AccessibilityStateChangeListener, Handler> listeners; synchronized (mLock) { |