Add a regression test on WebView

Make sure the soft-keyboard will visible after tapping
EditText on WebView.

Fix 78123829
Bug: 154243117

Test: atest KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView
Change-Id: I7d96c8fecc12ad4f6b21f1d19a55b692e69e167f
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
index e4d6319..e7abf6c 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
@@ -26,9 +26,11 @@
 import static com.android.cts.mockime.ImeEventStreamTestUtils.notExpectEvent;
 
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import android.os.SystemClock;
+import android.support.test.uiautomator.UiObject2;
 import android.text.TextUtils;
 import android.util.Pair;
 import android.view.View;
@@ -37,6 +39,7 @@
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.cts.util.EndToEndImeTestBase;
 import android.view.inputmethod.cts.util.TestActivity;
+import android.view.inputmethod.cts.util.TestWebView;
 import android.view.inputmethod.cts.util.UnlockScreenRule;
 import android.widget.EditText;
 import android.widget.LinearLayout;
@@ -248,4 +251,29 @@
             expectImeInvisible(TIMEOUT);
         }
     }
+
+    @Test
+    public void testShowHideKeyboardOnWebView() throws Exception {
+        try (MockImeSession imeSession = MockImeSession.create(
+                InstrumentationRegistry.getContext(),
+                InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+                new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+
+            final UiObject2 inputTextField = TestWebView.launchTestWebViewActivity(
+                    TimeUnit.SECONDS.toMillis(5));
+            assertNotNull("Editor must exists on WebView", inputTextField);
+
+            expectEvent(stream, event -> "onStartInput".equals(event.getEventName()), TIMEOUT);
+            notExpectEvent(stream, event -> "onStartInputView".equals(event.getEventName()),
+                    TIMEOUT);
+            expectImeInvisible(TIMEOUT);
+
+            inputTextField.click();
+            expectEvent(stream.copy(), showSoftInputMatcher(InputMethod.SHOW_EXPLICIT), TIMEOUT);
+            expectEvent(stream.copy(), event -> "onStartInputView".equals(event.getEventName()),
+                    TIMEOUT);
+            expectImeVisible(TIMEOUT);
+        }
+    }
 }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/util/TestWebView.java b/tests/inputmethod/src/android/view/inputmethod/cts/util/TestWebView.java
new file mode 100644
index 0000000..5090d70
--- /dev/null
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/util/TestWebView.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 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.view.inputmethod.cts.util;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Context;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import com.android.compatibility.common.util.Timeout;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+/**
+ * A custom {@link WebView} class which provides a simple web page for verifying IME behavior.
+ */
+public class TestWebView {
+
+    private static final class Impl extends WebView {
+        private final static String MY_HTML =
+                "<html><body>Editor: <input type='text' name='testInput'></body></html>";
+        private UiDevice mUiDevice;
+
+        public Impl(Context context, UiDevice uiDevice) {
+            super(context);
+            mUiDevice = uiDevice;
+        }
+
+        private void loadEditorPage() {
+            super.loadData(MY_HTML, "text/html", "UTF-8");
+        }
+
+        private UiObject2 getInput(Timeout timeout) {
+            final BySelector selector = By.text("Editor: ");
+            UiObject2 label = null;
+            try {
+                label = timeout.run("waitForObject(" + selector + ")",
+                        () -> mUiDevice.findObject(selector));
+            } catch (Exception e) {
+            }
+            assertNotNull("Editor label must exists on WebView", label);
+
+            // Then the input is next.
+            final UiObject2 parent = label.getParent();
+            UiObject2 previous = null;
+            for (UiObject2 child : parent.getChildren()) {
+                if (label.equals(previous)) {
+                    if (child.getClassName().equals(EditText.class.getName())) {
+                        return child;
+                    }
+                }
+                previous = child;
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Not intended to be instantiated.
+     */
+    private TestWebView() {
+    }
+
+    public static UiObject2 launchTestWebViewActivity(long timeoutMs)
+            throws Exception {
+        final AtomicReference<UiObject2> inputTextFieldRef = new AtomicReference<>();
+        final AtomicReference<TestWebView.Impl> webViewRef = new AtomicReference<>();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final Timeout timeoutForFindObj = new Timeout("UIOBJECT_FIND_TIMEOUT",
+                timeoutMs, 2F, timeoutMs);
+
+        TestActivity.startSync(activity -> {
+            final LinearLayout layout = new LinearLayout(activity);
+            final TestWebView.Impl webView = new Impl(activity, UiDevice.getInstance(
+                    InstrumentationRegistry.getInstrumentation()));
+            webView.setWebViewClient(new WebViewClient() {
+                @Override
+                public void onPageFinished(WebView view, String url) {
+                    latch.countDown();
+                }
+            });
+            webViewRef.set(webView);
+            layout.setOrientation(LinearLayout.VERTICAL);
+            layout.addView(webView);
+            webView.loadEditorPage();
+            return layout;
+        });
+
+        latch.await(timeoutMs, TimeUnit.MILLISECONDS);
+        inputTextFieldRef.set(webViewRef.get().getInput(timeoutForFindObj));
+        return inputTextFieldRef.get();
+    }
+}