Make AM#isEnabled() true if any direct a11y connection exists.
Includes @TestApi AM#hasAnyDirectConnection() to improve test
reliability, because directly testing AM#isEnabled() is muddied
by UiAutomation used in the test itself.
Bug: 249164232
Test: atest AccessibilityEndToEndTest
Test: check node tree of a WebView when no real a11y service
is enabled.
Change-Id: I4931ce316e9f5a956d266b7fd99f0faf00b8cd0d
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -602,11 +602,20 @@ 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>
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user