diff --git a/tests/InputMethodStressTest/AndroidManifest.xml b/tests/InputMethodStressTest/AndroidManifest.xml
index f5fe8f2..2d183bc 100644
--- a/tests/InputMethodStressTest/AndroidManifest.xml
+++ b/tests/InputMethodStressTest/AndroidManifest.xml
@@ -16,11 +16,11 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.inputmethod.stresstest">
+          package="com.android.inputmethod.stresstest">
 
     <application>
-        <activity android:name=".AutoShowTest$TestActivity"/>
-        <activity android:name=".ImeOpenCloseStressTest$TestActivity"/>
+        <activity android:name=".ImeStressTestUtil$TestActivity"
+                  android:configChanges="orientation|screenSize"/>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/InputMethodStressTest/TEST_MAPPING b/tests/InputMethodStressTest/TEST_MAPPING
index ad07205..06e2ce8 100644
--- a/tests/InputMethodStressTest/TEST_MAPPING
+++ b/tests/InputMethodStressTest/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "InputMethodStressTest"
     }
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
index 92ea029..8e4ecf1 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
@@ -16,24 +16,32 @@
 
 package com.android.inputmethod.stresstest;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.REQUEST_FOCUS_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.TestActivity;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.TestActivity.createIntent;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.UNFOCUSABLE_VIEW;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.callOnMainSync;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.getWindowAndSoftInputFlagParameters;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.hasUnfocusableWindowFlags;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyImeAlwaysHiddenWithWindowFlagSet;
 import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyImeIsAlwaysHidden;
-import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntil;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyWindowAndViewFocus;
 import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsShown;
 
-import android.app.Activity;
+import static com.google.common.truth.Truth.assertThat;
+
 import android.app.Instrumentation;
 import android.content.Intent;
-import android.os.Bundle;
+import android.os.SystemClock;
 import android.platform.test.annotations.RootPermissionTest;
 import android.platform.test.rule.UnlockScreenRule;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
 import android.view.WindowManager;
 import android.widget.EditText;
-import android.widget.LinearLayout;
 
-import androidx.annotation.Nullable;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Rule;
@@ -41,135 +49,428 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
- * Tests to verify the "auto show" behavior in {@code InputMethodManagerService} when the window
+ * Tests to verify the "auto-show" behavior in {@code InputMethodManagerService} when the window
  * gaining the focus to start the input.
  */
 @RootPermissionTest
 @RunWith(Parameterized.class)
 public final class AutoShowTest {
 
-    @Rule
-    public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+    @Rule public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
 
     @Rule
     public ScreenCaptureRule mScreenCaptureRule =
             new ScreenCaptureRule("/sdcard/InputMethodStressTest");
 
-    private static final int[] SOFT_INPUT_VISIBILITY_FLAGS =
-            new int[] {
-                WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED,
-                WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN,
-                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN,
-                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE,
-                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE,
-            };
-
-    private static final int[] SOFT_INPUT_ADJUST_FLAGS =
-            new int[] {
-                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED,
-                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
-                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN,
-                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
-            };
-
     // TODO(b/240359838): add test case {@code Configuration.SCREENLAYOUT_SIZE_LARGE}.
     @Parameterized.Parameters(
-            name =
-                    "softInputVisibility={0}, softInputAdjustment={1},"
-                            + " softInputModeIsForwardNavigation={2}")
-    public static List<Object[]> softInputModeConfigs() {
-        ArrayList<Object[]> params = new ArrayList<>();
-        for (int softInputVisibility : SOFT_INPUT_VISIBILITY_FLAGS) {
-            for (int softInputAdjust : SOFT_INPUT_ADJUST_FLAGS) {
-                params.add(new Object[] {softInputVisibility, softInputAdjust, true});
-                params.add(new Object[] {softInputVisibility, softInputAdjust, false});
-            }
-        }
-        return params;
+            name = "windowFocusFlags={0}, softInputVisibility={1}, softInputAdjustment={2}")
+    public static List<Object[]> windowAndSoftInputFlagParameters() {
+        return getWindowAndSoftInputFlagParameters();
     }
 
-    private static final String SOFT_INPUT_FLAGS = "soft_input_flags";
+    private final int mSoftInputFlags;
+    private final int mWindowFocusFlags;
+    private final Instrumentation mInstrumentation;
 
-    private final int mSoftInputVisibility;
-    private final int mSoftInputAdjustment;
-    private final boolean mSoftInputIsForwardNavigation;
+    public AutoShowTest(int windowFocusFlags, int softInputVisibility, int softInputAdjustment) {
+        mSoftInputFlags = softInputVisibility | softInputAdjustment;
+        mWindowFocusFlags = windowFocusFlags;
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+    }
 
-    public AutoShowTest(
-            int softInputVisibility,
-            int softInputAdjustment,
-            boolean softInputIsForwardNavigation) {
-        mSoftInputVisibility = softInputVisibility;
-        mSoftInputAdjustment = softInputAdjustment;
-        mSoftInputIsForwardNavigation = softInputIsForwardNavigation;
+    /**
+     * Test auto-show IME behavior when the {@link EditText} is focusable ({@link
+     * EditText#isFocusableInTouchMode} is {@code true}) and has called {@link
+     * EditText#requestFocus}.
+     */
+    @Test
+    public void autoShow_hasFocusedView_requestFocus() {
+        // request focus at onCreate()
+        Intent intent =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+        TestActivity activity = TestActivity.start(intent);
+
+        verifyAutoShowBehavior_forwardWithKeyboardOff(activity);
+    }
+
+    /**
+     * Test auto-show IME behavior when the {@link EditText} is focusable ({@link
+     * EditText#isFocusableInTouchMode} is {@code true}) and {@link EditText#requestFocus} is not
+     * called. The IME should never be shown because there is no focused editor in the window.
+     */
+    @Test
+    public void autoShow_hasFocusedView_notRequestFocus() {
+        // request focus not set
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        EditText editText = activity.getEditText();
+
+        int windowFlags = activity.getWindow().getAttributes().flags;
+        if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            // When FLAG_NOT_FOCUSABLE is set true, the view will never gain window focus.
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ false);
+        } else {
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+        }
+        // IME is always hidden because there is no view focus.
+        verifyImeIsAlwaysHidden(editText);
+    }
+
+    /**
+     * Test auto-show IME behavior when the {@link EditText} is not focusable ({@link
+     * EditText#isFocusableInTouchMode} is {@code false}) and {@link EditText#requestFocus} is not
+     * called. The IME should never be shown because there is no focusable editor in the window.
+     */
+    @Test
+    public void autoShow_notFocusedView_notRequestFocus() {
+        // Unfocusable view, request focus not set
+        Intent intent =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Collections.singletonList(UNFOCUSABLE_VIEW));
+        TestActivity activity = TestActivity.start(intent);
+        EditText editText = activity.getEditText();
+
+        int windowFlags = activity.getWindow().getAttributes().flags;
+        if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            // When FLAG_NOT_FOCUSABLE is set true, the view will never gain window focus.
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ false);
+        } else {
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+        }
+        // IME is always hidden because there is no focused view.
+        verifyImeIsAlwaysHidden(editText);
+    }
+
+    /**
+     * Test auto-show IME behavior when the activity is navigated forward from another activity with
+     * keyboard off.
+     */
+    @Test
+    public void autoShow_forwardWithKeyboardOff() {
+        // Create first activity with keyboard off
+        Intent intent1 =
+                createIntent(
+                        0x0 /* No window focus flags */,
+                        WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+                                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+                        Collections.emptyList());
+        TestActivity firstActivity = TestActivity.start(intent1);
+
+        // Create second activity with parameterized flags:
+        Intent intent2 =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+        TestActivity secondActivity = firstActivity.startSecondTestActivity(intent2);
+
+        // The auto-show behavior should be the same as opening the app
+        verifyAutoShowBehavior_forwardWithKeyboardOff(secondActivity);
+    }
+
+    /**
+     * Test auto-show IME behavior when the activity is navigated forward from another activity with
+     * keyboard on.
+     */
+    @Test
+    public void autoShow_forwardWithKeyboardOn() {
+        // Create first activity with keyboard on
+        Intent intent1 =
+                createIntent(
+                        0x0 /* No window focus flags */,
+                        WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+                                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+                        Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+        TestActivity firstActivity = TestActivity.start(intent1);
+        // Show Ime with InputMethodManager to ensure the keyboard is on.
+        boolean succ = callOnMainSync(firstActivity::showImeWithInputMethodManager);
+        assertThat(succ).isTrue();
+        SystemClock.sleep(1000);
+        mInstrumentation.waitForIdleSync();
+
+        // Create second activity with parameterized flags:
+        Intent intent2 =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+        TestActivity secondActivity = firstActivity.startSecondTestActivity(intent2);
+
+        // The auto-show behavior should be the same as open app
+        verifyAutoShowBehavior_forwardWithKeyboardOn(secondActivity);
+    }
+
+    /**
+     * Test auto-show IME behavior when the activity is navigated back from another activity with
+     * keyboard off.
+     */
+    @Test
+    public void autoShow_backwardWithKeyboardOff() {
+        // Not request focus at onCreate() to avoid triggering auto-show behavior
+        Intent intent1 = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity firstActivity = TestActivity.start(intent1);
+        // Request view focus after app starts
+        mInstrumentation.runOnMainSync(firstActivity::requestFocus);
+
+        Intent intent2 =
+                createIntent(
+                        0x0 /* No window focus flags */,
+                        WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+                                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+                        Collections.emptyList());
+        TestActivity secondActivity = firstActivity.startSecondTestActivity(intent2);
+        secondActivity.finish();
+        mInstrumentation.waitForIdleSync();
+
+        // When activity is navigated back from another activity with keyboard off, the keyboard
+        // will not show except when soft input visibility flag is SOFT_INPUT_STATE_ALWAYS_VISIBLE.
+        verifyAutoShowBehavior_backwardWithKeyboardOff(firstActivity);
+    }
+
+    /**
+     * Test auto-show IME behavior when the activity is navigated back from another activity with
+     * keyboard on.
+     */
+    @Test
+    public void autoShow_backwardWithKeyboardOn() {
+        // Not request focus at onCreate() to avoid triggering auto-show behavior
+        Intent intent1 = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent1);
+        // Request view focus after app starts
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+
+        // Create second TestActivity
+        Intent intent2 =
+                createIntent(
+                        0x0 /* No window focus flags */,
+                        WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+                                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+                        Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+        ImeStressTestUtil.TestActivity secondActivity = activity.startSecondTestActivity(intent2);
+        // Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
+        boolean succ = callOnMainSync(secondActivity::showImeWithInputMethodManager);
+        assertThat(succ).isTrue();
+        SystemClock.sleep(1000);
+        mInstrumentation.waitForIdleSync();
+        // Close the second activity
+        secondActivity.finish();
+        SystemClock.sleep(1000);
+        mInstrumentation.waitForIdleSync();
+        // When activity is navigated back from another activity with keyboard on, the keyboard
+        // will not hide except when soft input visibility flag is SOFT_INPUT_STATE_ALWAYS_HIDDEN.
+        verifyAutoShowBehavior_backwardWithKeyboardOn(activity);
     }
 
     @Test
-    public void autoShow() {
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        int flags = mSoftInputVisibility | mSoftInputAdjustment;
-        if (mSoftInputIsForwardNavigation) {
-            flags |= WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
+    public void clickFocusableView_requestFocus() {
+        if ((mWindowFocusFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            // UiAutomator cannot get UiObject if FLAG_NOT_FOCUSABLE is set
+            return;
+        }
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request view focus after app starts
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+
+        // Find the editText and click it
+        UiObject2 editTextUiObject =
+                UiDevice.getInstance(mInstrumentation)
+                        .wait(Until.findObject(By.clazz(EditText.class)), 5000);
+        assertThat(editTextUiObject).isNotNull();
+        editTextUiObject.click();
+
+        // Ime will show unless window flag is set
+        verifyClickBehavior(activity);
+    }
+
+    @Test
+    public void clickFocusableView_notRequestFocus() {
+        if ((mWindowFocusFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            // UiAutomator cannot get UiObject if FLAG_NOT_FOCUSABLE is set
+            return;
+        }
+        // Not request focus
+        Intent intent1 = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent1);
+
+        // Find the editText and click it
+        UiObject2 editTextUiObject =
+                UiDevice.getInstance(mInstrumentation)
+                        .wait(Until.findObject(By.clazz(EditText.class)), 5000);
+        assertThat(editTextUiObject).isNotNull();
+        editTextUiObject.click();
+
+        // Ime will show unless window flag is set
+        verifyClickBehavior(activity);
+    }
+
+    public static void verifyAutoShowBehavior_forwardWithKeyboardOff(TestActivity activity) {
+        // public: also used by ImeOpenCloseStressTest
+        if (hasUnfocusableWindowFlags(activity)) {
+            verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+            return;
         }
 
-        Intent intent =
-                new Intent()
-                        .setAction(Intent.ACTION_MAIN)
-                        .setClass(instrumentation.getContext(), TestActivity.class)
-                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-                        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
-                        .putExtra(SOFT_INPUT_FLAGS, flags);
-        TestActivity activity = (TestActivity) instrumentation.startActivitySync(intent);
+        int softInputMode = activity.getWindow().getAttributes().softInputMode;
+        int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+        int softInputAdjustment = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
         EditText editText = activity.getEditText();
-        waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
 
-        if (mSoftInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
-                || mSoftInputVisibility
-                        == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) {
-            // IME will be auto-shown if softInputMode is set with flag:
-            // SOFT_INPUT_STATE_VISIBLE or SOFT_INPUT_STATE_ALWAYS_VISIBLE
-            waitOnMainUntilImeIsShown(editText);
-        } else if (mSoftInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
-                || mSoftInputVisibility
-                        == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
-            // IME will be not be shown if softInputMode is set with flag:
-            // SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN
-            verifyImeIsAlwaysHidden(editText);
-        } else {
-            // The current system behavior will choose to show IME automatically when navigating
-            // forward to an app that has no visibility state specified  (i.e.
-            // SOFT_INPUT_STATE_UNSPECIFIED) with set SOFT_INPUT_ADJUST_RESIZE flag.
-            if (mSoftInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
-                    && mSoftInputAdjustment == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
-                    && mSoftInputIsForwardNavigation) {
+        verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+        switch (softInputVisibility) {
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE: {
+                // IME will be auto-shown if softInputMode is set with flag:
+                // SOFT_INPUT_STATE_VISIBLE or SOFT_INPUT_STATE_ALWAYS_VISIBLE
                 waitOnMainUntilImeIsShown(editText);
+                break;
             }
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: {
+                // IME will be not be auto-shown if softInputMode is set with flag:
+                // SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN,
+                // or stay unchanged if set SOFT_INPUT_STATE_UNCHANGED
+                verifyImeIsAlwaysHidden(editText);
+                break;
+            }
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: {
+                if (softInputAdjustment
+                        == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
+                    // The current system behavior will choose to show IME automatically when
+                    // navigating forward to an app that has no visibility state specified
+                    // (i.e. SOFT_INPUT_STATE_UNSPECIFIED) with set SOFT_INPUT_ADJUST_RESIZE
+                    // flag.
+                    waitOnMainUntilImeIsShown(editText);
+                } else {
+                    verifyImeIsAlwaysHidden(editText);
+                }
+                break;
+            }
+            default:
+                break;
         }
     }
 
-    public static class TestActivity extends Activity {
-        private EditText mEditText;
+    private static void verifyAutoShowBehavior_forwardWithKeyboardOn(TestActivity activity) {
+        int windowFlags = activity.getWindow().getAttributes().flags;
+        int softInputMode = activity.getWindow().getAttributes().softInputMode;
+        int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+        int softInputAdjustment = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+        EditText editText = activity.getEditText();
 
-        @Override
-        protected void onCreate(@Nullable Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            int flags = getIntent().getIntExtra(SOFT_INPUT_FLAGS, 0);
-            getWindow().setSoftInputMode(flags);
-            LinearLayout rootView = new LinearLayout(this);
-            rootView.setOrientation(LinearLayout.VERTICAL);
-            mEditText = new EditText(this);
-            rootView.addView(mEditText, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
-            setContentView(rootView);
-            // Ensure the focused view is a text editor (View#onCheckIsTextEditor() returns true) to
-            // automatically display a soft input window.
-            mEditText.requestFocus();
+        if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            // When FLAG_NOT_FOCUSABLE is set true, the view will never gain window focus. The IME
+            // will always be hidden even though the view can get focus itself.
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ true);
+            // TODO(b/252192121): Ime should be hidden but is shown.
+            // waitOnMainUntilImeIsHidden(editText);
+            return;
+        } else if ((windowFlags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+                || (windowFlags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0) {
+            // When FLAG_ALT_FOCUSABLE_IM or FLAG_LOCAL_FOCUS_MODE is set, the view can gain both
+            // window focus and view focus but not IME focus. The IME will always be hidden.
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+            // TODO(b/252192121): Ime should be hidden but is shown.
+            // waitOnMainUntilImeIsHidden(editText);
+            return;
         }
+        verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+        switch (softInputVisibility) {
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE: {
+                // IME will be auto-shown if softInputMode is set with flag:
+                // SOFT_INPUT_STATE_VISIBLE or SOFT_INPUT_STATE_ALWAYS_VISIBLE
+                waitOnMainUntilImeIsShown(editText);
+                break;
+            }
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: {
+                // IME will be not be auto-shown if softInputMode is set with flag:
+                // SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN
+                // or stay unchanged if set SOFT_INPUT_STATE_UNCHANGED
+                verifyImeIsAlwaysHidden(editText);
+                break;
+            }
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: {
+                if (softInputAdjustment
+                        == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
+                    // The current system behavior will choose to show IME automatically when
+                    // navigating
+                    // forward to an app that has no visibility state specified  (i.e.
+                    // SOFT_INPUT_STATE_UNSPECIFIED) with set SOFT_INPUT_ADJUST_RESIZE flag.
+                    waitOnMainUntilImeIsShown(editText);
+                } else {
+                    verifyImeIsAlwaysHidden(editText);
+                }
+                break;
+            }
+            default:
+                break;
+        }
+    }
 
-        public EditText getEditText() {
-            return mEditText;
+    private static void verifyAutoShowBehavior_backwardWithKeyboardOff(TestActivity activity) {
+        if (hasUnfocusableWindowFlags(activity)) {
+            verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+            return;
+        }
+        int softInputMode = activity.getWindow().getAttributes().softInputMode;
+        int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+        EditText editText = activity.getEditText();
+
+        verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+        if (softInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) {
+            waitOnMainUntilImeIsShown(editText);
+        } else {
+            verifyImeIsAlwaysHidden(editText);
+        }
+    }
+
+    private static void verifyAutoShowBehavior_backwardWithKeyboardOn(TestActivity activity) {
+        if (hasUnfocusableWindowFlags(activity)) {
+            verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+            return;
+        }
+        int softInputMode = activity.getWindow().getAttributes().softInputMode;
+        int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+        EditText editText = activity.getEditText();
+
+        verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+        if (softInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
+            verifyImeIsAlwaysHidden(editText);
+        } else {
+            waitOnMainUntilImeIsShown(editText);
+        }
+    }
+
+    private static void verifyClickBehavior(TestActivity activity) {
+        int windowFlags = activity.getWindow().getAttributes().flags;
+        EditText editText = activity.getEditText();
+
+        verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+        if ((windowFlags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+                || (windowFlags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0) {
+            verifyImeIsAlwaysHidden(editText);
+        } else {
+            waitOnMainUntilImeIsShown(editText);
         }
     }
 }
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
index 8419276..82acfb6 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
@@ -16,224 +16,535 @@
 
 package com.android.inputmethod.stresstest;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
-
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.INPUT_METHOD_MANAGER_HIDE_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.INPUT_METHOD_MANAGER_SHOW_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.REQUEST_FOCUS_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.TestActivity;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.TestActivity.createIntent;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.callOnMainSync;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.getWindowAndSoftInputFlagParameters;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.hasUnfocusableWindowFlags;
 import static com.android.inputmethod.stresstest.ImeStressTestUtil.isImeShown;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyImeAlwaysHiddenWithWindowFlagSet;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyImeIsAlwaysHidden;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyWindowAndViewFocus;
 import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntil;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsHidden;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsShown;
 
-import android.app.Activity;
+import static com.google.common.truth.Truth.assertThat;
+
 import android.app.Instrumentation;
 import android.content.Intent;
-import android.os.Bundle;
+import android.os.Build;
 import android.os.SystemClock;
 import android.platform.test.annotations.RootPermissionTest;
 import android.platform.test.rule.UnlockScreenRule;
+import android.support.test.uiautomator.UiDevice;
 import android.util.Log;
-import android.view.WindowInsets;
-import android.view.WindowInsetsAnimation;
-import android.view.inputmethod.InputMethodManager;
+import android.view.WindowManager;
 import android.widget.EditText;
-import android.widget.LinearLayout;
 
-import androidx.annotation.Nullable;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 @RootPermissionTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public final class ImeOpenCloseStressTest {
 
     private static final String TAG = "ImeOpenCloseStressTest";
     private static final int NUM_TEST_ITERATIONS = 10;
 
-    @Rule
-    public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+    @Rule public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
 
     @Rule
     public ScreenCaptureRule mScreenCaptureRule =
             new ScreenCaptureRule("/sdcard/InputMethodStressTest");
-    private Instrumentation mInstrumentation;
 
-    @Before
-    public void setUp() {
+    private final Instrumentation mInstrumentation;
+    private final int mSoftInputFlags;
+    private final int mWindowFocusFlags;
+
+    @Parameterized.Parameters(
+            name = "windowFocusFlags={0}, softInputVisibility={1}, softInputAdjustment={2}")
+    public static List<Object[]> windowAndSoftInputFlagParameters() {
+        return getWindowAndSoftInputFlagParameters();
+    }
+
+    public ImeOpenCloseStressTest(
+            int windowFocusFlags, int softInputVisibility, int softInputAdjustment) {
+        mSoftInputFlags = softInputVisibility | softInputAdjustment;
+        mWindowFocusFlags = windowFocusFlags;
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
     }
 
     @Test
-    public void testShowHide_waitingVisibilityChange() {
-        TestActivity activity = TestActivity.start();
-        EditText editText = activity.getEditText();
-        waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
-        for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
+    public void testShowHideWithInputMethodManager_waitingVisibilityChange() {
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request focus after app starts to avoid triggering auto-show behavior.
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+        // Test only once if window flags set to save time.
+        int iterNum = hasUnfocusableWindowFlags(activity) ? 1 : NUM_TEST_ITERATIONS;
+        for (int i = 0; i < iterNum; i++) {
             String msgPrefix = "Iteration #" + i + " ";
             Log.i(TAG, msgPrefix + "start");
-            mInstrumentation.runOnMainSync(activity::showIme);
-            waitOnMainUntil(msgPrefix + "IME should be visible", () -> isImeShown(editText));
-            mInstrumentation.runOnMainSync(activity::hideIme);
-            waitOnMainUntil(msgPrefix + "IME should be hidden", () -> !isImeShown(editText));
+            boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+            assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+            verifyShowBehavior(activity);
+
+            boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
+            assertThat(hideResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+
+            verifyHideBehavior(activity);
         }
     }
 
     @Test
-    public void testShowHide_waitingAnimationEnd() {
-        TestActivity activity = TestActivity.start();
+    public void testShowHideWithInputMethodManager_waitingAnimationEnd() {
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request focus after app starts to avoid triggering auto-show behavior.
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+
+        if (hasUnfocusableWindowFlags(activity)) {
+            return; // Skip to save time.
+        }
         activity.enableAnimationMonitoring();
         EditText editText = activity.getEditText();
-        waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
         for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
             String msgPrefix = "Iteration #" + i + " ";
             Log.i(TAG, msgPrefix + "start");
-            mInstrumentation.runOnMainSync(activity::showIme);
-            waitOnMainUntil(msgPrefix + "IME should be visible",
+            boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+            assertThat(showResult).isTrue();
+            waitOnMainUntil(
+                    msgPrefix + "IME should be visible",
                     () -> !activity.isAnimating() && isImeShown(editText));
-            mInstrumentation.runOnMainSync(activity::hideIme);
-            waitOnMainUntil(msgPrefix + "IME should be hidden",
+
+            boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
+            assertThat(hideResult).isTrue();
+            waitOnMainUntil(
+                    msgPrefix + "IME should be hidden",
                     () -> !activity.isAnimating() && !isImeShown(editText));
         }
     }
 
     @Test
-    public void testShowHide_intervalAfterHide() {
+    public void testShowHideWithInputMethodManager_intervalAfterHide() {
         // Regression test for b/221483132
-        TestActivity activity = TestActivity.start();
-        EditText editText = activity.getEditText();
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request focus after app starts to avoid triggering auto-show behavior.
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+        if (hasUnfocusableWindowFlags(activity)) {
+            return; // Skip to save time.
+        }
         // Intervals = 10, 20, 30, ..., 100, 150, 200, ...
         List<Integer> intervals = new ArrayList<>();
         for (int i = 10; i < 100; i += 10) intervals.add(i);
         for (int i = 100; i < 1000; i += 50) intervals.add(i);
-        waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
+        boolean firstHide = false;
         for (int intervalMillis : intervals) {
             String msgPrefix = "Interval = " + intervalMillis + " ";
             Log.i(TAG, msgPrefix + " start");
-            mInstrumentation.runOnMainSync(activity::hideIme);
+            boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
+            assertThat(hideResult).isEqualTo(firstHide);
+            firstHide = true;
             SystemClock.sleep(intervalMillis);
-            mInstrumentation.runOnMainSync(activity::showIme);
-            waitOnMainUntil(msgPrefix + "IME should be visible",
-                    () -> isImeShown(editText));
+
+            boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+            assertThat(showResult).isTrue();
+            verifyShowBehavior(activity);
         }
     }
 
     @Test
-    public void testShowHideInSameFrame() {
-        TestActivity activity = TestActivity.start();
-        activity.enableAnimationMonitoring();
-        EditText editText = activity.getEditText();
-        waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
+    public void testShowHideWithInputMethodManager_inSameFrame() {
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request focus after app starts to avoid triggering auto-show behavior.
+        mInstrumentation.runOnMainSync(activity::requestFocus);
 
+        if (hasUnfocusableWindowFlags(activity)) {
+            return; // Skip to save time.
+        }
         // hidden -> show -> hide
-        mInstrumentation.runOnMainSync(() -> {
-            Log.i(TAG, "Calling showIme() and hideIme()");
-            activity.showIme();
-            activity.hideIme();
-        });
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    Log.i(TAG, "Calling showIme() and hideIme()");
+                    activity.showImeWithInputMethodManager();
+                    activity.hideImeWithInputMethodManager();
+                });
         // Wait until IMMS / IMS handles messages.
         SystemClock.sleep(1000);
         mInstrumentation.waitForIdleSync();
-        waitOnMainUntil("IME should be invisible after show/hide", () -> !isImeShown(editText));
+        verifyHideBehavior(activity);
 
-        mInstrumentation.runOnMainSync(activity::showIme);
-        waitOnMainUntil("IME should be visible",
-                () -> !activity.isAnimating() && isImeShown(editText));
+        mInstrumentation.runOnMainSync(activity::showImeWithInputMethodManager);
+        verifyShowBehavior(activity);
         mInstrumentation.waitForIdleSync();
 
         // shown -> hide -> show
-        mInstrumentation.runOnMainSync(() -> {
-            Log.i(TAG, "Calling hideIme() and showIme()");
-            activity.hideIme();
-            activity.showIme();
-        });
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    Log.i(TAG, "Calling hideIme() and showIme()");
+                    activity.hideImeWithInputMethodManager();
+                    activity.showImeWithInputMethodManager();
+                });
         // Wait until IMMS / IMS handles messages.
         SystemClock.sleep(1000);
         mInstrumentation.waitForIdleSync();
-        waitOnMainUntil("IME should be visible after hide/show",
-                () -> !activity.isAnimating() && isImeShown(editText));
+        verifyShowBehavior(activity);
     }
 
-    public static class TestActivity extends Activity {
+    @Test
+    public void testShowHideWithInputMethodManager_onCreate() {
+        // Show and hide with InputMethodManager at onCreate()
+        Intent intent =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Arrays.asList(
+                                REQUEST_FOCUS_ON_CREATE,
+                                INPUT_METHOD_MANAGER_SHOW_ON_CREATE,
+                                INPUT_METHOD_MANAGER_HIDE_ON_CREATE));
+        TestActivity activity = TestActivity.start(intent);
 
-        private EditText mEditText;
-        private boolean mIsAnimating;
+        // TODO: The Ime is expected to show first and then hide. But show or hide
+        // with InputMethodManager at onCreate() would always fail because the window
+        // has not gained focus, so the actual behavior will be the same as auto-show.
+        // verifyHideBehavior(activity);
+    }
 
-        private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
-                new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
-                    @Override
-                    public WindowInsetsAnimation.Bounds onStart(WindowInsetsAnimation animation,
-                            WindowInsetsAnimation.Bounds bounds) {
-                        mIsAnimating = true;
-                        return super.onStart(animation, bounds);
-                    }
+    @Test
+    public void testShowWithInputMethodManager_notRequestFocus() {
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
 
-                    @Override
-                    public void onEnd(WindowInsetsAnimation animation) {
-                        super.onEnd(animation);
-                        mIsAnimating = false;
-                    }
+        // Show InputMethodManager without requesting focus
+        boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+        assertThat(showResult).isFalse();
 
-                    @Override
-                    public WindowInsets onProgress(WindowInsets insets,
-                            List<WindowInsetsAnimation> runningAnimations) {
-                        return insets;
-                    }
-                };
+        int windowFlags = activity.getWindow().getAttributes().flags;
+        EditText editText = activity.getEditText();
+        if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ false);
+        } else {
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+        }
+        // The Ime should always be hidden because view never gains focus.
+        verifyImeIsAlwaysHidden(editText);
+    }
 
-        public static TestActivity start() {
-            Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-            Intent intent = new Intent()
-                    .setAction(Intent.ACTION_MAIN)
-                    .setClass(instrumentation.getContext(), TestActivity.class)
-                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            return (TestActivity) instrumentation.startActivitySync(intent);
+    @Test
+    public void testShowHideWithWindowInsetsController_waitingVisibilityChange() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return;
+        }
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request focus after app starts to avoid triggering auto-show behavior.
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+        // Test only once if window flags set to save time.
+        int iterNum = hasUnfocusableWindowFlags(activity) ? 1 : NUM_TEST_ITERATIONS;
+        for (int i = 0; i < iterNum; i++) {
+            String msgPrefix = "Iteration #" + i + " ";
+            Log.i(TAG, msgPrefix + "start");
+            mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+            verifyShowBehavior(activity);
+            mInstrumentation.runOnMainSync(activity::hideImeWithWindowInsetsController);
+            verifyHideBehavior(activity);
+        }
+    }
+
+    @Test
+    public void testShowHideWithWindowInsetsController_waitingAnimationEnd() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return;
+        }
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request focus after app starts to avoid triggering auto-show behavior.
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+
+        if (hasUnfocusableWindowFlags(activity)) {
+            return; // Skip to save time.
+        }
+        activity.enableAnimationMonitoring();
+        EditText editText = activity.getEditText();
+        for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
+            String msgPrefix = "Iteration #" + i + " ";
+            Log.i(TAG, msgPrefix + "start");
+            mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+            waitOnMainUntil(
+                    msgPrefix + "IME should be visible",
+                    () -> !activity.isAnimating() && isImeShown(editText));
+
+            mInstrumentation.runOnMainSync(activity::hideImeWithWindowInsetsController);
+            waitOnMainUntil(
+                    msgPrefix + "IME should be hidden",
+                    () -> !activity.isAnimating() && !isImeShown(editText));
+        }
+    }
+
+    @Test
+    public void testShowHideWithWindowInsetsController_intervalAfterHide() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return;
+        }
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request focus after app starts to avoid triggering auto-show behavior.
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+
+        if (hasUnfocusableWindowFlags(activity)) {
+            return; // Skip to save time.
+        }
+        // Intervals = 10, 20, 30, ..., 100, 150, 200, ...
+        List<Integer> intervals = new ArrayList<>();
+        for (int i = 10; i < 100; i += 10) intervals.add(i);
+        for (int i = 100; i < 1000; i += 50) intervals.add(i);
+        for (int intervalMillis : intervals) {
+            String msgPrefix = "Interval = " + intervalMillis + " ";
+            Log.i(TAG, msgPrefix + " start");
+            mInstrumentation.runOnMainSync(activity::hideImeWithWindowInsetsController);
+            SystemClock.sleep(intervalMillis);
+
+            mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+            verifyShowBehavior(activity);
+        }
+    }
+
+    @Test
+    public void testShowHideWithWindowInsetsController_inSameFrame() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return;
+        }
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        // Request focus after app starts to avoid triggering auto-show behavior.
+        mInstrumentation.runOnMainSync(activity::requestFocus);
+
+        if (hasUnfocusableWindowFlags(activity)) {
+            return; // Skip to save time.
+        }
+        // hidden -> show -> hide
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    Log.i(TAG, "Calling showIme() and hideIme()");
+                    activity.showImeWithWindowInsetsController();
+                    activity.hideImeWithWindowInsetsController();
+                });
+        // Wait until IMMS / IMS handles messages.
+        SystemClock.sleep(1000);
+        mInstrumentation.waitForIdleSync();
+        // TODO(b/248456059): Ime should be hidden but is shown.
+        // verifyHideBehavior(activity);
+
+        mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+        verifyShowBehavior(activity);
+        mInstrumentation.waitForIdleSync();
+
+        // shown -> hide -> show
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    Log.i(TAG, "Calling hideIme() and showIme()");
+                    activity.hideImeWithWindowInsetsController();
+                    activity.showImeWithWindowInsetsController();
+                });
+        // Wait until IMMS / IMS handles messages.
+        SystemClock.sleep(1000);
+        mInstrumentation.waitForIdleSync();
+        verifyShowBehavior(activity);
+    }
+
+    @Test
+    public void testShowWithWindowInsetsController_onCreate_requestFocus() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return;
+        }
+        // Show with InputMethodManager at onCreate()
+        Intent intent =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Arrays.asList(
+                                REQUEST_FOCUS_ON_CREATE, WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE));
+        TestActivity activity = TestActivity.start(intent);
+
+        verifyShowBehavior(activity);
+    }
+
+    @Test
+    public void testShowWithWindowInsetsController_onCreate_notRequestFocus() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return;
+        }
+        // Show and hide with InputMethodManager at onCreate()
+        Intent intent =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Collections.singletonList(WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE));
+        TestActivity activity = TestActivity.start(intent);
+
+        // Ime is shown but with a fallback InputConnection
+        verifyShowBehaviorNotRequestFocus(activity);
+    }
+
+    @Test
+    public void testShowWithWindowInsetsController_afterStart_notRequestFocus() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return;
+        }
+        // Show and hide with InputMethodManager at onCreate()
+        Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+        TestActivity activity = TestActivity.start(intent);
+        mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+
+        // Ime is shown but with a fallback InputConnection
+        verifyShowBehaviorNotRequestFocus(activity);
+    }
+
+    @Test
+    public void testHideWithWindowInsetsController_onCreate_requestFocus() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return;
+        }
+        // Show and hide with InputMethodManager at onCreate()
+        Intent intent =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Arrays.asList(
+                                REQUEST_FOCUS_ON_CREATE,
+                                WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE,
+                                WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE));
+        TestActivity activity = TestActivity.start(intent);
+
+        // TODO(b/248456059): Ime should be hidden but is shown.
+        //verifyHideBehavior(activity);
+    }
+
+    @Test
+    public void testScreenOffOn() throws Exception {
+        Intent intent1 =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+        TestActivity activity = TestActivity.start(intent1);
+        // Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
+        boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+        assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+
+        Thread.sleep(1000);
+        verifyShowBehavior(activity);
+
+        UiDevice uiDevice = UiDevice.getInstance(mInstrumentation);
+
+        if (uiDevice.isScreenOn()) {
+            uiDevice.sleep();
+        }
+        Thread.sleep(1000);
+        if (!uiDevice.isScreenOn()) {
+            uiDevice.wakeUp();
         }
 
-        @Override
-        protected void onCreate(@Nullable Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            LinearLayout rootView = new LinearLayout(this);
-            rootView.setOrientation(LinearLayout.VERTICAL);
-            mEditText = new EditText(this);
-            rootView.addView(mEditText, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
-            setContentView(rootView);
-        }
+        verifyShowBehavior(activity);
+    }
 
-        public EditText getEditText() {
-            return mEditText;
-        }
+    @Test
+    public void testRotateScreenWithKeyboardOn() throws Exception {
+        // TODO(b/256739702): Keyboard disappears after rotating screen to landscape mode if
+        // android:configChanges="orientation|screenSize" is not set
+        Intent intent =
+                createIntent(
+                        mWindowFocusFlags,
+                        mSoftInputFlags,
+                        Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+        TestActivity activity = TestActivity.start(intent);
+        // Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
+        boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+        assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+        Thread.sleep(2000);
+        verifyShowBehavior(activity);
 
-        public void showIme() {
-            Log.i(TAG, "TestActivity.showIme");
-            mEditText.requestFocus();
-            InputMethodManager imm = getSystemService(InputMethodManager.class);
-            imm.showSoftInput(mEditText, 0);
-        }
+        UiDevice uiDevice = UiDevice.getInstance(mInstrumentation);
 
-        public void hideIme() {
-            Log.i(TAG, "TestActivity.hideIme");
-            InputMethodManager imm = getSystemService(InputMethodManager.class);
-            imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
-        }
+        uiDevice.freezeRotation();
+        uiDevice.setOrientationRight();
+        uiDevice.waitForIdle();
+        Thread.sleep(1000);
+        Log.i(TAG, "Rotate screen right");
+        assertThat(uiDevice.isNaturalOrientation()).isFalse();
+        verifyShowBehavior(activity);
 
-        public void enableAnimationMonitoring() {
-            // Enable WindowInsetsAnimation.
-            // Note that this has a side effect of disabling InsetsAnimationThreadControlRunner.
-            InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-                getWindow().setDecorFitsSystemWindows(false);
-                mEditText.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback);
-            });
-        }
+        uiDevice.setOrientationLeft();
+        uiDevice.waitForIdle();
+        Thread.sleep(1000);
+        Log.i(TAG, "Rotate screen left");
+        assertThat(uiDevice.isNaturalOrientation()).isFalse();
+        verifyShowBehavior(activity);
 
-        public boolean isAnimating() {
-            return mIsAnimating;
+        uiDevice.setOrientationNatural();
+        uiDevice.waitForIdle();
+        uiDevice.unfreezeRotation();
+    }
+
+    private static void verifyShowBehavior(TestActivity activity) {
+        if (hasUnfocusableWindowFlags(activity)) {
+            verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+            return;
+        }
+        EditText editText = activity.getEditText();
+
+        verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+        waitOnMainUntilImeIsShown(editText);
+    }
+
+    private static void verifyHideBehavior(TestActivity activity) {
+        if (hasUnfocusableWindowFlags(activity)) {
+            verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+            return;
+        }
+        EditText editText = activity.getEditText();
+
+        verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+        waitOnMainUntilImeIsHidden(editText);
+    }
+
+    private static void verifyShowBehaviorNotRequestFocus(TestActivity activity) {
+        int windowFlags = activity.getWindow().getAttributes().flags;
+        EditText editText = activity.getEditText();
+
+        if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ false);
+            verifyImeIsAlwaysHidden(editText);
+        } else if ((windowFlags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+                || (windowFlags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0) {
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+            verifyImeIsAlwaysHidden(editText);
+        } else {
+            verifyWindowAndViewFocus(
+                    editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+            // Ime is shown but with a fallback InputConnection
+            waitOnMainUntilImeIsShown(editText);
         }
     }
 }
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
index b6d462c..e16c915 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
@@ -16,17 +16,37 @@
 
 package com.android.inputmethod.stresstest;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
+
 import static com.android.compatibility.common.util.SystemUtil.eventually;
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
 import android.view.View;
 import android.view.WindowInsets;
+import android.view.WindowInsetsAnimation;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.LinearLayout;
 
+import androidx.annotation.Nullable;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.compatibility.common.util.ThrowingRunnable;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
@@ -34,28 +54,96 @@
 /** Utility methods for IME stress test. */
 public final class ImeStressTestUtil {
 
-    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
-    private static final long VERIFY_DURATION = TimeUnit.SECONDS.toMillis(2);
+    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(3);
 
-    private ImeStressTestUtil() {
+    private ImeStressTestUtil() {}
+
+    private static final int[] WINDOW_FOCUS_FLAGS =
+            new int[] {
+                LayoutParams.FLAG_NOT_FOCUSABLE,
+                LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                LayoutParams.FLAG_LOCAL_FOCUS_MODE
+            };
+
+    private static final int[] SOFT_INPUT_VISIBILITY_FLAGS =
+            new int[] {
+                LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED,
+                LayoutParams.SOFT_INPUT_STATE_UNCHANGED,
+                LayoutParams.SOFT_INPUT_STATE_HIDDEN,
+                LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN,
+                LayoutParams.SOFT_INPUT_STATE_VISIBLE,
+                LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE,
+            };
+
+    private static final int[] SOFT_INPUT_ADJUST_FLAGS =
+            new int[] {
+                LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED,
+                LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+                LayoutParams.SOFT_INPUT_ADJUST_PAN,
+                LayoutParams.SOFT_INPUT_ADJUST_NOTHING
+            };
+
+    public static final String SOFT_INPUT_FLAGS = "soft_input_flags";
+    public static final String WINDOW_FLAGS = "window_flags";
+    public static final String UNFOCUSABLE_VIEW = "unfocusable_view";
+    public static final String REQUEST_FOCUS_ON_CREATE = "request_focus_on_create";
+    public static final String INPUT_METHOD_MANAGER_SHOW_ON_CREATE =
+            "input_method_manager_show_on_create";
+    public static final String INPUT_METHOD_MANAGER_HIDE_ON_CREATE =
+            "input_method_manager_hide_on_create";
+    public static final String WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE =
+            "window_insets_controller_show_on_create";
+    public static final String WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE =
+            "window_insets_controller_hide_on_create";
+
+    /** Parameters for show/hide ime parameterized tests. */
+    public static ArrayList<Object[]> getWindowAndSoftInputFlagParameters() {
+        ArrayList<Object[]> params = new ArrayList<>();
+
+        // Set different window focus flags and keep soft input flags as default values (4 cases)
+        for (int windowFocusFlags : WINDOW_FOCUS_FLAGS) {
+            params.add(
+                    new Object[] {
+                        windowFocusFlags,
+                        LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED,
+                        LayoutParams.SOFT_INPUT_ADJUST_RESIZE
+                    });
+        }
+        // Set the combinations of different softInputVisibility, softInputAdjustment flags,
+        // keep the window focus flag as default value ( 6 * 4 = 24 cases)
+        for (int softInputVisibility : SOFT_INPUT_VISIBILITY_FLAGS) {
+            for (int softInputAdjust : SOFT_INPUT_ADJUST_FLAGS) {
+                params.add(
+                        new Object[] {
+                            0x0 /* No window focus flags */, softInputVisibility, softInputAdjust
+                        });
+            }
+        }
+        return params;
     }
 
     /** Checks if the IME is shown on the window that the given view belongs to. */
     public static boolean isImeShown(View view) {
         WindowInsets insets = view.getRootWindowInsets();
+        if (insets == null) {
+            return false;
+        }
         return insets.isVisible(WindowInsets.Type.ime());
     }
 
     /** Calls the callable on the main thread and returns the result. */
     public static <V> V callOnMainSync(Callable<V> callable) {
         AtomicReference<V> result = new AtomicReference<>();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            try {
-                result.set(callable.call());
-            } catch (Exception e) {
-                throw new RuntimeException("Exception was thrown", e);
-            }
-        });
+        InstrumentationRegistry.getInstrumentation()
+                .runOnMainSync(
+                        () -> {
+                            try {
+                                result.set(callable.call());
+                            } catch (Exception e) {
+                                throw new RuntimeException("Exception was thrown", e);
+                            }
+                        });
         return result.get();
     }
 
@@ -70,15 +158,42 @@
 
     /** Waits until IME is shown, or throws on timeout. */
     public static void waitOnMainUntilImeIsShown(View view) {
-        eventually(() -> assertWithMessage("IME should be shown").that(
-                callOnMainSync(() -> isImeShown(view))).isTrue(), TIMEOUT);
+        eventually(
+                () ->
+                        assertWithMessage("IME should be shown")
+                                .that(callOnMainSync(() -> isImeShown(view)))
+                                .isTrue(),
+                TIMEOUT);
     }
 
     /** Waits until IME is hidden, or throws on timeout. */
     public static void waitOnMainUntilImeIsHidden(View view) {
-        //eventually(() -> assertThat(callOnMainSync(() -> isImeShown(view))).isFalse(), TIMEOUT);
-        eventually(() -> assertWithMessage("IME should be hidden").that(
-                callOnMainSync(() -> isImeShown(view))).isFalse(), TIMEOUT);
+        eventually(
+                () ->
+                        assertWithMessage("IME should be hidden")
+                                .that(callOnMainSync(() -> isImeShown(view)))
+                                .isFalse(),
+                TIMEOUT);
+    }
+
+    /** Waits until window get focus, or throws on timeout. */
+    public static void waitOnMainUntilWindowGainsFocus(View view) {
+        eventually(
+                () ->
+                        assertWithMessage("Window should gain focus")
+                                .that(callOnMainSync(view::hasWindowFocus))
+                                .isTrue(),
+                TIMEOUT);
+    }
+
+    /** Waits until view get focus, or throws on timeout. */
+    public static void waitOnMainUntilViewGainsFocus(View view) {
+        eventually(
+                () ->
+                        assertWithMessage("View should gain focus")
+                                .that(callOnMainSync(view::hasFocus))
+                                .isTrue(),
+                TIMEOUT);
     }
 
     /** Verify IME is always hidden within the given time duration. */
@@ -88,7 +203,27 @@
                         assertWithMessage("IME should be hidden")
                                 .that(callOnMainSync(() -> isImeShown(view)))
                                 .isFalse(),
-                VERIFY_DURATION);
+                TIMEOUT);
+    }
+
+    /** Verify the window never gains focus within the given time duration. */
+    public static void verifyWindowNeverGainsFocus(View view) {
+        always(
+                () ->
+                        assertWithMessage("window should never gain focus")
+                                .that(callOnMainSync(view::hasWindowFocus))
+                                .isFalse(),
+                TIMEOUT);
+    }
+
+    /** Verify the view never gains focus within the given time duration. */
+    public static void verifyViewNeverGainsFocus(View view) {
+        always(
+                () ->
+                        assertWithMessage("view should never gain ime focus")
+                                .that(callOnMainSync(view::hasFocus))
+                                .isFalse(),
+                TIMEOUT);
     }
 
     /**
@@ -117,4 +252,232 @@
             }
         }
     }
+
+    public static boolean hasUnfocusableWindowFlags(Activity activity) {
+        int windowFlags = activity.getWindow().getAttributes().flags;
+        return (windowFlags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0
+                || (windowFlags & LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+                || (windowFlags & LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0;
+    }
+
+    public static void verifyWindowAndViewFocus(
+            View view, boolean expectWindowFocus, boolean expectViewFocus) {
+        if (expectWindowFocus) {
+            waitOnMainUntilWindowGainsFocus(view);
+        } else {
+            verifyWindowNeverGainsFocus(view);
+        }
+        if (expectViewFocus) {
+            waitOnMainUntilViewGainsFocus(view);
+        } else {
+            verifyViewNeverGainsFocus(view);
+        }
+    }
+
+    public static void verifyImeAlwaysHiddenWithWindowFlagSet(TestActivity activity) {
+        int windowFlags = activity.getWindow().getAttributes().flags;
+        View view = activity.getEditText();
+        if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            // When FLAG_NOT_FOCUSABLE is set true, the view will never gain window focus. The IME
+            // will always be hidden even though the view can get focus itself.
+            verifyWindowAndViewFocus(view, /*expectWindowFocus*/ false, /*expectViewFocus*/ true);
+            verifyImeIsAlwaysHidden(view);
+        } else if ((windowFlags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+                || (windowFlags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0) {
+            // When FLAG_ALT_FOCUSABLE_IM or FLAG_LOCAL_FOCUS_MODE is set, the view can gain both
+            // window focus and view focus but not IME focus. The IME will always be hidden.
+            verifyWindowAndViewFocus(view, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+            verifyImeIsAlwaysHidden(view);
+        }
+    }
+
+    /** Activity to help test show/hide behavior of IME. */
+    public static class TestActivity extends Activity {
+        private static final String TAG = "ImeStressTestUtil.TestActivity";
+        private EditText mEditText;
+        private boolean mIsAnimating;
+
+        private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
+                new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
+                    @Override
+                    public WindowInsetsAnimation.Bounds onStart(
+                            WindowInsetsAnimation animation, WindowInsetsAnimation.Bounds bounds) {
+                        mIsAnimating = true;
+                        return super.onStart(animation, bounds);
+                    }
+
+                    @Override
+                    public void onEnd(WindowInsetsAnimation animation) {
+                        super.onEnd(animation);
+                        mIsAnimating = false;
+                    }
+
+                    @Override
+                    public WindowInsets onProgress(
+                            WindowInsets insets, List<WindowInsetsAnimation> runningAnimations) {
+                        return insets;
+                    }
+                };
+
+        /** Create intent with extras. */
+        public static Intent createIntent(
+                int windowFlags, int softInputFlags, List<String> extras) {
+            Intent intent =
+                    new Intent()
+                            .putExtra(WINDOW_FLAGS, windowFlags)
+                            .putExtra(SOFT_INPUT_FLAGS, softInputFlags);
+            for (String extra : extras) {
+                intent.putExtra(extra, true);
+            }
+            return intent;
+        }
+
+        @Override
+        protected void onCreate(@Nullable Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            Log.i(TAG, "onCreate()");
+            boolean isUnfocusableView = getIntent().getBooleanExtra(UNFOCUSABLE_VIEW, false);
+            boolean requestFocus = getIntent().getBooleanExtra(REQUEST_FOCUS_ON_CREATE, false);
+            int softInputFlags = getIntent().getIntExtra(SOFT_INPUT_FLAGS, 0);
+            int windowFlags = getIntent().getIntExtra(WINDOW_FLAGS, 0);
+            boolean showWithInputMethodManagerOnCreate =
+                    getIntent().getBooleanExtra(INPUT_METHOD_MANAGER_SHOW_ON_CREATE, false);
+            boolean hideWithInputMethodManagerOnCreate =
+                    getIntent().getBooleanExtra(INPUT_METHOD_MANAGER_HIDE_ON_CREATE, false);
+            boolean showWithWindowInsetsControllerOnCreate =
+                    getIntent().getBooleanExtra(WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE, false);
+            boolean hideWithWindowInsetsControllerOnCreate =
+                    getIntent().getBooleanExtra(WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE, false);
+
+            getWindow().addFlags(windowFlags);
+            getWindow().setSoftInputMode(softInputFlags);
+
+            LinearLayout rootView = new LinearLayout(this);
+            rootView.setOrientation(LinearLayout.VERTICAL);
+            mEditText = new EditText(this);
+            if (isUnfocusableView) {
+                mEditText.setFocusableInTouchMode(false);
+            }
+            rootView.addView(mEditText, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
+            setContentView(rootView);
+
+            if (requestFocus) {
+                requestFocus();
+            }
+            if (showWithInputMethodManagerOnCreate) {
+                showImeWithInputMethodManager();
+            }
+            if (hideWithInputMethodManagerOnCreate) {
+                hideImeWithInputMethodManager();
+            }
+            if (showWithWindowInsetsControllerOnCreate) {
+                showImeWithWindowInsetsController();
+            }
+            if (hideWithWindowInsetsControllerOnCreate) {
+                hideImeWithWindowInsetsController();
+            }
+        }
+
+        /** Show IME with InputMethodManager. */
+        public boolean showImeWithInputMethodManager() {
+            boolean showResult =
+                    getInputMethodManager()
+                            .showSoftInput(mEditText, InputMethodManager.SHOW_IMPLICIT);
+            if (showResult) {
+                Log.i(TAG, "IMM#showSoftInput successfully");
+            } else {
+                Log.i(TAG, "IMM#showSoftInput failed");
+            }
+            return showResult;
+        }
+
+        /** Hide IME with InputMethodManager. */
+        public boolean hideImeWithInputMethodManager() {
+            boolean hideResult =
+                    getInputMethodManager().hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
+            if (hideResult) {
+                Log.i(TAG, "IMM#hideSoftInput successfully");
+            } else {
+                Log.i(TAG, "IMM#hideSoftInput failed");
+            }
+            return hideResult;
+        }
+
+        /** Show IME with WindowInsetsController */
+        public void showImeWithWindowInsetsController() {
+            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+                return;
+            }
+            Log.i(TAG, "showImeWithWIC()");
+            WindowInsetsController windowInsetsController = mEditText.getWindowInsetsController();
+            assertWithMessage("WindowInsetsController shouldn't be null.")
+                    .that(windowInsetsController)
+                    .isNotNull();
+            windowInsetsController.show(WindowInsets.Type.ime());
+        }
+
+        /** Hide IME with WindowInsetsController. */
+        public void hideImeWithWindowInsetsController() {
+            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+                return;
+            }
+            Log.i(TAG, "hideImeWithWIC()");
+            WindowInsetsController windowInsetsController = mEditText.getWindowInsetsController();
+            assertWithMessage("WindowInsetsController shouldn't be null.")
+                    .that(windowInsetsController)
+                    .isNotNull();
+            windowInsetsController.hide(WindowInsets.Type.ime());
+        }
+
+        private InputMethodManager getInputMethodManager() {
+            return getSystemService(InputMethodManager.class);
+        }
+
+        public EditText getEditText() {
+            return mEditText;
+        }
+
+        /** Start TestActivity with intent. */
+        public static TestActivity start(Intent intent) {
+            Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+            intent.setAction(Intent.ACTION_MAIN)
+                    .setClass(instrumentation.getContext(), TestActivity.class)
+                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            return (TestActivity) instrumentation.startActivitySync(intent);
+        }
+
+        /** Start the second TestActivity with intent. */
+        public TestActivity startSecondTestActivity(Intent intent) {
+            Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+            intent.setClass(TestActivity.this, TestActivity.class);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            return (TestActivity) instrumentation.startActivitySync(intent);
+        }
+
+        public void enableAnimationMonitoring() {
+            // Enable WindowInsetsAnimation.
+            // Note that this has a side effect of disabling InsetsAnimationThreadControlRunner.
+            InstrumentationRegistry.getInstrumentation()
+                    .runOnMainSync(
+                            () -> {
+                                getWindow().setDecorFitsSystemWindows(false);
+                                mEditText.setWindowInsetsAnimationCallback(
+                                        mWindowInsetsAnimationCallback);
+                            });
+        }
+
+        public boolean isAnimating() {
+            return mIsAnimating;
+        }
+
+        public void requestFocus() {
+            boolean requestFocusResult = getEditText().requestFocus();
+            if (requestFocusResult) {
+                Log.i(TAG, "Request focus successfully");
+            } else {
+                Log.i(TAG, "Request focus failed");
+            }
+        }
+    }
 }
