A11y CTS: Check keyboard presence explicitly

We were inferring the presence or absence of an IME based
on the number of windows visible, but that method makes
assumptions about how IMEs behave that aren't always true.
Instead check for the presence of an IME window explicitly.
Also explicity forcing the IME to be shown and adding a 5s
timeout for the IME to show up and disappear.

In addition, we were requiring the IME to reappear when the
a11y feature is disabled or the service controlling it
turned off. It's not obvious that this is the correct
behavior in all cases, so I'm removing the tests that
require it.

Now passes on the phone in portrait and landscape as well as
on my Nemo watch.

Bug: 31986566
Change-Id: Ic2f99df78f3807436881633a4eaf6c1658b3cc07
diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml
index 3381f48..e13cdee 100644
--- a/tests/accessibilityservice/AndroidManifest.xml
+++ b/tests/accessibilityservice/AndroidManifest.xml
@@ -67,8 +67,7 @@
 
         <activity
             android:label="@string/accessibility_soft_keyboard_modes_activity"
-            android:name=".AccessibilitySoftKeyboardModesTest$SoftKeyboardModesActivity"
-            android:windowSoftInputMode="stateAlwaysVisible" />
+            android:name=".AccessibilitySoftKeyboardModesTest$SoftKeyboardModesActivity" />
 
         <service
             android:name=".InstrumentedAccessibilityService"
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
index 263c402..3c1db3b 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
@@ -16,24 +16,18 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.AccessibilityService.SoftKeyboardController;
+import android.app.Activity;
 import android.app.UiAutomation;
-import android.content.ContentResolver;
-import android.content.Context;
 import android.os.Bundle;
-import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
-import android.provider.Settings;
 import android.test.ActivityInstrumentationTestCase2;
+import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
 
 import android.accessibilityservice.cts.R;
+import android.view.accessibility.AccessibilityWindowInfo;
+import android.view.inputmethod.InputMethodManager;
 
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.concurrent.TimeoutException;
 
@@ -91,7 +85,11 @@
 
     @Override
     public void tearDown() throws Exception {
+        mKeyboardController.setShowMode(SHOW_MODE_AUTO);
         mService.runOnServiceSync(() -> mService.disableSelf());
+        Activity activity = getActivity();
+        activity.getSystemService(InputMethodManager.class)
+                .hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
     }
 
     public void testApiReturnValues_shouldChangeValueOnRequestAndSendCallback() throws Exception {
@@ -109,7 +107,7 @@
                 };
         mKeyboardController.addOnShowModeChangedListener(listener);
 
-        // The soft keyboard should be in its' default mode.
+        // The soft keyboard should be in its default mode.
         assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
 
         // Set the show mode to SHOW_MODE_HIDDEN.
@@ -130,56 +128,18 @@
         assertTrue(mKeyboardController.removeOnShowModeChangedListener(listener));
     }
 
-    public void testHideSoftKeyboard_shouldHideAndShowKeyboardOnRequest() throws Exception {
-        // The soft keyboard should be in its' default mode.
+    public void testHideSoftKeyboard_shouldHideKeyboardOnRequest() throws Exception {
+        // The soft keyboard should be in its default mode.
         assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
 
-        // Note: This Activity always has a visible keyboard (due to windowSoftInputMode being set
-        // to stateAlwaysVisible).
-        waitForIdle();
-        int numWindowsWithIme = mUiAutomation.getWindows().size();
-
+        forceImeToBeShown();
+        waitForImePresentToBe(true);
         // Request the keyboard be hidden.
         assertTrue(mKeyboardController.setShowMode(SHOW_MODE_HIDDEN));
-        waitForWindowStateChanged();
-        waitForIdle();
 
-        // Make sure the keyboard is hidden.
-        assertEquals(numWindowsWithIme - 1, mUiAutomation.getWindows().size());
+        waitForImePresentToBe(false);
 
-        // Request the default keyboard mode.
         assertTrue(mKeyboardController.setShowMode(SHOW_MODE_AUTO));
-        waitForWindowStateChanged();
-        waitForIdle();
-
-        // Make sure the keyboard is visible.
-        assertEquals(numWindowsWithIme, mUiAutomation.getWindows().size());
-    }
-
-    public void testHideSoftKeyboard_shouldHideKeyboardUntilServiceIsDisabled() throws Exception {
-        // The soft keyboard should be in its' default mode.
-        assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
-
-        // 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.
-        assertTrue(mKeyboardController.setShowMode(SHOW_MODE_HIDDEN));
-        waitForWindowStateChanged();
-        waitForIdle();
-
-        // Make sure the keyboard is hidden.
-        assertEquals(numWindowsWithIme - 1, mUiAutomation.getWindows().size());
-
-        // Make sure we can see the soft keyboard once all Accessibility Services are disabled.
-        mService.disableSelf();
-        waitForWindowStateChanged();
-        waitForIdle();
-
-        // See how many windows are present.
-        assertEquals(numWindowsWithIme, mUiAutomation.getWindows().size());
     }
 
     private void waitForCallbackValueWithLock(int expectedValue) throws Exception {
@@ -202,7 +162,7 @@
                 + "> does not match expected value < " + expectedValue + ">");
     }
 
-    private void waitForWindowStateChanged() throws Exception {
+    private void waitForWindowChanges() {
         try {
             mUiAutomation.executeAndWaitForEvent(new Runnable() {
                 @Override
@@ -223,8 +183,31 @@
         }
     }
 
-    private void waitForIdle() throws TimeoutException {
-        mUiAutomation.waitForIdle(TIMEOUT_ACCESSIBILITY_STATE_IDLE, TIMEOUT_ASYNC_PROCESSING);
+    private boolean isImeWindowPresent() {
+        List<AccessibilityWindowInfo> windows = mUiAutomation.getWindows();
+        for (int i = 0; i < windows.size(); i++) {
+            if (windows.get(i).getType() == AccessibilityWindowInfo.TYPE_INPUT_METHOD) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void waitForImePresentToBe(boolean imeShown) {
+        long timeOutTime = System.currentTimeMillis() + TIMEOUT_ASYNC_PROCESSING;
+        while (isImeWindowPresent() != imeShown) {
+            assertTrue(System.currentTimeMillis() < timeOutTime);
+            waitForWindowChanges();
+        }
+    }
+
+    private void forceImeToBeShown() {
+        getInstrumentation().runOnMainSync(() -> {
+            Activity activity = getActivity();
+            View editText = activity.findViewById(R.id.edit_text);
+            activity.getSystemService(InputMethodManager.class)
+                    .showSoftInput(editText, InputMethodManager.SHOW_FORCED);
+        });
     }
 
     /**