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