Commit 490ccaf2 authored by aurimas@chromium.org's avatar aurimas@chromium.org

Adding IME test changes to make it easier to test.

NOTRY=true


Review URL: https://chromiumcodereview.appspot.com/12262016

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@182344 0039d316-1c4b-4281-b951-d872f2087c98
parent 8838f983
......@@ -44,6 +44,7 @@ import org.chromium.base.JNINamespace;
import org.chromium.base.WeakContext;
import org.chromium.content.R;
import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate;
import org.chromium.content.browser.ImeAdapter.AdapterInputConnectionFactory;
import org.chromium.content.browser.accessibility.AccessibilityInjector;
import org.chromium.content.common.ProcessInitException;
import org.chromium.content.common.TraceEvent;
......@@ -211,6 +212,7 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient {
// Only valid when focused on a text / password field.
private ImeAdapter mImeAdapter;
private ImeAdapter.AdapterInputConnectionFactory mAdapterInputConnectionFactory;
private ImeAdapter.AdapterInputConnection mInputConnection;
private SelectionHandleController mSelectionHandleController;
......@@ -285,6 +287,7 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient {
WeakContext.initializeWeakContext(context);
mPersonality = personality;
HeapStatsLogger.init(mContext.getApplicationContext());
mAdapterInputConnectionFactory = new AdapterInputConnectionFactory();
}
/**
......@@ -332,6 +335,11 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient {
return mImeAdapter;
}
@VisibleForTesting
protected void setAdapterInputConnectionFactory(AdapterInputConnectionFactory factory) {
mAdapterInputConnectionFactory = factory;
}
@VisibleForTesting
protected ImeAdapter.AdapterInputConnection getInputConnectionForTest() {
return mInputConnection;
......@@ -1227,8 +1235,8 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient {
// enter fullscreen mode.
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
}
mInputConnection = ImeAdapter.AdapterInputConnection.getInstance(
mContainerView, mImeAdapter, outAttrs);
mInputConnection =
mAdapterInputConnectionFactory.get(mContainerView, mImeAdapter, outAttrs);
return mInputConnection;
}
......
......@@ -280,7 +280,8 @@ class ImeAdapter {
}
}
private boolean checkCompositionQueueAndCallNative(String text, int newCursorPosition,
@VisibleForTesting
boolean checkCompositionQueueAndCallNative(String text, int newCursorPosition,
boolean isCommit) {
if (mNativeImeAdapterAndroid == 0) {
return false;
......@@ -461,20 +462,21 @@ class ImeAdapter {
return true;
}
public static class AdapterInputConnectionFactory {
public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
EditorInfo outAttrs) {
return new AdapterInputConnection(view, imeAdapter, outAttrs);
}
}
// This InputConnection is created by ContentView.onCreateInputConnection.
// It then adapts android's IME to chrome's RenderWidgetHostView using the
// native ImeAdapterAndroid via the outer class ImeAdapter.
static public class AdapterInputConnection extends BaseInputConnection {
public static class AdapterInputConnection extends BaseInputConnection {
private View mInternalView;
private ImeAdapter mImeAdapter;
private boolean mSingleLine;
// Factory function.
static public AdapterInputConnection getInstance(View view, ImeAdapter imeAdapter,
EditorInfo outAttrs) {
return new AdapterInputConnection(view, imeAdapter, outAttrs);
}
/**
* Updates the AdapterInputConnection's internal representation of the text
* being edited and its selection and composition properties. The resulting
......@@ -522,7 +524,6 @@ class ImeAdapter {
}
Selection.setSelection(editable, selectionStart, selectionEnd);
super.setComposingRegion(compositionStart, compositionEnd);
if (textUnchanged || prevText.equals("")) {
// updateSelection should be called when a manual selection change occurs.
// Should not be called if text is being entered else issues can occur
......@@ -685,7 +686,8 @@ class ImeAdapter {
.getSystemService(Context.INPUT_METHOD_SERVICE);
}
private AdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
@VisibleForTesting
protected AdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
super(view, true);
mInternalView = view;
mImeAdapter = imeAdapter;
......
......@@ -5,9 +5,15 @@
package org.chromium.content.browser;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.content.browser.ImeAdapter.AdapterInputConnection;
import org.chromium.content.browser.ImeAdapter.AdapterInputConnectionFactory;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
......@@ -17,31 +23,132 @@ import org.chromium.content_shell.ContentShellTestBase;
public class ImeTest extends ContentShellTestBase {
private static final String DATA_URL =
"data:text/html;utf-8,<html><body>" +
private static final String DATA_URL = UrlUtils.encodeHtmlDataUri(
"<html><body>" +
"<form action=\"about:blank\">" +
"<input id=\"input_text\" type=\"text\" />" +
"</body></html>";
"</form></body></html>");
/*
@MediumTest
@Feature({"TextInput", "Main"})
*/
@DisabledTest
public void testKeyboardDismissedAfterClickingGo() throws Throwable {
launchContentShellWithUrl(DATA_URL);
assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
getContentViewCore().setAdapterInputConnectionFactory(
new TestAdapterInputConnectionFactory());
final ContentView view = getActivity().getActiveContentView();
final TestCallbackHelperContainer viewClient =
new TestCallbackHelperContainer(view);
DOMUtils.clickNode(this, view, viewClient, "input_text");
assertWaitForKeyboardStatus(true);
TestAdapterInputConnection connection =
(TestAdapterInputConnection) getAdapterInputConnection();
ImeAdapter adapter = getImeAdapter();
assertWaitForSetEditableCallback(1, connection);
assertEquals("", connection.mText);
assertEquals(0, connection.mSelectionStart);
assertEquals(0, connection.mSelectionEnd);
assertEquals(-1, connection.mCompositionStart);
assertEquals(-1, connection.mCompositionEnd);
adapter.checkCompositionQueueAndCallNative("hello", 1, false);
assertWaitForSetEditableCallback(2, connection);
assertEquals("hello", connection.mText);
assertEquals(5, connection.mSelectionStart);
assertEquals(5, connection.mSelectionEnd);
assertEquals(0, connection.mCompositionStart);
assertEquals(5, connection.mCompositionEnd);
performGo(getAdapterInputConnection(), viewClient);
assertWaitForSetEditableCallback(3, connection);
assertEquals("", connection.mText);
assertEquals(0, connection.mSelectionStart);
assertEquals(0, connection.mSelectionEnd);
assertEquals(-1, connection.mCompositionStart);
assertEquals(-1, connection.mCompositionEnd);
assertWaitForKeyboardStatus(true);
}
/*
@SmallTest
@Feature({"TextInput", "Main"})
*/
@DisabledTest
public void testGetTextUpdatesAfterEnteringText() throws Throwable {
launchContentShellWithUrl(DATA_URL);
assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
getContentViewCore().setAdapterInputConnectionFactory(
new TestAdapterInputConnectionFactory());
final ContentView view = getActivity().getActiveContentView();
final TestCallbackHelperContainer viewClient =
new TestCallbackHelperContainer(view);
DOMUtils.clickNode(this, view, viewClient, "input_text");
assertWaitForKeyboardStatus(true);
getAdapterInputConnection().setComposingText("hello", 5);
getAdapterInputConnection().performEditorAction(EditorInfo.IME_ACTION_GO);
TestAdapterInputConnection connection =
(TestAdapterInputConnection) getAdapterInputConnection();
ImeAdapter adapter = getImeAdapter();
// Since hiding the keyboard is an asynchronous task, it might take an arbitrary amount
// of time. settleDownUI will wait for one second and hopefully allowing the keyboard to
// get to it's final state.
UiUtils.settleDownUI(getInstrumentation());
assertWaitForKeyboardStatus(false);
assertWaitForSetEditableCallback(1, connection);
assertEquals("", connection.mText);
assertEquals(0, connection.mSelectionStart);
assertEquals(0, connection.mSelectionEnd);
assertEquals(-1, connection.mCompositionStart);
assertEquals(-1, connection.mCompositionEnd);
adapter.checkCompositionQueueAndCallNative("h", 1, false);
assertWaitForSetEditableCallback(2, connection);
assertEquals("h", connection.mText);
assertEquals(1, connection.mSelectionStart);
assertEquals(1, connection.mSelectionEnd);
assertEquals(0, connection.mCompositionStart);
assertEquals(1, connection.mCompositionEnd);
adapter.checkCompositionQueueAndCallNative("he", 1, false);
assertWaitForSetEditableCallback(3, connection);
assertEquals("he", connection.mText);
assertEquals(2, connection.mSelectionStart);
assertEquals(2, connection.mSelectionEnd);
assertEquals(0, connection.mCompositionStart);
assertEquals(2, connection.mCompositionEnd);
adapter.checkCompositionQueueAndCallNative("hel", 1, false);
assertWaitForSetEditableCallback(4, connection);
assertEquals("hel", connection.mText);
assertEquals(3, connection.mSelectionStart);
assertEquals(3, connection.mSelectionEnd);
assertEquals(0, connection.mCompositionStart);
assertEquals(3, connection.mCompositionEnd);
adapter.checkCompositionQueueAndCallNative("hel", 1, true);
assertWaitForSetEditableCallback(5, connection);
assertEquals("hel", connection.mText);
assertEquals(3, connection.mSelectionStart);
assertEquals(3, connection.mSelectionEnd);
assertEquals(-1, connection.mCompositionStart);
assertEquals(-1, connection.mCompositionEnd);
}
private void performGo(final AdapterInputConnection inputConnection,
TestCallbackHelperContainer testCallbackHelperContainer) throws Throwable {
handleBlockingCallbackAction(
testCallbackHelperContainer.getOnPageFinishedHelper(),
new Runnable() {
@Override
public void run() {
inputConnection.performEditorAction(EditorInfo.IME_ACTION_GO);
}
});
}
private void assertWaitForKeyboardStatus(final boolean show) throws Throwable {
......@@ -53,6 +160,16 @@ public class ImeTest extends ContentShellTestBase {
}));
}
private void assertWaitForSetEditableCallback(final int callbackNumber,
final TestAdapterInputConnection connection) throws Throwable {
assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
@Override
public boolean isSatisfied() {
return callbackNumber == connection.mSetEditableTextCallCounter;
}
}));
}
private ImeAdapter getImeAdapter() {
return getContentViewCore().getImeAdapterForTest();
}
......@@ -60,4 +177,38 @@ public class ImeTest extends ContentShellTestBase {
private ImeAdapter.AdapterInputConnection getAdapterInputConnection() {
return getContentViewCore().getInputConnectionForTest();
}
private static class TestAdapterInputConnectionFactory extends
ImeAdapter.AdapterInputConnectionFactory {
@Override
public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
EditorInfo outAttrs) {
return new TestAdapterInputConnection(view, imeAdapter, outAttrs);
}
}
private static class TestAdapterInputConnection extends ImeAdapter.AdapterInputConnection {
private int mSetEditableTextCallCounter;
private String mText;
private int mSelectionStart;
private int mSelectionEnd;
private int mCompositionStart;
private int mCompositionEnd;
public TestAdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
super(view, imeAdapter, outAttrs);
mSetEditableTextCallCounter = 0;
}
@Override
public void setEditableText(String text, int selectionStart, int selectionEnd,
int compositionStart, int compositionEnd) {
mText = text;
mSelectionStart = selectionStart;
mSelectionEnd = selectionEnd;
mCompositionStart = compositionStart;
mCompositionEnd = compositionEnd;
mSetEditableTextCallCounter++;
}
}
}
......@@ -146,6 +146,9 @@ public class Shell extends LinearLayout {
mContentView.loadUrl(new LoadUrlParams(sanitizeUrl(url)));
}
mUrlTextView.clearFocus();
// TODO(aurimas): Remove this when crbug.com/174541 is fixed.
mContentView.clearFocus();
mContentView.requestFocus();
}
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment