diff options
author | aurimas@chromium.org <aurimas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-20 19:21:54 +0000 |
---|---|---|
committer | aurimas@chromium.org <aurimas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-20 19:21:54 +0000 |
commit | cb0ce4d2ed4b5a81acd27f3bf2664551f7a5ef15 (patch) | |
tree | 5745f8f6f924699d22f091a8dabf2885d5d634ca /content | |
parent | 72a5b010a2394f092399d7d2bc566f1c2c0012a1 (diff) | |
download | chromium_src-cb0ce4d2ed4b5a81acd27f3bf2664551f7a5ef15.zip chromium_src-cb0ce4d2ed4b5a81acd27f3bf2664551f7a5ef15.tar.gz chromium_src-cb0ce4d2ed4b5a81acd27f3bf2664551f7a5ef15.tar.bz2 |
Fixing UpdateSelection issue and adding AdapterInputConnection tests.
AdapterInputConnection is not following Android IME API
http://developer.android.com/reference/android/view/inputmethod/InputConnection.html#setComposingText(java.lang.CharSequence, int)
updateSelection must be called on selection changes. Since we do not call updateSelection before passing this IME event to WebKit, we need to make the call when we get the update back from WebKit.
Fixing ImeTest#testUpdatesGetIgnoredDuringBatchEdits()
Adding AdapterInputConnection#setComposition() test.
TestAdapterInputConnection will eventually test entire AdapterInputConnection.
BUG=286348
Review URL: https://chromiumcodereview.appspot.com/23600066
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@224445 0039d316-1c4b-4281-b951-d872f2087c98
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; } |