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

Commit a8896902 authored by Yara Hassan's avatar Yara Hassan
Browse files

Re-use common fields in AccessibilityCheckResultReported across nodes of the same cache

Reduce repeated calls to the package manager and other methods as they are similar for nodes of the same cache.

Bug: 326385939
Test: th/unit tests
Flag: com.android.server.accessibility.enable_a11y_checker_logging
Change-Id: I887b5eb1e1c02627d067d5e54717ad403c4ac820
parent 4ae520ac
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ public final class AccessibilityCheckerManager {
    public Set<AndroidAccessibilityCheckerResult> maybeRunA11yChecker(
            List<AccessibilityNodeInfo> nodes, @Nullable String sourceEventClassName,
            ComponentName a11yServiceComponentName, @UserIdInt int userId) {
        if (!shouldRunA11yChecker()) {
        if (!shouldRunA11yChecker() || nodes.isEmpty()) {
            return Set.of();
        }

@@ -95,24 +95,33 @@ public final class AccessibilityCheckerManager {
        String defaultBrowserName = mPackageManager.getDefaultBrowserPackageNameAsUser(userId);

        try {
            AndroidAccessibilityCheckerResult.Builder commonResultBuilder =
                    AccessibilityCheckerUtils.getCommonResultBuilder(nodes.getFirst(),
                            sourceEventClassName, mPackageManager, a11yServiceComponentName);
            if (commonResultBuilder == null) {
                return Set.of();
            }
            for (AccessibilityNodeInfo nodeInfo : nodes) {
                // Skip browser results because they are mostly related to web content and not the
                // browser app itself.
                // Skip browser results because they are mostly related to web content and
                // not the browser app itself.
                if (nodeInfo.getPackageName() == null
                        || nodeInfo.getPackageName().toString().equals(defaultBrowserName)) {
                    continue;
                }
                List<AccessibilityHierarchyCheckResult> checkResults = runChecksOnNode(nodeInfo);
                List<AccessibilityHierarchyCheckResult> checkResults = runChecksOnNode(
                        nodeInfo);
                Set<AndroidAccessibilityCheckerResult> filteredResults =
                        AccessibilityCheckerUtils.processResults(nodeInfo, checkResults,
                                sourceEventClassName, mPackageManager, a11yServiceComponentName);
                                commonResultBuilder);
                allResults.addAll(filteredResults);
            }
            mCachedResults.addAll(allResults);
            return allResults;

        } catch (RuntimeException e) {
            Slog.e(LOG_TAG, "An unknown error occurred while running a11y checker.", e);
            return Set.of();
        }
        return allResults;
    }

    private List<AccessibilityHierarchyCheckResult> runChecksOnNode(
+28 −18
Original line number Diff line number Diff line
@@ -91,45 +91,55 @@ public class AccessibilityCheckerUtils {
                            AccessibilityCheckClass.TRAVERSAL_ORDER_CHECK));
    // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto)

    static Set<AndroidAccessibilityCheckerResult> processResults(

    /**
     * Returns AccessibilityCheckResultReported.Builder with the common fields for all nodes
     * belonging in the same cache pre-filled.
     */
    static @Nullable AndroidAccessibilityCheckerResult.Builder getCommonResultBuilder(
            AccessibilityNodeInfo nodeInfo,
            List<AccessibilityHierarchyCheckResult> checkResults,
            @Nullable String activityClassName,
            PackageManager packageManager,
            ComponentName a11yServiceComponentName) {
        String appPackageName = nodeInfo.getPackageName().toString();
        String nodePath = AccessibilityNodePathBuilder.createNodePath(nodeInfo);
        if (nodePath == null) {
            return Set.of();
        if (nodeInfo.getPackageName() == null) {
            return null;
        }
        AndroidAccessibilityCheckerResult.Builder commonBuilder;
        String appPackageName = nodeInfo.getPackageName().toString();
        try {
            commonBuilder = AndroidAccessibilityCheckerResult.newBuilder()
            return AndroidAccessibilityCheckerResult.newBuilder()
                    .setPackageName(appPackageName)
                    .setAppVersionCode(getAppVersionCode(packageManager, appPackageName))
                    .setUiElementPath(nodePath)
                    .setActivityName(
                            getActivityName(packageManager, appPackageName, activityClassName))
                    .setWindowTitle(getWindowTitle(nodeInfo))
                    .setSourceComponentName(a11yServiceComponentName)
                    .setSourceVersionCode(
                            getAppVersionCode(packageManager,
                    .setSourceVersionCode(getAppVersionCode(packageManager,
                            a11yServiceComponentName.getPackageName()));
        } catch (PackageManager.NameNotFoundException e) {
            Slog.e(LOG_TAG, "Unknown package name", e);
            return Set.of();
            return null;
        }
    }

    static Set<AndroidAccessibilityCheckerResult> processResults(
            AccessibilityNodeInfo nodeInfo,
            List<AccessibilityHierarchyCheckResult> checkResults,
            AndroidAccessibilityCheckerResult.Builder resultBuilder) {
        String nodePath = AccessibilityNodePathBuilder.createNodePath(nodeInfo);
        if (resultBuilder == null || nodePath == null) {
            return Set.of();
        }
        return checkResults.stream()
                .filter(checkResult -> checkResult.getType()
                        == AccessibilityCheckResult.AccessibilityCheckResultType.ERROR
                        || checkResult.getType()
                        == AccessibilityCheckResult.AccessibilityCheckResultType.WARNING)
                .map(checkResult -> new AndroidAccessibilityCheckerResult.Builder(
                        commonBuilder).setResultCheckClass(
                        getCheckClass(checkResult)).setResultType(
                        getCheckResultType(checkResult)).setResultId(
                        checkResult.getResultId()).build())
                .map(checkResult -> new AndroidAccessibilityCheckerResult.Builder(resultBuilder)
                        .setUiElementPath(nodePath)
                        .setResultCheckClass(getCheckClass(checkResult))
                        .setResultType(getCheckResultType(checkResult))
                        .setResultId(checkResult.getResultId())
                        .build())
                .collect(Collectors.toUnmodifiableSet());
    }

+11 −10
Original line number Diff line number Diff line
@@ -89,14 +89,15 @@ public class AccessibilityCheckerUtilsTest {
                        AccessibilityCheckResult.AccessibilityCheckResultType.NOT_RUN, null, 5,
                        null);

        Set<AndroidAccessibilityCheckerResult> results =
                AccessibilityCheckerUtils.processResults(
                        mockNodeInfo,
                        List.of(result1, result2, result3, result4),
                        null,

        AndroidAccessibilityCheckerResult.Builder resultBuilder =
                AccessibilityCheckerUtils.getCommonResultBuilder(mockNodeInfo, null,
                        mMockPackageManager,
                        new ComponentName(TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME,
                                TEST_A11Y_SERVICE_CLASS_NAME));
        Set<AndroidAccessibilityCheckerResult> results =
                AccessibilityCheckerUtils.processResults(mockNodeInfo,
                        List.of(result1, result2, result3, result4), resultBuilder);

        assertThat(results).containsExactly(
                createResult("TargetNode", "",
@@ -128,14 +129,14 @@ public class AccessibilityCheckerUtilsTest {
                        TouchTargetSizeCheck.class,
                        AccessibilityCheckResult.AccessibilityCheckResultType.ERROR, null, 2, null);

        Set<AndroidAccessibilityCheckerResult> results =
                AccessibilityCheckerUtils.processResults(
                        mockNodeInfo,
                        List.of(result1, result2),
                        null,
        AndroidAccessibilityCheckerResult.Builder resultBuilder =
                AccessibilityCheckerUtils.getCommonResultBuilder(mockNodeInfo, null,
                        mMockPackageManager,
                        new ComponentName(TEST_A11Y_SERVICE_SOURCE_PACKAGE_NAME,
                                TEST_A11Y_SERVICE_CLASS_NAME));
        Set<AndroidAccessibilityCheckerResult> results =
                AccessibilityCheckerUtils.processResults(mockNodeInfo,
                        List.of(result1, result2), resultBuilder);

        assertThat(results).isEmpty();
    }