Add a regression test for bug 228766370

..ensures that IME will visible an ime-focusable overlay window
when another activity behind the overlay that requests to show IME.

Fix: 232515113
Test: atest KeyboardVisiblityControlTest#\
        testImeVisibleOnImeFocusableOverlay
Change-Id: I1090a0a1b19d50742ebeeeeb2d3ba930c500e980
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
index ac95dc8..b5bf4d4 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
@@ -94,6 +94,7 @@
 import androidx.test.uiautomator.UiDevice;
 import androidx.test.uiautomator.Until;
 
+import com.android.compatibility.common.util.SystemUtil;
 import com.android.cts.mockime.ImeEvent;
 import com.android.cts.mockime.ImeEventStream;
 import com.android.cts.mockime.ImeLayoutInfo;
@@ -854,6 +855,56 @@
         }
     }
 
+    /**
+     * Test case for Bug 228766370.
+     *
+     * <p>This test ensures that IME will visible on an ime-focusable overlay window when another
+     * activity behind the overlay that requests to show IME. <p/>
+     */
+    @Test
+    public void testImeVisibleOnImeFocusableOverlay() throws Exception {
+        try (MockImeSession imeSession = MockImeSession.create(
+                InstrumentationRegistry.getInstrumentation().getContext(),
+                InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+                new ImeSettings.Builder()
+                        .setInputViewHeight(NEW_KEYBOARD_HEIGHT)
+                        .setDrawsBehindNavBar(true))) {
+            final ImeEventStream stream = imeSession.openEventStream();
+            TestActivity testActivity = TestActivity.startSync(activity -> {
+                final View view = new View(activity);
+                view.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+                return view;
+            });
+
+            // Show an overlay with "IME Focusable" (NOT_FOCUSABLE | ALT_FOCUSABLE_IM) flags.
+            runOnMainSync(() -> SystemUtil.runWithShellPermissionIdentity(() ->
+                    testActivity.showOverlayWindow(true /* imeFocusable */)));
+            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+            // Start a next activity to expect IME should visible on top of the overlay.
+            final String marker = getTestMarker();
+            final AtomicReference<EditText> editorRef = new AtomicReference<>();
+            TestActivity.startNewTaskSync(activity -> {
+                final LinearLayout layout = new LinearLayout(activity);
+                layout.setOrientation(LinearLayout.VERTICAL);
+                layout.setGravity(Gravity.BOTTOM);
+                final EditText editText = new EditText(activity);
+                editorRef.set(editText);
+                editText.setHint("focused editText");
+                editText.setPrivateImeOptions(marker);
+                editText.requestFocus();
+                layout.addView(editText);
+                return layout;
+            });
+            // Show IME.
+            runOnMainSync(() -> editorRef.get().getContext().getSystemService(
+                    InputMethodManager.class).showSoftInput(editorRef.get(), 0));
+
+            expectEvent(stream, editorMatcher("onStartInputView", marker), TIMEOUT);
+            expectImeVisible(TIMEOUT);
+        }
+    }
+
     private enum TestSoftInputMode {
         UNCHANGED_WITH_BACKWARD_NAV,
         ALWAYS_HIDDEN_WITH_BACKWARD_NAV,
diff --git a/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java b/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
index 2b12a3c..531de57 100644
--- a/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
+++ b/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
@@ -17,6 +17,7 @@
 package android.view.inputmethod.cts.util;
 
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -140,15 +141,19 @@
     }
 
     public void showOverlayWindow() {
+        showOverlayWindow(false /* imeFocusable */);
+    }
+    public void showOverlayWindow(boolean imeFocusable) {
         if (mOverlayView != null) {
             throw new IllegalStateException("can only show one overlay at a time.");
         }
         Context overlayContext = getApplicationContext().createWindowContext(getDisplay(),
                 TYPE_APPLICATION_OVERLAY, null);
         mOverlayView = new TextView(overlayContext);
-        WindowManager.LayoutParams params =
-                new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT,
-                        TYPE_APPLICATION_OVERLAY, FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
+        WindowManager.LayoutParams params = new WindowManager.LayoutParams(MATCH_PARENT,
+                MATCH_PARENT, TYPE_APPLICATION_OVERLAY,
+                (imeFocusable ? FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM : FLAG_NOT_FOCUSABLE),
+                PixelFormat.TRANSLUCENT);
         params.setTitle(OVERLAY_WINDOW_NAME);
         mOverlayView.setLayoutParams(params);
         mOverlayView.setText("IME CTS TestActivity OverlayView");