Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47d8fe5c authored by Daniel Norman's avatar Daniel Norman Committed by Android (Google) Code Review
Browse files

Merge changes from topic "reland-a11y-adp"

* changes:
  Tweak behavior of isAccessibilityDataPrivate() to reduce CPU usage.
  Revert "Revert "Limit off-label accessibility access using a new..."
parents 4b60d0f3 bc666bea
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -49972,6 +49972,7 @@ package android.view {
    method public void invalidate();
    method public void invalidateDrawable(@NonNull android.graphics.drawable.Drawable);
    method public void invalidateOutline();
    method public boolean isAccessibilityDataPrivate();
    method public boolean isAccessibilityFocused();
    method public boolean isAccessibilityHeading();
    method public boolean isActivated();
@@ -50149,6 +50150,7 @@ package android.view {
    method public void scrollTo(int, int);
    method public void sendAccessibilityEvent(int);
    method public void sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent);
    method public void setAccessibilityDataPrivate(int);
    method public void setAccessibilityDelegate(@Nullable android.view.View.AccessibilityDelegate);
    method public void setAccessibilityHeading(boolean);
    method public void setAccessibilityLiveRegion(int);
@@ -50329,6 +50331,9 @@ package android.view {
    method @CallSuper protected boolean verifyDrawable(@NonNull android.graphics.drawable.Drawable);
    method @Deprecated public boolean willNotCacheDrawing();
    method public boolean willNotDraw();
    field public static final int ACCESSIBILITY_DATA_PRIVATE_AUTO = 0; // 0x0
    field public static final int ACCESSIBILITY_DATA_PRIVATE_NO = 2; // 0x2
    field public static final int ACCESSIBILITY_DATA_PRIVATE_YES = 1; // 0x1
    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
@@ -51781,9 +51786,11 @@ package android.view.accessibility {
    method public int getSpeechStateChangeTypes();
    method public int getWindowChanges();
    method public void initFromParcel(android.os.Parcel);
    method public boolean isAccessibilityDataPrivate();
    method @Deprecated public static android.view.accessibility.AccessibilityEvent obtain(int);
    method @Deprecated public static android.view.accessibility.AccessibilityEvent obtain(android.view.accessibility.AccessibilityEvent);
    method @Deprecated public static android.view.accessibility.AccessibilityEvent obtain();
    method public void setAccessibilityDataPrivate(boolean);
    method public void setAction(int);
    method public void setContentChangeTypes(int);
    method public void setEventTime(long);
@@ -51874,6 +51881,7 @@ package android.view.accessibility {
    method public static boolean isAccessibilityButtonSupported();
    method public boolean isAudioDescriptionRequested();
    method public boolean isEnabled();
    method public boolean isRequestFromAccessibilityTool();
    method public boolean isTouchExplorationEnabled();
    method public void removeAccessibilityRequestPreparer(android.view.accessibility.AccessibilityRequestPreparer);
    method public boolean removeAccessibilityServicesStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener);
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ package android.accessibilityservice {

  public class AccessibilityServiceInfo implements android.os.Parcelable {
    method @NonNull public android.content.ComponentName getComponentName();
    method public void setAccessibilityTool(boolean);
  }

}
+21 −0
Original line number Diff line number Diff line
@@ -784,6 +784,7 @@ public class AccessibilityServiceInfo implements Parcelable {
        mNonInteractiveUiTimeout = other.mNonInteractiveUiTimeout;
        mInteractiveUiTimeout = other.mInteractiveUiTimeout;
        flags = other.flags;
        mIsAccessibilityTool = other.mIsAccessibilityTool;
    }

    private boolean isRequestAccessibilityButtonChangeEnabled(IPlatformCompat platformCompat) {
@@ -1111,6 +1112,26 @@ public class AccessibilityServiceInfo implements Parcelable {
                || mResolveInfo.serviceInfo.directBootAware;
    }

    /**
     * Sets whether the service is used to assist users with disabilities.
     *
     * <p>
     * This property is normally provided in the service's {@link #mResolveInfo ResolveInfo}.
     * </p>
     *
     * <p>
     * This method is helpful for unit testing. However, this property is not dynamically
     * configurable by a standard {@link AccessibilityService} so it's not possible to update the
     * copy held by the system with this method.
     * </p>
     *
     * @hide
     */
    @TestApi
    public void setAccessibilityTool(boolean isAccessibilityTool) {
        mIsAccessibilityTool = isAccessibilityTool;
    }

    /**
     * Indicates if the service is used to assist users with disabilities.
     *
+1 −0
Original line number Diff line number Diff line
@@ -550,6 +550,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
        info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS);
        info.setAccessibilityTool(true);
        try {
            // Calling out with a lock held is fine since if the system
            // process is gone the client calling in will be killed.
+52 −25
Original line number Diff line number Diff line
@@ -89,9 +89,7 @@ public final class AccessibilityInteractionController {

    // Callbacks should have the same configuration of the flags below to allow satisfying a pending
    // node request on prefetch
    private static final int FLAGS_AFFECTING_REPORTED_DATA =
            AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
            | AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
    private static final int FLAGS_AFFECTING_REPORTED_DATA = AccessibilityNodeInfo.FLAG_REPORT_MASK;

    private final ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
        new ArrayList<AccessibilityNodeInfo>();
@@ -167,6 +165,11 @@ public final class AccessibilityInteractionController {
        return (view != null) && (view.getWindowVisibility() == View.VISIBLE && view.isShown());
    }

    private boolean isVisibleToAccessibilityService(View view) {
        return view != null && (mA11yManager.isRequestFromAccessibilityTool()
                || !view.isAccessibilityDataPrivate());
    }

    public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
            long accessibilityNodeId, Region interactiveRegion, int interactionId,
            IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
@@ -358,7 +361,7 @@ public final class AccessibilityInteractionController {
            if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                return;
            }
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
            setAccessibilityFetchFlags(flags);
            requestedView = findViewByAccessibilityId(accessibilityViewId);
            if (requestedView != null && isShown(requestedView)) {
                requestedNode = populateAccessibilityNodeInfoForView(
@@ -371,7 +374,7 @@ public final class AccessibilityInteractionController {
                    mPrefetcher.prefetchAccessibilityNodeInfos(requestedView,
                            requestedNode == null ? null : new AccessibilityNodeInfo(requestedNode),
                            infos);
                    mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
                    resetAccessibilityFetchFlags();
                }
            }
        } finally {
@@ -396,7 +399,7 @@ public final class AccessibilityInteractionController {
        }
        mPrefetcher.prefetchAccessibilityNodeInfos(requestedView,
                requestedNode == null ? null : new AccessibilityNodeInfo(requestedNode), infos);
        mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
        resetAccessibilityFetchFlags();
        updateInfosForViewPort(infos, spec, matrixValues, interactiveRegion);
        final SatisfiedFindAccessibilityNodeByAccessibilityIdRequest satisfiedRequest =
                getSatisfiedRequestInPrefetch(requestedNode == null ? null : requestedNode, infos,
@@ -478,7 +481,7 @@ public final class AccessibilityInteractionController {
                    || viewId == null) {
                return;
            }
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
            setAccessibilityFetchFlags(flags);
            final View root = findViewByAccessibilityId(accessibilityViewId);
            if (root != null) {
                final int resolvedViewId = root.getContext().getResources()
@@ -494,7 +497,7 @@ public final class AccessibilityInteractionController {
                mAddNodeInfosForViewId.reset();
            }
        } finally {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            resetAccessibilityFetchFlags();
            updateInfosForViewportAndReturnFindNodeResult(
                    infos, callback, interactionId, spec, matrixValues, interactiveRegion);
        }
@@ -542,7 +545,7 @@ public final class AccessibilityInteractionController {
            if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                return;
            }
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
            setAccessibilityFetchFlags(flags);
            final View root = findViewByAccessibilityId(accessibilityViewId);
            if (root != null && isShown(root)) {
                AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
@@ -561,7 +564,7 @@ public final class AccessibilityInteractionController {
                        final int viewCount = foundViews.size();
                        for (int i = 0; i < viewCount; i++) {
                            View foundView = foundViews.get(i);
                            if (isShown(foundView)) {
                            if (isShown(foundView) && isVisibleToAccessibilityService(foundView)) {
                                provider = foundView.getAccessibilityNodeProvider();
                                if (provider != null) {
                                    List<AccessibilityNodeInfo> infosFromProvider =
@@ -579,7 +582,7 @@ public final class AccessibilityInteractionController {
                }
            }
        } finally {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            resetAccessibilityFetchFlags();
            updateInfosForViewportAndReturnFindNodeResult(
                    infos, callback, interactionId, spec, matrixValues, interactiveRegion);
        }
@@ -627,7 +630,7 @@ public final class AccessibilityInteractionController {
            if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                return;
            }
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
            setAccessibilityFetchFlags(flags);
            final View root = findViewByAccessibilityId(accessibilityViewId);
            if (root != null && isShown(root)) {
                switch (focusType) {
@@ -642,6 +645,9 @@ public final class AccessibilityInteractionController {
                        if (!isShown(host)) {
                            break;
                        }
                        if (!isVisibleToAccessibilityService(host)) {
                            break;
                        }
                        // If the host has a provider ask this provider to search for the
                        // focus instead fetching all provider nodes to do the search here.
                        AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
@@ -662,6 +668,9 @@ public final class AccessibilityInteractionController {
                        if (!isShown(target)) {
                            break;
                        }
                        if (!isVisibleToAccessibilityService(target)) {
                            break;
                        }
                        AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
                        if (provider != null) {
                            focused = provider.findFocus(focusType);
@@ -675,7 +684,7 @@ public final class AccessibilityInteractionController {
                }
            }
        } finally {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            resetAccessibilityFetchFlags();
            updateInfoForViewportAndReturnFindNodeResult(
                    focused, callback, interactionId, spec, matrixValues, interactiveRegion);
        }
@@ -722,7 +731,7 @@ public final class AccessibilityInteractionController {
            if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                return;
            }
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
            setAccessibilityFetchFlags(flags);
            final View root = findViewByAccessibilityId(accessibilityViewId);
            if (root != null && isShown(root)) {
                View nextView = root.focusSearch(direction);
@@ -731,7 +740,7 @@ public final class AccessibilityInteractionController {
                }
            }
        } finally {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            resetAccessibilityFetchFlags();
            updateInfoForViewportAndReturnFindNodeResult(
                    next, callback, interactionId, spec, matrixValues, interactiveRegion);
        }
@@ -778,9 +787,9 @@ public final class AccessibilityInteractionController {
                    mViewRootImpl.mStopped || mViewRootImpl.mPausedForTransition) {
                return;
            }
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
            setAccessibilityFetchFlags(flags);
            final View target = findViewByAccessibilityId(accessibilityViewId);
            if (target != null && isShown(target)) {
            if (target != null && isShown(target) && isVisibleToAccessibilityService(target)) {
                mA11yManager.notifyPerformingAction(action);
                if (action == R.id.accessibilityActionClickOnClickableSpan) {
                    // Handle this hidden action separately
@@ -799,7 +808,7 @@ public final class AccessibilityInteractionController {
            }
        } finally {
            try {
                mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
                resetAccessibilityFetchFlags();
                callback.setPerformAccessibilityActionResult(succeeded, interactionId);
            } catch (RemoteException re) {
                /* ignore - the other side will time out */
@@ -823,9 +832,9 @@ public final class AccessibilityInteractionController {
            return;
        }
        try {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags =
                    AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
            final View root = mViewRootImpl.mView;
            setAccessibilityFetchFlags(
                    AccessibilityNodeInfo.FLAG_SERVICE_REQUESTS_INCLUDE_NOT_IMPORTANT_VIEWS);
            final View root = getRootView();
            if (root != null && isShown(root)) {
                final View host = mViewRootImpl.mAccessibilityFocusedHost;
                // If there is no accessibility focus host or it is not a descendant
@@ -849,7 +858,7 @@ public final class AccessibilityInteractionController {
                }
            }
        } finally {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            resetAccessibilityFetchFlags();
        }
    }

@@ -869,7 +878,7 @@ public final class AccessibilityInteractionController {
                || mViewRootImpl.mStopped || mViewRootImpl.mPausedForTransition) {
            return;
        }
        final View root = mViewRootImpl.mView;
        final View root = getRootView();
        if (root != null && isShown(root)) {
            // trigger ACTION_OUTSIDE to notify windows
            final long now = SystemClock.uptimeMillis();
@@ -882,12 +891,30 @@ public final class AccessibilityInteractionController {

    private View findViewByAccessibilityId(int accessibilityId) {
        if (accessibilityId == AccessibilityNodeInfo.ROOT_ITEM_ID) {
            return mViewRootImpl.mView;
            return getRootView();
        } else {
            return AccessibilityNodeIdManager.getInstance().findView(accessibilityId);
        }
    }

    private View getRootView() {
        if (!isVisibleToAccessibilityService(mViewRootImpl.mView)) {
            return null;
        }
        return mViewRootImpl.mView;
    }

    private void setAccessibilityFetchFlags(int flags) {
        mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
        mA11yManager.setRequestFromAccessibilityTool(
                (flags & AccessibilityNodeInfo.FLAG_SERVICE_IS_ACCESSIBILITY_TOOL) != 0);
    }

    private void resetAccessibilityFetchFlags() {
        mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
        mA11yManager.setRequestFromAccessibilityTool(false);
    }

    // The boundInScreen includes magnification effect, so we need to normalize it before
    // determine the visibility.
    private void adjustIsVisibleToUserIfNeeded(AccessibilityNodeInfo info,
@@ -1706,7 +1733,7 @@ public final class AccessibilityInteractionController {

        @Override
        public boolean test(View view) {
            if (view.getId() == mViewId && isShown(view)) {
            if (view.getId() == mViewId && isShown(view) && isVisibleToAccessibilityService(view)) {
                mInfos.add(view.createAccessibilityNodeInfo());
            }
            return false;
Loading