1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.accessibilityservice.cts; 18 19 import static org.junit.Assert.assertTrue; 20 21 import android.accessibilityservice.AccessibilityServiceInfo; 22 import android.accessibilityservice.cts.utils.AsyncUtils; 23 import android.app.Instrumentation; 24 import android.app.UiAutomation; 25 import android.os.Debug; 26 import android.support.test.InstrumentationRegistry; 27 import android.support.test.runner.AndroidJUnit4; 28 import android.text.TextUtils; 29 import android.view.WindowManager; 30 import android.view.accessibility.AccessibilityNodeInfo; 31 import android.view.accessibility.AccessibilityWindowInfo; 32 import android.widget.Button; 33 34 import org.junit.After; 35 import org.junit.Before; 36 import org.junit.BeforeClass; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 40 import java.util.List; 41 42 // Test that an AccessibilityService can display an accessibility overlay 43 @RunWith(AndroidJUnit4.class) 44 public class AccessibilityOverlayTest { 45 46 private static Instrumentation sInstrumentation; 47 private static UiAutomation sUiAutomation; 48 InstrumentedAccessibilityService mService; 49 50 @BeforeClass 51 public static void oneTimeSetUp() { 52 sInstrumentation = InstrumentationRegistry.getInstrumentation(); 53 sUiAutomation = sInstrumentation 54 .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES); 55 AccessibilityServiceInfo info = sUiAutomation.getServiceInfo(); 56 info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS; 57 sUiAutomation.setServiceInfo(info); 58 } 59 60 @Before 61 public void setUp() { 62 mService = StubAccessibilityButtonService.enableSelf(sInstrumentation); 63 } 64 65 @After 66 public void tearDown() { 67 mService.runOnServiceSync(() -> mService.disableSelf()); 68 } 69 70 @Test 71 public void testA11yServiceShowsOverlay_shouldAppear() throws Exception { 72 final Button button = new Button(mService); 73 button.setText("Button"); 74 final String overlayTitle = "Overlay title"; 75 76 sUiAutomation.executeAndWaitForEvent(() -> mService.runOnServiceSync(() -> { 77 final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); 78 params.width = WindowManager.LayoutParams.MATCH_PARENT; 79 params.height = WindowManager.LayoutParams.MATCH_PARENT; 80 params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 81 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 82 params.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; 83 params.setTitle(overlayTitle); 84 mService.getSystemService(WindowManager.class).addView(button, params); 85 }), (event) -> findOverlayWindow() != null, AsyncUtils.DEFAULT_TIMEOUT_MS); 86 87 assertTrue(TextUtils.equals(findOverlayWindow().getTitle(), overlayTitle)); 88 } 89 90 private AccessibilityWindowInfo findOverlayWindow() { 91 List<AccessibilityWindowInfo> windows = sUiAutomation.getWindows(); 92 for (int i = 0; i < windows.size(); i++) { 93 AccessibilityWindowInfo window = windows.get(i); 94 if (window.getType() == AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) { 95 return window; 96 } 97 } 98 return null; 99 } 100 } 101