Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(925)

Unified Diff: content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java

Issue 699333003: Support InputMethodManager#updateCursorAnchorInfo for Android 5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase before splitting this CL. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..be18a330291ffab6a21ac6ade56d20c9ed68176b
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java
@@ -0,0 +1,576 @@
+// Copyright 2014 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.graphics.Matrix;
+import android.graphics.RectF;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
+import android.view.View;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.RenderCoordinates;
+import org.chromium.content.browser.test.util.TestCursorAnchorInfoWrapper;
+import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper;
+
+/**
+ * Test for {@link CursorAnchorInfoController}.
+ */
+public class CursorAnchorInfoControllerTest extends InstrumentationTestCase {
+
+ public static final int CURSOR_UPDATE_IMMEDIATE = 1 << 0;
+ public static final int CURSOR_UPDATE_MONITOR = 1 << 1;
+
+ private static RenderCoordinates createRenderCoordinates(float deviceScaleFactor,
+ float pageScaleFactor, float scrollXCss, float scrollYCss, float contentOffsetYPix) {
+ RenderCoordinates renderCoordinates = new RenderCoordinates();
+ renderCoordinates.setFrameInfoForTest(deviceScaleFactor, pageScaleFactor, scrollXCss,
+ scrollYCss, contentOffsetYPix);
+ return renderCoordinates;
+ }
+
+ private static final class TestViewDelegate implements CursorAnchorInfoController.ViewDelegate {
+ public int mLocationX;
+ public int mLocationY;
+ @Override
+ public void getLocationOnScreen(View view, int[] location) {
+ location[0] = mLocationX;
+ location[1] = mLocationY;
+ }
+ }
+
+ private void assertScaleAndTranslate(float expectedScale, float expectedTranslateX,
+ float expectedTranslateY, CursorAnchorInfoWrapper actual) {
+ Matrix expectedMatrix = new Matrix();
+ expectedMatrix.setScale(expectedScale, expectedScale);
+ expectedMatrix.postTranslate(expectedTranslateX, expectedTranslateY);
+ float[] expectedMatrixValues = new float[12];
+ expectedMatrix.getValues(expectedMatrixValues);
+ float[] actualMatrixValues = new float[12];
+ actual.getMatrix().getValues(actualMatrixValues);
+ for (int i = 0; i < expectedMatrixValues.length; ++i) {
+ assertEquals(expectedMatrixValues[i], actualMatrixValues[i]);
+ }
+ }
+
+ private void assertHasInsertionMarker(int expectedFlags, float expectedHorizontal,
+ float expectedTop, float expectedBaseline, float expectedBottom,
+ CursorAnchorInfoWrapper actual) {
+ assertEquals(expectedFlags, actual.getInsertionMarkerFlags());
+ assertEquals(expectedHorizontal, actual.getInsertionMarkerHorizontal());
+ assertEquals(expectedTop, actual.getInsertionMarkerTop());
+ assertEquals(expectedBaseline, actual.getInsertionMarkerBaseline());
+ assertEquals(expectedBottom, actual.getInsertionMarkerBottom());
+ }
+
+ private void assertHasNoInsertionMarker(CursorAnchorInfoWrapper actual) {
+ assertEquals(0, actual.getInsertionMarkerFlags());
+ assertTrue(Float.isNaN(actual.getInsertionMarkerHorizontal()));
+ assertTrue(Float.isNaN(actual.getInsertionMarkerTop()));
+ assertTrue(Float.isNaN(actual.getInsertionMarkerBaseline()));
+ assertTrue(Float.isNaN(actual.getInsertionMarkerBottom()));
+ }
+
+ private void assertComposingText(CharSequence expectedComposingText,
+ int expectedComposingTextStart, CursorAnchorInfoWrapper actual) {
+ assertTrue(TextUtils.equals(expectedComposingText, actual.getComposingText()));
+ assertEquals(expectedComposingTextStart, actual.getComposingTextStart());
+ }
+
+ private void assertSelection(int expecteSelectionStart, int expecteSelectionEnd,
+ CursorAnchorInfoWrapper actual) {
+ assertEquals(expecteSelectionStart, actual.getSelectionStart());
+ assertEquals(expecteSelectionEnd, actual.getSelectionEnd());
+ }
+
+ private void assertEquals(RectF expectedRect, RectF actualRect) {
+ if (expectedRect == null) {
+ assertNull(actualRect);
+ return;
+ }
+ assertNotNull(actualRect);
+ assertEquals(actualRect.left, expectedRect.left);
+ assertEquals(actualRect.top, expectedRect.top);
+ assertEquals(actualRect.right, expectedRect.right);
+ assertEquals(actualRect.bottom, expectedRect.bottom);
+ }
+
+ @SmallTest
+ @Feature({"Input-Text-IME"})
+ public void testFocusedNodeChanged() {
+ TestInputMethodManagerWrapper immw =
+ new TestInputMethodManagerWrapper(null);
+ TestViewDelegate viewDelegate = new TestViewDelegate();
+ TestCursorAnchorInfoWrapper.Builder builder = new TestCursorAnchorInfoWrapper.Builder();
+ CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+ immw, builder, viewDelegate);
+ View view = null;
+
+ viewDelegate.mLocationX = 0;
+ viewDelegate.mLocationY = 0;
+
+ assertFalse(
+ "IC#onRequestCursorUpdates() must be rejected if the focused node is not editable.",
+ controller.onRequestCursorUpdates(CURSOR_UPDATE_MONITOR, view));
+
+ // Make sure that the focused node is considered to be non-editable by default.
+ controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3.0f});
+ controller.updateTextAndSelection("0", 0, 1, 0, 1);
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(0, immw.getUpdateCursorAnchorInfoCounter());
+
+ controller.focusedNodeChanged(false);
+
+ // Make sure that the controller does not crash even if it is called while the focused node
+ // is not editable.
+ controller.setCompositionCharacterBounds(new float[]{30.0f, 1.0f, 32.0f, 3.0f});
+ controller.updateTextAndSelection("1", 0, 1, 0, 1);
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 2.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(0, immw.getUpdateCursorAnchorInfoCounter());
+ }
+
+ @SmallTest
+ @Feature({"Input-Text-IME"})
+ public void testImmediateMode() {
+ TestInputMethodManagerWrapper immw =
+ new TestInputMethodManagerWrapper(null);
+ TestViewDelegate viewDelegate = new TestViewDelegate();
+ TestCursorAnchorInfoWrapper.Builder builder = new TestCursorAnchorInfoWrapper.Builder();
+ CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+ immw, builder, viewDelegate);
+ View view = null;
+ viewDelegate.mLocationX = 0;
+ viewDelegate.mLocationY = 0;
+
+ controller.focusedNodeChanged(true);
+
+ // Make sure that #updateCursorAnchorInfo() is not be called until the matrix info becomes
+ // available with #onUpdateFrameInfo().
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_IMMEDIATE, view));
+ controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3.0f});
+ controller.updateTextAndSelection("0", 0, 1, 0, 1);
+ assertEquals(0, immw.getUpdateCursorAnchorInfoCounter());
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("0", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Make sure that 2nd call of #onUpdateFrameInfo() is ignored.
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 2.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+
+ // Make sure that #onUpdateFrameInfo() is immediately called because the matrix info is
+ // already available.
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_IMMEDIATE, view));
+ assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("0", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Make sure that CURSOR_UPDATE_IMMEDIATE and CURSOR_UPDATE_MONITOR can be specified at
+ // the same time.
+ assertTrue(controller.onRequestCursorUpdates(
+ CURSOR_UPDATE_IMMEDIATE | CURSOR_UPDATE_MONITOR, view));
+ assertEquals(3, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(4, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("0", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Make sure that CURSOR_UPDATE_IMMEDIATE is cleared if the focused node becomes
+ // non-editable.
+ controller.focusedNodeChanged(false);
+ controller.focusedNodeChanged(true);
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_IMMEDIATE, view));
+ controller.focusedNodeChanged(false);
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 2.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(4, immw.getUpdateCursorAnchorInfoCounter());
+
+ // Make sure that CURSOR_UPDATE_IMMEDIATE can be enabled again.
+ controller.focusedNodeChanged(true);
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_IMMEDIATE, view));
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(null, immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(0, immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText(null, -1, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(-1, -1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+ }
+
+ @SmallTest
+ @Feature({"Input-Text-IME"})
+ public void testMonitorMode() {
+ TestInputMethodManagerWrapper immw =
+ new TestInputMethodManagerWrapper(null);
+ TestViewDelegate viewDelegate = new TestViewDelegate();
+ TestCursorAnchorInfoWrapper.Builder builder = new TestCursorAnchorInfoWrapper.Builder();
+ CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+ immw, builder, viewDelegate);
+ View view = null;
+ viewDelegate.mLocationX = 0;
+ viewDelegate.mLocationY = 0;
+
+ controller.focusedNodeChanged(true);
+
+ // Make sure that #updateCursorAnchorInfo() is not be called until the matrix info becomes
+ // available with #onUpdateFrameInfo().
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_MONITOR, view));
+ controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3.0f});
+ controller.updateTextAndSelection("0", 0, 1, 0, 1);
+ assertEquals(0, immw.getUpdateCursorAnchorInfoCounter());
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("0", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Make sure that #updateCursorAnchorInfo() is not be called if any parameter is changed
+ // for better performance.
+ controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3.0f});
+ controller.updateTextAndSelection("0", 0, 1, 0, 1);
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+
+ // Make sure that #updateCursorAnchorInfo() is called if #setCompositionCharacterBounds()
+ // is called with a different parameter.
+ controller.setCompositionCharacterBounds(new float[]{30.0f, 1.0f, 32.0f, 3.0f});
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("0", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Make sure that #updateCursorAnchorInfo() is called if #updateTextAndSelection()
+ // is called with a different parameter.
+ controller.updateTextAndSelection("1", 0, 1, 0, 1);
+ assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(3, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("1", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Make sure that #updateCursorAnchorInfo() is called if #onUpdateFrameInfo()
+ // is called with a different parameter.
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 2.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(4, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("1", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Make sure that #updateCursorAnchorInfo() is called when the view origin is changed.
+ viewDelegate.mLocationX = 7;
+ viewDelegate.mLocationY = 9;
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 2.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(2.0f, 7.0f, 9.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("1", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Make sure that CURSOR_UPDATE_IMMEDIATE is cleared if the focused node becomes
+ // non-editable.
+ controller.focusedNodeChanged(false);
+ controller.focusedNodeChanged(true);
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_MONITOR, view));
+ controller.focusedNodeChanged(false);
+ controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3.0f});
+ controller.updateTextAndSelection("0", 0, 1, 0, 1);
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+
+ // Make sure that CURSOR_UPDATE_MONITOR can be enabled again.
+ controller.focusedNodeChanged(true);
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_MONITOR, view));
+ controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3.0f});
+ controller.updateTextAndSelection("0", 0, 1, 0, 1);
+ assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+ viewDelegate.mLocationX = 0;
+ viewDelegate.mLocationY = 0;
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 2.0f, 0.0f, 3.0f, view);
+ assertEquals(6, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+ 3.0f, immw.getLastCursorAnchorInfoWrapper());
+ assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertComposingText("0", 0, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(0, 1, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+ }
+
+ @SmallTest
+ @Feature({"Input-Text-IME"})
+ public void testSetCompositionCharacterBounds() {
+ TestInputMethodManagerWrapper immw =
+ new TestInputMethodManagerWrapper(null);
+ TestViewDelegate viewDelegate = new TestViewDelegate();
+ TestCursorAnchorInfoWrapper.Builder builder = new TestCursorAnchorInfoWrapper.Builder();
+ CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+ immw, builder, viewDelegate);
+ View view = null;
+
+ viewDelegate.mLocationX = 0;
+ viewDelegate.mLocationY = 0;
+
+ controller.focusedNodeChanged(true);
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_MONITOR, view));
+
+ controller.updateTextAndSelection("01234", 1, 3, 1, 1);
+ controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3.0f,
+ 4.0f, 1.1f, 6.0f, 2.9f});
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+ assertEquals(null, immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(0, immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(1));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(1));
+ assertEquals(new RectF(4.0f, 1.1f, 6.0f, 2.9f),
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(2));
+ assertEquals(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(2));
+ assertEquals(null, immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(3));
+ assertEquals(0, immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(3));
+ assertComposingText("12", 1, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(1, 1, immw.getLastCursorAnchorInfoWrapper());
+ }
+
+ @SmallTest
+ @Feature({"Input-Text-IME"})
+ public void testUpdateTextAndSelection() {
+ TestInputMethodManagerWrapper immw =
+ new TestInputMethodManagerWrapper(null);
+ TestViewDelegate viewDelegate = new TestViewDelegate();
+ TestCursorAnchorInfoWrapper.Builder builder = new TestCursorAnchorInfoWrapper.Builder();
+ CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+ immw, builder, viewDelegate);
+ View view = null;
+
+ viewDelegate.mLocationX = 0;
+ viewDelegate.mLocationY = 0;
+
+ controller.focusedNodeChanged(true);
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_MONITOR, view));
+
+ controller.updateTextAndSelection("01234", 3, 3, 1, 1);
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+ assertEquals(null, immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(0));
+ assertEquals(0, immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(0));
+ assertEquals(null, immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(1));
+ assertEquals(0, immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(1));
+ assertEquals(null, immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(2));
+ assertEquals(0, immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(2));
+ assertEquals(null, immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(3));
+ assertEquals(0, immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(3));
+ assertEquals(null, immw.getLastCursorAnchorInfoWrapper().getCharacterBounds(4));
+ assertEquals(0, immw.getLastCursorAnchorInfoWrapper().getCharacterBoundsFlags(4));
+ assertComposingText("", 3, immw.getLastCursorAnchorInfoWrapper());
+ assertSelection(1, 1, immw.getLastCursorAnchorInfoWrapper());
+ }
+
+ @SmallTest
+ @Feature({"Input-Text-IME"})
+ public void testInsertionMarker() {
+ TestInputMethodManagerWrapper immw =
+ new TestInputMethodManagerWrapper(null);
+ TestViewDelegate viewDelegate = new TestViewDelegate();
+ TestCursorAnchorInfoWrapper.Builder builder = new TestCursorAnchorInfoWrapper.Builder();
+ CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+ immw, builder, viewDelegate);
+ View view = null;
+
+ controller.focusedNodeChanged(true);
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_MONITOR, view));
+
+ // Test no insertion marker.
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+ assertHasNoInsertionMarker(immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Test a visible insertion marker.
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, true, 10.0f, 23.0f, 29.0f, view);
+ assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_VISIBLE_REGION,
+ 10.0f, 23.0f, 29.0f, 29.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // Test a invisible insertion marker.
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ true, false, 10.0f, 23.0f, 29.0f, view);
+ assertEquals(3, immw.getUpdateCursorAnchorInfoCounter());
+ assertHasInsertionMarker(CursorAnchorInfoWrapper.FLAG_HAS_INVISIBLE_REGION,
+ 10.0f, 23.0f, 29.0f, 29.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+ }
+
+ @SmallTest
+ @Feature({"Input-Text-IME"})
+ public void testMatrix() {
+ TestInputMethodManagerWrapper immw =
+ new TestInputMethodManagerWrapper(null);
+ TestViewDelegate viewDelegate = new TestViewDelegate();
+ TestCursorAnchorInfoWrapper.Builder builder = new TestCursorAnchorInfoWrapper.Builder();
+ CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+ immw, builder, viewDelegate);
+ View view = null;
+
+ controller.focusedNodeChanged(true);
+ assertTrue(controller.onRequestCursorUpdates(CURSOR_UPDATE_MONITOR, view));
+
+ // Test no transformation
+ viewDelegate.mLocationX = 0;
+ viewDelegate.mLocationY = 0;
+ controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // device scale factor == 2.0
+ viewDelegate.mLocationX = 0;
+ viewDelegate.mLocationY = 0;
+ controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // device scale factor == 2.0
+ // view origin == (10, 141)
+ viewDelegate.mLocationX = 10;
+ viewDelegate.mLocationY = 141;
+ controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 1.0f, 0.0f, 0.0f, 0.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(3, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(2.0f, 10.0f, 141.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // device scale factor == 2.0
+ // root scroll offset == (1.0f, 2.0f)
+ // view origin == (10, 141)
+ viewDelegate.mLocationX = 10;
+ viewDelegate.mLocationY = 141;
+ controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 1.0f, 1.0f, 2.0f, 0.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(4, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(2.0f, 8.0f, 137.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // device scale factor == 2.0
+ // page scale factor == 3.0f
+ // root scroll offset == (1.0f, 2.0f)
+ // view origin == (10, 141)
+ viewDelegate.mLocationX = 10;
+ viewDelegate.mLocationY = 141;
+ controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 3.0f, 1.0f, 2.0f, 0.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(6.0f, 4.0f, 129.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+
+ // device scale factor == 2.0
+ // page scale factor == 3.0f
+ // root scroll offset == (1.0f, 2.0f)
+ // content offset Y = 40.0f
+ // view origin == (10, 141)
+ viewDelegate.mLocationX = 10;
+ viewDelegate.mLocationY = 141;
+ controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 3.0f, 1.0f, 2.0f, 40.0f),
+ false, false, Float.NaN, Float.NaN, Float.NaN, view);
+ assertEquals(6, immw.getUpdateCursorAnchorInfoCounter());
+ assertScaleAndTranslate(6.0f, 4.0f, 169.0f, immw.getLastCursorAnchorInfoWrapper());
+ immw.clearLastCursorAnchorInfoWrapper();
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698