TextViewTest.java revision cfe27a9a9b8580e413a15912379aae9db161c19f
1fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su/*
2fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * Copyright (C) 2008 The Android Open Source Project
3fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su *
4fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * Licensed under the Apache License, Version 2.0 (the "License");
5fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * you may not use this file except in compliance with the License.
6fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * You may obtain a copy of the License at
7fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su *
8fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su *      http://www.apache.org/licenses/LICENSE-2.0
9fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su *
10fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * Unless required by applicable law or agreed to in writing, software
11fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * distributed under the License is distributed on an "AS IS" BASIS,
12fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * See the License for the specific language governing permissions and
14fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * limitations under the License.
15fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su */
16fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
17fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Supackage android.widget.cts;
18fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
19a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.junit.Assert.assertEquals;
20a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.junit.Assert.assertFalse;
21069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanuimport static org.junit.Assert.assertNotEquals;
22a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.junit.Assert.assertNotNull;
23a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.junit.Assert.assertNull;
24a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.junit.Assert.assertSame;
25a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.junit.Assert.assertTrue;
26a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.junit.Assert.fail;
27a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Matchers.any;
28a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Matchers.eq;
29a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Matchers.refEq;
30a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.doAnswer;
31a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.doCallRealMethod;
32a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.doNothing;
33a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.mock;
34a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.never;
35a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.reset;
36a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.spy;
37a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.times;
38a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.verify;
39a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.verifyNoMoreInteractions;
40a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.verifyZeroInteractions;
41a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport static org.mockito.Mockito.when;
42be24fc17bf75d329d40d8acce9e22d8d3ff30f1fAurimas Liutikas
43fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Activity;
44fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Instrumentation;
45fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Instrumentation.ActivityMonitor;
46354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.content.Context;
47fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.Intent;
482751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonakaimport android.content.pm.PackageManager;
49fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.res.ColorStateList;
50938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport android.content.res.Resources;
51fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.res.Resources.NotFoundException;
52fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Color;
53fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Paint;
54afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.graphics.Path;
559560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanuimport android.graphics.Point;
56fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukaiimport android.graphics.PorterDuff;
57fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Rect;
58afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.graphics.RectF;
59fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Typeface;
60fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.drawable.BitmapDrawable;
61ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.graphics.drawable.ColorDrawable;
62fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.drawable.Drawable;
63fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.net.Uri;
64fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.os.Bundle;
65354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.Handler;
66265b3d21959154e9a6ce0fdd888249f3699b7bddYohei Yukawaimport android.os.LocaleList;
67354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.Looper;
685b51f77b99861d48fec1c327252416f726b3b01aJames Cookimport android.os.Parcelable;
69354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.ResultReceiver;
7057c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarriimport android.os.SystemClock;
71a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport android.support.test.InstrumentationRegistry;
72a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport android.support.test.annotation.UiThreadTest;
733763966148d1d014b62a1bd27a68021c5ca17240Kirill Grouchnikovimport android.support.test.filters.MediumTest;
743763966148d1d014b62a1bd27a68021c5ca17240Kirill Grouchnikovimport android.support.test.filters.SmallTest;
75a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport android.support.test.rule.ActivityTestRule;
76a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport android.support.test.runner.AndroidJUnit4;
77fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Editable;
78fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.InputFilter;
79fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.InputType;
80fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Layout;
81fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Selection;
82fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Spannable;
83fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.SpannableString;
84ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.text.Spanned;
85fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextPaint;
86fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextUtils;
87fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextUtils.TruncateAt;
88afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.text.TextWatcher;
89fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.ArrowKeyMovementMethod;
90fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DateKeyListener;
91fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DateTimeKeyListener;
92fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DialerKeyListener;
93fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DigitsKeyListener;
94fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.KeyListener;
95fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.LinkMovementMethod;
96fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.MovementMethod;
97fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.PasswordTransformationMethod;
98fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.QwertyKeyListener;
99fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.SingleLineTransformationMethod;
100fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TextKeyListener;
101afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.text.method.TextKeyListener.Capitalize;
102fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TimeKeyListener;
103fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TransformationMethod;
10457c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarriimport android.text.style.ClickableSpan;
10598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinirimport android.text.style.ImageSpan;
106fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.style.URLSpan;
107ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagiimport android.text.style.UnderlineSpan;
108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.util.Linkify;
109fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.util.DisplayMetrics;
1109560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanuimport android.util.SparseArray;
111fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.util.TypedValue;
112ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.view.ActionMode;
113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.ContextMenu;
114afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.view.ContextMenu.ContextMenuInfo;
115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.Gravity;
11657c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarriimport android.view.InputDevice;
117fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.KeyEvent;
11832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagiimport android.view.Menu;
11957c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarriimport android.view.MotionEvent;
12057c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarriimport android.view.PointerIcon;
121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.View;
1229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanuimport android.view.ViewConfiguration;
123afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.view.ViewGroup;
1249560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanuimport android.view.ViewGroup.LayoutParams;
12532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagiimport android.view.accessibility.AccessibilityNodeInfo;
12672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.BaseInputConnection;
12718731b8489073e46e594c798247e5b6338204c3eSiyamed Sinirimport android.view.inputmethod.CompletionInfo;
12871e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagiimport android.view.inputmethod.CorrectionInfo;
12972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.EditorInfo;
13072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.ExtractedText;
13172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.ExtractedTextRequest;
132c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cookimport android.view.inputmethod.InputConnection;
133354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.view.inputmethod.InputMethodManager;
134ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Tokiimport android.view.textclassifier.TextClassificationManager;
135ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Tokiimport android.view.textclassifier.TextClassifier;
136ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Tokiimport android.view.textclassifier.TextSelection;
137c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunneimport android.widget.EditText;
138bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsuimport android.widget.FrameLayout;
13962808562ee0218f6ea3c07d333f7a65fc57c122fBrian Muramatsuimport android.widget.LinearLayout;
140354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.widget.ScrollView;
141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.Scroller;
142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.TextView;
143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.TextView.BufferType;
144938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport android.widget.cts.util.TestUtils;
145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1469259176007f5aad8fb9c79abb725b40c89327c40Aaron Holdenimport com.android.compatibility.common.util.CtsKeyEventUtil;
1479259176007f5aad8fb9c79abb725b40c89327c40Aaron Holdenimport com.android.compatibility.common.util.CtsTouchUtils;
1489259176007f5aad8fb9c79abb725b40c89327c40Aaron Holdenimport com.android.compatibility.common.util.PollingCheck;
1499259176007f5aad8fb9c79abb725b40c89327c40Aaron Holdenimport com.android.compatibility.common.util.WidgetTestUtils;
1509259176007f5aad8fb9c79abb725b40c89327c40Aaron Holden
151a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport org.junit.Before;
152a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport org.junit.Rule;
153a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport org.junit.Test;
154a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovimport org.junit.runner.RunWith;
155938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport org.mockito.invocation.InvocationOnMock;
156ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport org.xmlpull.v1.XmlPullParserException;
157ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport java.io.IOException;
159b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonakaimport java.util.Locale;
160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su/**
162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * Test {@link TextView}.
163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su */
164a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov@MediumTest
165a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov@RunWith(AndroidJUnit4.class)
166a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikovpublic class TextViewTest {
167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private Instrumentation mInstrumentation;
168a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    private Activity mActivity;
169a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    private TextView mTextView;
1709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private TextView mSecondTextView;
171a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov
172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static final String LONG_TEXT = "This is a really long string which exceeds "
1737375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "the width of the view. New devices have a much larger screen which "
1747375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "actually enables long strings to be displayed with no fading. "
1757375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "I have made this string longer to fix this case. If you are correcting "
1767375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "this text, I would love to see the kind of devices you guys now use!";
177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static final long TIMEOUT = 5000;
17822d40a1fcc078329a7e5a34ff5eeadeca9c70d49Kenny Root    private CharSequence mTransformedText;
179354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    private Handler mHandler = new Handler(Looper.getMainLooper());
180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
181a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Rule
182a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    public ActivityTestRule<TextViewCtsActivity> mActivityRule =
183a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov            new ActivityTestRule<>(TextViewCtsActivity.class);
184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
185a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Before
186a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    public void setup() {
187a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation = InstrumentationRegistry.getInstrumentation();
188a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mActivity = mActivityRule.getActivity();
189b7724cefaf6067b1f6b59d3abae73828b48945c3Kirill Grouchnikov        PollingCheck.waitFor(mActivity::hasWindowFocus);
190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
19228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    /**
1936beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu     * Promotes the TextView to editable and places focus in it to allow simulated typing. Used in
194a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov     * test methods annotated with {@link UiThreadTest}.
19528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook     */
19628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    private void initTextViewForTyping() {
1976beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView = findTextView(R.id.textview_text);
1986beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
1996beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.setText("", BufferType.EDITABLE);
2006beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.requestFocus();
201ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        // Disable smart selection
202ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        mTextView.setTextClassifier(TextClassifier.NO_OP);
2036beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu    }
2046beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
2056beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu    /**
2066beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu     * Used in test methods that can not entirely be run on the UiThread (e.g: tests that need to
2076beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu     * emulate touches and/or key presses).
2086beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu     */
2094b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void initTextViewForTypingOnUiThread() throws Throwable {
2104b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(this::initTextViewForTyping);
21128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        mInstrumentation.waitForIdleSync();
21228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
21328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
214047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu    @UiThreadTest
215a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
216047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu    public void testConstructorOnUiThread() {
217047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu        verifyConstructor();
218047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu    }
219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
220047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu    @Test
221047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu    public void testConstructorOffUiThread() {
222047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu        verifyConstructor();
223047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu    }
224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
225047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu    private void verifyConstructor() {
226047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu        new TextView(mActivity);
227047c430fa4b8c5dfb7735fe32b8a3d5abf8bbbafAndrei Stingaceanu        new TextView(mActivity, null);
228938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        new TextView(mActivity, null, android.R.attr.textViewStyle);
229f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_DeviceDefault_TextView);
230f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_DeviceDefault_Light_TextView);
231f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_Material_TextView);
232938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_Material_Light_TextView);
233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
236a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessText() {
238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String expected = mActivity.getResources().getString(R.string.text_view_hello);
241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(expected);
242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, tv.getText().toString());
243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null);
245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2489560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
249a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLineHeight() {
251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineHeight() > 0);
253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLineSpacing(1.2f, 1.5f);
255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineHeight() > 0);
256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
258a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2594b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testGetLayout() throws Throwable {
2609560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
2616beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView = findTextView(R.id.textview_text);
2626beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setGravity(Gravity.CENTER);
263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TestLayoutRunnable runnable = new TestLayoutRunnable(mTextView) {
268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // change the text of TextView.
270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText("Hello, Android!");
271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveLayout();
272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
2749560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(runnable);
275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(runnable.getLayout());
277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
280a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2814b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessKeyListener() throws Throwable {
2829560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = findTextView(R.id.textview_text));
283fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getKeyListener());
286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final KeyListener digitsKeyListener = DigitsKeyListener.getInstance();
288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setKeyListener(digitsKeyListener));
290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(digitsKeyListener, mTextView.getKeyListener());
292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener
294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                = QwertyKeyListener.getInstance(false, Capitalize.NONE);
2959560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setKeyListener(qwertyKeyListener));
296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(qwertyKeyListener, mTextView.getKeyListener());
298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
300a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3014b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessMovementMethod() throws Throwable {
302fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence LONG_TEXT = "Scrolls the specified widget to the specified "
303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "coordinates, except constrains the X scrolling position to the horizontal "
304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "regions of the text that will be visible after scrolling to "
305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "the specified Y position.";
306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int selectionStart = 10;
307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int selectionEnd = LONG_TEXT.length();
308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final MovementMethod movementMethod = ArrowKeyMovementMethod.getInstance();
3099560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
3106beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView = findTextView(R.id.textview_text);
3116beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setMovementMethod(movementMethod);
3126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(LONG_TEXT, BufferType.EDITABLE);
3136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Editable) mTextView.getText(),
3146beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    selectionStart, selectionEnd);
3156beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(movementMethod, mTextView.getMovementMethod());
320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
322b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_SHIFT_LEFT,
323b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu                KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_DPAD_UP);
324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the selection has been removed.
325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionEnd(mTextView.getText()));
327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3289560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
3296beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setMovementMethod(null);
3306beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Editable) mTextView.getText(),
3316beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    selectionStart, selectionEnd);
3326beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getMovementMethod());
337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
339b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_SHIFT_LEFT,
340b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu                KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_DPAD_UP);
341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the selection will not be changed.
342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
347a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testLength() {
349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String content = "This is content";
352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(content);
353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(content.length(), mTextView.length());
354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("");
356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.length());
357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(null);
359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.length());
360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
363a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessGravity() {
365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_gravity);
366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_default);
3684bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.TOP | Gravity.START, mTextView.getGravity());
369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_bottom);
3714bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.BOTTOM | Gravity.START, mTextView.getGravity());
372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
373fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_right);
374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity());
375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_center);
377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER, mTextView.getGravity());
378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_fill);
380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.FILL, mTextView.getGravity());
381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_center_vertical_right);
383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER_VERTICAL | Gravity.RIGHT, mTextView.getGravity());
384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, mTextView.getGravity());
387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.FILL);
388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.FILL, mTextView.getGravity());
389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER);
390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER, mTextView.getGravity());
391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.NO_GRAVITY);
3934bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.TOP | Gravity.START, mTextView.getGravity());
394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.RIGHT);
396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity());
397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.FILL_VERTICAL);
3994bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.FILL_VERTICAL | Gravity.START, mTextView.getGravity());
400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //test negative input value.
402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(-1);
403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getGravity());
404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
406a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4074b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessAutoLinkMask() throws Throwable {
408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text1 =
410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new SpannableString("URL: http://www.google.com. mailto: account@gmail.com");
4119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
4126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setAutoLinkMask(Linkify.ALL);
4136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(text1, BufferType.EDITABLE);
414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.ALL, mTextView.getAutoLinkMask());
417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Spannable spanString = (Spannable) mTextView.getText();
419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        URLSpan[] spans = spanString.getSpans(0, spanString.length(), URLSpan.class);
420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(spans);
421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("http://www.google.com", spans[0].getURL());
423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("mailto:account@gmail.com", spans[1].getURL());
424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text2 =
426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            new SpannableString("name: Jack. tel: +41 44 800 8999");
4279560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
4286beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS);
4296beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(text2, BufferType.EDITABLE);
430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS, mTextView.getAutoLinkMask());
433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spanString = (Spannable) mTextView.getText();
435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = spanString.getSpans(0, spanString.length(), URLSpan.class);
436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(spans);
437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, spans.length);
438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("tel:+41448008999", spans[0].getURL());
439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(R.layout.textview_autolink);
441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 1 for web, 2 for email, 4 for phone, 7 for all(web|email|phone)
442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, getAutoLinkMask(R.id.autolink_default));
443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS, getAutoLinkMask(R.id.autolink_web));
444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.EMAIL_ADDRESSES, getAutoLinkMask(R.id.autolink_email));
445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS, getAutoLinkMask(R.id.autolink_phone));
446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.ALL, getAutoLinkMask(R.id.autolink_all));
447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES,
448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound1));
449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS | Linkify.PHONE_NUMBERS,
450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound2));
451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS,
452fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound3));
453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS | Linkify.ALL,
454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound4));
455fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
456fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4579560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
458a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessTextSize() {
460fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
462fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
463fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 20f);
464fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20f, metrics),
465fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
466fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
467fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20f);
468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, metrics),
469fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
470fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
471fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20f);
472fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics),
473fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
474fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
475fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // setTextSize by default unit "sp"
476fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(20f);
477fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics),
478fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
479fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
480fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(200f);
481fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 200f, metrics),
482fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
483fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
484fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
486a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
487fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessTextColor() {
488fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
489fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
490fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.GREEN);
491fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GREEN, mTextView.getCurrentTextColor());
492fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getTextColors());
493fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
494fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.BLACK);
495fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentTextColor());
496fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.BLACK), mTextView.getTextColors());
497fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
498fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.RED);
499fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.RED, mTextView.getCurrentTextColor());
500fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.RED), mTextView.getTextColors());
501fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
502fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using ColorStateList
503fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
504fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
505fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_focused}, new int[0] },
506fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
507fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(colors);
508fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getTextColors());
509fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentTextColor());
510fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
511fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // exceptional
512fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
513fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setTextColor(null);
514fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should thrown exception if the colors is null");
515fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e){
516fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
517fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
518fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
519a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
520325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette    public void testGetTextColor() {
521325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        // TODO: How to get a suitable TypedArray to test this method.
522325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette
523325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        try {
524325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette            TextView.getTextColor(mActivity, null, -1);
525325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette            fail("There should be a NullPointerException thrown out.");
526325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        } catch (NullPointerException e) {
527325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        }
528325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette    }
529325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette
530a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5314b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessHighlightColor() throws Throwable {
532354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
533354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5349560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
535354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setTextIsSelectable(true);
536354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setText("abcd", BufferType.EDITABLE);
537354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setHighlightColor(Color.BLUE);
538354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        });
539354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
540354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
541354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(textView.isTextSelectable());
542354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.BLUE, textView.getHighlightColor());
543354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
544354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Long click on the text selects all text and shows selection handlers. The view has an
545354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // attribute layout_width="wrap_content", so clicked location (the center of the view)
546354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // should be on the text.
5479560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, textView);
548fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
549354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // At this point the entire content of our TextView should be selected and highlighted
550354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // with blue. Now change the highlight to red while the selection is still on.
5519560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> textView.setHighlightColor(Color.RED));
552354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
553354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
554354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.RED, textView.getHighlightColor());
555354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", textView.getText()));
556354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
557354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Remove the selection
5589560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> Selection.removeSelection((Spannable) textView.getText()));
559354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
560354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
561354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // And switch highlight to green after the selection has been removed
5629560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> textView.setHighlightColor(Color.GREEN));
563354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
564354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
565354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.GREEN, textView.getHighlightColor());
566354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", textView.getText()));
567fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
568fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
5699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
570a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
571fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetShadowLayer() {
5726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test values
5736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final MockTextView mockTextView = new MockTextView(mActivity);
5746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
5756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, 0.3f, 0.4f, Color.CYAN);
5766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(Color.CYAN, mockTextView.getShadowColor());
577a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(0.3f, mockTextView.getShadowDx(), 0.0f);
578a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(0.4f, mockTextView.getShadowDy(), 0.0f);
579a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(1.0f, mockTextView.getShadowRadius(), 0.0f);
580fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
581fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // shadow is placed to the left and below the text
5826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, 0.3f, 0.3f, Color.CYAN);
5836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(mockTextView.isPaddingOffsetRequired());
5846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getLeftPaddingOffset());
5856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getTopPaddingOffset());
5866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(1, mockTextView.getRightPaddingOffset());
5876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(1, mockTextView.getBottomPaddingOffset());
588fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
589fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // shadow is placed to the right and above the text
5906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, -0.8f, -0.8f, Color.CYAN);
5916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(mockTextView.isPaddingOffsetRequired());
5926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mockTextView.getLeftPaddingOffset());
5936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mockTextView.getTopPaddingOffset());
5946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getRightPaddingOffset());
5956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getBottomPaddingOffset());
596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // no shadow
5986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(0.0f, 0.0f, 0.0f, Color.CYAN);
5996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(mockTextView.isPaddingOffsetRequired());
6006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getLeftPaddingOffset());
6016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getTopPaddingOffset());
6026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getRightPaddingOffset());
6036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getBottomPaddingOffset());
604fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
606fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
607a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
608fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetSelectAllOnFocus() {
609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_selectallonfocus);
610fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String content = "This is the content";
611fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String blank = "";
612fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.selectAllOnFocus_default);
613fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(blank, BufferType.SPANNABLE);
614fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
615fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
616fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
617fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
618fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
619fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
620fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
621fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
622fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
623fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(content, BufferType.SPANNABLE);
624fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(true);
625fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
626fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
627fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
628fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
629fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
630fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
631fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
632fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(content.length(), mTextView.getSelectionEnd());
633fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
634fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 0);
635fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(false);
636fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
637fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
638fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
639fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
640fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
641fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
642fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
643fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionEnd());
644fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
645fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(blank, BufferType.SPANNABLE);
646fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(true);
647fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
648fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
649fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
650fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
651fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
652fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
653fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
654fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(blank.length(), mTextView.getSelectionEnd());
655fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
656fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 0);
657fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(false);
658fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
659fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
660fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
661fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
662fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
663fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
664fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
665fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionEnd());
666fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
667fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6689560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
669a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
670fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetPaint() {
671fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
672fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextPaint tp = mTextView.getPaint();
673fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(tp);
674fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
675fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaintFlags(), tp.getFlags());
676fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
677fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
678fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
679a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
680fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessLinksClickable() {
681fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext);
682fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
683fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
684fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
685fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
686fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.linksClickable_true);
687fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
688fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
689fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.linksClickable_false);
690fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getLinksClickable());
691fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
692fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinksClickable(false);
693fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getLinksClickable());
694fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
695fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinksClickable(true);
696fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
697fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
698fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getMovementMethod());
699fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
700fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text = new SpannableString("name: Jack. tel: +41 44 800 8999");
701fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
702fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS);
703fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
704fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
705fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Movement method will be automatically set to LinkMovementMethod
706fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getMovementMethod() instanceof LinkMovementMethod);
707fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
708fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7099560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
710a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
711fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessHintTextColor() {
712fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
713fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using int values
714fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
715fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.GREEN);
716fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GREEN, mTextView.getCurrentHintTextColor());
717fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getHintTextColors());
718fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
719fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.BLUE);
720fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.BLUE), mTextView.getHintTextColors());
721fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLUE, mTextView.getCurrentHintTextColor());
722fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
723fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.RED);
724fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.RED), mTextView.getHintTextColors());
725fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.RED, mTextView.getCurrentHintTextColor());
726fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
727fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using ColorStateList
728fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
729fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
730fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_focused}, new int[0] },
731fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
732fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(colors);
733fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getHintTextColors());
734fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentHintTextColor());
735fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
736fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // exceptional
737fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(null);
738fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getHintTextColors());
739fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCurrentTextColor(), mTextView.getCurrentHintTextColor());
740fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
741fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7429560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
743a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
744fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessLinkTextColor() {
745fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
746fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
747fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.GRAY);
748fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GRAY), mTextView.getLinkTextColors());
749fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GRAY, mTextView.getPaint().linkColor);
750fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
751fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.YELLOW);
752fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.YELLOW), mTextView.getLinkTextColors());
753fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.YELLOW, mTextView.getPaint().linkColor);
754fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
755fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.WHITE);
756fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.WHITE), mTextView.getLinkTextColors());
757fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.WHITE, mTextView.getPaint().linkColor);
758fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
759fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
760fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_expanded}, new int[0] },
761fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
762fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(colors);
763fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getLinkTextColors());
764fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getPaint().linkColor);
765fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
766fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(null);
767fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getLinkTextColors());
768fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getPaint().linkColor);
769fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
770fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7719560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
772a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
773fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessPaintFlags() {
774fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
77553959f211c113aa7b2a2ebaf80e10b79ddcccef1Victoria Lease        assertEquals(Paint.DEV_KERN_TEXT_FLAG | Paint.EMBEDDED_BITMAP_TEXT_FLAG
77653959f211c113aa7b2a2ebaf80e10b79ddcccef1Victoria Lease                | Paint.ANTI_ALIAS_FLAG, mTextView.getPaintFlags());
777fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
778fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG);
779fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG,
780fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getPaintFlags());
781fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
782fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG);
783fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG,
784fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getPaintFlags());
785fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
786fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
787a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
7884b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testHeight() throws Throwable {
789fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
7906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalHeight = mTextView.getHeight();
791fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setMaxHeight
7936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int newHeight = originalHeight + 1;
7946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
795fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
797fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
7996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
8006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
8016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
802fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
8046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
805fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getHeight());
8066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
807fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = Integer.MAX_VALUE;
8096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
810fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
8116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
812fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setMinHeight
8146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight + 1;
8156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
8166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
8176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
818fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
8206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
821fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
8226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
823fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
8256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
826fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
8276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
828fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // reset min and max height
830fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinHeight(0);
831fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxHeight(Integer.MAX_VALUE);
832fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setHeight
8346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight + 1;
8356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
8366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
8376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
8386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
8396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
8416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
8426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
8436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
8446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
8456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
8476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
848fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getHeight());
8496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
8506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
851fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
852fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHeight(originalHeight);
853fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
8546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(originalHeight, mTextView.getMaxHeight());
8556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(originalHeight, mTextView.getMinHeight());
856fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // setting max/min lines should cause getMaxHeight/getMinHeight to return -1
8586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxLines(2);
8596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting maxLines should return -1 fir maxHeight",
8606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                -1, mTextView.getMaxHeight());
8616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinLines(1);
8636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting minLines should return -1 for minHeight",
8646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                -1, mTextView.getMinHeight());
8656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
8666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
867a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
8684b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testWidth() throws Throwable {
8696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = findTextView(R.id.textview_text);
8706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int originalWidth = mTextView.getWidth();
8716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int newWidth = mTextView.getWidth() / 8;
8736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
8746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
8766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
877fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
878fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Min Width
8796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth + 1;
8806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinWidth(newWidth);
881fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
884fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth - 1;
886fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinWidth(originalWidth - 1);
8879c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu        assertEquals(2, mTextView.getLineCount());
8886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
890fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
891fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Width
8926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth + 1;
8936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
894fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
8976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
898fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth - 1;
9006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
9019c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu        assertEquals(2, mTextView.getLineCount());
9026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
9036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
9046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
9056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
9066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // setting ems should cause getMaxWidth/getMinWidth to return -1
9076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setEms(1);
9086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting ems should return -1 for maxWidth", -1, mTextView.getMaxWidth());
9096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting ems should return -1 for maxWidth", -1, mTextView.getMinWidth());
910fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
911fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
912a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
9134b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetMinEms() throws Throwable {
914fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
915fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
9169c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu
9176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
9186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
919fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
920fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinEms(originalEms + 1);
921fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals((originalEms + 1) * mTextView.getLineHeight(), mTextView.getWidth());
92298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
92398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMinEms());
924fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
925fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinEms(originalEms - 1);
926fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalWidth, mTextView.getWidth());
92798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
92898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMinEms());
9296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
9306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinWidth(1);
9316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mTextView.getMinEms());
932fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
933fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
934a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
9354b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetMaxEms() throws Throwable {
936fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
937fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
9386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
9396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
9406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
941fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
942fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxEms(originalEms + 1);
943fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
944fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalWidth, mTextView.getWidth());
94598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
94698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMaxEms());
947fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
948fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxEms(originalEms - 1);
949fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(1 < mTextView.getLineCount());
9506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms - 1) * mTextView.getLineHeight(), mTextView.getWidth());
95198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
95298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMaxEms());
9536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
9546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxWidth(originalWidth);
9556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mTextView.getMaxEms());
956fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
957fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
958a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
9594b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetEms() throws Throwable {
960fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
961fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("check height", 1, mTextView.getLineCount());
9626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
9636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
964fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
965fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setEms(originalEms + 1);
966fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
9676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms + 1) * mTextView.getLineHeight(), mTextView.getWidth());
96898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
96998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
97098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMinEms());
97198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMaxEms());
972fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
973fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setEms(originalEms - 1);
974fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((1 < mTextView.getLineCount()));
9756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms - 1) * mTextView.getLineHeight(), mTextView.getWidth());
97698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
97798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
97898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMinEms());
97998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMaxEms());
980fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
981fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
982a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
9834b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetLineSpacing() throws Throwable {
9849560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new TextView(mActivity));
9859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
986fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLineHeight = mTextView.getLineHeight();
987fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
988fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
989fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float add = 1.2f;
990fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float mult = 1.4f;
991fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
99292e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
993fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = 0.0f;
994fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = 1.4f;
995fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
99692e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
997fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
998fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // abnormal
999fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = -1.2f;
1000fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = 1.4f;
1001fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
100292e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1003fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = -1.2f;
1004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = -1.4f;
1005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
100692e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1007fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = 1.2f;
1008fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = 0.0f;
1009fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
101092e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1011fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1012fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // edge
1013fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = Float.MIN_VALUE;
1014fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = Float.MIN_VALUE;
1015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
1016ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1017ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette
1018ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        // edge case where the behavior of Math.round() deviates from
1019ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        // FastMath.round(), requiring us to use an explicit 0 value
1020fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = Float.MAX_VALUE;
1021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = Float.MAX_VALUE;
1022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
1023ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        assertEquals(0, mTextView.getLineHeight());
1024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1025fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1026a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
10274b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetElegantLineHeight() throws Throwable {
1028ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mTextView = findTextView(R.id.textview_text);
1029ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getPaint().isElegantTextHeight());
10309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
10316beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setWidth(mTextView.getWidth() / 3);
10326beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setPadding(1, 2, 3, 4);
10336beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setGravity(Gravity.BOTTOM);
1034ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        });
1035ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
1036ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
1037ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        int oldHeight = mTextView.getHeight();
10389560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setElegantTextHeight(true));
1039ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
1040ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
1041ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getPaint().isElegantTextHeight());
1042ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getHeight() > oldHeight);
1043ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
10449560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setElegantTextHeight(false));
1045ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
1046ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getPaint().isElegantTextHeight());
1047ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getHeight() == oldHeight);
1048ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien    }
1049ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
1050a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1051fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessFreezesText() throws Throwable {
1052fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(R.layout.textview_hint_linksclickable_freezestext);
1053fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1054fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
1055fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1056fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1057fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_true);
1058fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getFreezesText());
1059fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1060fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
1061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1062fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1063fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setFreezesText(false);
1064fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1065fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1066fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text = "Hello, TextView.";
10679560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setText(text));
1068fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
1069fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1070fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final URLSpan urlSpan = new URLSpan("ctstest://TextView/test");
107172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // TODO: How to simulate the TextView in frozen icicles.
1072a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        ActivityMonitor am = mInstrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
1073fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                null, false);
1074fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
10759560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
10766beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Uri uri = Uri.parse(urlSpan.getURL());
10776beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
10786beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mActivity.startActivity(intent);
1079fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1080fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1081fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Activity newActivity = am.waitForActivityWithTimeout(TIMEOUT);
1082fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(newActivity);
1083fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        newActivity.finish();
1084a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.removeMonitor(am);
1085fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text of TextView is removed.
1086fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
108772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
108872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(text.toString(), mTextView.getText().toString());
1089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setFreezesText(true);
1091fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getFreezesText());
1092fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
10939560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setText(text));
1094fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
109572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // TODO: How to simulate the TextView in frozen icicles.
1096a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        am = mInstrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
1097fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                null, false);
1098fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
10999560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
11006beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Uri uri = Uri.parse(urlSpan.getURL());
11016beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
11026beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mActivity.startActivity(intent);
1103fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1104fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
110507b9d3406e116f2f6b92932925783eed79503de0Mist Liao        Activity oldActivity = newActivity;
110607b9d3406e116f2f6b92932925783eed79503de0Mist Liao        while (true) {
110707b9d3406e116f2f6b92932925783eed79503de0Mist Liao            newActivity = am.waitForActivityWithTimeout(TIMEOUT);
110807b9d3406e116f2f6b92932925783eed79503de0Mist Liao            assertNotNull(newActivity);
110907b9d3406e116f2f6b92932925783eed79503de0Mist Liao            if (newActivity != oldActivity) {
111007b9d3406e116f2f6b92932925783eed79503de0Mist Liao                break;
111107b9d3406e116f2f6b92932925783eed79503de0Mist Liao            }
111207b9d3406e116f2f6b92932925783eed79503de0Mist Liao        }
1113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        newActivity.finish();
1114a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.removeMonitor(am);
1115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text of TextView is still there.
1116fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
1117fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text.toString(), mTextView.getText().toString());
1118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1119fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
11209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
1121a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetEditableFactory() {
1123fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "sample";
1125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
112698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final Editable.Factory mockEditableFactory = spy(new Editable.Factory());
112798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        doCallRealMethod().when(mockEditableFactory).newEditable(any(CharSequence.class));
112898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setEditableFactory(mockEditableFactory);
112998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov
1130fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text);
113198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1132fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
113398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1134fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
113598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1136fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
113798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1138fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
113998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1140fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
114198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
114398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, times(1)).newEditable(text);
1144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setKeyListener(DigitsKeyListener.getInstance());
114698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
114898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, times(1)).newEditable(text);
1149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setEditableFactory(null);
1152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("The factory can not set to null!");
1153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
1154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1155fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1156fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
11579560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
1158a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetSpannableFactory() {
1160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "sample";
1162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
116398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final Spannable.Factory mockSpannableFactory = spy(new Spannable.Factory());
116498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        doCallRealMethod().when(mockSpannableFactory).newSpannable(any(CharSequence.class));
116598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setSpannableFactory(mockSpannableFactory);
116698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov
1167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text);
116898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
117098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
117298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
117498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
117698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
117898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1179fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
118098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, times(1)).newSpannable(text);
1181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setMovementMethod(LinkMovementMethod.getInstance());
118398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
118598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, times(1)).newSpannable(text);
1186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setSpannableFactory(null);
1189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("The factory can not set to null!");
1190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
1191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
11949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
1195a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testTextChangedListener() {
1197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextWatcher watcher0 = new MockTextWatcher();
1199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextWatcher watcher1 = new MockTextWatcher();
1200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.addTextChangedListener(watcher0);
1202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.addTextChangedListener(watcher1);
1203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("Changed");
1207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1209fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1210fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1211fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1212fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // BeforeTextChanged and OnTextChanged are called though the strings are same
1217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("Changed");
1218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1220fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1221fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1222fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1227fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // BeforeTextChanged and OnTextChanged are called twice (The text is not
1228fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Editable, so in Append() it calls setText() first)
1229fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("and appended");
1230fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1236fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Methods are not called if the string does not change
1240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("");
1241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledBeforeTextChanged());
1242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledOnTextChanged());
1243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledAfterTextChanged());
1244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledBeforeTextChanged());
1245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledOnTextChanged());
1246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledAfterTextChanged());
1247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.removeTextChangedListener(watcher1);
1251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(null);
1252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledBeforeTextChanged());
1256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledOnTextChanged());
1257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledAfterTextChanged());
1258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
12609560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
1261a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetTextKeepState1() {
1263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String longString = "very long content";
1266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String shortString = "short";
1267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is inside the short string
1269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString, BufferType.SPANNABLE);
1270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 3);
1271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionStart());
1274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionEnd());
1275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is outside the short string
1277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), shortString.length() + 1);
1279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1283fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is inside the short string
1285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 1, 4);
1287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getSelectionStart());
1290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(4, mTextView.getSelectionEnd());
1291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which ends outside the short string
1293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 2, shortString.length() + 1);
1295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getSelectionStart());
1298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is outside the short string
1301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1302fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(),
1303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                shortString.length() + 1, shortString.length() + 3);
1304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1311a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetEditableText() {
1313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "Hello";
1316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(text, BufferType.EDITABLE);
1317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getText().toString());
1318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
1319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getEditableText().toString());
1320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(text, BufferType.SPANNABLE);
1322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getText().toString());
1323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
1324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(tv.getEditableText());
1325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null, BufferType.EDITABLE);
1327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
1329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getEditableText().toString());
1330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null, BufferType.SPANNABLE);
1332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
1334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(tv.getEditableText());
1335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1338a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText2() {
1340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String string = "This is a test for setting text content by char array";
1341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        char[] input = string.toCharArray();
1342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 0, input.length);
1345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(string, tv.getText().toString());
1346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1347fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 0, 5);
1348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(string.substring(0, 5), tv.getText().toString());
1349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, -1, input.length);
1352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the start position is negative!");
1353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, 0, -1);
1358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the length is negative!");
1359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, 1, input.length);
1364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the end position is out of index!");
1365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 1, 0);
1369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1371fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1373a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText1() {
1375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
1376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String longString = "very long content";
1378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String shortString = "short";
1379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is inside the short string
1381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString, BufferType.SPANNABLE);
1382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 3);
1383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionStart());
1388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionEnd());
1389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is outside the short string
1399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), longString.length());
1401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is inside the short string
1417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 1, shortString.length() - 1);
1419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getSelectionStart());
1424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length() - 1, mTextView.getSelectionEnd());
1425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which ends outside the short string
1435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 2, longString.length());
1437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getSelectionStart());
1442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1452fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is outside the short string
1453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(),
1455fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                shortString.length() + 1, shortString.length() + 3);
1456fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1457fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1458fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1460fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1462fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1463fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1464fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1465fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1466fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1467fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1469fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1470fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1471fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1472fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1473a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1474fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText3() {
1475fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1476fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1477fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int resId = R.string.text_view_hint;
1478fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String result = mActivity.getResources().getString(resId);
1479fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1480fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId);
1481fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
1482fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1483fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1484fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(-1);
1485fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception with illegal id");
1486fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
1487fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1488fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1489fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1490a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
14919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testSetTextUpdatesHeightAfterRemovingImageSpan() throws Throwable {
149298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // Height calculation had problems when TextView had width: match_parent
149398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int textViewWidth = ViewGroup.LayoutParams.MATCH_PARENT;
149498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final Spannable text = new SpannableString("some text");
149598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int spanHeight = 100;
149698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
149798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // prepare TextView, width: MATCH_PARENT
14989560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new TextView(mActivity));
14999560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
15009560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setSingleLine(true);
15019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 2);
15029560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setPadding(0, 0, 0, 0);
15039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setIncludeFontPadding(false);
15049560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setText(text);
150598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
150698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(textViewWidth,
150798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
15089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mTextView, layoutParams);
150998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        layout.setLayoutParams(layoutParams);
15109560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout));
1511a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.waitForIdleSync();
151298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
151398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // measure height of text with no span
15149560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final int heightWithoutSpan = mTextView.getHeight();
151598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertTrue("Text height should be smaller than span height",
151698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithoutSpan < spanHeight);
151798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
151898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // add ImageSpan to text
151998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        Drawable drawable = mInstrumentation.getContext().getDrawable(R.drawable.scenery);
152098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        drawable.setBounds(0, 0, spanHeight, spanHeight);
152198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        ImageSpan span = new ImageSpan(drawable);
152298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        text.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
15239560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setText(text));
152498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mInstrumentation.waitForIdleSync();
152598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
152698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // measure height with span
15279560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final int heightWithSpan = mTextView.getHeight();
152898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertTrue("Text height should be greater or equal than span height",
152998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithSpan >= spanHeight);
153098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
153198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // remove the span
153298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        text.removeSpan(span);
15339560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setText(text));
153498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mInstrumentation.waitForIdleSync();
153598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
15369560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final int heightAfterRemoveSpan = mTextView.getHeight();
153798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertEquals("Text height should be same after removing the span",
153898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithoutSpan, heightAfterRemoveSpan);
153998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir    }
154098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
1541a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
15424b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testRemoveSelectionWithSelectionHandles() throws Throwable {
15436beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
1544af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1545354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.isTextSelectable());
15469560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
1547354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mTextView.setTextIsSelectable(true);
1548354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mTextView.setText("abcd", BufferType.EDITABLE);
1549af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        });
1550af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        mInstrumentation.waitForIdleSync();
1551354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.isTextSelectable());
1552af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1553af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // Long click on the text selects all text and shows selection handlers. The view has an
1554af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // attribute layout_width="wrap_content", so clicked location (the center of the view)
1555af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // should be on the text.
15569560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, mTextView);
1557af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
15589560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> Selection.removeSelection((Spannable) mTextView.getText()));
1559af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        mInstrumentation.waitForIdleSync();
1560354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
1561354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", mTextView.getText()));
1562af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi    }
1563af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1564a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
15654b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_insert() throws Throwable {
15666beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
15675b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15685b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Type some text.
1569b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
15709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
15716beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Precondition: The cursor is at the end of the text.
15726beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals(3, mTextView.getSelectionStart());
15736beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
15746beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo removes the typed string in one step.
15756beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
15766beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
15776beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals(0, mTextView.getSelectionStart());
15786beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
15796beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Redo restores the text and cursor position.
15806beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.redo);
15816beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("abc", mTextView.getText().toString());
15826beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals(3, mTextView.getSelectionStart());
15836beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
15846beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undoing the redo clears the text again.
15856beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
15866beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
15876beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
15886beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo when the undo stack is empty does nothing.
15896beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
15906beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
15915b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
15925b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
159328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
15945b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1595a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
15964b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_delete() throws Throwable {
15976beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
15985b51f77b99861d48fec1c327252416f726b3b01aJames Cook
159928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        // Simulate deleting text and undoing it.
1600b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "xyz");
1601b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_DEL,
1602b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu                KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL);
16039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
16046beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Precondition: The text was actually deleted.
16056beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
16066beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals(0, mTextView.getSelectionStart());
16076beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
16086beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo restores the typed string and cursor position in one step.
16096beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
16106beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("xyz", mTextView.getText().toString());
16116beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals(3, mTextView.getSelectionStart());
16126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
16136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Redo removes the text in one step.
16146beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.redo);
16156beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
16166beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals(0, mTextView.getSelectionStart());
16176beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
16186beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undoing the redo restores the text again.
16196beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
16206beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("xyz", mTextView.getText().toString());
16216beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals(3, mTextView.getSelectionStart());
16226beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
16236beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undoing again undoes the original typing.
16246beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
16256beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
16266beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals(0, mTextView.getSelectionStart());
16275b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
16285b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
162928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
16305b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1631c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    // Initialize the text view for simulated IME typing. Must be called on UI thread.
1632c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    private InputConnection initTextViewForSimulatedIme() {
1633c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView = findTextView(R.id.textview_text);
163418731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        return initTextViewForSimulatedIme(mTextView);
163518731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir    }
163618731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir
163718731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir    private InputConnection initTextViewForSimulatedIme(TextView textView) {
163818731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        textView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
163918731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        textView.setText("", BufferType.EDITABLE);
164018731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        return textView.onCreateInputConnection(new EditorInfo());
1641c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1642c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1643c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    // Simulates IME composing text behavior.
1644c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    private void setComposingTextInBatch(InputConnection input, CharSequence text) {
1645c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1646c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.setComposingText(text, 1);  // Leave cursor at end.
1647c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1648c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1649c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1650c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1651a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1652c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeInsertLatin() {
1653c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1654c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1655c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Simulate IME text entry behavior. The Latin IME enters text by replacing partial words,
1656c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // such as "c" -> "ca" -> "cat" -> "cat ".
1657c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "c");
1658c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "ca");
1659c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1660c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The completion and space are added in the same batch.
1661c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1662c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText("cat", 1);
1663c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText(" ", 1);
1664c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1665c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1666c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The repeated replacements undo in a single step.
1667c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1668c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("", mTextView.getText().toString());
1669c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1670c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1671c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1672a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1673c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeInsertJapanese() {
1674c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1675c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1676c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The Japanese IME does repeated replacements of Latin characters to hiragana to kanji.
1677c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String HA = "\u306F";  // HIRAGANA LETTER HA
1678c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String NA = "\u306A";  // HIRAGANA LETTER NA
1679c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "h");
1680c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA);
1681c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + "n");
1682c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + NA);
1683c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1684c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The result may be a surrogate pair. The composition ends in the same batch.
1685c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1686c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText("\uD83C\uDF37", 1);  // U+1F337 TULIP
1687c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.setComposingText("", 1);
1688c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1689c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1690c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The repeated replacements are a single undo step.
1691c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1692c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("", mTextView.getText().toString());
1693c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1694c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1695c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1696a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
169771e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi    public void testUndo_imeInsertAndDeleteLatin() {
169871e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        InputConnection input = initTextViewForSimulatedIme();
169971e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi
170071e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "t");
170171e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "te");
170271e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "tes");
170371e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "test");
170471e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "tes");
170571e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "te");
170671e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "t");
170771e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi
170871e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        input.beginBatchEdit();
170971e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        input.setComposingText("", 1);
171071e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        input.finishComposingText();
171171e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        input.endBatchEdit();
171271e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi
171371e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        mTextView.onTextContextMenuItem(android.R.id.undo);
171471e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        assertEquals("test", mTextView.getText().toString());
171571e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        mTextView.onTextContextMenuItem(android.R.id.undo);
171671e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        assertEquals("", mTextView.getText().toString());
171771e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi    }
171871e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi
171971e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi    @UiThreadTest
1720a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
172171e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi    public void testUndo_imeAutoCorrection() {
172218731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        mTextView = findTextView(R.id.textview_text);
172318731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        TextView spiedTextView = spy(mTextView);
172418731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        InputConnection input = initTextViewForSimulatedIme(spiedTextView);
172571e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi
172671e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        // Start typing a composition.
172771e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "t");
172871e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "te");
172971e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        setComposingTextInBatch(input, "teh");
173071e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi
173118731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        CorrectionInfo correctionInfo = new CorrectionInfo(0, "teh", "the");
173218731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        reset(spiedTextView);
173371e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        input.beginBatchEdit();
173471e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        // Auto correct "teh" to "the".
173518731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        assertTrue(input.commitCorrection(correctionInfo));
173671e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        input.commitText("the", 1);
173771e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        input.endBatchEdit();
173871e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi
173918731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        verify(spiedTextView, times(1)).onCommitCorrection(refEq(correctionInfo));
174018731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir
174118731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        assertEquals("the", spiedTextView.getText().toString());
174218731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        spiedTextView.onTextContextMenuItem(android.R.id.undo);
174318731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        assertEquals("teh", spiedTextView.getText().toString());
174418731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        spiedTextView.onTextContextMenuItem(android.R.id.undo);
174518731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        assertEquals("", spiedTextView.getText().toString());
174618731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir    }
174718731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir
174818731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir    @UiThreadTest
1749a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
175018731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir    public void testUndo_imeAutoCompletion() {
175118731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        mTextView = findTextView(R.id.textview_text);
175218731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        TextView spiedTextView = spy(mTextView);
175318731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        InputConnection input = initTextViewForSimulatedIme(spiedTextView);
175418731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir
175518731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        // Start typing a composition.
175618731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        setComposingTextInBatch(input, "a");
175718731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        setComposingTextInBatch(input, "an");
175818731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        setComposingTextInBatch(input, "and");
175918731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir
176018731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        CompletionInfo completionInfo = new CompletionInfo(0, 0, "android");
176118731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        reset(spiedTextView);
176218731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        input.beginBatchEdit();
176318731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        // Auto complete "and" to "android".
176418731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        assertTrue(input.commitCompletion(completionInfo));
176518731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        input.commitText("android", 1);
176618731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        input.endBatchEdit();
176718731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir
176818731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        verify(spiedTextView, times(1)).onCommitCompletion(refEq(completionInfo));
176918731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir
177018731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        assertEquals("android", spiedTextView.getText().toString());
177118731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        spiedTextView.onTextContextMenuItem(android.R.id.undo);
177218731b8489073e46e594c798247e5b6338204c3eSiyamed Sinir        assertEquals("", spiedTextView.getText().toString());
177371e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi    }
177471e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi
177571e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi    @UiThreadTest
1776a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1777c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeCancel() {
1778c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1779c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setText("flower");
1780c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1781c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Start typing a composition.
1782c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String HA = "\u306F";  // HIRAGANA LETTER HA
1783c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "h");
1784c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA);
1785c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + "n");
1786c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1787c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Cancel the composition.
1788c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "");
1789c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1790c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
179171e696fcc640126a0360d30e8b1d9a5552f6dd1dKeisuke Kuroyanagi        assertEquals(HA + "n" + "flower", mTextView.getText().toString());
1792c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.redo);
1793c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1794c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1795c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1796c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1797a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1798c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeEmptyBatch() {
1799c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1800c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setText("flower");
1801c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1802c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Send an empty batch edit. This happens if the IME is hidden and shown.
1803c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1804c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1805c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1806c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Undo and redo do nothing.
1807c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1808c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1809c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.redo);
1810c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1811c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1812c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1813a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
18144b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_setText() throws Throwable {
18156beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
181628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1817c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Create two undo operations, an insert and a delete.
1818b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "xyz");
1819b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_DEL,
1820b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu                KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL);
18219560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
18226beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Calling setText() clears both undo operations, so undo doesn't happen.
18236beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText("Hello", BufferType.EDITABLE);
18246beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
18256beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("Hello", mTextView.getText().toString());
18266beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
18276beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Clearing text programmatically does not undo either.
18286beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText("", BufferType.EDITABLE);
18296beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
18306beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
1831277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1832277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1833277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
183428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1835a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
18364b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testRedo_setText() throws Throwable {
18376beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
1838277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1839277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text. This creates an undo entry.
1840b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
18419560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
18426beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo the typing to create a redo entry.
18436beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
1844277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
18456beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Calling setText() clears the redo stack, so redo doesn't happen.
18466beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText("Hello", BufferType.EDITABLE);
18476beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.redo);
18486beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("Hello", mTextView.getText().toString());
1849277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1850277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1851277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1852277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1853a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
18544b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_directAppend() throws Throwable {
18556beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
185628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1857277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
1858b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
18599560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
18606beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Programmatically append some text.
18616beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.append("def");
18626beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("abcdef", mTextView.getText().toString());
1863277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
18646beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo removes the append as a separate step.
18656beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
18666beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("abc", mTextView.getText().toString());
1867277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
18686beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Another undo removes the original typing.
18696beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
18706beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
1871277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1872277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1873277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1874277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1875a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
18764b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_directInsert() throws Throwable {
18776beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
1878277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1879277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
1880b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
18819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
18826beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Directly modify the underlying Editable to insert some text.
18836beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // NOTE: This is a violation of the API of getText() which specifies that the
18846beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // returned object should not be modified. However, some apps do this anyway and
18856beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // the framework needs to handle it.
18866beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Editable text = (Editable) mTextView.getText();
18876beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            text.insert(0, "def");
18886beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("defabc", mTextView.getText().toString());
18896beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
18906beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo removes the insert as a separate step.
18916beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
18926beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("abc", mTextView.getText().toString());
18936beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
18946beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Another undo removes the original typing.
18956beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
18966beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
1897277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1898277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1899277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1900277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
19016beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu    @UiThreadTest
1902a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1903c530472a02205f0b7d87f9f06140c56ca0849816James Cook    public void testUndo_noCursor() {
1904c530472a02205f0b7d87f9f06140c56ca0849816James Cook        initTextViewForTyping();
1905c530472a02205f0b7d87f9f06140c56ca0849816James Cook
19066beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Append some text to create an undo operation. There is no cursor present.
19076beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.append("cat");
1908c530472a02205f0b7d87f9f06140c56ca0849816James Cook
19096beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Place the cursor at the end of the text so the undo will have to change it.
19106beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        Selection.setSelection((Spannable) mTextView.getText(), 3);
1911c530472a02205f0b7d87f9f06140c56ca0849816James Cook
19126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Undo the append. This should not crash, despite not having a valid cursor
19136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // position in the undo operation.
19146beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.undo);
1915c530472a02205f0b7d87f9f06140c56ca0849816James Cook    }
1916c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1917a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
19184b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_textWatcher() throws Throwable {
19196beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
1920277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1921277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Add a TextWatcher that converts the text to spaces on each change.
1922277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher());
1923277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1924277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
1925b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
19269560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
19276beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // TextWatcher altered the text.
19286beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("   ", mTextView.getText().toString());
1929277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
19306beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo reverses both changes in one step.
19316beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
19326beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
1933277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1934277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1935c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook    }
1936c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
19376beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu    @UiThreadTest
1938a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
1939c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook    public void testUndo_textWatcherDirectAppend() {
1940c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        initTextViewForTyping();
1941c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1942c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        // Add a TextWatcher that converts the text to spaces on each change.
1943c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher());
1944c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
19456beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Programmatically append some text. The TextWatcher changes it to spaces.
19466beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.append("abc");
19476beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("   ", mTextView.getText().toString());
1948c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
19496beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Undo reverses both changes in one step.
19506beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.undo);
19516beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("", mTextView.getText().toString());
195228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
195328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1954a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
19554b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_shortcuts() throws Throwable {
19566beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
195728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
195828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        // Type some text.
1959b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
19609560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
19616beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Pressing Control-Z triggers undo.
19626beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            KeyEvent control = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z, 0,
19636beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    KeyEvent.META_CTRL_LEFT_ON);
19646beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, control));
19656beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
19666beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
19676beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Pressing Control-Shift-Z triggers redo.
19686beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            KeyEvent controlShift = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z,
19696beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    0, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_SHIFT_LEFT_ON);
19706beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, controlShift));
19716beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("abc", mTextView.getText().toString());
19725b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
19735b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
19745b51f77b99861d48fec1c327252416f726b3b01aJames Cook    }
19755b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1976a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
19774b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_saveInstanceState() throws Throwable {
19786beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
19795b51f77b99861d48fec1c327252416f726b3b01aJames Cook
19805b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Type some text to create an undo operation.
1981b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
19829560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
19836beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Parcel and unparcel the TextView.
19846beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Parcelable state = mTextView.onSaveInstanceState();
19856beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onRestoreInstanceState(state);
19865b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
19875b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
19885b51f77b99861d48fec1c327252416f726b3b01aJames Cook
19895b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Delete a character to create a new undo operation.
1990b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_DEL);
19919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
19926beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("ab", mTextView.getText().toString());
19935b51f77b99861d48fec1c327252416f726b3b01aJames Cook
19946beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo the delete.
19956beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
19966beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("abc", mTextView.getText().toString());
19975b51f77b99861d48fec1c327252416f726b3b01aJames Cook
19986beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Undo the typing, which verifies that the original undo operation was parceled
19996beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // correctly.
20006beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
20016beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
20025f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
20036beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Parcel and unparcel the undo stack (which is empty but has been used and may
20046beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // contain other state).
20056beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Parcelable state = mTextView.onSaveInstanceState();
20066beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onRestoreInstanceState(state);
20075f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        });
20085f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mInstrumentation.waitForIdleSync();
20095f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook    }
20105f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
2011a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
20124b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testUndo_saveInstanceStateEmpty() throws Throwable {
20136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
20145f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
20155f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        // Type and delete to create two new undo operations.
2016b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "a");
2017b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_DEL);
20189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
20196beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Empty the undo stack then parcel and unparcel the TextView. While the undo
20206beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // stack contains no operations it may contain other state.
20216beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
20226beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
20236beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Parcelable state = mTextView.onSaveInstanceState();
20246beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onRestoreInstanceState(state);
20255f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        });
20265f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mInstrumentation.waitForIdleSync();
20275f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
20285f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        // Create two more undo operations.
2029b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "b");
2030b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_DEL);
20319560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
20326beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Verify undo still works.
20336beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
20346beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("b", mTextView.getText().toString());
20356beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.undo);
20366beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("", mTextView.getText().toString());
20375b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
20385b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
20395b51f77b99861d48fec1c327252416f726b3b01aJames Cook    }
20405b51f77b99861d48fec1c327252416f726b3b01aJames Cook
20416beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu    @UiThreadTest
2042a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2043b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCopyAndPaste() {
2044b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
20456beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
20466beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.setText("abcd", BufferType.EDITABLE);
20476beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.setSelected(true);
20486beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
20496beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Copy "bc".
20506beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
20516beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.copy);
20526beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
20536beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Paste "bc" between "b" and "c".
20546beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        Selection.setSelection((Spannable) mTextView.getText(), 2, 2);
20556beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.paste);
20566beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("abbccd", mTextView.getText().toString());
20576beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
20586beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Select entire text and paste "bc".
20596beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        Selection.selectAll((Spannable) mTextView.getText());
20606beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.paste);
20616beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("bc", mTextView.getText().toString());
2062b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2063b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2064a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
20654b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testCopyAndPaste_byKey() throws Throwable {
20666beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
206749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
206849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Type "abc".
2069b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
20709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
20716beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Select "bc"
20726beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
207349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
207449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
207549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Copy "bc"
2076b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_COPY);
207749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
20789560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
20796beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Set cursor between 'b' and 'c'.
20806beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Spannable) mTextView.getText(), 2, 2);
208149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
208249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
208349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Paste "bc"
2084b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_PASTE);
208549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        assertEquals("abbcc", mTextView.getText().toString());
208649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
20879560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
20886beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.selectAll((Spannable) mTextView.getText());
20896beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            KeyEvent copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
20906beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    KeyEvent.KEYCODE_COPY, 0, KeyEvent.META_SHIFT_LEFT_ON);
20916beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Shift + copy doesn't perform copy.
20926beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
20936beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
20946beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.paste);
20956beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("bcabbcc", mTextView.getText().toString());
20966beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
20976beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.selectAll((Spannable) mTextView.getText());
20986beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0,
20996beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    KeyEvent.META_CTRL_LEFT_ON);
21006beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Control + copy doesn't perform copy.
21016beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
21026beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
21036beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.paste);
21046beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("bcbcabbcc", mTextView.getText().toString());
21056beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
21066beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.selectAll((Spannable) mTextView.getText());
21076beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0,
21086beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON);
21096beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Control + Shift + copy doesn't perform copy.
21106beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
21116beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
21126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.paste);
21136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("bcbcbcabbcc", mTextView.getText().toString());
211449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
21158e9fc4a5b2274a1279261f1a36c5396b9884042dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
211649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    }
211749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
21186beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu    @UiThreadTest
2119a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2120b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCutAndPaste() {
2121b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
21226beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
21236beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.setText("abcd", BufferType.EDITABLE);
21246beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.setSelected(true);
21256beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
21266beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Cut "bc".
21276beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
21286beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.cut);
21296beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("ad", mTextView.getText().toString());
21306beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
21316beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Cut "ad".
21326beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        Selection.setSelection((Spannable) mTextView.getText(), 0, 2);
21336beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.cut);
21346beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("", mTextView.getText().toString());
21356beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
21366beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Paste "ad".
21376beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.paste);
21386beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("ad", mTextView.getText().toString());
2139b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2140b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2141a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
21424b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testCutAndPaste_byKey() throws Throwable {
21436beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
214449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
214549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Type "abc".
2146b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "abc");
21479560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
21486beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Select "bc"
21496beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
215049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
215149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
215249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Cut "bc"
2153b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_CUT);
215449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
21559560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
21566beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("a", mTextView.getText().toString());
21576beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Move cursor to the head
21586beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
215949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
216049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
216149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Paste "bc"
2162b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_PASTE);
216349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        assertEquals("bca", mTextView.getText().toString());
216449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
21654b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> {
21666beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.selectAll((Spannable) mTextView.getText());
21676beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            KeyEvent cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
21686beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    KeyEvent.KEYCODE_CUT, 0, KeyEvent.META_SHIFT_LEFT_ON);
21696beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Shift + cut doesn't perform cut.
21706beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
21716beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("bca", mTextView.getText().toString());
21726beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
21736beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0,
21746beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    KeyEvent.META_CTRL_LEFT_ON);
21756beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Control + cut doesn't perform cut.
21766beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
21776beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("bca", mTextView.getText().toString());
21786beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
21796beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0,
21806beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON);
21816beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Control + Shift + cut doesn't perform cut.
21826beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
21836beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertEquals("bca", mTextView.getText().toString());
218449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
21852de5a65a1540ec0b1ed03ec75c49ff9c242331baSiyamed Sinir        mInstrumentation.waitForIdleSync();
218649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    }
218749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
2188b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    private static boolean hasSpansAtMiddleOfText(final TextView textView, final Class<?> type) {
2189b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        final Spannable spannable = (Spannable)textView.getText();
2190b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        final int at = spannable.length() / 2;
2191b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        return spannable.getSpans(at, at, type).length > 0;
2192b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2193b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
21946beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu    @UiThreadTest
2195a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2196b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCutAndPaste_withAndWithoutStyle() {
2197b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
21986beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
21996beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.setText("example", BufferType.EDITABLE);
22006beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.setSelected(true);
22016beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
22026beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Set URLSpan.
22036beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        final Spannable spannable = (Spannable) mTextView.getText();
22046beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        spannable.setSpan(new URLSpan("http://example.com"), 0, spannable.length(), 0);
22056beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
22066beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
22076beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Cut entire text.
22086beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        Selection.selectAll((Spannable) mTextView.getText());
22096beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.cut);
22106beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("", mTextView.getText().toString());
22116beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
22126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Paste without style.
22136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.pasteAsPlainText);
22146beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("example", mTextView.getText().toString());
22156beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Check that the text doesn't have URLSpan.
22166beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertFalse(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
22176beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu
22186beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Paste with style.
22196beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        Selection.selectAll((Spannable) mTextView.getText());
22206beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        mTextView.onTextContextMenuItem(android.R.id.paste);
22216beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertEquals("example", mTextView.getText().toString());
22226beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // Check that the text has URLSpan.
22236beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
2224b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2225b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2227a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
22284ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    public void testSaveInstanceState() {
2229baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // should save text when freezesText=true
22304ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        TextView originalTextView = new TextView(mActivity);
22314ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        final String text = "This is a string";
22324ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        originalTextView.setText(text);
22334ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        originalTextView.setFreezesText(true);  // needed to actually save state
22344ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        Parcelable state = originalTextView.onSaveInstanceState();
22354ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
22364ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        TextView restoredTextView = new TextView(mActivity);
22374ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        restoredTextView.onRestoreInstanceState(state);
22384ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        assertEquals(text, restoredTextView.getText().toString());
22394ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    }
22404ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
22414ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    @UiThreadTest
2242a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2243baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_whenFreezesTextIsFalse() {
22444ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        final String text = "This is a string";
2245baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        { // should not save text when freezesText=false
2246baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for before saveInstanceState
2247baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView1 = new TextView(mActivity);
2248baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setFreezesText(false);
2249baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setText(text);
22504ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
2251baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for after saveInstanceState
2252baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView2 = new TextView(mActivity);
2253baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setFreezesText(false);
2254baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2255baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2256baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2257baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            assertEquals("", textView2.getText().toString());
2258baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        }
2259baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2260baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        { // should not save text even when textIsSelectable=true
2261baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for before saveInstanceState
2262baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView1 = new TextView(mActivity);
2263baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setFreezesText(false);
2264baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setTextIsSelectable(true);
2265baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setText(text);
2266baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2267baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for after saveInstanceState
2268baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView2 = new TextView(mActivity);
2269baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setFreezesText(false);
2270baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setTextIsSelectable(true);
2271baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2272baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2273baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2274baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            assertEquals("", textView2.getText().toString());
2275baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        }
2276baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2277baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2278baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2279baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2280a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2281baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_doesNotSaveSelectionWhenDoesNotExist() {
2282baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2283baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2284baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2285baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(true);
2286baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2287baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2288baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2289baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2290baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(true);
2291baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2292baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2293baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2294baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(-1, textView2.getSelectionStart());
2295baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(-1, textView2.getSelectionEnd());
2296baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2297baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2298baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2299baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2300a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2301baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_doesNotRestoreSelectionWhenTextIsAbsent() {
2302baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2303baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2304baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2305baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(false);
2306baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setTextIsSelectable(true);
2307baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2308baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
2309baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2310baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2311baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2312baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(false);
2313baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setTextIsSelectable(true);
2314baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2315baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2316baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2317baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals("", textView2.getText().toString());
2318baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        //when textIsSelectable, selection start and end are initialized to 0
2319baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(0, textView2.getSelectionStart());
2320baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(0, textView2.getSelectionEnd());
2321baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2322baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2323baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2324baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2325a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2326baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_savesSelectionWhenExists() {
2327baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2328baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2329baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2330baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(true);
2331baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setTextIsSelectable(true);
2332baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2333baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
2334baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2335baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2336baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2337baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(true);
2338baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setTextIsSelectable(true);
2339baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2340baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2341baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2342baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(textView1.getSelectionStart(), textView2.getSelectionStart());
2343baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(textView1.getSelectionEnd(), textView2.getSelectionEnd());
23444ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    }
23454ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
23464ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    @UiThreadTest
2347a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText() {
2349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
2350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int resId = R.string.text_view_hint;
2352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String result = mActivity.getResources().getString(resId);
2353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId, BufferType.EDITABLE);
2355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
2356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
2357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId, BufferType.SPANNABLE);
2359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
2360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
2361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(-1, BufferType.EDITABLE);
2364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception with illegal id");
2365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
2366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2370a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2371fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessHint() {
2372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext);
2373fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
2375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getHint());
2376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_blank);
2378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", mTextView.getHint());
2379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_string);
2381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_simple_hint),
2382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint());
2383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_resid);
2385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_hint),
2386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint());
2387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHint("This is hint");
2389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("This is hint", mTextView.getHint().toString());
2390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHint(R.string.text_view_hello);
2392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
2393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint().toString());
2394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Non-exist resid
2396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setHint(-1);
2398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if id is illegal");
2399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
2400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2403a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
24044b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessError() throws Throwable {
2405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
240853b55f734fb3cf52df49a79cf76d410a77fbe8f5Craig Mautner        final String errorText = "Oops! There is an error";
2409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
24109560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setError(null));
2411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2414a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable icon = TestUtils.getDrawable(mActivity, R.drawable.failed);
24159560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setError(errorText, icon));
2416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(errorText, mTextView.getError().toString());
2418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // can not check whether the drawable is set correctly
2419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
24209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setError(null, null));
2421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
24249560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
24256beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setKeyListener(DigitsKeyListener.getInstance(""));
24266beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText("", BufferType.EDITABLE);
24276beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setError(errorText);
24286beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
2429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(errorText, mTextView.getError().toString());
2433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2434b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "a");
2435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // a key event that will not change the TextView's text
2436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", mTextView.getText().toString());
2437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // The icon and error message will not be reset to null
243853b55f734fb3cf52df49a79cf76d410a77fbe8f5Craig Mautner        assertEquals(errorText, mTextView.getError().toString());
2439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
24409560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
24416beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setKeyListener(DigitsKeyListener.getInstance());
24426beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText("", BufferType.EDITABLE);
24436beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setError(errorText);
24446beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
2445300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu        });
2446300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu        mInstrumentation.waitForIdleSync();
2447300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu
2448b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "1");
2449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // a key event cause changes to the TextView's text
2450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("1", mTextView.getText().toString());
2451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the error message and icon will be cleared.
2452fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2455a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
24564b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessFilters() throws Throwable {
2457fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final InputFilter[] expected = { new InputFilter.AllCaps(),
2458fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new InputFilter.LengthFilter(2) };
2459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2460fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener
2461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                = QwertyKeyListener.getInstance(false, Capitalize.NONE);
24629560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
24636beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView = findTextView(R.id.textview_text);
24646beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setKeyListener(qwertyKeyListener);
24656beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText("", BufferType.EDITABLE);
24666beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setFilters(expected);
24676beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
2468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2469fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2470fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2471fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(expected, mTextView.getFilters());
2472fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2473b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "a");
2474fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text is capitalized by InputFilter.AllCaps
2475fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("A", mTextView.getText().toString());
2476b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "b");
2477fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text is capitalized by InputFilter.AllCaps
2478fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("AB", mTextView.getText().toString());
2479b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "c");
2480fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 'C' could not be accepted, because there is a length filter.
2481fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("AB", mTextView.getText().toString());
2482fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2483fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2484fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setFilters(null);
2485fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw IllegalArgumentException!");
2486fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IllegalArgumentException e) {
2487fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2488fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2489fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2490a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
24914b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testGetFocusedRect() throws Throwable {
2492fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Rect rc = new Rect();
2493fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2494fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Basic
24959560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new TextView(mActivity));
24969560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
2497fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2498fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX(), rc.left);
2499fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2500fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY(), rc.top);
2501fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2502fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2503fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Single line
2504fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2505fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2506fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX(), rc.left);
2507fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2508fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY(), rc.top);
2509fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2510fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
25119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
25126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setSelected(true);
25136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            SpannableString text = new SpannableString(mTextView.getText());
25146beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection(text, 3, 13);
25156beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(text);
2516fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2517fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2518fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2519fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
2520fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        /* Cursor coordinates from getPrimaryHorizontal() may have a fractional
2521fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * component, while the result of getFocusedRect is in int coordinates.
2522fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * It's not practical for these to match exactly, so we compare that the
2523fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * integer components match - there can be a fractional pixel
2524fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * discrepancy, which should be okay for all practical applications. */
2525fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3), rc.left);
2526fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(13), rc.right);
2527fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2528fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2529fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
25309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
25316beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setSelected(true);
25326beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            SpannableString text = new SpannableString(mTextView.getText());
25336beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection(text, 13, 3);
25346beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(text);
2535fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2536fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2537fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2538fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2539fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) - 2, rc.left);
2540fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) + 2, rc.right);
2541fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2542fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2543fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2544fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Multi lines
2545fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView = findTextView(R.id.textview_text_two_lines);
2546fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2547fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollX(), rc.left);
2548fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2549fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollY(), rc.top);
2550fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2551fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
25529560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
25536beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setSelected(true);
25546beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            SpannableString text = new SpannableString(mTextView.getText());
25556beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection(text, 2, 4);
25566beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(text);
2557fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2558fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2559fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2560fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2561fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(2), rc.left);
2562fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(4), rc.right);
2563fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2564fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2565fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
25669560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
25676beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setSelected(true);
25686beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            SpannableString text = new SpannableString(mTextView.getText());
25696beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            Selection.setSelection(text, 2, 10); // cross the "\n" and two lines
25706beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(text);
2571fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2572fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2573fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2574fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        Path path = new Path();
2575fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getLayout().getSelectionPath(2, 10, path);
2576fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        RectF rcf = new RectF();
2577fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        path.computeBounds(rcf, true);
2578fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2579a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(rcf.left - 1, (float) rc.left, 0.0f);
2580a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(rcf.right + 1, (float) rc.right, 0.0f);
2581fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2582fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(1), rc.bottom);
2583fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2584fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Exception
2585fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2586fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.getFocusedRect(null);
2587fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException!");
2588fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
2589fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2590fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2591fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2592a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
25939560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testGetLineCount() throws Throwable {
25949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = findTextView(R.id.textview_text));
25959560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
2596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // this is an one line text with default setting.
2597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2598fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2599fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it multi-lines
2600fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxWidth(mTextView.getWidth() / 3);
2601fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(1 < mTextView.getLineCount());
2602fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2603fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it to an one line
2604fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxWidth(Integer.MAX_VALUE);
2605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2606fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2607fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set min lines don't effect the lines count for actual text.
2608fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(12);
2609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2610fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
26119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new TextView(mActivity));
26129560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
2613fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the internal Layout has not been built.
2614fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getLayout());
2615fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineCount());
2616fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2617fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2618a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
26194b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testGetLineBounds() throws Throwable {
2620fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Rect rc = new Rect();
26219560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new TextView(mActivity));
26229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
2623fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineBounds(0, null));
2624fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2625fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineBounds(0, rc));
2626fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.left);
2627fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.right);
2628fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.top);
2629fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.bottom);
2630fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2631fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2632fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, null));
2633fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2634fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc));
2635fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.left);
2636fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getWidth(), rc.right);
2637fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.top);
2638fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getHeight(), rc.bottom);
2639fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
26409560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
26416beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setPadding(1, 2, 3, 4);
26426beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setGravity(Gravity.BOTTOM);
2643fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2644fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2645fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc));
2646fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getTotalPaddingLeft(), rc.left);
2647fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getWidth() - mTextView.getTotalPaddingRight(), rc.right);
2648fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getTotalPaddingTop(), rc.top);
2649fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getHeight() - mTextView.getTotalPaddingBottom(), rc.bottom);
2650fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2651fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2652a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
26534b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testGetBaseLine() throws Throwable {
26549560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new TextView(mActivity));
26559560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
2656fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getBaseline());
2657fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2658fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2659fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getLayout().getLineBaseline(0), mTextView.getBaseline());
2660fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
26619560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
26626beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setPadding(1, 2, 3, 4);
26636beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setGravity(Gravity.BOTTOM);
2664fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2665fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2666fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = mTextView.getTotalPaddingTop() + mTextView.getLayout().getLineBaseline(0);
2667fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getBaseline());
2668fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2669fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2670a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
26714b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testPressKey() throws Throwable {
26726beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        initTextViewForTypingOnUiThread();
2673fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2674b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "a");
2675fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("a", mTextView.getText().toString());
2676b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "b");
2677fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("ab", mTextView.getText().toString());
2678b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_DEL);
2679fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("a", mTextView.getText().toString());
2680fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2681fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2682a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
26834b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetIncludeFontPadding() throws Throwable {
2684fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2685ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getIncludeFontPadding());
26869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
26876beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setWidth(mTextView.getWidth() / 3);
26886beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setPadding(1, 2, 3, 4);
26896beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setGravity(Gravity.BOTTOM);
2690fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2691fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2692fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2693fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int oldHeight = mTextView.getHeight();
26949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setIncludeFontPadding(false));
2695fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2696fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2697fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getHeight() < oldHeight);
2698ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getIncludeFontPadding());
2699fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2700fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
27019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
2702a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2703fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testScroll() {
2704fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2705fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2706fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollX());
2707fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollY());
2708fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2709fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //don't set the Scroller, nothing changed.
2710fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.computeScroll();
2711fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollX());
2712fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollY());
2713fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2714fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //set the Scroller
2715fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Scroller s = new Scroller(mActivity);
2716fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(s);
2717fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.startScroll(0, 0, 320, 480, 0);
2718fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.abortAnimation();
2719fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.forceFinished(false);
2720fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setScroller(s);
2721fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2722fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.computeScroll();
2723fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(320, mTextView.getScrollX());
2724fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(480, mTextView.getScrollY());
2725fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2726fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2727a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
27289560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testDebug() throws Throwable {
27299560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
27309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView = new TextView(mActivity);
27319560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.debug(0);
27329560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText("Hello!");
27339560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
27349560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
2735fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2736fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(mTextView);
2737fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.debug(1);
2738fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2739fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
27409560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
2741a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
27429560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testSelection() throws Throwable {
2743fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2744fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "This is the content";
2745fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
2746fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.hasSelection());
2747fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2748fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.selectAll((Spannable) mTextView.getText());
2749fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
2750fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text.length(), mTextView.getSelectionEnd());
2751fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.hasSelection());
2752fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2753fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int selectionStart = 5;
2754fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int selectionEnd = 7;
2755fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), selectionStart);
2756fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionStart());
2757fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionEnd());
2758fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.hasSelection());
2759fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2760fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
2761fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionStart());
2762fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, mTextView.getSelectionEnd());
2763fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.hasSelection());
2764fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2765fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2766a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
27679560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testOnSelectionChangedIsTriggeredWhenSelectionChanges() throws Throwable {
27686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String text = "any text";
27699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = spy(new MockTextView(mActivity)));
27709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
27719560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setText(text, BufferType.SPANNABLE);
27726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // assert that there is currently no selection
27749560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertFalse(mTextView.hasSelection());
27756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // select all
27779560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        Selection.selectAll((Spannable) mTextView.getText());
2778b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        // After selectAll OnSelectionChanged should have been called
27799560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ((MockTextView) verify(mTextView, times(1))).onSelectionChanged(0, text.length());
27806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        reset(mTextView);
27826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // change selection
27839560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        Selection.setSelection((Spannable) mTextView.getText(), 1, 5);
27849560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ((MockTextView) verify(mTextView, times(1))).onSelectionChanged(1, 5);
27856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        reset(mTextView);
27876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // clear selection
27889560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        Selection.removeSelection((Spannable) mTextView.getText());
27899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ((MockTextView) verify(mTextView, times(1))).onSelectionChanged(-1, -1);
27906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
27916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
2792fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2793a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
2794fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessEllipsize() {
2795fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_ellipsize);
2796fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2797fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_default);
2798fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2799fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2800fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_none);
2801fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2802fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2803fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_start);
2804fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.START, mTextView.getEllipsize());
2805fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2806fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_middle);
2807fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.MIDDLE, mTextView.getEllipsize());
2808fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2809fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_end);
2810fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.END, mTextView.getEllipsize());
2811fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2812fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.START);
2813fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize());
2814fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2815fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
2816fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.MIDDLE, mTextView.getEllipsize());
2817fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2818fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.END);
2819fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.END, mTextView.getEllipsize());
2820fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2821fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(null);
2822fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2823fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2824fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(10);
2825fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.START);
2826fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("ThisIsAVeryLongVeryLongVeryLongVeryLongVeryLongWord");
2827fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.invalidate();
2828fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2829fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize());
2830fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no method to check if '...yLongVeryLongWord' is painted in the screen.
2831fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2832fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2833a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
283492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir    public void testEllipsizeAndMaxLinesForSingleLine() throws Throwable {
283592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // no maxline or ellipsize set, single line text
283692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvNoMaxLine = new TextView(mActivity);
283792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvNoMaxLine.setLineSpacing(0, 1.5f);
283892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvNoMaxLine.setText("a");
283992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
284092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // maxline set, no ellipsize, text with two lines
284192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvEllipsizeNone = new TextView(mActivity);
284292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setMaxLines(1);
284392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setLineSpacing(0, 1.5f);
284492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setText("a\na");
284592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
284692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // maxline set, ellipsize end, text with two lines
284792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvEllipsizeEnd = new TextView(mActivity);
284892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
284992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setMaxLines(1);
285092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setLineSpacing(0, 1.5f);
285192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setText("a\na");
28522deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
285392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
285492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
285592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT,
285692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
285792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvEllipsizeEnd, layoutParams);
285892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvEllipsizeNone, layoutParams);
285992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvNoMaxLine, layoutParams);
286092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
286192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout,
286292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                new ViewGroup.LayoutParams(
286392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                        ViewGroup.LayoutParams.MATCH_PARENT,
286492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                        ViewGroup.LayoutParams.MATCH_PARENT)));
28659560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
28662deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
286792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        assertEquals(tvEllipsizeEnd.getHeight(), tvEllipsizeNone.getHeight());
286892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
286992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        assertEquals(tvEllipsizeEnd.getHeight(), tvNoMaxLine.getHeight());
287092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
287192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        assertEquals(tvEllipsizeEnd.getLayout().getLineBaseline(0),
287292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                tvEllipsizeNone.getLayout().getLineBaseline(0));
287392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
287492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        assertEquals(tvEllipsizeEnd.getLayout().getLineBaseline(0),
287592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                tvNoMaxLine.getLayout().getLineBaseline(0));
287692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir    }
287792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
287892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir    @Test
287992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir    public void testEllipsizeAndMaxLinesForMultiLine() throws Throwable {
288092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // no maxline, no ellipsize, text with two lines
288192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvNoMaxLine = new TextView(mActivity);
288292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvNoMaxLine.setLineSpacing(0, 1.5f);
288392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvNoMaxLine.setText("a\na");
288492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
288592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // maxline set, no ellipsize, text with three lines
288692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvEllipsizeNone = new TextView(mActivity);
288792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setMaxLines(2);
288892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setLineSpacing(0, 1.5f);
288992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setText("a\na\na");
289092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
289192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // maxline set, ellipsize end, text with three lines
289292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvEllipsizeEnd = new TextView(mActivity);
289392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
289492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setMaxLines(2);
289592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setLineSpacing(0, 1.5f);
289692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setText("a\na\na");
28976031df7acadcd35236309edcbb046847735bda65Siyamed Sinir
28982deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
28992deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
290092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT,
290192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
29022deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
290392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvNoMaxLine, layoutParams);
290492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvEllipsizeEnd, layoutParams);
290592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvEllipsizeNone, layoutParams);
290692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
290792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        mActivityRule.runOnUiThread(() ->  mActivity.setContentView(layout,
290892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                new ViewGroup.LayoutParams(
290992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                        ViewGroup.LayoutParams.MATCH_PARENT,
291092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                        ViewGroup.LayoutParams.MATCH_PARENT)));
2911a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.waitForIdleSync();
29122deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
291392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        assertEquals(tvEllipsizeEnd.getHeight(), tvEllipsizeNone.getHeight());
291492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
291592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        assertEquals(tvEllipsizeEnd.getHeight(), tvNoMaxLine.getHeight());
291692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
291792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        for (int i = 0; i < tvEllipsizeEnd.getLineCount(); i++) {
291892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir            assertEquals("Should have the same baseline for line " + i,
291992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                    tvEllipsizeEnd.getLayout().getLineBaseline(i),
292092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                    tvEllipsizeNone.getLayout().getLineBaseline(i));
292192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
292292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir            assertEquals("Should have the same baseline for line " + i,
292392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                    tvEllipsizeEnd.getLayout().getLineBaseline(i),
292492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                    tvNoMaxLine.getLayout().getLineBaseline(i));
292592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        }
29262deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    }
29272deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
2928a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
292992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir    public void testEllipsizeAndMaxLinesForHint() throws Throwable {
293092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // no maxline, no ellipsize, hint with two lines
293192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvTwoLines = new TextView(mActivity);
293292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvTwoLines.setLineSpacing(0, 1.5f);
293392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvTwoLines.setHint("a\na");
29342deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
293592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // no maxline, no ellipsize, hint with three lines
293692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvThreeLines = new TextView(mActivity);
293792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvThreeLines.setLineSpacing(0, 1.5f);
293892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvThreeLines.setHint("a\na\na");
293992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
294092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // maxline set, ellipsize end, hint with three lines
294192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvEllipsizeEnd = new TextView(mActivity);
294292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
294392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setMaxLines(2);
294492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setLineSpacing(0, 1.5f);
294592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeEnd.setHint("a\na\na");
29462deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
294792cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        // maxline set, no ellipsize, hint with three lines
294892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        final TextView tvEllipsizeNone = new TextView(mActivity);
294992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setMaxLines(2);
295092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setLineSpacing(0, 1.5f);
295192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        tvEllipsizeNone.setHint("a\na\na");
29526031df7acadcd35236309edcbb046847735bda65Siyamed Sinir
29532deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
29542deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
295592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT,
295692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
29572deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
295892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvTwoLines, layoutParams);
295992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvEllipsizeEnd, layoutParams);
296092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvEllipsizeNone, layoutParams);
296192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        layout.addView(tvThreeLines, layoutParams);
29622deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
296392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        mActivityRule.runOnUiThread(() ->  mActivity.setContentView(layout,
296492cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                new ViewGroup.LayoutParams(
296592cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                        ViewGroup.LayoutParams.MATCH_PARENT,
296692cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                        ViewGroup.LayoutParams.MATCH_PARENT)));
2967a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.waitForIdleSync();
29682deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
296992cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        assertEquals("Non-ellipsized hint should not crop text at maxLines",
297092cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                tvThreeLines.getHeight(), tvEllipsizeNone.getHeight());
297192cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
297292cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir        assertEquals("Ellipsized hint should crop text at maxLines",
297392cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir                tvTwoLines.getHeight(), tvEllipsizeEnd.getHeight());
29742deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    }
29752deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
2976a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
29774b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testTextViewInWeigthenedLayoutChangesWidthAfterSetText() throws Throwable {
29789560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
29799560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView = new TextView(mActivity);
29809560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setEllipsize(TruncateAt.END);
29819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setSingleLine(true);
29829560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText("a");
2983672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
29849560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mSecondTextView = new TextView(mActivity);
29859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mSecondTextView.setSingleLine(true);
29869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mSecondTextView.setText("any");
29879560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
29889560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
2989672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2990672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        final LinearLayout layout = new LinearLayout(mActivity);
2991672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.setOrientation(LinearLayout.HORIZONTAL);
2992672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2993672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // TextView under test has weight 1, and width 0
29949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mTextView, new LinearLayout.LayoutParams(0,
2995672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
2996672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2997672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // other TextView has default weight
29989560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mSecondTextView, new LinearLayout.LayoutParams(
2999672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
3000672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT));
3001672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
3002672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // main layout params
3003672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.setLayoutParams(new ViewGroup.LayoutParams(
3004672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
3005672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
30069560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout));
3007a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.waitForIdleSync();
3008672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
30099560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        int oldWidth = mTextView.getWidth();
3010672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
30119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setText("aaa"));
3012a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.waitForIdleSync();
3013672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
3014672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        assertTrue("TextView should have larger width after a longer text is set",
30159560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.getWidth() > oldWidth);
3016672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir    }
3017672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
301892cd9119d1dbcb9664a830f216920d5bbde961a1Siyamed Sinir
30199560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
3020a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3021354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testAccessCursorVisible() {
3022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
3023fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCursorVisible(true);
3025354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.isCursorVisible());
3026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCursorVisible(false);
3027354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.isCursorVisible());
3028fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3031a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testPerformLongClick() {
3033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("This is content");
3035938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
3036938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        View.OnLongClickListener mockOnLongClickListener = mock(View.OnLongClickListener.class);
3037938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        when(mockOnLongClickListener.onLongClick(any(View.class))).thenReturn(Boolean.TRUE);
3038938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
3039938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        View.OnCreateContextMenuListener mockOnCreateContextMenuListener =
3040938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                mock(View.OnCreateContextMenuListener.class);
30414e47d86641f4cbf8269723cca1a2ca1250f9aa02Kirill Grouchnikov        doAnswer((InvocationOnMock invocation) -> {
30424e47d86641f4cbf8269723cca1a2ca1250f9aa02Kirill Grouchnikov            ((ContextMenu) invocation.getArguments() [0]).add("menu item");
30434e47d86641f4cbf8269723cca1a2ca1250f9aa02Kirill Grouchnikov            return null;
3044938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }).when(mockOnCreateContextMenuListener).onCreateContextMenu(
3045938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), any(View.class), any(ContextMenuInfo.class));
3046938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
3047938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        mTextView.setOnLongClickListener(mockOnLongClickListener);
3048938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        mTextView.setOnCreateContextMenuListener(mockOnCreateContextMenuListener);
3049fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.performLongClick());
3050938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnLongClickListener, times(1)).onLongClick(mTextView);
3051938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyZeroInteractions(mockOnCreateContextMenuListener);
3052fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3053938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        reset(mockOnLongClickListener);
3054938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        when(mockOnLongClickListener.onLongClick(any(View.class))).thenReturn(Boolean.FALSE);
3055fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.performLongClick());
3056938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnLongClickListener, times(1)).onLongClick(mTextView);
3057938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnCreateContextMenuListener, times(1)).onCreateContextMenu(
3058938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), eq(mTextView), any(ContextMenuInfo.class));
3059fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3060938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        reset(mockOnCreateContextMenuListener);
3061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setOnLongClickListener(null);
3062938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        doNothing().when(mockOnCreateContextMenuListener).onCreateContextMenu(
3063938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), any(View.class), any(ContextMenuInfo.class));
3064fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.performLongClick());
3065938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyNoMoreInteractions(mockOnLongClickListener);
3066938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnCreateContextMenuListener, times(1)).onCreateContextMenu(
3067938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), eq(mTextView), any(ContextMenuInfo.class));
3068fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3069fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3070fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3071a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3072fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testTextAttr() {
3073fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_textAttr);
3074fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getText
3075fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getString(R.string.text_view_hello), mTextView.getText().toString());
3076fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3077fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getCurrentTextColor
3078fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
3079fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
3080fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
3081fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
3082fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
3083fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHintTextColors().getDefaultColor());
3084fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
3085fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
3086fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTextScaleX
3088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1.2f, mTextView.getTextScaleX(), 0.01f);
3089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // setTextScaleX
3091fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(2.4f);
3092fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2.4f, mTextView.getTextScaleX(), 0.01f);
3093fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3094fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(0f);
3095fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0f, mTextView.getTextScaleX(), 0.01f);
3096fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3097fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(- 2.4f);
3098fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(- 2.4f, mTextView.getTextScaleX(), 0.01f);
3099fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3100fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTextSize
3101fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20f, mTextView.getTextSize(), 0.01f);
3102fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3103fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTypeface
3104119351956fc53fdd61bfbfb0d1ab43857cf7a6d7Peter Eliasson        // getTypeface will be null if android:typeface is set to normal,
3105c02a9f453c5c1255d668bbd8970f4585ab5ff494Alan Viverette        // and android:style is not set or is set to normal, and
3106c02a9f453c5c1255d668bbd8970f4585ab5ff494Alan Viverette        // android:fontFamily is not set
3107fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTypeface());
3108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3109fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT);
3110fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.DEFAULT, mTextView.getTypeface());
3111fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // null type face
3112fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(null);
3113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTypeface());
3114fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // default type face, bold style, note: the type face will be changed
3116fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // after call set method
3117fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
3118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle());
3119fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // null type face, BOLD style
3121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(null, Typeface.BOLD);
3122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle());
3123fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // old type face, null style
3125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT, 0);
3126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
3127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3130a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3131fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAppend() {
3132fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
3133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3134fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 1: check the original length, should be blank as initialised.
3135fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getText().length());
3136fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 2: append a string use append(CharSquence) into the original blank
3138fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // buffer, check the content. And upgrading it to BufferType.EDITABLE if it was
3139fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // not already editable.
3140fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getText() instanceof Editable);
3141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append.");
3142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.", mTextView.getText().toString());
3143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 3: append a string from 0~3.
3146fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append", 0, 3);
3147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.App", mTextView.getText().toString());
3148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 4: append a string from 0~0, nothing will be append as expected.
3151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append", 0, 0);
3152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.App", mTextView.getText().toString());
3153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3155fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 5: append a string from -3~3. check the wrong left edge.
3156fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3157fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append("Append", -3, 3);
3158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw StringIndexOutOfBoundsException");
3159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (StringIndexOutOfBoundsException e) {
3160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 6: append a string from 3~10. check the wrong right edge.
3163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append("Append", 3, 10);
3165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw StringIndexOutOfBoundsException");
3166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (StringIndexOutOfBoundsException e) {
3167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 7: append a null string.
3170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append(null);
3172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException");
3173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
3174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3176fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3177f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3178a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3179f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_doesNotAddLinksWhenAppendedTextDoesNotContainLinks() {
3180f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3181f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3182f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3183f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3184f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" another text without URL");
3185f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3186f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3187f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3188f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be zero", 0, urlSpans.length);
3189f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL another text without URL", text.toString());
3190f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3191f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3192f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3193a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3194f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_doesNotAddLinksWhenAutoLinkIsNotEnabled() {
3195f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3196f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3197f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3198f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3199f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3200f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3201f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3202f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be zero", 0, urlSpans.length);
3203f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL text with URL http://android.com", text.toString());
3204f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3205f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3206f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3207a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3208f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksWhenAutoLinkIsEnabled() {
3209f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3210f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3211f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3212f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3213f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3214f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3215f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3216f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3217f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length);
3218f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3219f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3220f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL text with URL http://android.com", text.toString());
3221f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3222f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3223f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3224a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3225f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksEvenWhenThereAreUrlsSetBefore() {
3226f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3227f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3228f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with URL http://android.com/before");
3229f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3230f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3231f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3232f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3233f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3234f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be two after appending another URL", 2, urlSpans.length);
3235f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("First URLSpan URL should be same",
3236f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com/before");
3237f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3238f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[1].getURL(), "http://android.com");
3239f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text with URL http://android.com/before text with URL http://android.com",
3240f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                text.toString());
3241f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3242f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3243f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3244a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3245f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_setsMovementMethodWhenTextContainsUrlAndAutoLinkIsEnabled() {
3246f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3247f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3248f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without a URL");
3249f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3250f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with a url: http://android.com");
3251f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3252f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertNotNull("MovementMethod should not be null when text contains url",
3253f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                mTextView.getMovementMethod());
3254f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertTrue("MovementMethod should be instance of LinkMovementMethod when text contains url",
3255f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                mTextView.getMovementMethod() instanceof LinkMovementMethod);
3256f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3257f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3258f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3259a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3260f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksWhenTextIsSpannableAndContainsUrlAndAutoLinkIsEnabled() {
3261f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3262f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3263f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without a URL");
3264f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3265f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(new SpannableString(" text with a url: http://android.com"));
3266f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3267f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3268f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3269f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length);
3270f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3271f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3272f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3273f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3274f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3275a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3276f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinkIfAppendedTextCompletesPartialUrlAtTheEndOfExistingText() {
3277f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3278f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3279f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with a partial url android.");
3280f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3281f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append("com");
3282f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3283f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3284f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3285f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending to partial URL",
3286f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                1, urlSpans.length);
3287f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3288f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3289f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3290f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3291f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3292a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3293f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinkIfAppendedTextUpdatesUrlAtTheEndOfExistingText() {
3294f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3295f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3296f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with a url http://android.com");
3297f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3298f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append("/textview");
3299f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3300f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3301f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3302f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should still be one after extending a URL", 1, urlSpans.length);
3303f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the new URL",
3304f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com/textview");
3305f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3306f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
33079560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
3308a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
33096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetLetterSpacing_returnsValueThatWasSet() {
33106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
33116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLetterSpacing(2f);
33126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("getLetterSpacing should return the value that was set",
3313a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov                2f, mTextView.getLetterSpacing(), 0.0f);
33146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
33156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
3316a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
33179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testSetLetterSpacingChangesTextWidth() throws Throwable {
33189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
33199560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView = new TextView(mActivity);
33209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText("aa");
33219560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setLetterSpacing(0f);
33229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setTextSize(8f);
33239560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
33249560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
33256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
33276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
33286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT,
33296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
33309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mTextView, layoutParams);
33316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
33326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33339560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout));
3334a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.waitForIdleSync();
33356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with zero letter spacing
33379560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final float zeroSpacing = mTextView.getLayout().getLineWidth(0);
33386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33399560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setLetterSpacing(1f));
3340a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.waitForIdleSync();
33416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with single letter spacing
33439560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final float singleSpacing = mTextView.getLayout().getLineWidth(0);
33446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33459560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setLetterSpacing(2f));
3346a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.waitForIdleSync();
33476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with double letter spacing
33499560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final float doubleSpacing = mTextView.getLayout().getLineWidth(0);
33506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Double spacing should have two times the spacing of single spacing",
33526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                doubleSpacing - zeroSpacing, 2f * (singleSpacing - zeroSpacing), 1f);
33536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
33546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33559560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
3356a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
33576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetFontFeatureSettings_returnsValueThatWasSet() {
33586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
33596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setFontFeatureSettings("\"smcp\" on");
33606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("getFontFeatureSettings should return the value that was set",
33616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                "\"smcp\" on", mTextView.getFontFeatureSettings());
33626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
33636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
336477030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka    @UiThreadTest
336577030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka    @Test
336677030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka    public void testSetGetFontVariationSettings() {
336777030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka        mTextView = new TextView(mActivity);
336877030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka
336977030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka        // The default font variation settings should be null.
337077030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka        assertNull(mTextView.getFontVariationSettings());
337177030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka
337277030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka        final String setting = "'wdth' 2.0";
337377030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka        mTextView.setFontVariationSettings(setting);
337477030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka        assertEquals(setting, mTextView.getFontVariationSettings());
337577030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka
337677030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka        mTextView.setFontVariationSettings("");
337777030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka        assertNull(mTextView.getFontVariationSettings());
337877030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka    }
337977030801ef1b43a5bad184f4e4b5f34ce67aa15cSeigo Nonaka
3380a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
33819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testGetOffsetForPositionSingleLineLtr() throws Throwable {
33826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // asserts getOffsetPosition returns correct values for a single line LTR text
33839560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final String text = "aaaaa";
33849560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
33859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView = new TextView(mActivity);
33869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText(text);
33879560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setTextSize(8f);
33889560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setSingleLine(true);
33899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
33909560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
33916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
3393a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
33946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
33959560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setCompoundDrawables(drawable, drawable, drawable, drawable);
33966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
33986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
33996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
34006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
34019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mTextView, layoutParams);
34026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
34036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34044b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout));
3405023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.waitForIdleSync();
34066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int firstOffset = 0;
34086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int lastOffset = text.length() - 1;
34096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int midOffset = text.length() / 2;
34106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view
34126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float x = 0f;
34139560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        float y = mTextView.getHeight() / 2f;
34149560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(firstOffset, mTextView.getOffsetForPosition(x, y));
34156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text
34179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = mTextView.getLayout().getLineWidth(0) - 1f;
34189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(lastOffset, mTextView.getOffsetForPosition(x, y));
34196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view
34219560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = mTextView.getWidth();
34229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(lastOffset + 1, mTextView.getOffsetForPosition(x, y));
34236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view - out of bounds
34256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = -1f;
34269560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(firstOffset, mTextView.getOffsetForPosition(x, y));
34276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text
34299560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = (float) Math.floor(mTextView.getLayout().getLineWidth(0) / 2f + 0.5f);
34309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(midOffset, mTextView.getOffsetForPosition(x, y));
34316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
34326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
3433a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
34349560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testGetOffsetForPositionMultiLineLtr() throws Throwable {
3435023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        final String line = "aaa\n";
34366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String threeLines = line + line + line;
34379560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
34389560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView = new TextView(mActivity);
34399560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText(threeLines);
34409560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setTextSize(8f);
34419560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setLines(2);
34429560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
34439560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
34446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
3446a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
34476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
34489560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setCompoundDrawables(drawable, drawable, drawable, drawable);
34496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
34516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
34526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
34536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
34549560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mTextView, layoutParams);
34556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
34566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34574b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout));
3458023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.waitForIdleSync();
34596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Rect lineBounds = new Rect();
34619560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.getLayout().getLineBounds(0, lineBounds);
34626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at first line
34646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float x = 0f;
34656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float y = lineBounds.height() / 2f;
34669560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0, mTextView.getOffsetForPosition(x, y));
34676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at first line
34699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = mTextView.getWidth() - 1f;
34709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length() - 1, mTextView.getOffsetForPosition(x, y));
34716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // update lineBounds to be the second line
34739560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.getLayout().getLineBounds(1, lineBounds);
34746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        y = lineBounds.top + lineBounds.height() / 2;
34756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at second line
34776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
34789560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length(), mTextView.getOffsetForPosition(x, y));
34796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text at second line
34819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = mTextView.getLayout().getLineWidth(1) - 1f;
34829560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length() + line.length() - 1, mTextView.getOffsetForPosition(x, y));
34836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at second line
34859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = mTextView.getWidth() - 1f;
34869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length() + line.length() - 1, mTextView.getOffsetForPosition(x, y));
34876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text at second line
34899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = (float) Math.floor(mTextView.getLayout().getLineWidth(1) / 2f + 0.5f);
34906beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // second line mid offset should not include next line, therefore subtract one
34919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length() + (line.length() - 1) / 2, mTextView.getOffsetForPosition(x, y));
34926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
34936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
3494a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
34959560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testGetOffsetForPositionMultiLineRtl() throws Throwable {
3496023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        final String line = "\u0635\u0635\u0635\n";
34976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String threeLines = line + line + line;
34989560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
34999560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView = new TextView(mActivity);
35009560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText(threeLines);
35019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setTextSize(8f);
35029560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setLines(2);
35039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
35049560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
35056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
3507a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
35086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
35099560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setCompoundDrawables(drawable, drawable, drawable, drawable);
35106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
35129560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final LayoutParams layoutParams = new LayoutParams(
35139560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                LayoutParams.MATCH_PARENT,
35149560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                LayoutParams.WRAP_CONTENT);
35159560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mTextView, layoutParams);
35166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
35176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35184b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout));
3519023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.waitForIdleSync();
35206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Rect lineBounds = new Rect();
35229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.getLayout().getLineBounds(0, lineBounds);
35236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at first line
35259560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        float x = mTextView.getWidth() - 1f;
35266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float y = lineBounds.height() / 2f;
35279560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0, mTextView.getOffsetForPosition(x, y));
35286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at first line
35306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
35319560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length() - 1, mTextView.getOffsetForPosition(x, y));
35326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // update lineBounds to be the second line
35349560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.getLayout().getLineBounds(1, lineBounds);
35356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        y = lineBounds.top + lineBounds.height() / 2f;
35366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at second line
35389560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = mTextView.getWidth() - 1f;
35399560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length(), mTextView.getOffsetForPosition(x, y));
35406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at second line
35426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
35439560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length() + line.length() - 1, mTextView.getOffsetForPosition(x, y));
35446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text at second line
35469560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = mTextView.getWidth() - mTextView.getLayout().getLineWidth(1) + 1f;
35479560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length() + line.length() - 1, mTextView.getOffsetForPosition(x, y));
35486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text at second line
35509560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        x = mTextView.getWidth() - (float) Math.floor(
35519560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.getLayout().getLineWidth(1) / 2f + 0.5f);
35526beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu        // second line mid offset should not include next line, therefore subtract one
35539560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(line.length() + (line.length() - 1) / 2, mTextView.getOffsetForPosition(x, y));
35546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
35556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35569560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
3557a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
35586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testIsTextSelectable_returnsFalseByDefault() {
3559a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        final TextView textView = new TextView(mActivity);
35606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText("any text");
35616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isTextSelectable());
35626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
35636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35649560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
3565a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
35666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testIsTextSelectable_returnsTrueIfSetTextIsSelectableCalledWithTrue() {
3567a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        final TextView textView = new TextView(mActivity);
35686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText("any text");
35696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextIsSelectable(true);
35706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isTextSelectable());
35716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
35726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35739560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
3574a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
35756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testSetIsTextSelectable() {
3576a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        final TextView textView = new TextView(mActivity);
35776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isTextSelectable());
35796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isFocusable());
35806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isFocusableInTouchMode());
35816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isClickable());
35826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isLongClickable());
35836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextIsSelectable(true);
35856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isTextSelectable());
35876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isFocusable());
35886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isFocusableInTouchMode());
35896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isClickable());
35906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isLongClickable());
35916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(textView.getMovementMethod());
35926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
3593f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3594a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
35954b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessTransformationMethod() throws Throwable {
3596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check the password attribute in xml
3597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_password);
3598fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView);
3599fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(PasswordTransformationMethod.getInstance(),
3600fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3601fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3602fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check the singleLine attribute in xml
3603fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_singleLine);
3604fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView);
3605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(SingleLineTransformationMethod.getInstance(),
3606fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3607fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3608fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener = QwertyKeyListener.getInstance(false,
3609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Capitalize.NONE);
3610fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final TransformationMethod method = PasswordTransformationMethod.getInstance();
3611fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change transformation method by function
36129560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
36136beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setKeyListener(qwertyKeyListener);
36146beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setTransformationMethod(method);
36156beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTransformedText = method.getTransformation(mTextView.getText(), mTextView);
3616fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
36176beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
3618fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3619fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3620fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(PasswordTransformationMethod.getInstance(),
3621fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3622fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3623b6d441382890b4cd603124ee8dd0e7af3dca5454Andrei Stingaceanu        CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, "H E 2*L O");
36249560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.append(" "));
3625fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3626fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3627354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // It will get transformed after a while
3628354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // We're waiting for transformation to "******"
3629354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(TIMEOUT, () -> mTransformedText.toString()
3630354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov                .equals("\u2022\u2022\u2022\u2022\u2022\u2022"));
3631fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3632fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set null
36339560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setTransformationMethod(null));
3634fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3635fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTransformationMethod());
3636fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3637fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3638fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3639a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3640fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testCompound() {
3641fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
3642fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int padding = 3;
3643fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Drawable[] drawables = mTextView.getCompoundDrawables();
3644fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[0]);
3645fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[1]);
3646fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[2]);
3647fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3648fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3649fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test setCompoundDrawablePadding and getCompoundDrawablePadding
3650fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablePadding(padding);
3651fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(padding, mTextView.getCompoundDrawablePadding());
3652fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3653fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using resid, 0 represents null
3654fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.start, R.drawable.pass,
3655fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                R.drawable.failed, 0);
3656fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3657fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3658fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3659a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        WidgetTestUtils.assertEquals(TestUtils.getBitmap(mActivity, R.drawable.start),
3660fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[0]).getBitmap());
3661fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3662a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        WidgetTestUtils.assertEquals(TestUtils.getBitmap(mActivity, R.drawable.pass),
3663fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[1]).getBitmap());
3664fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3665a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        WidgetTestUtils.assertEquals(TestUtils.getBitmap(mActivity, R.drawable.failed),
3666fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[2]).getBitmap());
3667fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3668fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3669fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3670a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable left = TestUtils.getDrawable(mActivity, R.drawable.blue);
3671a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable right = TestUtils.getDrawable(mActivity, R.drawable.yellow);
3672a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable top = TestUtils.getDrawable(mActivity, R.drawable.red);
3673fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3674fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using drawables directly
3675fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, null);
3676fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3677fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3678fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3679fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(left, drawables[0]);
3680fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3681fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(top, drawables[1]);
3682fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3683fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(right, drawables[2]);
3684fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3685fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3686fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3687fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check compound padding
3688fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingLeft() + padding + left.getIntrinsicWidth(),
3689fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingLeft());
3690fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingTop() + padding + top.getIntrinsicHeight(),
3691fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingTop());
3692fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingRight() + padding + right.getIntrinsicWidth(),
3693fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingRight());
3694fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom());
3695fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3696fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set bounds to drawables and set them again.
3697fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        left.setBounds(0, 0, 1, 2);
3698fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        right.setBounds(0, 0, 3, 4);
3699fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 5, 6);
3700fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // usinf drawables
3701fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(left, top, right, null);
3702fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3703fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3704fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3705fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(left, drawables[0]);
3706fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3707fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(top, drawables[1]);
3708fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3709fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(right, drawables[2]);
3710fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3711fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3712fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3713fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check compound padding
3714fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingLeft() + padding + left.getBounds().width(),
3715fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingLeft());
3716fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingTop() + padding + top.getBounds().height(),
3717fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingTop());
3718fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingRight() + padding + right.getBounds().width(),
3719fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingRight());
3720fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom());
3721fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3722fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
37236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @UiThreadTest
3724a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
37256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetCompoundDrawablesRelative() {
37266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // prepare textview
37276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
37286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
37296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // prepare drawables
3730a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable start = TestUtils.getDrawable(mActivity, R.drawable.blue);
3731a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable end = TestUtils.getDrawable(mActivity, R.drawable.yellow);
3732a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable top = TestUtils.getDrawable(mActivity, R.drawable.red);
3733a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable bottom = TestUtils.getDrawable(mActivity, R.drawable.black);
37346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(start);
37356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(end);
37366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(top);
37376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(bottom);
37386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
37396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Drawable[] drawables = mTextView.getCompoundDrawablesRelative();
37406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
37416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
37426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[0]);
37436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[1]);
37446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[2]);
37456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[3]);
37466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
37476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
37486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(start, top, end, bottom);
37496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
37506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
37516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
37526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
37536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(start, drawables[0]);
37546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(top, drawables[1]);
37556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(end, drawables[2]);
37566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(bottom, drawables[3]);
37576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
37586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
37596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(start, top, end, bottom);
37606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
37616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
37626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
37636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
37646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(start, drawables[0]);
37656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(top, drawables[1]);
37666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(end, drawables[2]);
37676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(bottom, drawables[3]);
37686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
37696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(null, null, null, null);
37706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
37716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
37726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
37736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
37746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[0]);
37756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[1]);
37766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[2]);
37776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[3]);
37786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
37796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
3780a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
37814b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSingleLine() throws Throwable {
37829560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new TextView(mActivity));
37839560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
37849560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
37859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        setSpannableText(mTextView, "This is a really long sentence"
3786013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                + " which can not be placed in one line on the screen.");
3787013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
3788013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        // Narrow layout assures that the text will get wrapped.
37896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout innerLayout = new FrameLayout(mActivity);
3790013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        innerLayout.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
37919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        innerLayout.addView(mTextView);
3792013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
3793013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        final FrameLayout layout = new FrameLayout(mActivity);
3794013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        layout.addView(innerLayout);
3795013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
37969560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
37976beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mActivity.setContentView(layout);
37989560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setSingleLine(true);
3799013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        });
3800013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        mInstrumentation.waitForIdleSync();
3801fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3802fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(SingleLineTransformationMethod.getInstance(),
38039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.getTransformationMethod());
3804da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3805da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        int singleLineWidth = 0;
3806da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        int singleLineHeight = 0;
3807da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
38089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        if (mTextView.getLayout() != null) {
38099560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            singleLineWidth = mTextView.getLayout().getWidth();
38109560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            singleLineHeight = mTextView.getLayout().getHeight();
3811da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3812fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
38139560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setSingleLine(false));
3814fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
38159560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(null, mTextView.getTransformationMethod());
3816da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
38179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        if (mTextView.getLayout() != null) {
38189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            assertTrue(mTextView.getLayout().getHeight() > singleLineHeight);
38199560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            assertTrue(mTextView.getLayout().getWidth() < singleLineWidth);
3820da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3821fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3822fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // same behaviours as setSingLine(true)
38239560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(mTextView::setSingleLine);
3824fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3825fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(SingleLineTransformationMethod.getInstance(),
38269560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.getTransformationMethod());
3827da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
38289560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        if (mTextView.getLayout() != null) {
38299560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            assertEquals(singleLineHeight, mTextView.getLayout().getHeight());
38309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            assertEquals(singleLineWidth, mTextView.getLayout().getWidth());
3831da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3832fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3833fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3834fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3835a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
383698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testAccessMaxLines() {
3837fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
38386031df7acadcd35236309edcbb046847735bda65Siyamed Sinir        mTextView.setWidth((int) (mTextView.getPaint().measureText(LONG_TEXT) / 4));
3839fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(LONG_TEXT);
3840fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3841fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int maxLines = 2;
3842fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > maxLines);
3843fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3844fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setMaxLines(maxLines);
3845fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestLayout();
3846fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
384798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(2, mTextView.getMaxLines());
384898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxHeight());
3849fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getHeight() <= maxLines * mTextView.getLineHeight());
3850fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3851fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3852636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    @UiThreadTest
3853a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3854636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    public void testHyphenationNotHappen_frequencyNone() {
3855636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        final int[] BREAK_STRATEGIES = {
3856636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.BREAK_STRATEGY_SIMPLE, Layout.BREAK_STRATEGY_HIGH_QUALITY,
3857636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.BREAK_STRATEGY_BALANCED };
3858636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3859636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView = findTextView(R.id.textview_text);
3860636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3861636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        for (int breakStrategy : BREAK_STRATEGIES) {
3862636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            for (int charWidth = 10; charWidth < 120; charWidth += 5) {
3863636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                // Change the text view's width to charWidth width.
38646031df7acadcd35236309edcbb046847735bda65Siyamed Sinir                final String substring = LONG_TEXT.substring(0, charWidth);
38656031df7acadcd35236309edcbb046847735bda65Siyamed Sinir                mTextView.setWidth((int) Math.ceil(mTextView.getPaint().measureText(substring)));
3866636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3867636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setText(LONG_TEXT);
3868636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setBreakStrategy(breakStrategy);
3869636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3870636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
3871636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3872636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.requestLayout();
3873636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.onPreDraw();  // For freezing the layout.
3874636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                Layout layout = mTextView.getLayout();
3875636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3876636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                final int lineCount = layout.getLineCount();
3877636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                for (int line = 0; line < lineCount; ++line) {
3878636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    final int lineEnd = layout.getLineEnd(line);
3879636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // In any width, any break strategy, hyphenation should not happen if
3880636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // HYPHENATION_FREQUENCY_NONE is specified.
3881636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    assertTrue(lineEnd == LONG_TEXT.length() ||
3882636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                            Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1)));
3883636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                }
3884636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            }
3885636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        }
3886636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    }
3887636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3888636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    @UiThreadTest
3889a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3890636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    public void testHyphenationNotHappen_breakStrategySimple() {
3891636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        final int[] HYPHENATION_FREQUENCIES = {
3892636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.HYPHENATION_FREQUENCY_NORMAL, Layout.HYPHENATION_FREQUENCY_FULL,
3893636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.HYPHENATION_FREQUENCY_NONE };
3894636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3895636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView = findTextView(R.id.textview_text);
3896636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3897636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        for (int hyphenationFrequency: HYPHENATION_FREQUENCIES) {
3898636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            for (int charWidth = 10; charWidth < 120; charWidth += 5) {
3899636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                // Change the text view's width to charWidth width.
39006031df7acadcd35236309edcbb046847735bda65Siyamed Sinir                final String substring = LONG_TEXT.substring(0, charWidth);
39016031df7acadcd35236309edcbb046847735bda65Siyamed Sinir                mTextView.setWidth((int) Math.ceil(mTextView.getPaint().measureText(substring)));
3902636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3903636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setText(LONG_TEXT);
3904636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
3905636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3906636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setHyphenationFrequency(hyphenationFrequency);
3907636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3908636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.requestLayout();
3909636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.onPreDraw();  // For freezing the layout.
3910636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                Layout layout = mTextView.getLayout();
3911636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3912636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                final int lineCount = layout.getLineCount();
3913636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                for (int line = 0; line < lineCount; ++line) {
3914636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    final int lineEnd = layout.getLineEnd(line);
3915636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // In any width, any hyphenation frequency, hyphenation should not happen if
3916636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // BREAK_STRATEGY_SIMPLE is specified.
3917636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    assertTrue(lineEnd == LONG_TEXT.length() ||
3918636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                            Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1)));
3919636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                }
3920636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            }
3921636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        }
3922636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    }
3923636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3924fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3925a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3926fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetMaxLinesException() {
392772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
392872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mActivity.setContentView(mTextView);
3929fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(mTextView.getWidth() >> 3);
393072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setMaxLines(-1);
3931fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3932fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3933a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
39344b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessMinLines() throws Throwable {
3935fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3936fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 3);
3937fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLines = mTextView.getLineCount();
3938fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3939fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(originalLines - 1);
3940fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight());
394198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalLines - 1, mTextView.getMinLines());
394298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinHeight());
3943fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3944fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(originalLines + 1);
3945fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight());
394698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalLines + 1, mTextView.getMinLines());
394798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinHeight());
3948fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3949fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3950a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
39514b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetLines() throws Throwable {
3952fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3953fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it multiple lines
3954fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 3);
3955fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLines = mTextView.getLineCount();
3956fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3957fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(originalLines - 1);
3958fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight());
3959fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3960fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(originalLines + 1);
3961fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight());
3962fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3963fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3964fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3965a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3966fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetLinesException() {
396772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
396872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mActivity.setContentView(mTextView);
396972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setWidth(mTextView.getWidth() >> 3);
397072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setLines(-1);
3971fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3972fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3973fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3974a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3975fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetExtendedPaddingTop() {
3976fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3977fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3978fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getExtendedPaddingTop());
3979fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3980fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
3981a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable top = TestUtils.getDrawable(mActivity, R.drawable.red);
3982fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 100, 10);
3983fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, top, null, null);
3984fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingTop(), mTextView.getExtendedPaddingTop());
3985fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3986fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3987fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLines(mTextView.getLineCount() - 1);
3988fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.BOTTOM);
3989fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3990fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getExtendedPaddingTop() > 0);
3991fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3992fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3993fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3994a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
3995fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetExtendedPaddingBottom() {
3996fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3997fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3998fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getExtendedPaddingBottom());
3999fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4000fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
4001a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable bottom = TestUtils.getDrawable(mActivity, R.drawable.red);
4002fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        bottom.setBounds(0, 0, 100, 10);
4003fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, null, null, bottom);
4004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingBottom(), mTextView.getExtendedPaddingBottom());
4005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4006fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
4007fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLines(mTextView.getLineCount() - 1);
4008fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER_VERTICAL);
4009fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4010fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getExtendedPaddingBottom() > 0);
4011fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4012fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4013a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
40144b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testGetTotalPaddingTop() throws Throwable {
4015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
4016fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
4017fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingTop());
4018fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4019fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
4020a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable top = TestUtils.getDrawable(mActivity, R.drawable.red);
4021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 100, 10);
40229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
40236beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setCompoundDrawables(null, top, null, null);
40246beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setLines(mTextView.getLineCount() - 1);
40256beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setGravity(Gravity.BOTTOM);
4026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
4027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4028fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getExtendedPaddingTop(), mTextView.getTotalPaddingTop());
4029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
4031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(mTextView.getLineCount() + 1);
4032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = mTextView.getHeight()
4033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingBottom()
4034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getLayout().getLineTop(mTextView.getLineCount());
4035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getTotalPaddingTop());
4036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4038a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
40394b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testGetTotalPaddingBottom() throws Throwable {
4040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
4041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
4042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingBottom());
4043fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4044fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
4045a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable bottom = TestUtils.getDrawable(mActivity, R.drawable.red);
4046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        bottom.setBounds(0, 0, 100, 10);
40479560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
40486beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setCompoundDrawables(null, null, null, bottom);
40496beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setLines(mTextView.getLineCount() - 1);
40506beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setGravity(Gravity.CENTER_VERTICAL);
4051fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
4052fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4053fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getExtendedPaddingBottom(), mTextView.getTotalPaddingBottom());
4054fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4055fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
4056fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(mTextView.getLineCount() + 1);
4057fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = ((mTextView.getHeight()
4058fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingBottom()
4059fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingTop()
4060fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getLayout().getLineBottom(mTextView.getLineCount())) >> 1)
4061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + mTextView.getExtendedPaddingBottom();
4062fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getTotalPaddingBottom());
4063fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4064fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4065fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
4066a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4067fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingLeft() {
4068fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
4069fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
4070fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingLeft());
4071fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4072fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
4073a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable left = TestUtils.getDrawable(mActivity, R.drawable.red);
4074fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        left.setBounds(0, 0, 10, 100);
4075fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(left, null, null, null);
4076fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.RIGHT);
4077fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft());
4078fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4079fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change width
4080fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(Integer.MAX_VALUE);
4081fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft());
4082fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4083fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4084fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
4085a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4086fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingRight() {
4087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
4088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
4089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingRight());
4090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4091fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
4092a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable right = TestUtils.getDrawable(mActivity, R.drawable.red);
4093fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        right.setBounds(0, 0, 10, 100);
4094fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, null, right, null);
4095fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER_HORIZONTAL);
4096fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight());
4097fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4098fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change width
4099fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(Integer.MAX_VALUE);
4100fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight());
4101fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4102fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
41039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4104a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4105fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetUrls() {
4106fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
4107fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        URLSpan[] spans = mTextView.getUrls();
4109fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, spans.length);
4110fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4111fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String url = "http://www.google.com";
4112fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String email = "name@gmail.com";
4113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String string = url + " mailto:" + email;
4114fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        SpannableString spannable = new SpannableString(string);
4115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new URLSpan(url), 0, url.length(), 0);
4116fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
4117fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
4118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, spans.length);
4119fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(url, spans[0].getURL());
4120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new URLSpan(email), 0, email.length(), 0);
4122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
4123fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
4125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
4126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(url, spans[0].getURL());
4127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(email, spans[1].getURL());
4128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test the situation that param what is not a URLSpan
4130fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new Object(), 0, 9, 0);
4131fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
4132fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
4133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
4134fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4135fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
41369560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4137a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4138fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetPadding() {
4139fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
4140fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPadding(0, 1, 2, 4);
4142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getPaddingLeft());
4143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getPaddingTop());
4144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getPaddingRight());
4145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(4, mTextView.getPaddingBottom());
4146fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPadding(10, 20, 30, 40);
4148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(10, mTextView.getPaddingLeft());
4149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20, mTextView.getPaddingTop());
4150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(30, mTextView.getPaddingRight());
4151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(40, mTextView.getPaddingBottom());
4152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
41549560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4155a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4156fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testDeprecatedSetTextAppearance() {
4157fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
4158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_All);
4160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
4162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20f, mTextView.getTextSize(), 0.01f);
4163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
4164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
4165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
4166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
4168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Colors);
4170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
4172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
4174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
4175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
4176fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_NotColors);
4178fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(17f, mTextView.getTextSize(), 0.01f);
4179fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
4180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Style);
4182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(null, mTextView.getTypeface());
4183fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
41859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4186a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4187fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testSetTextAppearance() {
4188fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView = new TextView(mActivity);
4189fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4190fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_All);
4191fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4192fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentTextColor());
4193fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(20f, mTextView.getTextSize(), 0.01f);
4194fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
4195fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.red),
4196fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentHintTextColor());
4197fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4198fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getLinkTextColors().getDefaultColor());
41996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
42006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mTextView.getHighlightColor());
4201fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4202fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_Colors);
4203fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4204fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentTextColor());
4205fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4206fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentHintTextColor());
4207fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
4208fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getLinkTextColors().getDefaultColor());
42096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(mActivity.getResources().getColor(R.drawable.red),
42106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mTextView.getHighlightColor());
4211fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4212fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_NotColors);
4213fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(17f, mTextView.getTextSize(), 0.01f);
4214fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
4215fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4216fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_Style);
4217fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(null, mTextView.getTypeface());
4218fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    }
4219fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
42209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4221a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4222fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testAccessCompoundDrawableTint() {
4223fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView = new TextView(mActivity);
4224fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4225fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        ColorStateList colors = ColorStateList.valueOf(Color.RED);
4226fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setCompoundDrawableTintList(colors);
4227fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setCompoundDrawableTintMode(PorterDuff.Mode.XOR);
4228fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertSame(colors, mTextView.getCompoundDrawableTintList());
4229fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4230f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4231f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        // Ensure the tint is preserved across drawable changes.
4232f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawablesRelative(null, null, null, null);
4233f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4234f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4235f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4236f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawables(null, null, null, null);
4237f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4238f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4239f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4240f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr1 = new ColorDrawable(Color.RED);
4241f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr2 = new ColorDrawable(Color.GREEN);
4242f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr3 = new ColorDrawable(Color.BLUE);
4243f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr4 = new ColorDrawable(Color.YELLOW);
4244f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawables(dr1, dr2, dr3, dr4);
4245f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4246f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4247fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    }
4248fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4249a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
42504b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetHorizontallyScrolling() throws Throwable {
4251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make the text view has more than one line
4252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
4253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 1);
4254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > 1);
4255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHorizontallyScrolling(true);
4257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
4258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHorizontallyScrolling(false);
4260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > 1);
4261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4263a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
42649560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testComputeHorizontalScrollRange() throws Throwable {
42659560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new MockTextView(mActivity));
42669560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
4267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test when layout is null
42689560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getLayout());
42699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(mTextView.getWidth(),
42709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                ((MockTextView) mTextView).computeHorizontalScrollRange());
4271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
42729560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> ((MockTextView) mTextView).setFrame(0, 0, 40, 50));
42739560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
42749560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(mTextView.getWidth(),
42759560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                ((MockTextView) mTextView).computeHorizontalScrollRange());
4276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set the layout
42789560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout(mTextView);
42799560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(mTextView.getLayout().getWidth(),
42809560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                ((MockTextView) mTextView).computeHorizontalScrollRange());
4281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4283a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
42849560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testComputeVerticalScrollRange() throws Throwable {
42859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = new MockTextView(mActivity));
42869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
42879560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
4288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test when layout is null
42899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getLayout());
42909560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0, ((MockTextView) mTextView).computeVerticalScrollRange());
4291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
42929560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> ((MockTextView) mTextView).setFrame(0, 0, 40, 50));
42939560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
42949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(mTextView.getHeight(), ((MockTextView) mTextView).computeVerticalScrollRange());
4295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //set the layout
42979560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout(mTextView);
42989560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(mTextView.getLayout().getHeight(),
42999560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                ((MockTextView) mTextView).computeVerticalScrollRange());
4300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4302a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
43039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testDrawableStateChanged() throws Throwable {
43049560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = spy(new MockTextView(mActivity)));
43059560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
43069560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        reset(mTextView);
43079560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.refreshDrawableState();
43089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ((MockTextView) verify(mTextView, times(1))).drawableStateChanged();
4309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
43119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4312a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetDefaultEditable() {
43149560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView = new MockTextView(mActivity);
4315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //the TextView#getDefaultEditable() does nothing, and always return false.
43179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertFalse(((MockTextView) mTextView).getDefaultEditable());
4318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
43209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4321a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetDefaultMovementMethod() {
4323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //the TextView#getDefaultMovementMethod() does nothing, and always return null.
4326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getDefaultMovementMethod());
4327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
43299560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4330a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetFrame() {
4332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //Assign a new size to this view
4335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.setFrame(0, 0, 320, 480));
4336b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(0, textView.getLeft());
4337b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(0, textView.getTop());
4338b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(320, textView.getRight());
4339b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(480, textView.getBottom());
4340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //Assign a same size to this view
4342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(textView.setFrame(0, 0, 320, 480));
4343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //negative input
4345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.setFrame(-1, -1, -1, -1));
4346b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(-1, textView.getLeft());
4347b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(-1, textView.getTop());
4348b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(-1, textView.getRight());
4349b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(-1, textView.getBottom());
4350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4352a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
43534b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testMarquee() throws Throwable {
4354354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Both are pointing to the same object. This works around current limitation in CTS
4355354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // coverage report tool for properly reporting coverage of base class method calls.
43569560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
43579560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mSecondTextView = new MockTextView(mActivity);
4358354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
43599560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView = mSecondTextView;
43609560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText(LONG_TEXT);
43619560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setSingleLine();
43629560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setEllipsize(TruncateAt.MARQUEE);
43639560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setLayoutParams(new LayoutParams(100, 100));
43649560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
43659560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
4366bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu
4367bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu        final FrameLayout layout = new FrameLayout(mActivity);
43689560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mTextView);
4369bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu
4370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make the fading to be shown
43719560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setHorizontalFadingEdgeEnabled(true);
4372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
43739560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout));
4374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
43769560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        TestSelectedRunnable runnable = new TestSelectedRunnable(mTextView) {
4377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
43789560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.setMarqueeRepeatLimit(-1);
4379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // force the marquee to start
4380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected1();
43819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.setSelected(true);
4382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected2();
4383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
4384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
43859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(runnable);
4386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // wait for the marquee to run
4388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // fading is shown on both sides if the marquee runs for a while
43899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        PollingCheck.waitFor(TIMEOUT, () ->
43909560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                ((MockTextView) mSecondTextView).getLeftFadingEdgeStrength() > 0.0f
43919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                        && ((MockTextView) mSecondTextView).getRightFadingEdgeStrength() > 0.0f);
4392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
43930f095ca986d7558f9f5260c71a12cef4474d9da3Siyamed Sinir        // wait for left marquee to fully apply
43949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        PollingCheck.waitFor(TIMEOUT, () ->
43959560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                ((MockTextView) mSecondTextView).getLeftFadingEdgeStrength() > 0.99f);
4396354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
4397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(runnable.getIsSelected1());
4398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(runnable.getIsSelected2());
43999560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(-1, mTextView.getMarqueeRepeatLimit());
4400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        runnable = new TestSelectedRunnable(mTextView) {
4402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
44039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.setMarqueeRepeatLimit(0);
4404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // force the marquee to stop
4405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected1();
44069560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.setSelected(false);
4407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected2();
44089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                mTextView.setGravity(Gravity.LEFT);
4409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
4410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
4411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // force the marquee to stop
44129560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(runnable);
4413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(runnable.getIsSelected1());
4415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(runnable.getIsSelected2());
44169560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0.0f, ((MockTextView) mSecondTextView).getLeftFadingEdgeStrength(), 0.01f);
44179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(((MockTextView) mSecondTextView).getRightFadingEdgeStrength() > 0.0f);
44189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0, mTextView.getMarqueeRepeatLimit());
4419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setGravity(Gravity.RIGHT));
4421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
44229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(((MockTextView) mSecondTextView).getLeftFadingEdgeStrength() > 0.0f);
44239560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0.0f, ((MockTextView) mSecondTextView).getRightFadingEdgeStrength(), 0.01f);
4424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44259560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setGravity(Gravity.CENTER_HORIZONTAL));
4426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no left fading (Is it correct?)
44289560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0.0f, ((MockTextView) mSecondTextView).getLeftFadingEdgeStrength(), 0.01f);
44299560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(((MockTextView) mSecondTextView).getRightFadingEdgeStrength() > 0.0f);
4430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44329560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4433a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
44346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetMarqueeRepeatLimit() {
44356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
44366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
44376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setMarqueeRepeatLimit(10);
44386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(10, textView.getMarqueeRepeatLimit());
44396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
44406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
44419560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4442a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessInputExtras() throws XmlPullParserException, IOException {
44449560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView = new TextView(mActivity);
44459560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setText(null, BufferType.EDITABLE);
44469560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_TEXT);
4447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // do not create the extras
44499560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getInputExtras(false));
4450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // create if it does not exist
44529560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        Bundle inputExtras = mTextView.getInputExtras(true);
4453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(inputExtras);
4454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(inputExtras.isEmpty());
4455fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4456fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // it is created already
44579560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNotNull(mTextView.getInputExtras(false));
4458fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
44609560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setInputExtras(R.xml.input_extras);
4461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException!");
4462fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
4463fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
4464fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4465fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44669560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4467a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessContentType() {
44699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView = new TextView(mActivity);
44709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setText(null, BufferType.EDITABLE);
44719560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setKeyListener(null);
44729560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setTransformationMethod(null);
4473fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44749560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_DATETIME
4475fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL);
4476fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
44779560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_DATETIME_VARIATION_NORMAL, mTextView.getInputType());
44789560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getKeyListener() instanceof DateTimeKeyListener);
4479fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44809560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_DATETIME
4481fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE);
4482fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
44839560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_DATETIME_VARIATION_DATE, mTextView.getInputType());
44849560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getKeyListener() instanceof DateKeyListener);
4485fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_DATETIME
4487fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME);
4488fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
44899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_DATETIME_VARIATION_TIME, mTextView.getInputType());
44909560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getKeyListener() instanceof TimeKeyListener);
4491fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
44929560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_NUMBER
4493fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4494fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED);
4495fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_NUMBER
4496fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
44979560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_NUMBER_FLAG_SIGNED, mTextView.getInputType());
44989560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertSame(mTextView.getKeyListener(), DigitsKeyListener.getInstance(true, true));
4499fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45009560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_PHONE);
45019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(InputType.TYPE_CLASS_PHONE, mTextView.getInputType());
45029560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getKeyListener() instanceof DialerKeyListener);
4503fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45049560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_TEXT
4505fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
4506fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
45079560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, mTextView.getInputType());
45089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertSame(mTextView.getKeyListener(), TextKeyListener.getInstance(true, Capitalize.NONE));
4509fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45109560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setSingleLine();
45119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getTransformationMethod() instanceof SingleLineTransformationMethod);
45129560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_TEXT
4513fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4514fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
4515fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4516fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
45179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, mTextView.getInputType());
45189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertSame(mTextView.getKeyListener(),
4519fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.CHARACTERS));
45209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getTransformationMethod());
4521fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_TEXT
4523fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
4524fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
45259560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_TEXT_FLAG_CAP_WORDS, mTextView.getInputType());
45269560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertSame(mTextView.getKeyListener(),
4527fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.WORDS));
45289560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4529fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_CLASS_TEXT
4531fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
4532fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
45339560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, mTextView.getInputType());
45349560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertSame(mTextView.getKeyListener(),
4535fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.SENTENCES));
4536fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45379560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setInputType(InputType.TYPE_NULL);
45389560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(InputType.TYPE_NULL, mTextView.getInputType());
45399560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getKeyListener() instanceof TextKeyListener);
4540fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4541fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45429560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4543a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4544fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessRawContentType() {
45459560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView = new TextView(mActivity);
45469560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setText(null, BufferType.EDITABLE);
45479560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setKeyListener(null);
45489560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setTransformationMethod(null);
4549fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45509560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4551fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL);
4552fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
45539560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_DATETIME_VARIATION_NORMAL, mTextView.getInputType());
45549560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getTransformationMethod());
45559560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4556fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45579560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4558fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE);
4559fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
45609560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_DATETIME_VARIATION_DATE, mTextView.getInputType());
45619560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getTransformationMethod());
45629560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4563fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45649560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4565fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME);
4566fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
45679560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_DATETIME_VARIATION_TIME, mTextView.getInputType());
45689560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getTransformationMethod());
45699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4570fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45719560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_NUMBER
4572fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4573fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED);
4574fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_NUMBER
4575fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
45769560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_NUMBER_FLAG_SIGNED, mTextView.getInputType());
45779560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getTransformationMethod());
45789560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4579fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45809560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_PHONE);
45819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(InputType.TYPE_CLASS_PHONE, mTextView.getInputType());
45829560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getTransformationMethod());
45839560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4584fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_TEXT
4586fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
4587fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
45889560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, mTextView.getInputType());
45899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getTransformationMethod());
45909560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4591fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
45929560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setSingleLine();
45939560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getTransformationMethod() instanceof SingleLineTransformationMethod);
45949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_TEXT
4595fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
4597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4598fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
45999560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, mTextView.getInputType());
46009560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getTransformationMethod() instanceof SingleLineTransformationMethod);
46019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4602fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
46039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_TEXT
4604fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
4605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
46069560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_TEXT_FLAG_CAP_WORDS, mTextView.getInputType());
46079560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getTransformationMethod() instanceof SingleLineTransformationMethod);
46089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
46109560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_CLASS_TEXT
4611fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
4612fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
46139560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, mTextView.getInputType());
46149560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getTransformationMethod() instanceof SingleLineTransformationMethod);
46159560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4616fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
46179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setRawInputType(InputType.TYPE_NULL);
46189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.getTransformationMethod() instanceof SingleLineTransformationMethod);
46199560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertNull(mTextView.getKeyListener());
4620fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4621fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
46229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4623a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
462472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testVerifyDrawable() {
46259560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView = new MockTextView(mActivity);
462672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4627a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable d = TestUtils.getDrawable(mActivity, R.drawable.pass);
46289560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertFalse(((MockTextView ) mTextView).verifyDrawable(d));
462972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
46309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setCompoundDrawables(null, d, null, null);
46319560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(((MockTextView ) mTextView).verifyDrawable(d));
463272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
463372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4634a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
463572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessPrivateImeOptions() {
463672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
463772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getPrivateImeOptions());
463872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
463972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setPrivateImeOptions("com.example.myapp.SpecialMode=3");
464072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("com.example.myapp.SpecialMode=3", mTextView.getPrivateImeOptions());
464172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
464272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setPrivateImeOptions(null);
464372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getPrivateImeOptions());
464472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
464572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4646a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
464772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testSetOnEditorActionListener() {
464872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
464972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
465098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView.OnEditorActionListener mockOnEditorActionListener =
465198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                mock(TextView.OnEditorActionListener.class);
465298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verifyZeroInteractions(mockOnEditorActionListener);
465372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
465498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setOnEditorActionListener(mockOnEditorActionListener);
465598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verifyZeroInteractions(mockOnEditorActionListener);
465672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
465772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.onEditorAction(EditorInfo.IME_ACTION_DONE);
465898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockOnEditorActionListener, times(1)).onEditorAction(mTextView,
465998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                EditorInfo.IME_ACTION_DONE, null);
466072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
466172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4662a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
466372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessImeOptions() {
466472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
466572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions());
466672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
466772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_ACTION_GO);
466872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_ACTION_GO, mTextView.getImeOptions());
466972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
467072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_ACTION_DONE);
467172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_ACTION_DONE, mTextView.getImeOptions());
467272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
467372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_NULL);
467472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions());
467572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
467672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4677a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
467872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessImeActionLabel() {
467972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
468072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getImeActionLabel());
468172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, mTextView.getImeActionId());
468272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
468372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeActionLabel("pinyin", 1);
468472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("pinyin", mTextView.getImeActionLabel().toString());
468572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(1, mTextView.getImeActionId());
468672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
468772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
46889560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4689a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4690d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa    public void testAccessImeHintLocales() {
4691d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        final TextView textView = new TextView(mActivity);
4692d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setText("", BufferType.EDITABLE);
4693d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setKeyListener(null);
4694d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setRawInputType(InputType.TYPE_CLASS_TEXT);
4695d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        assertNull(textView.getImeHintLocales());
4696d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        {
4697d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            final EditorInfo editorInfo = new EditorInfo();
4698d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            textView.onCreateInputConnection(editorInfo);
4699d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            assertNull(editorInfo.hintLocales);
4700d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        }
4701d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa
4702d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        final LocaleList localeList = LocaleList.forLanguageTags("en-PH,en-US");
4703d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setImeHintLocales(localeList);
4704d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        assertEquals(localeList, textView.getImeHintLocales());
4705d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        {
4706d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            final EditorInfo editorInfo = new EditorInfo();
4707d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            textView.onCreateInputConnection(editorInfo);
4708d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            assertEquals(localeList, editorInfo.hintLocales);
4709d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        }
4710d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa    }
4711d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa
4712c873101a88e7ba584065de5e912508237378ca99Victoria Lease    @UiThreadTest
4713a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
471472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testSetExtractedText() {
471572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
471672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
471772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView.getText().toString());
471872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
471972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedText et = new ExtractedText();
4720ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4721ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Update text and selection.
472272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        et.text = "test";
4723ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionStart = 0;
4724ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionEnd = 2;
472572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
472672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setExtractedText(et);
472772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("test", mTextView.getText().toString());
4728ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(0, mTextView.getSelectionStart());
4729ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, mTextView.getSelectionEnd());
4730ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4731ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Use partialStartOffset and partialEndOffset
4732ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialStartOffset = 2;
4733ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialEndOffset = 3;
4734ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.text = "x";
4735ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionStart = 2;
4736ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionEnd = 3;
4737ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4738ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        mTextView.setExtractedText(et);
4739ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("text", mTextView.getText().toString());
4740ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, mTextView.getSelectionStart());
4741ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, mTextView.getSelectionEnd());
4742ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4743ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Update text with spans.
4744ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final SpannableString ss = new SpannableString("ex");
4745ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        ss.setSpan(new UnderlineSpan(), 0, 2, 0);
4746ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        ss.setSpan(new URLSpan("ctstest://TextView/test"), 1, 2, 0);
4747ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4748ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.text = ss;
4749ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialStartOffset = 1;
4750ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialEndOffset = 3;
4751ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        mTextView.setExtractedText(et);
4752ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4753ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("text", mTextView.getText().toString());
4754ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final Editable editable = mTextView.getEditableText();
4755ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final UnderlineSpan[] underlineSpans = mTextView.getEditableText().getSpans(
4756ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi                0, editable.length(), UnderlineSpan.class);
4757ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, underlineSpans.length);
4758ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, editable.getSpanStart(underlineSpans[0]));
4759ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, editable.getSpanEnd(underlineSpans[0]));
4760ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4761ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final URLSpan[] urlSpans = mTextView.getEditableText().getSpans(
4762ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi                0, editable.length(), URLSpan.class);
4763ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, urlSpans.length);
4764ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, editable.getSpanStart(urlSpans[0]));
4765ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, editable.getSpanEnd(urlSpans[0]));
4766ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("ctstest://TextView/test", urlSpans[0].getURL());
476772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
476872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4769a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
477072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testMoveCursorToVisibleOffset() throws Throwable {
477172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
477272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
477372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // not a spannable text
47744b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> assertFalse(mTextView.moveCursorToVisibleOffset()));
477572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
477672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
477772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // a selection range
477872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        final String spannableText = "text";
47796b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu        mActivityRule.runOnUiThread(() ->  mTextView = new TextView(mActivity));
47809560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
478172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
47824b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
4783a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov                () -> mTextView.setText(spannableText, BufferType.SPANNABLE));
478472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
478572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        Selection.setSelection((Spannable) mTextView.getText(), 0, spannableText.length());
478672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
478772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, mTextView.getSelectionStart());
478872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(spannableText.length(), mTextView.getSelectionEnd());
47894b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> assertFalse(mTextView.moveCursorToVisibleOffset()));
479072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
479172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
479272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // a spannable without range
47934b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> {
47946beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView = findTextView(R.id.textview_text);
47956beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(spannableText, BufferType.SPANNABLE);
479672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
479772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
479872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
47994b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> assertTrue(mTextView.moveCursorToVisibleOffset()));
480072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
480172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
480272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4803a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
4804afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu    public void testIsInputMethodTarget() throws Throwable {
480572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
480672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.isInputMethodTarget());
480772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
480872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.isFocused());
48094b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> {
48106beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setFocusable(true);
48116beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
48126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu         });
4813afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        mInstrumentation.waitForIdleSync();
4814afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        assertTrue(mTextView.isFocused());
481504d12809ae731ea2aea678707bcc606f05efb23aBrian Muramatsu
4816b7724cefaf6067b1f6b59d3abae73828b48945c3Kirill Grouchnikov        PollingCheck.waitFor(mTextView::isInputMethodTarget);
481772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
481872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
48199560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4820a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
48216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testBeginEndBatchEditAreNotCalledForNonEditableText() {
4822b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        final TextView mockTextView = spy(new TextView(mActivity));
4823b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir
4824b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        // TextView should not call onBeginBatchEdit or onEndBatchEdit during initialization
4825b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onBeginBatchEdit();
4826b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onEndBatchEdit();
48276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
482872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
48296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.beginBatchEdit();
4830b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        // Since TextView doesn't support editing, the callbacks should not be called
4831b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onBeginBatchEdit();
4832b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onEndBatchEdit();
48336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
48346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.endBatchEdit();
4835b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        // Since TextView doesn't support editing, the callbacks should not be called
4836b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onBeginBatchEdit();
4837b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onEndBatchEdit();
48386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
48396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
4840a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
48414b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testBeginEndBatchEditCallbacksAreCalledForEditableText() throws Throwable {
48429560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView = spy(new TextView(mActivity)));
48439560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
48446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
4845a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        final FrameLayout layout = new FrameLayout(mActivity);
48466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
48476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
48486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
48499560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        layout.addView(mTextView, layoutParams);
48506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
48516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
48529560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layout));
48536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
48546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
48559560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
48569560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
48579560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText("", BufferType.EDITABLE);
48589560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.requestFocus();
48596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
48606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
48616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
48629560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        reset(mTextView);
48639560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertTrue(mTextView.hasFocus());
48649560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(mTextView, never()).onBeginBatchEdit();
48659560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(mTextView, never()).onEndBatchEdit();
48666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
48679560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.beginBatchEdit();
48686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
48699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(mTextView, times(1)).onBeginBatchEdit();
48709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(mTextView, never()).onEndBatchEdit();
4871b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir
48729560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        reset(mTextView);
48739560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.endBatchEdit();
48749560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(mTextView, never()).onBeginBatchEdit();
48759560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(mTextView, times(1)).onEndBatchEdit();
487672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
487772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
487872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
4879a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
488072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testBringPointIntoView() throws Throwable {
488172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
488272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.bringPointIntoView(1));
488372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
488472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.layout(0, 0, 100, 100);
488572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.bringPointIntoView(2));
488672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
488772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4888a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
488972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testCancelLongPress() {
489072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
48919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, mTextView);
489272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.cancelLongPress();
489372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
489472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
489572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
4896a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
489772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testClearComposingText() {
489872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
489972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setText("Hello world!", BufferType.SPANNABLE);
490072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        Spannable text = (Spannable) mTextView.getText();
490172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
490272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
490372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
490472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
490572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        BaseInputConnection.setComposingSpans((Spannable) mTextView.getText());
490672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, BaseInputConnection.getComposingSpanStart(text));
490772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, BaseInputConnection.getComposingSpanStart(text));
490872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
490972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.clearComposingText();
491072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
491172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
491272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
491372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
49149560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4915a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
491672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testComputeVerticalScrollExtent() {
49179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView = new MockTextView(mActivity);
49189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0, ((MockTextView) mTextView).computeVerticalScrollExtent());
491972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4920a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable d = TestUtils.getDrawable(mActivity, R.drawable.pass);
49219560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.setCompoundDrawables(null, d, null, d);
492272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
49239560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        assertEquals(0, ((MockTextView) mTextView).computeVerticalScrollExtent());
492472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
492572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
492672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
4927a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
492872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testDidTouchFocusSelect() {
4929c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        mTextView = new EditText(mActivity);
493072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.didTouchFocusSelect());
493172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
493272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setFocusable(true);
493372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.requestFocus();
493472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.didTouchFocusSelect());
493572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
493672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4937a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
49384b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSelectAllJustAfterTap() throws Throwable {
49390ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Prepare an EditText with focus.
49409560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
49416beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView = new EditText(mActivity);
49426beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mActivity.setContentView(mTextView);
49430ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
49446beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertFalse(mTextView.didTouchFocusSelect());
49456beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setFocusable(true);
49466beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
49476beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            assertTrue(mTextView.didTouchFocusSelect());
49480ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
49496beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText("Hello, World.", BufferType.SPANNABLE);
49500ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        });
49510ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mInstrumentation.waitForIdleSync();
49520ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
49530ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Tap the view to show InsertPointController.
49549404cdc3d439d5a2d1b805934c53a8ba6dc68fa8Andrei Stingaceanu        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
495583a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        // bad workaround for waiting onStartInputView of LeanbackIme.apk done
495683a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        try {
495783a70cb57c839148a4feff786cdbb3803828d484Bobby Wang            Thread.sleep(1000);
495883a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        } catch (InterruptedException e) {
495983a70cb57c839148a4feff786cdbb3803828d484Bobby Wang            e.printStackTrace();
496083a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        }
49610ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
49620ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Execute SelectAll context menu.
49639560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.onTextContextMenuItem(android.R.id.selectAll));
49640ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mInstrumentation.waitForIdleSync();
49650ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
49660ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // The selection must be whole of the text contents.
49670ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        assertEquals(0, mTextView.getSelectionStart());
496883a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        assertEquals("Hello, World.", mTextView.getText().toString());
49690ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        assertEquals(mTextView.length(), mTextView.getSelectionEnd());
49700ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka    }
49710ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
49729560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
4973a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
497472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testExtractText() {
497572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
497672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
497772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedTextRequest request = new ExtractedTextRequest();
497872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedText outText = new ExtractedText();
497972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
498072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.token = 0;
498172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.flags = 10;
498272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.hintMaxLines = 2;
498372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.hintMaxChars = 20;
498472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.extractText(request, outText));
498572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
498672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
498772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.extractText(request, outText));
498872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
498972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
499072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                outText.text.toString());
4991c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi
4992c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        // Tests for invalid arguments.
4993c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(request, null));
4994c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(null, outText));
4995c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(null, null));
499672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
499772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
499894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
4999a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
500094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testTextDirectionDefault() {
5001c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
50022a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection());
500394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
500494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
500594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
5006a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
500794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testSetGetTextDirection() {
5008c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
500994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50112a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getRawTextDirection());
501294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
50142a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getRawTextDirection());
501594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50172a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection());
501894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
50202a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getRawTextDirection());
502194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
502294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
50232a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getRawTextDirection());
502494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
502594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
50262a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getRawTextDirection());
502702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
502802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
502902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getRawTextDirection());
503002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
503102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
503202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getRawTextDirection());
503394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
503494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
503594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
5036a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
503794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionLtr() {
5038c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
503994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("this is a test");
504094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
50412a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
504294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50442a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
504594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
50472a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
504894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50502a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
505194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
505294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
50532a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
505494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
505594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
50562a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
505794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
505894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
50592a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
506002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
506102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
506202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
506302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
506402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
506502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
506694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
506794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
506894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
5069a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
507094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionLtrWithInheritance() {
5071c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = new LinearLayout(mActivity);
507294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
507394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
5074c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
507594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("this is a test");
507694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.addView(tv);
507794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
507894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50792a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
508094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
508194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
50822a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
508394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
508494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50852a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
508694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
508794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
50882a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
508994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
509094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
50912a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
509294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
509394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
50942a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
509502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
509602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
509702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
509802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
509902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
510002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
510194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
510294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
510394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
5104a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
510594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionRtl() {
5106c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
510794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("\u05DD\u05DE"); // hebrew
510894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
51092a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
511094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
511194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
51122a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
511394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
511494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
51152a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
511694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
511794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
51182a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
511994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
512094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
51212a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
512294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
512394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
51242a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
512594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
512694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
51272a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
512802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
512902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
513002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
513102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
513202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
513302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
513494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
513594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
513694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
5137a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
513894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionRtlWithInheritance() {
5139c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = new LinearLayout(mActivity);
514094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
514194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
5142c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
514394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("\u05DD\u05DE"); // hebrew
514494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.addView(tv);
514594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
514694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
51472a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
514894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
514994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
51502a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
515194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
515294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
51532a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
515494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
515594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
51562a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
515794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
515894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
51592a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
516094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
516194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
51622a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
516394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
516402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
516502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
516602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
516702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
516802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
516902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
517094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        // Force to RTL text direction on the layout
517194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
517294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
517394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
51742a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
517594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
517694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
51772a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
517894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
517994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
51802a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
518194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
518294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
51832a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
518494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
518594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
51862a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
518794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
518894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
51892a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
519002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
519102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
519202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
519302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
519402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
519502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
519694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
519794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
519894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
5199a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
520094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testResetTextDirection() {
5201c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest);
5202c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = (TextView) mActivity.findViewById(R.id.textview_rtl);
520394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
520494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
520594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
52062a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
520794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
5208f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        // No reset when we remove the view
520994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.removeView(tv);
5210f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
5211f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio
5212f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        // Reset is done when we add the view
5213f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        ll.addView(tv);
52142a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
521594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
521694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
521702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    @UiThreadTest
5218a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
521902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    public void testTextDirectionFirstStrongLtr() {
522002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
522102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is LTR, the paragraph direction is LTR.
522202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
522302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
522402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
522502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("this is a test");
522602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
522702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
522802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
522902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
523002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
523102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
523202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
523302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
523402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
523502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
523602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is RTL, the paragraph direction is RTL.
523702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
523802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
523902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
524002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\u05DD\u05DE"); // Hebrew
524102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
524202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
524302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
524402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
524502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
524602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
524702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
524802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
524902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
525002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
525102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is not a strong directional character, the paragraph
525202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // direction is LTR.
525302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
525402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
525502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
525602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\uFFFD");  // REPLACEMENT CHARACTER. Neutral direction.
525702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
525802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
525902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
526002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
526102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
526202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
526302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
526402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
526502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
526602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    }
526702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
526802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    @UiThreadTest
5269a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
527002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    public void testTextDirectionFirstStrongRtl() {
527102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
527202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is LTR, the paragraph direction is LTR.
527302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
527402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
527502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
527602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("this is a test");
527702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
527802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
527902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
528002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
528102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
528202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
528302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
528402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
528502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
528602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
528702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is RTL, the paragraph direction is RTL.
528802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
528902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
529002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
529102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\u05DD\u05DE"); // Hebrew
529202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
529302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
529402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
529502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
529602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
529702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
529802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
529902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
530002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
530102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
530202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is not a strong directional character, the paragraph
530302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // direction is RTL.
530402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
530502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
530602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
530702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\uFFFD");  // REPLACEMENT CHARACTER. Neutral direction.
530802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
530902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
531002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
531102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
531202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
531302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
531402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
531502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
531602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
531702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    }
531802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
53199560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
5320a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5321c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader    public void testTextLocales() {
5322c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        TextView tv = new TextView(mActivity);
5323c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.getDefault(), tv.getTextLocale());
5324c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(LocaleList.getDefault(), tv.getTextLocales());
5325c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5326c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        tv.setTextLocale(Locale.CHINESE);
5327c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.CHINESE, tv.getTextLocale());
5328c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(new LocaleList(Locale.CHINESE), tv.getTextLocales());
5329c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5330c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        tv.setTextLocales(LocaleList.forLanguageTags("en,ja"));
5331c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.forLanguageTag("en"), tv.getTextLocale());
5332c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(LocaleList.forLanguageTags("en,ja"), tv.getTextLocales());
5333c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5334c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5335c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocale(null);
5336c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locale to null should throw");
5337c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5338c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5339c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5340c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5341c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5342c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocales(null);
5343c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locales to null should throw");
5344c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5345c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5346c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5347c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5348c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5349c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocales(new LocaleList());
5350c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locale to an empty list should throw");
5351c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5352c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5353c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5354c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader    }
5355c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
53569560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
5357a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5358b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka    public void testAllCapsLocalization() {
5359b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        String testString = "abcdefghijklmnopqrstuvwxyz";
5360b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5361b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        // The capitalized characters of "i" on Turkish and Azerbaijani are different from English.
5362b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        Locale[] testLocales = {
5363b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("az", "AZ"),
5364b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("tr", "TR"),
5365b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("en", "US"),
5366b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        };
5367b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5368b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        TextView tv = new TextView(mActivity);
5369b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        tv.setAllCaps(true);
5370b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        for (Locale locale: testLocales) {
5371b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            tv.setTextLocale(locale);
5372b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            assertEquals("Locale: " + locale.getDisplayName(),
5373b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka                         testString.toUpperCase(locale),
5374b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka                         tv.getTransformationMethod().getTransformation(testString, tv).toString());
5375b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        }
5376b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka    }
5377b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5378dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5379a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5380dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testTextAlignmentDefault() {
5381a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        TextView tv = new TextView(mActivity);
53827fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5383dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // resolved default text alignment is GRAVITY
53847fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5385dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5386dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5387dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5388a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5389dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testSetGetTextAlignment() {
5390a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        TextView tv = new TextView(mActivity);
5391dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5392dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
53937fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5394dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5395dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
53967fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getRawTextAlignment());
5397dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5398dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
53997fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getRawTextAlignment());
5400dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5401dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
54027fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getRawTextAlignment());
5403dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5404dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
54057fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getRawTextAlignment());
5406dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5407dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
54087fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getRawTextAlignment());
5409dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5410dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5411dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5412a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5413dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testGetResolvedTextAlignment() {
5414a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        TextView tv = new TextView(mActivity);
5415dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
54167fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5417dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5418757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        // Test center alignment first so that we dont hit the default case
5419dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
54207fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5421dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5422757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        // Test the default case too
5423757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
5424757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5425757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio
5426dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
54277fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
5428dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5429dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
54307fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
5431dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5432dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
54337fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
5434dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5435dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
54367fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
5437dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5438dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5439dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5440a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5441dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testGetResolvedTextAlignmentWithInheritance() {
5442a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        LinearLayout ll = new LinearLayout(mActivity);
5443dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
5444dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5445a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        TextView tv = new TextView(mActivity);
5446dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.addView(tv);
5447dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5448dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // check defaults
54497fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5450dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5451dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5452dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // set inherit and check that child is following parent
5453dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
54547fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_INHERIT, tv.getRawTextAlignment());
5455dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5456dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
54577fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5458dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5459dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
54607fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
5461dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5462dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
54637fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
5464dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5465dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
54667fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
5467dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5468dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
54697fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
5470dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5471dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // now get rid of the inheritance but still change the parent
5472dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
5473dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5474dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
54757fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5476dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5477dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
54787fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5479dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5480dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
54817fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5482dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5483dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
54847fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5485dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5486dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
54877fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5488dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5489dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5490dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5491a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5492dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testResetTextAlignment() {
5493a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest);
5494a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        TextView tv = (TextView) mActivity.findViewById(R.id.textview_rtl);
5495dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5496dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
5497dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
54987fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5499dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
55004f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // No reset when we remove the view
5501dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.removeView(tv);
55024f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
55034f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio
55044f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // Reset is done when we add the view
55054f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // Default text alignment is GRAVITY
55064f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        ll.addView(tv);
55077fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5508dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5509dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5510938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    @UiThreadTest
5511a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5512938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    public void testDrawableResolution() {
5513b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 1.1: left / right drawable defined in default LTR mode
5514938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        TextView tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_1);
5515a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5516938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5517a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, -1, -1,
5518938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5519b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5520b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 1.2: left / right drawable defined in default RTL mode
5521938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_2);
5522a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5523938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5524a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, -1, -1,
5525938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5526b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5527b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 2.1: start / end drawable defined in LTR mode
5528938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_2_1);
5529a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5530938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5531a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5532938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5533b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5534b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 2.2: start / end drawable defined in RTL mode
5535938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_2_2);
5536a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5537938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5538a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5539938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5540b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5541b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 3.1: left / right / start / end drawable defined in LTR mode
5542938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_3_1);
5543a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5544938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5545a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5546938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5547b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5548b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 3.2: left / right / start / end drawable defined in RTL mode
5549938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_3_2);
5550a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5551938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5552a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5553938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5554b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5555b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 4.1: start / end drawable defined in LTR mode inside a layout
5556b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5557938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_4_1);
5558a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5559938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5560a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5561938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5562b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5563b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 4.2: start / end drawable defined in RTL mode inside a layout
5564b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5565938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_4_2);
5566a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5567938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5568a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5569938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5570b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5571b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 5.1: left / right / start / end drawable defined in LTR mode inside a layout
5572b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5573938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_5_1);
5574a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5575938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5576a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5577938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5578b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5579b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 5.2: left / right / start / end drawable defined in RTL mode inside a layout
5580b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5581938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_5_2);
5582a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5583938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5584a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5585938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5586b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio    }
5587b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
55889776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    @UiThreadTest
5589a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
55909776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    public void testDrawableResolution2() {
55919776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        // Case 1.1: left / right drawable defined in default LTR mode
5592938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        TextView tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_1);
5593a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5594938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
55959776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5596a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        tv.setCompoundDrawables(null, null,
5597a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov                TestUtils.getDrawable(mActivity, R.drawable.icon_yellow), null);
5598a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, -1, R.drawable.icon_yellow, -1, -1);
55999776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5600938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_2);
5601a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5602938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
56039776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5604a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        tv.setCompoundDrawables(TestUtils.getDrawable(mActivity, R.drawable.icon_yellow), null,
5605a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov                null, null);
5606a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_yellow, -1, -1, -1);
56079776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5608938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_ltr);
5609a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, -1, -1, -1, -1);
56109776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5611a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        tv.setCompoundDrawables(TestUtils.getDrawable(mActivity, R.drawable.icon_blue), null,
5612a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov                TestUtils.getDrawable(mActivity, R.drawable.icon_red), null);
5613a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red, -1, -1);
56149776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5615a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        tv.setCompoundDrawablesRelative(TestUtils.getDrawable(mActivity, R.drawable.icon_yellow),
5616a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov                null, null, null);
5617a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_yellow, -1, -1, -1);
5618938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    }
5619938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5620a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5621938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    public void testCompoundAndTotalPadding() {
5622938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final Resources res = mActivity.getResources();
5623938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int drawablePadding = res.getDimensionPixelSize(R.dimen.textview_drawable_padding);
5624938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingLeft = res.getDimensionPixelSize(R.dimen.textview_padding_left);
5625938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingRight = res.getDimensionPixelSize(R.dimen.textview_padding_right);
5626938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingTop = res.getDimensionPixelSize(R.dimen.textview_padding_top);
5627938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingBottom = res.getDimensionPixelSize(R.dimen.textview_padding_bottom);
5628938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int iconSize = TestUtils.dpToPx(mActivity, 32);
5629938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5630938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final TextView textViewLtr = (TextView) mActivity.findViewById(
5631938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.id.textview_compound_drawable_ltr);
5632938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingLeftLtr = paddingLeft + drawablePadding + iconSize;
5633938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingRightLtr = paddingRight + drawablePadding + iconSize;
5634938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getCompoundPaddingLeft());
5635938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getCompoundPaddingStart());
5636938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getTotalPaddingLeft());
5637938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getTotalPaddingStart());
5638938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getCompoundPaddingRight());
5639938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getCompoundPaddingEnd());
5640938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getTotalPaddingRight());
5641938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getTotalPaddingEnd());
5642938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingTop + drawablePadding + iconSize,
5643938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewLtr.getCompoundPaddingTop());
5644938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingBottom + drawablePadding + iconSize,
5645938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewLtr.getCompoundPaddingBottom());
5646938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5647938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final TextView textViewRtl = (TextView) mActivity.findViewById(
5648938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.id.textview_compound_drawable_rtl);
5649938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingLeftRtl = paddingLeft + drawablePadding + iconSize;
5650938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingRightRtl = paddingRight + drawablePadding + iconSize;
5651938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getCompoundPaddingLeft());
5652938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getCompoundPaddingEnd());
5653938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getTotalPaddingLeft());
5654938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getTotalPaddingEnd());
5655938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getCompoundPaddingRight());
5656938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getCompoundPaddingStart());
5657938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getTotalPaddingRight());
5658938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getTotalPaddingStart());
5659938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingTop + drawablePadding + iconSize,
5660938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewRtl.getCompoundPaddingTop());
5661938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingBottom + drawablePadding + iconSize,
5662938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewRtl.getCompoundPaddingBottom());
56639776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    }
56649776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
56659560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
5666a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5667e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    public void testSetGetBreakStrategy() {
5668e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        TextView tv = new TextView(mActivity);
5669e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5670a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        final PackageManager pm = mInstrumentation.getTargetContext().getPackageManager();
56712751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka
5672d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // The default value is from the theme, here the default is BREAK_STRATEGY_HIGH_QUALITY for
56732751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        // TextView except for Android Wear. The default value for Android Wear is
56742751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        // BREAK_STRATEGY_BALANCED.
56752751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        if (pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
56762751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            // Android Wear
56772751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy());
56782751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        } else {
56792751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            // All other form factor.
56802751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy());
56812751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        }
5682e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5683e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
5684e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, tv.getBreakStrategy());
5685e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5686e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
5687e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy());
5688e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5689e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED);
5690e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy());
5691d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5692d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        EditText et = new EditText(mActivity);
5693d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5694d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // The default value is from the theme, here the default is BREAK_STRATEGY_SIMPLE for
5695d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // EditText.
5696d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy());
5697d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5698d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
5699d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy());
5700d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5701d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
5702d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, et.getBreakStrategy());
5703d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5704d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED);
5705d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_BALANCED, et.getBreakStrategy());
5706e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    }
5707e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
57089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @UiThreadTest
5709a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
5710e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    public void testSetGetHyphenationFrequency() {
5711e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        TextView tv = new TextView(mActivity);
5712e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5713d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency());
5714e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5715e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
5716e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, tv.getHyphenationFrequency());
5717e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5718e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL);
5719e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency());
5720e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5721e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
5722e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_FULL, tv.getHyphenationFrequency());
5723e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    }
5724e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5725a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka    @UiThreadTest
5726a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka    @Test
5727a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka    public void testSetGetJustify() {
5728a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka        TextView tv = new TextView(mActivity);
5729a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka
5730a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka        assertFalse(tv.getJustify());
5731a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka        tv.setJustify(true);
5732a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka        assertTrue(tv.getJustify());
5733a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka        tv.setJustify(false);
5734a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka        assertFalse(tv.getJustify());
5735a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka    }
5736a3cf2598fa76975e1051852c12fffe208cdfb52cSeigo Nonaka
5737a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
57384b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testSetAndGetCustomSelectionActionModeCallback() throws Throwable {
573932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        final String text = "abcde";
57409560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
57416beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView = new EditText(mActivity);
57426beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mActivity.setContentView(mTextView);
57436beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setText(text, BufferType.SPANNABLE);
57446beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setTextIsSelectable(true);
57456beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.requestFocus();
57466beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.setSelected(true);
574732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
574832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
574932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
575032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Check default value.
575132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        assertNull(mTextView.getCustomSelectionActionModeCallback());
575232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
575398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final ActionMode.Callback mockActionModeCallback = mock(ActionMode.Callback.class);
575498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
575598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.FALSE);
575698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setCustomSelectionActionModeCallback(mockActionModeCallback);
575798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback,
575832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.getCustomSelectionActionModeCallback());
575932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
57609560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
57616beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Set selection and try to start action mode.
57626beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            final Bundle args = new Bundle();
57636beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
57646beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
57656beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.performAccessibilityAction(
57666beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
576732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
576832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
576932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
577098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onCreateActionMode(
577198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                any(ActionMode.class), any(Menu.class));
577232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
57739560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
57746beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Remove selection and stop action mode.
57756beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.copy);
577632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
577732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
577832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
577932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Action mode was blocked.
578098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, never()).onDestroyActionMode(any(ActionMode.class));
578132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
578298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        // Reset and reconfigure callback.
578398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockActionModeCallback);
578498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
578598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.TRUE);
578698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback, mTextView.getCustomSelectionActionModeCallback());
578732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
57889560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
57896beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Set selection and try to start action mode.
57906beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            final Bundle args = new Bundle();
57916beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
57926beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
57936beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.performAccessibilityAction(
57946beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu                    AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
579532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
579632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
579732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
579832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
579998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onCreateActionMode(
580098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                any(ActionMode.class), any(Menu.class));
580132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
58029560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
58036beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            // Remove selection and stop action mode.
58046beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu            mTextView.onTextContextMenuItem(android.R.id.copy);
580532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
580632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
580732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
580832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Action mode was started
580998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onDestroyActionMode(any(ActionMode.class));
581032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi    }
581132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
58126beed5d1888fd4878ad9bbcaa8a8a83a4e1ebfa9Andrei Stingaceanu    @UiThreadTest
5813a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
581498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testSetAndGetCustomInsertionActionMode() {
581532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        initTextViewForTyping();
581632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Check default value.
581732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        assertNull(mTextView.getCustomInsertionActionModeCallback());
581832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
581998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final ActionMode.Callback mockActionModeCallback = mock(ActionMode.Callback.class);
582098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
582198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.FALSE);
582298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setCustomInsertionActionModeCallback(mockActionModeCallback);
582398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback, mTextView.getCustomInsertionActionModeCallback());
582432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // TODO(Bug: 22033189): Tests the set callback is actually used.
582532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi    }
582632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
582789b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky    @UiThreadTest
582889b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky    @Test
582989b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky    public void testRespectsViewFocusability() {
583089b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky        TextView v = (TextView) mActivity.findViewById(R.id.textview_singleLine);
583189b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky        assertFalse(v.isFocusable());
583289b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky        // TextView used to set focusable to true or false verbatim which would break the following.
583389b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky        v.setClickable(true);
583489b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky        assertTrue(v.isFocusable());
583589b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky    }
583689b9540bbc634ab5acdf9083c694406dd4d1bb37Evan Rosky
5837a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
58389560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    public void testTextShadows() throws Throwable {
583998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView textViewWithConfiguredShadow =
584098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                (TextView) mActivity.findViewById(R.id.textview_with_shadow);
5841a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(1.0f, textViewWithConfiguredShadow.getShadowDx(), 0.0f);
5842a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(2.0f, textViewWithConfiguredShadow.getShadowDy(), 0.0f);
5843a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(3.0f, textViewWithConfiguredShadow.getShadowRadius(), 0.0f);
584498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(Color.GREEN, textViewWithConfiguredShadow.getShadowColor());
584532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
584698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
5847a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(0.0f, textView.getShadowDx(), 0.0f);
5848a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(0.0f, textView.getShadowDy(), 0.0f);
5849a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(0.0f, textView.getShadowRadius(), 0.0f);
585032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
58519560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> textView.setShadowLayer(5.0f, 3.0f, 4.0f, Color.RED));
585298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5853a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(3.0f, textView.getShadowDx(), 0.0f);
5854a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(4.0f, textView.getShadowDy(), 0.0f);
5855a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(5.0f, textView.getShadowRadius(), 0.0f);
585698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(Color.RED, textView.getShadowColor());
585772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
585872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
5859a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
58604b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testFontFeatureSettings() throws Throwable {
5861354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
5862354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.isEmpty(textView.getFontFeatureSettings()));
5863354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
58649560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> textView.setFontFeatureSettings("smcp"));
5865354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5866354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals("smcp", textView.getFontFeatureSettings());
5867354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
58689560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> textView.setFontFeatureSettings("frac"));
5869354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5870354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals("frac", textView.getFontFeatureSettings());
5871354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5872354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5873354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    private static class SoftInputResultReceiver extends ResultReceiver {
5874354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        private boolean mIsDone;
5875354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        private int mResultCode;
5876354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5877354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        public SoftInputResultReceiver(Handler handler) {
5878354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            super(handler);
5879354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5880354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5881354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        @Override
5882354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        protected void onReceiveResult(int resultCode, Bundle resultData) {
5883354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mResultCode = resultCode;
5884354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mIsDone = true;
5885354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5886354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5887354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        public void reset() {
5888354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mIsDone = false;
5889354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5890354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5891354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5892a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
58934b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessShowSoftInputOnFocus() throws Throwable {
5894354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        if (!mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)) {
5895354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            return;
5896354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5897354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5898354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Scroll down to our EditText
5899354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final ScrollView scrollView = (ScrollView) mActivity.findViewById(R.id.scroller);
5900354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mTextView = findTextView(R.id.editview_text);
59019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> scrollView.fullScroll(View.FOCUS_DOWN));
5902354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5903354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5904354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Mark it to show soft input on focus
59059560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setShowSoftInputOnFocus(true));
5906354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5907354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.getShowSoftInputOnFocus());
5908354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5909354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // And emulate click on it
59109404cdc3d439d5a2d1b805934c53a8ba6dc68fa8Andrei Stingaceanu        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
5911354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5912354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Verify that input method manager is active and accepting text
5913354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final InputMethodManager imManager = (InputMethodManager) mActivity
5914354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov                .getSystemService(Context.INPUT_METHOD_SERVICE);
5915b7724cefaf6067b1f6b59d3abae73828b48945c3Kirill Grouchnikov        PollingCheck.waitFor(imManager::isActive);
5916354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(imManager.isAcceptingText());
5917354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(imManager.isActive(mTextView));
5918354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5919354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Since there is no API to check that soft input is showing, we're going to ask
5920354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // the input method manager to show soft input, passing our custom result receiver.
5921354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // We're expecting to get UNCHANGED_SHOWN, indicating that the soft input was already
5922354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // showing before showSoftInput was called.
5923354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        SoftInputResultReceiver receiver = new SoftInputResultReceiver(mHandler);
5924354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        imManager.showSoftInput(mTextView, 0, receiver);
5925354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> receiver.mIsDone);
5926354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(InputMethodManager.RESULT_UNCHANGED_SHOWN, receiver.mResultCode);
5927354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5928354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Close soft input
5929a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
5930354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5931354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Reconfigure our edit text to not show soft input on focus
59329560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setShowSoftInputOnFocus(false));
5933354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5934354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.getShowSoftInputOnFocus());
5935354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5936354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Emulate click on it
59379404cdc3d439d5a2d1b805934c53a8ba6dc68fa8Andrei Stingaceanu        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
5938354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5939354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Ask input method manager to show soft input again. This time we're expecting to get
5940354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // SHOWN, indicating that the soft input was not showing before showSoftInput was called.
5941354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        receiver.reset();
5942354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        imManager.showSoftInput(mTextView, 0, receiver);
5943354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> receiver.mIsDone);
5944354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(InputMethodManager.RESULT_SHOWN, receiver.mResultCode);
5945354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5946354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Close soft input
5947a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
5948354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5949354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5950a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
59514b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testIsSuggestionsEnabled() throws Throwable {
595241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
595341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
595441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Anything without InputType.TYPE_CLASS_TEXT doesn't have suggestions enabled
59554b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> mTextView.setInputType(InputType.TYPE_CLASS_DATETIME));
595641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
595741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
59584b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> mTextView.setInputType(InputType.TYPE_CLASS_PHONE));
595941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
596041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
59614b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(() -> mTextView.setInputType(InputType.TYPE_CLASS_NUMBER));
596241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
596341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
596441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // From this point our text view has InputType.TYPE_CLASS_TEXT
596541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
596641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Anything with InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS doesn't have suggestions enabled
59674b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
596841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
596941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
597041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
597141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
59724b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
597341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
597441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL |
597541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
597641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
597741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
59784b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
597941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
598041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS |
598141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
598241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
598341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
598441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Otherwise suggestions are enabled for specific type variations enumerated in the
598541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // documentation of TextView.isSuggestionsEnabled
59864b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
598741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
598841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL));
598941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
599041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
59914b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
599241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
599341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT));
599441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
599541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
59964b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
599741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
599841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE));
599941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
600041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60014b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
600241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
600341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE));
600441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
600541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60064b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
600741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
600841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT));
600941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
601041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
601141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // and not on any other type variation
60124b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
601341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
601441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS));
601541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
601641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60174b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
601841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
601941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_FILTER));
602041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
602141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60224b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
602341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
602441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD));
602541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
602641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60274b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
602841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
602941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PERSON_NAME));
603041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
603141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60324b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
603341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
603441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PHONETIC));
603541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
603641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60374b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
603841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
603941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS));
604041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
604141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60424b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
604341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
604441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI));
604541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
604641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60474b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
604841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
604941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT |
605041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD));
605141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
605241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60534b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
605441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
605541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT |
605641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS));
605741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
605841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
60594b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        mActivityRule.runOnUiThread(
606041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
606141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD));
606241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
606341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
606441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
6065a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
60664b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testAccessLetterSpacing() throws Throwable {
606741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
6068a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(0.0f, mTextView.getLetterSpacing(), 0.0f);
606941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
607041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final CharSequence text = mTextView.getText();
607141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int textLength = text.length();
607241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
607341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at the default letter spacing
607441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] initialWidths = new float[textLength];
607541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), initialWidths);
607641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
607741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at letter spacing = 1.0f
60784b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mTextView,
607941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setLetterSpacing(1.0f));
6080a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(1.0f, mTextView.getLetterSpacing(), 0.0f);
608141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] singleWidths = new float[textLength];
608241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), singleWidths);
608341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
608441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at letter spacing = 2.0f
60854b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mTextView,
608641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setLetterSpacing(2.0f));
6087a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov        assertEquals(2.0f, mTextView.getLetterSpacing(), 0.0f);
608841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] doubleWidths = new float[textLength];
608941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), doubleWidths);
609041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
609141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Since letter spacing setter treats the parameter as EM units, and we don't have
609241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // a way to convert EMs into pixels, go over the three arrays of advance widths and
609341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // test that the extra advance width at letter spacing 2.0f is double the extra
609441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // advance width at letter spacing 1.0f.
609541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        for (int i = 0; i < textLength; i++) {
609641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            float singleWidthDelta = singleWidths[i] - initialWidths[i];
609741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            float doubleWidthDelta = doubleWidths[i] - initialWidths[i];
609841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            assertEquals("At index " + i + " initial is " + initialWidths[i] +
609941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                ", single is " + singleWidths[i] + " and double is " + doubleWidths[i],
610041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                    singleWidthDelta * 2.0f, doubleWidthDelta, 0.05f);
610141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        }
610241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
610341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
6104a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
61054b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testTextIsSelectableFocusAndOnClick() throws Throwable {
6106288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        // Prepare a focusable TextView with an onClickListener attached.
6107288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        final View.OnClickListener mockOnClickListener = mock(View.OnClickListener.class);
6108d25d1649c5d744044a0174a734e38ec22cdc7d25Andrei Stingaceanu        final int safeDoubleTapTimeout = ViewConfiguration.getDoubleTapTimeout() + 1;
61099560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
6110288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mTextView = new TextView(mActivity);
611152e5d256861edd0ff4f58da581b8bbd9df1c1d99Siyamed Sinir            mTextView.setText("...text 11:11. some more text is in here...");
6112288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mTextView.setFocusable(true);
6113288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mTextView.setOnClickListener(mockOnClickListener);
6114288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mActivity.setContentView(mTextView);
6115288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        });
6116288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6117288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocusable());
6118288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isTextSelectable());
6119288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocusableInTouchMode());
6120288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocused());
6121288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isInTouchMode());
6122288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu
6123288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        // First tap on the view triggers onClick() but does not focus the TextView.
61248bd3e888824438c3bc8ae24ca8842d9248b33924Andrei Stingaceanu        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
6125d25d1649c5d744044a0174a734e38ec22cdc7d25Andrei Stingaceanu        SystemClock.sleep(safeDoubleTapTimeout);
6126288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isInTouchMode());
6127288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocused());
6128288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        verify(mockOnClickListener, times(1)).onClick(mTextView);
6129288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        reset(mockOnClickListener);
6130d25d1649c5d744044a0174a734e38ec22cdc7d25Andrei Stingaceanu        // So does the second tap.
61318bd3e888824438c3bc8ae24ca8842d9248b33924Andrei Stingaceanu        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
6132d25d1649c5d744044a0174a734e38ec22cdc7d25Andrei Stingaceanu        SystemClock.sleep(safeDoubleTapTimeout);
6133288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isInTouchMode());
6134288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocused());
6135288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        verify(mockOnClickListener, times(1)).onClick(mTextView);
6136288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu
61379560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setTextIsSelectable(true));
6138288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6139288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocusable());
6140288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isTextSelectable());
6141288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocusableInTouchMode());
6142288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocused());
6143288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu
6144288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        // First tap on the view focuses the TextView but does not trigger onClick().
6145288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        reset(mockOnClickListener);
61468bd3e888824438c3bc8ae24ca8842d9248b33924Andrei Stingaceanu        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
6147d25d1649c5d744044a0174a734e38ec22cdc7d25Andrei Stingaceanu        SystemClock.sleep(safeDoubleTapTimeout);
6148288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isInTouchMode());
6149288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocused());
6150288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        verify(mockOnClickListener, never()).onClick(mTextView);
6151288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        reset(mockOnClickListener);
6152d25d1649c5d744044a0174a734e38ec22cdc7d25Andrei Stingaceanu        // The second tap triggers onClick() and keeps the focus.
61538bd3e888824438c3bc8ae24ca8842d9248b33924Andrei Stingaceanu        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
6154d25d1649c5d744044a0174a734e38ec22cdc7d25Andrei Stingaceanu        SystemClock.sleep(safeDoubleTapTimeout);
6155288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isInTouchMode());
6156288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocused());
6157288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        verify(mockOnClickListener, times(1)).onClick(mTextView);
6158288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu    }
6159288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu
616041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    private void verifyGetOffsetForPosition(final int x, final int y) {
616141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int actual = mTextView.getOffsetForPosition(x, y);
616241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
616341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final Layout layout = mTextView.getLayout();
616441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        if (layout == null) {
616541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            assertEquals("For [" + x + ", " + y + "]", -1, actual);
616641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            return;
616741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        }
616841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
616941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get the line which corresponds to the Y position
617041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int line = layout.getLineForVertical(y + mTextView.getScrollY());
617141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get the offset in that line that corresponds to the X position
617241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int expected = layout.getOffsetForHorizontal(line, x + mTextView.getScrollX());
617341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals("For [" + x + ", " + y + "]", expected, actual);
617441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
617541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
6176a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
61774b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    public void testGetOffsetForPosition() throws Throwable {
617841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
61794b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mTextView, () -> {
618041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            mTextView.setText(LONG_TEXT);
618141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            mTextView.setPadding(0, 0, 0, 0);
618241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        });
618341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
618441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertNotNull(mTextView.getLayout());
618541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int viewWidth = mTextView.getWidth();
618641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int viewHeight = mTextView.getHeight();
618741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int lineHeight = mTextView.getLineHeight();
618841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
618941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(0, 0);
619041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(0, viewHeight / 2);
619141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth / 3, lineHeight / 2);
619241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth / 2, viewHeight / 2);
619341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth, viewHeight);
619441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
619541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
619657c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri    @UiThreadTest
6197a75fb03266b58562af9ed30eff91f2a67d177adcKirill Grouchnikov    @Test
619857c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri    public void testOnResolvePointerIcon() throws InterruptedException {
619957c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        final TextView selectableTextView = findTextView(R.id.textview_pointer);
620057c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        final MotionEvent event = createMouseHoverEvent(selectableTextView);
620157c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
620257c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        // A selectable view shows the I beam
620357c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        selectableTextView.setTextIsSelectable(true);
620457c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
620557c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_TEXT),
620657c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                selectableTextView.onResolvePointerIcon(event, 0));
620757c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        selectableTextView.setTextIsSelectable(false);
620857c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
620957c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        // A clickable view shows the hand
621057c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        selectableTextView.setLinksClickable(true);
621157c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        SpannableString builder = new SpannableString("hello world");
621257c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        selectableTextView.setText(builder, BufferType.SPANNABLE);
621357c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        Spannable text = (Spannable) selectableTextView.getText();
621457c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        text.setSpan(
621557c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                new ClickableSpan() {
621657c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                    @Override
621757c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                    public void onClick(View widget) {
621857c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
621957c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                    }
622057c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                }, 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
622157c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
622257c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_HAND),
622357c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                selectableTextView.onResolvePointerIcon(event, 0));
622457c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
622557c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        // A selectable & clickable view shows hand
622657c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        selectableTextView.setTextIsSelectable(true);
622757c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
622857c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_HAND),
622957c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                selectableTextView.onResolvePointerIcon(event, 0));
623057c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
623157c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        // An editable view shows the I-beam
623257c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        final TextView editableTextView = new EditText(mActivity);
623357c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
623457c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_TEXT),
623557c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                editableTextView.onResolvePointerIcon(event, 0));
623657c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri    }
623757c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
62389560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @Test
62396b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu    public void testClickableSpanOnClickSingleTapInside() throws Throwable {
62409560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpanTestDetails spanDetails = prepareAndRetrieveClickableSpanDetails();
62419560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateTapOnView(mInstrumentation, mTextView, spanDetails.mXPosInside,
62429560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                spanDetails.mYPosInside);
62439560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        SystemClock.sleep(ViewConfiguration.getDoubleTapTimeout() + 1);
62449560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(spanDetails.mClickableSpan, times(1)).onClick(mTextView);
62459560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
62469560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
62479560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @Test
62486b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu    public void testClickableSpanOnClickDoubleTapInside() throws Throwable {
62499560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpanTestDetails spanDetails = prepareAndRetrieveClickableSpanDetails();
62509560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateDoubleTapOnView(mInstrumentation, mTextView, spanDetails.mXPosInside,
62519560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                spanDetails.mYPosInside);
62529560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(spanDetails.mClickableSpan, never()).onClick(mTextView);
62539560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
62549560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
62559560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @Test
62566b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu    public void testClickableSpanOnClickSingleTapOutside() throws Throwable {
62579560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpanTestDetails spanDetails = prepareAndRetrieveClickableSpanDetails();
62589560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateTapOnView(mInstrumentation, mTextView, spanDetails.mXPosOutside,
62599560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                spanDetails.mYPosOutside);
62609560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        SystemClock.sleep(ViewConfiguration.getDoubleTapTimeout() + 1);
62619560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(spanDetails.mClickableSpan, never()).onClick(mTextView);
62629560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
62639560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
62649560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @Test
62656b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu    public void testClickableSpanOnClickDragOutside() throws Throwable {
62669560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpanTestDetails spanDetails = prepareAndRetrieveClickableSpanDetails();
62679560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final int[] viewOnScreenXY = new int[2];
62689560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.getLocationOnScreen(viewOnScreenXY);
62699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
62709560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        SparseArray<Point> swipeCoordinates = new SparseArray<>();
62719560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        swipeCoordinates.put(0, new Point(viewOnScreenXY[0] + spanDetails.mXPosOutside,
62729560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                viewOnScreenXY[1] + spanDetails.mYPosOutside));
62739560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        swipeCoordinates.put(1, new Point(viewOnScreenXY[0] + spanDetails.mXPosOutside + 50,
62749560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                viewOnScreenXY[1] + spanDetails.mYPosOutside + 50));
62759560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateDragGesture(mInstrumentation, swipeCoordinates);
62769560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(spanDetails.mClickableSpan, never()).onClick(mTextView);
62779560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
62789560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
62799560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @Test
62806b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu    public void testClickableSpanOnClickDragInsideFromOutside() throws Throwable {
62819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpanTestDetails spanDetails = prepareAndRetrieveClickableSpanDetails();
62829560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final int[] viewOnScreenXY = new int[2];
62839560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.getLocationOnScreen(viewOnScreenXY);
62849560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
62859560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        SparseArray<Point> swipeCoordinates = new SparseArray<>();
62869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        swipeCoordinates.put(0, new Point(viewOnScreenXY[0] + spanDetails.mXPosOutside,
62879560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                viewOnScreenXY[1] + spanDetails.mYPosOutside));
62889560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        swipeCoordinates.put(1, new Point(viewOnScreenXY[0] + spanDetails.mXPosInside,
62899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                viewOnScreenXY[1] + spanDetails.mYPosInside));
62909560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateDragGesture(mInstrumentation, swipeCoordinates);
62919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(spanDetails.mClickableSpan, never()).onClick(mTextView);
62929560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
62939560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
62949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @Test
62956b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu    public void testClickableSpanOnClickDragInsideOutsideInside() throws Throwable {
62969560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpanTestDetails spanDetails = prepareAndRetrieveClickableSpanDetails();
62979560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final int[] viewOnScreenXY = new int[2];
62989560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mTextView.getLocationOnScreen(viewOnScreenXY);
62999560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
63009560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        // Drag outside from within the clickable span and come back within the clickable span
63019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        // (without lifting the finger)
63029560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        SparseArray<Point> swipeCoordinates = new SparseArray<>();
63039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        swipeCoordinates.put(0, new Point(viewOnScreenXY[0] + spanDetails.mXPosInside,
63049560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                viewOnScreenXY[1] + spanDetails.mYPosInside));
63059560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        swipeCoordinates.put(1, new Point(viewOnScreenXY[0] + spanDetails.mXPosOutside,
63069560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                viewOnScreenXY[1] + spanDetails.mYPosOutside));
63079560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        swipeCoordinates.put(2, new Point(viewOnScreenXY[0] + spanDetails.mXPosInside,
63089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                viewOnScreenXY[1] + spanDetails.mYPosInside));
63099560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateDragGesture(mInstrumentation, swipeCoordinates);
63109560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(spanDetails.mClickableSpan, never()).onClick(mTextView);
63119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
63129560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
63139560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    @Test
63146b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu    public void testClickableSpanOnClickLongPress() throws Throwable {
63159560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpanTestDetails spanDetails = prepareAndRetrieveClickableSpanDetails();
63169560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        CtsTouchUtils.emulateLongPressOnView(mInstrumentation, mTextView, spanDetails.mXPosInside,
63179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                spanDetails.mYPosInside);
63189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        verify(spanDetails.mClickableSpan, never()).onClick(mTextView);
63199560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
63209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
6321771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    @UiThreadTest
6322771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    @Test
6323771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    public void testOnInitializeA11yNodeInfo_populatesHintTextProperly() {
6324771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final TextView textView = new TextView(mActivity);
6325771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setText("", BufferType.EDITABLE);
6326771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final String hintText = "Hint text";
6327771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setHint(hintText);
6328771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
6329771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.onInitializeAccessibilityNodeInfo(info);
6330771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertTrue("Hint text flag set incorrectly for accessibility", info.isShowingHintText());
6331771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertTrue("Hint text not showing as accessibility text",
6332771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu                TextUtils.equals(hintText, info.getText()));
6333771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertTrue("Hint text not provided to accessibility",
6334771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu                TextUtils.equals(hintText, info.getHintText()));
6335771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6336771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final String nonHintText = "Something else";
6337771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setText(nonHintText, BufferType.EDITABLE);
6338771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.onInitializeAccessibilityNodeInfo(info);
6339771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertFalse("Hint text flag set incorrectly for accessibility", info.isShowingHintText());
6340771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertTrue("Text not provided to accessibility",
6341771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu                TextUtils.equals(nonHintText, info.getText()));
6342771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertTrue("Hint text not provided to accessibility",
6343771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu                TextUtils.equals(hintText, info.getHintText()));
6344771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    }
6345771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
63465b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu    @Test
6347cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setCompoundDrawables() throws Throwable {
6348069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6349cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6350069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6351cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
6352c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        drawable.setBounds(0, 0, autoSizeTextView.getWidth() / 3, autoSizeTextView.getHeight() / 3);
6353cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6354cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                autoSizeTextView.setCompoundDrawables(drawable, drawable, drawable, drawable));
6355cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6356069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6357069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6358cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6359cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6360cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6361cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setCompoundDrawablesRelative() throws Throwable {
6362069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6363cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6364069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6365cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
6366c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        drawable.setBounds(0, 0, autoSizeTextView.getWidth() / 3, autoSizeTextView.getHeight() / 3);
6367cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setCompoundDrawablesRelative(
6368cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                drawable, drawable, drawable, drawable));
6369cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6370069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6371069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6372cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6373cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6374cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6375cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setCompoundDrawablePadding() throws Throwable {
6376069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6377cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6378cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        // Setup the drawables before setting their padding in order to modify the available
6379cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        // space and trigger a resize.
6380cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
6381c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        drawable.setBounds(0, 0, autoSizeTextView.getWidth() / 3, autoSizeTextView.getHeight() / 3);
6382cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setCompoundDrawables(
6383cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                drawable, drawable, drawable, drawable));
6384cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6385069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6386cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setCompoundDrawablePadding(50));
6387cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6388069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6389069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6390cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6391cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6392cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6393cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setPadding() throws Throwable {
6394069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6395cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6396069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6397c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setPadding(
6398c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                autoSizeTextView.getWidth() / 3, autoSizeTextView.getHeight() / 3,
6399c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                autoSizeTextView.getWidth() / 3, autoSizeTextView.getHeight() / 3));
6400cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6401069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6402069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6403cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6404cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6405cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6406cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setPaddingRelative() throws Throwable {
6407069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6408cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6409069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6410cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6411c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setPaddingRelative(
6412c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                autoSizeTextView.getWidth() / 3, autoSizeTextView.getHeight() / 3,
6413c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                autoSizeTextView.getWidth() / 3, autoSizeTextView.getHeight() / 3));
6414cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6415069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6416069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6417cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6418cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6419cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6420cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setTextScaleX() throws Throwable {
6421069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6422cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6423069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6424cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6425cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6426069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                autoSizeTextView.setTextScaleX(autoSizeTextView.getTextScaleX() * 4.5f));
6427cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6428069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float changedTextSize = autoSizeTextView.getTextSize();
6429069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6430069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(changedTextSize < initialTextSize);
6431069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6432cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6433cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                autoSizeTextView.setTextScaleX(autoSizeTextView.getTextScaleX()));
6434cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6435069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6436069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertEquals(changedTextSize, autoSizeTextView.getTextSize(), 0f);
6437cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6438cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6439cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6440cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setTypeface() throws Throwable {
6441069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6442cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6443069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6444069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                autoSizeTextView.setText("The typeface change needs a bit more text then "
6445069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                        + "the default used for this batch of tests in order to get to resize text."
6446069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                        + " The resize function is always called but even with different typefaces "
6447069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                        + "there may not be a need to resize text because it just fits. The longer "
6448069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                        + "the text, the higher the chance for a resize. And here is yet another "
6449069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                        + "sentence to make sure this test is not flaky. Not flaky at all."));
6450069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6451069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6452cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6453c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
6454c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu            Typeface differentTypeface = Typeface.MONOSPACE;
6455c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu            if (autoSizeTextView.getTypeface() == Typeface.MONOSPACE) {
6456c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                differentTypeface = Typeface.SANS_SERIF;
6457c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu            }
6458c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu            autoSizeTextView.setTypeface(differentTypeface);
6459c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        });
6460cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6461069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float changedTextSize = autoSizeTextView.getTextSize();
6462069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6463069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        // Don't really know if it is larger or smaller (depends on the typeface chosen above),
6464069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        // but it should definitely have changed.
6465069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertNotEquals(initialTextSize, changedTextSize, 0f);
6466069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6467cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6468cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                autoSizeTextView.setTypeface(autoSizeTextView.getTypeface()));
6469cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6470069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6471069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertEquals(changedTextSize, autoSizeTextView.getTextSize(), 0f);
6472cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6473cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6474cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6475cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setLetterSpacing() throws Throwable {
6476069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6477cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6478069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6479cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6480cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6481c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                // getLetterSpacing() could return 0, make sure there is enough of a difference to
6482c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                // trigger auto-size.
6483c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                autoSizeTextView.setLetterSpacing(
6484069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                        autoSizeTextView.getLetterSpacing() * 1.5f + 4.5f));
6485cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6486069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float changedTextSize = autoSizeTextView.getTextSize();
6487cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6488069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(changedTextSize < initialTextSize);
6489c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu
6490cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6491069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                autoSizeTextView.setLetterSpacing(autoSizeTextView.getLetterSpacing()));
6492cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6493069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6494069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertEquals(changedTextSize, autoSizeTextView.getTextSize(), 0f);
6495cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6496cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6497cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6498cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setHorizontallyScrolling() throws Throwable {
6499069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6500cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6501069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6502cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setHorizontallyScrolling(
6503cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                !autoSizeTextView.getHorizontallyScrolling()));
6504cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6505069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float changedTextSize = autoSizeTextView.getTextSize();
6506069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6507069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(changedTextSize < initialTextSize);
6508069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6509cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setHorizontallyScrolling(
6510cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                autoSizeTextView.getHorizontallyScrolling()));
6511cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6512cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6513069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertEquals(changedTextSize, autoSizeTextView.getTextSize(), 0f);
6514cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6515cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6516cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6517cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setMaxLines() throws Throwable {
6518069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6519cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6520069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6521cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setMaxLines(1));
6522cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6523069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6524069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6525cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6526cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6527cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6528cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setMaxHeight() throws Throwable {
6529069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6530cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, true);
6531069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        // Do not force exact height only.
6532069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
6533069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                200,
6534069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                LinearLayout.LayoutParams.WRAP_CONTENT);
6535069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setLayoutParams(layoutParams));
6536069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6537069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6538c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setMaxHeight(
6539069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                autoSizeTextView.getHeight() / 4));
6540cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6541069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6542069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6543cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6544cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6545cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6546cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setHeight() throws Throwable {
6547069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6548cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, true);
6549069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        // Do not force exact height only.
6550069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
6551069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                200,
6552069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                LinearLayout.LayoutParams.WRAP_CONTENT);
6553069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setLayoutParams(layoutParams));
6554069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6555069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6556c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setHeight(
6557c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                autoSizeTextView.getHeight() / 4));
6558cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6559069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6560069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6561cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6562cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6563cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6564cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setLines() throws Throwable {
6565069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6566069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6567069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6568069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setLines(1));
6569cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6570069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6571069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() < initialTextSize);
6572cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6573cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6574cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6575cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setMaxWidth() throws Throwable {
6576069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6577069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                R.id.textview_autosize_xy, true);
6578cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        // Do not force exact width only.
6579cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
6580cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                LinearLayout.LayoutParams.WRAP_CONTENT,
6581069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                200);
6582cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setLayoutParams(layoutParams));
6583cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6584069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6585c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setMaxWidth(
6586c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                autoSizeTextView.getWidth() / 4));
6587cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6588069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6589069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() != initialTextSize);
6590cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6591cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6592cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6593cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setWidth() throws Throwable {
6594069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6595cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, true);
6596069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        // Do not force exact width only.
6597069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
6598069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                LinearLayout.LayoutParams.WRAP_CONTENT,
6599069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                200);
6600069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setLayoutParams(layoutParams));
6601069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6602cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6603069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6604c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setWidth(
6605c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu                autoSizeTextView.getWidth() / 4));
6606cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6607069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6608069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(autoSizeTextView.getTextSize() != initialTextSize);
6609cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6610cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6611cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
6612cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    public void testAutoSizeCallers_setLineSpacing() throws Throwable {
6613069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6614cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6615069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6616c0e543b38bdb38c13644ae3f74242afdbf064e9fAndrei Stingaceanu
6617cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setLineSpacing(
6618069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                autoSizeTextView.getLineSpacingExtra() * 4,
6619069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                autoSizeTextView.getLineSpacingMultiplier() * 4));
6620cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6621069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float changedTextSize = autoSizeTextView.getTextSize();
6622069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6623069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertTrue(changedTextSize < initialTextSize);
6624069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6625cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setLineSpacing(
6626cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                autoSizeTextView.getLineSpacingExtra(),
6627cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                autoSizeTextView.getLineSpacingMultiplier()));
6628cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6629069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6630069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertEquals(changedTextSize, autoSizeTextView.getTextSize(), 0f);
6631069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu    }
6632069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6633069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu    @Test
6634069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu    public void testAutoSizeCallers_setTextSizeIsNoOp() throws Throwable {
6635069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView autoSizeTextView = prepareAndRetrieveAutoSizeTestData(
6636069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                R.id.textview_autosize_xy, false);
6637069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final float initialTextSize = autoSizeTextView.getTextSize();
6638069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6639069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> autoSizeTextView.setTextSize(
6640069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                initialTextSize + 123f));
6641069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6642069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu
6643069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        assertEquals(initialTextSize, autoSizeTextView.getTextSize(), 0f);
6644cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6645cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6646cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    @Test
66475b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu    public void testAutoSizeXY_obtainStyledAttributes() {
66485b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu        DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
66495b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu        TextView autoSizeTextViewXY = (TextView) mActivity.findViewById(R.id.textview_autosize_xy);
66505b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu
6651771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // The size has been set to 50dp in the layout but this being an AUTO_SIZE_TEXT_TYPE_XY
6652771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // TextView, the size is considered max size thus the value returned by getSize() in this
6653771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // case should be lower than the one set (given that there is not much available space and
6654771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // the font size is very high). In theory the values could be equal for a different TextView
66555b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu        // configuration.
66565b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu        final float sizeSetInPixels = TypedValue.applyDimension(
66575b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu                TypedValue.COMPLEX_UNIT_DIP, 50f, metrics);
66585b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu        assertTrue(autoSizeTextViewXY.getTextSize() < sizeSetInPixels);
66595b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu    }
66605b44d230a4e966f12488126d75b1c0ea57072748Andrei Stingaceanu
66614f0c51ceb2e72548d9028e3797c4a86752d2b14fPhil Weaver    @Test
6662771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    public void testAutoSizeXY_getSetAutoSizeTextXY_defaults() {
66634f0c51ceb2e72548d9028e3797c4a86752d2b14fPhil Weaver        final TextView textView = new TextView(mActivity);
6664771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(TextView.AUTO_SIZE_TEXT_TYPE_NONE, textView.getAutoSizeTextType());
6665771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Min/Max/Granularity values for auto-sizing are 0 because they are not used.
6666771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(0, textView.getAutoSizeMinTextSize());
6667771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(0, textView.getAutoSizeMaxTextSize());
6668771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(0, textView.getAutoSizeStepGranularity());
6669771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6670771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeTextType(TextView.AUTO_SIZE_TEXT_TYPE_XY);
6671771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(TextView.AUTO_SIZE_TEXT_TYPE_XY, textView.getAutoSizeTextType());
6672771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Min/Max default values for auto-sizing XY have been loaded.
6673771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int minSize = textView.getAutoSizeMinTextSize();
6674771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertNotEquals(0, minSize);
6675771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int maxSize = textView.getAutoSizeMaxTextSize();
6676771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertNotEquals(0, maxSize);
6677771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertTrue(minSize < maxSize);
6678771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int stepGranularity = textView.getAutoSizeStepGranularity();
6679771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertNotEquals(0, stepGranularity);
6680771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6681771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeTextType(TextView.AUTO_SIZE_TEXT_TYPE_NONE);
6682771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(TextView.AUTO_SIZE_TEXT_TYPE_NONE, textView.getAutoSizeTextType());
6683771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Min/Max values for auto-sizing XY have been cleared.
6684771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(0, textView.getAutoSizeMinTextSize());
6685771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(0, textView.getAutoSizeMaxTextSize());
6686771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(0, textView.getAutoSizeStepGranularity());
6687771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    }
6688771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6689771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    @Test
6690771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    public void testAutoSizeXY_getSetAutoSizeStepGranularity() {
6691771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final TextView textView = new TextView(mActivity);
6692771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(TextView.AUTO_SIZE_TEXT_TYPE_NONE, textView.getAutoSizeTextType());
6693771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int initialValue = 0;
6694771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(initialValue, textView.getAutoSizeStepGranularity());
66954f0c51ceb2e72548d9028e3797c4a86752d2b14fPhil Weaver
6696771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeTextType(TextView.AUTO_SIZE_TEXT_TYPE_XY);
6697771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(TextView.AUTO_SIZE_TEXT_TYPE_XY, textView.getAutoSizeTextType());
6698771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int defaultValue = 1; // 1px.
6699771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // If the auto-size type is AUTO_SIZE_TEXT_TYPE_XY then it means textView went through the
6700771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // auto-size setup and given that 0 is an invalid value it changed it to the default.
6701771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(defaultValue, textView.getAutoSizeStepGranularity());
6702771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6703771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int newValue = 33;
6704771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeStepGranularity(TypedValue.COMPLEX_UNIT_PX, newValue);
6705771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(newValue, textView.getAutoSizeStepGranularity());
6706771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    }
6707771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6708771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    @Test
6709771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    public void testAutoSizeXY_getSetAutoSizeMinTextSize() {
6710771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final TextView textView = new TextView(mActivity);
6711771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeTextType(TextView.AUTO_SIZE_TEXT_TYPE_XY);
6712771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(TextView.AUTO_SIZE_TEXT_TYPE_XY, textView.getAutoSizeTextType());
6713771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int minSize = textView.getAutoSizeMinTextSize();
6714771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertNotEquals(0, minSize);
6715771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int maxSize = textView.getAutoSizeMaxTextSize();
6716771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertNotEquals(0, maxSize);
6717771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6718771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // This is just a test check to verify the next assertions. If this fails it is a problem
6719771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // of this test setup (we need at least 2 units).
6720771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertTrue((maxSize - minSize) > 1);
6721771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int newMinSize = maxSize - 1;
6722771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeMinTextSize(TypedValue.COMPLEX_UNIT_PX, newMinSize);
6723771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(newMinSize, textView.getAutoSizeMinTextSize());
6724771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Max size has not changed.
6725771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(maxSize, textView.getAutoSizeMaxTextSize());
6726771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6727771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Prevent validation error (max <= min).
6728771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeMaxTextSize(TypedValue.COMPLEX_UNIT_SP, newMinSize + 10);
6729771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeMinTextSize(TypedValue.COMPLEX_UNIT_SP, newMinSize);
6730771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // It does not matter which unit has been used to set the min size, the getter always
6731771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // returns it in pixels.
6732771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, newMinSize,
6733771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu                mActivity.getResources().getDisplayMetrics()), textView.getAutoSizeMinTextSize());
6734771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    }
6735771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6736771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    @Test(expected = IllegalStateException.class)
6737771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    public void testAutoSizeXY_throwsException_whenMaxLessThanMin() {
6738771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final TextView textView = new TextView(mActivity);
6739771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeTextType(TextView.AUTO_SIZE_TEXT_TYPE_XY);
6740771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeMinTextSize(TypedValue.COMPLEX_UNIT_PX, 10);
6741771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Should throw IllegalStateException here (because min > max).
6742771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeMaxTextSize(TypedValue.COMPLEX_UNIT_PX, 9);
6743771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    }
6744771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6745771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    @Test
6746771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    public void testAutoSizeXY_getSetAutoSizeMaxTextSize() {
6747771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final TextView textView = new TextView(mActivity);
6748771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeTextType(TextView.AUTO_SIZE_TEXT_TYPE_XY);
6749771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(TextView.AUTO_SIZE_TEXT_TYPE_XY, textView.getAutoSizeTextType());
6750771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int minSize = textView.getAutoSizeMinTextSize();
6751771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertNotEquals(0, minSize);
6752771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int maxSize = textView.getAutoSizeMaxTextSize();
6753771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertNotEquals(0, maxSize);
6754771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6755771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int newMaxSize = maxSize + 11;
6756771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeMaxTextSize(TypedValue.COMPLEX_UNIT_PX, newMaxSize);
6757771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(newMaxSize, textView.getAutoSizeMaxTextSize());
6758771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Min size has not changed.
6759771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(minSize, textView.getAutoSizeMinTextSize());
6760771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu
6761771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        textView.setAutoSizeMaxTextSize(TypedValue.COMPLEX_UNIT_SP, newMaxSize);
6762771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // It does not matter which unit has been used to set the max size, the getter always
6763771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // returns it in pixels.
6764771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, newMaxSize,
6765771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu                mActivity.getResources().getDisplayMetrics()), textView.getAutoSizeMaxTextSize());
67664f0c51ceb2e72548d9028e3797c4a86752d2b14fPhil Weaver    }
67674f0c51ceb2e72548d9028e3797c4a86752d2b14fPhil Weaver
6768771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    @Test
6769771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    public void testAutoSizeXY_autoSizeCalledWhenTypeChanged() throws Throwable {
6770771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        mTextView = findTextView(R.id.textview_text);
6771771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Make sure we pick an already inflated non auto-sized text view.
6772771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(TextView.AUTO_SIZE_TEXT_TYPE_NONE, mTextView.getAutoSizeTextType());
6773771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // Set the text size to a very low value in order to prepare for auto-size.
6774771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        final int customTextSize = 3;
6775771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6776771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu                mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, customTextSize));
6777771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        mInstrumentation.waitForIdleSync();
6778771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertEquals(customTextSize, mTextView.getTextSize(), 0f);
6779771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        mActivityRule.runOnUiThread(() ->
6780771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu                mTextView.setAutoSizeTextType(TextView.AUTO_SIZE_TEXT_TYPE_XY));
6781771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        mInstrumentation.waitForIdleSync();
6782771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        // The size of the text should have changed.
6783771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu        assertNotEquals(customTextSize, mTextView.getTextSize(), 0f);
6784771078e382470352e547c3ac6a3dd93883d504fdAndrei Stingaceanu    }
67854f0c51ceb2e72548d9028e3797c4a86752d2b14fPhil Weaver
6786ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki    @Test
6787ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki    public void testSmartSelection() throws Throwable {
6788ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        mTextView = findTextView(R.id.textview_text);
6789ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        String text = "The president-elect, Filip, is coming to town tomorrow.";
6790ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        int startIndex = text.indexOf("president");
6791ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        int endIndex = startIndex + "president".length();
6792ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        initTextViewForTypingOnUiThread();
6793ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        TextClassificationManager tcm = mActivity.getSystemService(TextClassificationManager.class);
6794ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        mActivityRule.runOnUiThread(() -> {
6795ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki            mTextView.setTextIsSelectable(true);
6796ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki            mTextView.setText(text, BufferType.EDITABLE);
6797ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki            mTextView.setTextClassifier(tcm.getDefaultTextClassifier());
6798ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        });
6799ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        mInstrumentation.waitForIdleSync();
6800ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki
6801ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        Point offset = getCenterPositionOfTextAt(mTextView, startIndex, endIndex);
6802ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        CtsTouchUtils.emulateLongPressOnView(mInstrumentation, mTextView, offset.x, offset.y);
6803ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        PollingCheck.waitFor(mTextView::hasSelection);
6804ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki
6805ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        TextSelection selection = tcm.getDefaultTextClassifier()
6806ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki                .suggestSelection(text, startIndex, endIndex);
6807ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        assertEquals(selection.getSelectionStartIndex(), mTextView.getSelectionStart());
6808ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        assertEquals(selection.getSelectionEndIndex(), mTextView.getSelectionEnd());
6809ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        // TODO: Test the floating toolbar content.
6810ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki    }
6811ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki
6812cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki    @Test
6813cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki    public void testSmartSelection_multiSelect() throws Throwable {
6814cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        mTextView = findTextView(R.id.textview_text);
6815cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        String text = "The president-elect, Filip, is coming to town tomorrow.";
6816cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        int startIndex = text.indexOf("is coming to town");
6817cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        int endIndex = startIndex + "is coming to town".length();
6818cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        initTextViewForTypingOnUiThread();
6819cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        TextClassificationManager tcm = mActivity.getSystemService(TextClassificationManager.class);
6820cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        mActivityRule.runOnUiThread(() -> {
6821cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki            mTextView.setTextIsSelectable(true);
6822cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki            mTextView.setText(text, BufferType.EDITABLE);
6823cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki            mTextView.setTextClassifier(tcm.getDefaultTextClassifier());
6824cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        });
6825cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        mInstrumentation.waitForIdleSync();
6826cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki
6827cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        Point start = getCenterPositionOfTextAt(mTextView, startIndex, startIndex);
6828cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        Point end = getCenterPositionOfTextAt(mTextView, endIndex, endIndex);
6829cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        int[] viewOnScreenXY = new int[2];
6830cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        mTextView.getLocationOnScreen(viewOnScreenXY);
6831cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        int startX = start.x + viewOnScreenXY[0];
6832cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        int startY = start.y + viewOnScreenXY[1];
6833cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        int offsetX = end.x - start.x;
6834cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki
6835cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        CtsTouchUtils.emulateLongPressAndDragGesture(
6836cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki                mInstrumentation, startX, startY, offsetX, 0 /* offsetY */);
6837cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki
6838cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        // No smart selection when multiple words are selected.
6839cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        assertEquals(startIndex, mTextView.getSelectionStart());
6840cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki        assertEquals(endIndex, mTextView.getSelectionEnd());
6841cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki    }
6842cfe27a9a9b8580e413a15912379aae9db161c19fAbodunrinwa Toki
68439560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    /**
6844069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu     * Some TextView attributes require non-fixed width and/or layout height. This function removes
6845069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu     * all other existing views from the layout leaving only one auto-size TextView (for exercising
6846069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu     * the auto-size behavior) which has been set up to suit the test needs.
6847cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu     *
6848069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu     * @param viewId The id of the view to prepare.
6849cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu     * @param shouldWrapLayoutContent Specifies if the layout params should wrap content
6850cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu     *
6851069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu     * @return a TextView configured for auto size tests.
6852cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu     */
6853069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu    private TextView prepareAndRetrieveAutoSizeTestData(final int viewId,
6854cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu            final boolean shouldWrapLayoutContent) throws Throwable {
6855cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
6856cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu            LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest);
6857069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu            TextView targetedTextView = (TextView) mActivity.findViewById(viewId);
6858cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu            ll.removeAllViews();
6859069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu            ll.addView(targetedTextView);
6860cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        });
6861cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
6862cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6863069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        final TextView textView = (TextView) mActivity.findViewById(viewId);
6864cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        if (shouldWrapLayoutContent) {
6865cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu            // Do not force exact width or height.
6866cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu            final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
6867cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                    LinearLayout.LayoutParams.WRAP_CONTENT,
6868cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu                    LinearLayout.LayoutParams.WRAP_CONTENT);
6869069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu            mActivityRule.runOnUiThread(() -> {
6870069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu                textView.setLayoutParams(layoutParams);
6871069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu            });
6872cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu            mInstrumentation.waitForIdleSync();
6873cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu        }
6874cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6875069b4a9d9beacb7ae994d97ef44b696917822d21Andrei Stingaceanu        return textView;
6876cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    }
6877cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu
6878cbd4b0d6ffb56f4506b738559cfacc93b6338604Andrei Stingaceanu    /**
68799560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu     * Removes all existing views from the layout and adds a basic TextView (for exercising the
68809560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu     * ClickableSpan onClick() behavior) in order to prevent scrolling. Adds a ClickableSpan to the
68819560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu     * TextView and returns the ClickableSpan and position details about it to be used in individual
68829560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu     * tests.
68839560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu     */
68846b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu    private ClickableSpanTestDetails prepareAndRetrieveClickableSpanDetails() throws Throwable {
68856b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
68869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest);
68879560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            ll.removeAllViews();
68889560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView = new TextView(mActivity);
68899560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            ll.addView(mTextView);
68909560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
68919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
68929560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
68939560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpan mockTextLink = mock(ClickableSpan.class);
68949560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        StringBuilder textViewContent = new StringBuilder();
68959560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        String clickableString = "clickMe!";
68969560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        textViewContent.append(clickableString);
68979560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final int startPos = 0;
68989560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
68999560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        // Insert more characters to make some room for swiping.
69009560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        for (int i = 0; i < 200; i++) {
69019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            textViewContent.append(" text");
69029560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        }
69039560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        SpannableString spannableString = new SpannableString(textViewContent);
69049560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        final int endPos = clickableString.length();
69059560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        spannableString.setSpan(mockTextLink, startPos, endPos, 0);
69066b02e92df9486b4b1723473987bf025dcd18a23dAndrei Stingaceanu        mActivityRule.runOnUiThread(() -> {
69079560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setText(spannableString);
69089560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mTextView.setMovementMethod(LinkMovementMethod.getInstance());
69099560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        });
69109560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
69119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
69129560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        return new ClickableSpanTestDetails(mockTextLink, mTextView, startPos, endPos);
69139560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
69149560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
69159560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private static final class ClickableSpanTestDetails {
69169560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpan mClickableSpan;
69179560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        int mXPosInside;
69189560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        int mYPosInside;
69199560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        int mXPosOutside;
69209560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        int mYPosOutside;
69219560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
69229560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        private int mStartCharPos;
69239560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        private int mEndCharPos;
69249560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        private TextView mParent;
69259560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
69269560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        ClickableSpanTestDetails(ClickableSpan clickableSpan, TextView parent,
69279560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu                int startCharPos, int endCharPos) {
69289560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mClickableSpan = clickableSpan;
69299560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mParent = parent;
69309560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mStartCharPos = startCharPos;
69319560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mEndCharPos = endCharPos;
69329560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
69339560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            calculatePositions();
69349560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        }
69359560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
69369560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        private void calculatePositions() {
6937934d09af7f0bc700eeecb3091ab2ee4dad757476Keisuke Kuroyanagi            int xStart = (int) mParent.getLayout().getPrimaryHorizontal(mStartCharPos, true, true);
6938934d09af7f0bc700eeecb3091ab2ee4dad757476Keisuke Kuroyanagi            int xEnd = (int) mParent.getLayout().getPrimaryHorizontal(mEndCharPos, true, true);
69399560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            int line = mParent.getLayout().getLineForOffset(mEndCharPos);
69409560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            int yTop = mParent.getLayout().getLineTop(line);
69419560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            int yBottom = mParent.getLayout().getLineBottom(line);
69429560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
69439560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mXPosInside = (xStart + xEnd) / 2;
69449560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mYPosInside = (yTop + yBottom) / 2;
69459560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mXPosOutside = xEnd + 1;
69469560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu            mYPosOutside = yBottom + 1;
69479560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        }
69489560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    }
69499560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu
695057c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri    private MotionEvent createMouseHoverEvent(View view) {
695157c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        final int[] xy = new int[2];
695257c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        view.getLocationOnScreen(xy);
695357c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        final int viewWidth = view.getWidth();
695457c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        final int viewHeight = view.getHeight();
695557c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        float x = xy[0] + viewWidth / 2.0f;
695657c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        float y = xy[1] + viewHeight / 2.0f;
695757c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        long eventTime = SystemClock.uptimeMillis();
695857c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[1];
695957c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        pointerCoords[0] = new MotionEvent.PointerCoords();
696057c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        pointerCoords[0].x = x;
696157c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        pointerCoords[0].y = y;
696257c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        final int[] pointerIds = new int[1];
696357c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        pointerIds[0] = 0;
696457c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri        return MotionEvent.obtain(0, eventTime, MotionEvent.ACTION_HOVER_MOVE, 1, pointerIds,
696557c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri                pointerCoords, 0, 0, 0, 0, 0, InputDevice.SOURCE_MOUSE, 0);
696657c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri    }
696757c708762722100ec4e7b4fa57c67248c5a50b66Clara Bayarri
69689560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void layout(final TextView textView) throws Throwable {
69699560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mActivity.setContentView(textView));
6970fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6971fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6972fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
69739560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void layout(final int layoutId) throws Throwable {
69749560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mActivity.setContentView(layoutId));
6975fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6976fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6977fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6978fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private TextView findTextView(int id) {
6979fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        return (TextView) mActivity.findViewById(id);
6980fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6981fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6982fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private int getAutoLinkMask(int id) {
6983fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        return findTextView(id).getAutoLinkMask();
6984fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6985fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
69869560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void setMaxLines(final int lines) throws Throwable {
69879560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setMaxLines(lines));
69886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
69896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
69906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
69919560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void setMaxWidth(final int pixels) throws Throwable {
69929560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setMaxWidth(pixels));
6993fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6994fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6995fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
69969560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void setMinWidth(final int pixels) throws Throwable {
69979560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setMinWidth(pixels));
6998fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6999fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7000fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70019560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void setMaxHeight(final int pixels) throws Throwable {
70029560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setMaxHeight(pixels));
7003fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70069560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void setMinHeight(final int pixels) throws Throwable {
70079560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setMinHeight(pixels));
7008fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7009fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7010fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70119560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void setMinLines(final int minLines) throws Throwable {
70129560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setMinLines(minLines));
7013fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7014fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7016fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    /**
7017fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * Convenience for {@link TextView#setText(CharSequence, BufferType)}. And
7018fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * the buffer type is fixed to SPANNABLE.
7019fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     *
7020fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * @param tv the text view
7021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * @param content the content
7022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     */
70239560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu    private void setSpannableText(final TextView tv, final String content) throws Throwable {
70249560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> tv.setText(content, BufferType.SPANNABLE));
7025fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70284b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void setLines(final int lines) throws Throwable {
70299560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setLines(lines));
7030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70334b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void setHorizontallyScrolling(final boolean whether) throws Throwable {
70349560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setHorizontallyScrolling(whether));
7035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70384b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void setWidth(final int pixels) throws Throwable {
70399560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setWidth(pixels));
7040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70434b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void setHeight(final int pixels) throws Throwable {
70449560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setHeight(pixels));
7045fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7047fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70484b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void setMinEms(final int ems) throws Throwable {
70499560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setMinEms(ems));
7050fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7051fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7052fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70534b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void setMaxEms(final int ems) throws Throwable {
70549560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setMaxEms(ems));
7055fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7056fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7057fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70584b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void setEms(final int ems) throws Throwable {
70599560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setEms(ems));
7060fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7062fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
70634b645d615abed9d92ce586a135ad0c8f2e08bd48Kirill Grouchnikov    private void setLineSpacing(final float add, final float mult) throws Throwable {
70649560fd0bff8ebc15f71898067d514cf1e2d3ad09Andrei Stingaceanu        mActivityRule.runOnUiThread(() -> mTextView.setLineSpacing(add, mult));
7065fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
7066fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7067fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7068ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki    /**
7069ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki     * Returns the x, y coordinates of text at a specified indices relative to the position of the
7070ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki     * TextView.
7071ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki     *
7072ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki     * @param textView
7073ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki     * @param startIndex start index of the text in the textView
7074ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki     * @param endIndex end index of the text in the textView
7075ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki     */
7076ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki    private static Point getCenterPositionOfTextAt(
7077ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki            TextView textView, int startIndex, int endIndex) {
7078ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        int xStart = (int) textView.getLayout().getPrimaryHorizontal(startIndex, true, true);
7079ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        int xEnd = (int) textView.getLayout().getPrimaryHorizontal(endIndex, true, true);
7080ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        int line = textView.getLayout().getLineForOffset(endIndex);
7081ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        int yTop = textView.getLayout().getLineTop(line);
7082ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        int yBottom = textView.getLayout().getLineBottom(line);
7083ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki
7084ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki        return new Point((xStart + xEnd) / 2 /* x */, (yTop + yBottom) / 2 /* y */);
7085ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki    }
7086ad7abe36f771de18179fa1bc5487b65e12e1e7dcAbodunrinwa Toki
7087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static abstract class TestSelectedRunnable implements Runnable {
7088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private TextView mTextView;
7089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mIsSelected1;
7090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mIsSelected2;
7091fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7092fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public TestSelectedRunnable(TextView textview) {
7093fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView = textview;
7094fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7095fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7096fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean getIsSelected1() {
7097fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mIsSelected1;
7098fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7099fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7100fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean getIsSelected2() {
7101fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mIsSelected2;
7102fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7103fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7104fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveIsSelected1() {
7105fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mIsSelected1 = mTextView.isSelected();
7106fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7107fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveIsSelected2() {
7109fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mIsSelected2 = mTextView.isSelected();
7110fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7111fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7112fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static abstract class TestLayoutRunnable implements Runnable {
7114fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private TextView mTextView;
7115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private Layout mLayout;
7116fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7117fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public TestLayoutRunnable(TextView textview) {
7118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView = textview;
7119fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public Layout getLayout() {
7122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mLayout;
7123fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveLayout() {
7126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mLayout = mTextView.getLayout();
7127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7130fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static class MockTextWatcher implements TextWatcher {
7131fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasCalledAfterTextChanged;
7132fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasCalledBeforeTextChanged;
7133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasOnTextChanged;
7134fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7135fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void reset(){
7136fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledAfterTextChanged = false;
7137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledBeforeTextChanged = false;
7138fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasOnTextChanged = false;
7139fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7140fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledAfterTextChanged() {
7142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasCalledAfterTextChanged;
7143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledBeforeTextChanged() {
7146fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasCalledBeforeTextChanged;
7147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledOnTextChanged() {
7150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasOnTextChanged;
7151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void afterTextChanged(Editable s) {
7154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledAfterTextChanged = true;
7155fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7156fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7157fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
7158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledBeforeTextChanged = true;
7159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void onTextChanged(CharSequence s, int start, int before, int count) {
7162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasOnTextChanged = true;
7163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
7164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
7165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    /**
7167277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook     * A TextWatcher that converts the text to spaces whenever the text changes.
7168277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook     */
7169277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    private static class ConvertToSpacesTextWatcher implements TextWatcher {
7170277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        boolean mChangingText;
7171277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
7172277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
7173277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
7174277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
7175277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
7176277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
7177277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void onTextChanged(CharSequence s, int start, int before, int count) {
7178277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
7179277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
7180277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
7181277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void afterTextChanged(Editable s) {
7182277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            // Avoid infinite recursion.
7183277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            if (mChangingText) {
7184277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                return;
7185277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
7186277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            mChangingText = true;
7187277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            // Create a string of s.length() spaces.
7188277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            StringBuilder builder = new StringBuilder(s.length());
7189277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            for (int i = 0; i < s.length(); i++) {
7190277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                builder.append(' ');
7191277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
7192277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            s.replace(0, s.length(), builder.toString());
7193277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            mChangingText = false;
7194277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
7195277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
7196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su}
7197