TextViewTest.java revision 288d156a90ddd9dd93c05e4892a73390e3778c00
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
19fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Activity;
20fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Instrumentation;
21fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Instrumentation.ActivityMonitor;
22354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.content.Context;
23fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.Intent;
242751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonakaimport android.content.pm.PackageManager;
25fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.res.ColorStateList;
26938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport android.content.res.Resources;
27fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.res.Resources.NotFoundException;
285bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinirimport android.cts.util.KeyEventUtil;
290162547f44173f0604d8a80143c128d9892460a1Kristian Monsenimport android.cts.util.PollingCheck;
30d82745ff4a8b174f7be1258fd329dedc52ce58bbChenjie Luoimport android.cts.util.WidgetTestUtils;
31fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Color;
32fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Paint;
33afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.graphics.Path;
34fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukaiimport android.graphics.PorterDuff;
35fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Rect;
36afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.graphics.RectF;
37fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Typeface;
38fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.drawable.BitmapDrawable;
39ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.graphics.drawable.ColorDrawable;
40fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.drawable.Drawable;
41fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.net.Uri;
42fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.os.Bundle;
43354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.Handler;
44265b3d21959154e9a6ce0fdd888249f3699b7bddYohei Yukawaimport android.os.LocaleList;
45354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.Looper;
465b51f77b99861d48fec1c327252416f726b3b01aJames Cookimport android.os.Parcelable;
47354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.ResultReceiver;
48fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.test.ActivityInstrumentationTestCase2;
4972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.test.TouchUtils;
50fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.test.UiThreadTest;
5198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinirimport android.test.suitebuilder.annotation.MediumTest;
52ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.test.suitebuilder.annotation.SmallTest;
53fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Editable;
54fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.InputFilter;
55fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.InputType;
56fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Layout;
57fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Selection;
58fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Spannable;
59fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.SpannableString;
60ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.text.Spanned;
61fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextPaint;
62fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextUtils;
63fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextUtils.TruncateAt;
64afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.text.TextWatcher;
65fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.ArrowKeyMovementMethod;
66fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DateKeyListener;
67fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DateTimeKeyListener;
68fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DialerKeyListener;
69fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DigitsKeyListener;
70fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.KeyListener;
71fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.LinkMovementMethod;
72fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.MovementMethod;
73fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.PasswordTransformationMethod;
74fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.QwertyKeyListener;
75fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.SingleLineTransformationMethod;
76fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TextKeyListener;
77afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.text.method.TextKeyListener.Capitalize;
78fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TimeKeyListener;
79fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TransformationMethod;
8098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinirimport android.text.style.ImageSpan;
81fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.style.URLSpan;
82ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagiimport android.text.style.UnderlineSpan;
83fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.util.Linkify;
84fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.util.DisplayMetrics;
85fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.util.TypedValue;
86ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.view.ActionMode;
87fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.ContextMenu;
88afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.view.ContextMenu.ContextMenuInfo;
89fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.Gravity;
90fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.KeyEvent;
9132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagiimport android.view.Menu;
92fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.View;
93afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.view.ViewGroup;
9432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagiimport android.view.accessibility.AccessibilityNodeInfo;
9572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.BaseInputConnection;
9672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.EditorInfo;
9772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.ExtractedText;
9872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.ExtractedTextRequest;
99c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cookimport android.view.inputmethod.InputConnection;
100354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.view.inputmethod.InputMethodManager;
101c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunneimport android.widget.EditText;
102bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsuimport android.widget.FrameLayout;
10362808562ee0218f6ea3c07d333f7a65fc57c122fBrian Muramatsuimport android.widget.LinearLayout;
104354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.widget.ScrollView;
105fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.Scroller;
106fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.TextView;
107fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.TextView.BufferType;
108938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport android.widget.cts.util.TestUtils;
10941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikovimport android.widget.cts.util.ViewTestUtils;
110fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
111938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport org.mockito.invocation.InvocationOnMock;
112ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport org.xmlpull.v1.XmlPullParserException;
113ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
114fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport java.io.IOException;
115b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonakaimport java.util.Locale;
116fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
117938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport static org.mockito.Matchers.any;
118938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport static org.mockito.Mockito.*;
119938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su/**
121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * Test {@link TextView}.
122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su */
1234ca04c0729a0e810b5af16edcd52bb8cb59bf55eChenjie Luopublic class TextViewTest extends ActivityInstrumentationTestCase2<TextViewCtsActivity> {
124fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private TextView mTextView;
126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private Activity mActivity;
127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private Instrumentation mInstrumentation;
128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static final String LONG_TEXT = "This is a really long string which exceeds "
1297375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "the width of the view. New devices have a much larger screen which "
1307375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "actually enables long strings to be displayed with no fading. "
1317375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "I have made this string longer to fix this case. If you are correcting "
1327375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "this text, I would love to see the kind of devices you guys now use!";
133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static final long TIMEOUT = 5000;
13422d40a1fcc078329a7e5a34ff5eeadeca9c70d49Kenny Root    private CharSequence mTransformedText;
1355bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir    private KeyEventUtil mKeyEventUtil;
136354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    private Handler mHandler = new Handler(Looper.getMainLooper());
137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
138fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public TextViewTest() {
139a3e5fa456a01c74b91a5d66981433db598bcc9a7Agatha Man        super("android.widget.cts", TextViewCtsActivity.class);
140fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @Override
143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    protected void setUp() throws Exception {
144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        super.setUp();
145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity = getActivity();
146938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        PollingCheck.waitFor(() -> mActivity.hasWindowFocus());
147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation = getInstrumentation();
1485bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil = new KeyEventUtil(mInstrumentation);
149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
15128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    /**
15228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook     * Promotes the TextView to editable and places focus in it to allow simulated typing.
15328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook     */
15428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    private void initTextViewForTyping() {
15528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        mActivity.runOnUiThread(new Runnable() {
15628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook            public void run() {
15728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView = findTextView(R.id.textview_text);
15828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
15928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.setText("", BufferType.EDITABLE);
16028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.requestFocus();
16128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook            }
16228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        });
16328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        mInstrumentation.waitForIdleSync();
16428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
16528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testConstructor() {
167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        new TextView(mActivity);
168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        new TextView(mActivity, null);
170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
171938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        new TextView(mActivity, null, android.R.attr.textViewStyle);
172938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
173f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_DeviceDefault_TextView);
174f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov
175f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_DeviceDefault_Light_TextView);
176f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov
177f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_Material_TextView);
178f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov
179938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_Material_Light_TextView);
180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
183fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessText() {
184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
185fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String expected = mActivity.getResources().getString(R.string.text_view_hello);
187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(expected);
188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, tv.getText().toString());
189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null);
191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
194fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLineHeight() {
195fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineHeight() > 0);
197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLineSpacing(1.2f, 1.5f);
199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineHeight() > 0);
200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLayout() {
203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView = findTextView(R.id.textview_text);
206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.CENTER);
207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
209fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
210fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
211fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
212fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TestLayoutRunnable runnable = new TestLayoutRunnable(mTextView) {
213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // change the text of TextView.
215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText("Hello, Android!");
216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveLayout();
217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(runnable);
220fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
221fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(runnable.getLayout());
222fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessKeyListener() {
226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
227fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
228fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView = findTextView(R.id.textview_text);
229fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
230fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getKeyListener());
234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final KeyListener digitsKeyListener = DigitsKeyListener.getInstance();
236fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setKeyListener(digitsKeyListener);
240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(digitsKeyListener, mTextView.getKeyListener());
244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener
246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                = QwertyKeyListener.getInstance(false, Capitalize.NONE);
247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setKeyListener(qwertyKeyListener);
250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(qwertyKeyListener, mTextView.getKeyListener());
254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessMovementMethod() {
257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence LONG_TEXT = "Scrolls the specified widget to the specified "
258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "coordinates, except constrains the X scrolling position to the horizontal "
259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "regions of the text that will be visible after scrolling to "
260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "the specified Y position.";
261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int selectionStart = 10;
262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int selectionEnd = LONG_TEXT.length();
263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final MovementMethod movementMethod = ArrowKeyMovementMethod.getInstance();
264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView = findTextView(R.id.textview_text);
267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMovementMethod(movementMethod);
268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(LONG_TEXT, BufferType.EDITABLE);
269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Selection.setSelection((Editable) mTextView.getText(),
270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                        selectionStart, selectionEnd);
271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(movementMethod, mTextView.getMovementMethod());
277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
27903818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_ALT_LEFT,
280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                KeyEvent.KEYCODE_DPAD_UP);
281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the selection has been removed.
282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
283fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionEnd(mTextView.getText()));
284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMovementMethod(null);
288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Selection.setSelection((Editable) mTextView.getText(),
289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                        selectionStart, selectionEnd);
290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getMovementMethod());
296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
29803818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_ALT_LEFT,
299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                KeyEvent.KEYCODE_DPAD_UP);
300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the selection will not be changed.
301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
302fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testLength() {
307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String content = "This is content";
310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(content);
311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(content.length(), mTextView.length());
312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("");
314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.length());
315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(null);
317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.length());
318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessGravity() {
322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_gravity);
323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_default);
3254bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.TOP | Gravity.START, mTextView.getGravity());
326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_bottom);
3284bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.BOTTOM | Gravity.START, mTextView.getGravity());
329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_right);
331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity());
332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_center);
334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER, mTextView.getGravity());
335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_fill);
337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.FILL, mTextView.getGravity());
338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_center_vertical_right);
340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER_VERTICAL | Gravity.RIGHT, mTextView.getGravity());
341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, mTextView.getGravity());
344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.FILL);
345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.FILL, mTextView.getGravity());
346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER);
347fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER, mTextView.getGravity());
348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.NO_GRAVITY);
3504bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.TOP | Gravity.START, mTextView.getGravity());
351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.RIGHT);
353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity());
354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.FILL_VERTICAL);
3564bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.FILL_VERTICAL | Gravity.START, mTextView.getGravity());
357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //test negative input value.
359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(-1);
360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getGravity());
361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessAutoLinkMask() {
364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text1 =
366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new SpannableString("URL: http://www.google.com. mailto: account@gmail.com");
367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setAutoLinkMask(Linkify.ALL);
370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text1, BufferType.EDITABLE);
371fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
373fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.ALL, mTextView.getAutoLinkMask());
375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Spannable spanString = (Spannable) mTextView.getText();
377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        URLSpan[] spans = spanString.getSpans(0, spanString.length(), URLSpan.class);
378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(spans);
379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("http://www.google.com", spans[0].getURL());
381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("mailto:account@gmail.com", spans[1].getURL());
382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text2 =
384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            new SpannableString("name: Jack. tel: +41 44 800 8999");
385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS);
388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text2, BufferType.EDITABLE);
389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS, mTextView.getAutoLinkMask());
393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spanString = (Spannable) mTextView.getText();
395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = spanString.getSpans(0, spanString.length(), URLSpan.class);
396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(spans);
397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, spans.length);
398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("tel:+41448008999", spans[0].getURL());
399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(R.layout.textview_autolink);
401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 1 for web, 2 for email, 4 for phone, 7 for all(web|email|phone)
402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, getAutoLinkMask(R.id.autolink_default));
403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS, getAutoLinkMask(R.id.autolink_web));
404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.EMAIL_ADDRESSES, getAutoLinkMask(R.id.autolink_email));
405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS, getAutoLinkMask(R.id.autolink_phone));
406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.ALL, getAutoLinkMask(R.id.autolink_all));
407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES,
408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound1));
409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS | Linkify.PHONE_NUMBERS,
410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound2));
411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS,
412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound3));
413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS | Linkify.ALL,
414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound4));
415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessTextSize() {
418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 20f);
422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20f, metrics),
423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20f);
426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, metrics),
427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20f);
430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics),
431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // setTextSize by default unit "sp"
434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(20f);
435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics),
436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(200f);
439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 200f, metrics),
440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessTextColor() {
444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.GREEN);
447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GREEN, mTextView.getCurrentTextColor());
448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getTextColors());
449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.BLACK);
451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentTextColor());
452fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.BLACK), mTextView.getTextColors());
453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.RED);
455fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.RED, mTextView.getCurrentTextColor());
456fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.RED), mTextView.getTextColors());
457fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
458fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using ColorStateList
459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
460fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_focused}, new int[0] },
462fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
463fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(colors);
464fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getTextColors());
465fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentTextColor());
466fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
467fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // exceptional
468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
469fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setTextColor(null);
470fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should thrown exception if the colors is null");
471fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e){
472fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
473fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
474fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
475325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette    public void testGetTextColor() {
476325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        // TODO: How to get a suitable TypedArray to test this method.
477325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette
478325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        try {
479325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette            TextView.getTextColor(mActivity, null, -1);
480325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette            fail("There should be a NullPointerException thrown out.");
481325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        } catch (NullPointerException e) {
482325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        }
483325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette    }
484325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette
485354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testAccessHighlightColor() {
486354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
487354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
488354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> {
489354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setTextIsSelectable(true);
490354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setText("abcd", BufferType.EDITABLE);
491354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setHighlightColor(Color.BLUE);
492354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        });
493354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
494354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
495354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(textView.isTextSelectable());
496354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.BLUE, textView.getHighlightColor());
497354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
498354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Long click on the text selects all text and shows selection handlers. The view has an
499354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // attribute layout_width="wrap_content", so clicked location (the center of the view)
500354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // should be on the text.
501354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        TouchUtils.longClickView(this, textView);
502fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
503354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // At this point the entire content of our TextView should be selected and highlighted
504354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // with blue. Now change the highlight to red while the selection is still on.
505354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setHighlightColor(Color.RED));
506354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
507354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
508354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.RED, textView.getHighlightColor());
509354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", textView.getText()));
510354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
511354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Remove the selection
512354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> Selection.removeSelection((Spannable) textView.getText()));
513354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
514354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
515354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // And switch highlight to green after the selection has been removed
516354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setHighlightColor(Color.GREEN));
517354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
518354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
519354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.GREEN, textView.getHighlightColor());
520354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", textView.getText()));
521fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
522fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
5236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
524fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetShadowLayer() {
5256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test values
5266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final MockTextView mockTextView = new MockTextView(mActivity);
5276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
5286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, 0.3f, 0.4f, Color.CYAN);
5296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(Color.CYAN, mockTextView.getShadowColor());
5306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0.3f, mockTextView.getShadowDx());
5316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0.4f, mockTextView.getShadowDy());
5326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(1.0f, mockTextView.getShadowRadius());
533fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
534fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // shadow is placed to the left and below the text
5356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, 0.3f, 0.3f, Color.CYAN);
5366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(mockTextView.isPaddingOffsetRequired());
5376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getLeftPaddingOffset());
5386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getTopPaddingOffset());
5396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(1, mockTextView.getRightPaddingOffset());
5406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(1, mockTextView.getBottomPaddingOffset());
541fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
542fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // shadow is placed to the right and above the text
5436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, -0.8f, -0.8f, Color.CYAN);
5446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(mockTextView.isPaddingOffsetRequired());
5456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mockTextView.getLeftPaddingOffset());
5466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mockTextView.getTopPaddingOffset());
5476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getRightPaddingOffset());
5486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getBottomPaddingOffset());
549fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
550fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // no shadow
5516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(0.0f, 0.0f, 0.0f, Color.CYAN);
5526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(mockTextView.isPaddingOffsetRequired());
5536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getLeftPaddingOffset());
5546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getTopPaddingOffset());
5556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getRightPaddingOffset());
5566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getBottomPaddingOffset());
557fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
558fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
559fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
560fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetSelectAllOnFocus() {
561fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_selectallonfocus);
562fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String content = "This is the content";
563fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String blank = "";
564fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.selectAllOnFocus_default);
565fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(blank, BufferType.SPANNABLE);
566fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
567fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
568fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
569fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
570fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
571fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
572fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
573fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
574fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
575fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(content, BufferType.SPANNABLE);
576fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(true);
577fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
578fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
579fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
580fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
581fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
582fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
583fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
584fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(content.length(), mTextView.getSelectionEnd());
585fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
586fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 0);
587fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(false);
588fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
589fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
590fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
591fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
592fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
593fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
594fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
595fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionEnd());
596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(blank, BufferType.SPANNABLE);
598fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(true);
599fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
600fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
601fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
602fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
603fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
604fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
606fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(blank.length(), mTextView.getSelectionEnd());
607fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
608fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 0);
609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(false);
610fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
611fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
612fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
613fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
614fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
615fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
616fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
617fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionEnd());
618fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
619fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
620fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetPaint() {
621fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
622fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextPaint tp = mTextView.getPaint();
623fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(tp);
624fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
625fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaintFlags(), tp.getFlags());
626fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
627fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
628fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
629fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessLinksClickable() {
630fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext);
631fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
632fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
633fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
634fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
635fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.linksClickable_true);
636fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
637fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
638fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.linksClickable_false);
639fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getLinksClickable());
640fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
641fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinksClickable(false);
642fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getLinksClickable());
643fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
644fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinksClickable(true);
645fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
646fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
647fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getMovementMethod());
648fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
649fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text = new SpannableString("name: Jack. tel: +41 44 800 8999");
650fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
651fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS);
652fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
653fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
654fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Movement method will be automatically set to LinkMovementMethod
655fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getMovementMethod() instanceof LinkMovementMethod);
656fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
657fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
658fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessHintTextColor() {
659fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
660fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using int values
661fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
662fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.GREEN);
663fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GREEN, mTextView.getCurrentHintTextColor());
664fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getHintTextColors());
665fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
666fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.BLUE);
667fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.BLUE), mTextView.getHintTextColors());
668fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLUE, mTextView.getCurrentHintTextColor());
669fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
670fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.RED);
671fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.RED), mTextView.getHintTextColors());
672fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.RED, mTextView.getCurrentHintTextColor());
673fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
674fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using ColorStateList
675fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
676fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
677fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_focused}, new int[0] },
678fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
679fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(colors);
680fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getHintTextColors());
681fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentHintTextColor());
682fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
683fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // exceptional
684fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(null);
685fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getHintTextColors());
686fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCurrentTextColor(), mTextView.getCurrentHintTextColor());
687fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
688fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
689fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessLinkTextColor() {
690fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
691fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
692fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.GRAY);
693fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GRAY), mTextView.getLinkTextColors());
694fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GRAY, mTextView.getPaint().linkColor);
695fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
696fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.YELLOW);
697fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.YELLOW), mTextView.getLinkTextColors());
698fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.YELLOW, mTextView.getPaint().linkColor);
699fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
700fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.WHITE);
701fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.WHITE), mTextView.getLinkTextColors());
702fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.WHITE, mTextView.getPaint().linkColor);
703fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
704fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
705fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_expanded}, new int[0] },
706fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
707fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(colors);
708fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getLinkTextColors());
709fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getPaint().linkColor);
710fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
711fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(null);
712fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getLinkTextColors());
713fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getPaint().linkColor);
714fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
715fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
716fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessPaintFlags() {
717fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
71853959f211c113aa7b2a2ebaf80e10b79ddcccef1Victoria Lease        assertEquals(Paint.DEV_KERN_TEXT_FLAG | Paint.EMBEDDED_BITMAP_TEXT_FLAG
71953959f211c113aa7b2a2ebaf80e10b79ddcccef1Victoria Lease                | Paint.ANTI_ALIAS_FLAG, mTextView.getPaintFlags());
720fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
721fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG);
722fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG,
723fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getPaintFlags());
724fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
725fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG);
726fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG,
727fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getPaintFlags());
728fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
729fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
7316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testHeight() {
732fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
7336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalHeight = mTextView.getHeight();
734fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setMaxHeight
7366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int newHeight = originalHeight + 1;
7376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
738fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
740fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
7426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
7436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
7446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
745fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
7476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
748fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getHeight());
7496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
750fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = Integer.MAX_VALUE;
7526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
753fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
755fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setMinHeight
7576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight + 1;
7586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
7596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
7606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
761fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
7636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
764fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
766fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
7686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
769fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
771fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // reset min and max height
773fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinHeight(0);
774fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxHeight(Integer.MAX_VALUE);
775fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setHeight
7776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight + 1;
7786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
7796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
7806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
7816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
7826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
7836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
7846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
7856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
7866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
7876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
7886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
7896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
7906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
791fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getHeight());
7926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
7936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
794fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
795fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHeight(originalHeight);
796fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(originalHeight, mTextView.getMaxHeight());
7986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(originalHeight, mTextView.getMinHeight());
799fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // setting max/min lines should cause getMaxHeight/getMinHeight to return -1
8016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxLines(2);
8026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting maxLines should return -1 fir maxHeight",
8036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                -1, mTextView.getMaxHeight());
8046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinLines(1);
8066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting minLines should return -1 for minHeight",
8076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                -1, mTextView.getMinHeight());
8086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
8096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
8116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testWidth() {
8126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = findTextView(R.id.textview_text);
8136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int originalWidth = mTextView.getWidth();
8146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int newWidth = mTextView.getWidth() / 8;
8166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
8176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
8196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
820fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
821fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Min Width
8226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth + 1;
8236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinWidth(newWidth);
824fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
827fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth - 1;
829fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinWidth(originalWidth - 1);
8309c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu        assertEquals(2, mTextView.getLineCount());
8316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
833fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
834fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Width
8356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth + 1;
8366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
837fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
8406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
841fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth - 1;
8436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
8449c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu        assertEquals(2, mTextView.getLineCount());
8456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
8476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
8486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // setting ems should cause getMaxWidth/getMinWidth to return -1
8506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setEms(1);
8516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting ems should return -1 for maxWidth", -1, mTextView.getMaxWidth());
8526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting ems should return -1 for maxWidth", -1, mTextView.getMinWidth());
853fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
854fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
856fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetMinEms() {
857fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
858fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8599c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu
8606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
8616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
862fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
863fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinEms(originalEms + 1);
864fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals((originalEms + 1) * mTextView.getLineHeight(), mTextView.getWidth());
86598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
86698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMinEms());
867fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
868fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinEms(originalEms - 1);
869fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalWidth, mTextView.getWidth());
87098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
87198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMinEms());
8726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinWidth(1);
8746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mTextView.getMinEms());
875fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
876fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
878fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetMaxEms() {
879fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
880fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
8836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
884fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
885fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxEms(originalEms + 1);
886fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
887fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalWidth, mTextView.getWidth());
88898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
88998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMaxEms());
890fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
891fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxEms(originalEms - 1);
892fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(1 < mTextView.getLineCount());
8936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms - 1) * mTextView.getLineHeight(), mTextView.getWidth());
89498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
89598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMaxEms());
8966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxWidth(originalWidth);
8986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mTextView.getMaxEms());
899fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
900fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
9016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
902fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetEms() {
903fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
904fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("check height", 1, mTextView.getLineCount());
9056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
9066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
907fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
908fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setEms(originalEms + 1);
909fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
9106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms + 1) * mTextView.getLineHeight(), mTextView.getWidth());
91198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
91298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
91398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMinEms());
91498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMaxEms());
915fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
916fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setEms(originalEms - 1);
917fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((1 < mTextView.getLineCount()));
9186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms - 1) * mTextView.getLineHeight(), mTextView.getWidth());
91998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
92098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
92198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMinEms());
92298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMaxEms());
923fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
924fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
925fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetLineSpacing() {
926fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
927fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLineHeight = mTextView.getLineHeight();
928fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
929fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
930fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float add = 1.2f;
931fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float mult = 1.4f;
932fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
93392e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
934fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = 0.0f;
935fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = 1.4f;
936fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
93792e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
938fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
939fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // abnormal
940fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = -1.2f;
941fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = 1.4f;
942fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
94392e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
944fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = -1.2f;
945fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = -1.4f;
946fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
94792e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
948fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = 1.2f;
949fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = 0.0f;
950fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
95192e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
952fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
953fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // edge
954fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = Float.MIN_VALUE;
955fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = Float.MIN_VALUE;
956fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
957ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
958ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette
959ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        // edge case where the behavior of Math.round() deviates from
960ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        // FastMath.round(), requiring us to use an explicit 0 value
961fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = Float.MAX_VALUE;
962fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = Float.MAX_VALUE;
963fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
964ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        assertEquals(0, mTextView.getLineHeight());
965fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
966fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
967ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien    public void testSetElegantLineHeight() {
968ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mTextView = findTextView(R.id.textview_text);
969ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getPaint().isElegantTextHeight());
970ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mActivity.runOnUiThread(new Runnable() {
971ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            public void run() {
972ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setWidth(mTextView.getWidth() / 3);
973ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setPadding(1, 2, 3, 4);
974ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setGravity(Gravity.BOTTOM);
975ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            }
976ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        });
977ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
978ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
979ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        int oldHeight = mTextView.getHeight();
980ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mActivity.runOnUiThread(new Runnable() {
981ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            public void run() {
982ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setElegantTextHeight(true);
983ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            }
984ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        });
985ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
986ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
987ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getPaint().isElegantTextHeight());
988ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getHeight() > oldHeight);
989ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
990ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mActivity.runOnUiThread(new Runnable() {
991ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            public void run() {
992ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setElegantTextHeight(false);
993ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            }
994ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        });
995ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
996ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getPaint().isElegantTextHeight());
997ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getHeight() == oldHeight);
998ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien    }
999ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
1000fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testInstanceState() {
1001fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
1002fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1003fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessFreezesText() throws Throwable {
1005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(R.layout.textview_hint_linksclickable_freezestext);
1006fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1007fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
1008fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1009fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1010fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_true);
1011fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getFreezesText());
1012fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1013fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
1014fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1016fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setFreezesText(false);
1017fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1018fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1019fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text = "Hello, TextView.";
1020fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
1021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
1022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text);
1023fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
1024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1025fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
1026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final URLSpan urlSpan = new URLSpan("ctstest://TextView/test");
102872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // TODO: How to simulate the TextView in frozen icicles.
1029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Instrumentation instrumentation = getInstrumentation();
1030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ActivityMonitor am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
1031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                null, false);
1032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
1034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
1035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Uri uri = Uri.parse(urlSpan.getURL());
1036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
1037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mActivity.startActivity(intent);
1038fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
1039fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Activity newActivity = am.waitForActivityWithTimeout(TIMEOUT);
1042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(newActivity);
1043fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        newActivity.finish();
104472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        instrumentation.removeMonitor(am);
1045fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text of TextView is removed.
1046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
104772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
104872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(text.toString(), mTextView.getText().toString());
1049fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1050fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setFreezesText(true);
1051fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getFreezesText());
1052fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1053fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
1054fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
1055fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text);
1056fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
1057fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1058fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
105972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // TODO: How to simulate the TextView in frozen icicles.
1060fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
1061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                null, false);
1062fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1063fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
1064fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
1065fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Uri uri = Uri.parse(urlSpan.getURL());
1066fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
1067fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mActivity.startActivity(intent);
1068fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
1069fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1070fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
107107b9d3406e116f2f6b92932925783eed79503de0Mist Liao        Activity oldActivity = newActivity;
107207b9d3406e116f2f6b92932925783eed79503de0Mist Liao        while (true) {
107307b9d3406e116f2f6b92932925783eed79503de0Mist Liao            newActivity = am.waitForActivityWithTimeout(TIMEOUT);
107407b9d3406e116f2f6b92932925783eed79503de0Mist Liao            assertNotNull(newActivity);
107507b9d3406e116f2f6b92932925783eed79503de0Mist Liao            if (newActivity != oldActivity) {
107607b9d3406e116f2f6b92932925783eed79503de0Mist Liao                break;
107707b9d3406e116f2f6b92932925783eed79503de0Mist Liao            }
107807b9d3406e116f2f6b92932925783eed79503de0Mist Liao        }
1079fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        newActivity.finish();
108072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        instrumentation.removeMonitor(am);
1081fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text of TextView is still there.
1082fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
1083fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text.toString(), mTextView.getText().toString());
1084fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1085fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1086fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetEditableFactory() {
1087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "sample";
1089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
109098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final Editable.Factory mockEditableFactory = spy(new Editable.Factory());
109198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        doCallRealMethod().when(mockEditableFactory).newEditable(any(CharSequence.class));
109298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setEditableFactory(mockEditableFactory);
109398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov
1094fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text);
109598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1096fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
109798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1098fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
109998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1100fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
110198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1102fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
110398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1104fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
110598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1106fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
110798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, times(1)).newEditable(text);
1108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1109fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setKeyListener(DigitsKeyListener.getInstance());
111098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1111fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
111298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, times(1)).newEditable(text);
1113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1114fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setEditableFactory(null);
1116fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("The factory can not set to null!");
1117fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
1118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1119fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetSpannableFactory() {
1122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1123fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "sample";
1124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
112598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final Spannable.Factory mockSpannableFactory = spy(new Spannable.Factory());
112698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        doCallRealMethod().when(mockSpannableFactory).newSpannable(any(CharSequence.class));
112798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setSpannableFactory(mockSpannableFactory);
112898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov
1129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text);
113098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1131fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
113298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
113498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1135fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
113698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
113898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1139fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
114098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
114298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, times(1)).newSpannable(text);
1143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setMovementMethod(LinkMovementMethod.getInstance());
114598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1146fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
114798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, times(1)).newSpannable(text);
1148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setSpannableFactory(null);
1151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("The factory can not set to null!");
1152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
1153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1155fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1156fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testTextChangedListener() {
1157fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextWatcher watcher0 = new MockTextWatcher();
1159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextWatcher watcher1 = new MockTextWatcher();
1160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.addTextChangedListener(watcher0);
1162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.addTextChangedListener(watcher1);
1163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("Changed");
1167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1176fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // BeforeTextChanged and OnTextChanged are called though the strings are same
1177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("Changed");
1178fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1179fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1183fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1185fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // BeforeTextChanged and OnTextChanged are called twice (The text is not
1188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Editable, so in Append() it calls setText() first)
1189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("and appended");
1190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1194fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1195fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Methods are not called if the string does not change
1200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("");
1201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledBeforeTextChanged());
1202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledOnTextChanged());
1203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledAfterTextChanged());
1204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledBeforeTextChanged());
1205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledOnTextChanged());
1206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledAfterTextChanged());
1207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1209fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1210fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.removeTextChangedListener(watcher1);
1211fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(null);
1212fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledBeforeTextChanged());
1216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledOnTextChanged());
1217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledAfterTextChanged());
1218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1220fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetTextKeepState1() {
1221fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1222fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String longString = "very long content";
1224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String shortString = "short";
1225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is inside the short string
1227fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString, BufferType.SPANNABLE);
1228fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 3);
1229fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1230fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionStart());
1232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionEnd());
1233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is outside the short string
1235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1236fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), shortString.length() + 1);
1237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is inside the short string
1243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 1, 4);
1245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getSelectionStart());
1248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(4, mTextView.getSelectionEnd());
1249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which ends outside the short string
1251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 2, shortString.length() + 1);
1253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getSelectionStart());
1256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is outside the short string
1259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(),
1261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                shortString.length() + 1, shortString.length() + 3);
1262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetEditableText() {
1270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "Hello";
1273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(text, BufferType.EDITABLE);
1274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getText().toString());
1275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
1276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getEditableText().toString());
1277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(text, BufferType.SPANNABLE);
1279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getText().toString());
1280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
1281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(tv.getEditableText());
1282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1283fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null, BufferType.EDITABLE);
1284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
1286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getEditableText().toString());
1287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null, BufferType.SPANNABLE);
1289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
1291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(tv.getEditableText());
1292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText2() {
1296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String string = "This is a test for setting text content by char array";
1297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        char[] input = string.toCharArray();
1298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 0, input.length);
1301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(string, tv.getText().toString());
1302fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 0, 5);
1304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(string.substring(0, 5), tv.getText().toString());
1305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, -1, input.length);
1308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the start position is negative!");
1309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, 0, -1);
1314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the length is negative!");
1315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, 1, input.length);
1320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the end position is out of index!");
1321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 1, 0);
1325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText1() {
1330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
1331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String longString = "very long content";
1333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String shortString = "short";
1334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is inside the short string
1336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString, BufferType.SPANNABLE);
1337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 3);
1338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionStart());
1343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionEnd());
1344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1347fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is outside the short string
1354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), longString.length());
1356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1371fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is inside the short string
1372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1373fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 1, shortString.length() - 1);
1374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getSelectionStart());
1379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length() - 1, mTextView.getSelectionEnd());
1380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which ends outside the short string
1390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 2, longString.length());
1392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getSelectionStart());
1397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is outside the short string
1408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(),
1410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                shortString.length() + 1, shortString.length() + 3);
1411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText3() {
1429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int resId = R.string.text_view_hint;
1432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String result = mActivity.getResources().getString(resId);
1433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId);
1435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
1436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(-1);
1439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception with illegal id");
1440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
1441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
144498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir    @MediumTest
144598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir    public void testSetText_updatesHeightAfterRemovingImageSpan() {
144698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // Height calculation had problems when TextView had width: match_parent
144798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int textViewWidth = ViewGroup.LayoutParams.MATCH_PARENT;
144898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final Spannable text = new SpannableString("some text");
144998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int spanHeight = 100;
145098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
145198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // prepare TextView, width: MATCH_PARENT
145298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        TextView textView = new TextView(getActivity());
145398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setSingleLine(true);
145498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 2);
145598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setPadding(0, 0, 0, 0);
145698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setIncludeFontPadding(false);
145798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setText(text);
145898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
145998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(textViewWidth,
146098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
146198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        layout.addView(textView, layoutParams);
146298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        layout.setLayoutParams(layoutParams);
146398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
146498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            @Override
146598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            public void run() {
146698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                getActivity().setContentView(layout);
146798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            }
146898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        });
146998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        getInstrumentation().waitForIdleSync();
147098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
147198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // measure height of text with no span
147298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int heightWithoutSpan = textView.getHeight();
147398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertTrue("Text height should be smaller than span height",
147498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithoutSpan < spanHeight);
147598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
147698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // add ImageSpan to text
147798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        Drawable drawable = mInstrumentation.getContext().getDrawable(R.drawable.scenery);
147898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        drawable.setBounds(0, 0, spanHeight, spanHeight);
147998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        ImageSpan span = new ImageSpan(drawable);
148098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        text.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
148198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
148298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            @Override
148398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            public void run() {
148498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                textView.setText(text);
148598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            }
148698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        });
148798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mInstrumentation.waitForIdleSync();
148898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
148998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // measure height with span
149098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int heightWithSpan = textView.getHeight();
149198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertTrue("Text height should be greater or equal than span height",
149298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithSpan >= spanHeight);
149398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
149498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // remove the span
149598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        text.removeSpan(span);
149698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
149798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            @Override
149898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            public void run() {
149998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                textView.setText(text);
150098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            }
150198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        });
150298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mInstrumentation.waitForIdleSync();
150398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
150498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int heightAfterRemoveSpan = textView.getHeight();
150598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertEquals("Text height should be same after removing the span",
150698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithoutSpan, heightAfterRemoveSpan);
150798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir    }
150898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
1509af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi    public void testRemoveSelectionWithSelectionHandles() {
1510af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        initTextViewForTyping();
1511af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1512354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.isTextSelectable());
1513354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> {
1514354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mTextView.setTextIsSelectable(true);
1515354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mTextView.setText("abcd", BufferType.EDITABLE);
1516af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        });
1517af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        mInstrumentation.waitForIdleSync();
1518354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.isTextSelectable());
1519af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1520af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // Long click on the text selects all text and shows selection handlers. The view has an
1521af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // attribute layout_width="wrap_content", so clicked location (the center of the view)
1522af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // should be on the text.
1523af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        TouchUtils.longClickView(this, mTextView);
1524af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1525354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> Selection.removeSelection((Spannable) mTextView.getText()));
1526af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1527af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // Make sure that a crash doesn't happen with {@link Selection#removeSelection}.
1528af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        mInstrumentation.waitForIdleSync();
1529354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
1530354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", mTextView.getText()));
1531af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi    }
1532af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1533c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_insert() {
153428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
15355b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15365b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Type some text.
15375bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
15385b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
15395b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
154028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Precondition: The cursor is at the end of the text.
154128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(3, mTextView.getSelectionStart());
15425b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15435b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undo removes the typed string in one step.
15445b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
15455b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
154628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(0, mTextView.getSelectionStart());
15475b51f77b99861d48fec1c327252416f726b3b01aJames Cook
154828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Redo restores the text and cursor position.
15495b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.redo);
15505b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("abc", mTextView.getText().toString());
155128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(3, mTextView.getSelectionStart());
15525b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15535b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undoing the redo clears the text again.
15545b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
15555b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
15565b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15575b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undo when the undo stack is empty does nothing.
15585b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
15595b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
15605b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
15615b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
15625b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
156328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
15645b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1565c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_delete() {
156628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
15675b51f77b99861d48fec1c327252416f726b3b01aJames Cook
156828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        // Simulate deleting text and undoing it.
15695bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "xyz");
15705bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL,
15715bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir                KeyEvent.KEYCODE_DEL);
15725b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
15735b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
157428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Precondition: The text was actually deleted.
157528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("", mTextView.getText().toString());
157628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(0, mTextView.getSelectionStart());
157728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
157828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Undo restores the typed string and cursor position in one step.
15795b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
158028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("xyz", mTextView.getText().toString());
158128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(3, mTextView.getSelectionStart());
15825b51f77b99861d48fec1c327252416f726b3b01aJames Cook
158328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Redo removes the text in one step.
158428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.onTextContextMenuItem(android.R.id.redo);
158528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("", mTextView.getText().toString());
158628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(0, mTextView.getSelectionStart());
15875b51f77b99861d48fec1c327252416f726b3b01aJames Cook
158828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Undoing the redo restores the text again.
158928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
159028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("xyz", mTextView.getText().toString());
159128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(3, mTextView.getSelectionStart());
159228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
159328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Undoing again undoes the original typing.
15945b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
15955b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
159628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(0, mTextView.getSelectionStart());
15975b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
15985b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
15995b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
160028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
16015b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1602c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    // Initialize the text view for simulated IME typing. Must be called on UI thread.
1603c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    private InputConnection initTextViewForSimulatedIme() {
1604c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView = findTextView(R.id.textview_text);
1605c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
1606c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setText("", BufferType.EDITABLE);
1607c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        return mTextView.onCreateInputConnection(new EditorInfo());
1608c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1609c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1610c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    // Simulates IME composing text behavior.
1611c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    private void setComposingTextInBatch(InputConnection input, CharSequence text) {
1612c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1613c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.setComposingText(text, 1);  // Leave cursor at end.
1614c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1615c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1616c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1617c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1618c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeInsertLatin() {
1619c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1620c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1621c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Simulate IME text entry behavior. The Latin IME enters text by replacing partial words,
1622c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // such as "c" -> "ca" -> "cat" -> "cat ".
1623c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "c");
1624c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "ca");
1625c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1626c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The completion and space are added in the same batch.
1627c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1628c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText("cat", 1);
1629c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText(" ", 1);
1630c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1631c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1632c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The repeated replacements undo in a single step.
1633c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1634c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("", mTextView.getText().toString());
1635c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1636c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1637c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1638c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeInsertJapanese() {
1639c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1640c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1641c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The Japanese IME does repeated replacements of Latin characters to hiragana to kanji.
1642c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String HA = "\u306F";  // HIRAGANA LETTER HA
1643c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String NA = "\u306A";  // HIRAGANA LETTER NA
1644c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "h");
1645c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA);
1646c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + "n");
1647c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + NA);
1648c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1649c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The result may be a surrogate pair. The composition ends in the same batch.
1650c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1651c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText("\uD83C\uDF37", 1);  // U+1F337 TULIP
1652c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.setComposingText("", 1);
1653c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1654c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1655c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The repeated replacements are a single undo step.
1656c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1657c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("", mTextView.getText().toString());
1658c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1659c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1660c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1661c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeCancel() {
1662c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1663c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setText("flower");
1664c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1665c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Start typing a composition.
1666c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String HA = "\u306F";  // HIRAGANA LETTER HA
1667c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "h");
1668c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA);
1669c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + "n");
1670c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1671c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Cancel the composition.
1672c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "");
1673c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1674c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Undo and redo do nothing.
1675c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1676c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1677c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.redo);
1678c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1679c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1680c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1681c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1682c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeEmptyBatch() {
1683c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1684c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setText("flower");
1685c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1686c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Send an empty batch edit. This happens if the IME is hidden and shown.
1687c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1688c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1689c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1690c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Undo and redo do nothing.
1691c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1692c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1693c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.redo);
1694c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1695c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1696c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1697c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_setText() {
1698277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
169928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1700c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Create two undo operations, an insert and a delete.
17015bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "xyz");
17025bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL,
17035bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir                KeyEvent.KEYCODE_DEL);
1704277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1705277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1706c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook                // Calling setText() clears both undo operations, so undo doesn't happen.
1707277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.setText("Hello", BufferType.EDITABLE);
1708277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1709277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("Hello", mTextView.getText().toString());
171028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1711277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Clearing text programmatically does not undo either.
1712277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.setText("", BufferType.EDITABLE);
1713277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1714277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("", mTextView.getText().toString());
1715277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1716277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1717277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1718277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
171928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1720c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testRedo_setText() {
1721277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
1722277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1723277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text. This creates an undo entry.
17245bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
1725277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1726277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1727277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Undo the typing to create a redo entry.
1728277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1729277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1730277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Calling setText() clears the redo stack, so redo doesn't happen.
1731277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.setText("Hello", BufferType.EDITABLE);
1732277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.redo);
1733277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("Hello", mTextView.getText().toString());
1734277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1735277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1736277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1737277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1738277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1739c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_directAppend() {
1740277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
174128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1742277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
17435bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
1744277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1745277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1746277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Programmatically append some text.
1747277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.append("def");
1748277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("abcdef", mTextView.getText().toString());
1749277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1750277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Undo removes the append as a separate step.
1751277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1752277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("abc", mTextView.getText().toString());
1753277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1754277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Another undo removes the original typing.
1755277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1756277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("", mTextView.getText().toString());
1757277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1758277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1759277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1760277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1761277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1762c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_directInsert() {
1763277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
1764277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1765277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
17665bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
1767277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1768277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1769277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Directly modify the underlying Editable to insert some text.
1770277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // NOTE: This is a violation of the API of getText() which specifies that the
1771277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // returned object should not be modified. However, some apps do this anyway and
1772277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // the framework needs to handle it.
1773277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                Editable text = (Editable) mTextView.getText();
1774277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                text.insert(0, "def");
1775277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("defabc", mTextView.getText().toString());
1776277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1777277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Undo removes the insert as a separate step.
1778277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1779277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("abc", mTextView.getText().toString());
1780277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1781277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Another undo removes the original typing.
1782277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1783277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("", mTextView.getText().toString());
1784277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1785277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1786277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1787277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1788277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1789c530472a02205f0b7d87f9f06140c56ca0849816James Cook    public void testUndo_noCursor() {
1790c530472a02205f0b7d87f9f06140c56ca0849816James Cook        initTextViewForTyping();
1791c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1792c530472a02205f0b7d87f9f06140c56ca0849816James Cook        mActivity.runOnUiThread(new Runnable() {
1793c530472a02205f0b7d87f9f06140c56ca0849816James Cook            public void run() {
1794c530472a02205f0b7d87f9f06140c56ca0849816James Cook                // Append some text to create an undo operation. There is no cursor present.
1795c530472a02205f0b7d87f9f06140c56ca0849816James Cook                mTextView.append("cat");
1796c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1797c530472a02205f0b7d87f9f06140c56ca0849816James Cook                // Place the cursor at the end of the text so the undo will have to change it.
1798c530472a02205f0b7d87f9f06140c56ca0849816James Cook                Selection.setSelection((Spannable) mTextView.getText(), 3);
1799c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1800c530472a02205f0b7d87f9f06140c56ca0849816James Cook                // Undo the append. This should not crash, despite not having a valid cursor
1801c530472a02205f0b7d87f9f06140c56ca0849816James Cook                // position in the undo operation.
1802c530472a02205f0b7d87f9f06140c56ca0849816James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1803c530472a02205f0b7d87f9f06140c56ca0849816James Cook            }
1804c530472a02205f0b7d87f9f06140c56ca0849816James Cook        });
1805c530472a02205f0b7d87f9f06140c56ca0849816James Cook        mInstrumentation.waitForIdleSync();
1806c530472a02205f0b7d87f9f06140c56ca0849816James Cook    }
1807c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1808c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_textWatcher() {
1809277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
1810277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1811277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Add a TextWatcher that converts the text to spaces on each change.
1812277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher());
1813277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1814277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
18155bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
1816277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1817277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1818277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // TextWatcher altered the text.
1819277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("   ", mTextView.getText().toString());
1820277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1821277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Undo reverses both changes in one step.
1822277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1823277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("", mTextView.getText().toString());
1824277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1825277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1826277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1827c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook    }
1828c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1829c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook    public void testUndo_textWatcherDirectAppend() {
1830c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        initTextViewForTyping();
1831c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1832c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        // Add a TextWatcher that converts the text to spaces on each change.
1833c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher());
1834c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1835c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        mActivity.runOnUiThread(new Runnable() {
1836c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook            public void run() {
1837c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                // Programmatically append some text. The TextWatcher changes it to spaces.
1838c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                mTextView.append("abc");
1839c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                assertEquals("   ", mTextView.getText().toString());
1840c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1841c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                // Undo reverses both changes in one step.
1842c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1843c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                assertEquals("", mTextView.getText().toString());
1844c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook            }
1845c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        });
1846c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        mInstrumentation.waitForIdleSync();
184728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
184828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1849c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_shortcuts() {
185028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
185128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
185228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        // Type some text.
18535bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
18545b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
18555b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
18565b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Pressing Control-Z triggers undo.
18575b51f77b99861d48fec1c327252416f726b3b01aJames Cook                KeyEvent control = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z, 0,
18585b51f77b99861d48fec1c327252416f726b3b01aJames Cook                        KeyEvent.META_CTRL_LEFT_ON);
1859277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, control));
18605b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
18615b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18625b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Pressing Control-Shift-Z triggers redo.
18635b51f77b99861d48fec1c327252416f726b3b01aJames Cook                KeyEvent controlShift = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z,
18645b51f77b99861d48fec1c327252416f726b3b01aJames Cook                        0, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_SHIFT_LEFT_ON);
1865277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, controlShift));
186628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("abc", mTextView.getText().toString());
18675b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
18685b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
18695b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
18705b51f77b99861d48fec1c327252416f726b3b01aJames Cook    }
18715b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1872c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_saveInstanceState() {
187328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
18745b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18755b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Type some text to create an undo operation.
18765bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
18775b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
18785b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
18795b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Parcel and unparcel the TextView.
18805b51f77b99861d48fec1c327252416f726b3b01aJames Cook                Parcelable state = mTextView.onSaveInstanceState();
18815b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onRestoreInstanceState(state);
18825b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
18835b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
18845b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
18855b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18865b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Delete a character to create a new undo operation.
18875bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL);
18885b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
18895b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
18905b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("ab", mTextView.getText().toString());
18915b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18925b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undo the delete.
18935b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
18945b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("abc", mTextView.getText().toString());
18955b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18965b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undo the typing, which verifies that the original undo operation was parceled
18975b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // correctly.
18985b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
18995b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
19005f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
19015f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // Parcel and unparcel the undo stack (which is empty but has been used and may
19025f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // contain other state).
19035f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                Parcelable state = mTextView.onSaveInstanceState();
19045f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onRestoreInstanceState(state);
19055f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook            }
19065f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        });
19075f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mInstrumentation.waitForIdleSync();
19085f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook    }
19095f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
1910c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_saveInstanceStateEmpty() {
19115f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        initTextViewForTyping();
19125f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
19135f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        // Type and delete to create two new undo operations.
19145bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "a");
19155bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL);
19165f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mActivity.runOnUiThread(new Runnable() {
19175f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook            public void run() {
19185f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // Empty the undo stack then parcel and unparcel the TextView. While the undo
19195f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // stack contains no operations it may contain other state.
19205f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19215f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19225f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                Parcelable state = mTextView.onSaveInstanceState();
19235f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onRestoreInstanceState(state);
19245f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook            }
19255f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        });
19265f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mInstrumentation.waitForIdleSync();
19275f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
19285f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        // Create two more undo operations.
19295bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "b");
19305bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL);
19315f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mActivity.runOnUiThread(new Runnable() {
19325f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook            public void run() {
19335f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // Verify undo still works.
19345f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19355f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                assertEquals("b", mTextView.getText().toString());
19365f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19375f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                assertEquals("", mTextView.getText().toString());
19385b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
19395b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
19405b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
19415b51f77b99861d48fec1c327252416f726b3b01aJames Cook    }
19425b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1943b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCopyAndPaste() {
1944b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
1945b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
1946b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            public void run() {
1947b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setText("abcd", BufferType.EDITABLE);
1948b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setSelected(true);
1949b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
1950b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Copy "bc".
1951b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
1952b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.copy);
1953b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
1954b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Paste "bc" between "b" and "c".
1955b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 2, 2);
1956b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
1957b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("abbccd", mTextView.getText().toString());
1958b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
1959b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Select entire text and paste "bc".
1960b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
1961b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
1962b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("bc", mTextView.getText().toString());
1963b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            }
1964b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        });
1965b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
1966b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
1967b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
196849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    public void testCopyAndPaste_byKey() {
196949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        initTextViewForTyping();
197049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
197149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Type "abc".
197203818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
197349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
197449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
197549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Select "bc"
197649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
197749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
197849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
197949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
198049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Copy "bc"
198103818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_COPY);
198249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
198349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
198449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
198549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Set cursor between 'b' and 'c'.
198649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 2, 2);
198749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
198849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
198949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
199049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Paste "bc"
199103818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_PASTE);
199249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        assertEquals("abbcc", mTextView.getText().toString());
199349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
199449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
199549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
199649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
199749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                KeyEvent copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
199849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.KEYCODE_COPY, 0, KeyEvent.META_SHIFT_LEFT_ON);
199949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Shift + copy doesn't perform copy.
200049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
200149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
200249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
200349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bcabbcc", mTextView.getText().toString());
200449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
200549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
200649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0,
200749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.META_CTRL_LEFT_ON);
200849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Control + copy doesn't perform copy.
200949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
201049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
201149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
201249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bcbcabbcc", mTextView.getText().toString());
201349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
201449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
201549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0,
201649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON);
201749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Control + Shift + copy doesn't perform copy.
201849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
201949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
202049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
202149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bcbcbcabbcc", mTextView.getText().toString());
202249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
202349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
20248e9fc4a5b2274a1279261f1a36c5396b9884042dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
202549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    }
202649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
2027b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCutAndPaste() {
2028b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
2029b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
2030b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            public void run() {
2031b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setText("abcd", BufferType.EDITABLE);
2032b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setSelected(true);
2033b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2034b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Cut "bc".
2035b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
2036b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.cut);
2037b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("ad", mTextView.getText().toString());
2038b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2039b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Cut "ad".
2040b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 2);
2041b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.cut);
2042b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("", mTextView.getText().toString());
2043b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2044b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Paste "ad".
2045b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
2046b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("ad", mTextView.getText().toString());
2047b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            }
2048b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        });
2049b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
2050b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2051b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
205249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    public void testCutAndPaste_byKey() {
205349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        initTextViewForTyping();
205449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
205549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Type "abc".
205603818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
205749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
205849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
205949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Select "bc"
206049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
206149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
206249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
206349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
206449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Cut "bc"
206503818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_CUT);
206649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
206749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
206849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
206949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("a", mTextView.getText().toString());
207049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Move cursor to the head
207149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
207249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
207349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
207449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
207549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Paste "bc"
207603818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_PASTE);
207749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        assertEquals("bca", mTextView.getText().toString());
207849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
207949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
208049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
208149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
208249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                KeyEvent cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
208349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.KEYCODE_CUT, 0, KeyEvent.META_SHIFT_LEFT_ON);
208449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Shift + cut doesn't perform cut.
208549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
208649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bca", mTextView.getText().toString());
208749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
208849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0,
208949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.META_CTRL_LEFT_ON);
209049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Control + cut doesn't perform cut.
209149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
209249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bca", mTextView.getText().toString());
209349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
209449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0,
209549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON);
209649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Control + Shift + cut doesn't perform cut.
209749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
209849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bca", mTextView.getText().toString());
209949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
210049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
210149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    }
210249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
2103b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    private static boolean hasSpansAtMiddleOfText(final TextView textView, final Class<?> type) {
2104b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        final Spannable spannable = (Spannable)textView.getText();
2105b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        final int at = spannable.length() / 2;
2106b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        return spannable.getSpans(at, at, type).length > 0;
2107b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2108b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2109b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCutAndPaste_withAndWithoutStyle() {
2110b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
2111b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
2112b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            public void run() {
2113b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setText("example", BufferType.EDITABLE);
2114b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setSelected(true);
2115b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2116b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Set URLSpan.
2117b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                final Spannable spannable = (Spannable) mTextView.getText();
2118b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                spannable.setSpan(new URLSpan("http://example.com"), 0, spannable.length(), 0);
2119b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
2120b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2121b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Cut entire text.
2122b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
2123b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.cut);
2124b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("", mTextView.getText().toString());
2125b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2126b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Paste without style.
2127b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.pasteAsPlainText);
2128b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("example", mTextView.getText().toString());
2129b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Check that the text doesn't have URLSpan.
2130b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertFalse(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
2131b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2132b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Paste with style.
2133b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
2134b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
2135b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("example", mTextView.getText().toString());
2136b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Check that the text has URLSpan.
2137b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
2138b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            }
2139b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        });
2140b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
2141b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2142b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
21444ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    public void testSaveInstanceState() {
2145baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // should save text when freezesText=true
21464ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        TextView originalTextView = new TextView(mActivity);
21474ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        final String text = "This is a string";
21484ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        originalTextView.setText(text);
21494ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        originalTextView.setFreezesText(true);  // needed to actually save state
21504ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        Parcelable state = originalTextView.onSaveInstanceState();
21514ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
21524ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        TextView restoredTextView = new TextView(mActivity);
21534ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        restoredTextView.onRestoreInstanceState(state);
21544ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        assertEquals(text, restoredTextView.getText().toString());
21554ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    }
21564ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
21574ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    @UiThreadTest
2158baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_whenFreezesTextIsFalse() {
21594ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        final String text = "This is a string";
2160baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        { // should not save text when freezesText=false
2161baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for before saveInstanceState
2162baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView1 = new TextView(mActivity);
2163baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setFreezesText(false);
2164baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setText(text);
21654ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
2166baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for after saveInstanceState
2167baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView2 = new TextView(mActivity);
2168baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setFreezesText(false);
2169baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2170baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2171baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2172baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            assertEquals("", textView2.getText().toString());
2173baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        }
2174baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2175baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        { // should not save text even when textIsSelectable=true
2176baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for before saveInstanceState
2177baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView1 = new TextView(mActivity);
2178baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setFreezesText(false);
2179baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setTextIsSelectable(true);
2180baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setText(text);
2181baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2182baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for after saveInstanceState
2183baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView2 = new TextView(mActivity);
2184baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setFreezesText(false);
2185baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setTextIsSelectable(true);
2186baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2187baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2188baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2189baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            assertEquals("", textView2.getText().toString());
2190baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        }
2191baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2192baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2193baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2194baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2195baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_doesNotSaveSelectionWhenDoesNotExist() {
2196baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2197baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2198baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2199baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(true);
2200baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2201baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2202baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2203baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2204baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(true);
2205baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2206baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2207baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2208baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(-1, textView2.getSelectionStart());
2209baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(-1, textView2.getSelectionEnd());
2210baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2211baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2212baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2213baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2214baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_doesNotRestoreSelectionWhenTextIsAbsent() {
2215baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2216baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2217baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2218baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(false);
2219baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setTextIsSelectable(true);
2220baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2221baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
2222baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2223baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2224baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2225baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(false);
2226baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setTextIsSelectable(true);
2227baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2228baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2229baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2230baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals("", textView2.getText().toString());
2231baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        //when textIsSelectable, selection start and end are initialized to 0
2232baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(0, textView2.getSelectionStart());
2233baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(0, textView2.getSelectionEnd());
2234baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2235baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2236baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2237baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2238baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_savesSelectionWhenExists() {
2239baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2240baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2241baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2242baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(true);
2243baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setTextIsSelectable(true);
2244baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2245baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
2246baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2247baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2248baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2249baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(true);
2250baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setTextIsSelectable(true);
2251baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2252baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2253baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2254baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(textView1.getSelectionStart(), textView2.getSelectionStart());
2255baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(textView1.getSelectionEnd(), textView2.getSelectionEnd());
22564ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    }
22574ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
22584ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    @UiThreadTest
2259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText() {
2260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
2261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int resId = R.string.text_view_hint;
2263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String result = mActivity.getResources().getString(resId);
2264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId, BufferType.EDITABLE);
2266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
2267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
2268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId, BufferType.SPANNABLE);
2270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
2271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
2272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(-1, BufferType.EDITABLE);
2275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception with illegal id");
2276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
2277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessHint() {
2282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext);
2283fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
2285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getHint());
2286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_blank);
2288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", mTextView.getHint());
2289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_string);
2291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_simple_hint),
2292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint());
2293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_resid);
2295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_hint),
2296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint());
2297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHint("This is hint");
2299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("This is hint", mTextView.getHint().toString());
2300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHint(R.string.text_view_hello);
2302fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
2303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint().toString());
2304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Non-exist resid
2306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setHint(-1);
2308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if id is illegal");
2309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
2310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessError() {
2314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
231753b55f734fb3cf52df49a79cf76d410a77fbe8f5Craig Mautner        final String errorText = "Oops! There is an error";
2318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setError(null);
2322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2327a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable icon = TestUtils.getDrawable(mActivity, R.drawable.failed);
2328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setError(errorText, icon);
2331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(errorText, mTextView.getError().toString());
2335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // can not check whether the drawable is set correctly
2336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setError(null, null);
2340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2347300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.setKeyListener(DigitsKeyListener.getInstance(""));
2348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText("", BufferType.EDITABLE);
2349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setError(errorText);
2350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
2351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(errorText, mTextView.getError().toString());
2356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
235703818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "a");
2358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // a key event that will not change the TextView's text
2359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", mTextView.getText().toString());
2360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // The icon and error message will not be reset to null
236153b55f734fb3cf52df49a79cf76d410a77fbe8f5Craig Mautner        assertEquals(errorText, mTextView.getError().toString());
2362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2363300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu        mActivity.runOnUiThread(new Runnable() {
2364300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu            public void run() {
2365300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.setKeyListener(DigitsKeyListener.getInstance());
2366300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.setText("", BufferType.EDITABLE);
2367300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.setError(errorText);
2368300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.requestFocus();
2369300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu            }
2370300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu        });
2371300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu        mInstrumentation.waitForIdleSync();
2372300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu
237303818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "1");
2374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // a key event cause changes to the TextView's text
2375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("1", mTextView.getText().toString());
2376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the error message and icon will be cleared.
2377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessFilters() {
2381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final InputFilter[] expected = { new InputFilter.AllCaps(),
2382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new InputFilter.LengthFilter(2) };
2383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener
2385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                = QwertyKeyListener.getInstance(false, Capitalize.NONE);
2386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView = findTextView(R.id.textview_text);
2389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setKeyListener(qwertyKeyListener);
2390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText("", BufferType.EDITABLE);
2391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setFilters(expected);
2392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
2393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(expected, mTextView.getFilters());
2398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
239903818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "a");
2400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text is capitalized by InputFilter.AllCaps
2401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("A", mTextView.getText().toString());
240203818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "b");
2403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text is capitalized by InputFilter.AllCaps
2404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("AB", mTextView.getText().toString());
240503818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "c");
2406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 'C' could not be accepted, because there is a length filter.
2407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("AB", mTextView.getText().toString());
2408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setFilters(null);
2411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw IllegalArgumentException!");
2412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IllegalArgumentException e) {
2413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetFocusedRect() {
2417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Rect rc = new Rect();
2418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2419fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Basic
2420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX(), rc.left);
2423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY(), rc.top);
2425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2427fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Single line
2428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX(), rc.left);
2431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY(), rc.top);
2433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setSelected(true);
2438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                SpannableString text = new SpannableString(mTextView.getText());
2439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Selection.setSelection(text, 3, 13);
2440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text);
2441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
2446fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        /* Cursor coordinates from getPrimaryHorizontal() may have a fractional
2447fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * component, while the result of getFocusedRect is in int coordinates.
2448fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * It's not practical for these to match exactly, so we compare that the
2449fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * integer components match - there can be a fractional pixel
2450fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * discrepancy, which should be okay for all practical applications. */
2451fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3), rc.left);
2452fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(13), rc.right);
2453fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2454fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2455fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2456fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mActivity.runOnUiThread(new Runnable() {
2457fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            public void run() {
2458fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setSelected(true);
2459fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                SpannableString text = new SpannableString(mTextView.getText());
2460fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                Selection.setSelection(text, 13, 3);
2461fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setText(text);
2462fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            }
2463fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2464fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2465fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2466fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2467fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) - 2, rc.left);
2468fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) + 2, rc.right);
2469fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2470fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2471fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2472fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Multi lines
2473fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView = findTextView(R.id.textview_text_two_lines);
2474fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2475fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollX(), rc.left);
2476fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2477fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollY(), rc.top);
2478fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2479fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2480fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mActivity.runOnUiThread(new Runnable() {
2481fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            public void run() {
2482fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setSelected(true);
2483fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                SpannableString text = new SpannableString(mTextView.getText());
2484fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                Selection.setSelection(text, 2, 4);
2485fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setText(text);
2486fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            }
2487fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2488fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2489fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2490fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2491fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(2), rc.left);
2492fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(4), rc.right);
2493fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2494fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2495fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2496fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mActivity.runOnUiThread(new Runnable() {
2497fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            public void run() {
2498fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setSelected(true);
2499fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                SpannableString text = new SpannableString(mTextView.getText());
2500fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                Selection.setSelection(text, 2, 10); // cross the "\n" and two lines
2501fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setText(text);
2502fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            }
2503fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2504fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2505fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2506fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        Path path = new Path();
2507fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getLayout().getSelectionPath(2, 10, path);
2508fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        RectF rcf = new RectF();
2509fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        path.computeBounds(rcf, true);
2510fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2511fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(rcf.left - 1, (float) rc.left);
2512fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(rcf.right + 1, (float) rc.right);
2513fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2514fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(1), rc.bottom);
2515fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2516fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Exception
2517fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2518fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.getFocusedRect(null);
2519fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException!");
2520fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
2521fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2522fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2523fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2524fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLineCount() {
2525fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2526fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // this is an one line text with default setting.
2527fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2528fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2529fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it multi-lines
2530fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxWidth(mTextView.getWidth() / 3);
2531fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(1 < mTextView.getLineCount());
2532fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2533fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it to an one line
2534fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxWidth(Integer.MAX_VALUE);
2535fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2536fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2537fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set min lines don't effect the lines count for actual text.
2538fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(12);
2539fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2540fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2541fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2542fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the internal Layout has not been built.
2543fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getLayout());
2544fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineCount());
2545fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2546fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2547fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLineBounds() {
2548fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Rect rc = new Rect();
2549fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2550fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineBounds(0, null));
2551fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2552fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineBounds(0, rc));
2553fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.left);
2554fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.right);
2555fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.top);
2556fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.bottom);
2557fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2558fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2559fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, null));
2560fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2561fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc));
2562fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.left);
2563fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getWidth(), rc.right);
2564fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.top);
2565fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getHeight(), rc.bottom);
2566fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2567fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2568fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2569fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setPadding(1, 2, 3, 4);
2570fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.BOTTOM);
2571fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2572fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2573fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2574fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc));
2575fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getTotalPaddingLeft(), rc.left);
2576fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getWidth() - mTextView.getTotalPaddingRight(), rc.right);
2577fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getTotalPaddingTop(), rc.top);
2578fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getHeight() - mTextView.getTotalPaddingBottom(), rc.bottom);
2579fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2580fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2581fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetBaseLine() {
2582fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2583fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getBaseline());
2584fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2585fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2586fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getLayout().getLineBaseline(0), mTextView.getBaseline());
2587fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2588fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2589fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2590fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setPadding(1, 2, 3, 4);
2591fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.BOTTOM);
2592fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2593fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2594fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2595fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = mTextView.getTotalPaddingTop() + mTextView.getLayout().getLineBaseline(0);
2596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getBaseline());
2597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2598fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2599fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testPressKey() {
260028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
2601fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
260203818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "a");
2603fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("a", mTextView.getText().toString());
260403818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "b");
2605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("ab", mTextView.getText().toString());
260603818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL);
2607fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("a", mTextView.getText().toString());
2608fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2610fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetIncludeFontPadding() {
2611fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2612ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getIncludeFontPadding());
2613fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2614fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2615fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setWidth(mTextView.getWidth() / 3);
2616fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setPadding(1, 2, 3, 4);
2617fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.BOTTOM);
2618fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2619fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2620fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2621fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2622fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int oldHeight = mTextView.getHeight();
2623fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2624fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2625fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setIncludeFontPadding(false);
2626fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2627fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2628fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2629fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2630fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getHeight() < oldHeight);
2631ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getIncludeFontPadding());
2632fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2633fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2634fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testScroll() {
2635fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2636fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2637fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollX());
2638fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollY());
2639fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2640fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //don't set the Scroller, nothing changed.
2641fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.computeScroll();
2642fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollX());
2643fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollY());
2644fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2645fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //set the Scroller
2646fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Scroller s = new Scroller(mActivity);
2647fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(s);
2648fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.startScroll(0, 0, 320, 480, 0);
2649fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.abortAnimation();
2650fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.forceFinished(false);
2651fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setScroller(s);
2652fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2653fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.computeScroll();
2654fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(320, mTextView.getScrollX());
2655fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(480, mTextView.getScrollY());
2656fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2657fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2658fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testDebug() {
2659fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2660fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.debug(0);
2661fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2662fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("Hello!");
2663fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(mTextView);
2664fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.debug(1);
2665fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2666fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2667fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSelection() {
2668fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2669fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "This is the content";
2670fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
2671fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.hasSelection());
2672fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2673fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.selectAll((Spannable) mTextView.getText());
2674fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
2675fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text.length(), mTextView.getSelectionEnd());
2676fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.hasSelection());
2677fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2678fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int selectionStart = 5;
2679fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int selectionEnd = 7;
2680fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), selectionStart);
2681fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionStart());
2682fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionEnd());
2683fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.hasSelection());
2684fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2685fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
2686fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionStart());
2687fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, mTextView.getSelectionEnd());
2688fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.hasSelection());
2689fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2690fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
26916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
26926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testOnSelectionChanged_isTriggeredWhenSelectionChanges() {
2693b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        final MockTextView textView = spy(new MockTextView(mActivity));
26946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String text = "any text";
26956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText(text, BufferType.SPANNABLE);
26966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
26976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // assert that there is currently no selection
26986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.hasSelection());
26996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // select all
27016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Selection.selectAll((Spannable) textView.getText());
2702b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        // After selectAll OnSelectionChanged should have been called
2703b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(textView, times(1)).onSelectionChanged(0, text.length());
27046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
2705b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        reset(textView);
27066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // change selection
27076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Selection.setSelection((Spannable) textView.getText(), 1, 5);
2708b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(textView, times(1)).onSelectionChanged(1, 5);
27096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
2710b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        reset(textView);
27116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // clear selection
27126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Selection.removeSelection((Spannable) textView.getText());
2713b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(textView, times(1)).onSelectionChanged(-1, -1);
27146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
27156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
2716fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2717fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessEllipsize() {
2718fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_ellipsize);
2719fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2720fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_default);
2721fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2722fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2723fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_none);
2724fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2725fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2726fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_start);
2727fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.START, mTextView.getEllipsize());
2728fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2729fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_middle);
2730fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.MIDDLE, mTextView.getEllipsize());
2731fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2732fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_end);
2733fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.END, mTextView.getEllipsize());
2734fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2735fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.START);
2736fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize());
2737fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2738fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
2739fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.MIDDLE, mTextView.getEllipsize());
2740fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2741fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.END);
2742fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.END, mTextView.getEllipsize());
2743fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2744fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(null);
2745fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2746fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2747fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(10);
2748fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.START);
2749fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("ThisIsAVeryLongVeryLongVeryLongVeryLongVeryLongWord");
2750fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.invalidate();
2751fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2752fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize());
2753fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no method to check if '...yLongVeryLongWord' is painted in the screen.
2754fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2755fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
27562deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    public void testEllipsizeEndAndNoEllipsizeHasSameBaselineForSingleLine() {
27572deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        int textWidth = calculateTextWidth(LONG_TEXT);
27582deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27592deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        TextView tvEllipsizeEnd = new TextView(getActivity());
27602deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
27612deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setMaxLines(1);
27622deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setWidth(textWidth >> 2);
27632deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setText(LONG_TEXT);
27642deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27652deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        TextView tvEllipsizeNone = new TextView(getActivity());
27662deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setWidth(textWidth >> 2);
27672deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setText("a");
27682deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27692deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
27702deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
27712deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
27722deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
27732deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.addView(tvEllipsizeEnd, layoutParams);
27742deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.addView(tvEllipsizeNone, layoutParams);
27752deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.setLayoutParams(layoutParams);
27762deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27772deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        mActivity.runOnUiThread(new Runnable() {
27782deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            @Override
27792deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            public void run() {
27802deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                getActivity().setContentView(layout);
27812deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            }
27822deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        });
27832deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        getInstrumentation().waitForIdleSync();
27842deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27852deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        assertEquals("Ellipsized and non ellipsized single line texts should have the same " +
27862deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                        "baseline",
27872deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                tvEllipsizeEnd.getLayout().getLineBaseline(0),
27882deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                tvEllipsizeNone.getLayout().getLineBaseline(0));
27892deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    }
27902deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27912deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    public void testEllipsizeEndAndNoEllipsizeHasSameBaselineForMultiLine() {
27922deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        int textWidth = calculateTextWidth(LONG_TEXT);
27932deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27942deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        TextView tvEllipsizeEnd = new TextView(getActivity());
27952deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
27962deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setMaxLines(2);
27972deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setWidth(textWidth >> 2);
27982deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setText(LONG_TEXT);
27992deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28002deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        TextView tvEllipsizeNone = new TextView(getActivity());
28012deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setMaxLines(2);
28022deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setWidth(textWidth >> 2);
28032deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setText(LONG_TEXT);
28042deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28052deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
28062deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
28072deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
28082deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
28092deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28102deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.addView(tvEllipsizeEnd, layoutParams);
28112deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.addView(tvEllipsizeNone, layoutParams);
28122deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.setLayoutParams(layoutParams);
28132deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28142deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        mActivity.runOnUiThread(new Runnable() {
28152deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            @Override
28162deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            public void run() {
28172deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                getActivity().setContentView(layout);
28182deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            }
28192deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        });
28202deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        getInstrumentation().waitForIdleSync();
28212deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28222deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        for (int i = 0; i < tvEllipsizeEnd.getLineCount(); i++) {
28232deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            assertEquals("Ellipsized and non ellipsized multi line texts should have the same " +
28242deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                            "baseline for line " + i,
28252deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                    tvEllipsizeEnd.getLayout().getLineBaseline(i),
28262deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                    tvEllipsizeNone.getLayout().getLineBaseline(i));
28272deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        }
28282deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    }
28292deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
2830672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir    public void testTextViewInWeigthenedLayoutChangesWidthAfterSetText() {
2831672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        final TextView textView = new TextView(getActivity());
2832672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        textView.setEllipsize(TruncateAt.END);
2833672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        textView.setSingleLine(true);
2834672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        textView.setText("a");
2835672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2836672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        TextView otherTextView = new TextView(getActivity());
2837672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        otherTextView.setSingleLine(true);
2838672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        otherTextView.setText("any");
2839672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2840672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        final LinearLayout layout = new LinearLayout(mActivity);
2841672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.setOrientation(LinearLayout.HORIZONTAL);
2842672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2843672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // TextView under test has weight 1, and width 0
2844672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.addView(textView, new LinearLayout.LayoutParams(0,
2845672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
2846672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2847672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // other TextView has default weight
2848672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.addView(otherTextView, new LinearLayout.LayoutParams(
2849672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
2850672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT));
2851672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2852672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // main layout params
2853672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.setLayoutParams(new ViewGroup.LayoutParams(
2854672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
2855672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2856672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        mActivity.runOnUiThread(new Runnable() {
2857672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            @Override
2858672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            public void run() {
2859672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                getActivity().setContentView(layout);
2860672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            }
2861672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        });
2862672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        getInstrumentation().waitForIdleSync();
2863672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2864672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        int oldWidth = textView.getWidth();
2865672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2866672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        mActivity.runOnUiThread(new Runnable() {
2867672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            @Override
2868672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            public void run() {
2869672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                textView.setText("aaa");
2870672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            }
2871672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        });
2872672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        getInstrumentation().waitForIdleSync();
2873672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2874672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        assertTrue("TextView should have larger width after a longer text is set",
2875672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                textView.getWidth() > oldWidth);
2876672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir    }
2877672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2878354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testAccessCursorVisible() {
2879fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2880fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2881fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCursorVisible(true);
2882354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.isCursorVisible());
2883fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCursorVisible(false);
2884354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.isCursorVisible());
2885fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2886fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2887fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnWindowFocusChanged() {
2888fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
2889fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2890fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2891fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnTouchEvent() {
2892fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
2893fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2894fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2895fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnTrackballEvent() {
2896fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
2897fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2898fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2899fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTextColors() {
2900fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // TODO: How to get a suitable TypedArray to test this method.
2901fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2902fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2903fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnKeyShortcut() {
2904fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
2905fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2906fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2907fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2908fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testPerformLongClick() {
2909fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2910fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("This is content");
2911938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
2912938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        View.OnLongClickListener mockOnLongClickListener = mock(View.OnLongClickListener.class);
2913938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        when(mockOnLongClickListener.onLongClick(any(View.class))).thenReturn(Boolean.TRUE);
2914938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
2915938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        View.OnCreateContextMenuListener mockOnCreateContextMenuListener =
2916938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                mock(View.OnCreateContextMenuListener.class);
29174e47d86641f4cbf8269723cca1a2ca1250f9aa02Kirill Grouchnikov        doAnswer((InvocationOnMock invocation) -> {
29184e47d86641f4cbf8269723cca1a2ca1250f9aa02Kirill Grouchnikov            ((ContextMenu) invocation.getArguments() [0]).add("menu item");
29194e47d86641f4cbf8269723cca1a2ca1250f9aa02Kirill Grouchnikov            return null;
2920938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }).when(mockOnCreateContextMenuListener).onCreateContextMenu(
2921938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), any(View.class), any(ContextMenuInfo.class));
2922938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
2923938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        mTextView.setOnLongClickListener(mockOnLongClickListener);
2924938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        mTextView.setOnCreateContextMenuListener(mockOnCreateContextMenuListener);
2925fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.performLongClick());
2926938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnLongClickListener, times(1)).onLongClick(mTextView);
2927938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyZeroInteractions(mockOnCreateContextMenuListener);
2928fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2929938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        reset(mockOnLongClickListener);
2930938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        when(mockOnLongClickListener.onLongClick(any(View.class))).thenReturn(Boolean.FALSE);
2931fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.performLongClick());
2932938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnLongClickListener, times(1)).onLongClick(mTextView);
2933938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnCreateContextMenuListener, times(1)).onCreateContextMenu(
2934938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), eq(mTextView), any(ContextMenuInfo.class));
2935fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2936938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        reset(mockOnCreateContextMenuListener);
2937fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setOnLongClickListener(null);
2938938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        doNothing().when(mockOnCreateContextMenuListener).onCreateContextMenu(
2939938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), any(View.class), any(ContextMenuInfo.class));
2940fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.performLongClick());
2941938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyNoMoreInteractions(mockOnLongClickListener);
2942938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnCreateContextMenuListener, times(1)).onCreateContextMenu(
2943938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), eq(mTextView), any(ContextMenuInfo.class));
2944fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2945fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2946fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2947fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testTextAttr() {
2948fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_textAttr);
2949fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getText
2950fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getString(R.string.text_view_hello), mTextView.getText().toString());
2951fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2952fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getCurrentTextColor
2953fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
2954fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
2955fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
2956fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
2957fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
2958fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHintTextColors().getDefaultColor());
2959fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
2960fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
2961fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2962fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTextScaleX
2963fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1.2f, mTextView.getTextScaleX(), 0.01f);
2964fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2965fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // setTextScaleX
2966fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(2.4f);
2967fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2.4f, mTextView.getTextScaleX(), 0.01f);
2968fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2969fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(0f);
2970fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0f, mTextView.getTextScaleX(), 0.01f);
2971fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2972fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(- 2.4f);
2973fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(- 2.4f, mTextView.getTextScaleX(), 0.01f);
2974fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2975fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTextSize
2976fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20f, mTextView.getTextSize(), 0.01f);
2977fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2978fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTypeface
2979119351956fc53fdd61bfbfb0d1ab43857cf7a6d7Peter Eliasson        // getTypeface will be null if android:typeface is set to normal,
2980c02a9f453c5c1255d668bbd8970f4585ab5ff494Alan Viverette        // and android:style is not set or is set to normal, and
2981c02a9f453c5c1255d668bbd8970f4585ab5ff494Alan Viverette        // android:fontFamily is not set
2982fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTypeface());
2983fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2984fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT);
2985fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.DEFAULT, mTextView.getTypeface());
2986fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // null type face
2987fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(null);
2988fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTypeface());
2989fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2990fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // default type face, bold style, note: the type face will be changed
2991fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // after call set method
2992fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
2993fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle());
2994fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2995fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // null type face, BOLD style
2996fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(null, Typeface.BOLD);
2997fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle());
2998fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2999fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // old type face, null style
3000fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT, 0);
3001fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
3002fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3003fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAppend() {
3006fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
3007fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3008fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 1: check the original length, should be blank as initialised.
3009fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getText().length());
3010fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3011fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 2: append a string use append(CharSquence) into the original blank
3012fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // buffer, check the content. And upgrading it to BufferType.EDITABLE if it was
3013fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // not already editable.
3014fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getText() instanceof Editable);
3015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append.");
3016fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.", mTextView.getText().toString());
3017fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3018fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3019fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 3: append a string from 0~3.
3020fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append", 0, 3);
3021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.App", mTextView.getText().toString());
3022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3023fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 4: append a string from 0~0, nothing will be append as expected.
3025fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append", 0, 0);
3026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.App", mTextView.getText().toString());
3027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3028fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 5: append a string from -3~3. check the wrong left edge.
3030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append("Append", -3, 3);
3032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw StringIndexOutOfBoundsException");
3033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (StringIndexOutOfBoundsException e) {
3034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 6: append a string from 3~10. check the wrong right edge.
3037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3038fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append("Append", 3, 10);
3039fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw StringIndexOutOfBoundsException");
3040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (StringIndexOutOfBoundsException e) {
3041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3043fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 7: append a null string.
3044fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3045fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append(null);
3046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException");
3047fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
3048fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3049fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3050fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3051f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3052f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_doesNotAddLinksWhenAppendedTextDoesNotContainLinks() {
3053f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3054f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3055f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3056f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3057f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" another text without URL");
3058f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3059f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3060f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3061f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be zero", 0, urlSpans.length);
3062f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL another text without URL", text.toString());
3063f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3064f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3065f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3066f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_doesNotAddLinksWhenAutoLinkIsNotEnabled() {
3067f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3068f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3069f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3070f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3071f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3072f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3073f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3074f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be zero", 0, urlSpans.length);
3075f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL text with URL http://android.com", text.toString());
3076f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3077f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3078f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3079f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksWhenAutoLinkIsEnabled() {
3080f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3081f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3082f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3083f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3084f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3085f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3086f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3087f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3088f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length);
3089f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3090f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3091f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL text with URL http://android.com", text.toString());
3092f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3093f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3094f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3095f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksEvenWhenThereAreUrlsSetBefore() {
3096f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3097f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3098f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with URL http://android.com/before");
3099f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3100f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3101f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3102f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3103f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3104f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be two after appending another URL", 2, urlSpans.length);
3105f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("First URLSpan URL should be same",
3106f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com/before");
3107f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3108f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[1].getURL(), "http://android.com");
3109f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text with URL http://android.com/before text with URL http://android.com",
3110f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                text.toString());
3111f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3112f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3113f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3114f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_setsMovementMethodWhenTextContainsUrlAndAutoLinkIsEnabled() {
3115f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3116f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3117f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without a URL");
3118f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3119f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with a url: http://android.com");
3120f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3121f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertNotNull("MovementMethod should not be null when text contains url",
3122f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                mTextView.getMovementMethod());
3123f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertTrue("MovementMethod should be instance of LinkMovementMethod when text contains url",
3124f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                mTextView.getMovementMethod() instanceof LinkMovementMethod);
3125f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3126f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3127f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3128f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksWhenTextIsSpannableAndContainsUrlAndAutoLinkIsEnabled() {
3129f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3130f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3131f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without a URL");
3132f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3133f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(new SpannableString(" text with a url: http://android.com"));
3134f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3135f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3136f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3137f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length);
3138f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3139f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3140f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3141f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3142f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3143f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinkIfAppendedTextCompletesPartialUrlAtTheEndOfExistingText() {
3144f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3145f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3146f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with a partial url android.");
3147f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3148f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append("com");
3149f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3150f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3151f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3152f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending to partial URL",
3153f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                1, urlSpans.length);
3154f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3155f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3156f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3157f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3158f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3159f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinkIfAppendedTextUpdatesUrlAtTheEndOfExistingText() {
3160f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3161f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3162f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with a url http://android.com");
3163f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3164f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append("/textview");
3165f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3166f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3167f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3168f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should still be one after extending a URL", 1, urlSpans.length);
3169f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the new URL",
3170f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com/textview");
3171f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3172f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
31736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
31746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetLetterSpacing_returnsValueThatWasSet() {
31756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
31766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLetterSpacing(2f);
31776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("getLetterSpacing should return the value that was set",
31786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                2f, mTextView.getLetterSpacing());
31796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
31806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
31816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
31826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testSetLetterSpacing_changesTextWidth() {
31836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
31846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText("aa");
31856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setLetterSpacing(0f);
31866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextSize(8f);
31876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
31886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
31896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
31906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT,
31916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
31926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(textView, layoutParams);
31936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
31946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
31956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
31966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
31976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
31986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                getActivity().setContentView(layout);
31996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
32006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
32016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
32026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with zero letter spacing
32046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final float zeroSpacing = textView.getLayout().getLineWidth(0);
32056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getActivity().runOnUiThread(new Runnable() {
32076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
32086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
32096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                textView.setLetterSpacing(1f);
32106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
32116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
32126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
32136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with single letter spacing
32156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final float singleSpacing = textView.getLayout().getLineWidth(0);
32166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getActivity().runOnUiThread(new Runnable() {
32186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
32196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
32206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                textView.setLetterSpacing(2f);
32216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
32226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
32236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
32246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with double letter spacing
32266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final float doubleSpacing = textView.getLayout().getLineWidth(0);
32276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Double spacing should have two times the spacing of single spacing",
32296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                doubleSpacing - zeroSpacing, 2f * (singleSpacing - zeroSpacing), 1f);
32306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
32316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
32336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetFontFeatureSettings_returnsValueThatWasSet() {
32346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
32356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setFontFeatureSettings("\"smcp\" on");
32366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("getFontFeatureSettings should return the value that was set",
32376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                "\"smcp\" on", mTextView.getFontFeatureSettings());
32386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
32396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
32416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetOffsetForPosition_singleLineLtr() {
32426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // asserts getOffsetPosition returns correct values for a single line LTR text
32436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        String text = "aaaaa";
32446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
32456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText(text);
32466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextSize(8f);
32476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setSingleLine(true);
32486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
3250a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
32516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
32526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setCompoundDrawables(drawable, drawable, drawable, drawable);
32536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
32556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
32566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
32576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
32586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(textView, layoutParams);
32596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
32606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
3261023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.runOnMainSync(() -> getActivity().setContentView(layout));
3262023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.waitForIdleSync();
32636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int firstOffset = 0;
32656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int lastOffset = text.length() - 1;
32666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int midOffset = text.length() / 2;
32676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view
32696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float x = 0f;
32706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float y = textView.getHeight() / 2f;
32716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(firstOffset, textView.getOffsetForPosition(x, y));
32726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text
32746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getLayout().getLineWidth(0) - 1f;
32756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(lastOffset, textView.getOffsetForPosition(x, y));
32766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view
32786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth();
32796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(lastOffset + 1, textView.getOffsetForPosition(x, y));
32806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view - out of bounds
32826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = -1f;
32836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(firstOffset, textView.getOffsetForPosition(x, y));
32846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text
3286023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        x = (float) Math.floor(textView.getLayout().getLineWidth(0) / 2f + 0.5f);
32876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(midOffset, textView.getOffsetForPosition(x, y));
32886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
32896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
32916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetOffsetForPosition_multiLineLtr() {
3292023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        final String line = "aaa\n";
32936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String threeLines = line + line + line;
32946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
32956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText(threeLines);
32966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextSize(8f);
32976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setLines(2);
32986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
3300a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
33016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
33026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setCompoundDrawables(drawable, drawable, drawable, drawable);
33036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
33056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
33066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
33076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
33086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(textView, layoutParams);
33096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
33106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
3311023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.runOnMainSync(() -> getActivity().setContentView(layout));
3312023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.waitForIdleSync();
33136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Rect lineBounds = new Rect();
33156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.getLayout().getLineBounds(0, lineBounds);
33166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at first line
33186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float x = 0f;
33196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float y = lineBounds.height() / 2f;
33206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, textView.getOffsetForPosition(x, y));
33216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at first line
33236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - 1f;
33246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() - 1, textView.getOffsetForPosition(x, y));
33256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // update lineBounds to be the second line
33276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.getLayout().getLineBounds(1, lineBounds);
33286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        y = lineBounds.top + lineBounds.height() / 2;
33296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at second line
33316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
33326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length(), textView.getOffsetForPosition(x, y));
33336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text at second line
33356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getLayout().getLineWidth(1) - 1f;
33366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() - 1, textView.getOffsetForPosition(x, y));
33376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at second line
33396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - 1f;
33406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() - 1, textView.getOffsetForPosition(x, y));
33416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text at second line
3343023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        x = (float) Math.floor(textView.getLayout().getLineWidth(1) / 2f + 0.5f);
3344023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        // second line mid offset shoud not include next line, therefore subtract one
3345023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        assertEquals(line.length() + (line.length() - 1) / 2, textView.getOffsetForPosition(x, y));
33466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
33476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
33496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetOffsetForPosition_multiLineRtl() {
3350023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        final String line = "\u0635\u0635\u0635\n";
33516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String threeLines = line + line + line;
33526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
33536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText(threeLines);
33546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextSize(8f);
33556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setLines(2);
33566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
3358a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable drawable = TestUtils.getDrawable(mActivity, R.drawable.red);
33596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
33606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setCompoundDrawables(drawable, drawable, drawable, drawable);
33616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
33636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
33646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
33656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
33666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(textView, layoutParams);
33676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
33686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
3369023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.runOnMainSync(() -> getActivity().setContentView(layout));
3370023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        mInstrumentation.waitForIdleSync();
33716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Rect lineBounds = new Rect();
33736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.getLayout().getLineBounds(0, lineBounds);
33746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at first line
33766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float x = textView.getWidth() - 1f;
33776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float y = lineBounds.height() / 2f;
33786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, textView.getOffsetForPosition(x, y));
33796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at first line
33816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
33826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() - 1, textView.getOffsetForPosition(x, y));
33836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // update lineBounds to be the second line
33856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.getLayout().getLineBounds(1, lineBounds);
33866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        y = lineBounds.top + lineBounds.height() / 2f;
33876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at second line
33896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - 1f;
33906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length(), textView.getOffsetForPosition(x, y));
33916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at second line
33936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
33946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() - 1, textView.getOffsetForPosition(x, y));
33956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text at second line
33976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - textView.getLayout().getLineWidth(1) + 1f;
33986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() - 1, textView.getOffsetForPosition(x, y));
33996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text at second line
3401023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        x = textView.getWidth() - (float) Math.floor(
3402023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir                textView.getLayout().getLineWidth(1) / 2f + 0.5f);
3403023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        // second line mid offset shoud not include next line, therefore subtract one
3404023f7673deecf213c762bc7358faba360ccb16e1Siyamed Sinir        assertEquals(line.length() + (line.length() - 1) / 2, textView.getOffsetForPosition(x, y));
34056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
34066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
34086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testIsTextSelectable_returnsFalseByDefault() {
34096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(getActivity());
34106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText("any text");
34116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isTextSelectable());
34126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
34136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
34156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testIsTextSelectable_returnsTrueIfSetTextIsSelectableCalledWithTrue() {
34166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(getActivity());
34176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText("any text");
34186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextIsSelectable(true);
34196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isTextSelectable());
34206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
34216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
34236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testSetIsTextSelectable() {
34246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(getActivity());
34256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isTextSelectable());
34276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isFocusable());
34286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isFocusableInTouchMode());
34296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isClickable());
34306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isLongClickable());
34316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextIsSelectable(true);
34336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isTextSelectable());
34356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isFocusable());
34366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isFocusableInTouchMode());
34376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isClickable());
34386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isLongClickable());
34396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(textView.getMovementMethod());
34406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
3441f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessTransformationMethod() {
3443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check the password attribute in xml
3444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_password);
3445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView);
3446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(PasswordTransformationMethod.getInstance(),
3447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check the singleLine attribute in xml
3450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_singleLine);
3451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView);
3452fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(SingleLineTransformationMethod.getInstance(),
3453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3455fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener = QwertyKeyListener.getInstance(false,
3456fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Capitalize.NONE);
3457fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final TransformationMethod method = PasswordTransformationMethod.getInstance();
3458fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change transformation method by function
3459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3460fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setKeyListener(qwertyKeyListener);
3462fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setTransformationMethod(method);
346322d40a1fcc078329a7e5a34ff5eeadeca9c70d49Kenny Root                mTransformedText = method.getTransformation(mTextView.getText(), mTextView);
3464fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3465fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
3466fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3467fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3469fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(PasswordTransformationMethod.getInstance(),
3470fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3471fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
347203818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, "H E 2*L O");
3473fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3474fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3475fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.append(" ");
3476fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3477fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3478fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3479fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3480354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // It will get transformed after a while
3481354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // We're waiting for transformation to "******"
3482354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(TIMEOUT, () -> mTransformedText.toString()
3483354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov                .equals("\u2022\u2022\u2022\u2022\u2022\u2022"));
3484fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3485fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set null
3486fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3487fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3488fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setTransformationMethod(null);
3489fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3490fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3491fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3492fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTransformationMethod());
3493fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3494fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3495fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3496fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testCompound() {
3497fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
3498fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int padding = 3;
3499fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Drawable[] drawables = mTextView.getCompoundDrawables();
3500fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[0]);
3501fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[1]);
3502fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[2]);
3503fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3504fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3505fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test setCompoundDrawablePadding and getCompoundDrawablePadding
3506fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablePadding(padding);
3507fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(padding, mTextView.getCompoundDrawablePadding());
3508fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3509fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using resid, 0 represents null
3510fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.start, R.drawable.pass,
3511fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                R.drawable.failed, 0);
3512fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3513fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3514fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3515a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        WidgetTestUtils.assertEquals(TestUtils.getBitmap(mActivity, R.drawable.start),
3516fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[0]).getBitmap());
3517fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3518a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        WidgetTestUtils.assertEquals(TestUtils.getBitmap(mActivity, R.drawable.pass),
3519fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[1]).getBitmap());
3520fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3521a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        WidgetTestUtils.assertEquals(TestUtils.getBitmap(mActivity, R.drawable.failed),
3522fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[2]).getBitmap());
3523fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3524fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3525fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3526a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable left = TestUtils.getDrawable(mActivity, R.drawable.blue);
3527a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable right = TestUtils.getDrawable(mActivity, R.drawable.yellow);
3528a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable top = TestUtils.getDrawable(mActivity, R.drawable.red);
3529fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3530fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using drawables directly
3531fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, null);
3532fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3533fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3534fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3535fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(left, drawables[0]);
3536fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3537fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(top, drawables[1]);
3538fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3539fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(right, drawables[2]);
3540fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3541fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3542fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3543fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check compound padding
3544fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingLeft() + padding + left.getIntrinsicWidth(),
3545fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingLeft());
3546fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingTop() + padding + top.getIntrinsicHeight(),
3547fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingTop());
3548fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingRight() + padding + right.getIntrinsicWidth(),
3549fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingRight());
3550fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom());
3551fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3552fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set bounds to drawables and set them again.
3553fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        left.setBounds(0, 0, 1, 2);
3554fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        right.setBounds(0, 0, 3, 4);
3555fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 5, 6);
3556fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // usinf drawables
3557fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(left, top, right, null);
3558fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3559fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3560fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3561fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(left, drawables[0]);
3562fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3563fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(top, drawables[1]);
3564fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3565fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(right, drawables[2]);
3566fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3567fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3568fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3569fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check compound padding
3570fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingLeft() + padding + left.getBounds().width(),
3571fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingLeft());
3572fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingTop() + padding + top.getBounds().height(),
3573fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingTop());
3574fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingRight() + padding + right.getBounds().width(),
3575fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingRight());
3576fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom());
3577fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3578fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
35796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
35806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @UiThreadTest
35816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetCompoundDrawablesRelative() {
35826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // prepare textview
35836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
35846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // prepare drawables
3586a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable start = TestUtils.getDrawable(mActivity, R.drawable.blue);
3587a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable end = TestUtils.getDrawable(mActivity, R.drawable.yellow);
3588a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable top = TestUtils.getDrawable(mActivity, R.drawable.red);
3589a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable bottom = TestUtils.getDrawable(mActivity, R.drawable.black);
35906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(start);
35916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(end);
35926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(top);
35936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(bottom);
35946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
35956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Drawable[] drawables = mTextView.getCompoundDrawablesRelative();
35966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
35976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
35986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[0]);
35996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[1]);
36006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[2]);
36016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[3]);
36026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
36046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(start, top, end, bottom);
36056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
36066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
36086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
36096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(start, drawables[0]);
36106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(top, drawables[1]);
36116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(end, drawables[2]);
36126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(bottom, drawables[3]);
36136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
36156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(start, top, end, bottom);
36166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
36176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
36196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
36206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(start, drawables[0]);
36216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(top, drawables[1]);
36226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(end, drawables[2]);
36236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(bottom, drawables[3]);
36246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(null, null, null, null);
36266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
36276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
36296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
36306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[0]);
36316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[1]);
36326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[2]);
36336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[3]);
36346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
36356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
3637fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSingleLine() {
3638013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        final TextView textView = new TextView(mActivity);
3639013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        setSpannableText(textView, "This is a really long sentence"
3640013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                + " which can not be placed in one line on the screen.");
3641013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
3642013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        // Narrow layout assures that the text will get wrapped.
36436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout innerLayout = new FrameLayout(mActivity);
3644013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        innerLayout.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
3645013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        innerLayout.addView(textView);
3646013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
3647013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        final FrameLayout layout = new FrameLayout(mActivity);
3648013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        layout.addView(innerLayout);
3649013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
3650013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        mActivity.runOnUiThread(new Runnable() {
3651013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu            public void run() {
3652013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                mActivity.setContentView(layout);
3653013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.setSingleLine(true);
3654013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu            }
3655013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        });
3656013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        mInstrumentation.waitForIdleSync();
3657fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3658fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(SingleLineTransformationMethod.getInstance(),
3659013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.getTransformationMethod());
3660da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3661da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        int singleLineWidth = 0;
3662da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        int singleLineHeight = 0;
3663da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3664da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        if (textView.getLayout() != null) {
3665da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            singleLineWidth = textView.getLayout().getWidth();
3666da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            singleLineHeight = textView.getLayout().getHeight();
3667da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3668fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3669fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3670fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3671013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.setSingleLine(false);
3672fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3673fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3674fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3675013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        assertEquals(null, textView.getTransformationMethod());
3676da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3677da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        if (textView.getLayout() != null) {
3678da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            assertTrue(textView.getLayout().getHeight() > singleLineHeight);
3679da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            assertTrue(textView.getLayout().getWidth() < singleLineWidth);
3680da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3681fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3682fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // same behaviours as setSingLine(true)
3683fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3684fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3685013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.setSingleLine();
3686fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3687fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3688fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3689fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(SingleLineTransformationMethod.getInstance(),
3690013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.getTransformationMethod());
3691da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3692da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        if (textView.getLayout() != null) {
3693da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            assertEquals(singleLineHeight, textView.getLayout().getHeight());
3694da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            assertEquals(singleLineWidth, textView.getLayout().getWidth());
3695da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3696fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3697fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3698fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
369998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testAccessMaxLines() {
3700fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3701fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3702fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float[] widths = new float[LONG_TEXT.length()];
3703fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getPaint().getTextWidths(LONG_TEXT, widths);
3704fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float totalWidth = 0.0f;
3705fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        for (float f : widths) {
3706fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            totalWidth += f;
3707fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3708fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int stringWidth = (int) totalWidth;
3709fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(stringWidth >> 2);
3710fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(LONG_TEXT);
3711fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3712fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int maxLines = 2;
3713fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > maxLines);
3714fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3715fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setMaxLines(maxLines);
3716fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestLayout();
3717fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
371898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(2, mTextView.getMaxLines());
371998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxHeight());
3720fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getHeight() <= maxLines * mTextView.getLineHeight());
3721fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3722fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3723636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    public int calculateTextWidth(String text) {
3724636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView = findTextView(R.id.textview_text);
3725636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3726636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        // Set the TextView width as the half of the whole text.
3727636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        float[] widths = new float[text.length()];
3728636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView.getPaint().getTextWidths(text, widths);
3729636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        float textfieldWidth = 0.0f;
3730636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        for (int i = 0; i < text.length(); ++i) {
3731636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            textfieldWidth += widths[i];
3732636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        }
3733636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        return (int)textfieldWidth;
3734636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3735636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    }
3736636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3737636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    @UiThreadTest
3738636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    public void testHyphenationNotHappen_frequencyNone() {
3739636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        final int[] BREAK_STRATEGIES = {
3740636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.BREAK_STRATEGY_SIMPLE, Layout.BREAK_STRATEGY_HIGH_QUALITY,
3741636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.BREAK_STRATEGY_BALANCED };
3742636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3743636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView = findTextView(R.id.textview_text);
3744636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3745636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        for (int breakStrategy : BREAK_STRATEGIES) {
3746636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            for (int charWidth = 10; charWidth < 120; charWidth += 5) {
3747636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                // Change the text view's width to charWidth width.
3748636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setWidth(calculateTextWidth(LONG_TEXT.substring(0, charWidth)));
3749636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3750636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setText(LONG_TEXT);
3751636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setBreakStrategy(breakStrategy);
3752636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3753636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
3754636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3755636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.requestLayout();
3756636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.onPreDraw();  // For freezing the layout.
3757636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                Layout layout = mTextView.getLayout();
3758636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3759636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                final int lineCount = layout.getLineCount();
3760636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                for (int line = 0; line < lineCount; ++line) {
3761636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    final int lineEnd = layout.getLineEnd(line);
3762636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // In any width, any break strategy, hyphenation should not happen if
3763636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // HYPHENATION_FREQUENCY_NONE is specified.
3764636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    assertTrue(lineEnd == LONG_TEXT.length() ||
3765636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                            Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1)));
3766636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                }
3767636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            }
3768636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        }
3769636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    }
3770636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3771636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    @UiThreadTest
3772636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    public void testHyphenationNotHappen_breakStrategySimple() {
3773636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        final int[] HYPHENATION_FREQUENCIES = {
3774636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.HYPHENATION_FREQUENCY_NORMAL, Layout.HYPHENATION_FREQUENCY_FULL,
3775636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.HYPHENATION_FREQUENCY_NONE };
3776636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3777636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView = findTextView(R.id.textview_text);
3778636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3779636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        for (int hyphenationFrequency: HYPHENATION_FREQUENCIES) {
3780636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            for (int charWidth = 10; charWidth < 120; charWidth += 5) {
3781636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                // Change the text view's width to charWidth width.
3782636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setWidth(calculateTextWidth(LONG_TEXT.substring(0, charWidth)));
3783636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3784636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setText(LONG_TEXT);
3785636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
3786636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3787636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setHyphenationFrequency(hyphenationFrequency);
3788636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3789636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.requestLayout();
3790636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.onPreDraw();  // For freezing the layout.
3791636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                Layout layout = mTextView.getLayout();
3792636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3793636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                final int lineCount = layout.getLineCount();
3794636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                for (int line = 0; line < lineCount; ++line) {
3795636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    final int lineEnd = layout.getLineEnd(line);
3796636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // In any width, any hyphenation frequency, hyphenation should not happen if
3797636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // BREAK_STRATEGY_SIMPLE is specified.
3798636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    assertTrue(lineEnd == LONG_TEXT.length() ||
3799636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                            Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1)));
3800636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                }
3801636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            }
3802636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        }
3803636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    }
3804636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3805fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3806fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetMaxLinesException() {
380772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
380872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mActivity.setContentView(mTextView);
3809fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(mTextView.getWidth() >> 3);
381072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setMaxLines(-1);
3811fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3812fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
381398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testAccessMinLines() {
3814fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3815fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 3);
3816fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLines = mTextView.getLineCount();
3817fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3818fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(originalLines - 1);
3819fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight());
382098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalLines - 1, mTextView.getMinLines());
382198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinHeight());
3822fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3823fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(originalLines + 1);
3824fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight());
382598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalLines + 1, mTextView.getMinLines());
382698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinHeight());
3827fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3828fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3829fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetLines() {
3830fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3831fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it multiple lines
3832fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 3);
3833fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLines = mTextView.getLineCount();
3834fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3835fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(originalLines - 1);
3836fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight());
3837fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3838fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(originalLines + 1);
3839fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight());
3840fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3841fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3842fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3843fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetLinesException() {
384472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
384572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mActivity.setContentView(mTextView);
384672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setWidth(mTextView.getWidth() >> 3);
384772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setLines(-1);
3848fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3849fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3850fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3851fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetExtendedPaddingTop() {
3852fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3853fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3854fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getExtendedPaddingTop());
3855fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3856fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
3857a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable top = TestUtils.getDrawable(mActivity, R.drawable.red);
3858fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 100, 10);
3859fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, top, null, null);
3860fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingTop(), mTextView.getExtendedPaddingTop());
3861fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3862fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3863fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLines(mTextView.getLineCount() - 1);
3864fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.BOTTOM);
3865fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3866fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getExtendedPaddingTop() > 0);
3867fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3868fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3869fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3870fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetExtendedPaddingBottom() {
3871fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3872fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3873fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getExtendedPaddingBottom());
3874fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3875fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
3876a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable bottom = TestUtils.getDrawable(mActivity, R.drawable.red);
3877fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        bottom.setBounds(0, 0, 100, 10);
3878fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, null, null, bottom);
3879fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingBottom(), mTextView.getExtendedPaddingBottom());
3880fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3881fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3882fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLines(mTextView.getLineCount() - 1);
3883fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER_VERTICAL);
3884fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3885fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getExtendedPaddingBottom() > 0);
3886fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3887fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3888fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingTop() {
3889fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3890fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3891fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingTop());
3892fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3893fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
3894a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable top = TestUtils.getDrawable(mActivity, R.drawable.red);
3895fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 100, 10);
3896fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3897fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3898fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setCompoundDrawables(null, top, null, null);
3899fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setLines(mTextView.getLineCount() - 1);
3900fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.BOTTOM);
3901fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3902fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3903fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3904fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getExtendedPaddingTop(), mTextView.getTotalPaddingTop());
3905fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3906fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3907fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(mTextView.getLineCount() + 1);
3908fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = mTextView.getHeight()
3909fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingBottom()
3910fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getLayout().getLineTop(mTextView.getLineCount());
3911fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getTotalPaddingTop());
3912fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3913fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3914fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingBottom() {
3915fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3916fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3917fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingBottom());
3918fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3919fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
3920a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        final Drawable bottom = TestUtils.getDrawable(mActivity, R.drawable.red);
3921fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        bottom.setBounds(0, 0, 100, 10);
3922fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3923fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3924fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setCompoundDrawables(null, null, null, bottom);
3925fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setLines(mTextView.getLineCount() - 1);
3926fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.CENTER_VERTICAL);
3927fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3928fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3929fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3930fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getExtendedPaddingBottom(), mTextView.getTotalPaddingBottom());
3931fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3932fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3933fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(mTextView.getLineCount() + 1);
3934fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = ((mTextView.getHeight()
3935fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingBottom()
3936fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingTop()
3937fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getLayout().getLineBottom(mTextView.getLineCount())) >> 1)
3938fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + mTextView.getExtendedPaddingBottom();
3939fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getTotalPaddingBottom());
3940fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3941fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3942fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3943fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingLeft() {
3944fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3945fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3946fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingLeft());
3947fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3948fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
3949a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable left = TestUtils.getDrawable(mActivity, R.drawable.red);
3950fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        left.setBounds(0, 0, 10, 100);
3951fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(left, null, null, null);
3952fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.RIGHT);
3953fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft());
3954fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3955fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change width
3956fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(Integer.MAX_VALUE);
3957fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft());
3958fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3959fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3960fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3961fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingRight() {
3962fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3963fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3964fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingRight());
3965fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3966fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
3967a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable right = TestUtils.getDrawable(mActivity, R.drawable.red);
3968fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        right.setBounds(0, 0, 10, 100);
3969fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, null, right, null);
3970fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER_HORIZONTAL);
3971fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight());
3972fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3973fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change width
3974fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(Integer.MAX_VALUE);
3975fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight());
3976fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3977fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3978fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetUrls() {
3979fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
3980fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3981fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        URLSpan[] spans = mTextView.getUrls();
3982fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, spans.length);
3983fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3984fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String url = "http://www.google.com";
3985fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String email = "name@gmail.com";
3986fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String string = url + " mailto:" + email;
3987fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        SpannableString spannable = new SpannableString(string);
3988fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new URLSpan(url), 0, url.length(), 0);
3989fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
3990fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
3991fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, spans.length);
3992fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(url, spans[0].getURL());
3993fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3994fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new URLSpan(email), 0, email.length(), 0);
3995fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
3996fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3997fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
3998fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
3999fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(url, spans[0].getURL());
4000fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(email, spans[1].getURL());
4001fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4002fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test the situation that param what is not a URLSpan
4003fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new Object(), 0, 9, 0);
4004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
4005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
4006fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
4007fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4008fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4009fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetPadding() {
4010fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
4011fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4012fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPadding(0, 1, 2, 4);
4013fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getPaddingLeft());
4014fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getPaddingTop());
4015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getPaddingRight());
4016fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(4, mTextView.getPaddingBottom());
4017fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4018fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPadding(10, 20, 30, 40);
4019fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(10, mTextView.getPaddingLeft());
4020fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20, mTextView.getPaddingTop());
4021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(30, mTextView.getPaddingRight());
4022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(40, mTextView.getPaddingBottom());
4023fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4025fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testDeprecatedSetTextAppearance() {
4026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
4027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4028fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_All);
4029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
4031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20f, mTextView.getTextSize(), 0.01f);
4032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
4033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
4034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
4035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
4037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4038fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Colors);
4039fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
4041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
4043fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
4044fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
4045fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_NotColors);
4047fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(17f, mTextView.getTextSize(), 0.01f);
4048fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
4049fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4050fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Style);
4051fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(null, mTextView.getTypeface());
4052fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4053fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4054fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testSetTextAppearance() {
4055fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView = new TextView(mActivity);
4056fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4057fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_All);
4058fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4059fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentTextColor());
4060fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(20f, mTextView.getTextSize(), 0.01f);
4061fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
4062fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.red),
4063fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentHintTextColor());
4064fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4065fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getLinkTextColors().getDefaultColor());
40666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
40676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mTextView.getHighlightColor());
4068fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4069fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_Colors);
4070fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4071fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentTextColor());
4072fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4073fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentHintTextColor());
4074fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
4075fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getLinkTextColors().getDefaultColor());
40766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(mActivity.getResources().getColor(R.drawable.red),
40776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mTextView.getHighlightColor());
4078fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4079fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_NotColors);
4080fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(17f, mTextView.getTextSize(), 0.01f);
4081fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
4082fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4083fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_Style);
4084fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(null, mTextView.getTypeface());
4085fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    }
4086fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnPreDraw() {
4088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4091fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testAccessCompoundDrawableTint() {
4092fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView = new TextView(mActivity);
4093fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4094fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        ColorStateList colors = ColorStateList.valueOf(Color.RED);
4095fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setCompoundDrawableTintList(colors);
4096fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setCompoundDrawableTintMode(PorterDuff.Mode.XOR);
4097fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertSame(colors, mTextView.getCompoundDrawableTintList());
4098fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4099f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4100f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        // Ensure the tint is preserved across drawable changes.
4101f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawablesRelative(null, null, null, null);
4102f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4103f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4104f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4105f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawables(null, null, null, null);
4106f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4107f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4108f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4109f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr1 = new ColorDrawable(Color.RED);
4110f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr2 = new ColorDrawable(Color.GREEN);
4111f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr3 = new ColorDrawable(Color.BLUE);
4112f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr4 = new ColorDrawable(Color.YELLOW);
4113f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawables(dr1, dr2, dr3, dr4);
4114f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4115f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4116fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    }
4117fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetHorizontallyScrolling() {
4119fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make the text view has more than one line
4120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
4121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 1);
4122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > 1);
4123fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHorizontallyScrolling(true);
4125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
4126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHorizontallyScrolling(false);
4128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > 1);
4129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4130fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4131fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testComputeHorizontalScrollRange() {
4132fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test when layout is null
4134fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getLayout());
4135fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getWidth(), textView.computeHorizontalScrollRange());
4136fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setFrame(0, 0, 40, 50);
4138fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getWidth(), textView.computeHorizontalScrollRange());
4139fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4140fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set the layout
4141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(textView);
4142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getLayout().getWidth(), textView.computeHorizontalScrollRange());
4143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testComputeVerticalScrollRange() {
4146fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test when layout is null
4148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getLayout());
4149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, textView.computeVerticalScrollRange());
4150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setFrame(0, 0, 40, 50);
4152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getHeight(), textView.computeVerticalScrollRange());
4153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //set the layout
4155fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(textView);
4156fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getLayout().getHeight(), textView.computeVerticalScrollRange());
4157fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testDrawableStateChanged() {
4160b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        MockTextView textView = spy(new MockTextView(mActivity));
4161b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        reset(textView);
4162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.refreshDrawableState();
4163b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(textView, times(1)).drawableStateChanged();
4164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetDefaultEditable() {
4167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //the TextView#getDefaultEditable() does nothing, and always return false.
4170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(textView.getDefaultEditable());
4171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetDefaultMovementMethod() {
4174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4176fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //the TextView#getDefaultMovementMethod() does nothing, and always return null.
4177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getDefaultMovementMethod());
4178fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4179fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnCreateContextMenu() {
4181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4183fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnDetachedFromWindow() {
4185fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnDraw() {
4189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnFocusChanged() {
4193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4194fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4195fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnMeasure() {
4197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnTextChanged() {
4201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetFrame() {
4205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //Assign a new size to this view
4208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.setFrame(0, 0, 320, 480));
4209b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(0, textView.getLeft());
4210b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(0, textView.getTop());
4211b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(320, textView.getRight());
4212b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(480, textView.getBottom());
4213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //Assign a same size to this view
4215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(textView.setFrame(0, 0, 320, 480));
4216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //negative input
4218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.setFrame(-1, -1, -1, -1));
4219b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(-1, textView.getLeft());
4220b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(-1, textView.getTop());
4221b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(-1, textView.getRight());
4222b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        assertEquals(-1, textView.getBottom());
4223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testMarquee() {
4226354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Both are pointing to the same object. This works around current limitation in CTS
4227354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // coverage report tool for properly reporting coverage of base class method calls.
4228354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final MockTextView mockTextView = new MockTextView(mActivity);
4229354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final TextView textView = mockTextView;
4230354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
4231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setText(LONG_TEXT);
4232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setSingleLine();
4233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setEllipsize(TruncateAt.MARQUEE);
4234bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu        textView.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
4235bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu
4236bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu        final FrameLayout layout = new FrameLayout(mActivity);
4237bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu        layout.addView(textView);
4238bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu
4239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make the fading to be shown
4240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setHorizontalFadingEdgeEnabled(true);
4241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4242354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> mActivity.setContentView(layout));
4243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TestSelectedRunnable runnable = new TestSelectedRunnable(textView) {
4246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
4247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setMarqueeRepeatLimit(-1);
4248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // force the marquee to start
4249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected1();
4250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setSelected(true);
4251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected2();
4252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
4253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
4254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(runnable);
4255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // wait for the marquee to run
4257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // fading is shown on both sides if the marquee runs for a while
4258354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(TIMEOUT, () -> mockTextView.getLeftFadingEdgeStrength() > 0.0f
4259354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov                && mockTextView.getRightFadingEdgeStrength() > 0.0f);
4260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
42610f095ca986d7558f9f5260c71a12cef4474d9da3Siyamed Sinir        // wait for left marquee to fully apply
4262354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(TIMEOUT, () -> mockTextView.getLeftFadingEdgeStrength() > 0.99f);
4263354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
4264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(runnable.getIsSelected1());
4265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(runnable.getIsSelected2());
4266354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(-1, textView.getMarqueeRepeatLimit());
4267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        runnable = new TestSelectedRunnable(textView) {
4269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
4270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setMarqueeRepeatLimit(0);
4271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // force the marquee to stop
4272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected1();
4273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setSelected(false);
4274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected2();
4275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setGravity(Gravity.LEFT);
4276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
4277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
4278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // force the marquee to stop
4279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(runnable);
4280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(runnable.getIsSelected1());
4282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(runnable.getIsSelected2());
4283354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(0.0f, mockTextView.getLeftFadingEdgeStrength(), 0.01f);
4284354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mockTextView.getRightFadingEdgeStrength() > 0.0f);
4285354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(0, textView.getMarqueeRepeatLimit());
4286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4287354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setGravity(Gravity.RIGHT));
4288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4289354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mockTextView.getLeftFadingEdgeStrength() > 0.0f);
4290354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(0.0f, mockTextView.getRightFadingEdgeStrength(), 0.01f);
4291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4292354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setGravity(Gravity.CENTER_HORIZONTAL));
4293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no left fading (Is it correct?)
4295354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(0.0f, mockTextView.getLeftFadingEdgeStrength(), 0.01f);
4296354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mockTextView.getRightFadingEdgeStrength() > 0.0f);
4297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
42996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
43006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetMarqueeRepeatLimit() {
43016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
43026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
43036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setMarqueeRepeatLimit(10);
43046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(10, textView.getMarqueeRepeatLimit());
43056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
43066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
4307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnKeyMultiple() {
4308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessInputExtras() throws XmlPullParserException, IOException {
4312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView textView = new TextView(mActivity);
4313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setText(null, BufferType.EDITABLE);
4314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT);
4315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // do not create the extras
4317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getInputExtras(false));
4318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // create if it does not exist
4320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Bundle inputExtras = textView.getInputExtras(true);
4321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(inputExtras);
4322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(inputExtras.isEmpty());
4323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // it is created already
4325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(textView.getInputExtras(false));
4326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
4328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            textView.setInputExtras(R.xml.input_extras);
4329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException!");
4330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
4331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
4332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessContentType() {
4335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView textView = new TextView(mActivity);
4336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setText(null, BufferType.EDITABLE);
4337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setKeyListener(null);
4338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setTransformationMethod(null);
4339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_DATETIME
4341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL);
4342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL, textView.getInputType());
4344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof DateTimeKeyListener);
4345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_DATETIME
4347fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE);
4348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE, textView.getInputType());
4350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof DateKeyListener);
4351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_DATETIME
4353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME);
4354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME, textView.getInputType());
4356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof TimeKeyListener);
4357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_NUMBER
4359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED);
4361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_NUMBER
4362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED, textView.getInputType());
4364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(), DigitsKeyListener.getInstance(true, true));
4365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_PHONE);
4367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_PHONE, textView.getInputType());
4368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof DialerKeyListener);
4369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT
4371fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
4372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4373fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, textView.getInputType());
4374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(), TextKeyListener.getInstance(true, Capitalize.NONE));
4375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setSingleLine();
4377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT
4379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
4381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, textView.getInputType());
4384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(),
4385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.CHARACTERS));
4386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT
4389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
4390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS, textView.getInputType());
4392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(),
4393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.WORDS));
4394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT
4397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
4398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, textView.getInputType());
4400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(),
4401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.SENTENCES));
4402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_NULL);
4404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_NULL, textView.getInputType());
4405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof TextKeyListener);
4406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessRawContentType() {
4409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView textView = new TextView(mActivity);
4410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setText(null, BufferType.EDITABLE);
4411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setKeyListener(null);
4412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setTransformationMethod(null);
4413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL);
4416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL, textView.getInputType());
4418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE);
4423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE, textView.getInputType());
4425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME);
4430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME, textView.getInputType());
4432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_NUMBER
4436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED);
4438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_NUMBER
4439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED, textView.getInputType());
4441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_PHONE);
4445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_PHONE, textView.getInputType());
4446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_TEXT
4450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
4451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4452fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, textView.getInputType());
4453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4455fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4456fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setSingleLine();
4457fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4458fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_TEXT
4459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4460fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
4461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4462fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4463fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, textView.getInputType());
4464fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4465fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4466fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4467fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_TEXT
4468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
4469fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4470fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS, textView.getInputType());
4471fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4472fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4473fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4474fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_TEXT
4475fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
4476fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4477fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, textView.getInputType());
4478fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4479fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4480fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4481fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_NULL);
4482fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4483fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4484fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4485fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4486fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnPrivateIMECommand() {
4487fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4488fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4489fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
449072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testFoo() {
449172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // Do not test. Implementation details.
449272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
449372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
449472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testVerifyDrawable() {
449572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        MockTextView textView = new MockTextView(mActivity);
449672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4497a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable d = TestUtils.getDrawable(mActivity, R.drawable.pass);
449872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(textView.verifyDrawable(d));
449972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
450072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        textView.setCompoundDrawables(null, d, null, null);
450172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(textView.verifyDrawable(d));
450272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
450372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
450472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessPrivateImeOptions() {
450572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
450672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getPrivateImeOptions());
450772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
450872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setPrivateImeOptions("com.example.myapp.SpecialMode=3");
450972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("com.example.myapp.SpecialMode=3", mTextView.getPrivateImeOptions());
451072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
451172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setPrivateImeOptions(null);
451272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getPrivateImeOptions());
451372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
451472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
451572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testSetOnEditorActionListener() {
451672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
451772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
451898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView.OnEditorActionListener mockOnEditorActionListener =
451998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                mock(TextView.OnEditorActionListener.class);
452098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verifyZeroInteractions(mockOnEditorActionListener);
452172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
452298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setOnEditorActionListener(mockOnEditorActionListener);
452398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verifyZeroInteractions(mockOnEditorActionListener);
452472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
452572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.onEditorAction(EditorInfo.IME_ACTION_DONE);
452698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockOnEditorActionListener, times(1)).onEditorAction(mTextView,
452798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                EditorInfo.IME_ACTION_DONE, null);
452872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
452972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
453072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessImeOptions() {
453172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
453272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions());
453372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
453472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_ACTION_GO);
453572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_ACTION_GO, mTextView.getImeOptions());
453672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
453772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_ACTION_DONE);
453872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_ACTION_DONE, mTextView.getImeOptions());
453972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
454072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_NULL);
454172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions());
454272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
454372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
454472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessImeActionLabel() {
454572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
454672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getImeActionLabel());
454772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, mTextView.getImeActionId());
454872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
454972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeActionLabel("pinyin", 1);
455072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("pinyin", mTextView.getImeActionLabel().toString());
455172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(1, mTextView.getImeActionId());
455272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
455372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4554d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa    public void testAccessImeHintLocales() {
4555d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        final TextView textView = new TextView(mActivity);
4556d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setText("", BufferType.EDITABLE);
4557d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setKeyListener(null);
4558d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setRawInputType(InputType.TYPE_CLASS_TEXT);
4559d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        assertNull(textView.getImeHintLocales());
4560d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        {
4561d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            final EditorInfo editorInfo = new EditorInfo();
4562d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            textView.onCreateInputConnection(editorInfo);
4563d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            assertNull(editorInfo.hintLocales);
4564d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        }
4565d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa
4566d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        final LocaleList localeList = LocaleList.forLanguageTags("en-PH,en-US");
4567d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setImeHintLocales(localeList);
4568d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        assertEquals(localeList, textView.getImeHintLocales());
4569d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        {
4570d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            final EditorInfo editorInfo = new EditorInfo();
4571d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            textView.onCreateInputConnection(editorInfo);
4572d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            assertEquals(localeList, editorInfo.hintLocales);
4573d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        }
4574d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa    }
4575d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa
4576c873101a88e7ba584065de5e912508237378ca99Victoria Lease    @UiThreadTest
457772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testSetExtractedText() {
457872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
457972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
458072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView.getText().toString());
458172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
458272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedText et = new ExtractedText();
4583ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4584ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Update text and selection.
458572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        et.text = "test";
4586ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionStart = 0;
4587ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionEnd = 2;
458872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
458972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setExtractedText(et);
459072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("test", mTextView.getText().toString());
4591ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(0, mTextView.getSelectionStart());
4592ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, mTextView.getSelectionEnd());
4593ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4594ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Use partialStartOffset and partialEndOffset
4595ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialStartOffset = 2;
4596ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialEndOffset = 3;
4597ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.text = "x";
4598ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionStart = 2;
4599ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionEnd = 3;
4600ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4601ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        mTextView.setExtractedText(et);
4602ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("text", mTextView.getText().toString());
4603ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, mTextView.getSelectionStart());
4604ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, mTextView.getSelectionEnd());
4605ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4606ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Update text with spans.
4607ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final SpannableString ss = new SpannableString("ex");
4608ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        ss.setSpan(new UnderlineSpan(), 0, 2, 0);
4609ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        ss.setSpan(new URLSpan("ctstest://TextView/test"), 1, 2, 0);
4610ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4611ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.text = ss;
4612ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialStartOffset = 1;
4613ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialEndOffset = 3;
4614ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        mTextView.setExtractedText(et);
4615ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4616ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("text", mTextView.getText().toString());
4617ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final Editable editable = mTextView.getEditableText();
4618ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final UnderlineSpan[] underlineSpans = mTextView.getEditableText().getSpans(
4619ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi                0, editable.length(), UnderlineSpan.class);
4620ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, underlineSpans.length);
4621ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, editable.getSpanStart(underlineSpans[0]));
4622ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, editable.getSpanEnd(underlineSpans[0]));
4623ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4624ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final URLSpan[] urlSpans = mTextView.getEditableText().getSpans(
4625ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi                0, editable.length(), URLSpan.class);
4626ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, urlSpans.length);
4627ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, editable.getSpanStart(urlSpans[0]));
4628ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, editable.getSpanEnd(urlSpans[0]));
4629ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("ctstest://TextView/test", urlSpans[0].getURL());
463072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
463172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
463272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testMoveCursorToVisibleOffset() throws Throwable {
463372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
463472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
463572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // not a spannable text
463672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
463772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
463872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                assertFalse(mTextView.moveCursorToVisibleOffset());
463972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
464072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
464172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
464272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
464372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // a selection range
464472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        final String spannableText = "text";
464572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
464672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
464772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
464872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
464972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView.setText(spannableText, BufferType.SPANNABLE);
465072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
465172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
465272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
465372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        Selection.setSelection((Spannable) mTextView.getText(), 0, spannableText.length());
465472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
465572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, mTextView.getSelectionStart());
465672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(spannableText.length(), mTextView.getSelectionEnd());
465772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
465872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
465972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                assertFalse(mTextView.moveCursorToVisibleOffset());
466072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
466172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
466272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
466372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
466472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // a spannable without range
466572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
466672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
466772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView = findTextView(R.id.textview_text);
466872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView.setText(spannableText, BufferType.SPANNABLE);
466972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
467072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
467172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
467272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
467372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
467472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
467572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                assertTrue(mTextView.moveCursorToVisibleOffset());
467672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
467772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
467872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
467972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
468072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4681afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu    public void testIsInputMethodTarget() throws Throwable {
468272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
468372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.isInputMethodTarget());
468472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
468572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.isFocused());
4686afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        runTestOnUiThread(new Runnable() {
4687afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu           @Override
4688afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu            public void run() {
4689afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu               mTextView.setFocusable(true);
4690afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu               mTextView.requestFocus();
4691afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu            }
4692afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        });
4693afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        mInstrumentation.waitForIdleSync();
4694afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        assertTrue(mTextView.isFocused());
469504d12809ae731ea2aea678707bcc606f05efb23aBrian Muramatsu
4696354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> mTextView.isInputMethodTarget());
469772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
469872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
46996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
47006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testBeginEndBatchEditAreNotCalledForNonEditableText() {
4701b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        final TextView mockTextView = spy(new TextView(mActivity));
4702b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir
4703b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        // TextView should not call onBeginBatchEdit or onEndBatchEdit during initialization
4704b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onBeginBatchEdit();
4705b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onEndBatchEdit();
47066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
470772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
47086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.beginBatchEdit();
4709b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        // Since TextView doesn't support editing, the callbacks should not be called
4710b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onBeginBatchEdit();
4711b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onEndBatchEdit();
47126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.endBatchEdit();
4714b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        // Since TextView doesn't support editing, the callbacks should not be called
4715b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onBeginBatchEdit();
4716b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onEndBatchEdit();
47176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
47186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
47206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testBeginEndBatchEditCallbacksAreCalledForEditableText() {
4721b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        final TextView mockTextView = spy(new TextView(mActivity));
47226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(getActivity());
47246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
47256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
47266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
47276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(mockTextView, layoutParams);
47286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
47296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
4730b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        mActivity.runOnUiThread(() -> mActivity.setContentView(layout));
47316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
47326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
4733b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        mActivity.runOnUiThread(() -> {
4734b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir            mockTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
4735b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir            mockTextView.setText("", BufferType.EDITABLE);
4736b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir            mockTextView.requestFocus();
47376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
47386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
47396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
4740b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        reset(mockTextView);
47416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(mockTextView.hasFocus());
4742b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onBeginBatchEdit();
4743b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onEndBatchEdit();
47446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.beginBatchEdit();
47466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
4747b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, times(1)).onBeginBatchEdit();
4748b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onEndBatchEdit();
4749b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir
4750b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        reset(mockTextView);
47516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.endBatchEdit();
4752b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, never()).onBeginBatchEdit();
4753b0bae288153f4ac94e7b6fd83595acdedf1f1f6aSiyamed Sinir        verify(mockTextView, times(1)).onEndBatchEdit();
475472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
475572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
475672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
475772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testBringPointIntoView() throws Throwable {
475872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
475972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.bringPointIntoView(1));
476072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
476172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.layout(0, 0, 100, 100);
476272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.bringPointIntoView(2));
476372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
476472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
476572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testCancelLongPress() {
476672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
476772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        TouchUtils.longClickView(this, mTextView);
476872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.cancelLongPress();
476972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
477072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
477172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
477272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testClearComposingText() {
477372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
477472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setText("Hello world!", BufferType.SPANNABLE);
477572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        Spannable text = (Spannable) mTextView.getText();
477672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
477772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
477872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
477972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
478072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        BaseInputConnection.setComposingSpans((Spannable) mTextView.getText());
478172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, BaseInputConnection.getComposingSpanStart(text));
478272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, BaseInputConnection.getComposingSpanStart(text));
478372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
478472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.clearComposingText();
478572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
478672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
478772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
478872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
478972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testComputeVerticalScrollExtent() {
479072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        MockTextView textView = new MockTextView(mActivity);
479172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, textView.computeVerticalScrollExtent());
479272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4793a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        Drawable d = TestUtils.getDrawable(mActivity, R.drawable.pass);
479472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        textView.setCompoundDrawables(null, d, null, d);
479572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
479672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, textView.computeVerticalScrollExtent());
479772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
479872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
479972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
480072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testDidTouchFocusSelect() {
4801c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        mTextView = new EditText(mActivity);
480272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.didTouchFocusSelect());
480372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
480472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setFocusable(true);
480572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.requestFocus();
480672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.didTouchFocusSelect());
480772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
480872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
48090ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka    public void testSelectAllJustAfterTap() {
48100ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Prepare an EditText with focus.
48110ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mActivity.runOnUiThread(new Runnable() {
48120ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka            public void run() {
48130ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView = new EditText(mActivity);
48140ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mActivity.setContentView(mTextView);
48150ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48160ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                assertFalse(mTextView.didTouchFocusSelect());
48170ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView.setFocusable(true);
48180ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView.requestFocus();
48190ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                assertTrue(mTextView.didTouchFocusSelect());
48200ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48210ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView.setText("Hello, World.", BufferType.SPANNABLE);
48220ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka            }
48230ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        });
48240ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mInstrumentation.waitForIdleSync();
48250ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48260ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Tap the view to show InsertPointController.
48270ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        TouchUtils.tapView(this, mTextView);
482883a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        // bad workaround for waiting onStartInputView of LeanbackIme.apk done
482983a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        try {
483083a70cb57c839148a4feff786cdbb3803828d484Bobby Wang            Thread.sleep(1000);
483183a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        } catch (InterruptedException e) {
483283a70cb57c839148a4feff786cdbb3803828d484Bobby Wang            e.printStackTrace();
483383a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        }
48340ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48350ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Execute SelectAll context menu.
48360ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mActivity.runOnUiThread(new Runnable() {
48370ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka            public void run() {
48380ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView.onTextContextMenuItem(android.R.id.selectAll);
48390ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka            }
48400ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        });
48410ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mInstrumentation.waitForIdleSync();
48420ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48430ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // The selection must be whole of the text contents.
48440ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        assertEquals(0, mTextView.getSelectionStart());
484583a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        assertEquals("Hello, World.", mTextView.getText().toString());
48460ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        assertEquals(mTextView.length(), mTextView.getSelectionEnd());
48470ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka    }
48480ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
484972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testExtractText() {
485072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
485172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
485272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedTextRequest request = new ExtractedTextRequest();
485372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedText outText = new ExtractedText();
485472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
485572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.token = 0;
485672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.flags = 10;
485772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.hintMaxLines = 2;
485872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.hintMaxChars = 20;
485972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.extractText(request, outText));
486072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
486172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
486272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.extractText(request, outText));
486372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
486472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
486572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                outText.text.toString());
4866c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi
4867c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        // Tests for invalid arguments.
4868c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(request, null));
4869c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(null, outText));
4870c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(null, null));
487172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
487272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
487394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
487494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testTextDirectionDefault() {
4875c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
48762a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection());
487794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
487894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
487994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
488094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testSetGetTextDirection() {
4881c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
488294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
488394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
48842a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getRawTextDirection());
488594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
488694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
48872a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getRawTextDirection());
488894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
488994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
48902a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection());
489194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
489294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
48932a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getRawTextDirection());
489494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
489594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
48962a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getRawTextDirection());
489794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
489894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
48992a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getRawTextDirection());
490002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
490102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
490202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getRawTextDirection());
490302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
490402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
490502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getRawTextDirection());
490694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
490794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
490894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
490994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionLtr() {
4910c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
491194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("this is a test");
491294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
49132a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
491494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
491594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
49162a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
491794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
491894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
49192a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
492094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
492194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
49222a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
492394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
492494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
49252a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
492694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
492794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
49282a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
492994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
493094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
49312a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
493202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
493302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
493402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
493502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
493602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
493702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
493894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
493994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
494094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
494194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionLtrWithInheritance() {
4942c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = new LinearLayout(mActivity);
494394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
494494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
4945c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
494694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("this is a test");
494794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.addView(tv);
494894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
494994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
49502a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
495194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
495294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
49532a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
495494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
495594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
49562a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
495794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
495894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
49592a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
496094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
496194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
49622a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
496394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
496494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
49652a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
496602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
496702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
496802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
496902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
497002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
497102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
497294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
497394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
497494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
497594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionRtl() {
4976c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
497794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("\u05DD\u05DE"); // hebrew
497894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
49792a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
498094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
498194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
49822a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
498394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
498494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
49852a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
498694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
498794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
49882a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
498994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
499094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
49912a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
499294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
499394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
49942a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
499594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
499694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
49972a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
499802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
499902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
500002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
500102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
500202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
500302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
500494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
500594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
500694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
500794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionRtlWithInheritance() {
5008c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = new LinearLayout(mActivity);
500994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
501094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
5011c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
501294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("\u05DD\u05DE"); // hebrew
501394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.addView(tv);
501494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50162a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
501794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
50192a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
502094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
502194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50222a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
502394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
502494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
50252a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
502694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
502794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
50282a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
502994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
503094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
50312a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
503294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
503302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
503402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
503502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
503602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
503702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
503802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
503994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        // Force to RTL text direction on the layout
504094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
504194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50432a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
504494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
50462a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
504794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50492a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
505094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
505194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
50522a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
505394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
505494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
50552a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
505694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
505794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
50582a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
505902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
506002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
506102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
506202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
506302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
506402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
506594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
506694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
506794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
506894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testResetTextDirection() {
5069c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest);
5070c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = (TextView) mActivity.findViewById(R.id.textview_rtl);
507194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
507294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
507394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50742a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
507594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
5076f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        // No reset when we remove the view
507794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.removeView(tv);
5078f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
5079f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio
5080f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        // Reset is done when we add the view
5081f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        ll.addView(tv);
50822a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
508394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
508494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
508502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    @UiThreadTest
508602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    public void testTextDirectionFirstStrongLtr() {
508702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
508802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is LTR, the paragraph direction is LTR.
508902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
509002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
509102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
509202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("this is a test");
509302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
509402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
509502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
509602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
509702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
509802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
509902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
510002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
510102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
510202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
510302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is RTL, the paragraph direction is RTL.
510402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
510502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
510602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
510702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\u05DD\u05DE"); // Hebrew
510802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
510902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
511002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
511102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
511202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
511302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
511402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
511502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
511602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
511702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
511802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is not a strong directional character, the paragraph
511902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // direction is LTR.
512002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
512102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
512202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
512302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\uFFFD");  // REPLACEMENT CHARACTER. Neutral direction.
512402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
512502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
512602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
512702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
512802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
512902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
513002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
513102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
513202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
513302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    }
513402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
513502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    @UiThreadTest
513602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    public void testTextDirectionFirstStrongRtl() {
513702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
513802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is LTR, the paragraph direction is LTR.
513902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
514002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
514102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
514202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("this is a test");
514302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
514402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
514502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
514602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
514702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
514802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
514902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
515002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
515102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
515202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
515302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is RTL, the paragraph direction is RTL.
515402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
515502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
515602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
515702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\u05DD\u05DE"); // Hebrew
515802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
515902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
516002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
516102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
516202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
516302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
516402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
516502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
516602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
516702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
516802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is not a strong directional character, the paragraph
516902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // direction is RTL.
517002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
517102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
517202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
517302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\uFFFD");  // REPLACEMENT CHARACTER. Neutral direction.
517402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
517502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
517602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
517702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
517802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
517902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
518002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
518102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
518202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
518302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    }
518402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
5185c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader    public void testTextLocales() {
5186c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        TextView tv = new TextView(mActivity);
5187c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.getDefault(), tv.getTextLocale());
5188c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(LocaleList.getDefault(), tv.getTextLocales());
5189c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5190c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        tv.setTextLocale(Locale.CHINESE);
5191c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.CHINESE, tv.getTextLocale());
5192c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(new LocaleList(Locale.CHINESE), tv.getTextLocales());
5193c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5194c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        tv.setTextLocales(LocaleList.forLanguageTags("en,ja"));
5195c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.forLanguageTag("en"), tv.getTextLocale());
5196c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(LocaleList.forLanguageTags("en,ja"), tv.getTextLocales());
5197c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5198c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5199c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocale(null);
5200c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locale to null should throw");
5201c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5202c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5203c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5204c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5205c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5206c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocales(null);
5207c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locales to null should throw");
5208c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5209c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5210c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5211c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5212c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5213c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocales(new LocaleList());
5214c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locale to an empty list should throw");
5215c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5216c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5217c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5218c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader    }
5219c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5220b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka    public void testAllCapsLocalization() {
5221b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        String testString = "abcdefghijklmnopqrstuvwxyz";
5222b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5223b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        // The capitalized characters of "i" on Turkish and Azerbaijani are different from English.
5224b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        Locale[] testLocales = {
5225b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("az", "AZ"),
5226b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("tr", "TR"),
5227b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("en", "US"),
5228b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        };
5229b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5230b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        TextView tv = new TextView(mActivity);
5231b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        tv.setAllCaps(true);
5232b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        for (Locale locale: testLocales) {
5233b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            tv.setTextLocale(locale);
5234b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            assertEquals("Locale: " + locale.getDisplayName(),
5235b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka                         testString.toUpperCase(locale),
5236b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka                         tv.getTransformationMethod().getTransformation(testString, tv).toString());
5237b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        }
5238b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka    }
5239b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5240dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5241dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testTextAlignmentDefault() {
5242dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = new TextView(getActivity());
52437fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5244dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // resolved default text alignment is GRAVITY
52457fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5246dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5247dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5248dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5249dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testSetGetTextAlignment() {
5250dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = new TextView(getActivity());
5251dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5252dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
52537fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5254dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5255dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
52567fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getRawTextAlignment());
5257dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5258dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
52597fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getRawTextAlignment());
5260dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5261dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
52627fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getRawTextAlignment());
5263dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5264dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
52657fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getRawTextAlignment());
5266dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5267dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
52687fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getRawTextAlignment());
5269dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5270dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5271dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5272dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testGetResolvedTextAlignment() {
5273dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = new TextView(getActivity());
5274dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
52757fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5276dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5277757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        // Test center alignment first so that we dont hit the default case
5278dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
52797fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5280dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5281757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        // Test the default case too
5282757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
5283757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5284757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio
5285dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
52867fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
5287dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5288dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
52897fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
5290dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5291dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
52927fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
5293dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5294dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
52957fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
5296dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5297dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5298dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5299dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testGetResolvedTextAlignmentWithInheritance() {
5300dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        LinearLayout ll = new LinearLayout(getActivity());
5301dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
5302dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5303dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = new TextView(getActivity());
5304dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.addView(tv);
5305dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5306dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // check defaults
53077fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5308dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5309dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5310dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // set inherit and check that child is following parent
5311dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
53127fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_INHERIT, tv.getRawTextAlignment());
5313dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5314dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
53157fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5316dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5317dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
53187fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
5319dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5320dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
53217fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
5322dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5323dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
53247fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
5325dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5326dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
53277fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
5328dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5329dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // now get rid of the inheritance but still change the parent
5330dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
5331dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5332dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
53337fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5334dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5335dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
53367fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5337dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5338dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
53397fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5340dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5341dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
53427fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5343dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5344dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
53457fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5346dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5347dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5348dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5349dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testResetTextAlignment() {
53504ca04c0729a0e810b5af16edcd52bb8cb59bf55eChenjie Luo        TextViewCtsActivity activity = getActivity();
5351dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5352dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        LinearLayout ll = (LinearLayout) activity.findViewById(R.id.layout_textviewtest);
5353dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = (TextView) activity.findViewById(R.id.textview_rtl);
5354dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5355dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
5356dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
53577fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5358dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
53594f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // No reset when we remove the view
5360dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.removeView(tv);
53614f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
53624f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio
53634f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // Reset is done when we add the view
53644f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // Default text alignment is GRAVITY
53654f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        ll.addView(tv);
53667fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5367dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5368dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5369938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    @UiThreadTest
5370938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    public void testDrawableResolution() {
5371b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 1.1: left / right drawable defined in default LTR mode
5372938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        TextView tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_1);
5373a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5374938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5375a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, -1, -1,
5376938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5377b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5378b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 1.2: left / right drawable defined in default RTL mode
5379938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_2);
5380a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5381938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5382a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, -1, -1,
5383938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5384b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5385b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 2.1: start / end drawable defined in LTR mode
5386938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_2_1);
5387a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5388938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5389a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5390938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5391b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5392b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 2.2: start / end drawable defined in RTL mode
5393938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_2_2);
5394a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5395938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5396a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5397938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5398b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5399b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 3.1: left / right / start / end drawable defined in LTR mode
5400938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_3_1);
5401a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5402938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5403a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5404938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5405b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5406b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 3.2: left / right / start / end drawable defined in RTL mode
5407938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_3_2);
5408a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5409938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5410a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5411938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5412b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5413b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 4.1: start / end drawable defined in LTR mode inside a layout
5414b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5415938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_4_1);
5416a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5417938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5418a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5419938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5420b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5421b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 4.2: start / end drawable defined in RTL mode inside a layout
5422b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5423938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_4_2);
5424a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5425938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5426a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5427938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5428b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5429b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 5.1: left / right / start / end drawable defined in LTR mode inside a layout
5430b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5431938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_5_1);
5432a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5433938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5434a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5435938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5436b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5437b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 5.2: left / right / start / end drawable defined in RTL mode inside a layout
5438b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5439938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_5_2);
5440a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5441938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5442a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5443938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5444b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio    }
5445b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
54469776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    @UiThreadTest
54479776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    public void testDrawableResolution2() {
54489776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        // Case 1.1: left / right drawable defined in default LTR mode
5449938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        TextView tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_1);
5450a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5451938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
54529776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5453a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        tv.setCompoundDrawables(null, null,
5454a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov                TestUtils.getDrawable(mActivity, R.drawable.icon_yellow), null);
5455a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, -1, R.drawable.icon_yellow, -1, -1);
54569776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5457938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_2);
5458a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5459938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
54609776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5461a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        tv.setCompoundDrawables(TestUtils.getDrawable(mActivity, R.drawable.icon_yellow), null,
5462a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov                null, null);
5463a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_yellow, -1, -1, -1);
54649776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5465938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_ltr);
5466a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, -1, -1, -1, -1);
54679776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5468a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        tv.setCompoundDrawables(TestUtils.getDrawable(mActivity, R.drawable.icon_blue), null,
5469a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov                TestUtils.getDrawable(mActivity, R.drawable.icon_red), null);
5470a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red, -1, -1);
54719776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5472a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        tv.setCompoundDrawablesRelative(TestUtils.getDrawable(mActivity, R.drawable.icon_yellow),
5473a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov                null, null, null);
5474a82283fc3d03aadf14baa7e731bd43ab744e732aKirill Grouchnikov        TestUtils.verifyCompoundDrawables(tv, R.drawable.icon_yellow, -1, -1, -1);
5475938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    }
5476938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5477938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    public void testCompoundAndTotalPadding() {
5478938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final Resources res = mActivity.getResources();
5479938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int drawablePadding = res.getDimensionPixelSize(R.dimen.textview_drawable_padding);
5480938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingLeft = res.getDimensionPixelSize(R.dimen.textview_padding_left);
5481938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingRight = res.getDimensionPixelSize(R.dimen.textview_padding_right);
5482938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingTop = res.getDimensionPixelSize(R.dimen.textview_padding_top);
5483938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingBottom = res.getDimensionPixelSize(R.dimen.textview_padding_bottom);
5484938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int iconSize = TestUtils.dpToPx(mActivity, 32);
5485938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5486938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final TextView textViewLtr = (TextView) mActivity.findViewById(
5487938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.id.textview_compound_drawable_ltr);
5488938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingLeftLtr = paddingLeft + drawablePadding + iconSize;
5489938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingRightLtr = paddingRight + drawablePadding + iconSize;
5490938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getCompoundPaddingLeft());
5491938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getCompoundPaddingStart());
5492938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getTotalPaddingLeft());
5493938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getTotalPaddingStart());
5494938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getCompoundPaddingRight());
5495938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getCompoundPaddingEnd());
5496938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getTotalPaddingRight());
5497938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getTotalPaddingEnd());
5498938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingTop + drawablePadding + iconSize,
5499938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewLtr.getCompoundPaddingTop());
5500938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingBottom + drawablePadding + iconSize,
5501938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewLtr.getCompoundPaddingBottom());
5502938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5503938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final TextView textViewRtl = (TextView) mActivity.findViewById(
5504938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.id.textview_compound_drawable_rtl);
5505938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingLeftRtl = paddingLeft + drawablePadding + iconSize;
5506938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingRightRtl = paddingRight + drawablePadding + iconSize;
5507938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getCompoundPaddingLeft());
5508938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getCompoundPaddingEnd());
5509938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getTotalPaddingLeft());
5510938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getTotalPaddingEnd());
5511938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getCompoundPaddingRight());
5512938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getCompoundPaddingStart());
5513938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getTotalPaddingRight());
5514938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getTotalPaddingStart());
5515938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingTop + drawablePadding + iconSize,
5516938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewRtl.getCompoundPaddingTop());
5517938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingBottom + drawablePadding + iconSize,
5518938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewRtl.getCompoundPaddingBottom());
55199776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    }
55209776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5521e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    public void testSetGetBreakStrategy() {
5522e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        TextView tv = new TextView(mActivity);
5523e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
55242751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        final PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
55252751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka
5526d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // The default value is from the theme, here the default is BREAK_STRATEGY_HIGH_QUALITY for
55272751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        // TextView except for Android Wear. The default value for Android Wear is
55282751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        // BREAK_STRATEGY_BALANCED.
55292751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        if (pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
55302751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            // Android Wear
55312751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy());
55322751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        } else {
55332751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            // All other form factor.
55342751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy());
55352751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        }
5536e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5537e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
5538e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, tv.getBreakStrategy());
5539e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5540e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
5541e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy());
5542e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5543e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED);
5544e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy());
5545d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5546d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        EditText et = new EditText(mActivity);
5547d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5548d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // The default value is from the theme, here the default is BREAK_STRATEGY_SIMPLE for
5549d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // EditText.
5550d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy());
5551d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5552d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
5553d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy());
5554d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5555d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
5556d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, et.getBreakStrategy());
5557d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5558d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED);
5559d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_BALANCED, et.getBreakStrategy());
5560e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    }
5561e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5562e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    public void testSetGetHyphenationFrequency() {
5563e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        TextView tv = new TextView(mActivity);
5564e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5565d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency());
5566e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5567e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
5568e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, tv.getHyphenationFrequency());
5569e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5570e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL);
5571e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency());
5572e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5573e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
5574e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_FULL, tv.getHyphenationFrequency());
5575e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    }
5576e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
557732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi    public void testSetAndGetCustomSelectionActionModeCallback() {
557832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        final String text = "abcde";
557932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
558032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
558132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView = new EditText(mActivity);
558232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mActivity.setContentView(mTextView);
558332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.setText(text, BufferType.SPANNABLE);
558432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.setTextIsSelectable(true);
558532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.requestFocus();
558632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.setSelected(true);
558732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
558832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
558932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
559032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
559132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Check default value.
559232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        assertNull(mTextView.getCustomSelectionActionModeCallback());
559332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
559498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final ActionMode.Callback mockActionModeCallback = mock(ActionMode.Callback.class);
559598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
559698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.FALSE);
559798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setCustomSelectionActionModeCallback(mockActionModeCallback);
559898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback,
559932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.getCustomSelectionActionModeCallback());
560032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
560132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
560232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
560332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                // Set selection and try to start action mode.
560432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                final Bundle args = new Bundle();
560532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
560632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
56078e92940803ad8d05bfeecdd6ef3abfe803c5a782Alan Viverette                mTextView.performAccessibilityAction(
560832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                        AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
560932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
561032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
561132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
561232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
561398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onCreateActionMode(
561498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                any(ActionMode.class), any(Menu.class));
561532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
561632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
561732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
561832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                // Remove selection and stop action mode.
561932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.copy);
562032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
562132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
562232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
562332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
562432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Action mode was blocked.
562598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, never()).onDestroyActionMode(any(ActionMode.class));
562632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
562798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        // Reset and reconfigure callback.
562898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockActionModeCallback);
562998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
563098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.TRUE);
563198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback, mTextView.getCustomSelectionActionModeCallback());
563232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
563332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
563432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
563532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                // Set selection and try to start action mode.
563632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                final Bundle args = new Bundle();
563732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
563832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
56398e92940803ad8d05bfeecdd6ef3abfe803c5a782Alan Viverette                mTextView.performAccessibilityAction(
564032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                        AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
564132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
564232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
564332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
564432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
564532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
564698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onCreateActionMode(
564798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                any(ActionMode.class), any(Menu.class));
564832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
564932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
565032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
565132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                // Remove selection and stop action mode.
565232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.copy);
565332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
565432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
565532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
565632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
565732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Action mode was started
565898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onDestroyActionMode(any(ActionMode.class));
565932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi    }
566032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
566198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testSetAndGetCustomInsertionActionMode() {
566232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        initTextViewForTyping();
566332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Check default value.
566432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        assertNull(mTextView.getCustomInsertionActionModeCallback());
566532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
566698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final ActionMode.Callback mockActionModeCallback = mock(ActionMode.Callback.class);
566798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
566898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.FALSE);
566998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setCustomInsertionActionModeCallback(mockActionModeCallback);
567098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback, mTextView.getCustomInsertionActionModeCallback());
567132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // TODO(Bug: 22033189): Tests the set callback is actually used.
567232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi    }
567332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
567498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testTextShadows() {
567598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView textViewWithConfiguredShadow =
567698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                (TextView) mActivity.findViewById(R.id.textview_with_shadow);
567798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(1.0f, textViewWithConfiguredShadow.getShadowDx());
567898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(2.0f, textViewWithConfiguredShadow.getShadowDy());
567998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(3.0f, textViewWithConfiguredShadow.getShadowRadius());
568098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(Color.GREEN, textViewWithConfiguredShadow.getShadowColor());
568132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
568298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
568398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(0.0f, textView.getShadowDx());
568498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(0.0f, textView.getShadowDy());
568598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(0.0f, textView.getShadowRadius());
568632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
568798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setShadowLayer(5.0f, 3.0f, 4.0f, Color.RED));
568898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mInstrumentation.waitForIdleSync();
568998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(3.0f, textView.getShadowDx());
569098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(4.0f, textView.getShadowDy());
569198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(5.0f, textView.getShadowRadius());
569298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(Color.RED, textView.getShadowColor());
569372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
569472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
5695354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testFontFeatureSettings() {
5696354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
5697354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.isEmpty(textView.getFontFeatureSettings()));
5698354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5699354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setFontFeatureSettings("smcp"));
5700354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5701354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals("smcp", textView.getFontFeatureSettings());
5702354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5703354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setFontFeatureSettings("frac"));
5704354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5705354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals("frac", textView.getFontFeatureSettings());
5706354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5707354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5708354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    private static class SoftInputResultReceiver extends ResultReceiver {
5709354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        private boolean mIsDone;
5710354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        private int mResultCode;
5711354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5712354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        public SoftInputResultReceiver(Handler handler) {
5713354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            super(handler);
5714354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5715354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5716354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        @Override
5717354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        protected void onReceiveResult(int resultCode, Bundle resultData) {
5718354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mResultCode = resultCode;
5719354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mIsDone = true;
5720354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5721354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5722354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        public void reset() {
5723354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mIsDone = false;
5724354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5725354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5726354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5727354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testAccessShowSoftInputOnFocus() {
5728354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        if (!mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)) {
5729354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            return;
5730354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5731354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5732354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Scroll down to our EditText
5733354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final ScrollView scrollView = (ScrollView) mActivity.findViewById(R.id.scroller);
5734354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mTextView = findTextView(R.id.editview_text);
5735354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> scrollView.fullScroll(View.FOCUS_DOWN));
5736354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5737354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5738354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Mark it to show soft input on focus
5739354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> mTextView.setShowSoftInputOnFocus(true));
5740354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5741354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.getShowSoftInputOnFocus());
5742354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5743354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // And emulate click on it
5744354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        TouchUtils.clickView(this, mTextView);
5745354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5746354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Verify that input method manager is active and accepting text
5747354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final InputMethodManager imManager = (InputMethodManager) mActivity
5748354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov                .getSystemService(Context.INPUT_METHOD_SERVICE);
5749354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> imManager.isActive());
5750354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(imManager.isAcceptingText());
5751354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(imManager.isActive(mTextView));
5752354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5753354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Since there is no API to check that soft input is showing, we're going to ask
5754354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // the input method manager to show soft input, passing our custom result receiver.
5755354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // We're expecting to get UNCHANGED_SHOWN, indicating that the soft input was already
5756354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // showing before showSoftInput was called.
5757354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        SoftInputResultReceiver receiver = new SoftInputResultReceiver(mHandler);
5758354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        imManager.showSoftInput(mTextView, 0, receiver);
5759354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> receiver.mIsDone);
5760354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(InputMethodManager.RESULT_UNCHANGED_SHOWN, receiver.mResultCode);
5761354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5762354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Close soft input
5763354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        sendKeys(KeyEvent.KEYCODE_BACK);
5764354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5765354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Reconfigure our edit text to not show soft input on focus
5766354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> mTextView.setShowSoftInputOnFocus(false));
5767354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5768354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.getShowSoftInputOnFocus());
5769354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5770354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Emulate click on it
5771354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        TouchUtils.clickView(this, mTextView);
5772354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5773354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Ask input method manager to show soft input again. This time we're expecting to get
5774354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // SHOWN, indicating that the soft input was not showing before showSoftInput was called.
5775354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        receiver.reset();
5776354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        imManager.showSoftInput(mTextView, 0, receiver);
5777354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> receiver.mIsDone);
5778354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(InputMethodManager.RESULT_SHOWN, receiver.mResultCode);
5779354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5780354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Close soft input
5781354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        sendKeys(KeyEvent.KEYCODE_BACK);
5782354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5783354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
578441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    public void testIsSuggestionsEnabled() {
578541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
578641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
578741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Anything without InputType.TYPE_CLASS_TEXT doesn't have suggestions enabled
578841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(() -> mTextView.setInputType(InputType.TYPE_CLASS_DATETIME));
578941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
579041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
579141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(() -> mTextView.setInputType(InputType.TYPE_CLASS_PHONE));
579241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
579341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
579441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(() -> mTextView.setInputType(InputType.TYPE_CLASS_NUMBER));
579541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
579641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
579741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // From this point our text view has InputType.TYPE_CLASS_TEXT
579841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
579941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Anything with InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS doesn't have suggestions enabled
580041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
580141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
580241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
580341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
580441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
580541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
580641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
580741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL |
580841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
580941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
581041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
581141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
581241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
581341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS |
581441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
581541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
581641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
581741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Otherwise suggestions are enabled for specific type variations enumerated in the
581841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // documentation of TextView.isSuggestionsEnabled
581941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
582041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
582141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL));
582241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
582341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
582441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
582541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
582641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT));
582741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
582841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
582941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
583041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
583141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE));
583241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
583341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
583441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
583541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
583641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE));
583741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
583841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
583941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
584041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
584141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT));
584241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
584341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
584441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // and not on any other type variation
584541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
584641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
584741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS));
584841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
584941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
585041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
585141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
585241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_FILTER));
585341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
585441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
585541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
585641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
585741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD));
585841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
585941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
586041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
586141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
586241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PERSON_NAME));
586341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
586441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
586541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
586641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
586741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PHONETIC));
586841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
586941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
587041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
587141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
587241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS));
587341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
587441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
587541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
587641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
587741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI));
587841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
587941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
588041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
588141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
588241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT |
588341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD));
588441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
588541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
588641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
588741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
588841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT |
588941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS));
589041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
589141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
589241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
589341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
589441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD));
589541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
589641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
589741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
589841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    public void testAccessLetterSpacing() {
589941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
590041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals(0.0f, mTextView.getLetterSpacing());
590141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
590241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final CharSequence text = mTextView.getText();
590341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int textLength = text.length();
590441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
590541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at the default letter spacing
590641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] initialWidths = new float[textLength];
590741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), initialWidths);
590841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
590941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at letter spacing = 1.0f
591041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mTextView,
591141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setLetterSpacing(1.0f));
591241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals(1.0f, mTextView.getLetterSpacing());
591341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] singleWidths = new float[textLength];
591441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), singleWidths);
591541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
591641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at letter spacing = 2.0f
591741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mTextView,
591841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setLetterSpacing(2.0f));
591941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals(2.0f, mTextView.getLetterSpacing());
592041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] doubleWidths = new float[textLength];
592141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), doubleWidths);
592241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
592341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Since letter spacing setter treats the parameter as EM units, and we don't have
592441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // a way to convert EMs into pixels, go over the three arrays of advance widths and
592541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // test that the extra advance width at letter spacing 2.0f is double the extra
592641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // advance width at letter spacing 1.0f.
592741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        for (int i = 0; i < textLength; i++) {
592841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            float singleWidthDelta = singleWidths[i] - initialWidths[i];
592941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            float doubleWidthDelta = doubleWidths[i] - initialWidths[i];
593041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            assertEquals("At index " + i + " initial is " + initialWidths[i] +
593141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                ", single is " + singleWidths[i] + " and double is " + doubleWidths[i],
593241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                    singleWidthDelta * 2.0f, doubleWidthDelta, 0.05f);
593341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        }
593441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
593541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
5936288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu    public void testTextIsSelectableFocusAndOnClick() {
5937288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        // Prepare a focusable TextView with an onClickListener attached.
5938288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        final View.OnClickListener mockOnClickListener = mock(View.OnClickListener.class);
5939288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        mActivity.runOnUiThread(() -> {
5940288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mTextView = new TextView(mActivity);
5941288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mTextView.setText("...zekiel 25:17. The path of the righteous...");
5942288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mTextView.setFocusable(true);
5943288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mTextView.setOnClickListener(mockOnClickListener);
5944288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu            mActivity.setContentView(mTextView);
5945288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        });
5946288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
5947288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocusable());
5948288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isTextSelectable());
5949288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocusableInTouchMode());
5950288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocused());
5951288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isInTouchMode());
5952288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu
5953288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        // First tap on the view triggers onClick() but does not focus the TextView.
5954288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        ViewTestUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
5955288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isInTouchMode());
5956288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocused());
5957288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        verify(mockOnClickListener, times(1)).onClick(mTextView);
5958288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        // So does the second tap.
5959288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        reset(mockOnClickListener);
5960288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        ViewTestUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
5961288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isInTouchMode());
5962288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocused());
5963288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        verify(mockOnClickListener, times(1)).onClick(mTextView);
5964288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu
5965288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        mActivity.runOnUiThread(() -> mTextView.setTextIsSelectable(true));
5966288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        mInstrumentation.waitForIdleSync();
5967288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocusable());
5968288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isTextSelectable());
5969288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocusableInTouchMode());
5970288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertFalse(mTextView.isFocused());
5971288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu
5972288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        // First tap on the view focuses the TextView but does not trigger onClick().
5973288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        reset(mockOnClickListener);
5974288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        ViewTestUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
5975288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isInTouchMode());
5976288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocused());
5977288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        verify(mockOnClickListener, never()).onClick(mTextView);
5978288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        // The second tap triggers onClick() and keeps the focus.
5979288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        reset(mockOnClickListener);
5980288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        ViewTestUtils.emulateTapOnViewCenter(mInstrumentation, mTextView);
5981288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isInTouchMode());
5982288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        assertTrue(mTextView.isFocused());
5983288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu        verify(mockOnClickListener, times(1)).onClick(mTextView);
5984288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu    }
5985288d156a90ddd9dd93c05e4892a73390e3778c00Andrei Stingaceanu
598641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    private void verifyGetOffsetForPosition(final int x, final int y) {
598741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int actual = mTextView.getOffsetForPosition(x, y);
598841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
598941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final Layout layout = mTextView.getLayout();
599041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        if (layout == null) {
599141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            assertEquals("For [" + x + ", " + y + "]", -1, actual);
599241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            return;
599341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        }
599441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
599541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get the line which corresponds to the Y position
599641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int line = layout.getLineForVertical(y + mTextView.getScrollY());
599741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get the offset in that line that corresponds to the X position
599841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int expected = layout.getOffsetForHorizontal(line, x + mTextView.getScrollX());
599941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals("For [" + x + ", " + y + "]", expected, actual);
600041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
600141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
600241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    public void testGetOffsetForPosition() {
600341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
600441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mTextView, () -> {
600541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            mTextView.setText(LONG_TEXT);
600641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            mTextView.setPadding(0, 0, 0, 0);
600741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        });
600841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
600941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertNotNull(mTextView.getLayout());
601041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int viewWidth = mTextView.getWidth();
601141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int viewHeight = mTextView.getHeight();
601241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int lineHeight = mTextView.getLineHeight();
601341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
601441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(0, 0);
601541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(0, viewHeight / 2);
601641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth / 3, lineHeight / 2);
601741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth / 2, viewHeight / 2);
601841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth, viewHeight);
601941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
602041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
6021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void layout(final TextView textView) {
6022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6023fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mActivity.setContentView(textView);
6025fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6028fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void layout(final int layoutId) {
6031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mActivity.setContentView(layoutId);
6034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6038fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6039fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private TextView findTextView(int id) {
6040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        return (TextView) mActivity.findViewById(id);
6041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6043fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private int getAutoLinkMask(int id) {
6044fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        return findTextView(id).getAutoLinkMask();
6045fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
60476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    private void setMaxLines(final int lines) {
60486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
60496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
60506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mTextView.setMaxLines(lines);
60516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
60526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
60536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
60546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
60556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
6056fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMaxWidth(final int pixels) {
6057fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6058fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6059fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMaxWidth(pixels);
6060fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6062fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6063fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6064fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6065fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMinWidth(final int pixels) {
6066fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6067fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6068fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMinWidth(pixels);
6069fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6070fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6071fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6072fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6073fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6074fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMaxHeight(final int pixels) {
6075fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6076fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6077fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMaxHeight(pixels);
6078fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6079fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6080fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6081fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6082fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6083fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMinHeight(final int pixels) {
6084fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6085fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6086fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMinHeight(pixels);
6087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6091fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6092fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMinLines(final int minlines) {
6093fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6094fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6095fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMinLines(minlines);
6096fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6097fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6098fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6099fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6100fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6101fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    /**
6102fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * Convenience for {@link TextView#setText(CharSequence, BufferType)}. And
6103fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * the buffer type is fixed to SPANNABLE.
6104fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     *
6105fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * @param tv the text view
6106fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * @param content the content
6107fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     */
6108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setSpannableText(final TextView tv, final String content) {
6109fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6110fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6111fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                tv.setText(content, BufferType.SPANNABLE);
6112fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6114fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6116fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6117fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setLines(final int lines) {
6118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6119fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setLines(lines);
6121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6123fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setHorizontallyScrolling(final boolean whether) {
6127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setHorizontallyScrolling(whether);
6130fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6131fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6132fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6134fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6135fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setWidth(final int pixels) {
6136fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6138fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setWidth(pixels);
6139fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6140fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setHeight(final int pixels) {
6145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6146fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setHeight(pixels);
6148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMinEms(final int ems) {
6154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6155fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6156fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMinEms(ems);
6157fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMaxEms(final int ems) {
6163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMaxEms(ems);
6166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setEms(final int ems) {
6172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setEms(ems);
6175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6176fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6178fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6179fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setLineSpacing(final float add, final float mult) {
6181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6183fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setLineSpacing(add, mult);
6184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6185fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static abstract class TestSelectedRunnable implements Runnable {
6190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private TextView mTextView;
6191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mIsSelected1;
6192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mIsSelected2;
6193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6194fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public TestSelectedRunnable(TextView textview) {
6195fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView = textview;
6196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean getIsSelected1() {
6199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mIsSelected1;
6200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean getIsSelected2() {
6203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mIsSelected2;
6204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveIsSelected1() {
6207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mIsSelected1 = mTextView.isSelected();
6208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6209fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6210fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveIsSelected2() {
6211fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mIsSelected2 = mTextView.isSelected();
6212fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static abstract class TestLayoutRunnable implements Runnable {
6216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private TextView mTextView;
6217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private Layout mLayout;
6218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public TestLayoutRunnable(TextView textview) {
6220fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView = textview;
6221fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6222fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public Layout getLayout() {
6224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mLayout;
6225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6227fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveLayout() {
6228fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mLayout = mTextView.getLayout();
6229fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6230fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static class MockTextWatcher implements TextWatcher {
6233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasCalledAfterTextChanged;
6234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasCalledBeforeTextChanged;
6235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasOnTextChanged;
6236fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void reset(){
6238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledAfterTextChanged = false;
6239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledBeforeTextChanged = false;
6240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasOnTextChanged = false;
6241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledAfterTextChanged() {
6244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasCalledAfterTextChanged;
6245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledBeforeTextChanged() {
6248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasCalledBeforeTextChanged;
6249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledOnTextChanged() {
6252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasOnTextChanged;
6253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void afterTextChanged(Editable s) {
6256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledAfterTextChanged = true;
6257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
6260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledBeforeTextChanged = true;
6261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void onTextChanged(CharSequence s, int start, int before, int count) {
6264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasOnTextChanged = true;
6265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    /**
6269277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook     * A TextWatcher that converts the text to spaces whenever the text changes.
6270277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook     */
6271277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    private static class ConvertToSpacesTextWatcher implements TextWatcher {
6272277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        boolean mChangingText;
6273277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
6274277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
6275277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
6276277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
6277277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
6278277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
6279277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void onTextChanged(CharSequence s, int start, int before, int count) {
6280277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
6281277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
6282277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
6283277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void afterTextChanged(Editable s) {
6284277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            // Avoid infinite recursion.
6285277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            if (mChangingText) {
6286277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                return;
6287277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
6288277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            mChangingText = true;
6289277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            // Create a string of s.length() spaces.
6290277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            StringBuilder builder = new StringBuilder(s.length());
6291277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            for (int i = 0; i < s.length(); i++) {
6292277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                builder.append(' ');
6293277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
6294277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            s.replace(0, s.length(), builder.toString());
6295277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            mChangingText = false;
6296277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
6297277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
6298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su}
6299