12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)package org.chromium.content.browser.input;
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.app.Activity;
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.ClipData;
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.ClipboardManager;
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.Context;
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.test.suitebuilder.annotation.MediumTest;
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.test.suitebuilder.annotation.SmallTest;
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.text.TextUtils;
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.view.View;
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.view.inputmethod.EditorInfo;
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.ThreadUtils;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.test.util.Feature;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.test.util.UrlUtils;
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import org.chromium.content.browser.ContentView;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.content.browser.test.util.Criteria;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.content.browser.test.util.CriteriaHelper;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.content.browser.test.util.DOMUtils;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.content_shell_apk.ContentShellTestBase;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import java.util.ArrayList;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import java.util.concurrent.Callable;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public class ImeTest extends ContentShellTestBase {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private static final String DATA_URL = UrlUtils.encodeHtmlDataUri(
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "<html><head><meta name=\"viewport\"" +
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" /></head>" +
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "<body><form action=\"about:blank\">" +
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "<input id=\"input_text\" type=\"text\" />" +
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "<input id=\"input_radio\" type=\"radio\" />" +
39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            "<br/><textarea id=\"textarea\" rows=\"4\" cols=\"20\"></textarea>" +
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "</form></body></html>");
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private TestAdapterInputConnection mConnection;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private ImeAdapter mImeAdapter;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private ContentView mContentView;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private TestCallbackHelperContainer mCallbackContainer;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private TestInputMethodManagerWrapper mInputMethodManagerWrapper;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Override
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void setUp() throws Exception {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        super.setUp();
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        launchContentShellWithUrl(DATA_URL);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mInputMethodManagerWrapper = new TestInputMethodManagerWrapper(getContentViewCore());
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        getImeAdapter().setInputMethodManagerWrapper(mInputMethodManagerWrapper);
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(0, mInputMethodManagerWrapper.getShowSoftInputCounter());
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        getContentViewCore().setAdapterInputConnectionFactory(
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                new TestAdapterInputConnectionFactory());
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mContentView = getActivity().getActiveContentView();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mCallbackContainer = new TestCallbackHelperContainer(mContentView);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // TODO(aurimas) remove this wait once crbug.com/179511 is fixed.
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForPageScaleFactor(1);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DOMUtils.clickNode(this, mContentView, mCallbackContainer, "input_text");
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForKeyboardStatus(true);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mConnection = (TestAdapterInputConnection) getAdapterInputConnection();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mImeAdapter = getImeAdapter();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 0, "", 0, 0, -1, -1);
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(1, mInputMethodManagerWrapper.getShowSoftInputCounter());
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(0, mInputMethodManagerWrapper.getEditorInfo().initialSelStart);
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(0, mInputMethodManagerWrapper.getEditorInfo().initialSelEnd);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @MediumTest
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"TextInput", "Main"})
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testKeyboardDismissedAfterClickingGo() throws Throwable {
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setComposingText("hello", 1);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hello", 5, 5, 0, 5);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        performGo(getAdapterInputConnection(), mCallbackContainer);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "", 0, 0, -1, -1);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForKeyboardStatus(false);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"TextInput", "Main"})
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testGetTextUpdatesAfterEnteringText() throws Throwable {
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setComposingText("h", 1);
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "h", 1, 1, 0, 1);
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(1, mInputMethodManagerWrapper.getShowSoftInputCounter());
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setComposingText("he", 1);
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "he", 2, 2, 0, 2);
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(1, mInputMethodManagerWrapper.getShowSoftInputCounter());
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setComposingText("hel", 1);
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "hel", 3, 3, 0, 3);
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(1, mInputMethodManagerWrapper.getShowSoftInputCounter());
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.commitText("hel", 1);
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 4, "hel", 3, 3, -1, -1);
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(1, mInputMethodManagerWrapper.getShowSoftInputCounter());
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"TextInput"})
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testImeCopy() throws Exception {
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.commitText("hello", 1);
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hello", 5, 5, -1, -1);
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setSelection(2, 5);
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "hello", 2, 5, -1, -1);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mImeAdapter.copy();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertClipboardContents(getActivity(), "llo");
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"TextInput"})
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public void testEnterTextAndRefocus() throws Exception {
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.commitText("hello", 1);
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hello", 5, 5, -1, -1);
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        DOMUtils.clickNode(this, mContentView, mCallbackContainer, "input_radio");
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        assertWaitForKeyboardStatus(false);
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        DOMUtils.clickNode(this, mContentView, mCallbackContainer, "input_text");
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        assertWaitForKeyboardStatus(true);
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(5, mInputMethodManagerWrapper.getEditorInfo().initialSelStart);
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        assertEquals(5, mInputMethodManagerWrapper.getEditorInfo().initialSelEnd);
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @SmallTest
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @Feature({"TextInput"})
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testImeCut() throws Exception {
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.commitText("snarful", 1);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "snarful", 7, 7, -1, -1);
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setSelection(1, 5);
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "snarful", 1, 5, -1, -1);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mImeAdapter.cut();
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "sul", 1, 1, -1, -1);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertClipboardContents(getActivity(), "narf");
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"TextInput"})
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testImePaste() throws Exception {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public void run() {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                ClipboardManager clipboardManager =
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        (ClipboardManager) getActivity().getSystemService(
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                Context.CLIPBOARD_SERVICE);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                clipboardManager.setPrimaryClip(ClipData.newPlainText("blarg", "blarg"));
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        });
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mImeAdapter.paste();
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "blarg", 5, 5, -1, -1);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setSelection(3, 5);
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "blarg", 3, 5, -1, -1);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mImeAdapter.paste();
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Paste is a two step process when there is a non-zero selection.
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "bla", 3, 3, -1, -1);
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 4, "blablarg", 8, 8, -1, -1);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mImeAdapter.paste();
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                mConnection.mImeUpdateQueue, 5, "blablargblarg", 13, 13, -1, -1);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"TextInput"})
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testImeSelectAndUnSelectAll() throws Exception {
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.commitText("hello", 1);
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hello", 5, 5, -1, -1);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mImeAdapter.selectAll();
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "hello", 0, 5, -1, -1);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mImeAdapter.unselect();
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "", 0, 0, -1, -1);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForKeyboardStatus(false);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"TextInput", "Main"})
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testUpdatesGetIgnoredDuringBatchEdits() throws Throwable {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mConnection.beginBatchEdit();
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForSetIgnoreUpdates(true, mConnection);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setComposingText("h", 1);
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "h", 1, 1, 0, 1);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue(mConnection.isIgnoringTextInputStateUpdates());
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setComposingText("he", 1);
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "he", 2, 2, 0, 2);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue(mConnection.isIgnoringTextInputStateUpdates());
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setComposingText("hel", 1);
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "hel", 3, 3, 0, 3);
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertEquals(0, mConnection.mUpdateSelectionCounter);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue(mConnection.isIgnoringTextInputStateUpdates());
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mConnection.endBatchEdit();
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForSetIgnoreUpdates(false, mConnection);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"TextInput", "Main"})
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testShowImeIfNeeded() throws Throwable {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DOMUtils.focusNode(this, mContentView, mCallbackContainer, "input_radio");
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForKeyboardStatus(false);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        performShowImeIfNeeded();
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForKeyboardStatus(false);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DOMUtils.focusNode(this, mContentView, mCallbackContainer, "input_text");
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForKeyboardStatus(false);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        performShowImeIfNeeded();
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertWaitForKeyboardStatus(true);
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @SmallTest
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @Feature({"TextInput", "Main"})
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public void testFinishComposingText() throws Throwable {
238a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        // Focus the textarea. We need to do the following steps because we are focusing using JS.
239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        DOMUtils.focusNode(this, mContentView, mCallbackContainer, "input_radio");
240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        assertWaitForKeyboardStatus(false);
241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        DOMUtils.focusNode(this, mContentView, mCallbackContainer, "textarea");
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        assertWaitForKeyboardStatus(false);
243a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        performShowImeIfNeeded();
244a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        assertWaitForKeyboardStatus(true);
245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
246a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        mConnection = (TestAdapterInputConnection) getAdapterInputConnection();
247a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 0, "", 0, 0, -1, -1);
248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.commitText("hllo", 1);
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hllo", 4, 4, -1, -1);
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.commitText(" ", 1);
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "hllo ", 5, 5, -1, -1);
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setSelection(1, 1);
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "hllo ", 1, 1, -1, -1);
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.setComposingRegion(0, 4);
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 4, "hllo ", 1, 1, 0, 4);
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mConnection.finishComposingText();
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 5, "hllo ", 1, 1, -1, -1);
263a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
264a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        mConnection.commitText("\n", 1);
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 6, "h\nllo ", 2, 2, -1, -1);
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void performShowImeIfNeeded() {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public void run() {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                mContentView.getContentViewCore().showImeIfNeeded();
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        });
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void performGo(final AdapterInputConnection inputConnection,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            TestCallbackHelperContainer testCallbackHelperContainer) throws Throwable {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        handleBlockingCallbackAction(
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                testCallbackHelperContainer.getOnPageFinishedHelper(),
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                new Runnable() {
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    @Override
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    public void run() {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        inputConnection.performEditorAction(EditorInfo.IME_ACTION_GO);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    }
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                });
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void assertWaitForPageScaleFactor(final float scale) throws InterruptedException {
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public boolean isSatisfied() {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return getContentViewCore().getScale() == scale;
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }));
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void assertWaitForKeyboardStatus(final boolean show) throws InterruptedException {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public boolean isSatisfied() {
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return show == getImeAdapter().mIsShowWithoutHideOutstanding &&
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        (!show || getAdapterInputConnection() != null);
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }));
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private void waitAndVerifyEditableCallback(final ArrayList<TestImeState> states,
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            final int index, String text, int selectionStart, int selectionEnd,
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int compositionStart, int compositionEnd) throws InterruptedException {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public boolean isSatisfied() {
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                return states.size() > index;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }));
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        states.get(index).assertEqualState(
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                text, selectionStart, selectionEnd, compositionStart, compositionEnd);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void assertClipboardContents(final Activity activity, final String expectedContents)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            throws InterruptedException {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public boolean isSatisfied() {
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    @Override
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    public Boolean call() throws Exception {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        ClipboardManager clipboardManager =
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                (ClipboardManager) activity.getSystemService(
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        Context.CLIPBOARD_SERVICE);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        ClipData clip = clipboardManager.getPrimaryClip();
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        return clip != null && clip.getItemCount() == 1
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                && TextUtils.equals(clip.getItemAt(0).getText(), expectedContents);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    }
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                });
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }));
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void assertWaitForSetIgnoreUpdates(final boolean ignore,
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            final TestAdapterInputConnection connection) throws Throwable {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public boolean isSatisfied() {
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return ignore == connection.isIgnoringTextInputStateUpdates();
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }));
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private ImeAdapter getImeAdapter() {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return getContentViewCore().getImeAdapterForTest();
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private AdapterInputConnection getAdapterInputConnection() {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return getContentViewCore().getInputConnectionForTest();
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private static class TestAdapterInputConnectionFactory extends
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ImeAdapter.AdapterInputConnectionFactory {
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        @Override
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                EditorInfo outAttrs) {
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return new TestAdapterInputConnection(view, imeAdapter, outAttrs);
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private static class TestAdapterInputConnection extends AdapterInputConnection {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        private int mUpdateSelectionCounter = 0;
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        private ArrayList<TestImeState> mImeUpdateQueue = new ArrayList<ImeTest.TestImeState>();
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        public TestAdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            super(view, imeAdapter, outAttrs);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        @Override
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        public void setEditableText(String text, int selectionStart, int selectionEnd,
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                int compositionStart, int compositionEnd) {
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mImeUpdateQueue.add(new TestImeState(text, selectionStart, selectionEnd,
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    compositionStart, compositionEnd));
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            super.setEditableText(
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    text, selectionStart, selectionEnd, compositionStart, compositionEnd);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        @Override
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        protected void updateSelection(
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                int selectionStart, int selectionEnd,
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                int compositionStart, int compositionEnd) {
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mUpdateSelectionCounter++;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private static class TestImeState {
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        private final String mText;
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        private final int mSelectionStart;
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        private final int mSelectionEnd;
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        private final int mCompositionStart;
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        private final int mCompositionEnd;
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        public TestImeState(String text, int selectionStart, int selectionEnd,
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                int compositionStart, int compositionEnd) {
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mText = text;
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mSelectionStart = selectionStart;
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mSelectionEnd = selectionEnd;
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mCompositionStart = compositionStart;
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mCompositionEnd = compositionEnd;
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        public void assertEqualState(String text, int selectionStart, int selectionEnd,
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                int compositionStart, int compositionEnd) {
413a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            assertEquals("Text did not match", text, mText);
414a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            assertEquals("Selection start did not match", selectionStart, mSelectionStart);
415a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            assertEquals("Selection end did not match", selectionEnd, mSelectionEnd);
416a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            assertEquals("Composition start did not match", compositionStart, mCompositionStart);
417a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            assertEquals("Composition end did not match", compositionEnd, mCompositionEnd);
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
421