AdapterInputConnectionTest.java revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.browser.input;
6
7import android.content.Context;
8import android.os.IBinder;
9import android.os.ResultReceiver;
10import android.test.suitebuilder.annotation.MediumTest;
11import android.view.View;
12import android.view.inputmethod.EditorInfo;
13
14import org.chromium.base.test.util.Feature;
15import org.chromium.content.browser.input.AdapterInputConnection.ImeState;
16import org.chromium.content.browser.input.ImeAdapter.ImeAdapterDelegate;
17import org.chromium.content_shell_apk.ContentShellTestBase;
18
19import java.util.ArrayList;
20
21/**
22 * Tests AdapterInputConnection class and its callbacks to ImeAdapter.
23 */
24public class AdapterInputConnectionTest extends ContentShellTestBase {
25
26    private AdapterInputConnection mConnection;
27    private TestInputMethodManagerWrapper mWrapper;
28
29    @Override
30    public void setUp() throws Exception {
31        super.setUp();
32        launchContentShellWithUrl("about:blank");
33        assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
34        mWrapper = new TestInputMethodManagerWrapper(getActivity());
35        ImeAdapterDelegate delegate = new TestImeAdapterDelegate();
36        ImeAdapter imeAdapter = new TestImeAdapter(mWrapper, delegate);
37        EditorInfo info = new EditorInfo();
38        mConnection = new AdapterInputConnection(
39                getActivity().getActiveContentView(), imeAdapter, info);
40    }
41
42    @MediumTest
43    @Feature({"TextInput", "Main"})
44    public void testSetComposingText() throws Throwable {
45        mConnection.setComposingText("t", 1);
46        assertCorrectState("t", 1, 1, 0, 1, mConnection.getImeStateForTesting());
47        mWrapper.verifyUpdateSelectionCall(0, 1, 1, 0 ,1);
48
49        mConnection.setComposingText("te", 1);
50        assertCorrectState("te", 2, 2, 0, 2, mConnection.getImeStateForTesting());
51        mWrapper.verifyUpdateSelectionCall(1, 2, 2, 0 ,2);
52
53        mConnection.setComposingText("tes", 1);
54        assertCorrectState("tes", 3, 3, 0, 3, mConnection.getImeStateForTesting());
55        mWrapper.verifyUpdateSelectionCall(2, 3, 3, 0, 3);
56
57        mConnection.setComposingText("test", 1);
58        assertCorrectState("test", 4, 4, 0, 4, mConnection.getImeStateForTesting());
59        mWrapper.verifyUpdateSelectionCall(3, 4, 4, 0, 4);
60    }
61
62    @MediumTest
63    @Feature({"TextInput", "Main"})
64    public void testSelectionUpdatesDuringBatch() throws Throwable {
65        mConnection.beginBatchEdit();
66        mConnection.setComposingText("t", 1);
67        assertEquals(0, mWrapper.getUpdateSelectionCallCount());
68        mConnection.setComposingText("te", 1);
69        assertEquals(0, mWrapper.getUpdateSelectionCallCount());
70        mConnection.beginBatchEdit();
71        mConnection.setComposingText("tes", 1);
72        assertEquals(0, mWrapper.getUpdateSelectionCallCount());
73        mConnection.endBatchEdit();
74        mConnection.setComposingText("test", 1);
75        assertEquals(0, mWrapper.getUpdateSelectionCallCount());
76        mConnection.endBatchEdit();
77        assertEquals(1, mWrapper.getUpdateSelectionCallCount());
78        mWrapper.verifyUpdateSelectionCall(0, 4, 4, 0 ,4);
79    }
80
81    @MediumTest
82    @Feature({"TextInput", "Main"})
83    public void testDismissInputMethodWindowAfterFinishingTyping() throws Throwable {
84        assertEquals(false, mWrapper.isHidden());
85
86        mConnection.performEditorAction(EditorInfo.IME_ACTION_NEXT);
87        assertEquals(false, mWrapper.isHidden());
88        mWrapper.showSoftInput(null, 0, null);
89
90        mConnection.performEditorAction(EditorInfo.IME_ACTION_SEND);
91        assertEquals(false, mWrapper.isHidden());
92        mWrapper.showSoftInput(null, 0, null);
93
94        mConnection.performEditorAction(EditorInfo.IME_ACTION_GO);
95        assertEquals(true, mWrapper.isHidden());
96        mWrapper.showSoftInput(null, 0, null);
97
98        mConnection.performEditorAction(EditorInfo.IME_ACTION_DONE);
99        assertEquals(true, mWrapper.isHidden());
100        mWrapper.showSoftInput(null, 0, null);
101
102        mConnection.performEditorAction(EditorInfo.IME_ACTION_SEARCH);
103        assertEquals(true, mWrapper.isHidden());
104        mWrapper.showSoftInput(null, 0, null);
105    }
106
107    private static class TestImeAdapter extends ImeAdapter {
108        public TestImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embedder) {
109            super(wrapper, embedder);
110        }
111    }
112
113    private static class TestInputMethodManagerWrapper extends InputMethodManagerWrapper {
114        private final ArrayList<ImeState> mUpdates = new ArrayList<ImeState>();
115        private boolean hidden = false;
116
117        public TestInputMethodManagerWrapper(Context context) {
118            super(context);
119        }
120
121        @Override
122        public void restartInput(View view) {}
123
124        @Override
125        public void showSoftInput(View view, int flags, ResultReceiver resultReceiver) {
126            hidden = false;
127        }
128
129        @Override
130        public boolean isActive(View view) {
131            return true;
132        }
133
134        @Override
135        public boolean hideSoftInputFromWindow(IBinder windowToken, int flags,
136                ResultReceiver resultReceiver) {
137            hidden = true;
138            return true;
139        }
140
141        @Override
142        public void updateSelection(View view, int selStart, int selEnd,
143                int candidatesStart, int candidatesEnd) {
144          mUpdates.add(new ImeState("", selStart, selEnd, candidatesStart, candidatesEnd));
145        }
146
147        public int getUpdateSelectionCallCount() {
148            return mUpdates.size();
149        }
150
151        public void verifyUpdateSelectionCall(int index, int selectionStart, int selectionEnd,
152                int compositionStart, int compositionEnd) {
153            ImeState state = mUpdates.get(index);
154            assertEquals("Selection start did not match", selectionStart, state.selectionStart);
155            assertEquals("Selection end did not match", selectionEnd, state.selectionEnd);
156            assertEquals("Composition start did not match", compositionStart,
157                    state.compositionStart);
158            assertEquals("Composition end did not match", compositionEnd, state.compositionEnd);
159        }
160
161        public boolean isHidden() {
162            return hidden;
163        }
164    }
165
166    private static class TestImeAdapterDelegate implements ImeAdapterDelegate {
167        @Override
168        public void onImeEvent(boolean isFinish) {}
169
170        @Override
171        public void onSetFieldValue() {}
172
173        @Override
174        public void onDismissInput() {}
175
176        @Override
177        public View getAttachedView() {
178            return null;
179        }
180
181        @Override
182        public ResultReceiver getNewShowKeyboardReceiver() {
183            return null;
184        }
185    }
186
187    private static void assertCorrectState(String text, int selectionStart, int selectionEnd,
188            int compositionStart, int compositionEnd, ImeState actual) {
189        assertEquals("Text did not match", text, actual.text);
190        assertEquals("Selection start did not match", selectionStart, actual.selectionStart);
191        assertEquals("Selection end did not match", selectionEnd, actual.selectionEnd);
192        assertEquals("Composition start did not match", compositionStart, actual.compositionStart);
193        assertEquals("Composition end did not match", compositionEnd, actual.compositionEnd);
194    }
195}
196