A11y CTS fixes for Fugu.

Moving magnification center in test away from the center of the
screen, which is the default. When it exactly matches the default,
setCenter returns false, which is not what the test expects.

Moving global actions into their own InstrumentationTestCase. A
couple of these tests were causing flakiness on following tests when,
for example, the HOME intent got fired while the next test was
setting up the activity. Rather than try to deal with the timing
issues, moving the tests into a class that won't try to set up
activities at all.

Skipping test for window divider for Android TV, which doesn't
implement split-screen window mode.

Skipping gesture dispatch tests for devices without touch screens.

Also added some waits for idle to the soft keyboard test. I believe
it was counting windows before its activity was ready and getting
confused.

Bug: 28450244
Change-Id: Ie09e5808350eae85670c7e2a0764732c579b5dfb
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
index c413d01..6542778 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -16,6 +16,7 @@
 
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.GestureDescription;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.graphics.Matrix;
 import android.graphics.Path;
@@ -48,6 +49,9 @@
     TextView mFullScreenTextView;
     Rect mViewBounds = new Rect();
     boolean mGotUpEvent;
+    // Without a touch screen, there's no point in testing this feature
+    boolean mHasTouchScreen;
+    boolean mHasMultiTouch;
 
     public AccessibilityGestureDispatchTest() {
         super(GestureDispatchActivity.class);
@@ -57,6 +61,16 @@
     public void setUp() throws Exception {
         super.setUp();
 
+        PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        mHasTouchScreen = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
+                || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
+        if (!mHasTouchScreen) {
+            return;
+        }
+
+        mHasMultiTouch = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)
+                || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT);
+
         mFullScreenTextView =
                 (TextView) getActivity().findViewById(R.id.full_screen_text_view);
         getInstrumentation().runOnMainSync(() -> {
@@ -73,12 +87,19 @@
 
     @Override
     public void tearDown() throws Exception {
-        mService.runOnServiceSync(() -> mService.disableSelf());
+        if (!mHasTouchScreen) {
+            return;
+        }
 
+        mService.runOnServiceSync(() -> mService.disableSelf());
         super.tearDown();
     }
 
     public void testClickAt_producesDownThenUp() throws InterruptedException {
+        if (!mHasTouchScreen) {
+            return;
+        }
+
         final int clickXInsideView = 10;
         final int clickYInsideView = 20;
         int clickX = clickXInsideView + mViewBounds.left;
@@ -115,6 +136,10 @@
     }
 
     public void testLongClickAt_producesEventsWithLongClickTiming() throws InterruptedException {
+        if (!mHasTouchScreen) {
+            return;
+        }
+
         final int clickXInsideView = 10;
         final int clickYInsideView = 20;
         int clickX = clickXInsideView + mViewBounds.left;
@@ -142,6 +167,10 @@
     }
 
     public void testSwipe_shouldContainPointsInALine() throws InterruptedException {
+        if (!mHasTouchScreen) {
+            return;
+        }
+
         int startXInsideView = 10;
         int startYInsideView = 20;
         int endXInsideView = 20;
@@ -186,6 +215,10 @@
     }
 
     public void testSlowSwipe_shouldNotContainMovesForTinyMovement() throws InterruptedException {
+        if (!mHasTouchScreen) {
+            return;
+        }
+
         int startXInsideView = 10;
         int startYInsideView = 20;
         int endXInsideView = 11;
@@ -223,6 +256,10 @@
     }
 
     public void testAngledPinch_looksReasonable() throws InterruptedException {
+        if (!(mHasTouchScreen && mHasMultiTouch)) {
+            return;
+        }
+
         int centerXInsideView = 50;
         int centerYInsideView = 60;
         int centerX = centerXInsideView + mViewBounds.left;
@@ -297,6 +334,10 @@
     }
 
     public void testClickWhenMagnified_matchesActualTouch() throws InterruptedException {
+        if (!mHasTouchScreen) {
+            return;
+        }
+
         final int clickXInsideView = 10;
         final int clickYInsideView = 20;
         int clickX = clickXInsideView + mViewBounds.left;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
new file mode 100644
index 0000000..b4f839e
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 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 android.accessibilityservice.cts;
+
+import android.accessibilityservice.AccessibilityService;
+import android.os.SystemClock;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Test global actions
+ */
+public class AccessibilityGlobalActionsTest extends InstrumentationTestCase {
+    /**
+     * Timeout required for pending Binder calls or event processing to
+     * complete.
+     */
+    private static final long TIMEOUT_ASYNC_PROCESSING = 5000;
+
+    /**
+     * The timeout since the last accessibility event to consider the device idle.
+     */
+    private static final long TIMEOUT_ACCESSIBILITY_STATE_IDLE = 500;
+
+    @MediumTest
+    public void testPerformGlobalActionBack() throws Exception {
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK));
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionHome() throws Exception {
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_HOME));
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionRecents() throws Exception {
+        // Check whether the action succeeded.
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_RECENTS));
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+
+        // This is a necessary since the back action does not
+        // dismiss recents until they stop animating. Sigh...
+        SystemClock.sleep(5000);
+
+        // Clean up.
+        getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK);
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionNotifications() throws Exception {
+        // Perform the action under test
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS));
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+
+        // Clean up.
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK));
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionQuickSettings() throws Exception {
+        // Check whether the action succeeded.
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS));
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+
+        // Clean up.
+        getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK);
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionPowerDialog() throws Exception {
+        // Check whether the action succeeded.
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_POWER_DIALOG));
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+
+        // Clean up.
+        getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK);
+
+        // Sleep a bit so the UI is settled.
+        waitForIdle();
+    }
+
+    private void waitForIdle() throws TimeoutException {
+        getInstrumentation().getUiAutomation().waitForIdle(
+                TIMEOUT_ACCESSIBILITY_STATE_IDLE,
+                TIMEOUT_ASYNC_PROCESSING);
+    }
+
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
index c021922..ca3ec96 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
@@ -74,8 +74,8 @@
         final Resources res = getInstrumentation().getTargetContext().getResources();
         final DisplayMetrics metrics = res.getDisplayMetrics();
         final float scale = 2.0f;
-        final float x = metrics.widthPixels / 2.0f;
-        final float y = metrics.heightPixels / 2.0f;
+        final float x = metrics.widthPixels / 4.0f;
+        final float y = metrics.heightPixels / 4.0f;
         final AtomicBoolean setScale = new AtomicBoolean();
         final AtomicBoolean setCenter = new AtomicBoolean();
         final AtomicBoolean result = new AtomicBoolean();
@@ -89,8 +89,8 @@
         assertEquals("Failed to apply scale", scale, controller.getScale());
 
         assertTrue("Failed to set center", setCenter.get());
-        assertEquals("Failed to apply center X", x, controller.getCenterX());
-        assertEquals("Failed to apply center Y", y, controller.getCenterY());
+        assertEquals("Failed to apply center X", x, controller.getCenterX(), 5.0f);
+        assertEquals("Failed to apply center Y", y, controller.getCenterY(), 5.0f);
 
         mService.runOnServiceSync(() -> result.set(controller.reset(false)));
 
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
index b782216e..263c402 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
@@ -136,6 +136,7 @@
 
         // Note: This Activity always has a visible keyboard (due to windowSoftInputMode being set
         // to stateAlwaysVisible).
+        waitForIdle();
         int numWindowsWithIme = mUiAutomation.getWindows().size();
 
         // Request the keyboard be hidden.
@@ -161,6 +162,7 @@
 
         // Note: This Activity always has a visible keyboard (due to windowSoftInputMode being set
         // to stateAlwaysVisible).
+        waitForIdle();
         int numWindowsWithIme = mUiAutomation.getWindows().size();
 
         // Set the show mode to SHOW_MODE_HIDDEN.
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index d328916..3924c750 100755
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -26,8 +26,8 @@
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.UiAutomation;
+import android.content.pm.PackageManager;
 import android.graphics.Rect;
-import android.os.SystemClock;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.view.Gravity;
 import android.view.Window;
@@ -519,96 +519,6 @@
     }
 
     @MediumTest
-    public void testPerformGlobalActionBack() throws Exception {
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionHome() throws Exception {
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_HOME));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionRecents() throws Exception {
-        // Check whether the action succeeded.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_RECENTS));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-
-        // This is a necessary since the back action does not
-        // dismiss recents until they stop animating. Sigh...
-        SystemClock.sleep(5000);
-
-        // Clean up.
-        getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK);
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionNotifications() throws Exception {
-        // Perform the action under test
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-
-        // Clean up.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionQuickSettings() throws Exception {
-        // Check whether the action succeeded.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-
-        // Clean up.
-        getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK);
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionPowerDialog() throws Exception {
-        // Check whether the action succeeded.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_POWER_DIALOG));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-
-        // Clean up.
-        getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK);
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
     public void testObjectContract() throws Exception {
         try {
             AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
@@ -640,6 +550,11 @@
 
     @MediumTest
     public void testWindowDockAndUndock_dividerWindowAppearsAndDisappears() throws Exception {
+        if (getInstrumentation().getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            // Android TV doesn't support the divider window
+            return;
+        }
         setAccessInteractiveWindowsFlag();
         final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
         assertFalse(isDividerWindowPresent(uiAutomation));