chromium/content/public/android/javatests/src/org/chromium/content/browser/input/ImeInputModeTest.java

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.content.browser.input;

import android.text.InputType;
import android.view.inputmethod.EditorInfo;

import androidx.test.filters.SmallTest;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.blink_public.web.WebTextInputMode;
import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner;
import org.chromium.ui.base.ime.TextInputType;

/** IME (input method editor) and text input tests for input-mode attribute. */
@RunWith(ContentJUnit4ClassRunner.class)
@Batch(ImeTest.IME_BATCH)
public class ImeInputModeTest {
    @Rule public ImeActivityTestRule mRule = new ImeActivityTestRule();

    @Before
    public void setUp() throws Exception {
        mRule.setUpForUrl(ImeActivityTestRule.INPUT_MODE_HTML);
    }

    @After
    public void tearDown() throws Exception {
        mRule.getActivity().finish();
    }

    @Test
    @SmallTest
    @Feature({"TextInput"})
    public void testNumericPassword() throws Exception {
        mRule.focusElement("input_numeric_password", /* shouldShowKeyboard= */ true);

        mRule.waitForKeyboardStates(
                1,
                0,
                1,
                new Integer[] {TextInputType.PASSWORD},
                new Integer[] {WebTextInputMode.NUMERIC});
        Assert.assertNotNull(mRule.getInputMethodManagerWrapper().getInputConnection());

        Assert.assertTrue(
                (mRule.getConnectionFactory().getOutAttrs().inputType
                                & (InputType.TYPE_CLASS_NUMBER
                                        | InputType.TYPE_NUMBER_VARIATION_PASSWORD))
                        != 0);
    }

    @DisabledTest(message = "crbug.com/1463785")
    @Test
    @SmallTest
    @Feature({"TextInput"})
    public void testShowAndHideInputMode() throws Exception {
        mRule.focusElement("contenteditable_none", false);

        // hideSoftKeyboard()
        mRule.waitForKeyboardStates(0, 1, 0, new Integer[] {}, new Integer[] {});
        Assert.assertNotNull(mRule.getInputConnection());

        Assert.assertTrue(
                (mRule.getConnectionFactory().getOutAttrs().imeOptions
                                & (EditorInfo.IME_FLAG_NO_FULLSCREEN
                                        | EditorInfo.IME_FLAG_NO_EXTRACT_UI))
                        != 0);

        // showSoftInput(), mRule.restartInput()
        mRule.focusElement("contenteditable_text");
        mRule.waitForKeyboardStates(
                1,
                1,
                1,
                new Integer[] {TextInputType.CONTENT_EDITABLE},
                new Integer[] {WebTextInputMode.TEXT});
        Assert.assertNotNull(mRule.getInputMethodManagerWrapper().getInputConnection());

        mRule.focusElement("contenteditable_tel");
        // Hide should never be called here. Otherwise we will see a flicker. Restarted to
        // reset internal states to handle the new input form.
        mRule.waitForKeyboardStates(
                2,
                1,
                2,
                new Integer[] {TextInputType.CONTENT_EDITABLE, TextInputType.CONTENT_EDITABLE},
                new Integer[] {WebTextInputMode.TEXT, WebTextInputMode.TEL});

        mRule.focusElement("contenteditable_url");
        mRule.waitForKeyboardStates(
                3,
                1,
                3,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE
                },
                new Integer[] {WebTextInputMode.TEXT, WebTextInputMode.TEL, WebTextInputMode.URL});

        mRule.focusElement("contenteditable_email");
        mRule.waitForKeyboardStates(
                4,
                1,
                4,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE
                },
                new Integer[] {
                    WebTextInputMode.TEXT,
                    WebTextInputMode.TEL,
                    WebTextInputMode.URL,
                    WebTextInputMode.EMAIL
                });

        mRule.focusElement("contenteditable_numeric");
        mRule.waitForKeyboardStates(
                5,
                1,
                5,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE
                },
                new Integer[] {
                    WebTextInputMode.TEXT,
                    WebTextInputMode.TEL,
                    WebTextInputMode.URL,
                    WebTextInputMode.EMAIL,
                    WebTextInputMode.NUMERIC
                });

        mRule.focusElement("contenteditable_decimal");
        mRule.waitForKeyboardStates(
                6,
                1,
                6,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE
                },
                new Integer[] {
                    WebTextInputMode.TEXT,
                    WebTextInputMode.TEL,
                    WebTextInputMode.URL,
                    WebTextInputMode.EMAIL,
                    WebTextInputMode.NUMERIC,
                    WebTextInputMode.DECIMAL
                });

        mRule.focusElement("contenteditable_search");
        mRule.waitForKeyboardStates(
                7,
                1,
                7,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE
                },
                new Integer[] {
                    WebTextInputMode.TEXT,
                    WebTextInputMode.TEL,
                    WebTextInputMode.URL,
                    WebTextInputMode.EMAIL,
                    WebTextInputMode.NUMERIC,
                    WebTextInputMode.DECIMAL,
                    WebTextInputMode.SEARCH
                });

        mRule.focusElement("contenteditable_none", false);
        mRule.waitForKeyboardStates(
                7,
                2,
                7,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE
                },
                new Integer[] {
                    WebTextInputMode.TEXT,
                    WebTextInputMode.TEL,
                    WebTextInputMode.URL,
                    WebTextInputMode.EMAIL,
                    WebTextInputMode.NUMERIC,
                    WebTextInputMode.DECIMAL,
                    WebTextInputMode.SEARCH
                });
    }

    @DisabledTest(message = "crbug.com/1463785")
    @Test
    @SmallTest
    @Feature({"TextInput"})
    public void testShowAndHideInputModeWithPhysicalKeyboard() throws Throwable {
        // First show should hide the keyboard.
        mRule.focusElement("contenteditable_none", false);

        // hideSoftKeyboard()
        mRule.waitForKeyboardStates(0, 1, 0, new Integer[] {}, new Integer[] {});
        Assert.assertNotNull(mRule.getInputConnection());

        // Now with the physical keyboard attached it should cause a show (because of the
        // IME composition window).
        mRule.attachPhysicalKeyboard();

        // showSoftKeyboard(), mRule.restartInput()
        mRule.waitForKeyboardStates(
                1,
                1,
                1,
                new Integer[] {TextInputType.CONTENT_EDITABLE},
                new Integer[] {WebTextInputMode.NONE});
        Assert.assertNotNull(mRule.getInputMethodManagerWrapper().getInputConnection());

        // Move focus to another input, cause it to do a show there.
        mRule.focusElement("contenteditable_text");
        mRule.waitForKeyboardStates(
                2,
                1,
                2,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE, TextInputType.CONTENT_EDITABLE,
                },
                new Integer[] {WebTextInputMode.NONE, WebTextInputMode.TEXT});
        Assert.assertNotNull(mRule.getInputMethodManagerWrapper().getInputConnection());

        // Focusing the none content editable should show the keyboard when there is one
        // physically attached.
        mRule.focusElement("contenteditable_none");

        // mRule.restartInput()
        mRule.waitForKeyboardStates(
                2,
                1,
                3,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE
                },
                new Integer[] {
                    WebTextInputMode.NONE, WebTextInputMode.TEXT, WebTextInputMode.NONE
                });
        Assert.assertNotNull(mRule.getInputMethodManagerWrapper().getInputConnection());

        mRule.detachPhysicalKeyboard();

        // mRule.restartInput(), hideSoftKeyboard()
        mRule.waitForKeyboardStates(
                2,
                2,
                4,
                new Integer[] {
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE,
                    TextInputType.CONTENT_EDITABLE
                },
                new Integer[] {
                    WebTextInputMode.NONE,
                    WebTextInputMode.TEXT,
                    WebTextInputMode.NONE,
                    WebTextInputMode.NONE
                });
        Assert.assertNotNull(mRule.getInputConnection());
    }
}