Loading services/accessibility/Android.bp +1 −12 Original line number Original line Diff line number Diff line Loading @@ -35,7 +35,7 @@ java_library_static { "androidx.annotation_annotation", "androidx.annotation_annotation", ], ], static_libs: [ static_libs: [ "a11ychecker-protos-java-proto-lite", "accessibility_protos_lite", "com_android_server_accessibility_flags_lib", "com_android_server_accessibility_flags_lib", "//frameworks/base/packages/SystemUI/aconfig:com_android_systemui_flags_lib", "//frameworks/base/packages/SystemUI/aconfig:com_android_systemui_flags_lib", ], ], Loading Loading @@ -71,17 +71,6 @@ java_aconfig_library { aconfig_declarations: "com_android_server_accessibility_flags", aconfig_declarations: "com_android_server_accessibility_flags", } } java_library_static { name: "a11ychecker-protos-java-proto-lite", proto: { type: "lite", canonical_path_from_root: false, }, srcs: [ "java/**/a11ychecker/proto/*.proto", ], } genrule { genrule { name: "statslog-accessibility-java-gen", name: "statslog-accessibility-java-gen", tools: ["stats-log-api-gen"], tools: ["stats-log-api-gen"], Loading services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerManager.java +5 −6 Original line number Original line Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.server.accessibility.Flags; import com.android.server.accessibility.Flags; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultReported; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckPreset; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckPreset; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck; Loading Loading @@ -58,7 +57,7 @@ public final class AccessibilityCheckerManager { private final PackageManager mPackageManager; private final PackageManager mPackageManager; private final Set<AccessibilityHierarchyCheck> mHierarchyChecks; private final Set<AccessibilityHierarchyCheck> mHierarchyChecks; private final ATFHierarchyBuilder mATFHierarchyBuilder; private final ATFHierarchyBuilder mATFHierarchyBuilder; private final Set<AccessibilityCheckResultReported> mCachedResults = new HashSet<>(); private final Set<AndroidAccessibilityCheckerResult> mCachedResults = new HashSet<>(); @VisibleForTesting @VisibleForTesting final A11yCheckerTimer mTimer = new A11yCheckerTimer(); final A11yCheckerTimer mTimer = new A11yCheckerTimer(); Loading @@ -85,14 +84,14 @@ public final class AccessibilityCheckerManager { * logging. Returns the check results for the given nodes. * logging. Returns the check results for the given nodes. */ */ @RequiresPermission(allOf = {android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) @RequiresPermission(allOf = {android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public Set<AccessibilityCheckResultReported> maybeRunA11yChecker( public Set<AndroidAccessibilityCheckerResult> maybeRunA11yChecker( List<AccessibilityNodeInfo> nodes, @Nullable String sourceEventClassName, List<AccessibilityNodeInfo> nodes, @Nullable String sourceEventClassName, ComponentName a11yServiceComponentName, @UserIdInt int userId) { ComponentName a11yServiceComponentName, @UserIdInt int userId) { if (!shouldRunA11yChecker()) { if (!shouldRunA11yChecker()) { return Set.of(); return Set.of(); } } Set<AccessibilityCheckResultReported> allResults = new HashSet<>(); Set<AndroidAccessibilityCheckerResult> allResults = new HashSet<>(); String defaultBrowserName = mPackageManager.getDefaultBrowserPackageNameAsUser(userId); String defaultBrowserName = mPackageManager.getDefaultBrowserPackageNameAsUser(userId); try { try { Loading @@ -104,7 +103,7 @@ public final class AccessibilityCheckerManager { continue; continue; } } List<AccessibilityHierarchyCheckResult> checkResults = runChecksOnNode(nodeInfo); List<AccessibilityHierarchyCheckResult> checkResults = runChecksOnNode(nodeInfo); Set<AccessibilityCheckResultReported> filteredResults = Set<AndroidAccessibilityCheckerResult> filteredResults = AccessibilityCheckerUtils.processResults(nodeInfo, checkResults, AccessibilityCheckerUtils.processResults(nodeInfo, checkResults, sourceEventClassName, mPackageManager, a11yServiceComponentName); sourceEventClassName, mPackageManager, a11yServiceComponentName); allResults.addAll(filteredResults); allResults.addAll(filteredResults); Loading @@ -127,7 +126,7 @@ public final class AccessibilityCheckerManager { return checkResults; return checkResults; } } public Set<AccessibilityCheckResultReported> getCachedResults() { public Set<AndroidAccessibilityCheckerResult> getCachedResults() { return Collections.unmodifiableSet(mCachedResults); return Collections.unmodifiableSet(mCachedResults); } } Loading services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerStatsdLogger.java +4 −5 Original line number Original line Diff line number Diff line Loading @@ -16,10 +16,9 @@ package com.android.server.accessibility.a11ychecker; package com.android.server.accessibility.a11ychecker; import android.text.TextUtils; import android.util.Slog; import android.util.Slog; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultReported; import java.util.Set; import java.util.Set; Loading @@ -35,11 +34,11 @@ public class AccessibilityCheckerStatsdLogger { /** /** * Writes results to statsd. * Writes results to statsd. */ */ public static void logResults(Set<AccessibilityCheckResultReported> results) { public static void logResults(Set<AndroidAccessibilityCheckerResult> results) { Slog.i(LOG_TAG, String.format("Writing %d AccessibilityCheckResultReported events", Slog.i(LOG_TAG, TextUtils.formatSimple("Writing %d AccessibilityCheckResultReported events", results.size())); results.size())); for (AccessibilityCheckResultReported result : results) { for (AndroidAccessibilityCheckerResult result : results) { AccessibilityCheckerStatsLog.write(ATOM_ID, AccessibilityCheckerStatsLog.write(ATOM_ID, result.getPackageName(), result.getPackageName(), result.getAppVersionCode(), result.getAppVersionCode(), Loading services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtils.java +11 −11 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.server.accessibility.a11ychecker; package com.android.server.accessibility.a11ychecker; import android.accessibility.AccessibilityCheckClass; import android.accessibility.AccessibilityCheckResultType; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ComponentName; import android.content.pm.PackageInfo; import android.content.pm.PackageInfo; Loading @@ -25,9 +27,6 @@ import android.util.Slog; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckClass; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultReported; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultType; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck; Loading Loading @@ -92,7 +91,7 @@ public class AccessibilityCheckerUtils { AccessibilityCheckClass.TRAVERSAL_ORDER_CHECK)); AccessibilityCheckClass.TRAVERSAL_ORDER_CHECK)); // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto) // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto) static Set<AccessibilityCheckResultReported> processResults( static Set<AndroidAccessibilityCheckerResult> processResults( AccessibilityNodeInfo nodeInfo, AccessibilityNodeInfo nodeInfo, List<AccessibilityHierarchyCheckResult> checkResults, List<AccessibilityHierarchyCheckResult> checkResults, @Nullable String activityClassName, @Nullable String activityClassName, Loading @@ -103,16 +102,16 @@ public class AccessibilityCheckerUtils { if (nodePath == null) { if (nodePath == null) { return Set.of(); return Set.of(); } } AccessibilityCheckResultReported.Builder builder; AndroidAccessibilityCheckerResult.Builder commonBuilder; try { try { builder = AccessibilityCheckResultReported.newBuilder() commonBuilder = AndroidAccessibilityCheckerResult.newBuilder() .setPackageName(appPackageName) .setPackageName(appPackageName) .setAppVersionCode(getAppVersionCode(packageManager, appPackageName)) .setAppVersionCode(getAppVersionCode(packageManager, appPackageName)) .setUiElementPath(nodePath) .setUiElementPath(nodePath) .setActivityName( .setActivityName( getActivityName(packageManager, appPackageName, activityClassName)) getActivityName(packageManager, appPackageName, activityClassName)) .setWindowTitle(getWindowTitle(nodeInfo)) .setWindowTitle(getWindowTitle(nodeInfo)) .setSourceComponentName(a11yServiceComponentName.flattenToString()) .setSourceComponentName(a11yServiceComponentName) .setSourceVersionCode( .setSourceVersionCode( getAppVersionCode(packageManager, getAppVersionCode(packageManager, a11yServiceComponentName.getPackageName())); a11yServiceComponentName.getPackageName())); Loading @@ -126,7 +125,8 @@ public class AccessibilityCheckerUtils { == AccessibilityCheckResult.AccessibilityCheckResultType.ERROR == AccessibilityCheckResult.AccessibilityCheckResultType.ERROR || checkResult.getType() || checkResult.getType() == AccessibilityCheckResult.AccessibilityCheckResultType.WARNING) == AccessibilityCheckResult.AccessibilityCheckResultType.WARNING) .map(checkResult -> builder.setResultCheckClass( .map(checkResult -> new AndroidAccessibilityCheckerResult.Builder( commonBuilder).setResultCheckClass( getCheckClass(checkResult)).setResultType( getCheckClass(checkResult)).setResultType( getCheckResultType(checkResult)).setResultId( getCheckResultType(checkResult)).setResultId( checkResult.getResultId()).build()) checkResult.getResultId()).build()) Loading Loading @@ -188,9 +188,9 @@ public class AccessibilityCheckerUtils { private static AccessibilityCheckResultType getCheckResultType( private static AccessibilityCheckResultType getCheckResultType( AccessibilityHierarchyCheckResult checkResult) { AccessibilityHierarchyCheckResult checkResult) { return switch (checkResult.getType()) { return switch (checkResult.getType()) { case ERROR -> AccessibilityCheckResultType.ERROR; case ERROR -> AccessibilityCheckResultType.ERROR_CHECK_RESULT_TYPE; case WARNING -> AccessibilityCheckResultType.WARNING; case WARNING -> AccessibilityCheckResultType.WARNING_CHECK_RESULT_TYPE; default -> AccessibilityCheckResultType.UNKNOWN_RESULT_TYPE; default -> AccessibilityCheckResultType.UNKNOWN_CHECK_RESULT_TYPE; }; }; } } Loading services/accessibility/java/com/android/server/accessibility/a11ychecker/AndroidAccessibilityCheckerResult.java 0 → 100644 +196 −0 Original line number Original line Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.accessibility.a11ychecker; import android.accessibility.AccessibilityCheckClass; import android.accessibility.AccessibilityCheckResultType; import android.content.ComponentName; import android.text.TextUtils; public class AndroidAccessibilityCheckerResult implements Cloneable { // Package name of the app containing the checked View. private String mPackageName; // Version code of the app containing the checked View. private long mAppVersionCode; // The path of the View starting from the root element in the window. Each element is // represented by the View's resource id, when available, or the View's class name. private String mUiElementPath; // Class name of the activity containing the checked View. private String mActivityName; // Title of the window containing the checked View. private String mWindowTitle; // The component name of the app running the AccessibilityService which provided the a11y node. private String mSourceComponentName; // Version code of the app running the AccessibilityService that provided the a11y node. private long mSourceVersionCode; // Class Name of the AccessibilityCheck that produced the result. private AccessibilityCheckClass mResultCheckClass; // Result type of the AccessibilityCheckResult. private AccessibilityCheckResultType mResultType; // Result ID of the AccessibilityCheckResult. private int mResultId; static final class Builder { private final AndroidAccessibilityCheckerResult mInstance; Builder() { mInstance = new AndroidAccessibilityCheckerResult(); } Builder(Builder otherBuilder) { mInstance = otherBuilder.mInstance.clone(); } public Builder setPackageName(String packageName) { mInstance.mPackageName = packageName; return this; } public Builder setAppVersionCode(long versionCode) { mInstance.mAppVersionCode = versionCode; return this; } public Builder setUiElementPath(String uiElementPath) { mInstance.mUiElementPath = uiElementPath; return this; } public Builder setActivityName(String activityName) { mInstance.mActivityName = activityName; return this; } public Builder setWindowTitle(String windowTitle) { mInstance.mWindowTitle = windowTitle; return this; } public Builder setSourceComponentName(ComponentName componentName) { mInstance.mSourceComponentName = componentName.flattenToString(); return this; } public Builder setSourceVersionCode(long versionCode) { mInstance.mSourceVersionCode = versionCode; return this; } public Builder setResultCheckClass(AccessibilityCheckClass checkClass) { mInstance.mResultCheckClass = checkClass; return this; } public Builder setResultType(AccessibilityCheckResultType resultType) { mInstance.mResultType = resultType; return this; } public Builder setResultId(int resultId) { mInstance.mResultId = resultId; return this; } public AndroidAccessibilityCheckerResult build() { // TODO: assert all fields are set, etc return mInstance; } } static Builder newBuilder() { return new Builder(); } public String getPackageName() { return mPackageName; } public long getAppVersionCode() { return mAppVersionCode; } public String getUiElementPath() { return mUiElementPath; } public String getActivityName() { return mActivityName; } public String getWindowTitle() { return mWindowTitle; } public String getSourceComponentName() { return mSourceComponentName; } public long getSourceVersionCode() { return mSourceVersionCode; } public AccessibilityCheckClass getResultCheckClass() { return mResultCheckClass; } public AccessibilityCheckResultType getResultType() { return mResultType; } public int getResultId() { return mResultId; } @Override public boolean equals(Object other) { if (!(other instanceof AndroidAccessibilityCheckerResult)) { return false; } AndroidAccessibilityCheckerResult otherResult = (AndroidAccessibilityCheckerResult) other; return mPackageName.equals(otherResult.mPackageName) && mAppVersionCode == otherResult.mAppVersionCode && mUiElementPath.equals(otherResult.mUiElementPath) && mActivityName.equals(otherResult.mActivityName) && mWindowTitle.equals(otherResult.mWindowTitle) && mSourceComponentName.equals(otherResult.mSourceComponentName) && mSourceVersionCode == otherResult.mSourceVersionCode && mResultCheckClass.equals(otherResult.mResultCheckClass) && mResultType.equals(otherResult.mResultType) && mResultId == otherResult.mResultId; } @Override public int hashCode() { return toString().hashCode(); } @Override public String toString() { return TextUtils.formatSimple("%s:%d:%s:%s:%s:%s:%d:%s:%s:%d", mPackageName, mAppVersionCode, mUiElementPath, mActivityName, mWindowTitle, mSourceComponentName, mSourceVersionCode, mResultCheckClass.name(), mResultType.name(), mResultId); } @Override public AndroidAccessibilityCheckerResult clone() { try { return (AndroidAccessibilityCheckerResult) super.clone(); } catch (CloneNotSupportedException e) { return null; } } } Loading
services/accessibility/Android.bp +1 −12 Original line number Original line Diff line number Diff line Loading @@ -35,7 +35,7 @@ java_library_static { "androidx.annotation_annotation", "androidx.annotation_annotation", ], ], static_libs: [ static_libs: [ "a11ychecker-protos-java-proto-lite", "accessibility_protos_lite", "com_android_server_accessibility_flags_lib", "com_android_server_accessibility_flags_lib", "//frameworks/base/packages/SystemUI/aconfig:com_android_systemui_flags_lib", "//frameworks/base/packages/SystemUI/aconfig:com_android_systemui_flags_lib", ], ], Loading Loading @@ -71,17 +71,6 @@ java_aconfig_library { aconfig_declarations: "com_android_server_accessibility_flags", aconfig_declarations: "com_android_server_accessibility_flags", } } java_library_static { name: "a11ychecker-protos-java-proto-lite", proto: { type: "lite", canonical_path_from_root: false, }, srcs: [ "java/**/a11ychecker/proto/*.proto", ], } genrule { genrule { name: "statslog-accessibility-java-gen", name: "statslog-accessibility-java-gen", tools: ["stats-log-api-gen"], tools: ["stats-log-api-gen"], Loading
services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerManager.java +5 −6 Original line number Original line Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.server.accessibility.Flags; import com.android.server.accessibility.Flags; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultReported; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckPreset; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckPreset; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck; Loading Loading @@ -58,7 +57,7 @@ public final class AccessibilityCheckerManager { private final PackageManager mPackageManager; private final PackageManager mPackageManager; private final Set<AccessibilityHierarchyCheck> mHierarchyChecks; private final Set<AccessibilityHierarchyCheck> mHierarchyChecks; private final ATFHierarchyBuilder mATFHierarchyBuilder; private final ATFHierarchyBuilder mATFHierarchyBuilder; private final Set<AccessibilityCheckResultReported> mCachedResults = new HashSet<>(); private final Set<AndroidAccessibilityCheckerResult> mCachedResults = new HashSet<>(); @VisibleForTesting @VisibleForTesting final A11yCheckerTimer mTimer = new A11yCheckerTimer(); final A11yCheckerTimer mTimer = new A11yCheckerTimer(); Loading @@ -85,14 +84,14 @@ public final class AccessibilityCheckerManager { * logging. Returns the check results for the given nodes. * logging. Returns the check results for the given nodes. */ */ @RequiresPermission(allOf = {android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) @RequiresPermission(allOf = {android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public Set<AccessibilityCheckResultReported> maybeRunA11yChecker( public Set<AndroidAccessibilityCheckerResult> maybeRunA11yChecker( List<AccessibilityNodeInfo> nodes, @Nullable String sourceEventClassName, List<AccessibilityNodeInfo> nodes, @Nullable String sourceEventClassName, ComponentName a11yServiceComponentName, @UserIdInt int userId) { ComponentName a11yServiceComponentName, @UserIdInt int userId) { if (!shouldRunA11yChecker()) { if (!shouldRunA11yChecker()) { return Set.of(); return Set.of(); } } Set<AccessibilityCheckResultReported> allResults = new HashSet<>(); Set<AndroidAccessibilityCheckerResult> allResults = new HashSet<>(); String defaultBrowserName = mPackageManager.getDefaultBrowserPackageNameAsUser(userId); String defaultBrowserName = mPackageManager.getDefaultBrowserPackageNameAsUser(userId); try { try { Loading @@ -104,7 +103,7 @@ public final class AccessibilityCheckerManager { continue; continue; } } List<AccessibilityHierarchyCheckResult> checkResults = runChecksOnNode(nodeInfo); List<AccessibilityHierarchyCheckResult> checkResults = runChecksOnNode(nodeInfo); Set<AccessibilityCheckResultReported> filteredResults = Set<AndroidAccessibilityCheckerResult> filteredResults = AccessibilityCheckerUtils.processResults(nodeInfo, checkResults, AccessibilityCheckerUtils.processResults(nodeInfo, checkResults, sourceEventClassName, mPackageManager, a11yServiceComponentName); sourceEventClassName, mPackageManager, a11yServiceComponentName); allResults.addAll(filteredResults); allResults.addAll(filteredResults); Loading @@ -127,7 +126,7 @@ public final class AccessibilityCheckerManager { return checkResults; return checkResults; } } public Set<AccessibilityCheckResultReported> getCachedResults() { public Set<AndroidAccessibilityCheckerResult> getCachedResults() { return Collections.unmodifiableSet(mCachedResults); return Collections.unmodifiableSet(mCachedResults); } } Loading
services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerStatsdLogger.java +4 −5 Original line number Original line Diff line number Diff line Loading @@ -16,10 +16,9 @@ package com.android.server.accessibility.a11ychecker; package com.android.server.accessibility.a11ychecker; import android.text.TextUtils; import android.util.Slog; import android.util.Slog; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultReported; import java.util.Set; import java.util.Set; Loading @@ -35,11 +34,11 @@ public class AccessibilityCheckerStatsdLogger { /** /** * Writes results to statsd. * Writes results to statsd. */ */ public static void logResults(Set<AccessibilityCheckResultReported> results) { public static void logResults(Set<AndroidAccessibilityCheckerResult> results) { Slog.i(LOG_TAG, String.format("Writing %d AccessibilityCheckResultReported events", Slog.i(LOG_TAG, TextUtils.formatSimple("Writing %d AccessibilityCheckResultReported events", results.size())); results.size())); for (AccessibilityCheckResultReported result : results) { for (AndroidAccessibilityCheckerResult result : results) { AccessibilityCheckerStatsLog.write(ATOM_ID, AccessibilityCheckerStatsLog.write(ATOM_ID, result.getPackageName(), result.getPackageName(), result.getAppVersionCode(), result.getAppVersionCode(), Loading
services/accessibility/java/com/android/server/accessibility/a11ychecker/AccessibilityCheckerUtils.java +11 −11 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.server.accessibility.a11ychecker; package com.android.server.accessibility.a11ychecker; import android.accessibility.AccessibilityCheckClass; import android.accessibility.AccessibilityCheckResultType; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ComponentName; import android.content.pm.PackageInfo; import android.content.pm.PackageInfo; Loading @@ -25,9 +27,6 @@ import android.util.Slog; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckClass; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultReported; import com.android.server.accessibility.a11ychecker.A11yCheckerProto.AccessibilityCheckResultType; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck; import com.google.android.apps.common.testing.accessibility.framework.AccessibilityHierarchyCheck; Loading Loading @@ -92,7 +91,7 @@ public class AccessibilityCheckerUtils { AccessibilityCheckClass.TRAVERSAL_ORDER_CHECK)); AccessibilityCheckClass.TRAVERSAL_ORDER_CHECK)); // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto) // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/a11ychecker/proto/a11ychecker.proto) static Set<AccessibilityCheckResultReported> processResults( static Set<AndroidAccessibilityCheckerResult> processResults( AccessibilityNodeInfo nodeInfo, AccessibilityNodeInfo nodeInfo, List<AccessibilityHierarchyCheckResult> checkResults, List<AccessibilityHierarchyCheckResult> checkResults, @Nullable String activityClassName, @Nullable String activityClassName, Loading @@ -103,16 +102,16 @@ public class AccessibilityCheckerUtils { if (nodePath == null) { if (nodePath == null) { return Set.of(); return Set.of(); } } AccessibilityCheckResultReported.Builder builder; AndroidAccessibilityCheckerResult.Builder commonBuilder; try { try { builder = AccessibilityCheckResultReported.newBuilder() commonBuilder = AndroidAccessibilityCheckerResult.newBuilder() .setPackageName(appPackageName) .setPackageName(appPackageName) .setAppVersionCode(getAppVersionCode(packageManager, appPackageName)) .setAppVersionCode(getAppVersionCode(packageManager, appPackageName)) .setUiElementPath(nodePath) .setUiElementPath(nodePath) .setActivityName( .setActivityName( getActivityName(packageManager, appPackageName, activityClassName)) getActivityName(packageManager, appPackageName, activityClassName)) .setWindowTitle(getWindowTitle(nodeInfo)) .setWindowTitle(getWindowTitle(nodeInfo)) .setSourceComponentName(a11yServiceComponentName.flattenToString()) .setSourceComponentName(a11yServiceComponentName) .setSourceVersionCode( .setSourceVersionCode( getAppVersionCode(packageManager, getAppVersionCode(packageManager, a11yServiceComponentName.getPackageName())); a11yServiceComponentName.getPackageName())); Loading @@ -126,7 +125,8 @@ public class AccessibilityCheckerUtils { == AccessibilityCheckResult.AccessibilityCheckResultType.ERROR == AccessibilityCheckResult.AccessibilityCheckResultType.ERROR || checkResult.getType() || checkResult.getType() == AccessibilityCheckResult.AccessibilityCheckResultType.WARNING) == AccessibilityCheckResult.AccessibilityCheckResultType.WARNING) .map(checkResult -> builder.setResultCheckClass( .map(checkResult -> new AndroidAccessibilityCheckerResult.Builder( commonBuilder).setResultCheckClass( getCheckClass(checkResult)).setResultType( getCheckClass(checkResult)).setResultType( getCheckResultType(checkResult)).setResultId( getCheckResultType(checkResult)).setResultId( checkResult.getResultId()).build()) checkResult.getResultId()).build()) Loading Loading @@ -188,9 +188,9 @@ public class AccessibilityCheckerUtils { private static AccessibilityCheckResultType getCheckResultType( private static AccessibilityCheckResultType getCheckResultType( AccessibilityHierarchyCheckResult checkResult) { AccessibilityHierarchyCheckResult checkResult) { return switch (checkResult.getType()) { return switch (checkResult.getType()) { case ERROR -> AccessibilityCheckResultType.ERROR; case ERROR -> AccessibilityCheckResultType.ERROR_CHECK_RESULT_TYPE; case WARNING -> AccessibilityCheckResultType.WARNING; case WARNING -> AccessibilityCheckResultType.WARNING_CHECK_RESULT_TYPE; default -> AccessibilityCheckResultType.UNKNOWN_RESULT_TYPE; default -> AccessibilityCheckResultType.UNKNOWN_CHECK_RESULT_TYPE; }; }; } } Loading
services/accessibility/java/com/android/server/accessibility/a11ychecker/AndroidAccessibilityCheckerResult.java 0 → 100644 +196 −0 Original line number Original line Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.accessibility.a11ychecker; import android.accessibility.AccessibilityCheckClass; import android.accessibility.AccessibilityCheckResultType; import android.content.ComponentName; import android.text.TextUtils; public class AndroidAccessibilityCheckerResult implements Cloneable { // Package name of the app containing the checked View. private String mPackageName; // Version code of the app containing the checked View. private long mAppVersionCode; // The path of the View starting from the root element in the window. Each element is // represented by the View's resource id, when available, or the View's class name. private String mUiElementPath; // Class name of the activity containing the checked View. private String mActivityName; // Title of the window containing the checked View. private String mWindowTitle; // The component name of the app running the AccessibilityService which provided the a11y node. private String mSourceComponentName; // Version code of the app running the AccessibilityService that provided the a11y node. private long mSourceVersionCode; // Class Name of the AccessibilityCheck that produced the result. private AccessibilityCheckClass mResultCheckClass; // Result type of the AccessibilityCheckResult. private AccessibilityCheckResultType mResultType; // Result ID of the AccessibilityCheckResult. private int mResultId; static final class Builder { private final AndroidAccessibilityCheckerResult mInstance; Builder() { mInstance = new AndroidAccessibilityCheckerResult(); } Builder(Builder otherBuilder) { mInstance = otherBuilder.mInstance.clone(); } public Builder setPackageName(String packageName) { mInstance.mPackageName = packageName; return this; } public Builder setAppVersionCode(long versionCode) { mInstance.mAppVersionCode = versionCode; return this; } public Builder setUiElementPath(String uiElementPath) { mInstance.mUiElementPath = uiElementPath; return this; } public Builder setActivityName(String activityName) { mInstance.mActivityName = activityName; return this; } public Builder setWindowTitle(String windowTitle) { mInstance.mWindowTitle = windowTitle; return this; } public Builder setSourceComponentName(ComponentName componentName) { mInstance.mSourceComponentName = componentName.flattenToString(); return this; } public Builder setSourceVersionCode(long versionCode) { mInstance.mSourceVersionCode = versionCode; return this; } public Builder setResultCheckClass(AccessibilityCheckClass checkClass) { mInstance.mResultCheckClass = checkClass; return this; } public Builder setResultType(AccessibilityCheckResultType resultType) { mInstance.mResultType = resultType; return this; } public Builder setResultId(int resultId) { mInstance.mResultId = resultId; return this; } public AndroidAccessibilityCheckerResult build() { // TODO: assert all fields are set, etc return mInstance; } } static Builder newBuilder() { return new Builder(); } public String getPackageName() { return mPackageName; } public long getAppVersionCode() { return mAppVersionCode; } public String getUiElementPath() { return mUiElementPath; } public String getActivityName() { return mActivityName; } public String getWindowTitle() { return mWindowTitle; } public String getSourceComponentName() { return mSourceComponentName; } public long getSourceVersionCode() { return mSourceVersionCode; } public AccessibilityCheckClass getResultCheckClass() { return mResultCheckClass; } public AccessibilityCheckResultType getResultType() { return mResultType; } public int getResultId() { return mResultId; } @Override public boolean equals(Object other) { if (!(other instanceof AndroidAccessibilityCheckerResult)) { return false; } AndroidAccessibilityCheckerResult otherResult = (AndroidAccessibilityCheckerResult) other; return mPackageName.equals(otherResult.mPackageName) && mAppVersionCode == otherResult.mAppVersionCode && mUiElementPath.equals(otherResult.mUiElementPath) && mActivityName.equals(otherResult.mActivityName) && mWindowTitle.equals(otherResult.mWindowTitle) && mSourceComponentName.equals(otherResult.mSourceComponentName) && mSourceVersionCode == otherResult.mSourceVersionCode && mResultCheckClass.equals(otherResult.mResultCheckClass) && mResultType.equals(otherResult.mResultType) && mResultId == otherResult.mResultId; } @Override public int hashCode() { return toString().hashCode(); } @Override public String toString() { return TextUtils.formatSimple("%s:%d:%s:%s:%s:%s:%d:%s:%s:%d", mPackageName, mAppVersionCode, mUiElementPath, mActivityName, mWindowTitle, mSourceComponentName, mSourceVersionCode, mResultCheckClass.name(), mResultType.name(), mResultId); } @Override public AndroidAccessibilityCheckerResult clone() { try { return (AndroidAccessibilityCheckerResult) super.clone(); } catch (CloneNotSupportedException e) { return null; } } }