From abdfd6f63b53db8b836e7734789efdf59618b42e Mon Sep 17 00:00:00 2001 From: Daniel Norman Date: Thu, 2 Feb 2023 12:59:07 -0800 Subject: AccessibilityMenuService test class setup & initial test. Bug: 265173123 Test: atest AccessibilityMenuServiceTests Change-Id: I388e02b58bf582ae6b481804c5f34883e8692e5f --- .../accessibility/accessibilitymenu/Android.bp | 9 + .../accessibilitymenu/res/layout/grid_item.xml | 1 + .../AccessibilityMenuService.java | 41 ++++- .../accessibilitymenu/view/A11yMenuAdapter.java | 10 ++ .../accessibilitymenu/tests/Android.bp | 43 +++++ .../accessibilitymenu/tests/AndroidManifest.xml | 32 ++++ .../accessibilitymenu/tests/AndroidTest.xml | 29 ++++ .../accessibilitymenu/tests/TEST_MAPPING | 15 ++ .../tests/AccessibilityMenuServiceTest.java | 183 +++++++++++++++++++++ 9 files changed, 356 insertions(+), 7 deletions(-) create mode 100644 packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp create mode 100644 packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidManifest.xml create mode 100644 packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidTest.xml create mode 100644 packages/SystemUI/accessibility/accessibilitymenu/tests/TEST_MAPPING create mode 100644 packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java diff --git a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp index 140c10da922e..f358417e6bea 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp +++ b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp @@ -18,6 +18,15 @@ package { default_applicable_licenses: ["Android-Apache-2.0"], } +// This filegroup is used by menu tests. +filegroup { + name: "AccessibilityMenuSource", + srcs: [ + "src/**/AccessibilityMenuService.java", + "src/**/A11yMenuShortcut.java", + ], +} + android_app { name: "AccessibilityMenu", diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/layout/grid_item.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/layout/grid_item.xml index 39e5a8c6876b..a902c5b54b7b 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/layout/grid_item.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/layout/grid_item.xml @@ -1,5 +1,6 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidTest.xml b/packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidTest.xml new file mode 100644 index 000000000000..39bee5392720 --- /dev/null +++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidTest.xml @@ -0,0 +1,29 @@ + + + + \ No newline at end of file diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/TEST_MAPPING b/packages/SystemUI/accessibility/accessibilitymenu/tests/TEST_MAPPING new file mode 100644 index 000000000000..2bd52b552698 --- /dev/null +++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/TEST_MAPPING @@ -0,0 +1,15 @@ +{ + "presubmit": [ + { + "name": "AccessibilityMenuServiceTests", + "options": [ + { + "include-annotation": "android.platform.test.annotations.Presubmit" + }, + { + "exclude-annotation": "android.support.test.filters.FlakyTest" + } + ] + } + ] +} \ No newline at end of file diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java new file mode 100644 index 000000000000..529a70c1ab18 --- /dev/null +++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2023 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.systemui.accessibility.accessibilitymenu.tests; + +import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_HIDE_MENU; +import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_TOGGLE_MENU; +import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.PACKAGE_NAME; + +import android.accessibilityservice.AccessibilityServiceInfo; +import android.app.Instrumentation; +import android.app.UiAutomation; +import android.content.Context; +import android.content.Intent; +import android.hardware.display.BrightnessInfo; +import android.hardware.display.DisplayManager; +import android.provider.Settings; +import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.compatibility.common.util.TestUtils; +import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut.ShortcutId; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.List; + +@RunWith(AndroidJUnit4.class) +public class AccessibilityMenuServiceTest { + private static final String TAG = "A11yMenuServiceTest"; + + private static final int TIMEOUT_SERVICE_STATUS_CHANGE_S = 5; + private static final int TIMEOUT_UI_CHANGE_S = 5; + + private static Instrumentation sInstrumentation; + private static UiAutomation sUiAutomation; + + private static AccessibilityManager sAccessibilityManager; + + @BeforeClass + public static void classSetup() throws Throwable { + final String serviceName = PACKAGE_NAME + "/.AccessibilityMenuService"; + sInstrumentation = InstrumentationRegistry.getInstrumentation(); + sUiAutomation = sInstrumentation.getUiAutomation( + UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES); + final Context context = sInstrumentation.getContext(); + sAccessibilityManager = context.getSystemService(AccessibilityManager.class); + + // Disable all a11yServices if any are active. + if (!sAccessibilityManager.getEnabledAccessibilityServiceList( + AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) { + Settings.Secure.putString(context.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, ""); + TestUtils.waitUntil("Failed to disable all services", + TIMEOUT_SERVICE_STATUS_CHANGE_S, + () -> sAccessibilityManager.getEnabledAccessibilityServiceList( + AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()); + } + + // Enable a11yMenu service. + Settings.Secure.putString(context.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, serviceName); + + TestUtils.waitUntil("Failed to enable service", + TIMEOUT_SERVICE_STATUS_CHANGE_S, + () -> sAccessibilityManager.getEnabledAccessibilityServiceList( + AccessibilityServiceInfo.FEEDBACK_ALL_MASK).stream().filter( + info -> info.getId().contains(serviceName)).count() == 1); + } + + @AfterClass + public static void classTeardown() throws Throwable { + Settings.Secure.putString(sInstrumentation.getTargetContext().getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, ""); + } + + private boolean isMenuVisible() { + return sUiAutomation.getRootInActiveWindow() != null + && sUiAutomation.getRootInActiveWindow().getPackageName().toString().equals( + PACKAGE_NAME); + } + + private void openMenu() throws Throwable { + if (isMenuVisible()) { + return; + } + Intent intent = new Intent(PACKAGE_NAME + INTENT_TOGGLE_MENU); + sInstrumentation.getContext().sendBroadcast(intent); + TestUtils.waitUntil("Timed out before menu could appear.", + TIMEOUT_UI_CHANGE_S, () -> isMenuVisible()); + } + + private void closeMenu() throws Throwable { + if (!isMenuVisible()) { + return; + } + Intent intent = new Intent(PACKAGE_NAME + INTENT_HIDE_MENU); + sInstrumentation.getContext().sendBroadcast(intent); + TestUtils.waitUntil("Timed out before menu could close.", + TIMEOUT_UI_CHANGE_S, () -> !isMenuVisible()); + } + + private List getGridButtonList() { + return sUiAutomation.getRootInActiveWindow() + .findAccessibilityNodeInfosByViewId(PACKAGE_NAME + ":id/shortcutIconBtn"); + } + + private AccessibilityNodeInfo findGridButtonInfo( + List buttons, String text) { + for (AccessibilityNodeInfo button: buttons) { + if (button.getUniqueId().equals(text)) { + return button; + } + } + return null; + } + + @Test + public void testAdjustBrightness() throws Throwable { + openMenu(); + + Context context = sInstrumentation.getTargetContext(); + DisplayManager displayManager = context.getSystemService( + DisplayManager.class); + float resetBrightness = displayManager.getBrightness(context.getDisplayId()); + + List buttons = getGridButtonList(); + AccessibilityNodeInfo brightnessUpButton = findGridButtonInfo(buttons, + String.valueOf(ShortcutId.ID_BRIGHTNESS_UP_VALUE.ordinal())); + AccessibilityNodeInfo brightnessDownButton = findGridButtonInfo(buttons, + String.valueOf(ShortcutId.ID_BRIGHTNESS_DOWN_VALUE.ordinal())); + + int clickId = AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.getId(); + BrightnessInfo brightnessInfo = displayManager.getDisplay( + context.getDisplayId()).getBrightnessInfo(); + + try { + displayManager.setBrightness(context.getDisplayId(), brightnessInfo.brightnessMinimum); + TestUtils.waitUntil("Could not change to minimum brightness", + TIMEOUT_UI_CHANGE_S, + () -> displayManager.getBrightness(context.getDisplayId()) + == brightnessInfo.brightnessMinimum); + brightnessUpButton.performAction(clickId); + TestUtils.waitUntil("Did not detect an increase in brightness.", + TIMEOUT_UI_CHANGE_S, + () -> displayManager.getBrightness(context.getDisplayId()) + > brightnessInfo.brightnessMinimum); + + displayManager.setBrightness(context.getDisplayId(), brightnessInfo.brightnessMaximum); + TestUtils.waitUntil("Could not change to maximum brightness", + TIMEOUT_UI_CHANGE_S, + () -> displayManager.getBrightness(context.getDisplayId()) + == brightnessInfo.brightnessMaximum); + brightnessDownButton.performAction(clickId); + TestUtils.waitUntil("Did not detect a decrease in brightness.", + TIMEOUT_UI_CHANGE_S, + () -> displayManager.getBrightness(context.getDisplayId()) + < brightnessInfo.brightnessMaximum); + } finally { + displayManager.setBrightness(context.getDisplayId(), resetBrightness); + closeMenu(); + } + } +} -- cgit v1.2.3-59-g8ed1b