• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.view.cts;
18 
19 import static com.android.compatibility.common.util.CtsMockitoUtils.within;
20 
21 import static org.junit.Assert.assertArrayEquals;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertSame;
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.Mockito.doAnswer;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.reset;
31 import static org.mockito.Mockito.spy;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.verifyNoMoreInteractions;
35 
36 import android.Manifest;
37 import android.app.Activity;
38 import android.app.Instrumentation;
39 import android.graphics.Bitmap;
40 import android.graphics.Color;
41 import android.platform.test.annotations.AppModeSdkSandbox;
42 import android.view.View;
43 import android.view.View.OnClickListener;
44 import android.widget.Button;
45 import android.widget.EditText;
46 import android.widget.RelativeLayout;
47 import android.widget.TextView;
48 
49 import androidx.test.InstrumentationRegistry;
50 import androidx.test.annotation.UiThreadTest;
51 import androidx.test.filters.MediumTest;
52 import androidx.test.rule.ActivityTestRule;
53 import androidx.test.runner.AndroidJUnit4;
54 import androidx.test.uiautomator.UiDevice;
55 
56 import com.android.compatibility.common.util.AdoptShellPermissionsRule;
57 import com.android.compatibility.common.util.CtsTouchUtils;
58 
59 import org.junit.Before;
60 import org.junit.Rule;
61 import org.junit.Test;
62 import org.junit.runner.RunWith;
63 import org.mockito.invocation.InvocationOnMock;
64 
65 @MediumTest
66 @RunWith(AndroidJUnit4.class)
67 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).")
68 public class View_UsingViewsTest {
69     /**
70      * country of Argentina
71      */
72     private static final String ARGENTINA = "Argentina";
73 
74     /**
75      * country of America
76      */
77     private static final String AMERICA = "America";
78 
79     /**
80      * country of China
81      */
82     private static final String CHINA = "China";
83 
84     /**
85      * the symbol of Argentina is football
86      */
87     private static final String ARGENTINA_SYMBOL = "football";
88 
89     /**
90      * the symbol of America is basketball
91      */
92     private static final String AMERICA_SYMBOL = "basketball";
93 
94     /**
95      * the symbol of China is table tennis
96      */
97     private static final String CHINA_SYMBOL = "table tennis";
98 
99     private Instrumentation mInstrumentation;
100     private CtsTouchUtils mCtsTouchUtils;
101 
102     private Activity mActivity;
103 
104     private EditText mEditText;
105     private Button mButtonOk;
106     private Button mButtonCancel;
107     private TextView mSymbolTextView;
108     private TextView mWarningTextView;
109 
110     @Rule(order = 0)
111     public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule(
112             androidx.test.platform.app.InstrumentationRegistry
113                     .getInstrumentation().getUiAutomation(),
114             Manifest.permission.START_ACTIVITIES_FROM_SDK_SANDBOX);
115 
116     @Rule(order = 1)
117     public ActivityTestRule<UsingViewsCtsActivity> mActivityRule =
118             new ActivityTestRule<>(UsingViewsCtsActivity.class, /* initialTouchMode= */ true);
119 
120     @Before
setup()121     public void setup() {
122         mInstrumentation = InstrumentationRegistry.getInstrumentation();
123         mCtsTouchUtils = new CtsTouchUtils(mInstrumentation.getTargetContext());
124         mActivity = mActivityRule.getActivity();
125 
126         mEditText = (EditText) mActivity.findViewById(R.id.entry);
127         mButtonOk = (Button) mActivity.findViewById(R.id.ok);
128         mButtonCancel = (Button) mActivity.findViewById(R.id.cancel);
129         mSymbolTextView = (TextView) mActivity.findViewById(R.id.symbolball);
130         mWarningTextView = (TextView) mActivity.findViewById(R.id.warning);
131     }
132 
133     @UiThreadTest
134     @Test
testSetProperties()135     public void testSetProperties() {
136         // setClickable, setOnClickListener
137         mButtonOk.setClickable(true);
138         assertTrue(mButtonOk.isClickable());
139 
140         View.OnClickListener okButtonListener = spy(new MockOnClickOkListener());
141         mButtonOk.setOnClickListener(okButtonListener);
142 
143         mButtonOk.performClick();
144         verify(okButtonListener, times(1)).onClick(mButtonOk);
145 
146         mButtonCancel.setClickable(false);
147         assertFalse(mButtonCancel.isClickable());
148 
149         View.OnClickListener cancelButtonListener = mock(View.OnClickListener.class);
150         doAnswer((InvocationOnMock invocation) -> {
151             mEditText.setText(null);
152             return null;
153         }).when(cancelButtonListener).onClick(any(View.class));
154         mButtonCancel.setOnClickListener(cancelButtonListener);
155         assertTrue(mButtonCancel.isClickable());
156 
157         mButtonCancel.performClick();
158         verify(cancelButtonListener, times(1)).onClick(mButtonCancel);
159 
160         // setDrawingCacheEnabled, setDrawingCacheQuality, setDrawingCacheBackgroundColor,
161         mEditText.setDrawingCacheEnabled(true);
162         assertTrue(mEditText.isDrawingCacheEnabled());
163 
164         // the default quality is auto
165         assertEquals(View.DRAWING_CACHE_QUALITY_AUTO, mEditText.getDrawingCacheQuality());
166         mEditText.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_LOW);
167         assertEquals(View.DRAWING_CACHE_QUALITY_LOW, mEditText.getDrawingCacheQuality());
168         mEditText.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
169         assertEquals(View.DRAWING_CACHE_QUALITY_HIGH, mEditText.getDrawingCacheQuality());
170 
171         mEditText.setDrawingCacheBackgroundColor(Color.GREEN);
172         assertEquals(Color.GREEN, mEditText.getDrawingCacheBackgroundColor());
173 
174         // create the cache
175         Bitmap b = mEditText.getDrawingCache();
176         assertNotNull(b);
177         assertEquals(mEditText.getHeight(), b.getHeight());
178         assertEquals(mEditText.getWidth(), b.getWidth());
179         assertEquals(Color.GREEN, b.getPixel(0, 0));
180 
181         // setDrawingCacheEnabled to false
182         mEditText.setDrawingCacheEnabled(false);
183         assertFalse(mEditText.isDrawingCacheEnabled());
184 
185         mEditText.setDrawingCacheBackgroundColor(Color.YELLOW);
186         assertEquals(Color.YELLOW, mEditText.getDrawingCacheBackgroundColor());
187 
188         // build drawable cache
189         mEditText.buildDrawingCache();
190         b = mEditText.getDrawingCache();
191         assertNotNull(b);
192         assertEquals(mEditText.getHeight(), b.getHeight());
193         assertEquals(mEditText.getWidth(), b.getWidth());
194         assertEquals(Color.YELLOW, b.getPixel(0, 0));
195         mEditText.destroyDrawingCache();
196 
197         // setDuplicateParentStateEnabled
198         TextView v = new TextView(mActivity);
199         v.setSingleLine(); // otherwise the multiline state interferes with theses tests
200         v.setEnabled(false);
201         v.setText("Test setDuplicateParentStateEnabled");
202 
203         v.setDuplicateParentStateEnabled(false);
204         assertFalse(v.isDuplicateParentStateEnabled());
205 
206         RelativeLayout parent = (RelativeLayout) mEditText.getParent();
207         parent.addView(v);
208 
209         assertFalse(parent.getDrawableState().length == v.getDrawableState().length);
210         parent.removeView(v);
211 
212         v.setDuplicateParentStateEnabled(true);
213         assertTrue(v.isDuplicateParentStateEnabled());
214 
215         parent.addView(v);
216         v.refreshDrawableState();
217 
218         assertArrayEquals(parent.getDrawableState(), v.getDrawableState());
219         parent.removeView(v);
220 
221         // setEnabled
222         mWarningTextView.setEnabled(false);
223         assertFalse(mWarningTextView.isEnabled());
224 
225         mWarningTextView.setEnabled(true);
226         assertTrue(mWarningTextView.isEnabled());
227 
228         // setFadingEdgeLength, setVerticalFadingEdgeEnabled and
229         // setHorizontalFadingEdgeEnabled(boolean)
230         mWarningTextView.setVerticalFadingEdgeEnabled(true);
231         assertTrue(mWarningTextView.isVerticalFadingEdgeEnabled());
232         mWarningTextView.setFadingEdgeLength(10);
233 
234         mSymbolTextView.setHorizontalFadingEdgeEnabled(true);
235         assertTrue(mSymbolTextView.isHorizontalFadingEdgeEnabled());
236         mSymbolTextView.setFadingEdgeLength(100);
237 
238         // setFocusable and setFocusableInTouchMode
239         mButtonCancel.setFocusable(false);
240         assertFalse(mButtonCancel.isFocusable());
241         assertFalse(mButtonCancel.isFocusableInTouchMode());
242 
243         mButtonCancel.setFocusable(true);
244         assertTrue(mButtonCancel.isFocusable());
245         assertFalse(mButtonCancel.isFocusableInTouchMode());
246 
247         mButtonCancel.setFocusableInTouchMode(true);
248         assertTrue(mButtonCancel.isFocusable());
249         assertTrue(mButtonCancel.isFocusableInTouchMode());
250 
251         mButtonOk.setFocusable(false);
252         assertFalse(mButtonOk.isFocusable());
253         assertFalse(mButtonOk.isFocusableInTouchMode());
254 
255         mButtonOk.setFocusableInTouchMode(true);
256         assertTrue(mButtonOk.isFocusable());
257         assertTrue(mButtonOk.isFocusableInTouchMode());
258 
259         // setHorizontalScrollBarEnabled and setVerticalScrollBarEnabled
260         // both two bar is not drawn by default
261         assertFalse(parent.isHorizontalScrollBarEnabled());
262         assertFalse(parent.isVerticalScrollBarEnabled());
263 
264         parent.setHorizontalScrollBarEnabled(true);
265         assertTrue(parent.isHorizontalScrollBarEnabled());
266 
267         parent.setVerticalScrollBarEnabled(true);
268         assertTrue(parent.isVerticalScrollBarEnabled());
269 
270         // setId
271         assertEquals(View.NO_ID, parent.getId());
272         assertEquals(R.id.entry, mEditText.getId());
273         assertEquals(R.id.symbolball, mSymbolTextView.getId());
274 
275         mSymbolTextView.setId(0x5555);
276         assertEquals(0x5555, mSymbolTextView.getId());
277         TextView t = (TextView) parent.findViewById(0x5555);
278         assertSame(mSymbolTextView, t);
279 
280         mSymbolTextView.setId(R.id.symbolball);
281         assertEquals(R.id.symbolball, mSymbolTextView.getId());
282     }
283 
284     @UiThreadTest
285     @Test
testSetFocus()286     public void testSetFocus() {
287         boolean focusWasOnEditText = mEditText.hasFocus();
288 
289         View.OnFocusChangeListener editListener = mock(View.OnFocusChangeListener.class);
290         View.OnFocusChangeListener okListener = mock(View.OnFocusChangeListener.class);
291         View.OnFocusChangeListener cancelListener = mock(View.OnFocusChangeListener.class);
292         View.OnFocusChangeListener symbolListener = mock(View.OnFocusChangeListener.class);
293         View.OnFocusChangeListener warningListener = mock(View.OnFocusChangeListener.class);
294 
295         mEditText.setOnFocusChangeListener(editListener);
296         mButtonOk.setOnFocusChangeListener(okListener);
297         mButtonCancel.setOnFocusChangeListener(cancelListener);
298         mSymbolTextView.setOnFocusChangeListener(symbolListener);
299         mWarningTextView.setOnFocusChangeListener(warningListener);
300 
301         mSymbolTextView.setText(ARGENTINA_SYMBOL);
302         mWarningTextView.setVisibility(View.VISIBLE);
303 
304         assertTrue(mEditText.requestFocus());
305         assertTrue(mEditText.hasFocus());
306         assertFalse(mButtonOk.hasFocus());
307         assertFalse(mButtonCancel.hasFocus());
308         assertFalse(mSymbolTextView.hasFocus());
309         assertFalse(mWarningTextView.hasFocus());
310 
311         if (!focusWasOnEditText) {
312             verify(editListener, times(1)).onFocusChange(mEditText, true);
313         }
314         verifyNoMoreInteractions(okListener);
315         verifyNoMoreInteractions(cancelListener);
316         verifyNoMoreInteractions(symbolListener);
317         verifyNoMoreInteractions(warningListener);
318 
319         // exit touch mode and set ok button to focus
320         reset(editListener);
321         assertTrue(mButtonOk.requestFocusFromTouch());
322         assertTrue(mButtonOk.hasFocus());
323         verify(okListener, times(1)).onFocusChange(mButtonOk, true);
324         assertFalse(mEditText.hasFocus());
325         verify(editListener, times(1)).onFocusChange(mEditText, false);
326         verifyNoMoreInteractions(cancelListener);
327         verifyNoMoreInteractions(symbolListener);
328         verifyNoMoreInteractions(warningListener);
329 
330         // set cancel button to focus
331         reset(okListener);
332         reset(editListener);
333         assertTrue(mButtonCancel.requestFocus());
334         assertTrue(mButtonCancel.hasFocus());
335         verify(cancelListener, times(1)).onFocusChange(mButtonCancel, true);
336         assertFalse(mButtonOk.hasFocus());
337         verify(okListener, times(1)).onFocusChange(mButtonOk, false);
338         verifyNoMoreInteractions(editListener);
339         verifyNoMoreInteractions(symbolListener);
340         verifyNoMoreInteractions(warningListener);
341 
342         // set symbol text to focus
343         mSymbolTextView.setFocusable(true);
344         assertTrue(mSymbolTextView.requestFocus());
345         assertTrue(mSymbolTextView.hasFocus());
346         verify(symbolListener, times(1)).onFocusChange(mSymbolTextView, true);
347         assertFalse(mButtonCancel.hasFocus());
348         verify(cancelListener, times(1)).onFocusChange(mButtonCancel, false);
349         verifyNoMoreInteractions(okListener);
350         verifyNoMoreInteractions(editListener);
351         verifyNoMoreInteractions(warningListener);
352 
353         // set warning text to focus
354         mWarningTextView.setFocusable(true);
355         assertTrue(mWarningTextView.requestFocus());
356         assertTrue(mWarningTextView.hasFocus());
357         verify(warningListener, times(1)).onFocusChange(mWarningTextView, true);
358         assertFalse(mSymbolTextView.hasFocus());
359         verify(symbolListener, times(1)).onFocusChange(mSymbolTextView, false);
360         verifyNoMoreInteractions(editListener);
361         verifyNoMoreInteractions(okListener);
362         verifyNoMoreInteractions(cancelListener);
363 
364         // set edit text to focus
365         assertTrue(mEditText.requestFocus());
366         assertTrue(mEditText.hasFocus());
367         verify(editListener, times(1)).onFocusChange(mEditText, true);
368         assertFalse(mWarningTextView.hasFocus());
369         verify(warningListener, times(1)).onFocusChange(mWarningTextView, false);
370         verifyNoMoreInteractions(cancelListener);
371         verifyNoMoreInteractions(symbolListener);
372         verifyNoMoreInteractions(okListener);
373     }
374 
375     @Test
testSetupListeners()376     public void testSetupListeners() throws Throwable {
377         // set ok button OnClick listener
378         mButtonOk.setClickable(true);
379         assertTrue(mButtonOk.isClickable());
380 
381         View.OnClickListener okButtonListener = spy(new MockOnClickOkListener());
382         mButtonOk.setOnClickListener(okButtonListener);
383 
384         // set cancel button OnClick listener
385         mButtonCancel.setClickable(true);
386         assertTrue(mButtonCancel.isClickable());
387 
388         View.OnClickListener cancelButtonListener = mock(View.OnClickListener.class);
389         doAnswer((InvocationOnMock invocation) -> {
390             mEditText.setText(null);
391             return null;
392         }).when(cancelButtonListener).onClick(any(View.class));
393         mButtonCancel.setOnClickListener(cancelButtonListener);
394 
395         // set edit text OnLongClick listener
396         mEditText.setLongClickable(true);
397         assertTrue(mEditText.isLongClickable());
398 
399         final View.OnLongClickListener onLongClickListener =
400                 mock(View.OnLongClickListener.class);
401         mEditText.setOnLongClickListener(onLongClickListener);
402 
403         // long click the edit text
404         mInstrumentation.waitForIdleSync();
405         mCtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, mActivityRule, mEditText);
406         verify(onLongClickListener, within(1000)).onLongClick(mEditText);
407 
408         // Wait for the UI Thread to become idle.
409         final UiDevice device = UiDevice.getInstance(mInstrumentation);
410 
411         // click the Cancel button
412         mActivityRule.runOnUiThread(() -> mEditText.setText("Germany"));
413         mInstrumentation.waitForIdleSync();
414         device.waitForIdle();
415 
416         mCtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mButtonCancel);
417         assertEquals("", mEditText.getText().toString());
418 
419         mInstrumentation.waitForIdleSync();
420         device.waitForIdle();
421 
422         // click the OK button
423         mActivityRule.runOnUiThread(() -> mEditText.setText(ARGENTINA));
424         mInstrumentation.waitForIdleSync();
425 
426         mCtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mButtonOk);
427         assertEquals(ARGENTINA_SYMBOL, mSymbolTextView.getText().toString());
428 
429         mActivityRule.runOnUiThread(() -> mEditText.setText(AMERICA));
430         mInstrumentation.waitForIdleSync();
431 
432         mCtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mButtonOk);
433         assertEquals(AMERICA_SYMBOL, mSymbolTextView.getText().toString());
434 
435         mActivityRule.runOnUiThread(() -> mEditText.setText(CHINA));
436         mInstrumentation.waitForIdleSync();
437 
438         mCtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mButtonOk);
439         assertEquals(CHINA_SYMBOL, mSymbolTextView.getText().toString());
440 
441         mActivityRule.runOnUiThread(() -> mEditText.setText("Unknown"));
442         mInstrumentation.waitForIdleSync();
443 
444         mCtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mButtonOk);
445         assertEquals(View.VISIBLE, mWarningTextView.getVisibility());
446     }
447 
448     @UiThreadTest
449     @Test
testSetVisibility()450     public void testSetVisibility() {
451         mActivity.setContentView(R.layout.view_visibility_layout);
452 
453         View v1 = mActivity.findViewById(R.id.textview1);
454         View v2 = mActivity.findViewById(R.id.textview2);
455         View v3 = mActivity.findViewById(R.id.textview3);
456 
457         assertNotNull(v1);
458         assertNotNull(v2);
459         assertNotNull(v3);
460 
461         assertEquals(View.VISIBLE, v1.getVisibility());
462         assertEquals(View.INVISIBLE, v2.getVisibility());
463         assertEquals(View.GONE, v3.getVisibility());
464 
465         v1.setVisibility(View.GONE);
466         assertEquals(View.GONE, v1.getVisibility());
467 
468         v2.setVisibility(View.VISIBLE);
469         assertEquals(View.VISIBLE, v2.getVisibility());
470 
471         v3.setVisibility(View.INVISIBLE);
472         assertEquals(View.INVISIBLE, v3.getVisibility());
473     }
474 
475     protected class MockOnClickOkListener implements OnClickListener {
showPicture(String country)476         private boolean showPicture(String country) {
477             if (ARGENTINA.equals(country)) {
478                 mSymbolTextView.setText(ARGENTINA_SYMBOL);
479                 return true;
480             } else if (AMERICA.equals(country)) {
481                 mSymbolTextView.setText(AMERICA_SYMBOL);
482                 return true;
483             } else if (CHINA.equals(country)) {
484                 mSymbolTextView.setText(CHINA_SYMBOL);
485                 return true;
486             }
487 
488             return false;
489         }
490 
onClick(View v)491         public void onClick(View v) {
492             String country = mEditText.getText().toString();
493             if (!showPicture(country)) {
494                 mWarningTextView.setVisibility(View.VISIBLE);
495             } else if (View.VISIBLE == mWarningTextView.getVisibility()) {
496                 mWarningTextView.setVisibility(View.INVISIBLE);
497             }
498         }
499     }
500 }
501