1223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki/*
2223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * Copyright (C) 2015 The Android Open Source Project
3223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki *
4223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * Licensed under the Apache License, Version 2.0 (the "License");
5223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * you may not use this file except in compliance with the License.
6223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * You may obtain a copy of the License at
7223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki *
8223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki *      http://www.apache.org/licenses/LICENSE-2.0
9223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki *
10223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * Unless required by applicable law or agreed to in writing, software
11223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * distributed under the License is distributed on an "AS IS" BASIS,
12223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * See the License for the specific language governing permissions and
14223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * limitations under the License
15223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki */
16223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki
17223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokipackage android.widget;
18223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki
19987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinirimport static android.support.test.espresso.action.ViewActions.longClick;
20d42cb8ffa77266abe3bcffe98212d313d223a86cKeisuke Kuroyanagiimport static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles;
21d42cb8ffa77266abe3bcffe98212d313d223a86cKeisuke Kuroyanagiimport static android.widget.espresso.DragHandleUtils.onHandleView;
2290cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Tokiimport static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
23ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Tokiimport static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
248a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Tokiimport static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex;
25da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagiimport static android.widget.espresso.TextViewActions.dragHandle;
26da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagiimport static android.widget.espresso.TextViewActions.Handle;
27ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Tokiimport static android.widget.espresso.TextViewActions.longPressAndDragOnText;
288a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Tokiimport static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
298a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Tokiimport static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
30ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Tokiimport static android.widget.espresso.TextViewAssertions.hasSelection;
318a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Tokiimport static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed;
32b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagiimport static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsNotDisplayed;
33b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagiimport static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem;
34b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagiimport static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarDoesNotContainItem;
3531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.widget.espresso.FloatingToolbarEspressoUtils.clickFloatingToolbarItem;
3631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup;
37223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport static android.support.test.espresso.Espresso.onView;
38223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport static android.support.test.espresso.action.ViewActions.click;
3990cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Tokiimport static android.support.test.espresso.action.ViewActions.pressKey;
4026454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagiimport static android.support.test.espresso.action.ViewActions.replaceText;
41223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView;
42223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport static android.support.test.espresso.assertion.ViewAssertions.matches;
43fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Tokiimport static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
44223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport static android.support.test.espresso.matcher.ViewMatchers.withId;
45223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport static android.support.test.espresso.matcher.ViewMatchers.withText;
46223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki
47223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport com.android.frameworks.coretests.R;
48223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki
49fae4578311970afadca8ee28a47e1e11df00eeddKeisuke Kuroyanagiimport android.support.test.espresso.action.EspressoKey;
50223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport android.test.ActivityInstrumentationTestCase2;
51223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokiimport android.test.suitebuilder.annotation.SmallTest;
52c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagiimport android.text.Selection;
53c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagiimport android.text.Spannable;
54987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinirimport android.text.InputType;
5590cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Tokiimport android.view.KeyEvent;
56223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki
57e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagiimport static org.hamcrest.Matchers.anyOf;
58e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagiimport static org.hamcrest.Matchers.is;
59e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi
60223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki/**
61223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki * Tests the TextView widget from an Activity
62223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki */
63223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Tokipublic class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextViewActivity>{
64223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki
65223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki    public TextViewActivityTest() {
66223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki        super(TextViewActivity.class);
67223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki    }
68223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki
69c9e924eb5347872aeec64ed09d1793ac8483ea10Abodunrinwa Toki    @Override
7031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi    public void setUp() throws Exception {
7131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi        super.setUp();
72e36c7112e7c48f3c8964f95a2a489d25504356b0Abodunrinwa Toki        getActivity();
73c9e924eb5347872aeec64ed09d1793ac8483ea10Abodunrinwa Toki    }
74c9e924eb5347872aeec64ed09d1793ac8483ea10Abodunrinwa Toki
75223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki    @SmallTest
76223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki    public void testTypedTextIsOnScreen() throws Exception {
77223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki        final String helloWorld = "Hello world!";
78223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
79223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
80223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki
81223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki        onView(withId(R.id.textview)).check(matches(withText(helloWorld)));
82223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki    }
8390cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki
8490cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki    @SmallTest
8590cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki    public void testPositionCursorAtTextAtIndex() throws Exception {
8690cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki        final String helloWorld = "Hello world!";
878a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
8890cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
8990cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("world")));
9090cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki
9190cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki        // Delete text at specified index and see if we got the right one.
9290cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki        onView(withId(R.id.textview)).perform(pressKey(KeyEvent.KEYCODE_FORWARD_DEL));
9390cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki        onView(withId(R.id.textview)).check(matches(withText("Hello orld!")));
9490cdfe0514154bbc008d39f1c99f7a1d2684446cAbodunrinwa Toki    }
95ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki
96ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki    @SmallTest
97e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi    public void testPositionCursorAtTextAtIndex_arabic() throws Exception {
98e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        // Arabic text. The expected cursorable boundary is
99e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        // | \u0623 \u064F | \u067A | \u0633 \u0652 |
100e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        final String text = "\u0623\u064F\u067A\u0633\u0652";
101e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
102e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(replaceText(text));
103e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi
104e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(0));
105e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
106e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(1));
107e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(0), is(2))));
108e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(2));
109e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2));
110e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(3));
111e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(3));
112e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(4));
113e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(3), is(5))));
114e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(5));
115e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(5));
116e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi    }
117e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi
118e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi    @SmallTest
119e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi    public void testPositionCursorAtTextAtIndex_devanagari() throws Exception {
120e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        // Devanagari text. The expected cursorable boundary is | \u0915 \u093E |
121e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        final String text = "\u0915\u093E";
122e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
123e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(replaceText(text));
124e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi
125e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(0));
126e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
127e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(1));
128e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(0), is(2))));
129e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(2));
130e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2));
131e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi    }
132e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi
133e27e0850fe4acbdc911e2e4e6272be10ac2f2779Keisuke Kuroyanagi    @SmallTest
1348a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    public void testLongPressToSelect() throws Exception {
1358a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        final String helloWorld = "Hello Kirk!";
1368a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
1378a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
1388a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(
1398a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki                longPressOnTextAtIndex(helloWorld.indexOf("Kirk")));
1408a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
1418a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).check(hasSelection("Kirk"));
1428a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    }
1438a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
1448a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    @SmallTest
1458a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    public void testLongPressEmptySpace() throws Exception {
1468a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        final String helloWorld = "Hello big round sun!";
1478a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
1488a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
1498a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        // Move cursor somewhere else
1508a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("big")));
1518a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        // Long-press at end of line.
1528a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(helloWorld.length()));
1538a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
1548a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(helloWorld.length()));
1558a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    }
1568a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
1578a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    @SmallTest
158ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki    public void testLongPressAndDragToSelect() throws Exception {
159ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki        final String helloWorld = "Hello little handsome boy!";
1608a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
161ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
162ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(
163ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki                longPressAndDragOnText(helloWorld.indexOf("little"), helloWorld.indexOf(" boy!")));
164ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki
165ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki        onView(withId(R.id.textview)).check(hasSelection("little handsome"));
166ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki    }
167ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki
168ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki    @SmallTest
1694307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi    public void testDragAndDrop() throws Exception {
1704307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        final String text = "abc def ghi.";
1714307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
1724307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
1734307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("e")));
1744307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi
1754307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(
1764307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi                longPressAndDragOnText(text.indexOf("e"), text.length()));
1774307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi
1784307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(matches(withText("abc ghi.def")));
1794307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection(""));
1804307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        assertNoSelectionHandles();
1814307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length()));
182fae4578311970afadca8ee28a47e1e11df00eeddKeisuke Kuroyanagi
183fae4578311970afadca8ee28a47e1e11df00eeddKeisuke Kuroyanagi        // Test undo returns to the original state.
184fae4578311970afadca8ee28a47e1e11df00eeddKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(pressKey(
185fae4578311970afadca8ee28a47e1e11df00eeddKeisuke Kuroyanagi                (new EspressoKey.Builder()).withCtrlPressed(true).withKeyCode(KeyEvent.KEYCODE_Z)
186fae4578311970afadca8ee28a47e1e11df00eeddKeisuke Kuroyanagi                        .build()));
187fae4578311970afadca8ee28a47e1e11df00eeddKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(matches(withText(text)));
1884307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi    }
1894307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi
1904307aeb935ab9c824f90d41bf181660c3937b1e4Keisuke Kuroyanagi    @SmallTest
1918a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    public void testDoubleTapToSelect() throws Exception {
1928a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        final String helloWorld = "Hello SuetYi!";
1938a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
1948a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
1958a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(
1968a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki                doubleClickOnTextAtIndex(helloWorld.indexOf("SuetYi")));
1978a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
1988a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).check(hasSelection("SuetYi"));
1998a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    }
2008a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
2018a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    @SmallTest
202ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki    public void testDoubleTapAndDragToSelect() throws Exception {
203ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki        final String helloWorld = "Hello young beautiful girl!";
2048a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
205ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
206ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(
207ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki                doubleTapAndDragOnText(helloWorld.indexOf("young"), helloWorld.indexOf(" girl!")));
208ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki
209ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki        onView(withId(R.id.textview)).check(hasSelection("young beautiful"));
210ca4aaf3c17fdea4e373accc212867bd9f1e2be7fAbodunrinwa Toki    }
2118a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
2128a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    @SmallTest
2138a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    public void testSelectBackwordsByTouch() throws Exception {
2148a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        final String helloWorld = "Hello king of the Jungle!";
2158a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
2168a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
2178a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(
2188a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki                doubleTapAndDragOnText(helloWorld.indexOf(" Jungle!"), helloWorld.indexOf("king")));
2198a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
2208a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).check(hasSelection("king of the"));
2218a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    }
2228a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
2238a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    @SmallTest
2248a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    public void testToolbarAppearsAfterSelection() throws Exception {
2258a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        final String text = "Toolbar appears after selection.";
2268a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(click());
227b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarIsNotDisplayed();
2288a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
2298a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki        onView(withId(R.id.textview)).perform(
2308a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki                longPressOnTextAtIndex(text.indexOf("appears")));
2318a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki
232b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
233b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
234b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
235b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final String text2 = "Toolbar disappears after typing text.";
236b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text2));
237b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarIsNotDisplayed();
238b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi    }
239b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
240b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi    @SmallTest
241987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir    public void testToolbarAppearsAfterSelection_withFirstStringLtrAlgorithmAndRtlHint()
242987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir            throws Exception {
243987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        // after the hint layout change, the floating toolbar was not visible in the case below
244987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        // this test tests that the floating toolbar is displayed on the screen and is visible to
245987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        // user.
246987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
247987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        textView.post(new Runnable() {
248987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir            @Override
249987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir            public void run() {
250987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir                textView.setTextDirection(TextView.TEXT_DIRECTION_FIRST_STRONG_LTR);
251987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir                textView.setInputType(InputType.TYPE_CLASS_TEXT);
252987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir                textView.setSingleLine(true);
253987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir                textView.setHint("الروبوت");
254987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir            }
255987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        });
256987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        getInstrumentation().waitForIdleSync();
257987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir
258987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView("test"));
259987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(1));
26031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi        clickFloatingToolbarItem(
26131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.cut));
262987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        onView(withId(R.id.textview)).perform(longClick());
263987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        sleepForFloatingToolbarPopup();
264987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir
265987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir        assertFloatingToolbarIsDisplayed();
266987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir    }
267987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir
268987ec6588b2279891179c9eff09fc25ec14430c4Siyamed Sinir    @SmallTest
269b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi    public void testToolbarAndInsertionHandle() throws Exception {
270b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final String text = "text";
271b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
272b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
273b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
274b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarIsNotDisplayed();
275b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
276b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.insertion_handle).perform(click());
277b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
278b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
279b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
280b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarContainsItem(
281b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.selectAll));
282b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarDoesNotContainItem(
283b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.copy));
284b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarDoesNotContainItem(
285b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.cut));
286b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi    }
287b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
288b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi    @SmallTest
289b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi    public void testToolbarAndSelectionHandle() throws Exception {
290b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final String text = "abcd efg hijk";
291b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
292b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
293b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
294b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("f")));
295b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
296b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
297b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
298b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarContainsItem(
299b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.selectAll));
300b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarContainsItem(
301b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.copy));
302b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarContainsItem(
303b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.cut));
304b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
305b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
306b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
307b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
308b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
309b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
310b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
311b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
312b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.length()));
313b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
314b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
315b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi
316b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarDoesNotContainItem(
317b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.selectAll));
318b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarContainsItem(
319b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.copy));
320b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        assertFloatingToolbarContainsItem(
321b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.cut));
3228a5e1ae2f4e1aaf2db2a217e841371e18851df3fAbodunrinwa Toki    }
323da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi
324da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi    @SmallTest
325e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi    public void testInsertionHandle() throws Exception {
326e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        final String text = "abcd efg hijk ";
327e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
328e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
329e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
330e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
331e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
332e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
333b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
334e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
335e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.insertion_handle)
336e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
337e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
338e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
339e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.insertion_handle)
340e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
341e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
342e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi    }
343e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
344e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi    @SmallTest
345e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi    public void testInsertionHandle_multiLine() throws Exception {
346e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        final String text = "abcd\n" + "efg\n" + "hijk\n";
347e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
348e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
349e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
350e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
351e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
352e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
353b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
354e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
355e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.insertion_handle)
356e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
357e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
358e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
359e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.insertion_handle)
360e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
361e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
362e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi    }
363e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi
364e8b3dd47914a52a229c1726b79fe8f02fb59bb73Keisuke Kuroyanagi    @SmallTest
365da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi    public void testSelectionHandles() throws Exception {
366da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi        final String text = "abcd efg hijk lmn";
367da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
368da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
369fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Toki
370fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Toki        assertNoSelectionHandles();
371fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Toki
372da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f')));
373da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi
374fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Toki        onHandleView(com.android.internal.R.id.selection_start_handle)
375fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Toki                .check(matches(isDisplayed()));
376fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Toki        onHandleView(com.android.internal.R.id.selection_end_handle)
377fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Toki                .check(matches(isDisplayed()));
378fc6e25ef6e288cf75d70cf8185ff1c8831428936Abodunrinwa Toki
379b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
380da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
381da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
382da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abcd efg"));
383da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi
384da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
385da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('k') + 1));
386da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk"));
387da79ee683d74f2ad7d29147a30f3da17dd0ea6e2Keisuke Kuroyanagi    }
388c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi
389c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi    @SmallTest
390f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi    public void testSelectionHandles_bidi() throws Exception {
391f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        final String text = "abc \u0621\u0622\u0623 def";
392f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
393f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(replaceText(text));
394f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
395f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        assertNoSelectionHandles();
396f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
397f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('\u0622')));
398f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
399f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
400f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                .check(matches(isDisplayed()));
401f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
402f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                .check(matches(isDisplayed()));
403f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
404f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
405f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
406f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
407f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
408f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
409f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
410f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
411f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
412f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
413f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
414f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
415f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
416f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0623') + 1,
417f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                        false));
418f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("\u0623"));
419f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
420f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
421f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0621'),
422f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                        false));
423f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
424f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
425f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
426f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
427f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623"));
428f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
429f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
430f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.length()));
431f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623 def"));
432f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi    }
433f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi
434f0bb87b7c40efeeaee58d4c7b767961c9800463eKeisuke Kuroyanagi    @SmallTest
435c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi    public void testSelectionHandles_multiLine() throws Exception {
436c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
437c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
438c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
439c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
440c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi
441b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
442c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
443c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('e')));
444c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("efg\nhijk"));
445c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi
446c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
447c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
448c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk"));
449c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi
450c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
451c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('n') + 1));
452c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn"));
453c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi
454c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
455c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('r') + 1));
456c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn\nopqr"));
457c24c2bbb69634435d1d9fc97671229df245bd8d0Keisuke Kuroyanagi    }
458cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi
459cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi    @SmallTest
46026454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi    public void testSelectionHandles_multiLine_rtl() throws Exception {
46126454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        // Arabic text.
46226454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        final String text = "\u062A\u062B\u062C\n" + "\u062D\u062E\u062F\n"
46326454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                + "\u0630\u0631\u0632\n" + "\u0633\u0634\u0635\n" + "\u0636\u0637\u0638\n"
46426454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                + "\u0639\u063A\u063B";
46526454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
46626454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(replaceText(text));
46726454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
46826454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('\u0634')));
46926454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi
47026454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
47126454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
47226454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062E')));
47326454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection(
47426454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                text.substring(text.indexOf('\u062D'), text.indexOf('\u0635') + 1)));
47526454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi
47626454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
47726454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062A')));
47826454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection(
47926454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                text.substring(text.indexOf('\u062A'), text.indexOf('\u0635') + 1)));
48026454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi
48126454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
48226454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u0638')));
48326454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection(
48426454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                text.substring(text.indexOf('\u062A'), text.indexOf('\u0638') + 1)));
48526454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi
48626454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
48726454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u063B')));
48826454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection(text));
48926454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi    }
49026454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi
49126454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi
49226454141a8c489d84b7d486ad03869ff0f44dfdcKeisuke Kuroyanagi    @SmallTest
493cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi    public void testSelectionHandles_doesNotPassAnotherHandle() throws Exception {
494cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        final String text = "abcd efg hijk lmn";
495cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
496cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
497cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f')));
498cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi
499b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
500cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
501cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('l')));
502cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("g"));
503cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi
504cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f')));
505cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
506cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
507cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("e"));
508cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi    }
509cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi
510cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi    @SmallTest
511cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi    public void testSelectionHandles_doesNotPassAnotherHandle_multiLine() throws Exception {
512cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
513cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
514cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
515cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
516cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi
517b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
518cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
519cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('r') + 1));
520cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("k"));
521cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi
522cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
523cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
524cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
525cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("h"));
526cb6e8420cbf8bc4000d4761e38fd6d830fc1aca0Keisuke Kuroyanagi    }
527ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
528ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi    @SmallTest
529ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi    public void testSelectionHandles_snapToWordBoundary() throws Exception {
530ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        final String text = "abcd efg hijk lmn opqr";
531ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
532ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
533ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
534ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
535b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
536ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
537ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
538ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
539ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
540ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
541ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
542ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('d') + 1));
543ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
544ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
545ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
546ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
547ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c')));
548ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk"));
549ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
550ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
551ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('d')));
552ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("d efg hijk"));
553ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
554ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
555ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('b')));
556ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("bcd efg hijk"));
557ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
558ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
559ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
560ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
561ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('n')));
562ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("hijk lmn"));
563ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
564ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
565ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('o')));
566ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("hijk lmn"));
567ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
568ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
569ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('q')));
570ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("hijk lmn opqr"));
571ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
572ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
573ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('p')));
574ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("hijk lmn o"));
575ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
576ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
577ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('r')));
578ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("hijk lmn opq"));
579ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi    }
580ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
581ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi    @SmallTest
582ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi    public void testSelectionHandles_snapToWordBoundary_multiLine() throws Exception {
583ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        final String text = "abcd efg\n" + "hijk lmn\n" + "opqr stu";
584ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
585ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
586ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('m')));
587ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
588b0dd77c4115d333527a06cad84bc1c6ea8b4ac8eKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
589ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
590ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
591ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c')));
592ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("abcd efg\nhijk lmn"));
593ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
594ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
595ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('g')));
596ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("g\nhijk lmn"));
597ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
598ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_start_handle)
599ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('m')));
600ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("lmn"));
601ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
602ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
603ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
604ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
605ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('u')));
606ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("hijk lmn\nopqr stu"));
607ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
608ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
609ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('p')));
610ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("hijk lmn\no"));
611ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi
612ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onHandleView(com.android.internal.R.id.selection_end_handle)
613ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('i')));
614ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi        onView(withId(R.id.textview)).check(hasSelection("hijk"));
615ec913c0eb6c3cb70f69653ee988d440f47e5cc55Keisuke Kuroyanagi    }
616c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi
617c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi    @SmallTest
618c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi    public void testSetSelectionAndActionMode() throws Exception {
619c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        final String text = "abc def";
620c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
621c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(replaceText(text));
622c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi
623c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
624c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsNotDisplayed();
625c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
626c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        getInstrumentation().waitForIdleSync();
627c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
628c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // Don't automatically start action mode.
629c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsNotDisplayed();
630c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // Make sure that "Select All" is included in the selection action mode when the entire text
631c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // is not selected.
632c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('e')));
633c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
634c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
635c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // Changing the selection range by API should not interrupt the selection action mode.
636c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
637c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        getInstrumentation().waitForIdleSync();
638c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
639c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
640c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarContainsItem(
641c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.selectAll));
642c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // Make sure that "Select All" is no longer included when the entire text is selected by
643c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // API.
644c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        textView.post(
645c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi                () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length()));
646c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        getInstrumentation().waitForIdleSync();
647c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
648c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
649c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarDoesNotContainItem(
650c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.selectAll));
651c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // Make sure that shrinking the selection range to cursor (an empty range) by API
652c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // terminates selection action mode and does not trigger the insertion action mode.
653c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0));
654c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        getInstrumentation().waitForIdleSync();
655c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
656c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsNotDisplayed();
657c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // Make sure that user click can trigger the insertion action mode.
658c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
659c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        onHandleView(com.android.internal.R.id.insertion_handle).perform(click());
660c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
661c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
662c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // Make sure that an existing insertion action mode keeps alive after the insertion point is
663c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // moved by API.
664c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0));
665c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        getInstrumentation().waitForIdleSync();
666c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
667c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
668c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarDoesNotContainItem(
669c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.copy));
670c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // Make sure that selection action mode is started after selection is created by API when
671c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        // insertion action mode is active.
672c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        textView.post(
673c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi                () -> Selection.setSelection((Spannable) textView.getText(), 1, text.length()));
674c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        getInstrumentation().waitForIdleSync();
675c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        sleepForFloatingToolbarPopup();
676c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarIsDisplayed();
677c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi        assertFloatingToolbarContainsItem(
678c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi                getActivity().getString(com.android.internal.R.string.copy));
679c477b5830af5f9e87069fae4ff87a2a6b3e275fbKeisuke Kuroyanagi    }
680183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi
681183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi    @SmallTest
682183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi    public void testTransientState() throws Exception {
683183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        final String text = "abc def";
684183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(click());
685183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(replaceText(text));
686183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi
687183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
688183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        assertFalse(textView.hasTransientState());
689183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi
690183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('b')));
691183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        // hasTransientState should return true when user generated selection is active.
692183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        assertTrue(textView.hasTransientState());
693183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.indexOf('d')));
694183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        // hasTransientState should return false as the selection has been cleared.
695183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        assertFalse(textView.hasTransientState());
696183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        textView.post(
697183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi                () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length()));
698183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        getInstrumentation().waitForIdleSync();
699183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        // hasTransientState should return false when selection is created by API.
700183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi        assertFalse(textView.hasTransientState());
701183fd5071ea84aab82209c827fa0e4ff84a6b590Keisuke Kuroyanagi    }
702223c8392f066823cf4a3a98957960deb80ab1680Abodunrinwa Toki}
703