TextViewTest.java revision 41b3e249a7d16d5b58a079f64ed9d769393391b6
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
19938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport android.annotation.IdRes;
20938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport android.annotation.NonNull;
21fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Activity;
22fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Instrumentation;
23fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.app.Instrumentation.ActivityMonitor;
24354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.content.Context;
25fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.Intent;
262751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonakaimport android.content.pm.PackageManager;
27fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.res.ColorStateList;
28938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport android.content.res.Resources;
29fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.content.res.Resources.NotFoundException;
305bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinirimport android.cts.util.KeyEventUtil;
310162547f44173f0604d8a80143c128d9892460a1Kristian Monsenimport android.cts.util.PollingCheck;
32d82745ff4a8b174f7be1258fd329dedc52ce58bbChenjie Luoimport android.cts.util.WidgetTestUtils;
33fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Bitmap;
34fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Color;
35fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Paint;
36afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.graphics.Path;
37fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukaiimport android.graphics.PorterDuff;
38fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Rect;
39afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.graphics.RectF;
40fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.Typeface;
41fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.drawable.BitmapDrawable;
42ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.graphics.drawable.ColorDrawable;
43fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.graphics.drawable.Drawable;
44fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.net.Uri;
45fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.os.Bundle;
46354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.Handler;
47265b3d21959154e9a6ce0fdd888249f3699b7bddYohei Yukawaimport android.os.LocaleList;
48354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.Looper;
495b51f77b99861d48fec1c327252416f726b3b01aJames Cookimport android.os.Parcelable;
50354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.os.ResultReceiver;
51fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.test.ActivityInstrumentationTestCase2;
5272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.test.TouchUtils;
53fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.test.UiThreadTest;
5498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinirimport android.test.suitebuilder.annotation.MediumTest;
55ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.test.suitebuilder.annotation.SmallTest;
56fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Editable;
57fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.InputFilter;
58fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.InputType;
59fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Layout;
60fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Selection;
61fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.Spannable;
62fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.SpannableString;
63ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.text.Spanned;
64fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextPaint;
65fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextUtils;
66fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.TextUtils.TruncateAt;
67afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.text.TextWatcher;
68fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.ArrowKeyMovementMethod;
69fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DateKeyListener;
70fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DateTimeKeyListener;
71fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DialerKeyListener;
72fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.DigitsKeyListener;
73fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.KeyListener;
74fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.LinkMovementMethod;
75fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.MovementMethod;
76fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.PasswordTransformationMethod;
77fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.QwertyKeyListener;
78fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.SingleLineTransformationMethod;
79fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TextKeyListener;
80afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.text.method.TextKeyListener.Capitalize;
81fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TimeKeyListener;
82fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.method.TransformationMethod;
8398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinirimport android.text.style.ImageSpan;
84fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.style.URLSpan;
85ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagiimport android.text.style.UnderlineSpan;
86fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.text.util.Linkify;
87fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.util.DisplayMetrics;
88fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.util.TypedValue;
89ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport android.view.ActionMode;
90fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.ContextMenu;
91afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.view.ContextMenu.ContextMenuInfo;
92fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.Gravity;
93fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.KeyEvent;
9432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagiimport android.view.Menu;
95fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.view.View;
96afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsuimport android.view.ViewGroup;
9732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagiimport android.view.accessibility.AccessibilityNodeInfo;
9872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.BaseInputConnection;
9972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.EditorInfo;
10072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.ExtractedText;
10172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubachimport android.view.inputmethod.ExtractedTextRequest;
102c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cookimport android.view.inputmethod.InputConnection;
103354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.view.inputmethod.InputMethodManager;
104c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunneimport android.widget.EditText;
105bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsuimport android.widget.FrameLayout;
10662808562ee0218f6ea3c07d333f7a65fc57c122fBrian Muramatsuimport android.widget.LinearLayout;
107354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikovimport android.widget.ScrollView;
108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.Scroller;
109fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.TextView;
110fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport android.widget.TextView.BufferType;
111938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport android.widget.cts.util.TestUtils;
11241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikovimport android.widget.cts.util.ViewTestUtils;
113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
114938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport org.mockito.invocation.InvocationOnMock;
115938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport org.mockito.stubbing.Answer;
116ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levienimport org.xmlpull.v1.XmlPullParserException;
117ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Suimport java.io.IOException;
119b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonakaimport java.util.Locale;
120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
121938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport static org.mockito.Matchers.any;
122938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikovimport static org.mockito.Mockito.*;
123938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su/**
125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su * Test {@link TextView}.
126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su */
1274ca04c0729a0e810b5af16edcd52bb8cb59bf55eChenjie Luopublic class TextViewTest extends ActivityInstrumentationTestCase2<TextViewCtsActivity> {
128fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private TextView mTextView;
130fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private Activity mActivity;
131fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private Instrumentation mInstrumentation;
132fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static final String LONG_TEXT = "This is a really long string which exceeds "
1337375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "the width of the view. New devices have a much larger screen which "
1347375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "actually enables long strings to be displayed with no fading. "
1357375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "I have made this string longer to fix this case. If you are correcting "
1367375565c2caf62392b32049cafb7df0730373794Gilles Debunne            + "this text, I would love to see the kind of devices you guys now use!";
137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static final long TIMEOUT = 5000;
13822d40a1fcc078329a7e5a34ff5eeadeca9c70d49Kenny Root    private CharSequence mTransformedText;
1395bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir    private KeyEventUtil mKeyEventUtil;
140354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    private Handler mHandler = new Handler(Looper.getMainLooper());
141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public TextViewTest() {
143a3e5fa456a01c74b91a5d66981433db598bcc9a7Agatha Man        super("android.widget.cts", TextViewCtsActivity.class);
144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
146fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @Override
147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    protected void setUp() throws Exception {
148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        super.setUp();
149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity = getActivity();
150938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        PollingCheck.waitFor(() -> mActivity.hasWindowFocus());
151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation = getInstrumentation();
1525bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil = new KeyEventUtil(mInstrumentation);
153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
15528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    /**
15628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook     * Promotes the TextView to editable and places focus in it to allow simulated typing.
15728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook     */
15828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    private void initTextViewForTyping() {
15928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        mActivity.runOnUiThread(new Runnable() {
16028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook            public void run() {
16128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView = findTextView(R.id.textview_text);
16228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
16328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.setText("", BufferType.EDITABLE);
16428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.requestFocus();
16528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook            }
16628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        });
16728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        mInstrumentation.waitForIdleSync();
16828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
16928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testConstructor() {
171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        new TextView(mActivity);
172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        new TextView(mActivity, null);
174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
175938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        new TextView(mActivity, null, android.R.attr.textViewStyle);
176938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
177f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_DeviceDefault_TextView);
178f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov
179f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_DeviceDefault_Light_TextView);
180f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov
181f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_Material_TextView);
182f0b8eb2d36b704834dd594c9eebe7f7134a94b40Kirill Grouchnikov
183938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        new TextView(mActivity, null, 0, android.R.style.Widget_Material_Light_TextView);
184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
185fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessText() {
188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String expected = mActivity.getResources().getString(R.string.text_view_hello);
191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(expected);
192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, tv.getText().toString());
193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
194fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null);
195fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLineHeight() {
199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineHeight() > 0);
201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLineSpacing(1.2f, 1.5f);
203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineHeight() > 0);
204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLayout() {
207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
209fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView = findTextView(R.id.textview_text);
210fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.CENTER);
211fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
212fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TestLayoutRunnable runnable = new TestLayoutRunnable(mTextView) {
217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // change the text of TextView.
219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText("Hello, Android!");
220fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveLayout();
221fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
222fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(runnable);
224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(runnable.getLayout());
226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
227fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
228fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
229fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessKeyListener() {
230fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView = findTextView(R.id.textview_text);
233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
236fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getKeyListener());
238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final KeyListener digitsKeyListener = DigitsKeyListener.getInstance();
240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setKeyListener(digitsKeyListener);
244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(digitsKeyListener, mTextView.getKeyListener());
248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener
250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                = QwertyKeyListener.getInstance(false, Capitalize.NONE);
251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setKeyListener(qwertyKeyListener);
254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(qwertyKeyListener, mTextView.getKeyListener());
258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessMovementMethod() {
261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence LONG_TEXT = "Scrolls the specified widget to the specified "
262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "coordinates, except constrains the X scrolling position to the horizontal "
263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "regions of the text that will be visible after scrolling to "
264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + "the specified Y position.";
265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int selectionStart = 10;
266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int selectionEnd = LONG_TEXT.length();
267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final MovementMethod movementMethod = ArrowKeyMovementMethod.getInstance();
268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView = findTextView(R.id.textview_text);
271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMovementMethod(movementMethod);
272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(LONG_TEXT, BufferType.EDITABLE);
273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Selection.setSelection((Editable) mTextView.getText(),
274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                        selectionStart, selectionEnd);
275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(movementMethod, mTextView.getMovementMethod());
281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
28303818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_ALT_LEFT,
284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                KeyEvent.KEYCODE_DPAD_UP);
285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the selection has been removed.
286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionEnd(mTextView.getText()));
288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMovementMethod(null);
292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Selection.setSelection((Editable) mTextView.getText(),
293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                        selectionStart, selectionEnd);
294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getMovementMethod());
300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
30203818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_ALT_LEFT,
303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                KeyEvent.KEYCODE_DPAD_UP);
304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the selection will not be changed.
305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testLength() {
311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String content = "This is content";
314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(content);
315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(content.length(), mTextView.length());
316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("");
318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.length());
319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(null);
321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.length());
322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessGravity() {
326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_gravity);
327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_default);
3294bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.TOP | Gravity.START, mTextView.getGravity());
330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_bottom);
3324bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.BOTTOM | Gravity.START, mTextView.getGravity());
333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_right);
335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity());
336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_center);
338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER, mTextView.getGravity());
339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_fill);
341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.FILL, mTextView.getGravity());
342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.gravity_center_vertical_right);
344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER_VERTICAL | Gravity.RIGHT, mTextView.getGravity());
345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
347fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, mTextView.getGravity());
348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.FILL);
349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.FILL, mTextView.getGravity());
350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER);
351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.CENTER, mTextView.getGravity());
352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.NO_GRAVITY);
3544bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.TOP | Gravity.START, mTextView.getGravity());
355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.RIGHT);
357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity());
358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.FILL_VERTICAL);
3604bb7d555a927c5f7a8747fdd85f7c94e1c0d2f19Fabrice Di Meglio        assertEquals(Gravity.FILL_VERTICAL | Gravity.START, mTextView.getGravity());
361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //test negative input value.
363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(-1);
364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getGravity());
365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessAutoLinkMask() {
368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text1 =
370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new SpannableString("URL: http://www.google.com. mailto: account@gmail.com");
371fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
373fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setAutoLinkMask(Linkify.ALL);
374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text1, BufferType.EDITABLE);
375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.ALL, mTextView.getAutoLinkMask());
379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Spannable spanString = (Spannable) mTextView.getText();
381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        URLSpan[] spans = spanString.getSpans(0, spanString.length(), URLSpan.class);
382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(spans);
383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("http://www.google.com", spans[0].getURL());
385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("mailto:account@gmail.com", spans[1].getURL());
386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text2 =
388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            new SpannableString("name: Jack. tel: +41 44 800 8999");
389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS);
392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text2, BufferType.EDITABLE);
393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS, mTextView.getAutoLinkMask());
397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spanString = (Spannable) mTextView.getText();
399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = spanString.getSpans(0, spanString.length(), URLSpan.class);
400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(spans);
401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, spans.length);
402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("tel:+41448008999", spans[0].getURL());
403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(R.layout.textview_autolink);
405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 1 for web, 2 for email, 4 for phone, 7 for all(web|email|phone)
406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, getAutoLinkMask(R.id.autolink_default));
407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS, getAutoLinkMask(R.id.autolink_web));
408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.EMAIL_ADDRESSES, getAutoLinkMask(R.id.autolink_email));
409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS, getAutoLinkMask(R.id.autolink_phone));
410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.ALL, getAutoLinkMask(R.id.autolink_all));
411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES,
412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound1));
413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.WEB_URLS | Linkify.PHONE_NUMBERS,
414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound2));
415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS,
416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound3));
417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Linkify.PHONE_NUMBERS | Linkify.ALL,
418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                getAutoLinkMask(R.id.autolink_compound4));
419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessTextSize() {
422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 20f);
426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20f, metrics),
427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20f);
430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, metrics),
431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20f);
434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics),
435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // setTextSize by default unit "sp"
438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(20f);
439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics),
440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextSize(200f);
443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 200f, metrics),
444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTextSize(), 0.01f);
445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessTextColor() {
448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.GREEN);
451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GREEN, mTextView.getCurrentTextColor());
452fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getTextColors());
453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.BLACK);
455fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentTextColor());
456fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.BLACK), mTextView.getTextColors());
457fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
458fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(Color.RED);
459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.RED, mTextView.getCurrentTextColor());
460fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.RED), mTextView.getTextColors());
461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
462fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using ColorStateList
463fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
464fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
465fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_focused}, new int[0] },
466fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
467fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextColor(colors);
468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getTextColors());
469fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentTextColor());
470fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
471fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // exceptional
472fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
473fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setTextColor(null);
474fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should thrown exception if the colors is null");
475fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e){
476fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
477fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
478fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
479325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette    public void testGetTextColor() {
480325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        // TODO: How to get a suitable TypedArray to test this method.
481325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette
482325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        try {
483325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette            TextView.getTextColor(mActivity, null, -1);
484325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette            fail("There should be a NullPointerException thrown out.");
485325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        } catch (NullPointerException e) {
486325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette        }
487325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette    }
488325d45563875cb6915e40070f3f687a3d92566f2Alan Viverette
489354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testAccessHighlightColor() {
490354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
491354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
492354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> {
493354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setTextIsSelectable(true);
494354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setText("abcd", BufferType.EDITABLE);
495354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            textView.setHighlightColor(Color.BLUE);
496354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        });
497354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
498354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
499354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(textView.isTextSelectable());
500354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.BLUE, textView.getHighlightColor());
501354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
502354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Long click on the text selects all text and shows selection handlers. The view has an
503354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // attribute layout_width="wrap_content", so clicked location (the center of the view)
504354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // should be on the text.
505354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        TouchUtils.longClickView(this, textView);
506fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
507354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // At this point the entire content of our TextView should be selected and highlighted
508354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // with blue. Now change the highlight to red while the selection is still on.
509354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setHighlightColor(Color.RED));
510354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
511354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
512354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.RED, textView.getHighlightColor());
513354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", textView.getText()));
514354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
515354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Remove the selection
516354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> Selection.removeSelection((Spannable) textView.getText()));
517354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
518354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
519354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // And switch highlight to green after the selection has been removed
520354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setHighlightColor(Color.GREEN));
521354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
522354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
523354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(Color.GREEN, textView.getHighlightColor());
524354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", textView.getText()));
525fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
526fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
5276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
528fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetShadowLayer() {
5296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test values
5306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final MockTextView mockTextView = new MockTextView(mActivity);
5316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
5326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, 0.3f, 0.4f, Color.CYAN);
5336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(Color.CYAN, mockTextView.getShadowColor());
5346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0.3f, mockTextView.getShadowDx());
5356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0.4f, mockTextView.getShadowDy());
5366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(1.0f, mockTextView.getShadowRadius());
537fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
538fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // shadow is placed to the left and below the text
5396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, 0.3f, 0.3f, Color.CYAN);
5406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(mockTextView.isPaddingOffsetRequired());
5416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getLeftPaddingOffset());
5426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getTopPaddingOffset());
5436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(1, mockTextView.getRightPaddingOffset());
5446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(1, mockTextView.getBottomPaddingOffset());
545fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
546fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // shadow is placed to the right and above the text
5476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(1.0f, -0.8f, -0.8f, Color.CYAN);
5486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(mockTextView.isPaddingOffsetRequired());
5496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mockTextView.getLeftPaddingOffset());
5506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mockTextView.getTopPaddingOffset());
5516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getRightPaddingOffset());
5526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getBottomPaddingOffset());
553fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
554fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // no shadow
5556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.setShadowLayer(0.0f, 0.0f, 0.0f, Color.CYAN);
5566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(mockTextView.isPaddingOffsetRequired());
5576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getLeftPaddingOffset());
5586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getTopPaddingOffset());
5596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getRightPaddingOffset());
5606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, mockTextView.getBottomPaddingOffset());
561fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
562fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
563fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
564fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetSelectAllOnFocus() {
565fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_selectallonfocus);
566fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String content = "This is the content";
567fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String blank = "";
568fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.selectAllOnFocus_default);
569fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(blank, BufferType.SPANNABLE);
570fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
571fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
572fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
573fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
574fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
575fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
576fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
577fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
578fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
579fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(content, BufferType.SPANNABLE);
580fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(true);
581fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
582fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
583fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
584fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
585fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
586fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
587fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
588fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(content.length(), mTextView.getSelectionEnd());
589fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
590fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 0);
591fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(false);
592fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
593fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
594fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
595fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
598fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
599fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionEnd());
600fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
601fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(blank, BufferType.SPANNABLE);
602fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(true);
603fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
604fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
606fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
607fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
608fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
610fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(blank.length(), mTextView.getSelectionEnd());
611fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
612fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 0);
613fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setSelectAllOnFocus(false);
614fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change the focus
615fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
616fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.isFocused());
617fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestFocus();
618fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.isFocused());
619fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
620fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
621fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionEnd());
622fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
623fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
624fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetPaint() {
625fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
626fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextPaint tp = mTextView.getPaint();
627fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(tp);
628fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
629fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaintFlags(), tp.getFlags());
630fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
631fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
632fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
633fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessLinksClickable() {
634fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext);
635fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
636fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
637fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
638fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
639fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.linksClickable_true);
640fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
641fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
642fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.linksClickable_false);
643fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getLinksClickable());
644fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
645fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinksClickable(false);
646fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getLinksClickable());
647fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
648fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinksClickable(true);
649fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLinksClickable());
650fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
651fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getMovementMethod());
652fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
653fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text = new SpannableString("name: Jack. tel: +41 44 800 8999");
654fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
655fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS);
656fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
657fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
658fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Movement method will be automatically set to LinkMovementMethod
659fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getMovementMethod() instanceof LinkMovementMethod);
660fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
661fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
662fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessHintTextColor() {
663fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
664fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using int values
665fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
666fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.GREEN);
667fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GREEN, mTextView.getCurrentHintTextColor());
668fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getHintTextColors());
669fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
670fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.BLUE);
671fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.BLUE), mTextView.getHintTextColors());
672fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLUE, mTextView.getCurrentHintTextColor());
673fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
674fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(Color.RED);
675fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.RED), mTextView.getHintTextColors());
676fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.RED, mTextView.getCurrentHintTextColor());
677fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
678fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using ColorStateList
679fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
680fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
681fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_focused}, new int[0] },
682fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
683fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(colors);
684fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getHintTextColors());
685fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getCurrentHintTextColor());
686fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
687fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // exceptional
688fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHintTextColor(null);
689fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getHintTextColors());
690fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCurrentTextColor(), mTextView.getCurrentHintTextColor());
691fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
692fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
693fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessLinkTextColor() {
694fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
695fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
696fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.GRAY);
697fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.GRAY), mTextView.getLinkTextColors());
698fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.GRAY, mTextView.getPaint().linkColor);
699fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
700fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.YELLOW);
701fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.YELLOW), mTextView.getLinkTextColors());
702fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.YELLOW, mTextView.getPaint().linkColor);
703fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
704fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(Color.WHITE);
705fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(ColorStateList.valueOf(Color.WHITE), mTextView.getLinkTextColors());
706fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.WHITE, mTextView.getPaint().linkColor);
707fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
708fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ColorStateList colors = new ColorStateList(new int[][] {
709fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { android.R.attr.state_expanded}, new int[0] },
710fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new int[] { Color.rgb(0, 255, 0), Color.BLACK });
711fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(colors);
712fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(colors, mTextView.getLinkTextColors());
713fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getPaint().linkColor);
714fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
715fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLinkTextColor(null);
716fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getLinkTextColors());
717fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Color.BLACK, mTextView.getPaint().linkColor);
718fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
719fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
720fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessPaintFlags() {
721fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
72253959f211c113aa7b2a2ebaf80e10b79ddcccef1Victoria Lease        assertEquals(Paint.DEV_KERN_TEXT_FLAG | Paint.EMBEDDED_BITMAP_TEXT_FLAG
72353959f211c113aa7b2a2ebaf80e10b79ddcccef1Victoria Lease                | Paint.ANTI_ALIAS_FLAG, mTextView.getPaintFlags());
724fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
725fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG);
726fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG,
727fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getPaintFlags());
728fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
729fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG);
730fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG,
731fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getPaintFlags());
732fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
733fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
7356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testHeight() {
736fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
7376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalHeight = mTextView.getHeight();
738fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setMaxHeight
7406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int newHeight = originalHeight + 1;
7416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
742fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
744fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
7466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
7476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
7486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
749fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
7516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
752fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getHeight());
7536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
754fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = Integer.MAX_VALUE;
7566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxHeight(newHeight);
757fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
759fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setMinHeight
7616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight + 1;
7626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
7636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
7646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
765fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
7676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
768fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
770fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
7726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinHeight(newHeight);
773fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
7746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
775fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // reset min and max height
777fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinHeight(0);
778fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxHeight(Integer.MAX_VALUE);
779fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
7806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // test setHeight
7816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight + 1;
7826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
7836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
7846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
7856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
7866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
7876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = originalHeight - 1;
7886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
7896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getHeight());
7906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
7916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
7926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
7936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newHeight = -1;
7946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setHeight(newHeight);
795fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getHeight());
7966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMaxHeight());
7976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newHeight, mTextView.getMinHeight());
798fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
799fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHeight(originalHeight);
800fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalHeight, mTextView.getHeight());
8016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(originalHeight, mTextView.getMaxHeight());
8026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(originalHeight, mTextView.getMinHeight());
803fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // setting max/min lines should cause getMaxHeight/getMinHeight to return -1
8056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxLines(2);
8066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting maxLines should return -1 fir maxHeight",
8076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                -1, mTextView.getMaxHeight());
8086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinLines(1);
8106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting minLines should return -1 for minHeight",
8116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                -1, mTextView.getMinHeight());
8126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
8136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
8156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testWidth() {
8166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = findTextView(R.id.textview_text);
8176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int originalWidth = mTextView.getWidth();
8186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        int newWidth = mTextView.getWidth() / 8;
8206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
8216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
8236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
824fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
825fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Min Width
8266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth + 1;
8276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinWidth(newWidth);
828fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
831fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth - 1;
833fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinWidth(originalWidth - 1);
8349c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu        assertEquals(2, mTextView.getLineCount());
8356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
837fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
838fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Width
8396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth + 1;
8406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
841fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
8446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
845fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        newWidth = originalWidth - 1;
8476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setWidth(newWidth);
8489c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu        assertEquals(2, mTextView.getLineCount());
8496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getWidth());
8506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMaxWidth());
8516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(newWidth, mTextView.getMinWidth());
8526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // setting ems should cause getMaxWidth/getMinWidth to return -1
8546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setEms(1);
8556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting ems should return -1 for maxWidth", -1, mTextView.getMaxWidth());
8566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Setting ems should return -1 for maxWidth", -1, mTextView.getMinWidth());
857fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
858fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
860fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetMinEms() {
861fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
862fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8639c3b459233e30a88d24e7178cc7514731fa56f55Brian Muramatsu
8646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
8656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
866fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
867fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinEms(originalEms + 1);
868fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals((originalEms + 1) * mTextView.getLineHeight(), mTextView.getWidth());
86998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
87098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMinEms());
871fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
872fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinEms(originalEms - 1);
873fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalWidth, mTextView.getWidth());
87498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
87598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMinEms());
8766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMinWidth(1);
8786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mTextView.getMinEms());
879fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
880fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
8816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
882fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetMaxEms() {
883fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
884fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
8856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
8866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
8876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
888fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
889fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxEms(originalEms + 1);
890fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
891fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(originalWidth, mTextView.getWidth());
89298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
89398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMaxEms());
894fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
895fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxEms(originalEms - 1);
896fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(1 < mTextView.getLineCount());
8976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms - 1) * mTextView.getLineHeight(), mTextView.getWidth());
89898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
89998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMaxEms());
9006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
9016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        setMaxWidth(originalWidth);
9026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(-1, mTextView.getMaxEms());
903fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
904fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
9056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
906fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetEms() {
907fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
908fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("check height", 1, mTextView.getLineCount());
9096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalWidth = mTextView.getWidth();
9106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int originalEms = originalWidth / mTextView.getLineHeight();
911fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
912fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setEms(originalEms + 1);
913fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
9146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms + 1) * mTextView.getLineHeight(), mTextView.getWidth());
91598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
91698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
91798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMinEms());
91898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms + 1, mTextView.getMaxEms());
919fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
920fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setEms(originalEms - 1);
921fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((1 < mTextView.getLineCount()));
9226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals((originalEms - 1) * mTextView.getLineHeight(), mTextView.getWidth());
92398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinWidth());
92498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxWidth());
92598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMinEms());
92698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalEms - 1, mTextView.getMaxEms());
927fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
928fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
929fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetLineSpacing() {
930fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
931fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLineHeight = mTextView.getLineHeight();
932fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
933fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // normal
934fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float add = 1.2f;
935fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float mult = 1.4f;
936fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
93792e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
938fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = 0.0f;
939fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = 1.4f;
940fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
94192e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
942fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
943fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // abnormal
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 = -1.4f;
950fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
95192e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
952fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = 1.2f;
953fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = 0.0f;
954fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
95592e24e51c89759b176c38a0ceaa94ae7b23c1930Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
956fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
957fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // edge
958fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = Float.MIN_VALUE;
959fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = Float.MIN_VALUE;
960fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
961ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
962ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette
963ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        // edge case where the behavior of Math.round() deviates from
964ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        // FastMath.round(), requiring us to use an explicit 0 value
965fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        add = Float.MAX_VALUE;
966fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mult = Float.MAX_VALUE;
967fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLineSpacing(add, mult);
968ae663de2120beb9de33d57e2c0ebfa6662e1d9f8Alan Viverette        assertEquals(0, mTextView.getLineHeight());
969fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
970fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
971ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien    public void testSetElegantLineHeight() {
972ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mTextView = findTextView(R.id.textview_text);
973ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getPaint().isElegantTextHeight());
974ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mActivity.runOnUiThread(new Runnable() {
975ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            public void run() {
976ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setWidth(mTextView.getWidth() / 3);
977ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setPadding(1, 2, 3, 4);
978ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setGravity(Gravity.BOTTOM);
979ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            }
980ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        });
981ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
982ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
983ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        int oldHeight = mTextView.getHeight();
984ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mActivity.runOnUiThread(new Runnable() {
985ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            public void run() {
986ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setElegantTextHeight(true);
987ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            }
988ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        });
989ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
990ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
991ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getPaint().isElegantTextHeight());
992ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getHeight() > oldHeight);
993ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
994ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mActivity.runOnUiThread(new Runnable() {
995ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            public void run() {
996ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien                mTextView.setElegantTextHeight(false);
997ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien            }
998ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        });
999ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        mInstrumentation.waitForIdleSync();
1000ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getPaint().isElegantTextHeight());
1001ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getHeight() == oldHeight);
1002ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien    }
1003ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien
1004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testInstanceState() {
1005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
1006fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1007fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1008fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessFreezesText() throws Throwable {
1009fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(R.layout.textview_hint_linksclickable_freezestext);
1010fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1011fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
1012fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1013fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1014fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_true);
1015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getFreezesText());
1016fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1017fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
1018fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1019fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1020fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setFreezesText(false);
1021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getFreezesText());
1022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1023fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final CharSequence text = "Hello, TextView.";
1024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
1025fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
1026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text);
1027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
1028fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
1030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final URLSpan urlSpan = new URLSpan("ctstest://TextView/test");
103272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // TODO: How to simulate the TextView in frozen icicles.
1033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Instrumentation instrumentation = getInstrumentation();
1034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        ActivityMonitor am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
1035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                null, false);
1036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
1038fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
1039fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Uri uri = Uri.parse(urlSpan.getURL());
1040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
1041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mActivity.startActivity(intent);
1042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
1043fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1044fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1045fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Activity newActivity = am.waitForActivityWithTimeout(TIMEOUT);
1046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(newActivity);
1047fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        newActivity.finish();
104872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        instrumentation.removeMonitor(am);
1049fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text of TextView is removed.
1050fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
105172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
105272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(text.toString(), mTextView.getText().toString());
1053fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1054fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setFreezesText(true);
1055fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getFreezesText());
1056fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1057fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
1058fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
1059fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text);
1060fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
1061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1062fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
106372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // TODO: How to simulate the TextView in frozen icicles.
1064fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
1065fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                null, false);
1066fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1067fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
1068fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
1069fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Uri uri = Uri.parse(urlSpan.getURL());
1070fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
1071fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mActivity.startActivity(intent);
1072fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
1073fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
1074fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
107507b9d3406e116f2f6b92932925783eed79503de0Mist Liao        Activity oldActivity = newActivity;
107607b9d3406e116f2f6b92932925783eed79503de0Mist Liao        while (true) {
107707b9d3406e116f2f6b92932925783eed79503de0Mist Liao            newActivity = am.waitForActivityWithTimeout(TIMEOUT);
107807b9d3406e116f2f6b92932925783eed79503de0Mist Liao            assertNotNull(newActivity);
107907b9d3406e116f2f6b92932925783eed79503de0Mist Liao            if (newActivity != oldActivity) {
108007b9d3406e116f2f6b92932925783eed79503de0Mist Liao                break;
108107b9d3406e116f2f6b92932925783eed79503de0Mist Liao            }
108207b9d3406e116f2f6b92932925783eed79503de0Mist Liao        }
1083fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        newActivity.finish();
108472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        instrumentation.removeMonitor(am);
1085fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text of TextView is still there.
1086fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.freezesText_false);
1087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text.toString(), mTextView.getText().toString());
1088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetEditableFactory() {
1091fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1092fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "sample";
1093fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
109498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final Editable.Factory mockEditableFactory = spy(new Editable.Factory());
109598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        doCallRealMethod().when(mockEditableFactory).newEditable(any(CharSequence.class));
109698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setEditableFactory(mockEditableFactory);
109798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov
1098fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text);
109998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1100fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
110198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1102fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
110398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1104fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
110598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1106fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
110798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, never()).newEditable(any(CharSequence.class));
1108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
110998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1110fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
111198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, times(1)).newEditable(text);
1112fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1113fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setKeyListener(DigitsKeyListener.getInstance());
111498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockEditableFactory);
1115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
111698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockEditableFactory, times(1)).newEditable(text);
1117fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1118fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1119fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setEditableFactory(null);
1120fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("The factory can not set to null!");
1121fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
1122fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1123fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1124fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1125fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetSpannableFactory() {
1126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "sample";
1128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
112998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final Spannable.Factory mockSpannableFactory = spy(new Spannable.Factory());
113098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        doCallRealMethod().when(mockSpannableFactory).newSpannable(any(CharSequence.class));
113198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setSpannableFactory(mockSpannableFactory);
113298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov
1133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text);
113498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1135fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
113698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.EDITABLE);
113898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1139fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
114098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
114298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, never()).newSpannable(any(CharSequence.class));
1143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
114498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
114698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, times(1)).newSpannable(text);
1147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setMovementMethod(LinkMovementMethod.getInstance());
114998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockSpannableFactory);
1150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.NORMAL);
115198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockSpannableFactory, times(1)).newSpannable(text);
1152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setSpannableFactory(null);
1155fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("The factory can not set to null!");
1156fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
1157fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testTextChangedListener() {
1161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextWatcher watcher0 = new MockTextWatcher();
1163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextWatcher watcher1 = new MockTextWatcher();
1164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.addTextChangedListener(watcher0);
1166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.addTextChangedListener(watcher1);
1167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("Changed");
1171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1176fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1178fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1179fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // BeforeTextChanged and OnTextChanged are called though the strings are same
1181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("Changed");
1182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1183fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1185fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // BeforeTextChanged and OnTextChanged are called twice (The text is not
1192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Editable, so in Append() it calls setText() first)
1193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("and appended");
1194fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1195fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledBeforeTextChanged());
1198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledOnTextChanged());
1199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher1.hasCalledAfterTextChanged());
1200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Methods are not called if the string does not change
1204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("");
1205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledBeforeTextChanged());
1206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledOnTextChanged());
1207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher0.hasCalledAfterTextChanged());
1208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledBeforeTextChanged());
1209fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledOnTextChanged());
1210fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledAfterTextChanged());
1211fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1212fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher0.reset();
1213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        watcher1.reset();
1214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.removeTextChangedListener(watcher1);
1215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(null);
1216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledBeforeTextChanged());
1217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledOnTextChanged());
1218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(watcher0.hasCalledAfterTextChanged());
1219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledBeforeTextChanged());
1220fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledOnTextChanged());
1221fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(watcher1.hasCalledAfterTextChanged());
1222fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetTextKeepState1() {
1225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
1226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1227fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String longString = "very long content";
1228fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String shortString = "short";
1229fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1230fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is inside the short string
1231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString, BufferType.SPANNABLE);
1232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 3);
1233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionStart());
1236fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionEnd());
1237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is outside the short string
1239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), shortString.length() + 1);
1241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is inside the short string
1247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 1, 4);
1249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getSelectionStart());
1252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(4, mTextView.getSelectionEnd());
1253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which ends outside the short string
1255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 2, shortString.length() + 1);
1257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getSelectionStart());
1260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is outside the short string
1263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(),
1265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                shortString.length() + 1, shortString.length() + 3);
1266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString);
1267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetEditableText() {
1274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "Hello";
1277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(text, BufferType.EDITABLE);
1278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getText().toString());
1279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
1280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getEditableText().toString());
1281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(text, BufferType.SPANNABLE);
1283fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text, tv.getText().toString());
1284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
1285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(tv.getEditableText());
1286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null, BufferType.EDITABLE);
1288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
1290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getEditableText().toString());
1291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(null, BufferType.SPANNABLE);
1293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
1295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(tv.getEditableText());
1296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText2() {
1300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String string = "This is a test for setting text content by char array";
1301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        char[] input = string.toCharArray();
1302fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 0, input.length);
1305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(string, tv.getText().toString());
1306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 0, 5);
1308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(string.substring(0, 5), tv.getText().toString());
1309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, -1, input.length);
1312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the start position is negative!");
1313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, 0, -1);
1318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the length is negative!");
1319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(input, 1, input.length);
1324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if the end position is out of index!");
1325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IndexOutOfBoundsException exception) {
1326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(input, 1, 0);
1329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", tv.getText().toString());
1330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText1() {
1334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
1335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String longString = "very long content";
1337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String shortString = "short";
1338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is inside the short string
1340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString, BufferType.SPANNABLE);
1341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 3);
1342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionStart());
1347fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(3, mTextView.getSelectionEnd());
1348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // selection is at the exact place which is outside the short string
1358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), longString.length());
1360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1371fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1373fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is inside the short string
1376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 1, shortString.length() - 1);
1378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getSelectionStart());
1383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length() - 1, mTextView.getSelectionEnd());
1384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which ends outside the short string
1394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), 2, longString.length());
1396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getSelectionStart());
1401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // select the sub string which is outside the short string
1412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(longString);
1413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(),
1414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                shortString.length() + 1, shortString.length() + 3);
1415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionStart());
1420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString.length(), mTextView.getSelectionEnd());
1421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(shortString, BufferType.EDITABLE);
1423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
1424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getText().toString());
1425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(shortString, mTextView.getEditableText().toString());
1426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no selection.
1427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionStart());
1428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getSelectionEnd());
1429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
1432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText3() {
1433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
1434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int resId = R.string.text_view_hint;
1436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String result = mActivity.getResources().getString(resId);
1437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId);
1439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
1440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
1441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
1442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(-1);
1443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception with illegal id");
1444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
1445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
1446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
1447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
144898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir    @MediumTest
144998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir    public void testSetText_updatesHeightAfterRemovingImageSpan() {
145098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // Height calculation had problems when TextView had width: match_parent
145198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int textViewWidth = ViewGroup.LayoutParams.MATCH_PARENT;
145298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final Spannable text = new SpannableString("some text");
145398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int spanHeight = 100;
145498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
145598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // prepare TextView, width: MATCH_PARENT
145698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        TextView textView = new TextView(getActivity());
145798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setSingleLine(true);
145898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 2);
145998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setPadding(0, 0, 0, 0);
146098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setIncludeFontPadding(false);
146198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        textView.setText(text);
146298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
146398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(textViewWidth,
146498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
146598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        layout.addView(textView, layoutParams);
146698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        layout.setLayoutParams(layoutParams);
146798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
146898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            @Override
146998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            public void run() {
147098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                getActivity().setContentView(layout);
147198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            }
147298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        });
147398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        getInstrumentation().waitForIdleSync();
147498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
147598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // measure height of text with no span
147698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int heightWithoutSpan = textView.getHeight();
147798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertTrue("Text height should be smaller than span height",
147898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithoutSpan < spanHeight);
147998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
148098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // add ImageSpan to text
148198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        Drawable drawable = mInstrumentation.getContext().getDrawable(R.drawable.scenery);
148298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        drawable.setBounds(0, 0, spanHeight, spanHeight);
148398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        ImageSpan span = new ImageSpan(drawable);
148498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        text.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
148598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
148698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            @Override
148798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            public void run() {
148898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                textView.setText(text);
148998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            }
149098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        });
149198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mInstrumentation.waitForIdleSync();
149298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
149398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // measure height with span
149498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int heightWithSpan = textView.getHeight();
149598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertTrue("Text height should be greater or equal than span height",
149698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithSpan >= spanHeight);
149798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
149898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        // remove the span
149998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        text.removeSpan(span);
150098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
150198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            @Override
150298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            public void run() {
150398d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                textView.setText(text);
150498d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir            }
150598d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        });
150698d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        mInstrumentation.waitForIdleSync();
150798d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
150898d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        final int heightAfterRemoveSpan = textView.getHeight();
150998d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir        assertEquals("Text height should be same after removing the span",
151098d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir                heightWithoutSpan, heightAfterRemoveSpan);
151198d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir    }
151298d94f2d9f2354dc151fe0ad12646c39b7cf49b8Siyamed Sinir
1513af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi    public void testRemoveSelectionWithSelectionHandles() {
1514af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        initTextViewForTyping();
1515af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1516354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.isTextSelectable());
1517354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> {
1518354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mTextView.setTextIsSelectable(true);
1519354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mTextView.setText("abcd", BufferType.EDITABLE);
1520af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        });
1521af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        mInstrumentation.waitForIdleSync();
1522354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.isTextSelectable());
1523af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1524af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // Long click on the text selects all text and shows selection handlers. The view has an
1525af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // attribute layout_width="wrap_content", so clicked location (the center of the view)
1526af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // should be on the text.
1527af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        TouchUtils.longClickView(this, mTextView);
1528af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1529354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> Selection.removeSelection((Spannable) mTextView.getText()));
1530af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1531af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        // Make sure that a crash doesn't happen with {@link Selection#removeSelection}.
1532af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi        mInstrumentation.waitForIdleSync();
1533354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
1534354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.equals("abcd", mTextView.getText()));
1535af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi    }
1536af32bc382e1eae93a12b5c2aa91c2acf8a999adfYoshiki Iguchi
1537c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_insert() {
153828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
15395b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15405b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Type some text.
15415bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
15425b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
15435b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
154428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Precondition: The cursor is at the end of the text.
154528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(3, mTextView.getSelectionStart());
15465b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15475b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undo removes the typed string in one step.
15485b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
15495b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
155028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(0, mTextView.getSelectionStart());
15515b51f77b99861d48fec1c327252416f726b3b01aJames Cook
155228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Redo restores the text and cursor position.
15535b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.redo);
15545b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("abc", mTextView.getText().toString());
155528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(3, mTextView.getSelectionStart());
15565b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15575b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undoing the redo clears the text again.
15585b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
15595b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
15605b51f77b99861d48fec1c327252416f726b3b01aJames Cook
15615b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undo when the undo stack is empty does nothing.
15625b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
15635b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
15645b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
15655b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
15665b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
156728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
15685b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1569c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_delete() {
157028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
15715b51f77b99861d48fec1c327252416f726b3b01aJames Cook
157228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        // Simulate deleting text and undoing it.
15735bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "xyz");
15745bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL,
15755bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir                KeyEvent.KEYCODE_DEL);
15765b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
15775b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
157828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Precondition: The text was actually deleted.
157928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("", mTextView.getText().toString());
158028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(0, mTextView.getSelectionStart());
158128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
158228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Undo restores the typed string and cursor position in one step.
15835b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
158428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("xyz", mTextView.getText().toString());
158528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(3, mTextView.getSelectionStart());
15865b51f77b99861d48fec1c327252416f726b3b01aJames Cook
158728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Redo removes the text in one step.
158828715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.onTextContextMenuItem(android.R.id.redo);
158928715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("", mTextView.getText().toString());
159028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(0, mTextView.getSelectionStart());
15915b51f77b99861d48fec1c327252416f726b3b01aJames Cook
159228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Undoing the redo restores the text again.
159328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
159428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("xyz", mTextView.getText().toString());
159528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(3, mTextView.getSelectionStart());
159628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
159728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                // Undoing again undoes the original typing.
15985b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
15995b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
160028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals(0, mTextView.getSelectionStart());
16015b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
16025b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
16035b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
160428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
16055b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1606c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    // Initialize the text view for simulated IME typing. Must be called on UI thread.
1607c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    private InputConnection initTextViewForSimulatedIme() {
1608c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView = findTextView(R.id.textview_text);
1609c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
1610c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setText("", BufferType.EDITABLE);
1611c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        return mTextView.onCreateInputConnection(new EditorInfo());
1612c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1613c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1614c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    // Simulates IME composing text behavior.
1615c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    private void setComposingTextInBatch(InputConnection input, CharSequence text) {
1616c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1617c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.setComposingText(text, 1);  // Leave cursor at end.
1618c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1619c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1620c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1621c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1622c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeInsertLatin() {
1623c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1624c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1625c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Simulate IME text entry behavior. The Latin IME enters text by replacing partial words,
1626c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // such as "c" -> "ca" -> "cat" -> "cat ".
1627c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "c");
1628c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "ca");
1629c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1630c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The completion and space are added in the same batch.
1631c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1632c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText("cat", 1);
1633c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText(" ", 1);
1634c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1635c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1636c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The repeated replacements undo in a single step.
1637c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1638c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("", mTextView.getText().toString());
1639c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1640c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1641c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1642c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeInsertJapanese() {
1643c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1644c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1645c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The Japanese IME does repeated replacements of Latin characters to hiragana to kanji.
1646c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String HA = "\u306F";  // HIRAGANA LETTER HA
1647c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String NA = "\u306A";  // HIRAGANA LETTER NA
1648c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "h");
1649c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA);
1650c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + "n");
1651c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + NA);
1652c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1653c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The result may be a surrogate pair. The composition ends in the same batch.
1654c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1655c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.commitText("\uD83C\uDF37", 1);  // U+1F337 TULIP
1656c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.setComposingText("", 1);
1657c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1658c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1659c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // The repeated replacements are a single undo step.
1660c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1661c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("", mTextView.getText().toString());
1662c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1663c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1664c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1665c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeCancel() {
1666c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1667c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setText("flower");
1668c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1669c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Start typing a composition.
1670c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        final String HA = "\u306F";  // HIRAGANA LETTER HA
1671c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "h");
1672c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA);
1673c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, HA + "n");
1674c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1675c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Cancel the composition.
1676c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        setComposingTextInBatch(input, "");
1677c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1678c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Undo and redo do nothing.
1679c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1680c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1681c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.redo);
1682c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1683c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1684c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1685c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    @UiThreadTest
1686c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_imeEmptyBatch() {
1687c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        InputConnection input = initTextViewForSimulatedIme();
1688c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.setText("flower");
1689c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1690c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Send an empty batch edit. This happens if the IME is hidden and shown.
1691c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.beginBatchEdit();
1692c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        input.endBatchEdit();
1693c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1694c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Undo and redo do nothing.
1695c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.undo);
1696c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1697c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        mTextView.onTextContextMenuItem(android.R.id.redo);
1698c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        assertEquals("flower", mTextView.getText().toString());
1699c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    }
1700c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook
1701c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_setText() {
1702277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
170328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1704c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook        // Create two undo operations, an insert and a delete.
17055bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "xyz");
17065bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL,
17075bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir                KeyEvent.KEYCODE_DEL);
1708277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1709277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1710c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook                // Calling setText() clears both undo operations, so undo doesn't happen.
1711277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.setText("Hello", BufferType.EDITABLE);
1712277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1713277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("Hello", mTextView.getText().toString());
171428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1715277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Clearing text programmatically does not undo either.
1716277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.setText("", BufferType.EDITABLE);
1717277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1718277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("", mTextView.getText().toString());
1719277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1720277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1721277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1722277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
172328715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1724c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testRedo_setText() {
1725277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
1726277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1727277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text. This creates an undo entry.
17285bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
1729277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1730277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1731277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Undo the typing to create a redo entry.
1732277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1733277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1734277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Calling setText() clears the redo stack, so redo doesn't happen.
1735277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.setText("Hello", BufferType.EDITABLE);
1736277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.redo);
1737277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("Hello", mTextView.getText().toString());
1738277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1739277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1740277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1741277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1742277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1743c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_directAppend() {
1744277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
174528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1746277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
17475bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
1748277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1749277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1750277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Programmatically append some text.
1751277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.append("def");
1752277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("abcdef", mTextView.getText().toString());
1753277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1754277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Undo removes the append as a separate step.
1755277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1756277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("abc", mTextView.getText().toString());
1757277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1758277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Another undo removes the original typing.
1759277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1760277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("", mTextView.getText().toString());
1761277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1762277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1763277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1764277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1765277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1766c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_directInsert() {
1767277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
1768277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1769277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
17705bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
1771277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1772277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1773277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Directly modify the underlying Editable to insert some text.
1774277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // NOTE: This is a violation of the API of getText() which specifies that the
1775277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // returned object should not be modified. However, some apps do this anyway and
1776277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // the framework needs to handle it.
1777277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                Editable text = (Editable) mTextView.getText();
1778277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                text.insert(0, "def");
1779277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("defabc", mTextView.getText().toString());
1780277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1781277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Undo removes the insert as a separate step.
1782277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1783277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("abc", mTextView.getText().toString());
1784277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1785277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Another undo removes the original typing.
1786277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1787277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("", mTextView.getText().toString());
1788277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1789277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1790277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1791277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
1792277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1793c530472a02205f0b7d87f9f06140c56ca0849816James Cook    public void testUndo_noCursor() {
1794c530472a02205f0b7d87f9f06140c56ca0849816James Cook        initTextViewForTyping();
1795c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1796c530472a02205f0b7d87f9f06140c56ca0849816James Cook        mActivity.runOnUiThread(new Runnable() {
1797c530472a02205f0b7d87f9f06140c56ca0849816James Cook            public void run() {
1798c530472a02205f0b7d87f9f06140c56ca0849816James Cook                // Append some text to create an undo operation. There is no cursor present.
1799c530472a02205f0b7d87f9f06140c56ca0849816James Cook                mTextView.append("cat");
1800c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1801c530472a02205f0b7d87f9f06140c56ca0849816James Cook                // Place the cursor at the end of the text so the undo will have to change it.
1802c530472a02205f0b7d87f9f06140c56ca0849816James Cook                Selection.setSelection((Spannable) mTextView.getText(), 3);
1803c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1804c530472a02205f0b7d87f9f06140c56ca0849816James Cook                // Undo the append. This should not crash, despite not having a valid cursor
1805c530472a02205f0b7d87f9f06140c56ca0849816James Cook                // position in the undo operation.
1806c530472a02205f0b7d87f9f06140c56ca0849816James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1807c530472a02205f0b7d87f9f06140c56ca0849816James Cook            }
1808c530472a02205f0b7d87f9f06140c56ca0849816James Cook        });
1809c530472a02205f0b7d87f9f06140c56ca0849816James Cook        mInstrumentation.waitForIdleSync();
1810c530472a02205f0b7d87f9f06140c56ca0849816James Cook    }
1811c530472a02205f0b7d87f9f06140c56ca0849816James Cook
1812c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_textWatcher() {
1813277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        initTextViewForTyping();
1814277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1815277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Add a TextWatcher that converts the text to spaces on each change.
1816277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher());
1817277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1818277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        // Type some text.
18195bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
1820277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mActivity.runOnUiThread(new Runnable() {
1821277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            public void run() {
1822277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // TextWatcher altered the text.
1823277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("   ", mTextView.getText().toString());
1824277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
1825277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                // Undo reverses both changes in one step.
1826277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1827277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertEquals("", mTextView.getText().toString());
1828277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
1829277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        });
1830277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        mInstrumentation.waitForIdleSync();
1831c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook    }
1832c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1833c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook    public void testUndo_textWatcherDirectAppend() {
1834c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        initTextViewForTyping();
1835c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1836c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        // Add a TextWatcher that converts the text to spaces on each change.
1837c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher());
1838c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1839c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        mActivity.runOnUiThread(new Runnable() {
1840c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook            public void run() {
1841c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                // Programmatically append some text. The TextWatcher changes it to spaces.
1842c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                mTextView.append("abc");
1843c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                assertEquals("   ", mTextView.getText().toString());
1844c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook
1845c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                // Undo reverses both changes in one step.
1846c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
1847c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook                assertEquals("", mTextView.getText().toString());
1848c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook            }
1849c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        });
1850c4dca4185874f3a78380439d678f1a8fa86f7a66James Cook        mInstrumentation.waitForIdleSync();
185128715a6877392e4e63cb2b0170c1592fb50079dcJames Cook    }
185228715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
1853c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_shortcuts() {
185428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
185528715a6877392e4e63cb2b0170c1592fb50079dcJames Cook
185628715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        // Type some text.
18575bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
18585b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
18595b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
18605b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Pressing Control-Z triggers undo.
18615b51f77b99861d48fec1c327252416f726b3b01aJames Cook                KeyEvent control = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z, 0,
18625b51f77b99861d48fec1c327252416f726b3b01aJames Cook                        KeyEvent.META_CTRL_LEFT_ON);
1863277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, control));
18645b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
18655b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18665b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Pressing Control-Shift-Z triggers redo.
18675b51f77b99861d48fec1c327252416f726b3b01aJames Cook                KeyEvent controlShift = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z,
18685b51f77b99861d48fec1c327252416f726b3b01aJames Cook                        0, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_SHIFT_LEFT_ON);
1869277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, controlShift));
187028715a6877392e4e63cb2b0170c1592fb50079dcJames Cook                assertEquals("abc", mTextView.getText().toString());
18715b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
18725b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
18735b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
18745b51f77b99861d48fec1c327252416f726b3b01aJames Cook    }
18755b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1876c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_saveInstanceState() {
187728715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
18785b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18795b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Type some text to create an undo operation.
18805bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
18815b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
18825b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
18835b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Parcel and unparcel the TextView.
18845b51f77b99861d48fec1c327252416f726b3b01aJames Cook                Parcelable state = mTextView.onSaveInstanceState();
18855b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onRestoreInstanceState(state);
18865b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
18875b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
18885b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
18895b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18905b51f77b99861d48fec1c327252416f726b3b01aJames Cook        // Delete a character to create a new undo operation.
18915bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL);
18925b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mActivity.runOnUiThread(new Runnable() {
18935b51f77b99861d48fec1c327252416f726b3b01aJames Cook            public void run() {
18945b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("ab", mTextView.getText().toString());
18955b51f77b99861d48fec1c327252416f726b3b01aJames Cook
18965b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undo the delete.
18975b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
18985b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("abc", mTextView.getText().toString());
18995b51f77b99861d48fec1c327252416f726b3b01aJames Cook
19005b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // Undo the typing, which verifies that the original undo operation was parceled
19015b51f77b99861d48fec1c327252416f726b3b01aJames Cook                // correctly.
19025b51f77b99861d48fec1c327252416f726b3b01aJames Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19035b51f77b99861d48fec1c327252416f726b3b01aJames Cook                assertEquals("", mTextView.getText().toString());
19045f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
19055f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // Parcel and unparcel the undo stack (which is empty but has been used and may
19065f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // contain other state).
19075f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                Parcelable state = mTextView.onSaveInstanceState();
19085f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onRestoreInstanceState(state);
19095f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook            }
19105f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        });
19115f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mInstrumentation.waitForIdleSync();
19125f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook    }
19135f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
1914c1198c0aa7c7e9b52a32d9e2c0d663c69ee131c6James Cook    public void testUndo_saveInstanceStateEmpty() {
19155f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        initTextViewForTyping();
19165f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
19175f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        // Type and delete to create two new undo operations.
19185bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "a");
19195bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL);
19205f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mActivity.runOnUiThread(new Runnable() {
19215f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook            public void run() {
19225f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // Empty the undo stack then parcel and unparcel the TextView. While the undo
19235f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // stack contains no operations it may contain other state.
19245f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19255f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19265f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                Parcelable state = mTextView.onSaveInstanceState();
19275f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onRestoreInstanceState(state);
19285f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook            }
19295f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        });
19305f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mInstrumentation.waitForIdleSync();
19315f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook
19325f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        // Create two more undo operations.
19335bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "b");
19345bd6955fa69a7f5e07d669ea677840099c4e1dbcSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL);
19355f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook        mActivity.runOnUiThread(new Runnable() {
19365f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook            public void run() {
19375f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                // Verify undo still works.
19385f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19395f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                assertEquals("b", mTextView.getText().toString());
19405f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                mTextView.onTextContextMenuItem(android.R.id.undo);
19415f31960d0d0e9aac4b48e895ee8fd144791a5109James Cook                assertEquals("", mTextView.getText().toString());
19425b51f77b99861d48fec1c327252416f726b3b01aJames Cook            }
19435b51f77b99861d48fec1c327252416f726b3b01aJames Cook        });
19445b51f77b99861d48fec1c327252416f726b3b01aJames Cook        mInstrumentation.waitForIdleSync();
19455b51f77b99861d48fec1c327252416f726b3b01aJames Cook    }
19465b51f77b99861d48fec1c327252416f726b3b01aJames Cook
1947b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCopyAndPaste() {
1948b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
1949b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
1950b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            public void run() {
1951b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setText("abcd", BufferType.EDITABLE);
1952b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setSelected(true);
1953b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
1954b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Copy "bc".
1955b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
1956b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.copy);
1957b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
1958b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Paste "bc" between "b" and "c".
1959b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 2, 2);
1960b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
1961b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("abbccd", mTextView.getText().toString());
1962b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
1963b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Select entire text and paste "bc".
1964b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
1965b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
1966b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("bc", mTextView.getText().toString());
1967b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            }
1968b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        });
1969b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
1970b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
1971b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
197249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    public void testCopyAndPaste_byKey() {
197349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        initTextViewForTyping();
197449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
197549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Type "abc".
197603818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
197749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
197849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
197949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Select "bc"
198049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
198149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
198249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
198349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
198449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Copy "bc"
198503818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_COPY);
198649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
198749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
198849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
198949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Set cursor between 'b' and 'c'.
199049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 2, 2);
199149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
199249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
199349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
199449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Paste "bc"
199503818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_PASTE);
199649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        assertEquals("abbcc", mTextView.getText().toString());
199749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
199849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
199949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
200049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
200149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                KeyEvent copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
200249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.KEYCODE_COPY, 0, KeyEvent.META_SHIFT_LEFT_ON);
200349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Shift + copy doesn't perform copy.
200449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
200549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
200649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
200749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bcabbcc", mTextView.getText().toString());
200849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
200949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
201049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0,
201149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.META_CTRL_LEFT_ON);
201249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Control + copy doesn't perform copy.
201349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
201449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
201549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
201649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bcbcabbcc", mTextView.getText().toString());
201749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
201849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
201949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0,
202049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON);
202149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Control + Shift + copy doesn't perform copy.
202249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
202349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
202449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
202549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bcbcbcabbcc", mTextView.getText().toString());
202649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
202749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
20288e9fc4a5b2274a1279261f1a36c5396b9884042dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
202949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    }
203049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
2031b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCutAndPaste() {
2032b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
2033b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
2034b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            public void run() {
2035b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setText("abcd", BufferType.EDITABLE);
2036b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setSelected(true);
2037b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2038b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Cut "bc".
2039b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
2040b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.cut);
2041b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("ad", mTextView.getText().toString());
2042b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2043b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Cut "ad".
2044b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 2);
2045b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.cut);
2046b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("", mTextView.getText().toString());
2047b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2048b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Paste "ad".
2049b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
2050b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("ad", mTextView.getText().toString());
2051b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            }
2052b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        });
2053b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
2054b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2055b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
205649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    public void testCutAndPaste_byKey() {
205749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        initTextViewForTyping();
205849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
205949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Type "abc".
206003818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "abc");
206149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
206249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
206349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Select "bc"
206449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
206549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
206649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
206749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
206849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Cut "bc"
206903818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_CUT);
207049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
207149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
207249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
207349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("a", mTextView.getText().toString());
207449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Move cursor to the head
207549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
207649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
207749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
207849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
207949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        // Paste "bc"
208003818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_PASTE);
208149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        assertEquals("bca", mTextView.getText().toString());
208249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
208349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
208449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            public void run() {
208549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
208649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                KeyEvent cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
208749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.KEYCODE_CUT, 0, KeyEvent.META_SHIFT_LEFT_ON);
208849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Shift + cut doesn't perform cut.
208949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
209049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bca", mTextView.getText().toString());
209149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
209249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0,
209349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.META_CTRL_LEFT_ON);
209449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Control + cut doesn't perform cut.
209549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
209649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bca", mTextView.getText().toString());
209749279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
209849279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0,
209949279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                        KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON);
210049279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                // Control + Shift + cut doesn't perform cut.
210149279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
210249279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi                assertEquals("bca", mTextView.getText().toString());
210349279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi            }
210449279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi        });
210549279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi    }
210649279f3ccd432c3d9611ee3c357ebb407b84c5c5Keisuke Kuroyanagi
2107b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    private static boolean hasSpansAtMiddleOfText(final TextView textView, final Class<?> type) {
2108b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        final Spannable spannable = (Spannable)textView.getText();
2109b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        final int at = spannable.length() / 2;
2110b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        return spannable.getSpans(at, at, type).length > 0;
2111b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2112b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2113b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    public void testCutAndPaste_withAndWithoutStyle() {
2114b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        initTextViewForTyping();
2115b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
2116b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            public void run() {
2117b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setText("example", BufferType.EDITABLE);
2118b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.setSelected(true);
2119b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2120b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Set URLSpan.
2121b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                final Spannable spannable = (Spannable) mTextView.getText();
2122b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                spannable.setSpan(new URLSpan("http://example.com"), 0, spannable.length(), 0);
2123b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
2124b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2125b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Cut entire text.
2126b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
2127b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.cut);
2128b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("", mTextView.getText().toString());
2129b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2130b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Paste without style.
2131b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.pasteAsPlainText);
2132b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("example", mTextView.getText().toString());
2133b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Check that the text doesn't have URLSpan.
2134b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertFalse(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
2135b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2136b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Paste with style.
2137b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                Selection.selectAll((Spannable) mTextView.getText());
2138b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.paste);
2139b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertEquals("example", mTextView.getText().toString());
2140b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                // Check that the text has URLSpan.
2141b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi                assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
2142b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi            }
2143b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        });
2144b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
2145b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi    }
2146b07a600d96f12f712b7914822fea7db15b881a5dKeisuke Kuroyanagi
2147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
21484ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    public void testSaveInstanceState() {
2149baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // should save text when freezesText=true
21504ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        TextView originalTextView = new TextView(mActivity);
21514ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        final String text = "This is a string";
21524ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        originalTextView.setText(text);
21534ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        originalTextView.setFreezesText(true);  // needed to actually save state
21544ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        Parcelable state = originalTextView.onSaveInstanceState();
21554ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
21564ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        TextView restoredTextView = new TextView(mActivity);
21574ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        restoredTextView.onRestoreInstanceState(state);
21584ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        assertEquals(text, restoredTextView.getText().toString());
21594ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    }
21604ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
21614ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    @UiThreadTest
2162baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_whenFreezesTextIsFalse() {
21634ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien        final String text = "This is a string";
2164baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        { // should not save text when freezesText=false
2165baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for before saveInstanceState
2166baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView1 = new TextView(mActivity);
2167baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setFreezesText(false);
2168baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setText(text);
21694ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
2170baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for after saveInstanceState
2171baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView2 = new TextView(mActivity);
2172baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setFreezesText(false);
2173baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2174baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2175baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2176baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            assertEquals("", textView2.getText().toString());
2177baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        }
2178baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2179baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        { // should not save text even when textIsSelectable=true
2180baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for before saveInstanceState
2181baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView1 = new TextView(mActivity);
2182baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setFreezesText(false);
2183baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setTextIsSelectable(true);
2184baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView1.setText(text);
2185baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2186baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            // prepare TextView for after saveInstanceState
2187baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            TextView textView2 = new TextView(mActivity);
2188baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setFreezesText(false);
2189baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.setTextIsSelectable(true);
2190baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2191baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2192baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2193baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir            assertEquals("", textView2.getText().toString());
2194baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        }
2195baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2196baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2197baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2198baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2199baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_doesNotSaveSelectionWhenDoesNotExist() {
2200baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2201baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2202baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2203baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(true);
2204baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2205baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2206baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2207baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2208baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(true);
2209baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2210baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2211baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2212baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(-1, textView2.getSelectionStart());
2213baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(-1, textView2.getSelectionEnd());
2214baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2215baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2216baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2217baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2218baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_doesNotRestoreSelectionWhenTextIsAbsent() {
2219baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2220baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2221baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2222baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(false);
2223baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setTextIsSelectable(true);
2224baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2225baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
2226baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2227baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2228baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2229baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(false);
2230baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setTextIsSelectable(true);
2231baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2232baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2233baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2234baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals("", textView2.getText().toString());
2235baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        //when textIsSelectable, selection start and end are initialized to 0
2236baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(0, textView2.getSelectionStart());
2237baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(0, textView2.getSelectionEnd());
2238baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    }
2239baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2240baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @UiThreadTest
2241baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    @SmallTest
2242baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir    public void testOnSaveInstanceState_savesSelectionWhenExists() {
2243baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        final String text = "This is a string";
2244baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for before saveInstanceState
2245baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView1 = new TextView(mActivity);
2246baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setFreezesText(true);
2247baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setTextIsSelectable(true);
2248baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView1.setText(text);
2249baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
2250baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2251baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        // prepare TextView for after saveInstanceState
2252baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        TextView textView2 = new TextView(mActivity);
2253baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setFreezesText(true);
2254baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.setTextIsSelectable(true);
2255baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2256baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
2257baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir
2258baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(textView1.getSelectionStart(), textView2.getSelectionStart());
2259baeafb8c1c7feacfa0fd684d38646ac24d642e34Siyamed Sinir        assertEquals(textView1.getSelectionEnd(), textView2.getSelectionEnd());
22604ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    }
22614ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien
22624ed3b6c02b917394dfc68c4d421c4b935a3325c8Raph Levien    @UiThreadTest
2263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetText() {
2264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView tv = findTextView(R.id.textview_text);
2265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int resId = R.string.text_view_hint;
2267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String result = mActivity.getResources().getString(resId);
2268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId, BufferType.EDITABLE);
2270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
2271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Editable);
2272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        tv.setText(resId, BufferType.SPANNABLE);
2274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(result, tv.getText().toString());
2275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(tv.getText() instanceof Spannable);
2276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            tv.setText(-1, BufferType.EDITABLE);
2279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception with illegal id");
2280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
2281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2283fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessHint() {
2286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext);
2287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
2289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getHint());
2290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_blank);
2292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", mTextView.getHint());
2293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_string);
2295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_simple_hint),
2296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint());
2297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.hint_resid);
2299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_hint),
2300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint());
2301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2302fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHint("This is hint");
2303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("This is hint", mTextView.getHint().toString());
2304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setHint(R.string.text_view_hello);
2306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
2307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHint().toString());
2308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Non-exist resid
2310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setHint(-1);
2312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw exception if id is illegal");
2313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NotFoundException e) {
2314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessError() {
2318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
232153b55f734fb3cf52df49a79cf76d410a77fbe8f5Craig Mautner        final String errorText = "Oops! There is an error";
2322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setError(null);
2326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
23319776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        final Drawable icon = getDrawable(R.drawable.failed);
2332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setError(errorText, icon);
2335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(errorText, mTextView.getError().toString());
2339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // can not check whether the drawable is set correctly
2340fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2341fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2342fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2343fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setError(null, null);
2344fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2345fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2346fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2347fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2351300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.setKeyListener(DigitsKeyListener.getInstance(""));
2352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText("", BufferType.EDITABLE);
2353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setError(errorText);
2354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
2355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(errorText, mTextView.getError().toString());
2360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
236103818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "a");
2362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // a key event that will not change the TextView's text
2363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("", mTextView.getText().toString());
2364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // The icon and error message will not be reset to null
236553b55f734fb3cf52df49a79cf76d410a77fbe8f5Craig Mautner        assertEquals(errorText, mTextView.getError().toString());
2366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2367300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu        mActivity.runOnUiThread(new Runnable() {
2368300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu            public void run() {
2369300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.setKeyListener(DigitsKeyListener.getInstance());
2370300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.setText("", BufferType.EDITABLE);
2371300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.setError(errorText);
2372300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu                mTextView.requestFocus();
2373300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu            }
2374300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu        });
2375300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu        mInstrumentation.waitForIdleSync();
2376300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu
237703818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "1");
2378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // a key event cause changes to the TextView's text
2379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("1", mTextView.getText().toString());
2380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the error message and icon will be cleared.
2381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getError());
2382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessFilters() {
2385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final InputFilter[] expected = { new InputFilter.AllCaps(),
2386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                new InputFilter.LengthFilter(2) };
2387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener
2389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                = QwertyKeyListener.getInstance(false, Capitalize.NONE);
2390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView = findTextView(R.id.textview_text);
2393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setKeyListener(qwertyKeyListener);
2394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText("", BufferType.EDITABLE);
2395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setFilters(expected);
2396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
2397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(expected, mTextView.getFilters());
2402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
240303818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "a");
2404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text is capitalized by InputFilter.AllCaps
2405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("A", mTextView.getText().toString());
240603818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "b");
2407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the text is capitalized by InputFilter.AllCaps
2408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("AB", mTextView.getText().toString());
240903818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "c");
2410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 'C' could not be accepted, because there is a length filter.
2411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("AB", mTextView.getText().toString());
2412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.setFilters(null);
2415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw IllegalArgumentException!");
2416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (IllegalArgumentException e) {
2417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetFocusedRect() {
2421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Rect rc = new Rect();
2422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2423fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Basic
2424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX(), rc.left);
2427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY(), rc.top);
2429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2431fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Single line
2432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX(), rc.left);
2435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY(), rc.top);
2437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setSelected(true);
2442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                SpannableString text = new SpannableString(mTextView.getText());
2443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Selection.setSelection(text, 3, 13);
2444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setText(text);
2445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getFocusedRect(rc);
2449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView.getLayout());
2450fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        /* Cursor coordinates from getPrimaryHorizontal() may have a fractional
2451fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * component, while the result of getFocusedRect is in int coordinates.
2452fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * It's not practical for these to match exactly, so we compare that the
2453fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * integer components match - there can be a fractional pixel
2454fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien         * discrepancy, which should be okay for all practical applications. */
2455fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3), rc.left);
2456fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(13), rc.right);
2457fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2458fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2459fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2460fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mActivity.runOnUiThread(new Runnable() {
2461fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            public void run() {
2462fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setSelected(true);
2463fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                SpannableString text = new SpannableString(mTextView.getText());
2464fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                Selection.setSelection(text, 13, 3);
2465fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setText(text);
2466fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            }
2467fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2468fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2469fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2470fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2471fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) - 2, rc.left);
2472fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) + 2, rc.right);
2473fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2474fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2475fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2476fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        // Multi lines
2477fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView = findTextView(R.id.textview_text_two_lines);
2478fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2479fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollX(), rc.left);
2480fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
2481fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollY(), rc.top);
2482fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
2483fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2484fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mActivity.runOnUiThread(new Runnable() {
2485fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            public void run() {
2486fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setSelected(true);
2487fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                SpannableString text = new SpannableString(mTextView.getText());
2488fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                Selection.setSelection(text, 2, 4);
2489fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setText(text);
2490fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            }
2491fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2492fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2493fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2494fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2495fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(2), rc.left);
2496fe2fb182b7998f5384f78a6956962966b10b5699Raph Levien        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(4), rc.right);
2497fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2498fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
2499fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio
2500fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mActivity.runOnUiThread(new Runnable() {
2501fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            public void run() {
2502fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setSelected(true);
2503fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                SpannableString text = new SpannableString(mTextView.getText());
2504fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                Selection.setSelection(text, 2, 10); // cross the "\n" and two lines
2505fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio                mTextView.setText(text);
2506fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio            }
2507fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        });
2508fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mInstrumentation.waitForIdleSync();
2509fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getFocusedRect(rc);
2510fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        Path path = new Path();
2511fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        mTextView.getLayout().getSelectionPath(2, 10, path);
2512fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        RectF rcf = new RectF();
2513fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        path.computeBounds(rcf, true);
2514fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertNotNull(mTextView.getLayout());
2515fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(rcf.left - 1, (float) rc.left);
2516fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(rcf.right + 1, (float) rc.right);
2517fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
2518fb0961aa68799b42121f3d8cac094b341c2f9084Fabrice Di Meglio        assertEquals(mTextView.getLayout().getLineBottom(1), rc.bottom);
2519fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2520fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Exception
2521fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
2522fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.getFocusedRect(null);
2523fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException!");
2524fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
2525fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
2526fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2527fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2528fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLineCount() {
2529fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2530fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // this is an one line text with default setting.
2531fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2532fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2533fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it multi-lines
2534fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxWidth(mTextView.getWidth() / 3);
2535fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(1 < mTextView.getLineCount());
2536fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2537fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it to an one line
2538fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMaxWidth(Integer.MAX_VALUE);
2539fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2540fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2541fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set min lines don't effect the lines count for actual text.
2542fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(12);
2543fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
2544fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2545fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2546fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // the internal Layout has not been built.
2547fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getLayout());
2548fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineCount());
2549fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2550fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2551fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetLineBounds() {
2552fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Rect rc = new Rect();
2553fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2554fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineBounds(0, null));
2555fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2556fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getLineBounds(0, rc));
2557fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.left);
2558fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.right);
2559fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.top);
2560fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.bottom);
2561fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2562fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2563fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, null));
2564fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2565fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc));
2566fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.left);
2567fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getWidth(), rc.right);
2568fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, rc.top);
2569fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getHeight(), rc.bottom);
2570fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2571fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2572fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2573fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setPadding(1, 2, 3, 4);
2574fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.BOTTOM);
2575fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2576fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2577fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2578fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc));
2579fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getTotalPaddingLeft(), rc.left);
2580fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getWidth() - mTextView.getTotalPaddingRight(), rc.right);
2581fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getTotalPaddingTop(), rc.top);
2582fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getHeight() - mTextView.getTotalPaddingBottom(), rc.bottom);
2583fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2584fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2585fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetBaseLine() {
2586fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2587fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, mTextView.getBaseline());
2588fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2589fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2590fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getLayout().getLineBaseline(0), mTextView.getBaseline());
2591fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2592fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2593fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2594fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setPadding(1, 2, 3, 4);
2595fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.BOTTOM);
2596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2598fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2599fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = mTextView.getTotalPaddingTop() + mTextView.getLayout().getLineBaseline(0);
2600fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getBaseline());
2601fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2602fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2603fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testPressKey() {
260428715a6877392e4e63cb2b0170c1592fb50079dcJames Cook        initTextViewForTyping();
2605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
260603818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "a");
2607fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("a", mTextView.getText().toString());
260803818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendString(mTextView, "b");
2609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("ab", mTextView.getText().toString());
261003818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL);
2611fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("a", mTextView.getText().toString());
2612fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2613fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2614fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetIncludeFontPadding() {
2615fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2616ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertTrue(mTextView.getIncludeFontPadding());
2617fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2618fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2619fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setWidth(mTextView.getWidth() / 3);
2620fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setPadding(1, 2, 3, 4);
2621fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.BOTTOM);
2622fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2623fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2624fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2625fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2626fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int oldHeight = mTextView.getHeight();
2627fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
2628fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
2629fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setIncludeFontPadding(false);
2630fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
2631fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
2632fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
2633fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2634fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getHeight() < oldHeight);
2635ac8bc1679adcd60c7d0b1580d468ae1f58894d4fRaph Levien        assertFalse(mTextView.getIncludeFontPadding());
2636fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2637fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2638fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testScroll() {
2639fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2640fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2641fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollX());
2642fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollY());
2643fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2644fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //don't set the Scroller, nothing changed.
2645fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.computeScroll();
2646fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollX());
2647fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getScrollY());
2648fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2649fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //set the Scroller
2650fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Scroller s = new Scroller(mActivity);
2651fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(s);
2652fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.startScroll(0, 0, 320, 480, 0);
2653fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.abortAnimation();
2654fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        s.forceFinished(false);
2655fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setScroller(s);
2656fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2657fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.computeScroll();
2658fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(320, mTextView.getScrollX());
2659fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(480, mTextView.getScrollY());
2660fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2661fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2662fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testDebug() {
2663fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2664fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.debug(0);
2665fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2666fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("Hello!");
2667fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(mTextView);
2668fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.debug(1);
2669fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2670fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2671fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSelection() {
2672fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2673fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String text = "This is the content";
2674fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(text, BufferType.SPANNABLE);
2675fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.hasSelection());
2676fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2677fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.selectAll((Spannable) mTextView.getText());
2678fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getSelectionStart());
2679fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(text.length(), mTextView.getSelectionEnd());
2680fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.hasSelection());
2681fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2682fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int selectionStart = 5;
2683fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int selectionEnd = 7;
2684fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), selectionStart);
2685fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionStart());
2686fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionEnd());
2687fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.hasSelection());
2688fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2689fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
2690fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionStart, mTextView.getSelectionStart());
2691fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(selectionEnd, mTextView.getSelectionEnd());
2692fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.hasSelection());
2693fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2694fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
26956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
26966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testOnSelectionChanged_isTriggeredWhenSelectionChanges() {
26976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final MockTextView textView = new MockTextView(mActivity);
26986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String text = "any text";
26996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText(text, BufferType.SPANNABLE);
27006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // assert that there is currently no selection
27026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.hasSelection());
27036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // select all
27056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Selection.selectAll((Spannable) textView.getText());
27066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue("After selectAll OnSelectionChanged should have been called",
27086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                textView.hasCalledOnSelectionChanged());
27096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("OnSelectionChanged should have been called with 0 for selection start",
27106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                0, textView.getSelectionChangedStart());
27116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("OnSelectionChanged should have been called with text length for "
27126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                        + "selection end",
27136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                text.length(), textView.getSelectionChangedEnd());
27146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // reset MockTextView selection flags
27166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.reset();
27176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // change selection
27196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Selection.setSelection((Spannable) textView.getText(), 1, 5);
27206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue("OnSelectionChanged should have been called",
27226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                textView.hasCalledOnSelectionChanged());
27236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("OnSelectionChanged should have been called with 1 for selection start",
27246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                1, textView.getSelectionChangedStart());
27256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("OnSelectionChanged should have been called with -1 for selection end",
27266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                5, textView.getSelectionChangedEnd());
27276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // reset MockTextView selection flags
27296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.reset();
27306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // clear selection
27326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Selection.removeSelection((Spannable) textView.getText());
27336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
27346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue("OnSelectionChanged should have been called",
27356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                textView.hasCalledOnSelectionChanged());
27366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("OnSelectionChanged should have been called with -1 for selection start",
27376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                -1, textView.getSelectionChangedStart());
27386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("OnSelectionChanged should have been called with -1 for selection end",
27396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                -1, textView.getSelectionChangedEnd());
27406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
27416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
2742fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2743fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessEllipsize() {
2744fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.setContentView(R.layout.textview_ellipsize);
2745fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2746fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_default);
2747fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2748fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2749fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_none);
2750fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2751fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2752fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_start);
2753fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.START, mTextView.getEllipsize());
2754fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2755fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_middle);
2756fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.MIDDLE, mTextView.getEllipsize());
2757fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2758fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.ellipsize_end);
2759fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TruncateAt.END, mTextView.getEllipsize());
2760fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2761fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.START);
2762fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize());
2763fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2764fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
2765fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.MIDDLE, mTextView.getEllipsize());
2766fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2767fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.END);
2768fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.END, mTextView.getEllipsize());
2769fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2770fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(null);
2771fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getEllipsize());
2772fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2773fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(10);
2774fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setEllipsize(TextUtils.TruncateAt.START);
2775fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("ThisIsAVeryLongVeryLongVeryLongVeryLongVeryLongWord");
2776fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.invalidate();
2777fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2778fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize());
2779fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no method to check if '...yLongVeryLongWord' is painted in the screen.
2780fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2781fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
27822deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    public void testEllipsizeEndAndNoEllipsizeHasSameBaselineForSingleLine() {
27832deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        int textWidth = calculateTextWidth(LONG_TEXT);
27842deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27852deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        TextView tvEllipsizeEnd = new TextView(getActivity());
27862deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
27872deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setMaxLines(1);
27882deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setWidth(textWidth >> 2);
27892deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setText(LONG_TEXT);
27902deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27912deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        TextView tvEllipsizeNone = new TextView(getActivity());
27922deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setWidth(textWidth >> 2);
27932deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setText("a");
27942deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
27952deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
27962deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
27972deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
27982deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
27992deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.addView(tvEllipsizeEnd, layoutParams);
28002deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.addView(tvEllipsizeNone, layoutParams);
28012deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.setLayoutParams(layoutParams);
28022deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28032deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        mActivity.runOnUiThread(new Runnable() {
28042deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            @Override
28052deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            public void run() {
28062deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                getActivity().setContentView(layout);
28072deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            }
28082deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        });
28092deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        getInstrumentation().waitForIdleSync();
28102deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28112deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        assertEquals("Ellipsized and non ellipsized single line texts should have the same " +
28122deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                        "baseline",
28132deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                tvEllipsizeEnd.getLayout().getLineBaseline(0),
28142deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                tvEllipsizeNone.getLayout().getLineBaseline(0));
28152deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    }
28162deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28172deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    public void testEllipsizeEndAndNoEllipsizeHasSameBaselineForMultiLine() {
28182deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        int textWidth = calculateTextWidth(LONG_TEXT);
28192deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28202deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        TextView tvEllipsizeEnd = new TextView(getActivity());
28212deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
28222deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setMaxLines(2);
28232deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setWidth(textWidth >> 2);
28242deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeEnd.setText(LONG_TEXT);
28252deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28262deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        TextView tvEllipsizeNone = new TextView(getActivity());
28272deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setMaxLines(2);
28282deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setWidth(textWidth >> 2);
28292deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        tvEllipsizeNone.setText(LONG_TEXT);
28302deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28312deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
28322deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
28332deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
28342deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
28352deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28362deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.addView(tvEllipsizeEnd, layoutParams);
28372deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.addView(tvEllipsizeNone, layoutParams);
28382deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        layout.setLayoutParams(layoutParams);
28392deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28402deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        mActivity.runOnUiThread(new Runnable() {
28412deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            @Override
28422deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            public void run() {
28432deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                getActivity().setContentView(layout);
28442deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            }
28452deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        });
28462deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        getInstrumentation().waitForIdleSync();
28472deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
28482deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        for (int i = 0; i < tvEllipsizeEnd.getLineCount(); i++) {
28492deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir            assertEquals("Ellipsized and non ellipsized multi line texts should have the same " +
28502deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                            "baseline for line " + i,
28512deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                    tvEllipsizeEnd.getLayout().getLineBaseline(i),
28522deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir                    tvEllipsizeNone.getLayout().getLineBaseline(i));
28532deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir        }
28542deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir    }
28552deef38f19cb26869b600cd0d075753a9f97d5daSiyamed Sinir
2856672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir    public void testTextViewInWeigthenedLayoutChangesWidthAfterSetText() {
2857672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        final TextView textView = new TextView(getActivity());
2858672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        textView.setEllipsize(TruncateAt.END);
2859672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        textView.setSingleLine(true);
2860672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        textView.setText("a");
2861672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2862672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        TextView otherTextView = new TextView(getActivity());
2863672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        otherTextView.setSingleLine(true);
2864672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        otherTextView.setText("any");
2865672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2866672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        final LinearLayout layout = new LinearLayout(mActivity);
2867672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.setOrientation(LinearLayout.HORIZONTAL);
2868672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2869672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // TextView under test has weight 1, and width 0
2870672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.addView(textView, new LinearLayout.LayoutParams(0,
2871672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
2872672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2873672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // other TextView has default weight
2874672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.addView(otherTextView, new LinearLayout.LayoutParams(
2875672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
2876672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT));
2877672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2878672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        // main layout params
2879672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        layout.setLayoutParams(new ViewGroup.LayoutParams(
2880672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
2881672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2882672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        mActivity.runOnUiThread(new Runnable() {
2883672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            @Override
2884672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            public void run() {
2885672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                getActivity().setContentView(layout);
2886672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            }
2887672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        });
2888672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        getInstrumentation().waitForIdleSync();
2889672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2890672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        int oldWidth = textView.getWidth();
2891672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2892672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        mActivity.runOnUiThread(new Runnable() {
2893672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            @Override
2894672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            public void run() {
2895672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                textView.setText("aaa");
2896672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir            }
2897672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        });
2898672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        getInstrumentation().waitForIdleSync();
2899672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2900672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir        assertTrue("TextView should have larger width after a longer text is set",
2901672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir                textView.getWidth() > oldWidth);
2902672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir    }
2903672de87741b35d488adeabd3a4b9f8440dbc8beeSiyamed Sinir
2904354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testAccessCursorVisible() {
2905fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
2906fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2907fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCursorVisible(true);
2908354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.isCursorVisible());
2909fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCursorVisible(false);
2910354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.isCursorVisible());
2911fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2912fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2913fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnWindowFocusChanged() {
2914fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
2915fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2916fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2917fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnTouchEvent() {
2918fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
2919fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2920fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2921fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnTrackballEvent() {
2922fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
2923fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2924fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2925fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTextColors() {
2926fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // TODO: How to get a suitable TypedArray to test this method.
2927fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2928fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2929fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnKeyShortcut() {
2930fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
2931fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2932fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2933fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2934fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testPerformLongClick() {
2935fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
2936fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText("This is content");
2937938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
2938938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        View.OnLongClickListener mockOnLongClickListener = mock(View.OnLongClickListener.class);
2939938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        when(mockOnLongClickListener.onLongClick(any(View.class))).thenReturn(Boolean.TRUE);
2940938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
2941938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        View.OnCreateContextMenuListener mockOnCreateContextMenuListener =
2942938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                mock(View.OnCreateContextMenuListener.class);
2943938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        doAnswer(new Answer() {
2944938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            public Object answer(InvocationOnMock invocation) {
2945938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                ((ContextMenu) invocation.getArguments() [0]).add("menu item");
2946938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                return null;
2947938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            }
2948938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }).when(mockOnCreateContextMenuListener).onCreateContextMenu(
2949938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), any(View.class), any(ContextMenuInfo.class));
2950938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
2951938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        mTextView.setOnLongClickListener(mockOnLongClickListener);
2952938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        mTextView.setOnCreateContextMenuListener(mockOnCreateContextMenuListener);
2953fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.performLongClick());
2954938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnLongClickListener, times(1)).onLongClick(mTextView);
2955938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyZeroInteractions(mockOnCreateContextMenuListener);
2956fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2957938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        reset(mockOnLongClickListener);
2958938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        when(mockOnLongClickListener.onLongClick(any(View.class))).thenReturn(Boolean.FALSE);
2959fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.performLongClick());
2960938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnLongClickListener, times(1)).onLongClick(mTextView);
2961938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnCreateContextMenuListener, times(1)).onCreateContextMenu(
2962938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), eq(mTextView), any(ContextMenuInfo.class));
2963fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2964938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        reset(mockOnCreateContextMenuListener);
2965fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setOnLongClickListener(null);
2966938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        doNothing().when(mockOnCreateContextMenuListener).onCreateContextMenu(
2967938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), any(View.class), any(ContextMenuInfo.class));
2968fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.performLongClick());
2969938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyNoMoreInteractions(mockOnLongClickListener);
2970938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verify(mockOnCreateContextMenuListener, times(1)).onCreateContextMenu(
2971938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                any(ContextMenu.class), eq(mTextView), any(ContextMenuInfo.class));
2972fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
2973fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2974fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
2975fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testTextAttr() {
2976fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_textAttr);
2977fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getText
2978fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getString(R.string.text_view_hello), mTextView.getText().toString());
2979fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2980fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getCurrentTextColor
2981fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
2982fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
2983fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
2984fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
2985fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
2986fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getHintTextColors().getDefaultColor());
2987fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
2988fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
2989fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2990fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTextScaleX
2991fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1.2f, mTextView.getTextScaleX(), 0.01f);
2992fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2993fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // setTextScaleX
2994fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(2.4f);
2995fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2.4f, mTextView.getTextScaleX(), 0.01f);
2996fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
2997fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(0f);
2998fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0f, mTextView.getTextScaleX(), 0.01f);
2999fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3000fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextScaleX(- 2.4f);
3001fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(- 2.4f, mTextView.getTextScaleX(), 0.01f);
3002fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3003fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTextSize
3004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20f, mTextView.getTextSize(), 0.01f);
3005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3006fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // getTypeface
3007119351956fc53fdd61bfbfb0d1ab43857cf7a6d7Peter Eliasson        // getTypeface will be null if android:typeface is set to normal,
3008c02a9f453c5c1255d668bbd8970f4585ab5ff494Alan Viverette        // and android:style is not set or is set to normal, and
3009c02a9f453c5c1255d668bbd8970f4585ab5ff494Alan Viverette        // android:fontFamily is not set
3010fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTypeface());
3011fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3012fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT);
3013fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.DEFAULT, mTextView.getTypeface());
3014fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // null type face
3015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(null);
3016fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTypeface());
3017fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3018fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // default type face, bold style, note: the type face will be changed
3019fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // after call set method
3020fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
3021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle());
3022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3023fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // null type face, BOLD style
3024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(null, Typeface.BOLD);
3025fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle());
3026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // old type face, null style
3028fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTypeface(Typeface.DEFAULT, 0);
3029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
3030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAppend() {
3034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
3035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 1: check the original length, should be blank as initialised.
3037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getText().length());
3038fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3039fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 2: append a string use append(CharSquence) into the original blank
3040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // buffer, check the content. And upgrading it to BufferType.EDITABLE if it was
3041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // not already editable.
3042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(mTextView.getText() instanceof Editable);
3043fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append.");
3044fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.", mTextView.getText().toString());
3045fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3047fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 3: append a string from 0~3.
3048fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append", 0, 3);
3049fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.App", mTextView.getText().toString());
3050fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3051fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3052fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 4: append a string from 0~0, nothing will be append as expected.
3053fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.append("Append", 0, 0);
3054fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals("Append.App", mTextView.getText().toString());
3055fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getText() instanceof Editable);
3056fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3057fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 5: append a string from -3~3. check the wrong left edge.
3058fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3059fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append("Append", -3, 3);
3060fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw StringIndexOutOfBoundsException");
3061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (StringIndexOutOfBoundsException e) {
3062fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3063fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3064fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 6: append a string from 3~10. check the wrong right edge.
3065fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3066fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append("Append", 3, 10);
3067fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw StringIndexOutOfBoundsException");
3068fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (StringIndexOutOfBoundsException e) {
3069fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3070fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3071fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // 7: append a null string.
3072fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
3073fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView.append(null);
3074fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException");
3075fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
3076fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3077fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3078fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3079f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3080f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_doesNotAddLinksWhenAppendedTextDoesNotContainLinks() {
3081f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3082f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3083f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3084f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3085f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" another text without URL");
3086f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3087f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3088f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3089f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be zero", 0, urlSpans.length);
3090f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL another text without URL", text.toString());
3091f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3092f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3093f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3094f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_doesNotAddLinksWhenAutoLinkIsNotEnabled() {
3095f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3096f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3097f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3098f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3099f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3100f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3101f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3102f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be zero", 0, urlSpans.length);
3103f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL text with URL http://android.com", text.toString());
3104f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3105f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3106f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3107f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksWhenAutoLinkIsEnabled() {
3108f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3109f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3110f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without URL");
3111f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3112f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3113f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3114f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3115f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3116f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length);
3117f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3118f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3119f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text without URL text with URL http://android.com", text.toString());
3120f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3121f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3122f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3123f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksEvenWhenThereAreUrlsSetBefore() {
3124f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3125f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3126f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with URL http://android.com/before");
3127f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3128f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with URL http://android.com");
3129f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3130f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3131f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3132f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be two after appending another URL", 2, urlSpans.length);
3133f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("First URLSpan URL should be same",
3134f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com/before");
3135f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3136f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[1].getURL(), "http://android.com");
3137f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("text with URL http://android.com/before text with URL http://android.com",
3138f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                text.toString());
3139f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3140f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3141f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3142f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_setsMovementMethodWhenTextContainsUrlAndAutoLinkIsEnabled() {
3143f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3144f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3145f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without a URL");
3146f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3147f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(" text with a url: http://android.com");
3148f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3149f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertNotNull("MovementMethod should not be null when text contains url",
3150f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                mTextView.getMovementMethod());
3151f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertTrue("MovementMethod should be instance of LinkMovementMethod when text contains url",
3152f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                mTextView.getMovementMethod() instanceof LinkMovementMethod);
3153f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3154f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3155f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3156f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinksWhenTextIsSpannableAndContainsUrlAndAutoLinkIsEnabled() {
3157f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3158f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3159f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text without a URL");
3160f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3161f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append(new SpannableString(" text with a url: http://android.com"));
3162f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3163f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3164f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3165f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length);
3166f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3167f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3168f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3169f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3170f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3171f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinkIfAppendedTextCompletesPartialUrlAtTheEndOfExistingText() {
3172f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3173f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3174f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with a partial url android.");
3175f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3176f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append("com");
3177f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3178f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3179f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3180f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should be one after appending to partial URL",
3181f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                1, urlSpans.length);
3182f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the appended URL",
3183f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com");
3184f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3185f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3186f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    @UiThreadTest
3187f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    public void testAppend_addsLinkIfAppendedTextUpdatesUrlAtTheEndOfExistingText() {
3188f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView = new TextView(mActivity);
3189f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setAutoLinkMask(Linkify.ALL);
3190f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.setText("text with a url http://android.com");
3191f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3192f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        mTextView.append("/textview");
3193f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3194f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        Spannable text = (Spannable) mTextView.getText();
3195f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
3196f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan count should still be one after extending a URL", 1, urlSpans.length);
3197f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir        assertEquals("URLSpan URL should be same as the new URL",
3198f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir                urlSpans[0].getURL(), "http://android.com/textview");
3199f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir    }
3200f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
32016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
32026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetLetterSpacing_returnsValueThatWasSet() {
32036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
32046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLetterSpacing(2f);
32056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("getLetterSpacing should return the value that was set",
32066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                2f, mTextView.getLetterSpacing());
32076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
32086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
32106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testSetLetterSpacing_changesTextWidth() {
32116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
32126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText("aa");
32136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setLetterSpacing(0f);
32146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextSize(8f);
32156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
32176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
32186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT,
32196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
32206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(textView, layoutParams);
32216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
32226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
32246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
32256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
32266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                getActivity().setContentView(layout);
32276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
32286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
32296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
32306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with zero letter spacing
32326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final float zeroSpacing = textView.getLayout().getLineWidth(0);
32336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getActivity().runOnUiThread(new Runnable() {
32356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
32366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
32376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                textView.setLetterSpacing(1f);
32386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
32396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
32406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
32416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with single letter spacing
32436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final float singleSpacing = textView.getLayout().getLineWidth(0);
32446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getActivity().runOnUiThread(new Runnable() {
32466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
32476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
32486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                textView.setLetterSpacing(2f);
32496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
32506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
32516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
32526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // measure text with double letter spacing
32546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final float doubleSpacing = textView.getLayout().getLineWidth(0);
32556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("Double spacing should have two times the spacing of single spacing",
32576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                doubleSpacing - zeroSpacing, 2f * (singleSpacing - zeroSpacing), 1f);
32586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
32596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
32616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetFontFeatureSettings_returnsValueThatWasSet() {
32626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
32636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setFontFeatureSettings("\"smcp\" on");
32646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals("getFontFeatureSettings should return the value that was set",
32656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                "\"smcp\" on", mTextView.getFontFeatureSettings());
32666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
32676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
32696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetOffsetForPosition_singleLineLtr() {
32706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // asserts getOffsetPosition returns correct values for a single line LTR text
32716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        String text = "aaaaa";
32726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
32736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText(text);
32746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextSize(8f);
32756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setSingleLine(true);
32766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
32786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Drawable drawable = getDrawable(R.drawable.red);
32796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
32806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setCompoundDrawables(drawable, drawable, drawable, drawable);
32816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
32836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
32846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
32856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
32866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(textView, layoutParams);
32876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
32886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
32906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
32916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
32926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                getActivity().setContentView(layout);
32936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
32946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
32956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
32966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
32976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int firstOffset = 0;
32986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int lastOffset = text.length() - 1;
32996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final int midOffset = text.length() / 2;
33006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view
33026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float x = 0f;
33036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float y = textView.getHeight() / 2f;
33046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(firstOffset, textView.getOffsetForPosition(x, y));
33056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text
33076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getLayout().getLineWidth(0) - 1f;
33086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(lastOffset, textView.getOffsetForPosition(x, y));
33096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view
33116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth();
33126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(lastOffset + 1, textView.getOffsetForPosition(x, y));
33136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view - out of bounds
33156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = -1f;
33166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(firstOffset, textView.getOffsetForPosition(x, y));
33176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text
33196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getLayout().getLineWidth(0) / 2f - 1f;
33206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(midOffset, textView.getOffsetForPosition(x, y));
33216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
33226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
33246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetOffsetForPosition_multiLineLtr() {
33256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String line = "aa\n";
33266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String threeLines = line + line + line;
33276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
33286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText(threeLines);
33296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextSize(8f);
33306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setLines(2);
33316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
33336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Drawable drawable = getDrawable(R.drawable.red);
33346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
33356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setCompoundDrawables(drawable, drawable, drawable, drawable);
33366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
33386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
33396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
33406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
33416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(textView, layoutParams);
33426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
33436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
33456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
33466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
33476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                getActivity().setContentView(layout);
33486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
33496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
33506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
33516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Rect lineBounds = new Rect();
33536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.getLayout().getLineBounds(0, lineBounds);
33546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at first line
33566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float x = 0f;
33576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float y = lineBounds.height() / 2f;
33586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, textView.getOffsetForPosition(x, y));
33596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at first line
33616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - 1f;
33626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() - 1, textView.getOffsetForPosition(x, y));
33636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // update lineBounds to be the second line
33656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.getLayout().getLineBounds(1, lineBounds);
33666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        y = lineBounds.top + lineBounds.height() / 2;
33676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at second line
33696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
33706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length(), textView.getOffsetForPosition(x, y));
33716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text at second line
33736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getLayout().getLineWidth(1) - 1f;
33746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() - 1, textView.getOffsetForPosition(x, y));
33756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at second line
33776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - 1f;
33786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() - 1, textView.getOffsetForPosition(x, y));
33796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text at second line
33816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getLayout().getLineWidth(1) / 2f;
33826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() / 2, textView.getOffsetForPosition(x, y));
33836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
33846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
33866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetOffsetForPosition_multiLineRtl() {
33876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String line = "\u0635\u0635\n";
33886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final String threeLines = line + line + line;
33896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
33906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText(threeLines);
33916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextSize(8f);
33926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setLines(2);
33936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // add a compound drawable to TextView to make offset calculation more interesting
33956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Drawable drawable = getDrawable(R.drawable.red);
33966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawable.setBounds(0, 0, 10, 10);
33976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setCompoundDrawables(drawable, drawable, drawable, drawable);
33986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
33996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(mActivity);
34006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
34016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
34026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.WRAP_CONTENT);
34036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(textView, layoutParams);
34046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
34056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
34076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            @Override
34086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
34096a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                getActivity().setContentView(layout);
34106a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
34116a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
34126a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        getInstrumentation().waitForIdleSync();
34136a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34146a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Rect lineBounds = new Rect();
34156a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.getLayout().getLineBounds(0, lineBounds);
34166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at first line
34186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float x = textView.getWidth() - 1f;
34196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        float y = lineBounds.height() / 2f;
34206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(0, textView.getOffsetForPosition(x, y));
34216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at first line
34236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
34246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() - 1, textView.getOffsetForPosition(x, y));
34256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // update lineBounds to be the second line
34276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.getLayout().getLineBounds(1, lineBounds);
34286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        y = lineBounds.top + lineBounds.height() / 2f;
34296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of view at second line
34316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - 1f;
34326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length(), textView.getOffsetForPosition(x, y));
34336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // left edge of view at second line
34356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = 0f;
34366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() - 1, textView.getOffsetForPosition(x, y));
34376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // right edge of text at second line
34396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - textView.getLayout().getLineWidth(1) + 1f;
34406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() - 1, textView.getOffsetForPosition(x, y));
34416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // horizontal center of text at second line
34436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        x = textView.getWidth() - (textView.getLayout().getLineWidth(1) / 2f);
34446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(line.length() + line.length() / 2, textView.getOffsetForPosition(x, y));
34456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
34466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
34486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testIsTextSelectable_returnsFalseByDefault() {
34496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(getActivity());
34506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText("any text");
34516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isTextSelectable());
34526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
34536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
34556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testIsTextSelectable_returnsTrueIfSetTextIsSelectableCalledWithTrue() {
34566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(getActivity());
34576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setText("any text");
34586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextIsSelectable(true);
34596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isTextSelectable());
34606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
34616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
34636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testSetIsTextSelectable() {
34646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(getActivity());
34656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isTextSelectable());
34676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isFocusable());
34686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isFocusableInTouchMode());
34696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isClickable());
34706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse(textView.isLongClickable());
34716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setTextIsSelectable(true);
34736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
34746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isTextSelectable());
34756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isFocusable());
34766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isFocusableInTouchMode());
34776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isClickable());
34786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(textView.isLongClickable());
34796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(textView.getMovementMethod());
34806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
3481f6d7a3822a73508d4bfeb0f21e1adb325a62fd18Siyamed Sinir
3482fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessTransformationMethod() {
3483fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check the password attribute in xml
3484fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_password);
3485fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView);
3486fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(PasswordTransformationMethod.getInstance(),
3487fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3488fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3489fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check the singleLine attribute in xml
3490fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_singleLine);
3491fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(mTextView);
3492fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(SingleLineTransformationMethod.getInstance(),
3493fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3494fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3495fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final QwertyKeyListener qwertyKeyListener = QwertyKeyListener.getInstance(false,
3496fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                Capitalize.NONE);
3497fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final TransformationMethod method = PasswordTransformationMethod.getInstance();
3498fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // change transformation method by function
3499fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3500fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3501fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setKeyListener(qwertyKeyListener);
3502fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setTransformationMethod(method);
350322d40a1fcc078329a7e5a34ff5eeadeca9c70d49Kenny Root                mTransformedText = method.getTransformation(mTextView.getText(), mTextView);
3504fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3505fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.requestFocus();
3506fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3507fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3508fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3509fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(PasswordTransformationMethod.getInstance(),
3510fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getTransformationMethod());
3511fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
351203818d9cc48f51e2ef65eacb2cdf40d90260c29eSiyamed Sinir        mKeyEventUtil.sendKeys(mTextView, "H E 2*L O");
3513fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3514fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3515fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.append(" ");
3516fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3517fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3518fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3519fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3520354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // It will get transformed after a while
3521354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // We're waiting for transformation to "******"
3522354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(TIMEOUT, () -> mTransformedText.toString()
3523354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov                .equals("\u2022\u2022\u2022\u2022\u2022\u2022"));
3524fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3525fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set null
3526fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3527fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3528fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setTransformationMethod(null);
3529fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3530fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3531fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3532fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(mTextView.getTransformationMethod());
3533fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3534fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3535fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3536fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testCompound() {
3537fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
3538fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int padding = 3;
3539fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Drawable[] drawables = mTextView.getCompoundDrawables();
3540fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[0]);
3541fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[1]);
3542fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[2]);
3543fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3544fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3545fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test setCompoundDrawablePadding and getCompoundDrawablePadding
3546fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablePadding(padding);
3547fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(padding, mTextView.getCompoundDrawablePadding());
3548fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3549fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using resid, 0 represents null
3550fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.start, R.drawable.pass,
3551fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                R.drawable.failed, 0);
3552fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3553fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3554fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3555fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        WidgetTestUtils.assertEquals(getBitmap(R.drawable.start),
3556fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[0]).getBitmap());
3557fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3558fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        WidgetTestUtils.assertEquals(getBitmap(R.drawable.pass),
3559fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[1]).getBitmap());
3560fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3561fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        WidgetTestUtils.assertEquals(getBitmap(R.drawable.failed),
3562fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                ((BitmapDrawable) drawables[2]).getBitmap());
3563fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3564fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3565fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
35669776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        Drawable left = getDrawable(R.drawable.blue);
35679776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        Drawable right = getDrawable(R.drawable.yellow);
35689776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        Drawable top = getDrawable(R.drawable.red);
3569fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3570fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // using drawables directly
3571fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, null);
3572fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3573fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3574fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3575fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(left, drawables[0]);
3576fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3577fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(top, drawables[1]);
3578fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3579fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(right, drawables[2]);
3580fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3581fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3582fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3583fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check compound padding
3584fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingLeft() + padding + left.getIntrinsicWidth(),
3585fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingLeft());
3586fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingTop() + padding + top.getIntrinsicHeight(),
3587fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingTop());
3588fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingRight() + padding + right.getIntrinsicWidth(),
3589fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingRight());
3590fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom());
3591fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3592fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set bounds to drawables and set them again.
3593fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        left.setBounds(0, 0, 1, 2);
3594fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        right.setBounds(0, 0, 3, 4);
3595fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 5, 6);
3596fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // usinf drawables
3597fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(left, top, right, null);
3598fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        drawables = mTextView.getCompoundDrawables();
3599fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3600fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableLeft
3601fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(left, drawables[0]);
3602fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableTop
3603fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(top, drawables[1]);
3604fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableRight
3605fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(right, drawables[2]);
3606fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // drawableBottom
3607fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(drawables[3]);
3608fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3609fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // check compound padding
3610fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingLeft() + padding + left.getBounds().width(),
3611fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingLeft());
3612fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingTop() + padding + top.getBounds().height(),
3613fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingTop());
3614fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingRight() + padding + right.getBounds().width(),
3615fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCompoundPaddingRight());
3616fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom());
3617fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3618fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
36196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
36206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @UiThreadTest
36216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetCompoundDrawablesRelative() {
36226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // prepare textview
36236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView = new TextView(mActivity);
36246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // prepare drawables
36266a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Drawable start = getDrawable(R.drawable.blue);
36276a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Drawable end = getDrawable(R.drawable.yellow);
36286a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Drawable top = getDrawable(R.drawable.red);
36296a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final Drawable bottom = getDrawable(R.drawable.black);
36306a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(start);
36316a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(end);
36326a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(top);
36336a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(bottom);
36346a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36356a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        Drawable[] drawables = mTextView.getCompoundDrawablesRelative();
36366a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
36376a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
36386a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[0]);
36396a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[1]);
36406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[2]);
36416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[3]);
36426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
36446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(start, top, end, bottom);
36456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
36466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
36486a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
36496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(start, drawables[0]);
36506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(top, drawables[1]);
36516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(end, drawables[2]);
36526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(bottom, drawables[3]);
36536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
36556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(start, top, end, bottom);
36566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
36576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
36596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
36606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(start, drawables[0]);
36616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(top, drawables[1]);
36626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(end, drawables[2]);
36636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertSame(bottom, drawables[3]);
36646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mTextView.setCompoundDrawablesRelative(null, null, null, null);
36666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        drawables = mTextView.getCompoundDrawablesRelative();
36676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNotNull(drawables);
36696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(4, drawables.length);
36706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[0]);
36716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[1]);
36726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[2]);
36736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertNull(drawables[3]);
36746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
36756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
36766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
3677fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSingleLine() {
3678013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        final TextView textView = new TextView(mActivity);
3679013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        setSpannableText(textView, "This is a really long sentence"
3680013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                + " which can not be placed in one line on the screen.");
3681013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
3682013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        // Narrow layout assures that the text will get wrapped.
36836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout innerLayout = new FrameLayout(mActivity);
3684013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        innerLayout.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
3685013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        innerLayout.addView(textView);
3686013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
3687013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        final FrameLayout layout = new FrameLayout(mActivity);
3688013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        layout.addView(innerLayout);
3689013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu
3690013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        mActivity.runOnUiThread(new Runnable() {
3691013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu            public void run() {
3692013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                mActivity.setContentView(layout);
3693013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.setSingleLine(true);
3694013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu            }
3695013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        });
3696013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        mInstrumentation.waitForIdleSync();
3697fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3698fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(SingleLineTransformationMethod.getInstance(),
3699013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.getTransformationMethod());
3700da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3701da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        int singleLineWidth = 0;
3702da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        int singleLineHeight = 0;
3703da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3704da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        if (textView.getLayout() != null) {
3705da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            singleLineWidth = textView.getLayout().getWidth();
3706da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            singleLineHeight = textView.getLayout().getHeight();
3707da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3708fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3709fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3710fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3711013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.setSingleLine(false);
3712fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3713fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3714fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3715013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu        assertEquals(null, textView.getTransformationMethod());
3716da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3717da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        if (textView.getLayout() != null) {
3718da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            assertTrue(textView.getLayout().getHeight() > singleLineHeight);
3719da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            assertTrue(textView.getLayout().getWidth() < singleLineWidth);
3720da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3721fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3722fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // same behaviours as setSingLine(true)
3723fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3724fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3725013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.setSingleLine();
3726fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3727fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3728fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3729fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(SingleLineTransformationMethod.getInstance(),
3730013d5ee5428a0fde1cbe1befa4587b0d7a5e39c1Brian Muramatsu                textView.getTransformationMethod());
3731da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu
3732da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        if (textView.getLayout() != null) {
3733da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            assertEquals(singleLineHeight, textView.getLayout().getHeight());
3734da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu            assertEquals(singleLineWidth, textView.getLayout().getWidth());
3735da492b574cec4f919a3952d3e03b098e7eb01ffeWei Liu        }
3736fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3737fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3738fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
373998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testAccessMaxLines() {
3740fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3741fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3742fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float[] widths = new float[LONG_TEXT.length()];
3743fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.getPaint().getTextWidths(LONG_TEXT, widths);
3744fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        float totalWidth = 0.0f;
3745fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        for (float f : widths) {
3746fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            totalWidth += f;
3747fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
3748fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int stringWidth = (int) totalWidth;
3749fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(stringWidth >> 2);
3750fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(LONG_TEXT);
3751fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3752fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        final int maxLines = 2;
3753fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > maxLines);
3754fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3755fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setMaxLines(maxLines);
3756fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.requestLayout();
3757fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
375898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(2, mTextView.getMaxLines());
375998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMaxHeight());
3760fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getHeight() <= maxLines * mTextView.getLineHeight());
3761fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3762fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3763636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    public int calculateTextWidth(String text) {
3764636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView = findTextView(R.id.textview_text);
3765636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3766636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        // Set the TextView width as the half of the whole text.
3767636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        float[] widths = new float[text.length()];
3768636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView.getPaint().getTextWidths(text, widths);
3769636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        float textfieldWidth = 0.0f;
3770636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        for (int i = 0; i < text.length(); ++i) {
3771636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            textfieldWidth += widths[i];
3772636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        }
3773636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        return (int)textfieldWidth;
3774636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3775636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    }
3776636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3777636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    @UiThreadTest
3778636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    public void testHyphenationNotHappen_frequencyNone() {
3779636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        final int[] BREAK_STRATEGIES = {
3780636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.BREAK_STRATEGY_SIMPLE, Layout.BREAK_STRATEGY_HIGH_QUALITY,
3781636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.BREAK_STRATEGY_BALANCED };
3782636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3783636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView = findTextView(R.id.textview_text);
3784636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3785636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        for (int breakStrategy : BREAK_STRATEGIES) {
3786636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            for (int charWidth = 10; charWidth < 120; charWidth += 5) {
3787636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                // Change the text view's width to charWidth width.
3788636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setWidth(calculateTextWidth(LONG_TEXT.substring(0, charWidth)));
3789636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3790636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setText(LONG_TEXT);
3791636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setBreakStrategy(breakStrategy);
3792636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3793636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
3794636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3795636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.requestLayout();
3796636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.onPreDraw();  // For freezing the layout.
3797636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                Layout layout = mTextView.getLayout();
3798636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3799636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                final int lineCount = layout.getLineCount();
3800636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                for (int line = 0; line < lineCount; ++line) {
3801636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    final int lineEnd = layout.getLineEnd(line);
3802636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // In any width, any break strategy, hyphenation should not happen if
3803636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // HYPHENATION_FREQUENCY_NONE is specified.
3804636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    assertTrue(lineEnd == LONG_TEXT.length() ||
3805636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                            Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1)));
3806636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                }
3807636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            }
3808636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        }
3809636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    }
3810636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3811636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    @UiThreadTest
3812636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    public void testHyphenationNotHappen_breakStrategySimple() {
3813636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        final int[] HYPHENATION_FREQUENCIES = {
3814636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.HYPHENATION_FREQUENCY_NORMAL, Layout.HYPHENATION_FREQUENCY_FULL,
3815636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            Layout.HYPHENATION_FREQUENCY_NONE };
3816636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3817636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        mTextView = findTextView(R.id.textview_text);
3818636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3819636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        for (int hyphenationFrequency: HYPHENATION_FREQUENCIES) {
3820636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            for (int charWidth = 10; charWidth < 120; charWidth += 5) {
3821636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                // Change the text view's width to charWidth width.
3822636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setWidth(calculateTextWidth(LONG_TEXT.substring(0, charWidth)));
3823636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3824636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setText(LONG_TEXT);
3825636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
3826636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3827636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.setHyphenationFrequency(hyphenationFrequency);
3828636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3829636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.requestLayout();
3830636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                mTextView.onPreDraw();  // For freezing the layout.
3831636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                Layout layout = mTextView.getLayout();
3832636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3833636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                final int lineCount = layout.getLineCount();
3834636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                for (int line = 0; line < lineCount; ++line) {
3835636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    final int lineEnd = layout.getLineEnd(line);
3836636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // In any width, any hyphenation frequency, hyphenation should not happen if
3837636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    // BREAK_STRATEGY_SIMPLE is specified.
3838636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                    assertTrue(lineEnd == LONG_TEXT.length() ||
3839636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                            Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1)));
3840636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka                }
3841636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka            }
3842636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka        }
3843636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka    }
3844636e9b2547b13f54b22ffd1451d5625a5183a4cdSeigo Nonaka
3845fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3846fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetMaxLinesException() {
384772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
384872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mActivity.setContentView(mTextView);
3849fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(mTextView.getWidth() >> 3);
385072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setMaxLines(-1);
3851fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3852fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
385398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testAccessMinLines() {
3854fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3855fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 3);
3856fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLines = mTextView.getLineCount();
3857fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3858fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(originalLines - 1);
3859fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight());
386098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalLines - 1, mTextView.getMinLines());
386198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinHeight());
3862fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3863fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setMinLines(originalLines + 1);
3864fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight());
386598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(originalLines + 1, mTextView.getMinLines());
386698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(-1, mTextView.getMinHeight());
3867fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3868fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3869fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetLines() {
3870fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3871fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make it multiple lines
3872fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 3);
3873fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int originalLines = mTextView.getLineCount();
3874fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3875fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(originalLines - 1);
3876fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight());
3877fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3878fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(originalLines + 1);
3879fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight());
3880fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3881fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3882fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3883fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetLinesException() {
388472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
388572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mActivity.setContentView(mTextView);
388672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setWidth(mTextView.getWidth() >> 3);
388772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setLines(-1);
3888fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3889fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3890fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3891fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetExtendedPaddingTop() {
3892fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3893fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3894fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getExtendedPaddingTop());
3895fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3896fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
38979776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        final Drawable top = getDrawable(R.drawable.red);
3898fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 100, 10);
3899fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, top, null, null);
3900fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingTop(), mTextView.getExtendedPaddingTop());
3901fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3902fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3903fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLines(mTextView.getLineCount() - 1);
3904fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.BOTTOM);
3905fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3906fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getExtendedPaddingTop() > 0);
3907fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3908fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3909fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3910fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetExtendedPaddingBottom() {
3911fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3912fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3913fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getExtendedPaddingBottom());
3914fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3915fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
39169776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        final Drawable bottom = getDrawable(R.drawable.red);
3917fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        bottom.setBounds(0, 0, 100, 10);
3918fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, null, null, bottom);
3919fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingBottom(), mTextView.getExtendedPaddingBottom());
3920fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3921fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3922fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setLines(mTextView.getLineCount() - 1);
3923fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER_VERTICAL);
3924fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3925fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getExtendedPaddingBottom() > 0);
3926fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3927fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3928fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingTop() {
3929fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3930fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3931fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingTop());
3932fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3933fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
39349776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        final Drawable top = getDrawable(R.drawable.red);
3935fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        top.setBounds(0, 0, 100, 10);
3936fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3937fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3938fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setCompoundDrawables(null, top, null, null);
3939fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setLines(mTextView.getLineCount() - 1);
3940fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.BOTTOM);
3941fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3942fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3943fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3944fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getExtendedPaddingTop(), mTextView.getTotalPaddingTop());
3945fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3946fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3947fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(mTextView.getLineCount() + 1);
3948fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = mTextView.getHeight()
3949fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingBottom()
3950fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getLayout().getLineTop(mTextView.getLineCount());
3951fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getTotalPaddingTop());
3952fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3953fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3954fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingBottom() {
3955fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3956fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3957fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingBottom());
3958fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3959fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
39609776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        final Drawable bottom = getDrawable(R.drawable.red);
3961fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        bottom.setBounds(0, 0, 100, 10);
3962fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
3963fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
3964fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setCompoundDrawables(null, null, null, bottom);
3965fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setLines(mTextView.getLineCount() - 1);
3966fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setGravity(Gravity.CENTER_VERTICAL);
3967fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
3968fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
3969fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
3970fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getExtendedPaddingBottom(), mTextView.getTotalPaddingBottom());
3971fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3972fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change line count
3973fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setLines(mTextView.getLineCount() + 1);
3974fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        int expected = ((mTextView.getHeight()
3975fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingBottom()
3976fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getExtendedPaddingTop()
3977fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                - mTextView.getLayout().getLineBottom(mTextView.getLineCount())) >> 1)
3978fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                + mTextView.getExtendedPaddingBottom();
3979fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(expected, mTextView.getTotalPaddingBottom());
3980fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3981fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3982fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
3983fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingLeft() {
3984fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
3985fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
3986fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingLeft());
3987fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3988fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
39899776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        Drawable left = getDrawable(R.drawable.red);
3990fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        left.setBounds(0, 0, 10, 100);
3991fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(left, null, null, null);
3992fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.RIGHT);
3993fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft());
3994fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
3995fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change width
3996fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(Integer.MAX_VALUE);
3997fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft());
3998fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
3999fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4000fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    @UiThreadTest
4001fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetTotalPaddingRight() {
4002fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
4003fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Initialized value
4004fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getTotalPaddingRight());
4005fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4006fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // After Set a Drawable
40079776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        Drawable right = getDrawable(R.drawable.red);
4008fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        right.setBounds(0, 0, 10, 100);
4009fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setCompoundDrawables(null, null, right, null);
4010fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setGravity(Gravity.CENTER_HORIZONTAL);
4011fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight());
4012fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4013fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Change width
4014fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setWidth(Integer.MAX_VALUE);
4015fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight());
4016fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4017fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4018fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetUrls() {
4019fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
4020fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4021fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        URLSpan[] spans = mTextView.getUrls();
4022fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, spans.length);
4023fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4024fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String url = "http://www.google.com";
4025fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String email = "name@gmail.com";
4026fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        String string = url + " mailto:" + email;
4027fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        SpannableString spannable = new SpannableString(string);
4028fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new URLSpan(url), 0, url.length(), 0);
4029fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
4030fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
4031fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, spans.length);
4032fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(url, spans[0].getURL());
4033fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4034fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new URLSpan(email), 0, email.length(), 0);
4035fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
4036fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4037fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
4038fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
4039fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(url, spans[0].getURL());
4040fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(email, spans[1].getURL());
4041fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4042fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test the situation that param what is not a URLSpan
4043fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spannable.setSpan(new Object(), 0, 9, 0);
4044fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setText(spannable, BufferType.SPANNABLE);
4045fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        spans = mTextView.getUrls();
4046fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, spans.length);
4047fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4048fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4049fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetPadding() {
4050fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
4051fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4052fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPadding(0, 1, 2, 4);
4053fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, mTextView.getPaddingLeft());
4054fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getPaddingTop());
4055fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(2, mTextView.getPaddingRight());
4056fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(4, mTextView.getPaddingBottom());
4057fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4058fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setPadding(10, 20, 30, 40);
4059fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(10, mTextView.getPaddingLeft());
4060fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20, mTextView.getPaddingTop());
4061fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(30, mTextView.getPaddingRight());
4062fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(40, mTextView.getPaddingBottom());
4063fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4064fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4065fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testDeprecatedSetTextAppearance() {
4066fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = new TextView(mActivity);
4067fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4068fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_All);
4069fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4070fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
4071fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(20f, mTextView.getTextSize(), 0.01f);
4072fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
4073fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.red),
4074fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
4075fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4076fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
4077fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4078fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Colors);
4079fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4080fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentTextColor());
4081fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4082fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getCurrentHintTextColor());
4083fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
4084fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.getLinkTextColors().getDefaultColor());
4085fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4086fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_NotColors);
4087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(17f, mTextView.getTextSize(), 0.01f);
4088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
4089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Style);
4091fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(null, mTextView.getTypeface());
4092fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4093fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4094fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testSetTextAppearance() {
4095fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView = new TextView(mActivity);
4096fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4097fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_All);
4098fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4099fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentTextColor());
4100fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(20f, mTextView.getTextSize(), 0.01f);
4101fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
4102fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.red),
4103fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentHintTextColor());
4104fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4105fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getLinkTextColors().getDefaultColor());
41066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
41076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mTextView.getHighlightColor());
4108fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4109fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_Colors);
4110fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.black),
4111fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentTextColor());
4112fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
4113fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getCurrentHintTextColor());
4114fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
4115fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai                mTextView.getLinkTextColors().getDefaultColor());
41166a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(mActivity.getResources().getColor(R.drawable.red),
41176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mTextView.getHighlightColor());
4118fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4119fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_NotColors);
4120fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(17f, mTextView.getTextSize(), 0.01f);
4121fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
4122fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4123fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setTextAppearance(R.style.TextAppearance_Style);
4124fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(null, mTextView.getTypeface());
4125fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    }
4126fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnPreDraw() {
4128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4130fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4131fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    public void testAccessCompoundDrawableTint() {
4132fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView = new TextView(mActivity);
4133fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4134fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        ColorStateList colors = ColorStateList.valueOf(Color.RED);
4135fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setCompoundDrawableTintList(colors);
4136fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        mTextView.setCompoundDrawableTintMode(PorterDuff.Mode.XOR);
4137fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertSame(colors, mTextView.getCompoundDrawableTintList());
4138fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4139f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4140f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        // Ensure the tint is preserved across drawable changes.
4141f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawablesRelative(null, null, null, null);
4142f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4143f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4144f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4145f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawables(null, null, null, null);
4146f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4147f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4148f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette
4149f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr1 = new ColorDrawable(Color.RED);
4150f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr2 = new ColorDrawable(Color.GREEN);
4151f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr3 = new ColorDrawable(Color.BLUE);
4152f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        ColorDrawable dr4 = new ColorDrawable(Color.YELLOW);
4153f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        mTextView.setCompoundDrawables(dr1, dr2, dr3, dr4);
4154f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertSame(colors, mTextView.getCompoundDrawableTintList());
4155f7773bad2586cf5562f81e49ad5353396744542eAlan Viverette        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
4156fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai    }
4157fc8d65e3fed8c61cd1cb442ecafc24ecf2a9a56bJun Mukai
4158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetHorizontallyScrolling() {
4159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make the text view has more than one line
4160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mTextView = findTextView(R.id.textview_text);
4161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setWidth(mTextView.getWidth() >> 1);
4162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > 1);
4163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHorizontallyScrolling(true);
4165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(1, mTextView.getLineCount());
4166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        setHorizontallyScrolling(false);
4168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(mTextView.getLineCount() > 1);
4169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testComputeHorizontalScrollRange() {
4172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test when layout is null
4174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getLayout());
4175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getWidth(), textView.computeHorizontalScrollRange());
4176fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setFrame(0, 0, 40, 50);
4178fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getWidth(), textView.computeHorizontalScrollRange());
4179fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // set the layout
4181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(textView);
4182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getLayout().getWidth(), textView.computeHorizontalScrollRange());
4183fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4185fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testComputeVerticalScrollRange() {
4186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // test when layout is null
4188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getLayout());
4189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, textView.computeVerticalScrollRange());
4190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setFrame(0, 0, 40, 50);
4192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getHeight(), textView.computeVerticalScrollRange());
4193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4194fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //set the layout
4195fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        layout(textView);
4196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(textView.getLayout().getHeight(), textView.computeVerticalScrollRange());
4197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testDrawableStateChanged() {
4200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.reset();
4203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.refreshDrawableState();
4204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.hasCalledDrawableStateChanged());
4205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetDefaultEditable() {
4208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4209fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4210fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //the TextView#getDefaultEditable() does nothing, and always return false.
4211fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(textView.getDefaultEditable());
4212fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testGetDefaultMovementMethod() {
4215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //the TextView#getDefaultMovementMethod() does nothing, and always return null.
4218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getDefaultMovementMethod());
4219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4220fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4221fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnCreateContextMenu() {
4222fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnDetachedFromWindow() {
4226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4227fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4228fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4229fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnDraw() {
4230fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnFocusChanged() {
4234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4236fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnMeasure() {
4238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnTextChanged() {
4242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testSetFrame() {
4246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        MockTextView textView = new MockTextView(mActivity);
4247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //Assign a new size to this view
4249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.setFrame(0, 0, 320, 480));
4250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, textView.getFrameLeft());
4251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(0, textView.getFrameTop());
4252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(320, textView.getFrameRight());
4253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(480, textView.getFrameBottom());
4254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //Assign a same size to this view
4256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(textView.setFrame(0, 0, 320, 480));
4257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        //negative input
4259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.setFrame(-1, -1, -1, -1));
4260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, textView.getFrameLeft());
4261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, textView.getFrameTop());
4262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, textView.getFrameRight());
4263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(-1, textView.getFrameBottom());
4264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testMarquee() {
4267354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Both are pointing to the same object. This works around current limitation in CTS
4268354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // coverage report tool for properly reporting coverage of base class method calls.
4269354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final MockTextView mockTextView = new MockTextView(mActivity);
4270354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final TextView textView = mockTextView;
4271354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
4272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setText(LONG_TEXT);
4273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setSingleLine();
4274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setEllipsize(TruncateAt.MARQUEE);
4275bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu        textView.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
4276bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu
4277bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu        final FrameLayout layout = new FrameLayout(mActivity);
4278bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu        layout.addView(textView);
4279bed9d222439713a766c3d5c91fae1526b5bc35dcBrian Muramatsu
4280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // make the fading to be shown
4281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setHorizontalFadingEdgeEnabled(true);
4282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4283354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> mActivity.setContentView(layout));
4284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TestSelectedRunnable runnable = new TestSelectedRunnable(textView) {
4287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
4288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setMarqueeRepeatLimit(-1);
4289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // force the marquee to start
4290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected1();
4291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setSelected(true);
4292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected2();
4293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
4294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
4295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(runnable);
4296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // wait for the marquee to run
4298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // fading is shown on both sides if the marquee runs for a while
4299354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(TIMEOUT, () -> mockTextView.getLeftFadingEdgeStrength() > 0.0f
4300354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov                && mockTextView.getRightFadingEdgeStrength() > 0.0f);
4301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
43020f095ca986d7558f9f5260c71a12cef4474d9da3Siyamed Sinir        // wait for left marquee to fully apply
4303354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(TIMEOUT, () -> mockTextView.getLeftFadingEdgeStrength() > 0.99f);
4304354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
4305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(runnable.getIsSelected1());
4306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(runnable.getIsSelected2());
4307354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(-1, textView.getMarqueeRepeatLimit());
4308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        runnable = new TestSelectedRunnable(textView) {
4310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
4311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setMarqueeRepeatLimit(0);
4312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                // force the marquee to stop
4313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected1();
4314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setSelected(false);
4315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                saveIsSelected2();
4316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                textView.setGravity(Gravity.LEFT);
4317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
4318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        };
4319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // force the marquee to stop
4320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(runnable);
4321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(runnable.getIsSelected1());
4323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertFalse(runnable.getIsSelected2());
4324354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(0.0f, mockTextView.getLeftFadingEdgeStrength(), 0.01f);
4325354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mockTextView.getRightFadingEdgeStrength() > 0.0f);
4326354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(0, textView.getMarqueeRepeatLimit());
4327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4328354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setGravity(Gravity.RIGHT));
4329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4330354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mockTextView.getLeftFadingEdgeStrength() > 0.0f);
4331354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(0.0f, mockTextView.getRightFadingEdgeStrength(), 0.01f);
4332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4333354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setGravity(Gravity.CENTER_HORIZONTAL));
4334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
4335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // there is no left fading (Is it correct?)
4336354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(0.0f, mockTextView.getLeftFadingEdgeStrength(), 0.01f);
4337354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mockTextView.getRightFadingEdgeStrength() > 0.0f);
4338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4339fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
43406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
43416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testGetMarqueeRepeatLimit() {
43426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final TextView textView = new TextView(mActivity);
43436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
43446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        textView.setMarqueeRepeatLimit(10);
43456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertEquals(10, textView.getMarqueeRepeatLimit());
43466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
43476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
4348fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnKeyMultiple() {
4349fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4350fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4351fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4352fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessInputExtras() throws XmlPullParserException, IOException {
4353fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView textView = new TextView(mActivity);
4354fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setText(null, BufferType.EDITABLE);
4355fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT);
4356fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4357fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // do not create the extras
4358fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getInputExtras(false));
4359fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4360fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // create if it does not exist
4361fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        Bundle inputExtras = textView.getInputExtras(true);
4362fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(inputExtras);
4363fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(inputExtras.isEmpty());
4364fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4365fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // it is created already
4366fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNotNull(textView.getInputExtras(false));
4367fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        try {
4369fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            textView.setInputExtras(R.xml.input_extras);
4370fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            fail("Should throw NullPointerException!");
4371fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        } catch (NullPointerException e) {
4372fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
4373fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4374fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4375fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessContentType() {
4376fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView textView = new TextView(mActivity);
4377fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setText(null, BufferType.EDITABLE);
4378fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setKeyListener(null);
4379fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setTransformationMethod(null);
4380fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4381fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_DATETIME
4382fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL);
4383fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4384fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL, textView.getInputType());
4385fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof DateTimeKeyListener);
4386fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4387fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_DATETIME
4388fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE);
4389fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4390fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE, textView.getInputType());
4391fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof DateKeyListener);
4392fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4393fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_DATETIME
4394fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME);
4395fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4396fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME, textView.getInputType());
4397fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof TimeKeyListener);
4398fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4399fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_NUMBER
4400fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4401fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED);
4402fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_NUMBER
4403fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4404fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED, textView.getInputType());
4405fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(), DigitsKeyListener.getInstance(true, true));
4406fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4407fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_PHONE);
4408fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_PHONE, textView.getInputType());
4409fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof DialerKeyListener);
4410fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4411fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT
4412fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
4413fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4414fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, textView.getInputType());
4415fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(), TextKeyListener.getInstance(true, Capitalize.NONE));
4416fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4417fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setSingleLine();
4418fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4419fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT
4420fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4421fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
4422fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4423fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4424fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, textView.getInputType());
4425fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(),
4426fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.CHARACTERS));
4427fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4428fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4429fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT
4430fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
4431fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4432fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS, textView.getInputType());
4433fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(),
4434fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.WORDS));
4435fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4436fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4437fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_CLASS_TEXT
4438fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
4439fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4440fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, textView.getInputType());
4441fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertSame(textView.getKeyListener(),
4442fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                TextKeyListener.getInstance(false, Capitalize.SENTENCES));
4443fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4444fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setInputType(InputType.TYPE_NULL);
4445fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_NULL, textView.getInputType());
4446fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getKeyListener() instanceof TextKeyListener);
4447fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4448fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4449fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testAccessRawContentType() {
4450fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        TextView textView = new TextView(mActivity);
4451fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setText(null, BufferType.EDITABLE);
4452fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setKeyListener(null);
4453fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setTransformationMethod(null);
4454fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4455fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4456fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL);
4457fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4458fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_NORMAL, textView.getInputType());
4459fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4460fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4461fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4462fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4463fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE);
4464fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4465fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_DATE, textView.getInputType());
4466fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4467fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4468fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4469fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
4470fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME);
4471fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_DATETIME
4472fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_DATETIME_VARIATION_TIME, textView.getInputType());
4473fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4474fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4475fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4476fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_NUMBER
4477fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4478fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED);
4479fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_NUMBER
4480fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_DECIMAL
4481fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_NUMBER_FLAG_SIGNED, textView.getInputType());
4482fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4483fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4484fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4485fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_PHONE);
4486fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_PHONE, textView.getInputType());
4487fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4488fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4489fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4490fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_TEXT
4491fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
4492fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4493fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, textView.getInputType());
4494fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getTransformationMethod());
4495fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4496fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4497fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setSingleLine();
4498fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4499fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_TEXT
4500fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4501fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
4502fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4503fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_MULTI_LINE
4504fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, textView.getInputType());
4505fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4506fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4507fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4508fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_TEXT
4509fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
4510fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4511fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_WORDS, textView.getInputType());
4512fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4513fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4514fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4515fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_CLASS_TEXT
4516fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
4517fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertEquals(InputType.TYPE_CLASS_TEXT
4518fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, textView.getInputType());
4519fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4520fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4521fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4522fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        textView.setRawInputType(InputType.TYPE_NULL);
4523fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
4524fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        assertNull(textView.getKeyListener());
4525fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4526fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
4527fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    public void testOnPrivateIMECommand() {
4528fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        // Do not test. Implementation details.
4529fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
4530fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
453172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testFoo() {
453272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // Do not test. Implementation details.
453372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
453472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
453572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testVerifyDrawable() {
453672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        MockTextView textView = new MockTextView(mActivity);
453772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
45389776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        Drawable d = getDrawable(R.drawable.pass);
453972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(textView.verifyDrawable(d));
454072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
454172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        textView.setCompoundDrawables(null, d, null, null);
454272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(textView.verifyDrawable(d));
454372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
454472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
454572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessPrivateImeOptions() {
454672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
454772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getPrivateImeOptions());
454872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
454972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setPrivateImeOptions("com.example.myapp.SpecialMode=3");
455072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("com.example.myapp.SpecialMode=3", mTextView.getPrivateImeOptions());
455172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
455272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setPrivateImeOptions(null);
455372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getPrivateImeOptions());
455472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
455572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
455672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testSetOnEditorActionListener() {
455772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
455872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
455998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView.OnEditorActionListener mockOnEditorActionListener =
456098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                mock(TextView.OnEditorActionListener.class);
456198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verifyZeroInteractions(mockOnEditorActionListener);
456272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
456398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setOnEditorActionListener(mockOnEditorActionListener);
456498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verifyZeroInteractions(mockOnEditorActionListener);
456572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
456672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.onEditorAction(EditorInfo.IME_ACTION_DONE);
456798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockOnEditorActionListener, times(1)).onEditorAction(mTextView,
456898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                EditorInfo.IME_ACTION_DONE, null);
456972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
457072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
457172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessImeOptions() {
457272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
457372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions());
457472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
457572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_ACTION_GO);
457672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_ACTION_GO, mTextView.getImeOptions());
457772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
457872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_ACTION_DONE);
457972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_ACTION_DONE, mTextView.getImeOptions());
458072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
458172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeOptions(EditorInfo.IME_NULL);
458272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions());
458372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
458472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
458572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testAccessImeActionLabel() {
458672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
458772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertNull(mTextView.getImeActionLabel());
458872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, mTextView.getImeActionId());
458972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
459072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setImeActionLabel("pinyin", 1);
459172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("pinyin", mTextView.getImeActionLabel().toString());
459272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(1, mTextView.getImeActionId());
459372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
459472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4595d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa    public void testAccessImeHintLocales() {
4596d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        final TextView textView = new TextView(mActivity);
4597d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setText("", BufferType.EDITABLE);
4598d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setKeyListener(null);
4599d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setRawInputType(InputType.TYPE_CLASS_TEXT);
4600d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        assertNull(textView.getImeHintLocales());
4601d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        {
4602d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            final EditorInfo editorInfo = new EditorInfo();
4603d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            textView.onCreateInputConnection(editorInfo);
4604d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            assertNull(editorInfo.hintLocales);
4605d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        }
4606d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa
4607d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        final LocaleList localeList = LocaleList.forLanguageTags("en-PH,en-US");
4608d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        textView.setImeHintLocales(localeList);
4609d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        assertEquals(localeList, textView.getImeHintLocales());
4610d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        {
4611d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            final EditorInfo editorInfo = new EditorInfo();
4612d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            textView.onCreateInputConnection(editorInfo);
4613d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa            assertEquals(localeList, editorInfo.hintLocales);
4614d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa        }
4615d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa    }
4616d14d9c9a3d9d8eeed720ecf28716fc51942c096aYohei Yukawa
4617c873101a88e7ba584065de5e912508237378ca99Victoria Lease    @UiThreadTest
461872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testSetExtractedText() {
461972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
462072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
462172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView.getText().toString());
462272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
462372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedText et = new ExtractedText();
4624ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4625ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Update text and selection.
462672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        et.text = "test";
4627ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionStart = 0;
4628ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionEnd = 2;
462972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
463072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setExtractedText(et);
463172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals("test", mTextView.getText().toString());
4632ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(0, mTextView.getSelectionStart());
4633ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, mTextView.getSelectionEnd());
4634ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4635ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Use partialStartOffset and partialEndOffset
4636ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialStartOffset = 2;
4637ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialEndOffset = 3;
4638ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.text = "x";
4639ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionStart = 2;
4640ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.selectionEnd = 3;
4641ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4642ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        mTextView.setExtractedText(et);
4643ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("text", mTextView.getText().toString());
4644ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, mTextView.getSelectionStart());
4645ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, mTextView.getSelectionEnd());
4646ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4647ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        // Update text with spans.
4648ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final SpannableString ss = new SpannableString("ex");
4649ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        ss.setSpan(new UnderlineSpan(), 0, 2, 0);
4650ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        ss.setSpan(new URLSpan("ctstest://TextView/test"), 1, 2, 0);
4651ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4652ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.text = ss;
4653ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialStartOffset = 1;
4654ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        et.partialEndOffset = 3;
4655ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        mTextView.setExtractedText(et);
4656ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4657ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("text", mTextView.getText().toString());
4658ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final Editable editable = mTextView.getEditableText();
4659ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final UnderlineSpan[] underlineSpans = mTextView.getEditableText().getSpans(
4660ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi                0, editable.length(), UnderlineSpan.class);
4661ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, underlineSpans.length);
4662ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, editable.getSpanStart(underlineSpans[0]));
4663ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, editable.getSpanEnd(underlineSpans[0]));
4664ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi
4665ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        final URLSpan[] urlSpans = mTextView.getEditableText().getSpans(
4666ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi                0, editable.length(), URLSpan.class);
4667ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(1, urlSpans.length);
4668ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(2, editable.getSpanStart(urlSpans[0]));
4669ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals(3, editable.getSpanEnd(urlSpans[0]));
4670ba5ce949fafd36e5318108a261af06763651d6b7Keisuke Kuroyanagi        assertEquals("ctstest://TextView/test", urlSpans[0].getURL());
467172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
467272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
467372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testMoveCursorToVisibleOffset() throws Throwable {
467472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
467572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
467672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // not a spannable text
467772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
467872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
467972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                assertFalse(mTextView.moveCursorToVisibleOffset());
468072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
468172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
468272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
468372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
468472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // a selection range
468572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        final String spannableText = "text";
468672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
468772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
468872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
468972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
469072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView.setText(spannableText, BufferType.SPANNABLE);
469172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
469272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
469372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
469472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        Selection.setSelection((Spannable) mTextView.getText(), 0, spannableText.length());
469572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
469672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, mTextView.getSelectionStart());
469772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(spannableText.length(), mTextView.getSelectionEnd());
469872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
469972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
470072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                assertFalse(mTextView.moveCursorToVisibleOffset());
470172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
470272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
470372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
470472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
470572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        // a spannable without range
470672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
470772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
470872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView = findTextView(R.id.textview_text);
470972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                mTextView.setText(spannableText, BufferType.SPANNABLE);
471072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
471172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
471272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
471372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
471472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        runTestOnUiThread(new Runnable() {
471572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            public void run() {
471672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                assertTrue(mTextView.moveCursorToVisibleOffset());
471772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach            }
471872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        });
471972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mInstrumentation.waitForIdleSync();
472072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
472172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
4722afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu    public void testIsInputMethodTarget() throws Throwable {
472372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
472472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.isInputMethodTarget());
472572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
472672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.isFocused());
4727afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        runTestOnUiThread(new Runnable() {
4728afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu           @Override
4729afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu            public void run() {
4730afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu               mTextView.setFocusable(true);
4731afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu               mTextView.requestFocus();
4732afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu            }
4733afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        });
4734afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        mInstrumentation.waitForIdleSync();
4735afefb471cb741d3787da90aa03338f28c5cb6d87Brian Muramatsu        assertTrue(mTextView.isFocused());
473604d12809ae731ea2aea678707bcc606f05efb23aBrian Muramatsu
4737354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> mTextView.isInputMethodTarget());
473872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
473972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
47406a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
47416a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testBeginEndBatchEditAreNotCalledForNonEditableText() {
47426a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final MockTextView mockTextView = new MockTextView(mActivity);
47436a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47446a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("TextView should not call onBeginBatchEdit during initialization",
47456a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnBeginBatchEdit());
47466a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("TextView should not call onEndBatchEdit during initialization",
47476a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnEndBatchEdit());
474872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
47496a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        // Since TextView doesn't support editing, the callbacks should not be called
47506a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.beginBatchEdit();
47516a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("Should not call onBeginBatchEdit when TextView doesn't support editing",
47526a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnBeginBatchEdit());
47536a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("Should not call onEndBatchEdit when TextView doesn't support editing",
47546a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnEndBatchEdit());
47556a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47566a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.endBatchEdit();
47576a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("Should not call onBeginBatchEdit when TextView doesn't support editing",
47586a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnEndBatchEdit());
47596a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("Should not call onEndBatchEdit when TextView doesn't support editing",
47606a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnEndBatchEdit());
47616a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
47626a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47636a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    @MediumTest
47646a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    public void testBeginEndBatchEditCallbacksAreCalledForEditableText() {
47656a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final MockTextView mockTextView = new MockTextView(mActivity);
47666a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47676a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        final FrameLayout layout = new FrameLayout(getActivity());
47686a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
47696a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT,
47706a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                ViewGroup.LayoutParams.MATCH_PARENT);
47716a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.addView(mockTextView, layoutParams);
47726a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        layout.setLayoutParams(layoutParams);
47736a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47746a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
47756a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
47766a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                getActivity().setContentView(layout);
47776a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
47786a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
47796a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
47806a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47816a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
47826a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
47836a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
47846a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.setText("", BufferType.EDITABLE);
47856a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.requestFocus();
47866a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
47876a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
47886a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
47896a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47906a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.reset();
47916a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue(mockTextView.hasFocus());
47926a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("onBeginBatchEdit should be false",
47936a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnBeginBatchEdit());
47946a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("onEndBatchEdit should be false",
47956a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnEndBatchEdit());
47966a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
47976a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.beginBatchEdit();
47986a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue("onBeginBatchEdit should be called after beginBatchEdit",
47996a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnBeginBatchEdit());
48006a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("onEndBatchEdit should not be called after beginBatchEdit",
48016a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnEndBatchEdit());
48026a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
48036a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.reset();
48046a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mockTextView.endBatchEdit();
48056a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertFalse("onBeginBatchEdit should not be called after endBatchEdit",
48066a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnBeginBatchEdit());
48076a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        assertTrue("onEndBatchEdit should be called after endBatchEdit",
48086a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mockTextView.hasCalledOnEndBatchEdit());
480972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
481072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
481172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
481272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testBringPointIntoView() throws Throwable {
481372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
481472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.bringPointIntoView(1));
481572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
481672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.layout(0, 0, 100, 100);
481772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.bringPointIntoView(2));
481872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
481972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
482072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testCancelLongPress() {
482172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
482272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        TouchUtils.longClickView(this, mTextView);
482372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.cancelLongPress();
482472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
482572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
482672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
482772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testClearComposingText() {
482872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
482972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setText("Hello world!", BufferType.SPANNABLE);
483072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        Spannable text = (Spannable) mTextView.getText();
483172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
483272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
483372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
483472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
483572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        BaseInputConnection.setComposingSpans((Spannable) mTextView.getText());
483672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, BaseInputConnection.getComposingSpanStart(text));
483772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, BaseInputConnection.getComposingSpanStart(text));
483872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
483972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.clearComposingText();
484072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
484172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
484272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
484372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
484472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testComputeVerticalScrollExtent() {
484572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        MockTextView textView = new MockTextView(mActivity);
484672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, textView.computeVerticalScrollExtent());
484772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
48489776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        Drawable d = getDrawable(R.drawable.pass);
484972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        textView.setCompoundDrawables(null, d, null, d);
485072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
485172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(0, textView.computeVerticalScrollExtent());
485272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
485372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
485472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    @UiThreadTest
485572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testDidTouchFocusSelect() {
4856c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        mTextView = new EditText(mActivity);
485772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertFalse(mTextView.didTouchFocusSelect());
485872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
485972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.setFocusable(true);
486072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView.requestFocus();
486172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.didTouchFocusSelect());
486272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
486372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
48640ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka    public void testSelectAllJustAfterTap() {
48650ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Prepare an EditText with focus.
48660ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mActivity.runOnUiThread(new Runnable() {
48670ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka            public void run() {
48680ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView = new EditText(mActivity);
48690ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mActivity.setContentView(mTextView);
48700ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48710ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                assertFalse(mTextView.didTouchFocusSelect());
48720ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView.setFocusable(true);
48730ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView.requestFocus();
48740ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                assertTrue(mTextView.didTouchFocusSelect());
48750ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48760ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView.setText("Hello, World.", BufferType.SPANNABLE);
48770ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka            }
48780ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        });
48790ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mInstrumentation.waitForIdleSync();
48800ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48810ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Tap the view to show InsertPointController.
48820ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        TouchUtils.tapView(this, mTextView);
488383a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        // bad workaround for waiting onStartInputView of LeanbackIme.apk done
488483a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        try {
488583a70cb57c839148a4feff786cdbb3803828d484Bobby Wang            Thread.sleep(1000);
488683a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        } catch (InterruptedException e) {
488783a70cb57c839148a4feff786cdbb3803828d484Bobby Wang            e.printStackTrace();
488883a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        }
48890ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48900ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // Execute SelectAll context menu.
48910ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mActivity.runOnUiThread(new Runnable() {
48920ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka            public void run() {
48930ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka                mTextView.onTextContextMenuItem(android.R.id.selectAll);
48940ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka            }
48950ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        });
48960ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        mInstrumentation.waitForIdleSync();
48970ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
48980ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        // The selection must be whole of the text contents.
48990ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        assertEquals(0, mTextView.getSelectionStart());
490083a70cb57c839148a4feff786cdbb3803828d484Bobby Wang        assertEquals("Hello, World.", mTextView.getText().toString());
49010ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka        assertEquals(mTextView.length(), mTextView.getSelectionEnd());
49020ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka    }
49030ddd054a4a00b9843563a38ab236fe3e47c99e9aSeigo Nonaka
490472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    public void testExtractText() {
490572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = new TextView(mActivity);
490672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
490772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedTextRequest request = new ExtractedTextRequest();
490872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        ExtractedText outText = new ExtractedText();
490972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
491072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.token = 0;
491172b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.flags = 10;
491272b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.hintMaxLines = 2;
491372b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        request.hintMaxChars = 20;
491472b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.extractText(request, outText));
491572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
491672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        mTextView = findTextView(R.id.textview_text);
491772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertTrue(mTextView.extractText(request, outText));
491872b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
491972b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach        assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
492072b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach                outText.text.toString());
4921c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi
4922c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        // Tests for invalid arguments.
4923c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(request, null));
4924c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(null, outText));
4925c778c0d53d612a73b39cbf965f5068a3b0a10695Yoshiki Iguchi        assertFalse(mTextView.extractText(null, null));
492672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
492772b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
492894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
492994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testTextDirectionDefault() {
4930c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
49312a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection());
493294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
493394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
493494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
493594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testSetGetTextDirection() {
4936c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
493794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
493894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
49392a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getRawTextDirection());
494094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
494194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
49422a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getRawTextDirection());
494394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
494494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
49452a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection());
494694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
494794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
49482a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getRawTextDirection());
494994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
495094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
49512a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getRawTextDirection());
495294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
495394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
49542a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getRawTextDirection());
495502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
495602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
495702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getRawTextDirection());
495802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
495902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
496002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getRawTextDirection());
496194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
496294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
496394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
496494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionLtr() {
4965c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
496694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("this is a test");
496794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
49682a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
496994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
497094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
49712a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
497294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
497394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
49742a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
497594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
497694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
49772a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
497894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
497994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
49802a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
498194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
498294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
49832a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
498494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
498594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
49862a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
498702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
498802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
498902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
499002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
499102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
499202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
499394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
499494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
499594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
499694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionLtrWithInheritance() {
4997c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = new LinearLayout(mActivity);
499894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
499994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
5000c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
500194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("this is a test");
500294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.addView(tv);
500394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
500494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50052a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
500694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
500794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
50082a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
500994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50112a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
501294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
50142a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
501594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
50172a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
501894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
501994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
50202a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
502102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
502202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
502302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
502402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
502502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
502602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
502794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
502894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
502994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
503094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionRtl() {
5031c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
503294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("\u05DD\u05DE"); // hebrew
503394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
50342a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
503594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
503694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50372a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
503894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
503994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
50402a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
504194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50432a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
504494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
50462a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
504794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
504894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
50492a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
505094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
505194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
50522a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
505302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
505402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
505502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
505602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
505702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
505802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
505994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
506094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
506194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
506294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testGetResolvedTextDirectionRtlWithInheritance() {
5063c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = new LinearLayout(mActivity);
506494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
506594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
5066c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = new TextView(mActivity);
506794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setText("\u05DD\u05DE"); // hebrew
506894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.addView(tv);
506994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
507094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50712a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
507294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
507394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
50742a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
507594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
507694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
50772a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
507894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
507994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
50802a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
508194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
508294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
50832a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
508494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
508594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
50862a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
508794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
508802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
508902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
509002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
509102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
509202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
509302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
509494c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        // Force to RTL text direction on the layout
509594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
509694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
509794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
50982a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
509994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
510094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
51012a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
510294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
510394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
51042a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
510594c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
510694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
51072a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
510894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
510994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
51102a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
511194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
511294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
51132a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
511402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
511502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
511602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
511702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
511802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
511902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
512094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
512194c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
512294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    @UiThreadTest
512394c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    public void testResetTextDirection() {
5124c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest);
5125c2499432269114271f4b8ec17d07b469d2966fbeGilles Debunne        TextView tv = (TextView) mActivity.findViewById(R.id.textview_rtl);
512694c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
512794c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
512894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
51292a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
513094c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
5131f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        // No reset when we remove the view
513294c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio        ll.removeView(tv);
5133f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
5134f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio
5135f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        // Reset is done when we add the view
5136f0d2af33ae194bead489caef9b461f2bee6f45a6Fabrice Di Meglio        ll.addView(tv);
51372a9c5b3b05fd5fae0fd01352283739c5f85ea8e0Fabrice Di Meglio        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
513894c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio    }
513994c94377f8f741065c7f15d52e4398699dae0844Fabrice Di Meglio
514002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    @UiThreadTest
514102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    public void testTextDirectionFirstStrongLtr() {
514202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
514302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is LTR, the paragraph direction is LTR.
514402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
514502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
514602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
514702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("this is a test");
514802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
514902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
515002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
515102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
515202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
515302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
515402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
515502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
515602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
515702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
515802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is RTL, the paragraph direction is RTL.
515902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
516002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
516102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
516202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\u05DD\u05DE"); // Hebrew
516302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
516402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
516502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
516602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
516702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
516802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
516902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
517002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
517102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
517202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
517302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is not a strong directional character, the paragraph
517402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // direction is LTR.
517502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
517602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
517702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
517802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\uFFFD");  // REPLACEMENT CHARACTER. Neutral direction.
517902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
518002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
518102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
518202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
518302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
518402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
518502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
518602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
518702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
518802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    }
518902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
519002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    @UiThreadTest
519102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    public void testTextDirectionFirstStrongRtl() {
519202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
519302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is LTR, the paragraph direction is LTR.
519402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
519502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
519602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
519702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("this is a test");
519802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
519902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
520002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
520102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
520202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
520302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
520402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
520502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
520602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
520702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
520802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is RTL, the paragraph direction is RTL.
520902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
521002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
521102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
521202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\u05DD\u05DE"); // Hebrew
521302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
521402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
521502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
521602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
521702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
521802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
521902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
522002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
522102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
522202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        {
522302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // The first directional character is not a strong directional character, the paragraph
522402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            // direction is RTL.
522502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            LinearLayout ll = new LinearLayout(mActivity);
522602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
522702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            TextView tv = new TextView(mActivity);
522802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setText("\uFFFD");  // REPLACEMENT CHARACTER. Neutral direction.
522902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            ll.addView(tv);
523002c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
523102c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
523202c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
523302c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
523402c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            tv.onPreDraw();  // For freezing layout.
523502c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            Layout layout = tv.getLayout();
523602c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
523702c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka        }
523802c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka    }
523902c09dc324e915d3786f0188704ad1753039bd40Seigo Nonaka
5240c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader    public void testTextLocales() {
5241c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        TextView tv = new TextView(mActivity);
5242c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.getDefault(), tv.getTextLocale());
5243c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(LocaleList.getDefault(), tv.getTextLocales());
5244c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5245c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        tv.setTextLocale(Locale.CHINESE);
5246c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.CHINESE, tv.getTextLocale());
5247c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(new LocaleList(Locale.CHINESE), tv.getTextLocales());
5248c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5249c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        tv.setTextLocales(LocaleList.forLanguageTags("en,ja"));
5250c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(Locale.forLanguageTag("en"), tv.getTextLocale());
5251c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        assertEquals(LocaleList.forLanguageTags("en,ja"), tv.getTextLocales());
5252c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5253c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5254c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocale(null);
5255c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locale to null should throw");
5256c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5257c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5258c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5259c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5260c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5261c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocales(null);
5262c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locales to null should throw");
5263c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5264c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5265c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5266c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5267c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        try {
5268c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            tv.setTextLocales(new LocaleList());
5269c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            fail("Setting the text locale to an empty list should throw");
5270c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        } catch (Throwable e) {
5271c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader            assertEquals(IllegalArgumentException.class, e.getClass());
5272c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader        }
5273c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader    }
5274c2c082a53615033ece708f7e392474fef8ae2417Roozbeh Pournader
5275b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka    public void testAllCapsLocalization() {
5276b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        String testString = "abcdefghijklmnopqrstuvwxyz";
5277b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5278b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        // The capitalized characters of "i" on Turkish and Azerbaijani are different from English.
5279b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        Locale[] testLocales = {
5280b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("az", "AZ"),
5281b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("tr", "TR"),
5282b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            new Locale("en", "US"),
5283b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        };
5284b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5285b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        TextView tv = new TextView(mActivity);
5286b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        tv.setAllCaps(true);
5287b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        for (Locale locale: testLocales) {
5288b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            tv.setTextLocale(locale);
5289b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka            assertEquals("Locale: " + locale.getDisplayName(),
5290b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka                         testString.toUpperCase(locale),
5291b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka                         tv.getTransformationMethod().getTransformation(testString, tv).toString());
5292b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka        }
5293b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka    }
5294b8eb7fd352a5fac5911460ebcedf53e6270c97dbSeigo Nonaka
5295dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5296dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testTextAlignmentDefault() {
5297dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = new TextView(getActivity());
52987fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5299dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // resolved default text alignment is GRAVITY
53007fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5301dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5302dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5303dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5304dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testSetGetTextAlignment() {
5305dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = new TextView(getActivity());
5306dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5307dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
53087fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5309dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5310dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
53117fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getRawTextAlignment());
5312dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5313dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
53147fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getRawTextAlignment());
5315dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5316dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
53177fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getRawTextAlignment());
5318dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5319dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
53207fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getRawTextAlignment());
5321dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5322dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
53237fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getRawTextAlignment());
5324dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5325dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5326dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5327dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testGetResolvedTextAlignment() {
5328dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = new TextView(getActivity());
5329dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
53307fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5331dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5332757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        // Test center alignment first so that we dont hit the default case
5333dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
53347fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5335dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5336757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        // Test the default case too
5337757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
5338757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5339757ec4fdfd1798a8e28d050433c67e628a7f578dFabrice Di Meglio
5340dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
53417fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
5342dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5343dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
53447fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
5345dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5346dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
53477fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
5348dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5349dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
53507fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
5351dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5352dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5353dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5354dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testGetResolvedTextAlignmentWithInheritance() {
5355dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        LinearLayout ll = new LinearLayout(getActivity());
5356dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
5357dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5358dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = new TextView(getActivity());
5359dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.addView(tv);
5360dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5361dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // check defaults
53627fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
5363dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5364dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5365dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // set inherit and check that child is following parent
5366dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
53677fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_INHERIT, tv.getRawTextAlignment());
5368dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5369dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
53707fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5371dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5372dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
53737fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
5374dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5375dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
53767fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
5377dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5378dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
53797fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
5380dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5381dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
53827fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
5383dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5384dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        // now get rid of the inheritance but still change the parent
5385dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
5386dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5387dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
53887fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5389dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5390dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
53917fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5392dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5393dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
53947fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5395dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5396dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
53977fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5398dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5399dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
54007fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5401dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5402dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5403dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    @UiThreadTest
5404dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    public void testResetTextAlignment() {
54054ca04c0729a0e810b5af16edcd52bb8cb59bf55eChenjie Luo        TextViewCtsActivity activity = getActivity();
5406dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5407dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        LinearLayout ll = (LinearLayout) activity.findViewById(R.id.layout_textviewtest);
5408dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        TextView tv = (TextView) activity.findViewById(R.id.textview_rtl);
5409dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5410dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
5411dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
54127fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
5413dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
54144f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // No reset when we remove the view
5415dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio        ll.removeView(tv);
54164f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
54174f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio
54184f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // Reset is done when we add the view
54194f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        // Default text alignment is GRAVITY
54204f6c5d77dfc74b490b8567d0b21adec0ccd72d22Fabrice Di Meglio        ll.addView(tv);
54217fc94900b8661e27f89ae21523bd952127d510eaFabrice Di Meglio        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
5422dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio    }
5423dd7e30e4e18f67c4257379adecaa1df2bbe1992cFabrice Di Meglio
5424938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    private void verifyCompoundDrawables(@NonNull TextView textView,
5425938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            @IdRes int expectedLeftDrawableId, @IdRes int expectedRightDrawableId,
5426938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            @IdRes int expectedTopDrawableId, @IdRes int expectedBottomDrawableId) {
5427938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final Drawable[] compoundDrawables = textView.getCompoundDrawables();
5428938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        if (expectedLeftDrawableId < 0) {
5429938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            assertNull(compoundDrawables[0]);
5430938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        } else {
5431938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            WidgetTestUtils.assertEquals(getBitmap(expectedLeftDrawableId),
5432938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                    ((BitmapDrawable) compoundDrawables[0]).getBitmap());
5433938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }
5434938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        if (expectedTopDrawableId < 0) {
5435938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            assertNull(compoundDrawables[1]);
5436938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        } else {
5437938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            WidgetTestUtils.assertEquals(getBitmap(expectedTopDrawableId),
5438938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                    ((BitmapDrawable) compoundDrawables[1]).getBitmap());
5439938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }
5440938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        if (expectedRightDrawableId < 0) {
5441938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            assertNull(compoundDrawables[2]);
5442938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        } else {
5443938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            WidgetTestUtils.assertEquals(getBitmap(expectedRightDrawableId),
5444938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                    ((BitmapDrawable) compoundDrawables[2]).getBitmap());
5445938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }
5446938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        if (expectedBottomDrawableId < 0) {
5447938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            assertNull(compoundDrawables[3]);
5448938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        } else {
5449938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            WidgetTestUtils.assertEquals(getBitmap(expectedBottomDrawableId),
5450938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                    ((BitmapDrawable) compoundDrawables[3]).getBitmap());
5451938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }
5452938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    }
5453b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5454938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    private void verifyCompoundDrawablesRelative(@NonNull TextView textView,
5455938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            @IdRes int expectedStartDrawableId, @IdRes int expectedEndDrawableId,
5456938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            @IdRes int expectedTopDrawableId, @IdRes int expectedBottomDrawableId) {
5457938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final Drawable[] compoundDrawablesRelative = textView.getCompoundDrawablesRelative();
5458938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        if (expectedStartDrawableId < 0) {
5459938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            assertNull(compoundDrawablesRelative[0]);
5460938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        } else {
5461938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            WidgetTestUtils.assertEquals(getBitmap(expectedStartDrawableId),
5462938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                    ((BitmapDrawable) compoundDrawablesRelative[0]).getBitmap());
5463938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }
5464938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        if (expectedTopDrawableId < 0) {
5465938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            assertNull(compoundDrawablesRelative[1]);
5466938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        } else {
5467938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            WidgetTestUtils.assertEquals(getBitmap(expectedTopDrawableId),
5468938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                    ((BitmapDrawable) compoundDrawablesRelative[1]).getBitmap());
5469938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }
5470938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        if (expectedEndDrawableId < 0) {
5471938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            assertNull(compoundDrawablesRelative[2]);
5472938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        } else {
5473938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            WidgetTestUtils.assertEquals(getBitmap(expectedEndDrawableId),
5474938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                    ((BitmapDrawable) compoundDrawablesRelative[2]).getBitmap());
5475938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }
5476938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        if (expectedBottomDrawableId < 0) {
5477938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            assertNull(compoundDrawablesRelative[3]);
5478938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        } else {
5479938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov            WidgetTestUtils.assertEquals(getBitmap(expectedBottomDrawableId),
5480938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                    ((BitmapDrawable) compoundDrawablesRelative[3]).getBitmap());
5481938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        }
5482938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    }
5483b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5484938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    @UiThreadTest
5485938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    public void testDrawableResolution() {
5486b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 1.1: left / right drawable defined in default LTR mode
5487938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        TextView tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_1);
5488938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5489938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5490938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, -1, -1,
5491938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5492b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5493b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 1.2: left / right drawable defined in default RTL mode
5494938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_2);
5495938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5496938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5497938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, -1, -1,
5498938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5499b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5500b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 2.1: start / end drawable defined in LTR mode
5501938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_2_1);
5502938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5503938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5504938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5505938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5506b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5507b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 2.2: start / end drawable defined in RTL mode
5508938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_2_2);
5509938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5510938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5511938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5512938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5513b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5514b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 3.1: left / right / start / end drawable defined in LTR mode
5515938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_3_1);
5516938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5517938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5518938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5519938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5520b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5521b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 3.2: left / right / start / end drawable defined in RTL mode
5522938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_3_2);
5523938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5524938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5525938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5526938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5527b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5528b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 4.1: start / end drawable defined in LTR mode inside a layout
5529b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5530938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_4_1);
5531938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5532938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5533938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5534938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5535b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5536b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 4.2: start / end drawable defined in RTL mode inside a layout
5537b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5538938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_4_2);
5539938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5540938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5541938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5542938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5543b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5544b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 5.1: left / right / start / end drawable defined in LTR mode inside a layout
5545b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5546938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_5_1);
5547938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5548938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5549938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5550938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5551b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
5552b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // Case 5.2: left / right / start / end drawable defined in RTL mode inside a layout
5553b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio        // that defines the layout direction
5554938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_5_2);
5555938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_red, R.drawable.icon_blue,
5556938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5557938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawablesRelative(tv, R.drawable.icon_blue, R.drawable.icon_red,
5558938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
5559b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio    }
5560b44fc868dc396032a3dae2ba8871168df95e620aFabrice Di Meglio
55619776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    @UiThreadTest
55629776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    public void testDrawableResolution2() {
55639776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        // Case 1.1: left / right drawable defined in default LTR mode
5564938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        TextView tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_1);
5565938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5566938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
55679776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
55689776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        tv.setCompoundDrawables(null, null, getDrawable(R.drawable.icon_yellow), null);
5569938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, -1, R.drawable.icon_yellow, -1, -1);
55709776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5571938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_drawable_1_2);
5572938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red,
5573938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.drawable.icon_green, R.drawable.icon_yellow);
55749776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5575938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv.setCompoundDrawables(getDrawable(R.drawable.icon_yellow), null, null, null);
5576938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_yellow, -1, -1, -1);
55779776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5578938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv = (TextView) mActivity.findViewById(R.id.textview_ltr);
5579938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, -1, -1, -1, -1);
55809776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5581938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        tv.setCompoundDrawables(getDrawable(R.drawable.icon_blue), null,
5582938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                getDrawable(R.drawable.icon_red), null);
5583938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_blue, R.drawable.icon_red, -1, -1);
55849776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
55859776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        tv.setCompoundDrawablesRelative(getDrawable(R.drawable.icon_yellow), null, null, null);
5586938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        verifyCompoundDrawables(tv, R.drawable.icon_yellow, -1, -1, -1);
5587938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    }
5588938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5589938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov    public void testCompoundAndTotalPadding() {
5590938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final Resources res = mActivity.getResources();
5591938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int drawablePadding = res.getDimensionPixelSize(R.dimen.textview_drawable_padding);
5592938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingLeft = res.getDimensionPixelSize(R.dimen.textview_padding_left);
5593938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingRight = res.getDimensionPixelSize(R.dimen.textview_padding_right);
5594938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingTop = res.getDimensionPixelSize(R.dimen.textview_padding_top);
5595938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int paddingBottom = res.getDimensionPixelSize(R.dimen.textview_padding_bottom);
5596938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int iconSize = TestUtils.dpToPx(mActivity, 32);
5597938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5598938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final TextView textViewLtr = (TextView) mActivity.findViewById(
5599938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.id.textview_compound_drawable_ltr);
5600938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingLeftLtr = paddingLeft + drawablePadding + iconSize;
5601938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingRightLtr = paddingRight + drawablePadding + iconSize;
5602938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getCompoundPaddingLeft());
5603938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getCompoundPaddingStart());
5604938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getTotalPaddingLeft());
5605938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftLtr, textViewLtr.getTotalPaddingStart());
5606938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getCompoundPaddingRight());
5607938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getCompoundPaddingEnd());
5608938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getTotalPaddingRight());
5609938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightLtr, textViewLtr.getTotalPaddingEnd());
5610938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingTop + drawablePadding + iconSize,
5611938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewLtr.getCompoundPaddingTop());
5612938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingBottom + drawablePadding + iconSize,
5613938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewLtr.getCompoundPaddingBottom());
5614938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov
5615938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final TextView textViewRtl = (TextView) mActivity.findViewById(
5616938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                R.id.textview_compound_drawable_rtl);
5617938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingLeftRtl = paddingLeft + drawablePadding + iconSize;
5618938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        final int combinedPaddingRightRtl = paddingRight + drawablePadding + iconSize;
5619938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getCompoundPaddingLeft());
5620938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getCompoundPaddingEnd());
5621938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getTotalPaddingLeft());
5622938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingLeftRtl, textViewRtl.getTotalPaddingEnd());
5623938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getCompoundPaddingRight());
5624938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getCompoundPaddingStart());
5625938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getTotalPaddingRight());
5626938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(combinedPaddingRightRtl, textViewRtl.getTotalPaddingStart());
5627938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingTop + drawablePadding + iconSize,
5628938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewRtl.getCompoundPaddingTop());
5629938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov        assertEquals(paddingBottom + drawablePadding + iconSize,
5630938e01e2ecbc870a6de7296ea3cbb1550404439dKirill Grouchnikov                textViewRtl.getCompoundPaddingBottom());
56319776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    }
56329776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
5633e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    public void testSetGetBreakStrategy() {
5634e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        TextView tv = new TextView(mActivity);
5635e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
56362751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        final PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
56372751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka
5638d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // The default value is from the theme, here the default is BREAK_STRATEGY_HIGH_QUALITY for
56392751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        // TextView except for Android Wear. The default value for Android Wear is
56402751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        // BREAK_STRATEGY_BALANCED.
56412751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        if (pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
56422751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            // Android Wear
56432751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy());
56442751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        } else {
56452751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            // All other form factor.
56462751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka            assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy());
56472751d704e7028d7b7a3919318c0b7381be24197aSeigo Nonaka        }
5648e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5649e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
5650e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, tv.getBreakStrategy());
5651e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5652e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
5653e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy());
5654e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5655e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED);
5656e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy());
5657d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5658d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        EditText et = new EditText(mActivity);
5659d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5660d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // The default value is from the theme, here the default is BREAK_STRATEGY_SIMPLE for
5661d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        // EditText.
5662d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy());
5663d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5664d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
5665d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy());
5666d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5667d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
5668d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, et.getBreakStrategy());
5669d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi
5670d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        et.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED);
5671d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.BREAK_STRATEGY_BALANCED, et.getBreakStrategy());
5672e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    }
5673e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5674e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    public void testSetGetHyphenationFrequency() {
5675e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        TextView tv = new TextView(mActivity);
5676e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5677d86c8a9d3dd63c69a09e5fa5c23b1ffc4d2fc2e2Keisuke Kuroyanagi        assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency());
5678e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5679e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
5680e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, tv.getHyphenationFrequency());
5681e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5682e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL);
5683e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency());
5684e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
5685e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
5686e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka        assertEquals(Layout.HYPHENATION_FREQUENCY_FULL, tv.getHyphenationFrequency());
5687e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka    }
5688e5862867943e7c107c70e825af58fffd30be7a9fSeigo Nonaka
568932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi    public void testSetAndGetCustomSelectionActionModeCallback() {
569032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        final String text = "abcde";
569132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
569232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
569332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView = new EditText(mActivity);
569432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mActivity.setContentView(mTextView);
569532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.setText(text, BufferType.SPANNABLE);
569632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.setTextIsSelectable(true);
569732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.requestFocus();
569832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.setSelected(true);
569932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
570032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
570132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
570232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
570332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Check default value.
570432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        assertNull(mTextView.getCustomSelectionActionModeCallback());
570532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
570698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final ActionMode.Callback mockActionModeCallback = mock(ActionMode.Callback.class);
570798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
570898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.FALSE);
570998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setCustomSelectionActionModeCallback(mockActionModeCallback);
571098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback,
571132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.getCustomSelectionActionModeCallback());
571232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
571332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
571432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
571532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                // Set selection and try to start action mode.
571632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                final Bundle args = new Bundle();
571732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
571832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
57198e92940803ad8d05bfeecdd6ef3abfe803c5a782Alan Viverette                mTextView.performAccessibilityAction(
572032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                        AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
572132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
572232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
572332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
572432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
572598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onCreateActionMode(
572698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                any(ActionMode.class), any(Menu.class));
572732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
572832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
572932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
573032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                // Remove selection and stop action mode.
573132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.copy);
573232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
573332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
573432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
573532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
573632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Action mode was blocked.
573798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, never()).onDestroyActionMode(any(ActionMode.class));
573832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
573998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        // Reset and reconfigure callback.
574098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        reset(mockActionModeCallback);
574198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
574298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.TRUE);
574398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback, mTextView.getCustomSelectionActionModeCallback());
574432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
574532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
574632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
574732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                // Set selection and try to start action mode.
574832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                final Bundle args = new Bundle();
574932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
575032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
57518e92940803ad8d05bfeecdd6ef3abfe803c5a782Alan Viverette                mTextView.performAccessibilityAction(
575232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                        AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
575332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
575432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
575532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
575632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
575732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
575898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onCreateActionMode(
575998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                any(ActionMode.class), any(Menu.class));
576032944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
576132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mActivity.runOnUiThread(new Runnable() {
576232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            public void run() {
576332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                // Remove selection and stop action mode.
576432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi                mTextView.onTextContextMenuItem(android.R.id.copy);
576532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi            }
576632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        });
576732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        mInstrumentation.waitForIdleSync();
576832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
576932944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Action mode was started
577098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        verify(mockActionModeCallback, times(1)).onDestroyActionMode(any(ActionMode.class));
577132944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi    }
577232944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
577398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testSetAndGetCustomInsertionActionMode() {
577432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        initTextViewForTyping();
577532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // Check default value.
577632944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        assertNull(mTextView.getCustomInsertionActionModeCallback());
577732944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
577898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final ActionMode.Callback mockActionModeCallback = mock(ActionMode.Callback.class);
577998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        when(mockActionModeCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).
578098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                thenReturn(Boolean.FALSE);
578198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mTextView.setCustomInsertionActionModeCallback(mockActionModeCallback);
578298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(mockActionModeCallback, mTextView.getCustomInsertionActionModeCallback());
578332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi        // TODO(Bug: 22033189): Tests the set callback is actually used.
578432944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi    }
578532944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
578698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov    public void testTextShadows() {
578798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView textViewWithConfiguredShadow =
578898d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov                (TextView) mActivity.findViewById(R.id.textview_with_shadow);
578998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(1.0f, textViewWithConfiguredShadow.getShadowDx());
579098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(2.0f, textViewWithConfiguredShadow.getShadowDy());
579198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(3.0f, textViewWithConfiguredShadow.getShadowRadius());
579298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(Color.GREEN, textViewWithConfiguredShadow.getShadowColor());
579332944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
579498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
579598d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(0.0f, textView.getShadowDx());
579698d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(0.0f, textView.getShadowDy());
579798d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(0.0f, textView.getShadowRadius());
579832944498e0627347cbe7c275b6ff6f21b8c983faKeisuke Kuroyanagi
579998d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setShadowLayer(5.0f, 3.0f, 4.0f, Color.RED));
580098d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        mInstrumentation.waitForIdleSync();
580198d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(3.0f, textView.getShadowDx());
580298d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(4.0f, textView.getShadowDy());
580398d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(5.0f, textView.getShadowRadius());
580498d000ba45f2a9485e391b8a8abff1d891ea4dbbKirill Grouchnikov        assertEquals(Color.RED, textView.getShadowColor());
580572b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach    }
580672b705b4df314c5cb81a9db2347fb6a6f9384b9aPhil Dubach
5807354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testFontFeatureSettings() {
5808354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final TextView textView = (TextView) mActivity.findViewById(R.id.textview_text);
5809354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(TextUtils.isEmpty(textView.getFontFeatureSettings()));
5810354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5811354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setFontFeatureSettings("smcp"));
5812354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5813354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals("smcp", textView.getFontFeatureSettings());
5814354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5815354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> textView.setFontFeatureSettings("frac"));
5816354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5817354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals("frac", textView.getFontFeatureSettings());
5818354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5819354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5820354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    private static class SoftInputResultReceiver extends ResultReceiver {
5821354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        private boolean mIsDone;
5822354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        private int mResultCode;
5823354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5824354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        public SoftInputResultReceiver(Handler handler) {
5825354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            super(handler);
5826354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5827354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5828354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        @Override
5829354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        protected void onReceiveResult(int resultCode, Bundle resultData) {
5830354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mResultCode = resultCode;
5831354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mIsDone = true;
5832354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5833354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5834354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        public void reset() {
5835354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            mIsDone = false;
5836354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5837354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5838354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5839354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    public void testAccessShowSoftInputOnFocus() {
5840354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        if (!mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)) {
5841354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov            return;
5842354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        }
5843354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5844354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Scroll down to our EditText
5845354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final ScrollView scrollView = (ScrollView) mActivity.findViewById(R.id.scroller);
5846354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mTextView = findTextView(R.id.editview_text);
5847354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> scrollView.fullScroll(View.FOCUS_DOWN));
5848354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5849354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5850354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Mark it to show soft input on focus
5851354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> mTextView.setShowSoftInputOnFocus(true));
5852354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5853354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(mTextView.getShowSoftInputOnFocus());
5854354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5855354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // And emulate click on it
5856354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        TouchUtils.clickView(this, mTextView);
5857354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5858354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Verify that input method manager is active and accepting text
5859354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        final InputMethodManager imManager = (InputMethodManager) mActivity
5860354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov                .getSystemService(Context.INPUT_METHOD_SERVICE);
5861354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> imManager.isActive());
5862354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(imManager.isAcceptingText());
5863354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertTrue(imManager.isActive(mTextView));
5864354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5865354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Since there is no API to check that soft input is showing, we're going to ask
5866354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // the input method manager to show soft input, passing our custom result receiver.
5867354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // We're expecting to get UNCHANGED_SHOWN, indicating that the soft input was already
5868354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // showing before showSoftInput was called.
5869354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        SoftInputResultReceiver receiver = new SoftInputResultReceiver(mHandler);
5870354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        imManager.showSoftInput(mTextView, 0, receiver);
5871354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> receiver.mIsDone);
5872354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(InputMethodManager.RESULT_UNCHANGED_SHOWN, receiver.mResultCode);
5873354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5874354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Close soft input
5875354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        sendKeys(KeyEvent.KEYCODE_BACK);
5876354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5877354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Reconfigure our edit text to not show soft input on focus
5878354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mActivity.runOnUiThread(() -> mTextView.setShowSoftInputOnFocus(false));
5879354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        mInstrumentation.waitForIdleSync();
5880354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertFalse(mTextView.getShowSoftInputOnFocus());
5881354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5882354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Emulate click on it
5883354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        TouchUtils.clickView(this, mTextView);
5884354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5885354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Ask input method manager to show soft input again. This time we're expecting to get
5886354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // SHOWN, indicating that the soft input was not showing before showSoftInput was called.
5887354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        receiver.reset();
5888354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        imManager.showSoftInput(mTextView, 0, receiver);
5889354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        PollingCheck.waitFor(() -> receiver.mIsDone);
5890354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        assertEquals(InputMethodManager.RESULT_SHOWN, receiver.mResultCode);
5891354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
5892354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        // Close soft input
5893354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov        sendKeys(KeyEvent.KEYCODE_BACK);
5894354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov    }
5895354a3744faf4006b2d997ca71ffedef1da823c5eKirill Grouchnikov
589641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    public void testIsSuggestionsEnabled() {
589741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
589841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
589941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Anything without InputType.TYPE_CLASS_TEXT doesn't have suggestions enabled
590041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(() -> mTextView.setInputType(InputType.TYPE_CLASS_DATETIME));
590141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
590241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
590341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(() -> mTextView.setInputType(InputType.TYPE_CLASS_PHONE));
590441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
590541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
590641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(() -> mTextView.setInputType(InputType.TYPE_CLASS_NUMBER));
590741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
590841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
590941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // From this point our text view has InputType.TYPE_CLASS_TEXT
591041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
591141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Anything with InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS doesn't have suggestions enabled
591241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
591341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
591441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
591541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
591641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
591741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
591841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
591941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL |
592041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
592141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
592241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
592341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
592441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
592541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS |
592641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS));
592741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
592841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
592941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Otherwise suggestions are enabled for specific type variations enumerated in the
593041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // documentation of TextView.isSuggestionsEnabled
593141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
593241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
593341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL));
593441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
593541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
593641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
593741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
593841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT));
593941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
594041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
594141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
594241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
594341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE));
594441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
594541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
594641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
594741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
594841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE));
594941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
595041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
595141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
595241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
595341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT));
595441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertTrue(mTextView.isSuggestionsEnabled());
595541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
595641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // and not on any other type variation
595741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
595841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
595941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS));
596041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
596141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
596241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
596341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
596441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_FILTER));
596541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
596641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
596741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
596841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
596941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD));
597041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
597141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
597241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
597341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
597441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PERSON_NAME));
597541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
597641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
597741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
597841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
597941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PHONETIC));
598041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
598141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
598241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
598341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
598441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS));
598541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
598641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
598741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
598841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
598941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI));
599041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
599141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
599241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
599341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
599441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT |
599541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD));
599641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
599741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
599841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
599941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
600041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT |
600141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                                InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS));
600241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
600341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
600441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mInstrumentation.runOnMainSync(
600541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setInputType(
600641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                        InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD));
600741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertFalse(mTextView.isSuggestionsEnabled());
600841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
600941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
601041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    public void testAccessLetterSpacing() {
601141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
601241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals(0.0f, mTextView.getLetterSpacing());
601341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
601441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final CharSequence text = mTextView.getText();
601541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int textLength = text.length();
601641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
601741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at the default letter spacing
601841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] initialWidths = new float[textLength];
601941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), initialWidths);
602041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
602141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at letter spacing = 1.0f
602241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mTextView,
602341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setLetterSpacing(1.0f));
602441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals(1.0f, mTextView.getLetterSpacing());
602541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] singleWidths = new float[textLength];
602641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), singleWidths);
602741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
602841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get advance widths of each character at letter spacing = 2.0f
602941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mTextView,
603041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                () -> mTextView.setLetterSpacing(2.0f));
603141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals(2.0f, mTextView.getLetterSpacing());
603241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final float[] doubleWidths = new float[textLength];
603341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView.getPaint().getTextWidths(text.toString(), doubleWidths);
603441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
603541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Since letter spacing setter treats the parameter as EM units, and we don't have
603641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // a way to convert EMs into pixels, go over the three arrays of advance widths and
603741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // test that the extra advance width at letter spacing 2.0f is double the extra
603841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // advance width at letter spacing 1.0f.
603941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        for (int i = 0; i < textLength; i++) {
604041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            float singleWidthDelta = singleWidths[i] - initialWidths[i];
604141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            float doubleWidthDelta = doubleWidths[i] - initialWidths[i];
604241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            assertEquals("At index " + i + " initial is " + initialWidths[i] +
604341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                ", single is " + singleWidths[i] + " and double is " + doubleWidths[i],
604441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov                    singleWidthDelta * 2.0f, doubleWidthDelta, 0.05f);
604541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        }
604641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
604741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
604841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    private void verifyGetOffsetForPosition(final int x, final int y) {
604941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int actual = mTextView.getOffsetForPosition(x, y);
605041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
605141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final Layout layout = mTextView.getLayout();
605241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        if (layout == null) {
605341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            assertEquals("For [" + x + ", " + y + "]", -1, actual);
605441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            return;
605541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        }
605641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
605741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get the line which corresponds to the Y position
605841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int line = layout.getLineForVertical(y + mTextView.getScrollY());
605941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        // Get the offset in that line that corresponds to the X position
606041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int expected = layout.getOffsetForHorizontal(line, x + mTextView.getScrollX());
606141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertEquals("For [" + x + ", " + y + "]", expected, actual);
606241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
606341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
606441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    public void testGetOffsetForPosition() {
606541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        mTextView = findTextView(R.id.textview_text);
606641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mTextView, () -> {
606741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            mTextView.setText(LONG_TEXT);
606841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov            mTextView.setPadding(0, 0, 0, 0);
606941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        });
607041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
607141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        assertNotNull(mTextView.getLayout());
607241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int viewWidth = mTextView.getWidth();
607341b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int viewHeight = mTextView.getHeight();
607441b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        final int lineHeight = mTextView.getLineHeight();
607541b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
607641b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(0, 0);
607741b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(0, viewHeight / 2);
607841b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth / 3, lineHeight / 2);
607941b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth / 2, viewHeight / 2);
608041b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov        verifyGetOffsetForPosition(viewWidth, viewHeight);
608141b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov    }
608241b3e249a7d16d5b58a079f64ed9d769393391b6Kirill Grouchnikov
6083fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void layout(final TextView textView) {
6084fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6085fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6086fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mActivity.setContentView(textView);
6087fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6088fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6089fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6090fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6091fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6092fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void layout(final int layoutId) {
6093fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6094fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6095fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mActivity.setContentView(layoutId);
6096fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6097fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6098fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6099fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6100fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6101fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private TextView findTextView(int id) {
6102fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        return (TextView) mActivity.findViewById(id);
6103fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6104fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6105fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private int getAutoLinkMask(int id) {
6106fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        return findTextView(id).getAutoLinkMask();
6107fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6108fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6109fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private Bitmap getBitmap(int resid) {
61109776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        return ((BitmapDrawable) getDrawable(resid)).getBitmap();
61119776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    }
61129776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio
61139776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio    private Drawable getDrawable(int resid) {
61149776f6746985a3740892cec4df71fbbc94bdaf84Fabrice Di Meglio        return mActivity.getResources().getDrawable(resid);
6115fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6116fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
61176a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    private void setMaxLines(final int lines) {
61186a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mActivity.runOnUiThread(new Runnable() {
61196a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            public void run() {
61206a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir                mTextView.setMaxLines(lines);
61216a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir            }
61226a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        });
61236a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir        mInstrumentation.waitForIdleSync();
61246a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir    }
61256a7d70f520117b679dc0e8af433e4241b47fe8b6Siyamed Sinir
6126fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMaxWidth(final int pixels) {
6127fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6128fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6129fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMaxWidth(pixels);
6130fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6131fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6132fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6133fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6134fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6135fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMinWidth(final int pixels) {
6136fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6137fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6138fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMinWidth(pixels);
6139fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6140fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6141fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6142fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6143fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6144fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMaxHeight(final int pixels) {
6145fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6146fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6147fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMaxHeight(pixels);
6148fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6149fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6150fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6151fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6152fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6153fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMinHeight(final int pixels) {
6154fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6155fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6156fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMinHeight(pixels);
6157fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6158fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6159fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6160fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6161fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6162fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMinLines(final int minlines) {
6163fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6164fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6165fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMinLines(minlines);
6166fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6167fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6168fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6169fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6170fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6171fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    /**
6172fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * Convenience for {@link TextView#setText(CharSequence, BufferType)}. And
6173fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * the buffer type is fixed to SPANNABLE.
6174fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     *
6175fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * @param tv the text view
6176fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     * @param content the content
6177fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su     */
6178fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setSpannableText(final TextView tv, final String content) {
6179fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6180fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6181fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                tv.setText(content, BufferType.SPANNABLE);
6182fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6183fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6184fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6185fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6186fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6187fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setLines(final int lines) {
6188fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6189fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6190fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setLines(lines);
6191fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6192fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6193fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6194fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6195fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6196fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setHorizontallyScrolling(final boolean whether) {
6197fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6198fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6199fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setHorizontallyScrolling(whether);
6200fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6201fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6202fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6203fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6204fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6205fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setWidth(final int pixels) {
6206fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6207fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6208fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setWidth(pixels);
6209fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6210fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6211fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6212fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6213fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6214fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setHeight(final int pixels) {
6215fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6216fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6217fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setHeight(pixels);
6218fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6219fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6220fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6221fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6222fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6223fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMinEms(final int ems) {
6224fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6225fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6226fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMinEms(ems);
6227fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6228fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6229fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6230fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6231fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6232fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setMaxEms(final int ems) {
6233fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6234fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6235fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setMaxEms(ems);
6236fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6237fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6238fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6239fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6240fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6241fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setEms(final int ems) {
6242fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6243fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6244fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setEms(ems);
6245fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6246fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6247fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6248fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6249fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6250fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private void setLineSpacing(final float add, final float mult) {
6251fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mActivity.runOnUiThread(new Runnable() {
6252fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            public void run() {
6253fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su                mTextView.setLineSpacing(add, mult);
6254fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            }
6255fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        });
6256fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        mInstrumentation.waitForIdleSync();
6257fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6258fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6259fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static abstract class TestSelectedRunnable implements Runnable {
6260fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private TextView mTextView;
6261fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mIsSelected1;
6262fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mIsSelected2;
6263fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6264fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public TestSelectedRunnable(TextView textview) {
6265fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView = textview;
6266fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6267fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6268fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean getIsSelected1() {
6269fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mIsSelected1;
6270fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6271fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6272fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean getIsSelected2() {
6273fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mIsSelected2;
6274fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6275fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6276fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveIsSelected1() {
6277fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mIsSelected1 = mTextView.isSelected();
6278fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6279fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6280fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveIsSelected2() {
6281fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mIsSelected2 = mTextView.isSelected();
6282fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6283fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6284fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6285fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static abstract class TestLayoutRunnable implements Runnable {
6286fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private TextView mTextView;
6287fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private Layout mLayout;
6288fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6289fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public TestLayoutRunnable(TextView textview) {
6290fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mTextView = textview;
6291fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6292fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6293fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public Layout getLayout() {
6294fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mLayout;
6295fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6296fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6297fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void saveLayout() {
6298fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mLayout = mTextView.getLayout();
6299fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6300fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6301fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6302fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    private static class MockTextWatcher implements TextWatcher {
6303fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasCalledAfterTextChanged;
6304fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasCalledBeforeTextChanged;
6305fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        private boolean mHasOnTextChanged;
6306fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6307fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void reset(){
6308fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledAfterTextChanged = false;
6309fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledBeforeTextChanged = false;
6310fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasOnTextChanged = false;
6311fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6312fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6313fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledAfterTextChanged() {
6314fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasCalledAfterTextChanged;
6315fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6316fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6317fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledBeforeTextChanged() {
6318fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasCalledBeforeTextChanged;
6319fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6320fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6321fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public boolean hasCalledOnTextChanged() {
6322fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            return mHasOnTextChanged;
6323fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6324fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6325fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void afterTextChanged(Editable s) {
6326fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledAfterTextChanged = true;
6327fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6328fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6329fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
6330fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasCalledBeforeTextChanged = true;
6331fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6332fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6333fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        public void onTextChanged(CharSequence s, int start, int before, int count) {
6334fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su            mHasOnTextChanged = true;
6335fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su        }
6336fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    }
6337fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su
6338fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su    /**
6339277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook     * A TextWatcher that converts the text to spaces whenever the text changes.
6340277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook     */
6341277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    private static class ConvertToSpacesTextWatcher implements TextWatcher {
6342277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        boolean mChangingText;
6343277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
6344277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
6345277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
6346277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
6347277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
6348277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
6349277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void onTextChanged(CharSequence s, int start, int before, int count) {
6350277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
6351277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook
6352277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        @Override
6353277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        public void afterTextChanged(Editable s) {
6354277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            // Avoid infinite recursion.
6355277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            if (mChangingText) {
6356277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                return;
6357277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
6358277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            mChangingText = true;
6359277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            // Create a string of s.length() spaces.
6360277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            StringBuilder builder = new StringBuilder(s.length());
6361277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            for (int i = 0; i < s.length(); i++) {
6362277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook                builder.append(' ');
6363277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            }
6364277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            s.replace(0, s.length(), builder.toString());
6365277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook            mChangingText = false;
6366277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook        }
6367277fd69e9d1f08b601cd6f12ff5f13e200a6b63aJames Cook    }
6368fa0bdcfa2bdacc555a6cecd0e5e0ed46afa06970Scott Su}
6369