diff options
Diffstat (limited to 'content')
4 files changed, 189 insertions, 16 deletions
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java b/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java index 653c366..59427b2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -23,8 +23,7 @@ import android.view.inputmethod.ExtractedTextRequest; * native ImeAdapterAndroid via the class ImeAdapter. */ public class AdapterInputConnection extends BaseInputConnection { - private static final String TAG = - "org.chromium.content.browser.input.AdapterInputConnection"; + private static final String TAG = "AdapterInputConnection"; private static final boolean DEBUG = false; /** * Selection value should be -1 if not known. See EditorInfo.java for details. @@ -99,7 +98,9 @@ public class AdapterInputConnection extends BaseInputConnection { outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT; } outAttrs.initialSelStart = imeAdapter.getInitialSelectionStart(); - outAttrs.initialSelEnd = imeAdapter.getInitialSelectionStart(); + outAttrs.initialSelEnd = imeAdapter.getInitialSelectionEnd(); + mLastUpdateSelectionStart = imeAdapter.getInitialSelectionStart(); + mLastUpdateSelectionEnd = imeAdapter.getInitialSelectionEnd(); } /** @@ -147,7 +148,8 @@ public class AdapterInputConnection extends BaseInputConnection { if (prevSelectionStart == selectionStart && prevSelectionEnd == selectionEnd && prevCompositionStart == compositionStart && prevCompositionEnd == compositionEnd) { - // Nothing has changed; don't need to do anything + if (mIgnoreTextInputStateUpdates) return; + updateSelection(selectionStart, selectionEnd, compositionStart, compositionEnd); return; } @@ -437,4 +439,33 @@ public class AdapterInputConnection extends BaseInputConnection { private InputMethodManagerWrapper getInputMethodManagerWrapper() { return mImeAdapter.getInputMethodManagerWrapper(); } + + @VisibleForTesting + static class ImeState { + public final String text; + public final int selectionStart; + public final int selectionEnd; + public final int compositionStart; + public final int compositionEnd; + + public ImeState(String text, int selectionStart, int selectionEnd, + int compositionStart, int compositionEnd) { + this.text = text; + this.selectionStart = selectionStart; + this.selectionEnd = selectionEnd; + this.compositionStart = compositionStart; + this.compositionEnd = compositionEnd; + } + } + + @VisibleForTesting + ImeState getImeStateForTesting() { + Editable editable = getEditable(); + String text = editable.toString(); + int selectionStart = Selection.getSelectionStart(editable); + int selectionEnd = Selection.getSelectionEnd(editable); + int compositionStart = getComposingSpanStart(editable); + int compositionEnd = getComposingSpanEnd(editable); + return new ImeState(text, selectionStart, selectionEnd, compositionStart, compositionEnd); + } } diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/AdapterInputConnectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/AdapterInputConnectionTest.java new file mode 100644 index 0000000..69be5f86 --- /dev/null +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/AdapterInputConnectionTest.java @@ -0,0 +1,142 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// 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.content.Context; +import android.os.IBinder; +import android.os.ResultReceiver; +import android.test.suitebuilder.annotation.MediumTest; +import android.view.View; +import android.view.inputmethod.EditorInfo; + +import org.chromium.base.test.util.Feature; +import org.chromium.content.browser.input.AdapterInputConnection.ImeState; +import org.chromium.content.browser.input.ImeAdapter.ImeAdapterDelegate; +import org.chromium.content_shell_apk.ContentShellTestBase; + +import java.util.ArrayList; + +/** + * Tests AdapterInputConnection class and its callbacks to ImeAdapter. + */ +public class AdapterInputConnectionTest extends ContentShellTestBase { + + private AdapterInputConnection mConnection; + private TestInputMethodManagerWrapper mWrapper; + + @Override + public void setUp() throws Exception { + super.setUp(); + launchContentShellWithUrl("about:blank"); + assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + mWrapper = new TestInputMethodManagerWrapper(getActivity()); + ImeAdapterDelegate delegate = new TestImeAdapterDelegate(); + ImeAdapter imeAdapter = new TestImeAdapter(mWrapper, delegate); + EditorInfo info = new EditorInfo(); + mConnection = new AdapterInputConnection( + getActivity().getActiveContentView(), imeAdapter, info); + } + + @MediumTest + @Feature({"TextInput", "Main"}) + public void testSetComposingText() throws Throwable { + mConnection.setComposingText("t", 1); + assertCorrectState("t", 1, 1, 0, 1, mConnection.getImeStateForTesting()); + mConnection.setEditableText("t", 1, 1, 0, 1); + mWrapper.verifyUpdateSelectionCall(0, 1, 1, 0 ,1); + + mConnection.setComposingText("te", 1); + assertCorrectState("te", 2, 2, 0, 2, mConnection.getImeStateForTesting()); + mConnection.setEditableText("te", 2, 2, 0, 2); + mWrapper.verifyUpdateSelectionCall(1, 2, 2, 0 ,2); + + mConnection.setComposingText("tes", 1); + assertCorrectState("tes", 3, 3, 0, 3, mConnection.getImeStateForTesting()); + mConnection.setEditableText("tes", 3, 3, 0, 3); + mWrapper.verifyUpdateSelectionCall(2, 3, 3, 0, 3); + + mConnection.setComposingText("test", 1); + assertCorrectState("test", 4, 4, 0, 4, mConnection.getImeStateForTesting()); + mConnection.setEditableText("test", 4, 4, 0, 4); + mWrapper.verifyUpdateSelectionCall(3, 4, 4, 0, 4); + } + + private static class TestImeAdapter extends ImeAdapter { + public TestImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embedder) { + super(wrapper, embedder); + } + } + + private static class TestInputMethodManagerWrapper extends InputMethodManagerWrapper { + private final ArrayList<ImeState> mUpdates = new ArrayList<ImeState>(); + + public TestInputMethodManagerWrapper(Context context) { + super(context); + } + + @Override + public void restartInput(View view) {} + + @Override + public void showSoftInput(View view, int flags, ResultReceiver resultReceiver) {} + + @Override + public boolean isActive(View view) { + return true; + } + + @Override + public boolean hideSoftInputFromWindow(IBinder windowToken, int flags, + ResultReceiver resultReceiver) { + return true; + } + + @Override + public void updateSelection(View view, int selStart, int selEnd, + int candidatesStart, int candidatesEnd) { + mUpdates.add(new ImeState("", selStart, selEnd, candidatesStart, candidatesEnd)); + } + + public void verifyUpdateSelectionCall(int index, int selectionStart, int selectionEnd, + int compositionStart, int compositionEnd) { + ImeState state = mUpdates.get(index); + assertEquals("Selection start did not match", selectionStart, state.selectionStart); + assertEquals("Selection end did not match", selectionEnd, state.selectionEnd); + assertEquals("Composition start did not match", compositionStart, + state.compositionStart); + assertEquals("Composition end did not match", compositionEnd, state.compositionEnd); + } + } + + private static class TestImeAdapterDelegate implements ImeAdapterDelegate { + @Override + public void onImeEvent(boolean isFinish) {} + + @Override + public void onSetFieldValue() {} + + @Override + public void onDismissInput() {} + + @Override + public View getAttachedView() { + return null; + } + + @Override + public ResultReceiver getNewShowKeyboardReceiver() { + return null; + } + } + + private static void assertCorrectState(String text, int selectionStart, int selectionEnd, + int compositionStart, int compositionEnd, ImeState actual) { + assertEquals("Text did not match", text, actual.text); + assertEquals("Selection start did not match", selectionStart, actual.selectionStart); + assertEquals("Selection end did not match", selectionEnd, actual.selectionEnd); + assertEquals("Composition start did not match", compositionStart, actual.compositionStart); + assertEquals("Composition end did not match", compositionEnd, actual.compositionEnd); + } +} diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java index 94cb245..c446207 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -203,15 +203,17 @@ public class ImeTest extends ContentShellTestBase { mConnection.setComposingText("h", 1); waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "h", 1, 1, 0, 1); assertTrue(mConnection.isIgnoringTextInputStateUpdates()); + assertEquals(0, mInputMethodManagerWrapper.getUpdateSelectionCounter()); mConnection.setComposingText("he", 1); waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "he", 2, 2, 0, 2); assertTrue(mConnection.isIgnoringTextInputStateUpdates()); + assertEquals(0, mInputMethodManagerWrapper.getUpdateSelectionCounter()); mConnection.setComposingText("hel", 1); waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "hel", 3, 3, 0, 3); - assertEquals(0, mConnection.mUpdateSelectionCounter); + assertEquals(0, mInputMethodManagerWrapper.getUpdateSelectionCounter()); assertTrue(mConnection.isIgnoringTextInputStateUpdates()); mConnection.endBatchEdit(); assertWaitForSetIgnoreUpdates(false, mConnection); @@ -391,7 +393,6 @@ public class ImeTest extends ContentShellTestBase { } private static class TestAdapterInputConnection extends AdapterInputConnection { - private int mUpdateSelectionCounter = 0; private ArrayList<TestImeState> mImeUpdateQueue = new ArrayList<ImeTest.TestImeState>(); public TestAdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) { @@ -406,13 +407,6 @@ public class ImeTest extends ContentShellTestBase { super.setEditableText( text, selectionStart, selectionEnd, compositionStart, compositionEnd); } - - @Override - protected void updateSelection( - int selectionStart, int selectionEnd, - int compositionStart, int compositionEnd) { - mUpdateSelectionCounter++; - } } private static class TestImeState { diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java index 4f3b5c9a..9826c0f 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java @@ -14,9 +14,10 @@ import org.chromium.content.browser.ContentViewCore; import org.chromium.content.browser.input.InputMethodManagerWrapper; public class TestInputMethodManagerWrapper extends InputMethodManagerWrapper { - private ContentViewCore mContentViewCore; + private final ContentViewCore mContentViewCore; private InputConnection mInputConnection; private int mShowSoftInputCounter = 0; + private int mUpdateSelectionCounter = 0; private EditorInfo mEditorInfo; public TestInputMethodManagerWrapper(ContentViewCore contentViewCore) { @@ -55,12 +56,17 @@ public class TestInputMethodManagerWrapper extends InputMethodManagerWrapper { @Override public void updateSelection(View view, int selStart, int selEnd, int candidatesStart, int candidatesEnd) { + mUpdateSelectionCounter++; } public int getShowSoftInputCounter() { return mShowSoftInputCounter; } + public int getUpdateSelectionCounter() { + return mUpdateSelectionCounter; + } + public EditorInfo getEditorInfo() { return mEditorInfo; } |