• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 org.mockito.Mockito.*;
20 
21 import android.graphics.BitmapFactory;
22 import com.android.internal.view.menu.ContextMenuBuilder;
23 
24 import android.content.Context;
25 import android.content.res.ColorStateList;
26 import android.content.res.Resources;
27 import android.content.res.XmlResourceParser;
28 import android.cts.util.PollingCheck;
29 import android.graphics.Bitmap;
30 import android.graphics.Canvas;
31 import android.graphics.Color;
32 import android.graphics.ColorFilter;
33 import android.graphics.Point;
34 import android.graphics.PorterDuff;
35 import android.graphics.Rect;
36 import android.graphics.drawable.BitmapDrawable;
37 import android.graphics.drawable.ColorDrawable;
38 import android.graphics.drawable.Drawable;
39 import android.graphics.drawable.StateListDrawable;
40 import android.os.Bundle;
41 import android.os.Parcelable;
42 import android.os.SystemClock;
43 import android.os.Vibrator;
44 import android.test.ActivityInstrumentationTestCase2;
45 import android.test.TouchUtils;
46 import android.test.UiThreadTest;
47 import android.text.format.DateUtils;
48 import android.util.AttributeSet;
49 import android.util.Log;
50 import android.util.Pair;
51 import android.util.SparseArray;
52 import android.util.Xml;
53 import android.view.ActionMode;
54 import android.view.ContextMenu;
55 import android.view.ContextMenu.ContextMenuInfo;
56 import android.view.Display;
57 import android.view.HapticFeedbackConstants;
58 import android.view.InputDevice;
59 import android.view.KeyEvent;
60 import android.view.Menu;
61 import android.view.MenuInflater;
62 import android.view.MotionEvent;
63 import android.view.PointerIcon;
64 import android.view.SoundEffectConstants;
65 import android.view.TouchDelegate;
66 import android.view.View;
67 import android.view.View.BaseSavedState;
68 import android.view.View.OnClickListener;
69 import android.view.View.OnContextClickListener;
70 import android.view.View.OnCreateContextMenuListener;
71 import android.view.View.OnFocusChangeListener;
72 import android.view.View.OnKeyListener;
73 import android.view.View.OnLongClickListener;
74 import android.view.View.OnTouchListener;
75 import android.view.ViewConfiguration;
76 import android.view.ViewGroup;
77 import android.view.ViewParent;
78 import android.view.ViewTreeObserver;
79 import android.view.WindowManager;
80 import android.view.accessibility.AccessibilityEvent;
81 import android.view.animation.AlphaAnimation;
82 import android.view.animation.Animation;
83 import android.view.inputmethod.EditorInfo;
84 import android.view.inputmethod.InputConnection;
85 import android.view.inputmethod.InputMethodManager;
86 import android.widget.Button;
87 import android.widget.EditText;
88 import android.widget.FrameLayout;
89 import android.widget.LinearLayout;
90 
91 import java.lang.reflect.Constructor;
92 import java.util.ArrayList;
93 import java.util.Arrays;
94 import java.util.Collections;
95 import java.util.concurrent.CountDownLatch;
96 import java.util.concurrent.TimeUnit;
97 import java.util.concurrent.atomic.AtomicBoolean;
98 
99 /**
100  * Test {@link View}.
101  */
102 public class ViewTest extends ActivityInstrumentationTestCase2<ViewTestCtsActivity> {
ViewTest()103     public ViewTest() {
104         super(ViewTestCtsActivity.class);
105     }
106 
107     private Resources mResources;
108     private MockViewParent mMockParent;
109     private ViewTestCtsActivity mActivity;
110 
111     /** timeout delta when wait in case the system is sluggish */
112     private static final long TIMEOUT_DELTA = 10000;
113 
114     private static final String LOG_TAG = "ViewTest";
115 
116     @Override
setUp()117     protected void setUp() throws Exception {
118         super.setUp();
119         mActivity = getActivity();
120         new PollingCheck() {
121             @Override
122                 protected boolean check() {
123                 return mActivity.hasWindowFocus();
124             }
125         }.run();
126         mResources = mActivity.getResources();
127         mMockParent = new MockViewParent(mActivity);
128         assertTrue(mActivity.waitForWindowFocus(5 * DateUtils.SECOND_IN_MILLIS));
129     }
130 
testConstructor()131     public void testConstructor() {
132         new View(mActivity);
133 
134         final XmlResourceParser parser = mResources.getLayout(R.layout.view_layout);
135         final AttributeSet attrs = Xml.asAttributeSet(parser);
136         new View(mActivity, attrs);
137 
138         new View(mActivity, null);
139 
140         try {
141             new View(null, attrs);
142             fail("should throw NullPointerException");
143         } catch (NullPointerException e) {
144         }
145 
146         new View(mActivity, attrs, 0);
147 
148         new View(mActivity, null, 1);
149 
150         try {
151             new View(null, null, 1);
152             fail("should throw NullPointerException");
153         } catch (NullPointerException e) {
154         }
155     }
156 
157     // Test that validates that Views can be constructed on a thread that
158     // does not have a Looper. Necessary for async inflation
159     private Pair<Class<?>, Throwable> sCtorException = null;
testConstructor2()160     public void testConstructor2() throws Exception {
161         final Object[] args = new Object[] { mActivity, null };
162         final CountDownLatch latch = new CountDownLatch(1);
163         sCtorException = null;
164         new Thread() {
165             @Override
166             public void run() {
167                 final Class<?>[] ctorSignature = new Class[] {
168                         Context.class, AttributeSet.class};
169                 for (Class<?> clazz : ASYNC_INFLATE_VIEWS) {
170                     try {
171                         Constructor<?> constructor = clazz.getConstructor(ctorSignature);
172                         constructor.setAccessible(true);
173                         constructor.newInstance(args);
174                     } catch (Throwable t) {
175                         sCtorException = new Pair<Class<?>, Throwable>(clazz, t);
176                         break;
177                     }
178                 }
179                 latch.countDown();
180             }
181         }.start();
182         latch.await();
183         if (sCtorException != null) {
184             throw new AssertionError("Failed to inflate "
185                     + sCtorException.first.getName(), sCtorException.second);
186         }
187     }
188 
testGetContext()189     public void testGetContext() {
190         View view = new View(mActivity);
191         assertSame(mActivity, view.getContext());
192     }
193 
testGetResources()194     public void testGetResources() {
195         View view = new View(mActivity);
196         assertSame(mResources, view.getResources());
197     }
198 
testGetAnimation()199     public void testGetAnimation() {
200         Animation animation = new AlphaAnimation(0.0f, 1.0f);
201         View view = new View(mActivity);
202         assertNull(view.getAnimation());
203 
204         view.setAnimation(animation);
205         assertSame(animation, view.getAnimation());
206 
207         view.clearAnimation();
208         assertNull(view.getAnimation());
209     }
210 
testSetAnimation()211     public void testSetAnimation() {
212         Animation animation = new AlphaAnimation(0.0f, 1.0f);
213         View view = new View(mActivity);
214         assertNull(view.getAnimation());
215 
216         animation.initialize(100, 100, 100, 100);
217         assertTrue(animation.isInitialized());
218         view.setAnimation(animation);
219         assertSame(animation, view.getAnimation());
220         assertFalse(animation.isInitialized());
221 
222         view.setAnimation(null);
223         assertNull(view.getAnimation());
224     }
225 
testClearAnimation()226     public void testClearAnimation() {
227         Animation animation = new AlphaAnimation(0.0f, 1.0f);
228         View view = new View(mActivity);
229 
230         assertNull(view.getAnimation());
231         view.clearAnimation();
232         assertNull(view.getAnimation());
233 
234         view.setAnimation(animation);
235         assertNotNull(view.getAnimation());
236         view.clearAnimation();
237         assertNull(view.getAnimation());
238     }
239 
testStartAnimation()240     public void testStartAnimation() {
241         Animation animation = new AlphaAnimation(0.0f, 1.0f);
242         View view = new View(mActivity);
243 
244         try {
245             view.startAnimation(null);
246             fail("should throw NullPointerException");
247         } catch (NullPointerException e) {
248         }
249 
250         animation.setStartTime(1L);
251         assertEquals(1L, animation.getStartTime());
252         view.startAnimation(animation);
253         assertEquals(Animation.START_ON_FIRST_FRAME, animation.getStartTime());
254     }
255 
testOnAnimation()256     public void testOnAnimation() throws Throwable {
257         final Animation animation = new AlphaAnimation(0.0f, 1.0f);
258         long duration = 2000L;
259         animation.setDuration(duration);
260         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
261 
262         // check whether it has started
263         runTestOnUiThread(new Runnable() {
264             @Override
265             public void run() {
266                 view.startAnimation(animation);
267             }
268         });
269         getInstrumentation().waitForIdleSync();
270 
271         new PollingCheck() {
272             @Override
273             protected boolean check() {
274                 return view.hasCalledOnAnimationStart();
275             }
276         }.run();
277 
278         // check whether it has ended after duration, and alpha changed during this time.
279         new PollingCheck(duration + TIMEOUT_DELTA) {
280             @Override
281             protected boolean check() {
282                 return view.hasCalledOnSetAlpha() && view.hasCalledOnAnimationEnd();
283             }
284         }.run();
285     }
286 
testGetParent()287     public void testGetParent() {
288         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
289         ViewGroup parent = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
290         assertSame(parent, view.getParent());
291     }
292 
testAccessScrollIndicators()293     public void testAccessScrollIndicators() {
294         View view = mActivity.findViewById(R.id.viewlayout_root);
295 
296         assertEquals(View.SCROLL_INDICATOR_LEFT | View.SCROLL_INDICATOR_RIGHT,
297                 view.getScrollIndicators());
298     }
299 
testSetScrollIndicators()300     public void testSetScrollIndicators() {
301         View view = new View(mActivity);
302 
303         view.setScrollIndicators(0);
304         assertEquals(0, view.getScrollIndicators());
305 
306         view.setScrollIndicators(View.SCROLL_INDICATOR_LEFT | View.SCROLL_INDICATOR_RIGHT);
307         assertEquals(View.SCROLL_INDICATOR_LEFT | View.SCROLL_INDICATOR_RIGHT,
308                 view.getScrollIndicators());
309 
310         view.setScrollIndicators(View.SCROLL_INDICATOR_TOP, View.SCROLL_INDICATOR_TOP);
311         assertEquals(View.SCROLL_INDICATOR_LEFT | View.SCROLL_INDICATOR_RIGHT
312                         | View.SCROLL_INDICATOR_TOP, view.getScrollIndicators());
313 
314         view.setScrollIndicators(0, view.getScrollIndicators());
315         assertEquals(0, view.getScrollIndicators());
316     }
317 
testFindViewById()318     public void testFindViewById() {
319         View parent = mActivity.findViewById(R.id.viewlayout_root);
320         assertSame(parent, parent.findViewById(R.id.viewlayout_root));
321 
322         View view = parent.findViewById(R.id.mock_view);
323         assertTrue(view instanceof MockView);
324     }
325 
testAccessTouchDelegate()326     public void testAccessTouchDelegate() throws Throwable {
327         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
328         Rect rect = new Rect();
329         final Button button = new Button(mActivity);
330         final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT;
331         final int btnHeight = view.getHeight()/3;
332         runTestOnUiThread(new Runnable() {
333             @Override
334             public void run() {
335                 mActivity.addContentView(button,
336                         new LinearLayout.LayoutParams(WRAP_CONTENT, btnHeight));
337             }
338         });
339         getInstrumentation().waitForIdleSync();
340         button.getHitRect(rect);
341         MockTouchDelegate delegate = new MockTouchDelegate(rect, button);
342 
343         assertNull(view.getTouchDelegate());
344 
345         view.setTouchDelegate(delegate);
346         assertSame(delegate, view.getTouchDelegate());
347         assertFalse(delegate.hasCalledOnTouchEvent());
348         TouchUtils.clickView(this, view);
349         assertTrue(view.hasCalledOnTouchEvent());
350         assertTrue(delegate.hasCalledOnTouchEvent());
351 
352         view.setTouchDelegate(null);
353         assertNull(view.getTouchDelegate());
354     }
355 
testMouseEventCallsGetPointerIcon()356     public void testMouseEventCallsGetPointerIcon() {
357         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
358 
359         final int[] xy = new int[2];
360         view.getLocationOnScreen(xy);
361         final int viewWidth = view.getWidth();
362         final int viewHeight = view.getHeight();
363         float x = xy[0] + viewWidth / 2.0f;
364         float y = xy[1] + viewHeight / 2.0f;
365 
366         long eventTime = SystemClock.uptimeMillis();
367 
368         MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[1];
369         pointerCoords[0] = new MotionEvent.PointerCoords();
370         pointerCoords[0].x = x;
371         pointerCoords[0].y = y;
372 
373         final int[] pointerIds = new int[1];
374         pointerIds[0] = 0;
375 
376         MotionEvent event = MotionEvent.obtain(0, eventTime, MotionEvent.ACTION_HOVER_MOVE,
377                 1, pointerIds, pointerCoords, 0, 0, 0, 0, 0, InputDevice.SOURCE_MOUSE, 0);
378         getInstrumentation().sendPointerSync(event);
379         getInstrumentation().waitForIdleSync();
380 
381         assertTrue(view.hasCalledOnResolvePointerIcon());
382 
383         final MockView view2 = (MockView) mActivity.findViewById(R.id.scroll_view);
384         assertFalse(view2.hasCalledOnResolvePointerIcon());
385     }
386 
testAccessPointerIcon()387     public void testAccessPointerIcon() {
388         View view = mActivity.findViewById(R.id.pointer_icon_layout);
389         MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE, 0, 0, 0);
390 
391         // First view has pointerIcon="help"
392         assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_HELP),
393                      view.onResolvePointerIcon(event, 0));
394 
395         // Second view inherits pointerIcon="crosshair" from the parent
396         event.setLocation(0, 21);
397         assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_CROSSHAIR),
398                      view.onResolvePointerIcon(event, 0));
399 
400         // Third view has custom pointer icon defined in a resource.
401         event.setLocation(0, 41);
402         assertNotNull(view.onResolvePointerIcon(event, 0));
403 
404         // Parent view has pointerIcon="crosshair"
405         event.setLocation(0, 61);
406         assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_CROSSHAIR),
407                      view.onResolvePointerIcon(event, 0));
408 
409         // Outside of the parent view, no pointer icon defined.
410         event.setLocation(0, 71);
411         assertNull(view.onResolvePointerIcon(event, 0));
412 
413         view.setPointerIcon(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_TEXT));
414         assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_TEXT),
415                      view.onResolvePointerIcon(event, 0));
416         event.recycle();
417     }
418 
testCreatePointerIcons()419     public void testCreatePointerIcons() {
420         assertSystemPointerIcon(PointerIcon.TYPE_NULL);
421         assertSystemPointerIcon(PointerIcon.TYPE_DEFAULT);
422         assertSystemPointerIcon(PointerIcon.TYPE_ARROW);
423         assertSystemPointerIcon(PointerIcon.TYPE_CONTEXT_MENU);
424         assertSystemPointerIcon(PointerIcon.TYPE_HAND);
425         assertSystemPointerIcon(PointerIcon.TYPE_HELP);
426         assertSystemPointerIcon(PointerIcon.TYPE_WAIT);
427         assertSystemPointerIcon(PointerIcon.TYPE_CELL);
428         assertSystemPointerIcon(PointerIcon.TYPE_CROSSHAIR);
429         assertSystemPointerIcon(PointerIcon.TYPE_TEXT);
430         assertSystemPointerIcon(PointerIcon.TYPE_VERTICAL_TEXT);
431         assertSystemPointerIcon(PointerIcon.TYPE_ALIAS);
432         assertSystemPointerIcon(PointerIcon.TYPE_COPY);
433         assertSystemPointerIcon(PointerIcon.TYPE_NO_DROP);
434         assertSystemPointerIcon(PointerIcon.TYPE_ALL_SCROLL);
435         assertSystemPointerIcon(PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW);
436         assertSystemPointerIcon(PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW);
437         assertSystemPointerIcon(PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW);
438         assertSystemPointerIcon(PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW);
439         assertSystemPointerIcon(PointerIcon.TYPE_ZOOM_IN);
440         assertSystemPointerIcon(PointerIcon.TYPE_ZOOM_OUT);
441         assertSystemPointerIcon(PointerIcon.TYPE_GRAB);
442 
443         assertNotNull(PointerIcon.load(mResources, R.drawable.custom_pointer_icon));
444 
445         Bitmap bitmap = BitmapFactory.decodeResource(mResources, R.drawable.icon_blue);
446         assertNotNull(PointerIcon.create(bitmap, 0, 0));
447     }
448 
assertSystemPointerIcon(int style)449     private void assertSystemPointerIcon(int style) {
450         assertNotNull(PointerIcon.getSystemIcon(mActivity, style));
451     }
452 
453     @UiThreadTest
testAccessTag()454     public void testAccessTag() {
455         ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
456         MockView mockView = (MockView) mActivity.findViewById(R.id.mock_view);
457         MockView scrollView = (MockView) mActivity.findViewById(R.id.scroll_view);
458 
459         ViewData viewData = new ViewData();
460         viewData.childCount = 3;
461         viewData.tag = "linearLayout";
462         viewData.firstChild = mockView;
463         viewGroup.setTag(viewData);
464         viewGroup.setFocusable(true);
465         assertSame(viewData, viewGroup.getTag());
466 
467         final String tag = "mock";
468         assertNull(mockView.getTag());
469         mockView.setTag(tag);
470         assertEquals(tag, mockView.getTag());
471 
472         scrollView.setTag(viewGroup);
473         assertSame(viewGroup, scrollView.getTag());
474 
475         assertSame(viewGroup, viewGroup.findViewWithTag(viewData));
476         assertSame(mockView, viewGroup.findViewWithTag(tag));
477         assertSame(scrollView, viewGroup.findViewWithTag(viewGroup));
478 
479         mockView.setTag(null);
480         assertNull(mockView.getTag());
481     }
482 
testOnSizeChanged()483     public void testOnSizeChanged() throws Throwable {
484         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
485         final MockView mockView = new MockView(mActivity);
486         assertEquals(-1, mockView.getOldWOnSizeChanged());
487         assertEquals(-1, mockView.getOldHOnSizeChanged());
488         runTestOnUiThread(new Runnable() {
489             @Override
490             public void run() {
491                 viewGroup.addView(mockView);
492             }
493         });
494         getInstrumentation().waitForIdleSync();
495         assertTrue(mockView.hasCalledOnSizeChanged());
496         assertEquals(0, mockView.getOldWOnSizeChanged());
497         assertEquals(0, mockView.getOldHOnSizeChanged());
498 
499         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
500         assertTrue(view.hasCalledOnSizeChanged());
501         view.reset();
502         assertEquals(-1, view.getOldWOnSizeChanged());
503         assertEquals(-1, view.getOldHOnSizeChanged());
504         int oldw = view.getWidth();
505         int oldh = view.getHeight();
506         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, 100);
507         runTestOnUiThread(new Runnable() {
508             @Override
509             public void run() {
510                 view.setLayoutParams(layoutParams);
511             }
512         });
513         getInstrumentation().waitForIdleSync();
514         assertTrue(view.hasCalledOnSizeChanged());
515         assertEquals(oldw, view.getOldWOnSizeChanged());
516         assertEquals(oldh, view.getOldHOnSizeChanged());
517     }
518 
testGetHitRect()519     public void testGetHitRect() {
520         MockView view = new MockView(mActivity);
521         Rect outRect = new Rect();
522 
523         try {
524             view.getHitRect(null);
525             fail("should throw NullPointerException");
526         } catch (NullPointerException e) {
527         }
528 
529         View mockView = mActivity.findViewById(R.id.mock_view);
530         mockView.getHitRect(outRect);
531         assertEquals(0, outRect.left);
532         assertEquals(0, outRect.top);
533         assertEquals(mockView.getWidth(), outRect.right);
534         assertEquals(mockView.getHeight(), outRect.bottom);
535     }
536 
testForceLayout()537     public void testForceLayout() {
538         View view = new View(mActivity);
539 
540         assertFalse(view.isLayoutRequested());
541         view.forceLayout();
542         assertTrue(view.isLayoutRequested());
543 
544         view.forceLayout();
545         assertTrue(view.isLayoutRequested());
546     }
547 
testIsLayoutRequested()548     public void testIsLayoutRequested() {
549         View view = new View(mActivity);
550 
551         assertFalse(view.isLayoutRequested());
552         view.forceLayout();
553         assertTrue(view.isLayoutRequested());
554 
555         view.layout(0, 0, 0, 0);
556         assertFalse(view.isLayoutRequested());
557     }
558 
testRequestLayout()559     public void testRequestLayout() {
560         MockView view = new MockView(mActivity);
561         assertFalse(view.isLayoutRequested());
562         assertNull(view.getParent());
563 
564         view.requestLayout();
565         assertTrue(view.isLayoutRequested());
566 
567         view.setParent(mMockParent);
568         assertTrue(mMockParent.hasRequestLayout());
569 
570         mMockParent.reset();
571         view.requestLayout();
572         assertTrue(view.isLayoutRequested());
573         assertTrue(mMockParent.hasRequestLayout());
574     }
575 
testLayout()576     public void testLayout() throws Throwable {
577         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
578         assertTrue(view.hasCalledOnLayout());
579 
580         view.reset();
581         assertFalse(view.hasCalledOnLayout());
582         runTestOnUiThread(new Runnable() {
583             @Override
584             public void run() {
585                 view.requestLayout();
586             }
587         });
588         getInstrumentation().waitForIdleSync();
589         assertTrue(view.hasCalledOnLayout());
590     }
591 
testGetBaseline()592     public void testGetBaseline() {
593         View view = new View(mActivity);
594 
595         assertEquals(-1, view.getBaseline());
596     }
597 
testAccessBackground()598     public void testAccessBackground() {
599         View view = new View(mActivity);
600         Drawable d1 = mResources.getDrawable(R.drawable.scenery);
601         Drawable d2 = mResources.getDrawable(R.drawable.pass);
602 
603         assertNull(view.getBackground());
604 
605         view.setBackgroundDrawable(d1);
606         assertEquals(d1, view.getBackground());
607 
608         view.setBackgroundDrawable(d2);
609         assertEquals(d2, view.getBackground());
610 
611         view.setBackgroundDrawable(null);
612         assertNull(view.getBackground());
613     }
614 
testSetBackgroundResource()615     public void testSetBackgroundResource() {
616         View view = new View(mActivity);
617 
618         assertNull(view.getBackground());
619 
620         view.setBackgroundResource(R.drawable.pass);
621         assertNotNull(view.getBackground());
622 
623         view.setBackgroundResource(0);
624         assertNull(view.getBackground());
625     }
626 
testAccessDrawingCacheBackgroundColor()627     public void testAccessDrawingCacheBackgroundColor() {
628         View view = new View(mActivity);
629 
630         assertEquals(0, view.getDrawingCacheBackgroundColor());
631 
632         view.setDrawingCacheBackgroundColor(0xFF00FF00);
633         assertEquals(0xFF00FF00, view.getDrawingCacheBackgroundColor());
634 
635         view.setDrawingCacheBackgroundColor(-1);
636         assertEquals(-1, view.getDrawingCacheBackgroundColor());
637     }
638 
testSetBackgroundColor()639     public void testSetBackgroundColor() {
640         View view = new View(mActivity);
641         ColorDrawable colorDrawable;
642         assertNull(view.getBackground());
643 
644         view.setBackgroundColor(0xFFFF0000);
645         colorDrawable = (ColorDrawable) view.getBackground();
646         assertNotNull(colorDrawable);
647         assertEquals(0xFF, colorDrawable.getAlpha());
648 
649         view.setBackgroundColor(0);
650         colorDrawable = (ColorDrawable) view.getBackground();
651         assertNotNull(colorDrawable);
652         assertEquals(0, colorDrawable.getAlpha());
653     }
654 
testVerifyDrawable()655     public void testVerifyDrawable() {
656         MockView view = new MockView(mActivity);
657         Drawable d1 = mResources.getDrawable(R.drawable.scenery);
658         Drawable d2 = mResources.getDrawable(R.drawable.pass);
659 
660         assertNull(view.getBackground());
661         assertTrue(view.verifyDrawable(null));
662         assertFalse(view.verifyDrawable(d1));
663 
664         view.setBackgroundDrawable(d1);
665         assertTrue(view.verifyDrawable(d1));
666         assertFalse(view.verifyDrawable(d2));
667     }
668 
testGetDrawingRect()669     public void testGetDrawingRect() {
670         MockView view = new MockView(mActivity);
671         Rect outRect = new Rect();
672 
673         view.getDrawingRect(outRect);
674         assertEquals(0, outRect.left);
675         assertEquals(0, outRect.top);
676         assertEquals(0, outRect.right);
677         assertEquals(0, outRect.bottom);
678 
679         view.scrollTo(10, 100);
680         view.getDrawingRect(outRect);
681         assertEquals(10, outRect.left);
682         assertEquals(100, outRect.top);
683         assertEquals(10, outRect.right);
684         assertEquals(100, outRect.bottom);
685 
686         View mockView = mActivity.findViewById(R.id.mock_view);
687         mockView.getDrawingRect(outRect);
688         assertEquals(0, outRect.left);
689         assertEquals(0, outRect.top);
690         assertEquals(mockView.getWidth(), outRect.right);
691         assertEquals(mockView.getHeight(), outRect.bottom);
692     }
693 
testGetFocusedRect()694     public void testGetFocusedRect() {
695         MockView view = new MockView(mActivity);
696         Rect outRect = new Rect();
697 
698         view.getFocusedRect(outRect);
699         assertEquals(0, outRect.left);
700         assertEquals(0, outRect.top);
701         assertEquals(0, outRect.right);
702         assertEquals(0, outRect.bottom);
703 
704         view.scrollTo(10, 100);
705         view.getFocusedRect(outRect);
706         assertEquals(10, outRect.left);
707         assertEquals(100, outRect.top);
708         assertEquals(10, outRect.right);
709         assertEquals(100, outRect.bottom);
710     }
711 
testGetGlobalVisibleRectPoint()712     public void testGetGlobalVisibleRectPoint() throws Throwable {
713         final View view = mActivity.findViewById(R.id.mock_view);
714         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
715         Rect rect = new Rect();
716         Point point = new Point();
717 
718         assertTrue(view.getGlobalVisibleRect(rect, point));
719         Rect rcParent = new Rect();
720         Point ptParent = new Point();
721         viewGroup.getGlobalVisibleRect(rcParent, ptParent);
722         assertEquals(rcParent.left, rect.left);
723         assertEquals(rcParent.top, rect.top);
724         assertEquals(rect.left + view.getWidth(), rect.right);
725         assertEquals(rect.top + view.getHeight(), rect.bottom);
726         assertEquals(ptParent.x, point.x);
727         assertEquals(ptParent.y, point.y);
728 
729         // width is 0
730         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
731         runTestOnUiThread(new Runnable() {
732             @Override
733             public void run() {
734                 view.setLayoutParams(layoutParams1);
735             }
736         });
737         getInstrumentation().waitForIdleSync();
738         assertFalse(view.getGlobalVisibleRect(rect, point));
739 
740         // height is -10
741         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
742         runTestOnUiThread(new Runnable() {
743             @Override
744             public void run() {
745                 view.setLayoutParams(layoutParams2);
746             }
747         });
748         getInstrumentation().waitForIdleSync();
749         assertFalse(view.getGlobalVisibleRect(rect, point));
750 
751         Display display = getActivity().getWindowManager().getDefaultDisplay();
752         int halfWidth = display.getWidth() / 2;
753         int halfHeight = display.getHeight() /2;
754 
755         final LinearLayout.LayoutParams layoutParams3 =
756                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
757         runTestOnUiThread(new Runnable() {
758             @Override
759             public void run() {
760                 view.setLayoutParams(layoutParams3);
761             }
762         });
763         getInstrumentation().waitForIdleSync();
764         assertTrue(view.getGlobalVisibleRect(rect, point));
765         assertEquals(rcParent.left, rect.left);
766         assertEquals(rcParent.top, rect.top);
767         assertEquals(rect.left + halfWidth, rect.right);
768         assertEquals(rect.top + halfHeight, rect.bottom);
769         assertEquals(ptParent.x, point.x);
770         assertEquals(ptParent.y, point.y);
771     }
772 
testGetGlobalVisibleRect()773     public void testGetGlobalVisibleRect() throws Throwable {
774         final View view = mActivity.findViewById(R.id.mock_view);
775         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
776         Rect rect = new Rect();
777 
778         assertTrue(view.getGlobalVisibleRect(rect));
779         Rect rcParent = new Rect();
780         viewGroup.getGlobalVisibleRect(rcParent);
781         assertEquals(rcParent.left, rect.left);
782         assertEquals(rcParent.top, rect.top);
783         assertEquals(rect.left + view.getWidth(), rect.right);
784         assertEquals(rect.top + view.getHeight(), rect.bottom);
785 
786         // width is 0
787         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
788         runTestOnUiThread(new Runnable() {
789             @Override
790             public void run() {
791                 view.setLayoutParams(layoutParams1);
792             }
793         });
794         getInstrumentation().waitForIdleSync();
795         assertFalse(view.getGlobalVisibleRect(rect));
796 
797         // height is -10
798         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
799         runTestOnUiThread(new Runnable() {
800             @Override
801             public void run() {
802                 view.setLayoutParams(layoutParams2);
803             }
804         });
805         getInstrumentation().waitForIdleSync();
806         assertFalse(view.getGlobalVisibleRect(rect));
807 
808         Display display = getActivity().getWindowManager().getDefaultDisplay();
809         int halfWidth = display.getWidth() / 2;
810         int halfHeight = display.getHeight() /2;
811 
812         final LinearLayout.LayoutParams layoutParams3 =
813                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
814         runTestOnUiThread(new Runnable() {
815             @Override
816             public void run() {
817                 view.setLayoutParams(layoutParams3);
818             }
819         });
820         getInstrumentation().waitForIdleSync();
821         assertTrue(view.getGlobalVisibleRect(rect));
822         assertEquals(rcParent.left, rect.left);
823         assertEquals(rcParent.top, rect.top);
824         assertEquals(rect.left + halfWidth, rect.right);
825         assertEquals(rect.top + halfHeight, rect.bottom);
826     }
827 
testComputeHorizontalScroll()828     public void testComputeHorizontalScroll() throws Throwable {
829         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
830 
831         assertEquals(0, view.computeHorizontalScrollOffset());
832         assertEquals(view.getWidth(), view.computeHorizontalScrollRange());
833         assertEquals(view.getWidth(), view.computeHorizontalScrollExtent());
834 
835         runTestOnUiThread(new Runnable() {
836             @Override
837             public void run() {
838                 view.scrollTo(12, 0);
839             }
840         });
841         getInstrumentation().waitForIdleSync();
842         assertEquals(12, view.computeHorizontalScrollOffset());
843         assertEquals(view.getWidth(), view.computeHorizontalScrollRange());
844         assertEquals(view.getWidth(), view.computeHorizontalScrollExtent());
845 
846         runTestOnUiThread(new Runnable() {
847             @Override
848             public void run() {
849                 view.scrollBy(12, 0);
850             }
851         });
852         getInstrumentation().waitForIdleSync();
853         assertEquals(24, view.computeHorizontalScrollOffset());
854         assertEquals(view.getWidth(), view.computeHorizontalScrollRange());
855         assertEquals(view.getWidth(), view.computeHorizontalScrollExtent());
856 
857         int newWidth = 200;
858         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(newWidth, 100);
859         runTestOnUiThread(new Runnable() {
860             @Override
861             public void run() {
862                 view.setLayoutParams(layoutParams);
863             }
864         });
865         getInstrumentation().waitForIdleSync();
866         assertEquals(24, view.computeHorizontalScrollOffset());
867         assertEquals(newWidth, view.getWidth());
868         assertEquals(view.getWidth(), view.computeHorizontalScrollRange());
869         assertEquals(view.getWidth(), view.computeHorizontalScrollExtent());
870     }
871 
testComputeVerticalScroll()872     public void testComputeVerticalScroll() throws Throwable {
873         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
874 
875         assertEquals(0, view.computeVerticalScrollOffset());
876         assertEquals(view.getHeight(), view.computeVerticalScrollRange());
877         assertEquals(view.getHeight(), view.computeVerticalScrollExtent());
878 
879         final int scrollToY = 34;
880         runTestOnUiThread(new Runnable() {
881             @Override
882             public void run() {
883                 view.scrollTo(0, scrollToY);
884             }
885         });
886         getInstrumentation().waitForIdleSync();
887         assertEquals(scrollToY, view.computeVerticalScrollOffset());
888         assertEquals(view.getHeight(), view.computeVerticalScrollRange());
889         assertEquals(view.getHeight(), view.computeVerticalScrollExtent());
890 
891         final int scrollByY = 200;
892         runTestOnUiThread(new Runnable() {
893             @Override
894             public void run() {
895                 view.scrollBy(0, scrollByY);
896             }
897         });
898         getInstrumentation().waitForIdleSync();
899         assertEquals(scrollToY + scrollByY, view.computeVerticalScrollOffset());
900         assertEquals(view.getHeight(), view.computeVerticalScrollRange());
901         assertEquals(view.getHeight(), view.computeVerticalScrollExtent());
902 
903         int newHeight = 333;
904         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, newHeight);
905         runTestOnUiThread(new Runnable() {
906             @Override
907             public void run() {
908                 view.setLayoutParams(layoutParams);
909             }
910         });
911         getInstrumentation().waitForIdleSync();
912         assertEquals(scrollToY + scrollByY, view.computeVerticalScrollOffset());
913         assertEquals(newHeight, view.getHeight());
914         assertEquals(view.getHeight(), view.computeVerticalScrollRange());
915         assertEquals(view.getHeight(), view.computeVerticalScrollExtent());
916     }
917 
testGetFadingEdgeStrength()918     public void testGetFadingEdgeStrength() throws Throwable {
919         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
920 
921         assertEquals(0f, view.getLeftFadingEdgeStrength());
922         assertEquals(0f, view.getRightFadingEdgeStrength());
923         assertEquals(0f, view.getTopFadingEdgeStrength());
924         assertEquals(0f, view.getBottomFadingEdgeStrength());
925 
926         runTestOnUiThread(new Runnable() {
927             @Override
928             public void run() {
929                 view.scrollTo(10, 10);
930             }
931         });
932         getInstrumentation().waitForIdleSync();
933         assertEquals(1f, view.getLeftFadingEdgeStrength());
934         assertEquals(0f, view.getRightFadingEdgeStrength());
935         assertEquals(1f, view.getTopFadingEdgeStrength());
936         assertEquals(0f, view.getBottomFadingEdgeStrength());
937 
938         runTestOnUiThread(new Runnable() {
939             @Override
940             public void run() {
941                 view.scrollTo(-10, -10);
942             }
943         });
944         getInstrumentation().waitForIdleSync();
945         assertEquals(0f, view.getLeftFadingEdgeStrength());
946         assertEquals(1f, view.getRightFadingEdgeStrength());
947         assertEquals(0f, view.getTopFadingEdgeStrength());
948         assertEquals(1f, view.getBottomFadingEdgeStrength());
949     }
950 
testGetLeftFadingEdgeStrength()951     public void testGetLeftFadingEdgeStrength() {
952         MockView view = new MockView(mActivity);
953 
954         assertEquals(0.0f, view.getLeftFadingEdgeStrength());
955 
956         view.scrollTo(1, 0);
957         assertEquals(1.0f, view.getLeftFadingEdgeStrength());
958     }
959 
testGetRightFadingEdgeStrength()960     public void testGetRightFadingEdgeStrength() {
961         MockView view = new MockView(mActivity);
962 
963         assertEquals(0.0f, view.getRightFadingEdgeStrength());
964 
965         view.scrollTo(-1, 0);
966         assertEquals(1.0f, view.getRightFadingEdgeStrength());
967     }
968 
testGetBottomFadingEdgeStrength()969     public void testGetBottomFadingEdgeStrength() {
970         MockView view = new MockView(mActivity);
971 
972         assertEquals(0.0f, view.getBottomFadingEdgeStrength());
973 
974         view.scrollTo(0, -2);
975         assertEquals(1.0f, view.getBottomFadingEdgeStrength());
976     }
977 
testGetTopFadingEdgeStrength()978     public void testGetTopFadingEdgeStrength() {
979         MockView view = new MockView(mActivity);
980 
981         assertEquals(0.0f, view.getTopFadingEdgeStrength());
982 
983         view.scrollTo(0, 2);
984         assertEquals(1.0f, view.getTopFadingEdgeStrength());
985     }
986 
testResolveSize()987     public void testResolveSize() {
988         assertEquals(50, View.resolveSize(50, View.MeasureSpec.UNSPECIFIED));
989 
990         assertEquals(40, View.resolveSize(50, 40 | View.MeasureSpec.EXACTLY));
991 
992         assertEquals(30, View.resolveSize(50, 30 | View.MeasureSpec.AT_MOST));
993 
994         assertEquals(20, View.resolveSize(20, 30 | View.MeasureSpec.AT_MOST));
995     }
996 
testGetDefaultSize()997     public void testGetDefaultSize() {
998         assertEquals(50, View.getDefaultSize(50, View.MeasureSpec.UNSPECIFIED));
999 
1000         assertEquals(40, View.getDefaultSize(50, 40 | View.MeasureSpec.EXACTLY));
1001 
1002         assertEquals(30, View.getDefaultSize(50, 30 | View.MeasureSpec.AT_MOST));
1003 
1004         assertEquals(30, View.getDefaultSize(20, 30 | View.MeasureSpec.AT_MOST));
1005     }
1006 
testAccessId()1007     public void testAccessId() {
1008         View view = new View(mActivity);
1009 
1010         assertEquals(View.NO_ID, view.getId());
1011 
1012         view.setId(10);
1013         assertEquals(10, view.getId());
1014 
1015         view.setId(0xFFFFFFFF);
1016         assertEquals(0xFFFFFFFF, view.getId());
1017     }
1018 
testAccessLongClickable()1019     public void testAccessLongClickable() {
1020         View view = new View(mActivity);
1021 
1022         assertFalse(view.isLongClickable());
1023 
1024         view.setLongClickable(true);
1025         assertTrue(view.isLongClickable());
1026 
1027         view.setLongClickable(false);
1028         assertFalse(view.isLongClickable());
1029     }
1030 
testAccessClickable()1031     public void testAccessClickable() {
1032         View view = new View(mActivity);
1033 
1034         assertFalse(view.isClickable());
1035 
1036         view.setClickable(true);
1037         assertTrue(view.isClickable());
1038 
1039         view.setClickable(false);
1040         assertFalse(view.isClickable());
1041     }
1042 
testAccessContextClickable()1043     public void testAccessContextClickable() {
1044         View view = new View(mActivity);
1045 
1046         assertFalse(view.isContextClickable());
1047 
1048         view.setContextClickable(true);
1049         assertTrue(view.isContextClickable());
1050 
1051         view.setContextClickable(false);
1052         assertFalse(view.isContextClickable());
1053     }
1054 
testGetContextMenuInfo()1055     public void testGetContextMenuInfo() {
1056         MockView view = new MockView(mActivity);
1057 
1058         assertNull(view.getContextMenuInfo());
1059     }
1060 
testSetOnCreateContextMenuListener()1061     public void testSetOnCreateContextMenuListener() {
1062         View view = new View(mActivity);
1063         assertFalse(view.isLongClickable());
1064 
1065         view.setOnCreateContextMenuListener(null);
1066         assertTrue(view.isLongClickable());
1067 
1068         view.setOnCreateContextMenuListener(new OnCreateContextMenuListenerImpl());
1069         assertTrue(view.isLongClickable());
1070     }
1071 
testCreateContextMenu()1072     public void testCreateContextMenu() {
1073         OnCreateContextMenuListenerImpl listener = new OnCreateContextMenuListenerImpl();
1074         MockView view = new MockView(mActivity);
1075         ContextMenu contextMenu = new ContextMenuBuilder(mActivity);
1076         view.setParent(mMockParent);
1077         view.setOnCreateContextMenuListener(listener);
1078         assertFalse(view.hasCalledOnCreateContextMenu());
1079         assertFalse(mMockParent.hasCreateContextMenu());
1080         assertFalse(listener.hasOnCreateContextMenu());
1081 
1082         view.createContextMenu(contextMenu);
1083         assertTrue(view.hasCalledOnCreateContextMenu());
1084         assertTrue(mMockParent.hasCreateContextMenu());
1085         assertTrue(listener.hasOnCreateContextMenu());
1086 
1087         try {
1088             view.createContextMenu(null);
1089             fail("should throw NullPointerException");
1090         } catch (NullPointerException e) {
1091         }
1092     }
1093 
testAddFocusables()1094     public void testAddFocusables() {
1095         View view = new View(mActivity);
1096         ArrayList<View> viewList = new ArrayList<>();
1097 
1098         // view is not focusable
1099         assertFalse(view.isFocusable());
1100         assertEquals(0, viewList.size());
1101         view.addFocusables(viewList, 0);
1102         assertEquals(0, viewList.size());
1103 
1104         // view is focusable
1105         view.setFocusable(true);
1106         view.addFocusables(viewList, 0);
1107         assertEquals(1, viewList.size());
1108         assertEquals(view, viewList.get(0));
1109 
1110         // null array should be ignored
1111         view.addFocusables(null, 0);
1112     }
1113 
testGetFocusables()1114     public void testGetFocusables() {
1115         View view = new View(mActivity);
1116         ArrayList<View> viewList;
1117 
1118         // view is not focusable
1119         assertFalse(view.isFocusable());
1120         viewList = view.getFocusables(0);
1121         assertEquals(0, viewList.size());
1122 
1123         // view is focusable
1124         view.setFocusable(true);
1125         viewList = view.getFocusables(0);
1126         assertEquals(1, viewList.size());
1127         assertEquals(view, viewList.get(0));
1128 
1129         viewList = view.getFocusables(-1);
1130         assertEquals(1, viewList.size());
1131         assertEquals(view, viewList.get(0));
1132     }
1133 
testAddFocusablesWithoutTouchMode()1134     public void testAddFocusablesWithoutTouchMode() {
1135         View view = new View(mActivity);
1136         assertFalse("test sanity", view.isInTouchMode());
1137         focusableInTouchModeTest(view, false);
1138     }
1139 
testAddFocusablesInTouchMode()1140     public void testAddFocusablesInTouchMode() {
1141         View view = spy(new View(mActivity));
1142         when(view.isInTouchMode()).thenReturn(true);
1143         focusableInTouchModeTest(view, true);
1144     }
1145 
focusableInTouchModeTest(View view, boolean inTouchMode)1146     private void focusableInTouchModeTest(View view, boolean inTouchMode) {
1147         ArrayList<View> views = new ArrayList<View>();
1148 
1149         view.setFocusableInTouchMode(false);
1150         view.setFocusable(true);
1151 
1152         view.addFocusables(views, View.FOCUS_FORWARD);
1153         if (inTouchMode) {
1154             assertEquals(Collections.emptyList(), views);
1155         } else {
1156             assertEquals(Collections.singletonList(view), views);
1157         }
1158 
1159 
1160         views.clear();
1161         view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_ALL);
1162         assertEquals(Collections.singletonList(view), views);
1163 
1164         views.clear();
1165         view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_TOUCH_MODE);
1166         assertEquals(Collections.emptyList(), views);
1167 
1168         view.setFocusableInTouchMode(true);
1169 
1170         views.clear();
1171         view.addFocusables(views, View.FOCUS_FORWARD);
1172         assertEquals(Collections.singletonList(view), views);
1173 
1174         views.clear();
1175         view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_ALL);
1176         assertEquals(Collections.singletonList(view), views);
1177 
1178         views.clear();
1179         view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_TOUCH_MODE);
1180         assertEquals(Collections.singletonList(view), views);
1181 
1182         view.setFocusable(false);
1183 
1184         views.clear();
1185         view.addFocusables(views, View.FOCUS_FORWARD);
1186         assertEquals(Collections.emptyList(), views);
1187 
1188         views.clear();
1189         view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_ALL);
1190         assertEquals(Collections.emptyList(), views);
1191 
1192         views.clear();
1193         view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_TOUCH_MODE);
1194         assertEquals(Collections.emptyList(), views);
1195     }
1196 
testGetRootView()1197     public void testGetRootView() {
1198         MockView view = new MockView(mActivity);
1199 
1200         assertNull(view.getParent());
1201         assertEquals(view, view.getRootView());
1202 
1203         view.setParent(mMockParent);
1204         assertEquals(mMockParent, view.getRootView());
1205     }
1206 
testGetSolidColor()1207     public void testGetSolidColor() {
1208         View view = new View(mActivity);
1209 
1210         assertEquals(0, view.getSolidColor());
1211     }
1212 
testSetMinimumWidth()1213     public void testSetMinimumWidth() {
1214         MockView view = new MockView(mActivity);
1215         assertEquals(0, view.getSuggestedMinimumWidth());
1216 
1217         view.setMinimumWidth(100);
1218         assertEquals(100, view.getSuggestedMinimumWidth());
1219 
1220         view.setMinimumWidth(-100);
1221         assertEquals(-100, view.getSuggestedMinimumWidth());
1222     }
1223 
testGetSuggestedMinimumWidth()1224     public void testGetSuggestedMinimumWidth() {
1225         MockView view = new MockView(mActivity);
1226         Drawable d = mResources.getDrawable(R.drawable.scenery);
1227         int drawableMinimumWidth = d.getMinimumWidth();
1228 
1229         // drawable is null
1230         view.setMinimumWidth(100);
1231         assertNull(view.getBackground());
1232         assertEquals(100, view.getSuggestedMinimumWidth());
1233 
1234         // drawable minimum width is larger than mMinWidth
1235         view.setBackgroundDrawable(d);
1236         view.setMinimumWidth(drawableMinimumWidth - 10);
1237         assertEquals(drawableMinimumWidth, view.getSuggestedMinimumWidth());
1238 
1239         // drawable minimum width is smaller than mMinWidth
1240         view.setMinimumWidth(drawableMinimumWidth + 10);
1241         assertEquals(drawableMinimumWidth + 10, view.getSuggestedMinimumWidth());
1242     }
1243 
testSetMinimumHeight()1244     public void testSetMinimumHeight() {
1245         MockView view = new MockView(mActivity);
1246         assertEquals(0, view.getSuggestedMinimumHeight());
1247 
1248         view.setMinimumHeight(100);
1249         assertEquals(100, view.getSuggestedMinimumHeight());
1250 
1251         view.setMinimumHeight(-100);
1252         assertEquals(-100, view.getSuggestedMinimumHeight());
1253     }
1254 
testGetSuggestedMinimumHeight()1255     public void testGetSuggestedMinimumHeight() {
1256         MockView view = new MockView(mActivity);
1257         Drawable d = mResources.getDrawable(R.drawable.scenery);
1258         int drawableMinimumHeight = d.getMinimumHeight();
1259 
1260         // drawable is null
1261         view.setMinimumHeight(100);
1262         assertNull(view.getBackground());
1263         assertEquals(100, view.getSuggestedMinimumHeight());
1264 
1265         // drawable minimum height is larger than mMinHeight
1266         view.setBackgroundDrawable(d);
1267         view.setMinimumHeight(drawableMinimumHeight - 10);
1268         assertEquals(drawableMinimumHeight, view.getSuggestedMinimumHeight());
1269 
1270         // drawable minimum height is smaller than mMinHeight
1271         view.setMinimumHeight(drawableMinimumHeight + 10);
1272         assertEquals(drawableMinimumHeight + 10, view.getSuggestedMinimumHeight());
1273     }
1274 
testAccessWillNotCacheDrawing()1275     public void testAccessWillNotCacheDrawing() {
1276         View view = new View(mActivity);
1277 
1278         assertFalse(view.willNotCacheDrawing());
1279 
1280         view.setWillNotCacheDrawing(true);
1281         assertTrue(view.willNotCacheDrawing());
1282     }
1283 
testAccessDrawingCacheEnabled()1284     public void testAccessDrawingCacheEnabled() {
1285         View view = new View(mActivity);
1286 
1287         assertFalse(view.isDrawingCacheEnabled());
1288 
1289         view.setDrawingCacheEnabled(true);
1290         assertTrue(view.isDrawingCacheEnabled());
1291     }
1292 
testGetDrawingCache()1293     public void testGetDrawingCache() {
1294         MockView view = new MockView(mActivity);
1295 
1296         // should not call buildDrawingCache when getDrawingCache
1297         assertNull(view.getDrawingCache());
1298 
1299         // should call buildDrawingCache when getDrawingCache
1300         view = (MockView) mActivity.findViewById(R.id.mock_view);
1301         view.setDrawingCacheEnabled(true);
1302         Bitmap bitmap1 = view.getDrawingCache();
1303         assertNotNull(bitmap1);
1304         assertEquals(view.getWidth(), bitmap1.getWidth());
1305         assertEquals(view.getHeight(), bitmap1.getHeight());
1306 
1307         view.setWillNotCacheDrawing(true);
1308         assertNull(view.getDrawingCache());
1309 
1310         view.setWillNotCacheDrawing(false);
1311         // build a new drawingcache
1312         Bitmap bitmap2 = view.getDrawingCache();
1313         assertNotSame(bitmap1, bitmap2);
1314     }
1315 
testBuildAndDestroyDrawingCache()1316     public void testBuildAndDestroyDrawingCache() {
1317         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
1318 
1319         assertNull(view.getDrawingCache());
1320 
1321         view.buildDrawingCache();
1322         Bitmap bitmap = view.getDrawingCache();
1323         assertNotNull(bitmap);
1324         assertEquals(view.getWidth(), bitmap.getWidth());
1325         assertEquals(view.getHeight(), bitmap.getHeight());
1326 
1327         view.destroyDrawingCache();
1328         assertNull(view.getDrawingCache());
1329     }
1330 
testAccessWillNotDraw()1331     public void testAccessWillNotDraw() {
1332         View view = new View(mActivity);
1333 
1334         assertFalse(view.willNotDraw());
1335 
1336         view.setWillNotDraw(true);
1337         assertTrue(view.willNotDraw());
1338     }
1339 
testAccessDrawingCacheQuality()1340     public void testAccessDrawingCacheQuality() {
1341         View view = new View(mActivity);
1342 
1343         assertEquals(0, view.getDrawingCacheQuality());
1344 
1345         view.setDrawingCacheQuality(1);
1346         assertEquals(0, view.getDrawingCacheQuality());
1347 
1348         view.setDrawingCacheQuality(0x00100000);
1349         assertEquals(0x00100000, view.getDrawingCacheQuality());
1350 
1351         view.setDrawingCacheQuality(0x00080000);
1352         assertEquals(0x00080000, view.getDrawingCacheQuality());
1353 
1354         view.setDrawingCacheQuality(0xffffffff);
1355         // 0x00180000 is View.DRAWING_CACHE_QUALITY_MASK
1356         assertEquals(0x00180000, view.getDrawingCacheQuality());
1357     }
1358 
testDispatchSetSelected()1359     public void testDispatchSetSelected() {
1360         MockView mockView1 = new MockView(mActivity);
1361         MockView mockView2 = new MockView(mActivity);
1362         mockView1.setParent(mMockParent);
1363         mockView2.setParent(mMockParent);
1364 
1365         mMockParent.dispatchSetSelected(true);
1366         assertTrue(mockView1.isSelected());
1367         assertTrue(mockView2.isSelected());
1368 
1369         mMockParent.dispatchSetSelected(false);
1370         assertFalse(mockView1.isSelected());
1371         assertFalse(mockView2.isSelected());
1372     }
1373 
testAccessSelected()1374     public void testAccessSelected() {
1375         View view = new View(mActivity);
1376 
1377         assertFalse(view.isSelected());
1378 
1379         view.setSelected(true);
1380         assertTrue(view.isSelected());
1381     }
1382 
testDispatchSetPressed()1383     public void testDispatchSetPressed() {
1384         MockView mockView1 = new MockView(mActivity);
1385         MockView mockView2 = new MockView(mActivity);
1386         mockView1.setParent(mMockParent);
1387         mockView2.setParent(mMockParent);
1388 
1389         mMockParent.dispatchSetPressed(true);
1390         assertTrue(mockView1.isPressed());
1391         assertTrue(mockView2.isPressed());
1392 
1393         mMockParent.dispatchSetPressed(false);
1394         assertFalse(mockView1.isPressed());
1395         assertFalse(mockView2.isPressed());
1396     }
1397 
testAccessPressed()1398     public void testAccessPressed() {
1399         View view = new View(mActivity);
1400 
1401         assertFalse(view.isPressed());
1402 
1403         view.setPressed(true);
1404         assertTrue(view.isPressed());
1405     }
1406 
testAccessSoundEffectsEnabled()1407     public void testAccessSoundEffectsEnabled() {
1408         View view = new View(mActivity);
1409 
1410         assertTrue(view.isSoundEffectsEnabled());
1411 
1412         view.setSoundEffectsEnabled(false);
1413         assertFalse(view.isSoundEffectsEnabled());
1414     }
1415 
testAccessKeepScreenOn()1416     public void testAccessKeepScreenOn() {
1417         View view = new View(mActivity);
1418 
1419         assertFalse(view.getKeepScreenOn());
1420 
1421         view.setKeepScreenOn(true);
1422         assertTrue(view.getKeepScreenOn());
1423     }
1424 
testAccessDuplicateParentStateEnabled()1425     public void testAccessDuplicateParentStateEnabled() {
1426         View view = new View(mActivity);
1427 
1428         assertFalse(view.isDuplicateParentStateEnabled());
1429 
1430         view.setDuplicateParentStateEnabled(true);
1431         assertTrue(view.isDuplicateParentStateEnabled());
1432     }
1433 
testAccessEnabled()1434     public void testAccessEnabled() {
1435         View view = new View(mActivity);
1436 
1437         assertTrue(view.isEnabled());
1438 
1439         view.setEnabled(false);
1440         assertFalse(view.isEnabled());
1441     }
1442 
testAccessSaveEnabled()1443     public void testAccessSaveEnabled() {
1444         View view = new View(mActivity);
1445 
1446         assertTrue(view.isSaveEnabled());
1447 
1448         view.setSaveEnabled(false);
1449         assertFalse(view.isSaveEnabled());
1450     }
1451 
testShowContextMenu()1452     public void testShowContextMenu() {
1453         MockView view = new MockView(mActivity);
1454 
1455         assertNull(view.getParent());
1456         try {
1457             view.showContextMenu();
1458             fail("should throw NullPointerException");
1459         } catch (NullPointerException e) {
1460         }
1461 
1462         view.setParent(mMockParent);
1463         assertFalse(mMockParent.hasShowContextMenuForChild());
1464 
1465         assertFalse(view.showContextMenu());
1466         assertTrue(mMockParent.hasShowContextMenuForChild());
1467     }
1468 
testShowContextMenuXY()1469     public void testShowContextMenuXY() {
1470         MockViewParent parent = new MockViewParent(mActivity);
1471         MockView view = new MockView(mActivity);
1472 
1473         assertNull(view.getParent());
1474         try {
1475             view.showContextMenu(0, 0);
1476             fail("should throw NullPointerException");
1477         } catch (NullPointerException e) {
1478         }
1479 
1480         view.setParent(parent);
1481         assertFalse(parent.hasShowContextMenuForChildXY());
1482 
1483         assertFalse(view.showContextMenu(0, 0));
1484         assertTrue(parent.hasShowContextMenuForChildXY());
1485     }
1486 
testFitSystemWindows()1487     public void testFitSystemWindows() {
1488         final XmlResourceParser parser = mResources.getLayout(R.layout.view_layout);
1489         final AttributeSet attrs = Xml.asAttributeSet(parser);
1490         Rect insets = new Rect(10, 20, 30, 50);
1491 
1492         MockView view = new MockView(mActivity);
1493         assertFalse(view.fitSystemWindows(insets));
1494         assertFalse(view.fitSystemWindows(null));
1495 
1496         view = new MockView(mActivity, attrs, android.R.attr.fitsSystemWindows);
1497         assertFalse(view.fitSystemWindows(insets));
1498         assertFalse(view.fitSystemWindows(null));
1499     }
1500 
testPerformClick()1501     public void testPerformClick() {
1502         View view = new View(mActivity);
1503         OnClickListenerImpl listener = new OnClickListenerImpl();
1504 
1505         assertFalse(view.performClick());
1506 
1507         assertFalse(listener.hasOnClick());
1508         view.setOnClickListener(listener);
1509 
1510         assertTrue(view.performClick());
1511         assertTrue(listener.hasOnClick());
1512 
1513         view.setOnClickListener(null);
1514         assertFalse(view.performClick());
1515     }
1516 
testSetOnClickListener()1517     public void testSetOnClickListener() {
1518         View view = new View(mActivity);
1519         assertFalse(view.performClick());
1520         assertFalse(view.isClickable());
1521 
1522         view.setOnClickListener(null);
1523         assertFalse(view.performClick());
1524         assertTrue(view.isClickable());
1525 
1526         view.setOnClickListener(new OnClickListenerImpl());
1527         assertTrue(view.performClick());
1528         assertTrue(view.isClickable());
1529     }
1530 
testPerformLongClick()1531     public void testPerformLongClick() {
1532         MockView view = new MockView(mActivity);
1533         OnLongClickListenerImpl listener = new OnLongClickListenerImpl();
1534 
1535         try {
1536             view.performLongClick();
1537             fail("should throw NullPointerException");
1538         } catch (NullPointerException e) {
1539         }
1540 
1541         view.setParent(mMockParent);
1542         assertFalse(mMockParent.hasShowContextMenuForChild());
1543         assertFalse(view.performLongClick());
1544         assertTrue(mMockParent.hasShowContextMenuForChild());
1545 
1546         view.setOnLongClickListener(listener);
1547         mMockParent.reset();
1548         assertFalse(mMockParent.hasShowContextMenuForChild());
1549         assertFalse(listener.hasOnLongClick());
1550         assertTrue(view.performLongClick());
1551         assertFalse(mMockParent.hasShowContextMenuForChild());
1552         assertTrue(listener.hasOnLongClick());
1553     }
1554 
testPerformLongClickXY()1555     public void testPerformLongClickXY() {
1556         MockViewParent parent = new MockViewParent(mActivity);
1557         MockView view = new MockView(mActivity);
1558 
1559         try {
1560             view.performLongClick(0, 0);
1561             fail("should throw NullPointerException");
1562         } catch (NullPointerException e) {
1563         }
1564 
1565         parent.addView(view);
1566         assertFalse(parent.hasShowContextMenuForChildXY());
1567 
1568         // Verify default context menu behavior.
1569         assertFalse(view.performLongClick(0, 0));
1570         assertTrue(parent.hasShowContextMenuForChildXY());
1571     }
1572 
testPerformLongClickXY_WithListener()1573     public void testPerformLongClickXY_WithListener() {
1574         OnLongClickListener listener = mock(OnLongClickListener.class);
1575         when(listener.onLongClick(any(View.class))).thenReturn(true);
1576 
1577         MockViewParent parent = new MockViewParent(mActivity);
1578         MockView view = new MockView(mActivity);
1579 
1580         view.setOnLongClickListener(listener);
1581         verify(listener, never()).onLongClick(any(View.class));
1582 
1583         parent.addView(view);
1584         assertFalse(parent.hasShowContextMenuForChildXY());
1585 
1586         // Verify listener is preferred over default context menu.
1587         assertTrue(view.performLongClick(0, 0));
1588         assertFalse(parent.hasShowContextMenuForChildXY());
1589         verify(listener).onLongClick(view);
1590     }
1591 
testSetOnLongClickListener()1592     public void testSetOnLongClickListener() {
1593         MockView view = new MockView(mActivity);
1594         view.setParent(mMockParent);
1595         assertFalse(view.performLongClick());
1596         assertFalse(view.isLongClickable());
1597 
1598         view.setOnLongClickListener(null);
1599         assertFalse(view.performLongClick());
1600         assertTrue(view.isLongClickable());
1601 
1602         view.setOnLongClickListener(new OnLongClickListenerImpl());
1603         assertTrue(view.performLongClick());
1604         assertTrue(view.isLongClickable());
1605     }
1606 
testPerformContextClick()1607     public void testPerformContextClick() {
1608         MockView view = new MockView(mActivity);
1609         view.setParent(mMockParent);
1610         OnContextClickListenerImpl listener = new OnContextClickListenerImpl();
1611 
1612         view.setOnContextClickListener(listener);
1613         assertFalse(listener.hasOnContextClick());
1614 
1615         assertTrue(view.performContextClick());
1616         assertTrue(listener.hasOnContextClick());
1617         assertSame(view, listener.getLastViewContextClicked());
1618     }
1619 
testSetOnContextClickListener()1620     public void testSetOnContextClickListener() {
1621         MockView view = new MockView(mActivity);
1622         view.setParent(mMockParent);
1623 
1624         assertFalse(view.performContextClick());
1625         assertFalse(view.isContextClickable());
1626 
1627         view.setOnContextClickListener(new OnContextClickListenerImpl());
1628         assertTrue(view.performContextClick());
1629         assertTrue(view.isContextClickable());
1630     }
1631 
testAccessOnFocusChangeListener()1632     public void testAccessOnFocusChangeListener() {
1633         View view = new View(mActivity);
1634         OnFocusChangeListener listener = new OnFocusChangeListenerImpl();
1635 
1636         assertNull(view.getOnFocusChangeListener());
1637 
1638         view.setOnFocusChangeListener(listener);
1639         assertSame(listener, view.getOnFocusChangeListener());
1640     }
1641 
testAccessNextFocusUpId()1642     public void testAccessNextFocusUpId() {
1643         View view = new View(mActivity);
1644 
1645         assertEquals(View.NO_ID, view.getNextFocusUpId());
1646 
1647         view.setNextFocusUpId(1);
1648         assertEquals(1, view.getNextFocusUpId());
1649 
1650         view.setNextFocusUpId(Integer.MAX_VALUE);
1651         assertEquals(Integer.MAX_VALUE, view.getNextFocusUpId());
1652 
1653         view.setNextFocusUpId(Integer.MIN_VALUE);
1654         assertEquals(Integer.MIN_VALUE, view.getNextFocusUpId());
1655     }
1656 
testAccessNextFocusDownId()1657     public void testAccessNextFocusDownId() {
1658         View view = new View(mActivity);
1659 
1660         assertEquals(View.NO_ID, view.getNextFocusDownId());
1661 
1662         view.setNextFocusDownId(1);
1663         assertEquals(1, view.getNextFocusDownId());
1664 
1665         view.setNextFocusDownId(Integer.MAX_VALUE);
1666         assertEquals(Integer.MAX_VALUE, view.getNextFocusDownId());
1667 
1668         view.setNextFocusDownId(Integer.MIN_VALUE);
1669         assertEquals(Integer.MIN_VALUE, view.getNextFocusDownId());
1670     }
1671 
testAccessNextFocusLeftId()1672     public void testAccessNextFocusLeftId() {
1673         View view = new View(mActivity);
1674 
1675         assertEquals(View.NO_ID, view.getNextFocusLeftId());
1676 
1677         view.setNextFocusLeftId(1);
1678         assertEquals(1, view.getNextFocusLeftId());
1679 
1680         view.setNextFocusLeftId(Integer.MAX_VALUE);
1681         assertEquals(Integer.MAX_VALUE, view.getNextFocusLeftId());
1682 
1683         view.setNextFocusLeftId(Integer.MIN_VALUE);
1684         assertEquals(Integer.MIN_VALUE, view.getNextFocusLeftId());
1685     }
1686 
testAccessNextFocusRightId()1687     public void testAccessNextFocusRightId() {
1688         View view = new View(mActivity);
1689 
1690         assertEquals(View.NO_ID, view.getNextFocusRightId());
1691 
1692         view.setNextFocusRightId(1);
1693         assertEquals(1, view.getNextFocusRightId());
1694 
1695         view.setNextFocusRightId(Integer.MAX_VALUE);
1696         assertEquals(Integer.MAX_VALUE, view.getNextFocusRightId());
1697 
1698         view.setNextFocusRightId(Integer.MIN_VALUE);
1699         assertEquals(Integer.MIN_VALUE, view.getNextFocusRightId());
1700     }
1701 
testAccessMeasuredDimension()1702     public void testAccessMeasuredDimension() {
1703         MockView view = new MockView(mActivity);
1704         assertEquals(0, view.getMeasuredWidth());
1705         assertEquals(0, view.getMeasuredHeight());
1706 
1707         view.setMeasuredDimensionWrapper(20, 30);
1708         assertEquals(20, view.getMeasuredWidth());
1709         assertEquals(30, view.getMeasuredHeight());
1710     }
1711 
testMeasure()1712     public void testMeasure() throws Throwable {
1713         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
1714         assertTrue(view.hasCalledOnMeasure());
1715         assertEquals(100, view.getMeasuredWidth());
1716         assertEquals(200, view.getMeasuredHeight());
1717 
1718         view.reset();
1719         runTestOnUiThread(new Runnable() {
1720             @Override
1721             public void run() {
1722                 view.requestLayout();
1723             }
1724         });
1725         getInstrumentation().waitForIdleSync();
1726         assertTrue(view.hasCalledOnMeasure());
1727         assertEquals(100, view.getMeasuredWidth());
1728         assertEquals(200, view.getMeasuredHeight());
1729 
1730         view.reset();
1731         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, 100);
1732         runTestOnUiThread(new Runnable() {
1733             @Override
1734             public void run() {
1735                 view.setLayoutParams(layoutParams);
1736             }
1737         });
1738         getInstrumentation().waitForIdleSync();
1739         assertTrue(view.hasCalledOnMeasure());
1740         assertEquals(200, view.getMeasuredWidth());
1741         assertEquals(100, view.getMeasuredHeight());
1742     }
1743 
testAccessLayoutParams()1744     public void testAccessLayoutParams() {
1745         View view = new View(mActivity);
1746         ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(10, 20);
1747 
1748         assertNull(view.getLayoutParams());
1749 
1750         try {
1751             view.setLayoutParams(null);
1752             fail("should throw NullPointerException");
1753         } catch (NullPointerException e) {
1754         }
1755 
1756         assertFalse(view.isLayoutRequested());
1757         view.setLayoutParams(params);
1758         assertSame(params, view.getLayoutParams());
1759         assertTrue(view.isLayoutRequested());
1760     }
1761 
testIsShown()1762     public void testIsShown() {
1763         MockView view = new MockView(mActivity);
1764 
1765         view.setVisibility(View.INVISIBLE);
1766         assertFalse(view.isShown());
1767 
1768         view.setVisibility(View.VISIBLE);
1769         assertNull(view.getParent());
1770         assertFalse(view.isShown());
1771 
1772         view.setParent(mMockParent);
1773         // mMockParent is not a instance of ViewRoot
1774         assertFalse(view.isShown());
1775     }
1776 
testGetDrawingTime()1777     public void testGetDrawingTime() {
1778         View view = new View(mActivity);
1779         // mAttachInfo is null
1780         assertEquals(0, view.getDrawingTime());
1781 
1782         // mAttachInfo is not null
1783         view = mActivity.findViewById(R.id.fit_windows);
1784         assertEquals(SystemClock.uptimeMillis(), view.getDrawingTime(), 1000);
1785     }
1786 
testScheduleDrawable()1787     public void testScheduleDrawable() {
1788         View view = new View(mActivity);
1789         Drawable drawable = new StateListDrawable();
1790         Runnable what = new Runnable() {
1791             @Override
1792             public void run() {
1793                 // do nothing
1794             }
1795         };
1796 
1797         // mAttachInfo is null
1798         view.scheduleDrawable(drawable, what, 1000);
1799 
1800         view.setBackgroundDrawable(drawable);
1801         view.scheduleDrawable(drawable, what, 1000);
1802 
1803         view.scheduleDrawable(null, null, -1000);
1804 
1805         // mAttachInfo is not null
1806         view = mActivity.findViewById(R.id.fit_windows);
1807         view.scheduleDrawable(drawable, what, 1000);
1808 
1809         view.scheduleDrawable(view.getBackground(), what, 1000);
1810         view.unscheduleDrawable(view.getBackground(), what);
1811 
1812         view.scheduleDrawable(null, null, -1000);
1813     }
1814 
testUnscheduleDrawable()1815     public void testUnscheduleDrawable() {
1816         View view = new View(mActivity);
1817         Drawable drawable = new StateListDrawable();
1818         Runnable what = new Runnable() {
1819             @Override
1820             public void run() {
1821                 // do nothing
1822             }
1823         };
1824 
1825         // mAttachInfo is null
1826         view.unscheduleDrawable(drawable, what);
1827 
1828         view.setBackgroundDrawable(drawable);
1829         view.unscheduleDrawable(drawable);
1830 
1831         view.unscheduleDrawable(null, null);
1832         view.unscheduleDrawable(null);
1833 
1834         // mAttachInfo is not null
1835         view = mActivity.findViewById(R.id.fit_windows);
1836         view.unscheduleDrawable(drawable);
1837 
1838         view.scheduleDrawable(view.getBackground(), what, 1000);
1839         view.unscheduleDrawable(view.getBackground(), what);
1840 
1841         view.unscheduleDrawable(null);
1842         view.unscheduleDrawable(null, null);
1843     }
1844 
testGetWindowVisibility()1845     public void testGetWindowVisibility() {
1846         View view = new View(mActivity);
1847         // mAttachInfo is null
1848         assertEquals(View.GONE, view.getWindowVisibility());
1849 
1850         // mAttachInfo is not null
1851         view = mActivity.findViewById(R.id.fit_windows);
1852         assertEquals(View.VISIBLE, view.getWindowVisibility());
1853     }
1854 
testGetWindowToken()1855     public void testGetWindowToken() {
1856         View view = new View(mActivity);
1857         // mAttachInfo is null
1858         assertNull(view.getWindowToken());
1859 
1860         // mAttachInfo is not null
1861         view = mActivity.findViewById(R.id.fit_windows);
1862         assertNotNull(view.getWindowToken());
1863     }
1864 
testHasWindowFocus()1865     public void testHasWindowFocus() {
1866         View view = new View(mActivity);
1867         // mAttachInfo is null
1868         assertFalse(view.hasWindowFocus());
1869 
1870         // mAttachInfo is not null
1871         final View view2 = mActivity.findViewById(R.id.fit_windows);
1872         // Wait until the window has been focused.
1873         new PollingCheck(TIMEOUT_DELTA) {
1874             @Override
1875             protected boolean check() {
1876                 return view2.hasWindowFocus();
1877             }
1878         }.run();
1879     }
1880 
testGetHandler()1881     public void testGetHandler() {
1882         MockView view = new MockView(mActivity);
1883         // mAttachInfo is null
1884         assertNull(view.getHandler());
1885     }
1886 
testRemoveCallbacks()1887     public void testRemoveCallbacks() throws InterruptedException {
1888         final long delay = 500L;
1889         View view = mActivity.findViewById(R.id.mock_view);
1890         MockRunnable runner = new MockRunnable();
1891         assertTrue(view.postDelayed(runner, delay));
1892         assertTrue(view.removeCallbacks(runner));
1893         assertTrue(view.removeCallbacks(null));
1894         assertTrue(view.removeCallbacks(new MockRunnable()));
1895         Thread.sleep(delay * 2);
1896         assertFalse(runner.hasRun);
1897         // check that the runner actually works
1898         runner = new MockRunnable();
1899         assertTrue(view.postDelayed(runner, delay));
1900         Thread.sleep(delay * 2);
1901         assertTrue(runner.hasRun);
1902     }
1903 
testCancelLongPress()1904     public void testCancelLongPress() {
1905         View view = new View(mActivity);
1906         // mAttachInfo is null
1907         view.cancelLongPress();
1908 
1909         // mAttachInfo is not null
1910         view = mActivity.findViewById(R.id.fit_windows);
1911         view.cancelLongPress();
1912     }
1913 
testGetViewTreeObserver()1914     public void testGetViewTreeObserver() {
1915         View view = new View(mActivity);
1916         // mAttachInfo is null
1917         assertNotNull(view.getViewTreeObserver());
1918 
1919         // mAttachInfo is not null
1920         view = mActivity.findViewById(R.id.fit_windows);
1921         assertNotNull(view.getViewTreeObserver());
1922     }
1923 
testGetWindowAttachCount()1924     public void testGetWindowAttachCount() {
1925         MockView view = new MockView(mActivity);
1926         // mAttachInfo is null
1927         assertEquals(0, view.getWindowAttachCount());
1928     }
1929 
1930     @UiThreadTest
testOnAttachedToAndDetachedFromWindow()1931     public void testOnAttachedToAndDetachedFromWindow() {
1932         MockView mockView = new MockView(mActivity);
1933         ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
1934 
1935         viewGroup.addView(mockView);
1936         assertTrue(mockView.hasCalledOnAttachedToWindow());
1937 
1938         viewGroup.removeView(mockView);
1939         assertTrue(mockView.hasCalledOnDetachedFromWindow());
1940 
1941         mockView.reset();
1942         mActivity.setContentView(mockView);
1943         assertTrue(mockView.hasCalledOnAttachedToWindow());
1944 
1945         mActivity.setContentView(R.layout.view_layout);
1946         assertTrue(mockView.hasCalledOnDetachedFromWindow());
1947     }
1948 
testGetLocationInWindow()1949     public void testGetLocationInWindow() {
1950         int[] location = new int[] { -1, -1 };
1951 
1952         View layout = mActivity.findViewById(R.id.viewlayout_root);
1953         int[] layoutLocation = new int[] { -1, -1 };
1954         layout.getLocationInWindow(layoutLocation);
1955 
1956         final View mockView = mActivity.findViewById(R.id.mock_view);
1957         mockView.getLocationInWindow(location);
1958         assertEquals(layoutLocation[0], location[0]);
1959         assertEquals(layoutLocation[1], location[1]);
1960 
1961         View scrollView = mActivity.findViewById(R.id.scroll_view);
1962         scrollView.getLocationInWindow(location);
1963         assertEquals(layoutLocation[0], location[0]);
1964         assertEquals(layoutLocation[1] + mockView.getHeight(), location[1]);
1965 
1966         try {
1967             mockView.getLocationInWindow(null);
1968             fail("should throw IllegalArgumentException");
1969         } catch (IllegalArgumentException e) {
1970         }
1971 
1972         try {
1973             mockView.getLocationInWindow(new int[] { 0 });
1974             fail("should throw IllegalArgumentException");
1975         } catch (IllegalArgumentException e) {
1976         }
1977     }
1978 
testGetLocationOnScreen()1979     public void testGetLocationOnScreen() {
1980         int[] location = new int[] { -1, -1 };
1981 
1982         // mAttachInfo is not null
1983         View layout = mActivity.findViewById(R.id.viewlayout_root);
1984         int[] layoutLocation = new int[] { -1, -1 };
1985         layout.getLocationOnScreen(layoutLocation);
1986 
1987         View mockView = mActivity.findViewById(R.id.mock_view);
1988         mockView.getLocationOnScreen(location);
1989         assertEquals(layoutLocation[0], location[0]);
1990         assertEquals(layoutLocation[1], location[1]);
1991 
1992         View scrollView = mActivity.findViewById(R.id.scroll_view);
1993         scrollView.getLocationOnScreen(location);
1994         assertEquals(layoutLocation[0], location[0]);
1995         assertEquals(layoutLocation[1] + mockView.getHeight(), location[1]);
1996 
1997         try {
1998             scrollView.getLocationOnScreen(null);
1999             fail("should throw IllegalArgumentException");
2000         } catch (IllegalArgumentException e) {
2001         }
2002 
2003         try {
2004             scrollView.getLocationOnScreen(new int[] { 0 });
2005             fail("should throw IllegalArgumentException");
2006         } catch (IllegalArgumentException e) {
2007         }
2008     }
2009 
testAddTouchables()2010     public void testAddTouchables() {
2011         View view = new View(mActivity);
2012         ArrayList<View> result = new ArrayList<>();
2013         assertEquals(0, result.size());
2014 
2015         view.addTouchables(result);
2016         assertEquals(0, result.size());
2017 
2018         view.setClickable(true);
2019         view.addTouchables(result);
2020         assertEquals(1, result.size());
2021         assertSame(view, result.get(0));
2022 
2023         try {
2024             view.addTouchables(null);
2025             fail("should throw NullPointerException");
2026         } catch (NullPointerException e) {
2027         }
2028 
2029         result.clear();
2030         view.setEnabled(false);
2031         assertTrue(view.isClickable());
2032         view.addTouchables(result);
2033         assertEquals(0, result.size());
2034     }
2035 
testGetTouchables()2036     public void testGetTouchables() {
2037         View view = new View(mActivity);
2038         ArrayList<View> result;
2039 
2040         result = view.getTouchables();
2041         assertEquals(0, result.size());
2042 
2043         view.setClickable(true);
2044         result = view.getTouchables();
2045         assertEquals(1, result.size());
2046         assertSame(view, result.get(0));
2047 
2048         result.clear();
2049         view.setEnabled(false);
2050         assertTrue(view.isClickable());
2051         result = view.getTouchables();
2052         assertEquals(0, result.size());
2053     }
2054 
testInflate()2055     public void testInflate() {
2056         View view = View.inflate(mActivity, R.layout.view_layout, null);
2057         assertNotNull(view);
2058         assertTrue(view instanceof LinearLayout);
2059 
2060         MockView mockView = (MockView) view.findViewById(R.id.mock_view);
2061         assertNotNull(mockView);
2062         assertTrue(mockView.hasCalledOnFinishInflate());
2063     }
2064 
testIsInTouchMode()2065     public void testIsInTouchMode() {
2066         View view = new View(mActivity);
2067         // mAttachInfo is null
2068         assertFalse(view.isInTouchMode());
2069 
2070         // mAttachInfo is not null
2071         view = mActivity.findViewById(R.id.fit_windows);
2072         assertFalse(view.isInTouchMode());
2073     }
2074 
testIsInEditMode()2075     public void testIsInEditMode() {
2076         View view = new View(mActivity);
2077         assertFalse(view.isInEditMode());
2078     }
2079 
testPostInvalidate1()2080     public void testPostInvalidate1() {
2081         View view = new View(mActivity);
2082         // mAttachInfo is null
2083         view.postInvalidate();
2084 
2085         // mAttachInfo is not null
2086         view = mActivity.findViewById(R.id.fit_windows);
2087         view.postInvalidate();
2088     }
2089 
testPostInvalidate2()2090     public void testPostInvalidate2() {
2091         View view = new View(mActivity);
2092         // mAttachInfo is null
2093         view.postInvalidate(0, 1, 2, 3);
2094 
2095         // mAttachInfo is not null
2096         view = mActivity.findViewById(R.id.fit_windows);
2097         view.postInvalidate(10, 20, 30, 40);
2098         view.postInvalidate(0, -20, -30, -40);
2099     }
2100 
testPostInvalidateDelayed()2101     public void testPostInvalidateDelayed() {
2102         View view = new View(mActivity);
2103         // mAttachInfo is null
2104         view.postInvalidateDelayed(1000);
2105         view.postInvalidateDelayed(500, 0, 0, 100, 200);
2106 
2107         // mAttachInfo is not null
2108         view = mActivity.findViewById(R.id.fit_windows);
2109         view.postInvalidateDelayed(1000);
2110         view.postInvalidateDelayed(500, 0, 0, 100, 200);
2111         view.postInvalidateDelayed(-1);
2112     }
2113 
testPost()2114     public void testPost() {
2115         View view = new View(mActivity);
2116         MockRunnable action = new MockRunnable();
2117 
2118         // mAttachInfo is null
2119         assertTrue(view.post(action));
2120         assertTrue(view.post(null));
2121 
2122         // mAttachInfo is not null
2123         view = mActivity.findViewById(R.id.fit_windows);
2124         assertTrue(view.post(action));
2125         assertTrue(view.post(null));
2126     }
2127 
testPostDelayed()2128     public void testPostDelayed() {
2129         View view = new View(mActivity);
2130         MockRunnable action = new MockRunnable();
2131 
2132         // mAttachInfo is null
2133         assertTrue(view.postDelayed(action, 1000));
2134         assertTrue(view.postDelayed(null, -1));
2135 
2136         // mAttachInfo is not null
2137         view = mActivity.findViewById(R.id.fit_windows);
2138         assertTrue(view.postDelayed(action, 1000));
2139         assertTrue(view.postDelayed(null, 0));
2140     }
2141 
2142     @UiThreadTest
testPlaySoundEffect()2143     public void testPlaySoundEffect() {
2144         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2145         // sound effect enabled
2146         view.playSoundEffect(SoundEffectConstants.CLICK);
2147 
2148         // sound effect disabled
2149         view.setSoundEffectsEnabled(false);
2150         view.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
2151 
2152         // no way to assert the soundConstant be really played.
2153     }
2154 
testOnKeyShortcut()2155     public void testOnKeyShortcut() throws Throwable {
2156         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2157         runTestOnUiThread(new Runnable() {
2158             @Override
2159             public void run() {
2160                 view.setFocusable(true);
2161                 view.requestFocus();
2162             }
2163         });
2164         getInstrumentation().waitForIdleSync();
2165         assertTrue(view.isFocused());
2166 
2167         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU);
2168         getInstrumentation().sendKeySync(event);
2169         event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
2170         getInstrumentation().sendKeySync(event);
2171         assertTrue(view.hasCalledOnKeyShortcut());
2172     }
2173 
testOnKeyMultiple()2174     public void testOnKeyMultiple() throws Throwable {
2175         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2176         runTestOnUiThread(new Runnable() {
2177             @Override
2178             public void run() {
2179                 view.setFocusable(true);
2180             }
2181         });
2182 
2183         assertFalse(view.hasCalledOnKeyMultiple());
2184         view.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_ENTER));
2185         assertTrue(view.hasCalledOnKeyMultiple());
2186     }
2187 
2188     @UiThreadTest
testDispatchKeyShortcutEvent()2189     public void testDispatchKeyShortcutEvent() {
2190         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2191         view.setFocusable(true);
2192 
2193         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
2194         view.dispatchKeyShortcutEvent(event);
2195         assertTrue(view.hasCalledOnKeyShortcut());
2196 
2197         try {
2198             view.dispatchKeyShortcutEvent(null);
2199             fail("should throw NullPointerException");
2200         } catch (NullPointerException e) {
2201         }
2202     }
2203 
testOnTrackballEvent()2204     public void testOnTrackballEvent() throws Throwable {
2205         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2206         runTestOnUiThread(new Runnable() {
2207             @Override
2208             public void run() {
2209                 view.setEnabled(true);
2210                 view.setFocusable(true);
2211                 view.requestFocus();
2212             }
2213         });
2214         getInstrumentation().waitForIdleSync();
2215 
2216         long downTime = SystemClock.uptimeMillis();
2217         long eventTime = downTime;
2218         MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
2219                 1, 2, 0);
2220         getInstrumentation().sendTrackballEventSync(event);
2221         getInstrumentation().waitForIdleSync();
2222         assertTrue(view.hasCalledOnTrackballEvent());
2223     }
2224 
2225     @UiThreadTest
testDispatchTrackballMoveEvent()2226     public void testDispatchTrackballMoveEvent() {
2227         ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
2228         MockView mockView1 = new MockView(mActivity);
2229         MockView mockView2 = new MockView(mActivity);
2230         viewGroup.addView(mockView1);
2231         viewGroup.addView(mockView2);
2232         mockView1.setFocusable(true);
2233         mockView2.setFocusable(true);
2234         mockView2.requestFocus();
2235 
2236         long downTime = SystemClock.uptimeMillis();
2237         long eventTime = downTime;
2238         MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
2239                 1, 2, 0);
2240         mockView1.dispatchTrackballEvent(event);
2241         // issue 1695243
2242         // It passes a trackball motion event down to itself even if it is not the focused view.
2243         assertTrue(mockView1.hasCalledOnTrackballEvent());
2244         assertFalse(mockView2.hasCalledOnTrackballEvent());
2245 
2246         mockView1.reset();
2247         mockView2.reset();
2248         downTime = SystemClock.uptimeMillis();
2249         eventTime = downTime;
2250         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, 1, 2, 0);
2251         mockView2.dispatchTrackballEvent(event);
2252         assertFalse(mockView1.hasCalledOnTrackballEvent());
2253         assertTrue(mockView2.hasCalledOnTrackballEvent());
2254     }
2255 
testDispatchUnhandledMove()2256     public void testDispatchUnhandledMove() throws Throwable {
2257         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2258         runTestOnUiThread(new Runnable() {
2259             @Override
2260             public void run() {
2261                 view.setFocusable(true);
2262                 view.requestFocus();
2263             }
2264         });
2265         getInstrumentation().waitForIdleSync();
2266 
2267         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT);
2268         getInstrumentation().sendKeySync(event);
2269 
2270         assertTrue(view.hasCalledDispatchUnhandledMove());
2271     }
2272 
testWindowVisibilityChanged()2273     public void testWindowVisibilityChanged() throws Throwable {
2274         final MockView mockView = new MockView(mActivity);
2275         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
2276 
2277         runTestOnUiThread(new Runnable() {
2278             @Override
2279             public void run() {
2280                 viewGroup.addView(mockView);
2281             }
2282         });
2283         getInstrumentation().waitForIdleSync();
2284         assertTrue(mockView.hasCalledOnWindowVisibilityChanged());
2285 
2286         mockView.reset();
2287         runTestOnUiThread(new Runnable() {
2288             @Override
2289             public void run() {
2290                 getActivity().setVisible(false);
2291             }
2292         });
2293         getInstrumentation().waitForIdleSync();
2294         assertTrue(mockView.hasCalledDispatchWindowVisibilityChanged());
2295         assertTrue(mockView.hasCalledOnWindowVisibilityChanged());
2296 
2297         mockView.reset();
2298         runTestOnUiThread(new Runnable() {
2299             @Override
2300             public void run() {
2301                 getActivity().setVisible(true);
2302             }
2303         });
2304         getInstrumentation().waitForIdleSync();
2305         assertTrue(mockView.hasCalledDispatchWindowVisibilityChanged());
2306         assertTrue(mockView.hasCalledOnWindowVisibilityChanged());
2307 
2308         mockView.reset();
2309         runTestOnUiThread(new Runnable() {
2310             @Override
2311             public void run() {
2312                 viewGroup.removeView(mockView);
2313             }
2314         });
2315         getInstrumentation().waitForIdleSync();
2316         assertTrue(mockView.hasCalledOnWindowVisibilityChanged());
2317     }
2318 
testGetLocalVisibleRect()2319     public void testGetLocalVisibleRect() throws Throwable {
2320         final View view = mActivity.findViewById(R.id.mock_view);
2321         Rect rect = new Rect();
2322 
2323         assertTrue(view.getLocalVisibleRect(rect));
2324         assertEquals(0, rect.left);
2325         assertEquals(0, rect.top);
2326         assertEquals(100, rect.right);
2327         assertEquals(200, rect.bottom);
2328 
2329         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
2330         runTestOnUiThread(new Runnable() {
2331             @Override
2332             public void run() {
2333                 view.setLayoutParams(layoutParams1);
2334             }
2335         });
2336         getInstrumentation().waitForIdleSync();
2337         assertFalse(view.getLocalVisibleRect(rect));
2338 
2339         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
2340         runTestOnUiThread(new Runnable() {
2341             @Override
2342             public void run() {
2343                 view.setLayoutParams(layoutParams2);
2344             }
2345         });
2346         getInstrumentation().waitForIdleSync();
2347         assertFalse(view.getLocalVisibleRect(rect));
2348 
2349         Display display = getActivity().getWindowManager().getDefaultDisplay();
2350         int halfWidth = display.getWidth() / 2;
2351         int halfHeight = display.getHeight() /2;
2352 
2353         final LinearLayout.LayoutParams layoutParams3 =
2354                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
2355         runTestOnUiThread(new Runnable() {
2356             @Override
2357             public void run() {
2358                 view.setLayoutParams(layoutParams3);
2359                 view.scrollTo(20, -30);
2360             }
2361         });
2362         getInstrumentation().waitForIdleSync();
2363         assertTrue(view.getLocalVisibleRect(rect));
2364         assertEquals(20, rect.left);
2365         assertEquals(-30, rect.top);
2366         assertEquals(halfWidth + 20, rect.right);
2367         assertEquals(halfHeight - 30, rect.bottom);
2368 
2369         try {
2370             view.getLocalVisibleRect(null);
2371             fail("should throw NullPointerException");
2372         } catch (NullPointerException e) {
2373         }
2374     }
2375 
testMergeDrawableStates()2376     public void testMergeDrawableStates() {
2377         MockView view = new MockView(mActivity);
2378 
2379         int[] states = view.mergeDrawableStatesWrapper(new int[] { 0, 1, 2, 0, 0 },
2380                 new int[] { 3 });
2381         assertNotNull(states);
2382         assertEquals(5, states.length);
2383         assertEquals(0, states[0]);
2384         assertEquals(1, states[1]);
2385         assertEquals(2, states[2]);
2386         assertEquals(3, states[3]);
2387         assertEquals(0, states[4]);
2388 
2389         try {
2390             view.mergeDrawableStatesWrapper(new int[] { 1, 2 }, new int[] { 3 });
2391             fail("should throw IndexOutOfBoundsException");
2392         } catch (IndexOutOfBoundsException e) {
2393         }
2394 
2395         try {
2396             view.mergeDrawableStatesWrapper(null, new int[] { 0 });
2397             fail("should throw NullPointerException");
2398         } catch (NullPointerException e) {
2399         }
2400 
2401         try {
2402             view.mergeDrawableStatesWrapper(new int [] { 0 }, null);
2403             fail("should throw NullPointerException");
2404         } catch (NullPointerException e) {
2405         }
2406     }
2407 
testOnSaveAndRestoreInstanceState()2408     public void testOnSaveAndRestoreInstanceState() {
2409         // it is hard to simulate operation to make callback be called.
2410     }
2411 
testSaveAndRestoreHierarchyState()2412     public void testSaveAndRestoreHierarchyState() {
2413         int viewId = R.id.mock_view;
2414         MockView view = (MockView) mActivity.findViewById(viewId);
2415         SparseArray<Parcelable> container = new SparseArray<>();
2416         view.saveHierarchyState(container);
2417         assertTrue(view.hasCalledDispatchSaveInstanceState());
2418         assertTrue(view.hasCalledOnSaveInstanceState());
2419         assertEquals(viewId, container.keyAt(0));
2420 
2421         view.reset();
2422         container.put(R.id.mock_view, BaseSavedState.EMPTY_STATE);
2423         view.restoreHierarchyState(container);
2424         assertTrue(view.hasCalledDispatchRestoreInstanceState());
2425         assertTrue(view.hasCalledOnRestoreInstanceState());
2426         container.clear();
2427         view.saveHierarchyState(container);
2428         assertTrue(view.hasCalledDispatchSaveInstanceState());
2429         assertTrue(view.hasCalledOnSaveInstanceState());
2430         assertEquals(viewId, container.keyAt(0));
2431 
2432         container.clear();
2433         container.put(viewId, new android.graphics.Rect());
2434         try {
2435             view.restoreHierarchyState(container);
2436             fail("Parcelable state must be an AbsSaveState, should throw IllegalArgumentException");
2437         } catch (IllegalArgumentException e) {
2438             // expected
2439         }
2440 
2441         try {
2442             view.restoreHierarchyState(null);
2443             fail("Cannot pass null to restoreHierarchyState(), should throw NullPointerException");
2444         } catch (NullPointerException e) {
2445             // expected
2446         }
2447 
2448         try {
2449             view.saveHierarchyState(null);
2450             fail("Cannot pass null to saveHierarchyState(), should throw NullPointerException");
2451         } catch (NullPointerException e) {
2452             // expected
2453         }
2454     }
2455 
testOnKeyDownOrUp()2456     public void testOnKeyDownOrUp() throws Throwable {
2457         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2458         runTestOnUiThread(new Runnable() {
2459             @Override
2460             public void run() {
2461                 view.setFocusable(true);
2462                 view.requestFocus();
2463             }
2464         });
2465         getInstrumentation().waitForIdleSync();
2466         assertTrue(view.isFocused());
2467 
2468         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
2469         getInstrumentation().sendKeySync(event);
2470         assertTrue(view.hasCalledOnKeyDown());
2471 
2472         event = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0);
2473         getInstrumentation().sendKeySync(event);
2474         assertTrue(view.hasCalledOnKeyUp());
2475 
2476         view.reset();
2477         assertTrue(view.isEnabled());
2478         assertFalse(view.isClickable());
2479         assertFalse(view.isPressed());
2480         event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER);
2481         getInstrumentation().sendKeySync(event);
2482         assertFalse(view.isPressed());
2483         assertTrue(view.hasCalledOnKeyDown());
2484 
2485         runTestOnUiThread(new Runnable() {
2486             @Override
2487             public void run() {
2488                 view.setEnabled(true);
2489                 view.setClickable(true);
2490             }
2491         });
2492         view.reset();
2493         OnClickListenerImpl listener = new OnClickListenerImpl();
2494         view.setOnClickListener(listener);
2495 
2496         assertFalse(view.isPressed());
2497         event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER);
2498         getInstrumentation().sendKeySync(event);
2499         assertTrue(view.isPressed());
2500         assertTrue(view.hasCalledOnKeyDown());
2501         event = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER);
2502         getInstrumentation().sendKeySync(event);
2503         assertFalse(view.isPressed());
2504         assertTrue(view.hasCalledOnKeyUp());
2505         assertTrue(listener.hasOnClick());
2506 
2507         view.setPressed(false);
2508         listener.reset();
2509         view.reset();
2510 
2511         assertFalse(view.isPressed());
2512         event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
2513         getInstrumentation().sendKeySync(event);
2514         assertTrue(view.isPressed());
2515         assertTrue(view.hasCalledOnKeyDown());
2516         event = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER);
2517         getInstrumentation().sendKeySync(event);
2518         assertFalse(view.isPressed());
2519         assertTrue(view.hasCalledOnKeyUp());
2520         assertTrue(listener.hasOnClick());
2521     }
2522 
checkBounds(final ViewGroup viewGroup, final View view, final CountDownLatch countDownLatch, final int left, final int top, final int width, final int height)2523     private void checkBounds(final ViewGroup viewGroup, final View view,
2524             final CountDownLatch countDownLatch, final int left, final int top,
2525             final int width, final int height) {
2526         viewGroup.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
2527             @Override
2528             public boolean onPreDraw() {
2529                 assertEquals(left, view.getLeft());
2530                 assertEquals(top, view.getTop());
2531                 assertEquals(width, view.getWidth());
2532                 assertEquals(height, view.getHeight());
2533                 countDownLatch.countDown();
2534                 viewGroup.getViewTreeObserver().removeOnPreDrawListener(this);
2535                 return true;
2536             }
2537         });
2538     }
2539 
testAddRemoveAffectsWrapContentLayout()2540     public void testAddRemoveAffectsWrapContentLayout() throws Throwable {
2541         final int childWidth = 100;
2542         final int childHeight = 200;
2543         final int parentHeight = 400;
2544         final MockLinearLayout parent = new MockLinearLayout(mActivity);
2545         ViewGroup.LayoutParams parentParams = new ViewGroup.LayoutParams(
2546                 ViewGroup.LayoutParams.WRAP_CONTENT, parentHeight);
2547         parent.setLayoutParams(parentParams);
2548         final MockView child = new MockView(mActivity);
2549         child.setBackgroundColor(Color.GREEN);
2550         ViewGroup.LayoutParams childParams = new ViewGroup.LayoutParams(childWidth, childHeight);
2551         child.setLayoutParams(childParams);
2552         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
2553 
2554         // Idea:
2555         // Add the wrap_content parent view to the hierarchy (removing other views as they
2556         // are not needed), test that parent is 0xparentHeight
2557         // Add the child view to the parent, test that parent has same width as child
2558         // Remove the child view from the parent, test that parent is 0xparentHeight
2559         final CountDownLatch countDownLatch1 = new CountDownLatch(1);
2560         runTestOnUiThread(new Runnable() {
2561             @Override
2562             public void run() {
2563                 viewGroup.removeAllViews();
2564                 viewGroup.addView(parent);
2565                 checkBounds(viewGroup, parent, countDownLatch1, 0, 0, 0, parentHeight);
2566             }
2567         });
2568         countDownLatch1.await(500, TimeUnit.MILLISECONDS);
2569 
2570         final CountDownLatch countDownLatch2 = new CountDownLatch(1);
2571         runTestOnUiThread(new Runnable() {
2572             @Override
2573             public void run() {
2574                 parent.addView(child);
2575                 checkBounds(viewGroup, parent, countDownLatch2, 0, 0, childWidth, parentHeight);
2576             }
2577         });
2578         countDownLatch2.await(500, TimeUnit.MILLISECONDS);
2579 
2580         final CountDownLatch countDownLatch3 = new CountDownLatch(1);
2581         runTestOnUiThread(new Runnable() {
2582             @Override
2583             public void run() {
2584                 parent.removeView(child);
2585                 checkBounds(viewGroup, parent, countDownLatch3, 0, 0, 0, parentHeight);
2586             }
2587         });
2588         countDownLatch3.await(500, TimeUnit.MILLISECONDS);
2589     }
2590 
2591     @UiThreadTest
testDispatchKeyEvent()2592     public void testDispatchKeyEvent() {
2593         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2594         MockView mockView1 = new MockView(mActivity);
2595         MockView mockView2 = new MockView(mActivity);
2596         ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
2597         viewGroup.addView(mockView1);
2598         viewGroup.addView(mockView2);
2599         view.setFocusable(true);
2600         mockView1.setFocusable(true);
2601         mockView2.setFocusable(true);
2602 
2603         assertFalse(view.hasCalledOnKeyDown());
2604         assertFalse(mockView1.hasCalledOnKeyDown());
2605         assertFalse(mockView2.hasCalledOnKeyDown());
2606         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
2607         assertFalse(view.dispatchKeyEvent(event));
2608         assertTrue(view.hasCalledOnKeyDown());
2609         assertFalse(mockView1.hasCalledOnKeyDown());
2610         assertFalse(mockView2.hasCalledOnKeyDown());
2611 
2612         view.reset();
2613         mockView1.reset();
2614         mockView2.reset();
2615         assertFalse(view.hasCalledOnKeyDown());
2616         assertFalse(mockView1.hasCalledOnKeyDown());
2617         assertFalse(mockView2.hasCalledOnKeyDown());
2618         event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
2619         assertFalse(mockView1.dispatchKeyEvent(event));
2620         assertFalse(view.hasCalledOnKeyDown());
2621         // issue 1695243
2622         // When the view has NOT focus, it dispatches to itself, which disobey the javadoc.
2623         assertTrue(mockView1.hasCalledOnKeyDown());
2624         assertFalse(mockView2.hasCalledOnKeyDown());
2625 
2626         assertFalse(view.hasCalledOnKeyUp());
2627         event = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0);
2628         assertFalse(view.dispatchKeyEvent(event));
2629         assertTrue(view.hasCalledOnKeyUp());
2630 
2631         assertFalse(view.hasCalledOnKeyMultiple());
2632         event = new KeyEvent(1, 2, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_0, 2);
2633         assertFalse(view.dispatchKeyEvent(event));
2634         assertTrue(view.hasCalledOnKeyMultiple());
2635 
2636         try {
2637             view.dispatchKeyEvent(null);
2638             fail("should throw NullPointerException");
2639         } catch (NullPointerException e) {
2640             // expected
2641         }
2642 
2643         view.reset();
2644         event = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0);
2645         OnKeyListenerImpl listener = new OnKeyListenerImpl();
2646         view.setOnKeyListener(listener);
2647         assertFalse(listener.hasOnKey());
2648         assertTrue(view.dispatchKeyEvent(event));
2649         assertTrue(listener.hasOnKey());
2650         assertFalse(view.hasCalledOnKeyUp());
2651     }
2652 
2653     @UiThreadTest
testDispatchTouchEvent()2654     public void testDispatchTouchEvent() {
2655         ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
2656         MockView mockView1 = new MockView(mActivity);
2657         MockView mockView2 = new MockView(mActivity);
2658         viewGroup.addView(mockView1);
2659         viewGroup.addView(mockView2);
2660 
2661         int[] xy = new int[2];
2662         mockView1.getLocationOnScreen(xy);
2663 
2664         final int viewWidth = mockView1.getWidth();
2665         final int viewHeight = mockView1.getHeight();
2666         final float x = xy[0] + viewWidth / 2.0f;
2667         final float y = xy[1] + viewHeight / 2.0f;
2668 
2669         long downTime = SystemClock.uptimeMillis();
2670         long eventTime = SystemClock.uptimeMillis();
2671         MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
2672                 x, y, 0);
2673 
2674         assertFalse(mockView1.hasCalledOnTouchEvent());
2675         assertFalse(mockView1.dispatchTouchEvent(event));
2676         assertTrue(mockView1.hasCalledOnTouchEvent());
2677 
2678         assertFalse(mockView2.hasCalledOnTouchEvent());
2679         assertFalse(mockView2.dispatchTouchEvent(event));
2680         // issue 1695243
2681         // it passes the touch screen motion event down to itself even if it is not the target view.
2682         assertTrue(mockView2.hasCalledOnTouchEvent());
2683 
2684         mockView1.reset();
2685         OnTouchListenerImpl listener = new OnTouchListenerImpl();
2686         mockView1.setOnTouchListener(listener);
2687         assertFalse(listener.hasOnTouch());
2688         assertTrue(mockView1.dispatchTouchEvent(event));
2689         assertTrue(listener.hasOnTouch());
2690         assertFalse(mockView1.hasCalledOnTouchEvent());
2691     }
2692 
testInvalidate1()2693     public void testInvalidate1() throws Throwable {
2694         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2695         assertTrue(view.hasCalledOnDraw());
2696 
2697         view.reset();
2698         runTestOnUiThread(new Runnable() {
2699             @Override
2700             public void run() {
2701                 view.invalidate();
2702             }
2703         });
2704         getInstrumentation().waitForIdleSync();
2705         new PollingCheck() {
2706             @Override
2707             protected boolean check() {
2708                 return view.hasCalledOnDraw();
2709             }
2710         }.run();
2711 
2712         view.reset();
2713         runTestOnUiThread(new Runnable() {
2714             @Override
2715             public void run() {
2716                 view.setVisibility(View.INVISIBLE);
2717                 view.invalidate();
2718             }
2719         });
2720         getInstrumentation().waitForIdleSync();
2721         assertFalse(view.hasCalledOnDraw());
2722     }
2723 
testInvalidate2()2724     public void testInvalidate2() throws Throwable {
2725         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2726         assertTrue(view.hasCalledOnDraw());
2727 
2728         try {
2729             view.invalidate(null);
2730             fail("should throw NullPointerException");
2731         } catch (NullPointerException e) {
2732         }
2733 
2734         view.reset();
2735         final Rect dirty = new Rect(view.getLeft() + 1, view.getTop() + 1,
2736                 view.getLeft() + view.getWidth() / 2, view.getTop() + view.getHeight() / 2);
2737         runTestOnUiThread(new Runnable() {
2738             @Override
2739             public void run() {
2740                 view.invalidate(dirty);
2741             }
2742         });
2743         getInstrumentation().waitForIdleSync();
2744         new PollingCheck() {
2745             @Override
2746             protected boolean check() {
2747                 return view.hasCalledOnDraw();
2748             }
2749         }.run();
2750 
2751         view.reset();
2752         runTestOnUiThread(new Runnable() {
2753             @Override
2754             public void run() {
2755                 view.setVisibility(View.INVISIBLE);
2756                 view.invalidate(dirty);
2757             }
2758         });
2759         getInstrumentation().waitForIdleSync();
2760         assertFalse(view.hasCalledOnDraw());
2761     }
2762 
testInvalidate3()2763     public void testInvalidate3() throws Throwable {
2764         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2765         assertTrue(view.hasCalledOnDraw());
2766 
2767         view.reset();
2768         final Rect dirty = new Rect(view.getLeft() + 1, view.getTop() + 1,
2769                 view.getLeft() + view.getWidth() / 2, view.getTop() + view.getHeight() / 2);
2770         runTestOnUiThread(new Runnable() {
2771             @Override
2772             public void run() {
2773                 view.invalidate(dirty.left, dirty.top, dirty.right, dirty.bottom);
2774             }
2775         });
2776         getInstrumentation().waitForIdleSync();
2777         new PollingCheck() {
2778             @Override
2779             protected boolean check() {
2780                 return view.hasCalledOnDraw();
2781             }
2782         }.run();
2783 
2784         view.reset();
2785         runTestOnUiThread(new Runnable() {
2786             @Override
2787             public void run() {
2788                 view.setVisibility(View.INVISIBLE);
2789                 view.invalidate(dirty.left, dirty.top, dirty.right, dirty.bottom);
2790             }
2791         });
2792         getInstrumentation().waitForIdleSync();
2793         assertFalse(view.hasCalledOnDraw());
2794     }
2795 
testInvalidateDrawable()2796     public void testInvalidateDrawable() throws Throwable {
2797         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2798         final Drawable d1 = mResources.getDrawable(R.drawable.scenery);
2799         final Drawable d2 = mResources.getDrawable(R.drawable.pass);
2800 
2801         view.reset();
2802         runTestOnUiThread(new Runnable() {
2803             @Override
2804             public void run() {
2805                 view.setBackgroundDrawable(d1);
2806                 view.invalidateDrawable(d1);
2807             }
2808         });
2809         getInstrumentation().waitForIdleSync();
2810         new PollingCheck() {
2811             @Override
2812             protected boolean check() {
2813                 return view.hasCalledOnDraw();
2814             }
2815         }.run();
2816 
2817         view.reset();
2818         runTestOnUiThread(new Runnable() {
2819             @Override
2820             public void run() {
2821                 view.invalidateDrawable(d2);
2822             }
2823         });
2824         getInstrumentation().waitForIdleSync();
2825         assertFalse(view.hasCalledOnDraw());
2826 
2827         MockView viewTestNull = new MockView(mActivity);
2828         try {
2829             viewTestNull.invalidateDrawable(null);
2830             fail("should throw NullPointerException");
2831         } catch (NullPointerException e) {
2832         }
2833     }
2834 
2835     @UiThreadTest
testOnFocusChanged()2836     public void testOnFocusChanged() {
2837         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2838 
2839         mActivity.findViewById(R.id.fit_windows).setFocusable(true);
2840         view.setFocusable(true);
2841         assertFalse(view.hasCalledOnFocusChanged());
2842 
2843         view.requestFocus();
2844         assertTrue(view.hasCalledOnFocusChanged());
2845 
2846         view.reset();
2847         view.clearFocus();
2848         assertTrue(view.hasCalledOnFocusChanged());
2849     }
2850 
testDrawableState()2851     public void testDrawableState() {
2852         MockView view = new MockView(mActivity);
2853         view.setParent(mMockParent);
2854 
2855         assertFalse(view.hasCalledOnCreateDrawableState());
2856         assertTrue(Arrays.equals(MockView.getEnabledStateSet(), view.getDrawableState()));
2857         assertTrue(view.hasCalledOnCreateDrawableState());
2858 
2859         view.reset();
2860         assertFalse(view.hasCalledOnCreateDrawableState());
2861         assertTrue(Arrays.equals(MockView.getEnabledStateSet(), view.getDrawableState()));
2862         assertFalse(view.hasCalledOnCreateDrawableState());
2863 
2864         view.reset();
2865         assertFalse(view.hasCalledDrawableStateChanged());
2866         view.setPressed(true);
2867         assertTrue(view.hasCalledDrawableStateChanged());
2868         assertTrue(Arrays.equals(MockView.getPressedEnabledStateSet(), view.getDrawableState()));
2869         assertTrue(view.hasCalledOnCreateDrawableState());
2870 
2871         view.reset();
2872         mMockParent.reset();
2873         assertFalse(view.hasCalledDrawableStateChanged());
2874         assertFalse(mMockParent.hasChildDrawableStateChanged());
2875         view.refreshDrawableState();
2876         assertTrue(view.hasCalledDrawableStateChanged());
2877         assertTrue(mMockParent.hasChildDrawableStateChanged());
2878         assertTrue(Arrays.equals(MockView.getPressedEnabledStateSet(), view.getDrawableState()));
2879         assertTrue(view.hasCalledOnCreateDrawableState());
2880     }
2881 
testWindowFocusChanged()2882     public void testWindowFocusChanged() {
2883         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2884 
2885         // Wait until the window has been focused.
2886         new PollingCheck(TIMEOUT_DELTA) {
2887             @Override
2888             protected boolean check() {
2889                 return view.hasWindowFocus();
2890             }
2891         }.run();
2892 
2893         new PollingCheck() {
2894             @Override
2895             protected boolean check() {
2896                 return view.hasCalledOnWindowFocusChanged();
2897             }
2898         }.run();
2899 
2900         assertTrue(view.hasCalledOnWindowFocusChanged());
2901         assertTrue(view.hasCalledDispatchWindowFocusChanged());
2902 
2903         view.reset();
2904         assertFalse(view.hasCalledOnWindowFocusChanged());
2905         assertFalse(view.hasCalledDispatchWindowFocusChanged());
2906 
2907         CtsActivity activity = launchActivity("android.view.cts", CtsActivity.class, null);
2908 
2909         // Wait until the window lost focus.
2910         new PollingCheck(TIMEOUT_DELTA) {
2911             @Override
2912             protected boolean check() {
2913                 return !view.hasWindowFocus();
2914             }
2915         }.run();
2916 
2917         assertTrue(view.hasCalledOnWindowFocusChanged());
2918         assertTrue(view.hasCalledDispatchWindowFocusChanged());
2919 
2920         activity.finish();
2921     }
2922 
testDraw()2923     public void testDraw() throws Throwable {
2924         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
2925         runTestOnUiThread(new Runnable() {
2926             @Override
2927             public void run() {
2928                 view.requestLayout();
2929             }
2930         });
2931         getInstrumentation().waitForIdleSync();
2932 
2933         assertTrue(view.hasCalledOnDraw());
2934         assertTrue(view.hasCalledDispatchDraw());
2935     }
2936 
testRequestFocusFromTouch()2937     public void testRequestFocusFromTouch() {
2938         View view = new View(mActivity);
2939         view.setFocusable(true);
2940         assertFalse(view.isFocused());
2941 
2942         view.requestFocusFromTouch();
2943         assertTrue(view.isFocused());
2944 
2945         view.requestFocusFromTouch();
2946         assertTrue(view.isFocused());
2947     }
2948 
testRequestRectangleOnScreen1()2949     public void testRequestRectangleOnScreen1() {
2950         MockView view = new MockView(mActivity);
2951         Rect rectangle = new Rect(10, 10, 20, 30);
2952         MockViewGroupParent parent = new MockViewGroupParent(mActivity);
2953 
2954         // parent is null
2955         assertFalse(view.requestRectangleOnScreen(rectangle, true));
2956         assertFalse(view.requestRectangleOnScreen(rectangle, false));
2957         assertFalse(view.requestRectangleOnScreen(null, true));
2958 
2959         view.setParent(parent);
2960         view.scrollTo(1, 2);
2961         assertFalse(parent.hasRequestChildRectangleOnScreen());
2962 
2963         assertFalse(view.requestRectangleOnScreen(rectangle, true));
2964         assertTrue(parent.hasRequestChildRectangleOnScreen());
2965 
2966         parent.reset();
2967         view.scrollTo(11, 22);
2968         assertFalse(parent.hasRequestChildRectangleOnScreen());
2969 
2970         assertFalse(view.requestRectangleOnScreen(rectangle, true));
2971         assertTrue(parent.hasRequestChildRectangleOnScreen());
2972 
2973         try {
2974             view.requestRectangleOnScreen(null, true);
2975             fail("should throw NullPointerException");
2976         } catch (NullPointerException e) {
2977         }
2978     }
2979 
testRequestRectangleOnScreen2()2980     public void testRequestRectangleOnScreen2() {
2981         MockView view = new MockView(mActivity);
2982         Rect rectangle = new Rect();
2983         MockViewGroupParent parent = new MockViewGroupParent(mActivity);
2984 
2985         MockViewGroupParent grandparent = new MockViewGroupParent(mActivity);
2986 
2987         // parent is null
2988         assertFalse(view.requestRectangleOnScreen(rectangle));
2989         assertFalse(view.requestRectangleOnScreen(null));
2990         assertEquals(0, rectangle.left);
2991         assertEquals(0, rectangle.top);
2992         assertEquals(0, rectangle.right);
2993         assertEquals(0, rectangle.bottom);
2994 
2995         parent.addView(view);
2996         parent.scrollTo(1, 2);
2997         grandparent.addView(parent);
2998 
2999         assertFalse(parent.hasRequestChildRectangleOnScreen());
3000         assertFalse(grandparent.hasRequestChildRectangleOnScreen());
3001 
3002         assertFalse(view.requestRectangleOnScreen(rectangle));
3003 
3004         assertTrue(parent.hasRequestChildRectangleOnScreen());
3005         assertTrue(grandparent.hasRequestChildRectangleOnScreen());
3006 
3007         // it is grand parent's responsibility to check parent's scroll offset
3008         final Rect requestedRect = grandparent.getLastRequestedChildRectOnScreen();
3009         assertEquals(0, requestedRect.left);
3010         assertEquals(0, requestedRect.top);
3011         assertEquals(0, requestedRect.right);
3012         assertEquals(0, requestedRect.bottom);
3013 
3014         try {
3015             view.requestRectangleOnScreen(null);
3016             fail("should throw NullPointerException");
3017         } catch (NullPointerException e) {
3018         }
3019     }
3020 
testRequestRectangleOnScreen3()3021     public void testRequestRectangleOnScreen3() {
3022         requestRectangleOnScreenTest(false);
3023     }
3024 
testRequestRectangleOnScreen4()3025     public void testRequestRectangleOnScreen4() {
3026         requestRectangleOnScreenTest(true);
3027     }
3028 
testRequestRectangleOnScreen5()3029     public void testRequestRectangleOnScreen5() {
3030         MockView child = new MockView(mActivity);
3031 
3032         MockViewGroupParent parent = new MockViewGroupParent(mActivity);
3033         MockViewGroupParent grandParent = new MockViewGroupParent(mActivity);
3034         parent.addView(child);
3035         grandParent.addView(parent);
3036 
3037         child.layout(5, 6, 7, 9);
3038         child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
3039         assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
3040         assertEquals(new Rect(15, 16, 17, 19), grandParent.getLastRequestedChildRectOnScreen());
3041 
3042         child.scrollBy(1, 2);
3043         child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
3044         assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
3045         assertEquals(new Rect(14, 14, 16, 17), grandParent.getLastRequestedChildRectOnScreen());
3046     }
3047 
requestRectangleOnScreenTest(boolean scrollParent)3048     private void requestRectangleOnScreenTest(boolean scrollParent) {
3049         MockView child = new MockView(mActivity);
3050 
3051         MockViewGroupParent parent = new MockViewGroupParent(mActivity);
3052         MockViewGroupParent grandParent = new MockViewGroupParent(mActivity);
3053         parent.addView(child);
3054         grandParent.addView(parent);
3055 
3056         child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
3057         assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
3058         assertEquals(new Rect(10, 10, 12, 13), grandParent.getLastRequestedChildRectOnScreen());
3059 
3060         child.scrollBy(1, 2);
3061         if (scrollParent) {
3062             // should not affect anything
3063             parent.scrollBy(25, 30);
3064             parent.layout(3, 5, 7, 9);
3065         }
3066         child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
3067         assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
3068         assertEquals(new Rect(9, 8, 11, 11), grandParent.getLastRequestedChildRectOnScreen());
3069     }
3070 
testRequestRectangleOnScreenWithScale()3071     public void testRequestRectangleOnScreenWithScale() {
3072         // scale should not affect the rectangle
3073         MockView child = new MockView(mActivity);
3074         child.setScaleX(2);
3075         child.setScaleX(3);
3076         MockViewGroupParent parent = new MockViewGroupParent(mActivity);
3077         MockViewGroupParent grandParent = new MockViewGroupParent(mActivity);
3078         parent.addView(child);
3079         grandParent.addView(parent);
3080         child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
3081         assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
3082         assertEquals(new Rect(10, 10, 12, 13), grandParent.getLastRequestedChildRectOnScreen());
3083     }
3084 
3085     /**
3086      * For the duration of the tap timeout we are in a 'prepressed' state
3087      * to differentiate between taps and touch scrolls.
3088      * Wait at least this long before testing if the view is pressed
3089      * by calling this function.
3090      */
waitPrepressedTimeout()3091     private void waitPrepressedTimeout() {
3092         try {
3093             Thread.sleep(ViewConfiguration.getTapTimeout() + 10);
3094         } catch (InterruptedException e) {
3095             Log.e(LOG_TAG, "waitPrepressedTimeout() interrupted! Test may fail!", e);
3096         }
3097         getInstrumentation().waitForIdleSync();
3098     }
3099 
testOnTouchEvent()3100     public void testOnTouchEvent() throws Throwable {
3101         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
3102 
3103         assertTrue(view.isEnabled());
3104         assertFalse(view.isClickable());
3105         assertFalse(view.isLongClickable());
3106 
3107         TouchUtils.clickView(this, view);
3108         assertTrue(view.hasCalledOnTouchEvent());
3109 
3110         runTestOnUiThread(new Runnable() {
3111             @Override
3112             public void run() {
3113                 view.setEnabled(true);
3114                 view.setClickable(true);
3115                 view.setLongClickable(true);
3116             }
3117         });
3118         getInstrumentation().waitForIdleSync();
3119         assertTrue(view.isEnabled());
3120         assertTrue(view.isClickable());
3121         assertTrue(view.isLongClickable());
3122 
3123         // MotionEvent.ACTION_DOWN
3124         int[] xy = new int[2];
3125         view.getLocationOnScreen(xy);
3126 
3127         final int viewWidth = view.getWidth();
3128         final int viewHeight = view.getHeight();
3129         float x = xy[0] + viewWidth / 2.0f;
3130         float y = xy[1] + viewHeight / 2.0f;
3131 
3132         long downTime = SystemClock.uptimeMillis();
3133         long eventTime = SystemClock.uptimeMillis();
3134         MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN,
3135                 x, y, 0);
3136         assertFalse(view.isPressed());
3137         getInstrumentation().sendPointerSync(event);
3138         waitPrepressedTimeout();
3139         assertTrue(view.hasCalledOnTouchEvent());
3140         assertTrue(view.isPressed());
3141 
3142         // MotionEvent.ACTION_MOVE
3143         // move out of the bound.
3144         view.reset();
3145         downTime = SystemClock.uptimeMillis();
3146         eventTime = SystemClock.uptimeMillis();
3147         int slop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
3148         x = xy[0] + viewWidth + slop;
3149         y = xy[1] + viewHeight + slop;
3150         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
3151         getInstrumentation().sendPointerSync(event);
3152         assertTrue(view.hasCalledOnTouchEvent());
3153         assertFalse(view.isPressed());
3154 
3155         // move into view
3156         view.reset();
3157         downTime = SystemClock.uptimeMillis();
3158         eventTime = SystemClock.uptimeMillis();
3159         x = xy[0] + viewWidth - 1;
3160         y = xy[1] + viewHeight - 1;
3161         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
3162         getInstrumentation().sendPointerSync(event);
3163         waitPrepressedTimeout();
3164         assertTrue(view.hasCalledOnTouchEvent());
3165         assertFalse(view.isPressed());
3166 
3167         // MotionEvent.ACTION_UP
3168         OnClickListenerImpl listener = new OnClickListenerImpl();
3169         view.setOnClickListener(listener);
3170         view.reset();
3171         downTime = SystemClock.uptimeMillis();
3172         eventTime = SystemClock.uptimeMillis();
3173         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
3174         getInstrumentation().sendPointerSync(event);
3175         assertTrue(view.hasCalledOnTouchEvent());
3176         assertFalse(listener.hasOnClick());
3177 
3178         view.reset();
3179         x = xy[0] + viewWidth / 2.0f;
3180         y = xy[1] + viewHeight / 2.0f;
3181         downTime = SystemClock.uptimeMillis();
3182         eventTime = SystemClock.uptimeMillis();
3183         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
3184         getInstrumentation().sendPointerSync(event);
3185         assertTrue(view.hasCalledOnTouchEvent());
3186 
3187         // MotionEvent.ACTION_CANCEL
3188         view.reset();
3189         listener.reset();
3190         downTime = SystemClock.uptimeMillis();
3191         eventTime = SystemClock.uptimeMillis();
3192         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_CANCEL, x, y, 0);
3193         getInstrumentation().sendPointerSync(event);
3194         assertTrue(view.hasCalledOnTouchEvent());
3195         assertFalse(view.isPressed());
3196         assertFalse(listener.hasOnClick());
3197     }
3198 
testBringToFront()3199     public void testBringToFront() {
3200         MockView view = new MockView(mActivity);
3201         view.setParent(mMockParent);
3202 
3203         assertFalse(mMockParent.hasBroughtChildToFront());
3204         view.bringToFront();
3205         assertTrue(mMockParent.hasBroughtChildToFront());
3206     }
3207 
testGetApplicationWindowToken()3208     public void testGetApplicationWindowToken() {
3209         View view = new View(mActivity);
3210         // mAttachInfo is null
3211         assertNull(view.getApplicationWindowToken());
3212 
3213         // mAttachInfo is not null
3214         view = mActivity.findViewById(R.id.fit_windows);
3215         assertNotNull(view.getApplicationWindowToken());
3216     }
3217 
testGetBottomPaddingOffset()3218     public void testGetBottomPaddingOffset() {
3219         MockView view = new MockView(mActivity);
3220         assertEquals(0, view.getBottomPaddingOffset());
3221     }
3222 
testGetLeftPaddingOffset()3223     public void testGetLeftPaddingOffset() {
3224         MockView view = new MockView(mActivity);
3225         assertEquals(0, view.getLeftPaddingOffset());
3226     }
3227 
testGetRightPaddingOffset()3228     public void testGetRightPaddingOffset() {
3229         MockView view = new MockView(mActivity);
3230         assertEquals(0, view.getRightPaddingOffset());
3231     }
3232 
testGetTopPaddingOffset()3233     public void testGetTopPaddingOffset() {
3234         MockView view = new MockView(mActivity);
3235         assertEquals(0, view.getTopPaddingOffset());
3236     }
3237 
testIsPaddingOffsetRequired()3238     public void testIsPaddingOffsetRequired() {
3239         MockView view = new MockView(mActivity);
3240         assertFalse(view.isPaddingOffsetRequired());
3241     }
3242 
3243     @UiThreadTest
testPadding()3244     public void testPadding() {
3245         MockView view = (MockView) mActivity.findViewById(R.id.mock_view_padding_full);
3246         Drawable background = view.getBackground();
3247         Rect backgroundPadding = new Rect();
3248         background.getPadding(backgroundPadding);
3249 
3250         // There is some background with a non null padding
3251         assertNotNull(background);
3252         assertTrue(backgroundPadding.left != 0);
3253         assertTrue(backgroundPadding.right != 0);
3254         assertTrue(backgroundPadding.top != 0);
3255         assertTrue(backgroundPadding.bottom != 0);
3256 
3257         // The XML defines android:padding="0dp" and that should be the resulting padding
3258         assertEquals(0, view.getPaddingLeft());
3259         assertEquals(0, view.getPaddingTop());
3260         assertEquals(0, view.getPaddingRight());
3261         assertEquals(0, view.getPaddingBottom());
3262 
3263         // LEFT case
3264         view = (MockView) mActivity.findViewById(R.id.mock_view_padding_left);
3265         background = view.getBackground();
3266         backgroundPadding = new Rect();
3267         background.getPadding(backgroundPadding);
3268 
3269         // There is some background with a non null padding
3270         assertNotNull(background);
3271         assertTrue(backgroundPadding.left != 0);
3272         assertTrue(backgroundPadding.right != 0);
3273         assertTrue(backgroundPadding.top != 0);
3274         assertTrue(backgroundPadding.bottom != 0);
3275 
3276         // The XML defines android:paddingLeft="0dp" and that should be the resulting padding
3277         assertEquals(0, view.getPaddingLeft());
3278         assertEquals(backgroundPadding.top, view.getPaddingTop());
3279         assertEquals(backgroundPadding.right, view.getPaddingRight());
3280         assertEquals(backgroundPadding.bottom, view.getPaddingBottom());
3281 
3282         // RIGHT case
3283         view = (MockView) mActivity.findViewById(R.id.mock_view_padding_right);
3284         background = view.getBackground();
3285         backgroundPadding = new Rect();
3286         background.getPadding(backgroundPadding);
3287 
3288         // There is some background with a non null padding
3289         assertNotNull(background);
3290         assertTrue(backgroundPadding.left != 0);
3291         assertTrue(backgroundPadding.right != 0);
3292         assertTrue(backgroundPadding.top != 0);
3293         assertTrue(backgroundPadding.bottom != 0);
3294 
3295         // The XML defines android:paddingRight="0dp" and that should be the resulting padding
3296         assertEquals(backgroundPadding.left, view.getPaddingLeft());
3297         assertEquals(backgroundPadding.top, view.getPaddingTop());
3298         assertEquals(0, view.getPaddingRight());
3299         assertEquals(backgroundPadding.bottom, view.getPaddingBottom());
3300 
3301         // TOP case
3302         view = (MockView) mActivity.findViewById(R.id.mock_view_padding_top);
3303         background = view.getBackground();
3304         backgroundPadding = new Rect();
3305         background.getPadding(backgroundPadding);
3306 
3307         // There is some background with a non null padding
3308         assertNotNull(background);
3309         assertTrue(backgroundPadding.left != 0);
3310         assertTrue(backgroundPadding.right != 0);
3311         assertTrue(backgroundPadding.top != 0);
3312         assertTrue(backgroundPadding.bottom != 0);
3313 
3314         // The XML defines android:paddingTop="0dp" and that should be the resulting padding
3315         assertEquals(backgroundPadding.left, view.getPaddingLeft());
3316         assertEquals(0, view.getPaddingTop());
3317         assertEquals(backgroundPadding.right, view.getPaddingRight());
3318         assertEquals(backgroundPadding.bottom, view.getPaddingBottom());
3319 
3320         // BOTTOM case
3321         view = (MockView) mActivity.findViewById(R.id.mock_view_padding_bottom);
3322         background = view.getBackground();
3323         backgroundPadding = new Rect();
3324         background.getPadding(backgroundPadding);
3325 
3326         // There is some background with a non null padding
3327         assertNotNull(background);
3328         assertTrue(backgroundPadding.left != 0);
3329         assertTrue(backgroundPadding.right != 0);
3330         assertTrue(backgroundPadding.top != 0);
3331         assertTrue(backgroundPadding.bottom != 0);
3332 
3333         // The XML defines android:paddingBottom="0dp" and that should be the resulting padding
3334         assertEquals(backgroundPadding.left, view.getPaddingLeft());
3335         assertEquals(backgroundPadding.top, view.getPaddingTop());
3336         assertEquals(backgroundPadding.right, view.getPaddingRight());
3337         assertEquals(0, view.getPaddingBottom());
3338 
3339         // Case for interleaved background/padding changes
3340         view = (MockView) mActivity.findViewById(R.id.mock_view_padding_runtime_updated);
3341         background = view.getBackground();
3342         backgroundPadding = new Rect();
3343         background.getPadding(backgroundPadding);
3344 
3345         // There is some background with a null padding
3346         assertNotNull(background);
3347         assertTrue(backgroundPadding.left == 0);
3348         assertTrue(backgroundPadding.right == 0);
3349         assertTrue(backgroundPadding.top == 0);
3350         assertTrue(backgroundPadding.bottom == 0);
3351 
3352         final int paddingLeft = view.getPaddingLeft();
3353         final int paddingRight = view.getPaddingRight();
3354         final int paddingTop = view.getPaddingTop();
3355         final int paddingBottom = view.getPaddingBottom();
3356         assertEquals(8, paddingLeft);
3357         assertEquals(0, paddingTop);
3358         assertEquals(8, paddingRight);
3359         assertEquals(0, paddingBottom);
3360 
3361         // Manipulate background and padding
3362         background.setState(view.getDrawableState());
3363         background.jumpToCurrentState();
3364         view.setBackground(background);
3365         view.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
3366 
3367         assertEquals(8, view.getPaddingLeft());
3368         assertEquals(0, view.getPaddingTop());
3369         assertEquals(8, view.getPaddingRight());
3370         assertEquals(0, view.getPaddingBottom());
3371     }
3372 
testGetWindowVisibleDisplayFrame()3373     public void testGetWindowVisibleDisplayFrame() {
3374         Rect outRect = new Rect();
3375         View view = new View(mActivity);
3376         // mAttachInfo is null
3377         WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
3378         Display d = wm.getDefaultDisplay();
3379         view.getWindowVisibleDisplayFrame(outRect);
3380         assertEquals(0, outRect.left);
3381         assertEquals(0, outRect.top);
3382         assertEquals(d.getWidth(), outRect.right);
3383         assertEquals(d.getHeight(), outRect.bottom);
3384 
3385         // mAttachInfo is not null
3386         outRect = new Rect();
3387         view = mActivity.findViewById(R.id.fit_windows);
3388         // it's implementation detail
3389         view.getWindowVisibleDisplayFrame(outRect);
3390     }
3391 
testSetScrollContainer()3392     public void testSetScrollContainer() throws Throwable {
3393         final MockView mockView = (MockView) mActivity.findViewById(R.id.mock_view);
3394         final MockView scrollView = (MockView) mActivity.findViewById(R.id.scroll_view);
3395         Bitmap bitmap = Bitmap.createBitmap(200, 300, Bitmap.Config.RGB_565);
3396         final BitmapDrawable d = new BitmapDrawable(bitmap);
3397         final InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(
3398                 Context.INPUT_METHOD_SERVICE);
3399         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(300, 500);
3400         runTestOnUiThread(new Runnable() {
3401             @Override
3402             public void run() {
3403                 mockView.setBackgroundDrawable(d);
3404                 mockView.setHorizontalFadingEdgeEnabled(true);
3405                 mockView.setVerticalFadingEdgeEnabled(true);
3406                 mockView.setLayoutParams(layoutParams);
3407                 scrollView.setLayoutParams(layoutParams);
3408 
3409                 mockView.setFocusable(true);
3410                 mockView.requestFocus();
3411                 mockView.setScrollContainer(true);
3412                 scrollView.setScrollContainer(false);
3413                 imm.showSoftInput(mockView, 0);
3414             }
3415         });
3416         getInstrumentation().waitForIdleSync();
3417 
3418         // FIXME: why the size of view doesn't change?
3419 
3420         runTestOnUiThread(new Runnable() {
3421             @Override
3422             public void run() {
3423                 imm.hideSoftInputFromInputMethod(mockView.getWindowToken(), 0);
3424             }
3425         });
3426         getInstrumentation().waitForIdleSync();
3427     }
3428 
testTouchMode()3429     public void testTouchMode() throws Throwable {
3430         final MockView mockView = (MockView) mActivity.findViewById(R.id.mock_view);
3431         final View fitWindowsView = mActivity.findViewById(R.id.fit_windows);
3432         runTestOnUiThread(new Runnable() {
3433             @Override
3434             public void run() {
3435                 mockView.setFocusableInTouchMode(true);
3436                 fitWindowsView.setFocusable(true);
3437                 fitWindowsView.requestFocus();
3438             }
3439         });
3440         getInstrumentation().waitForIdleSync();
3441         assertTrue(mockView.isFocusableInTouchMode());
3442         assertFalse(fitWindowsView.isFocusableInTouchMode());
3443         assertTrue(mockView.isFocusable());
3444         assertTrue(fitWindowsView.isFocusable());
3445         assertFalse(mockView.isFocused());
3446         assertTrue(fitWindowsView.isFocused());
3447         assertFalse(mockView.isInTouchMode());
3448         assertFalse(fitWindowsView.isInTouchMode());
3449 
3450         TouchUtils.tapView(this, mockView);
3451         assertFalse(fitWindowsView.isFocused());
3452         assertFalse(mockView.isFocused());
3453         runTestOnUiThread(new Runnable() {
3454             @Override
3455             public void run() {
3456                 mockView.requestFocus();
3457             }
3458         });
3459         getInstrumentation().waitForIdleSync();
3460         assertTrue(mockView.isFocused());
3461         runTestOnUiThread(new Runnable() {
3462             @Override
3463             public void run() {
3464                 fitWindowsView.requestFocus();
3465             }
3466         });
3467         getInstrumentation().waitForIdleSync();
3468         assertFalse(fitWindowsView.isFocused());
3469         assertTrue(mockView.isInTouchMode());
3470         assertTrue(fitWindowsView.isInTouchMode());
3471 
3472         KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
3473         getInstrumentation().sendKeySync(keyEvent);
3474         assertTrue(mockView.isFocused());
3475         assertFalse(fitWindowsView.isFocused());
3476         runTestOnUiThread(new Runnable() {
3477             @Override
3478             public void run() {
3479                 fitWindowsView.requestFocus();
3480             }
3481         });
3482         getInstrumentation().waitForIdleSync();
3483         assertFalse(mockView.isFocused());
3484         assertTrue(fitWindowsView.isFocused());
3485         assertFalse(mockView.isInTouchMode());
3486         assertFalse(fitWindowsView.isInTouchMode());
3487     }
3488 
3489     @UiThreadTest
testScrollbarStyle()3490     public void testScrollbarStyle() {
3491         MockView view = (MockView) mActivity.findViewById(R.id.scroll_view);
3492         Bitmap bitmap = Bitmap.createBitmap(200, 300, Bitmap.Config.RGB_565);
3493         BitmapDrawable d = new BitmapDrawable(bitmap);
3494         view.setBackgroundDrawable(d);
3495         view.setHorizontalFadingEdgeEnabled(true);
3496         view.setVerticalFadingEdgeEnabled(true);
3497 
3498         assertTrue(view.isHorizontalScrollBarEnabled());
3499         assertTrue(view.isVerticalScrollBarEnabled());
3500         int verticalScrollBarWidth = view.getVerticalScrollbarWidth();
3501         int horizontalScrollBarHeight = view.getHorizontalScrollbarHeight();
3502         assertTrue(verticalScrollBarWidth > 0);
3503         assertTrue(horizontalScrollBarHeight > 0);
3504         assertEquals(0, view.getPaddingRight());
3505         assertEquals(0, view.getPaddingBottom());
3506 
3507         view.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
3508         assertEquals(View.SCROLLBARS_INSIDE_INSET, view.getScrollBarStyle());
3509         assertEquals(verticalScrollBarWidth, view.getPaddingRight());
3510         assertEquals(horizontalScrollBarHeight, view.getPaddingBottom());
3511 
3512         view.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
3513         assertEquals(View.SCROLLBARS_OUTSIDE_OVERLAY, view.getScrollBarStyle());
3514         assertEquals(0, view.getPaddingRight());
3515         assertEquals(0, view.getPaddingBottom());
3516 
3517         view.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET);
3518         assertEquals(View.SCROLLBARS_OUTSIDE_INSET, view.getScrollBarStyle());
3519         assertEquals(verticalScrollBarWidth, view.getPaddingRight());
3520         assertEquals(horizontalScrollBarHeight, view.getPaddingBottom());
3521 
3522         // TODO: how to get the position of the Scrollbar to assert it is inside or outside.
3523     }
3524 
3525     @UiThreadTest
testScrollFading()3526     public void testScrollFading() {
3527         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
3528         Bitmap bitmap = Bitmap.createBitmap(200, 300, Bitmap.Config.RGB_565);
3529         BitmapDrawable d = new BitmapDrawable(bitmap);
3530         view.setBackgroundDrawable(d);
3531 
3532         assertFalse(view.isHorizontalFadingEdgeEnabled());
3533         assertFalse(view.isVerticalFadingEdgeEnabled());
3534         assertEquals(0, view.getHorizontalFadingEdgeLength());
3535         assertEquals(0, view.getVerticalFadingEdgeLength());
3536 
3537         view.setHorizontalFadingEdgeEnabled(true);
3538         view.setVerticalFadingEdgeEnabled(true);
3539         assertTrue(view.isHorizontalFadingEdgeEnabled());
3540         assertTrue(view.isVerticalFadingEdgeEnabled());
3541         assertTrue(view.getHorizontalFadingEdgeLength() > 0);
3542         assertTrue(view.getVerticalFadingEdgeLength() > 0);
3543 
3544         final int fadingLength = 20;
3545         view.setFadingEdgeLength(fadingLength);
3546         assertEquals(fadingLength, view.getHorizontalFadingEdgeLength());
3547         assertEquals(fadingLength, view.getVerticalFadingEdgeLength());
3548     }
3549 
3550     @UiThreadTest
testScrolling()3551     public void testScrolling() {
3552         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
3553         view.reset();
3554         assertEquals(0, view.getScrollX());
3555         assertEquals(0, view.getScrollY());
3556         assertFalse(view.hasCalledOnScrollChanged());
3557 
3558         view.scrollTo(0, 0);
3559         assertEquals(0, view.getScrollX());
3560         assertEquals(0, view.getScrollY());
3561         assertFalse(view.hasCalledOnScrollChanged());
3562 
3563         view.scrollBy(0, 0);
3564         assertEquals(0, view.getScrollX());
3565         assertEquals(0, view.getScrollY());
3566         assertFalse(view.hasCalledOnScrollChanged());
3567 
3568         view.scrollTo(10, 100);
3569         assertEquals(10, view.getScrollX());
3570         assertEquals(100, view.getScrollY());
3571         assertTrue(view.hasCalledOnScrollChanged());
3572 
3573         view.reset();
3574         assertFalse(view.hasCalledOnScrollChanged());
3575         view.scrollBy(-10, -100);
3576         assertEquals(0, view.getScrollX());
3577         assertEquals(0, view.getScrollY());
3578         assertTrue(view.hasCalledOnScrollChanged());
3579 
3580         view.reset();
3581         assertFalse(view.hasCalledOnScrollChanged());
3582         view.scrollTo(-1, -2);
3583         assertEquals(-1, view.getScrollX());
3584         assertEquals(-2, view.getScrollY());
3585         assertTrue(view.hasCalledOnScrollChanged());
3586     }
3587 
testInitializeScrollbarsAndFadingEdge()3588     public void testInitializeScrollbarsAndFadingEdge() {
3589         MockView view = (MockView) mActivity.findViewById(R.id.scroll_view);
3590 
3591         assertTrue(view.isHorizontalScrollBarEnabled());
3592         assertTrue(view.isVerticalScrollBarEnabled());
3593         assertFalse(view.isHorizontalFadingEdgeEnabled());
3594         assertFalse(view.isVerticalFadingEdgeEnabled());
3595 
3596         view = (MockView) mActivity.findViewById(R.id.scroll_view_2);
3597         final int fadingEdgeLength = 20;
3598 
3599         assertTrue(view.isHorizontalScrollBarEnabled());
3600         assertTrue(view.isVerticalScrollBarEnabled());
3601         assertTrue(view.isHorizontalFadingEdgeEnabled());
3602         assertTrue(view.isVerticalFadingEdgeEnabled());
3603         assertEquals(fadingEdgeLength, view.getHorizontalFadingEdgeLength());
3604         assertEquals(fadingEdgeLength, view.getVerticalFadingEdgeLength());
3605     }
3606 
3607     @UiThreadTest
testScrollIndicators()3608     public void testScrollIndicators() {
3609         MockView view = (MockView) mActivity.findViewById(R.id.scroll_view);
3610 
3611         assertEquals("Set indicators match those specified in XML",
3612                 View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM,
3613                 view.getScrollIndicators());
3614 
3615         view.setScrollIndicators(0);
3616         assertEquals("Cleared indicators", 0, view.getScrollIndicators());
3617 
3618         view.setScrollIndicators(View.SCROLL_INDICATOR_START | View.SCROLL_INDICATOR_RIGHT);
3619         assertEquals("Set start and right indicators",
3620                 View.SCROLL_INDICATOR_START | View.SCROLL_INDICATOR_RIGHT,
3621                 view.getScrollIndicators());
3622 
3623     }
3624 
testOnStartAndFinishTemporaryDetach()3625     public void testOnStartAndFinishTemporaryDetach() throws Throwable {
3626         final AtomicBoolean exitedDispatchStartTemporaryDetach = new AtomicBoolean(false);
3627         final AtomicBoolean exitedDispatchFinishTemporaryDetach = new AtomicBoolean(false);
3628 
3629         final View view = new View(mActivity) {
3630             private boolean mEnteredDispatchStartTemporaryDetach = false;
3631             private boolean mExitedDispatchStartTemporaryDetach = false;
3632             private boolean mEnteredDispatchFinishTemporaryDetach = false;
3633             private boolean mExitedDispatchFinishTemporaryDetach = false;
3634 
3635             private boolean mCalledOnStartTemporaryDetach = false;
3636             private boolean mCalledOnFinishTemporaryDetach = false;
3637 
3638             @Override
3639             public void dispatchStartTemporaryDetach() {
3640                 assertFalse(mEnteredDispatchStartTemporaryDetach);
3641                 assertFalse(mExitedDispatchStartTemporaryDetach);
3642                 assertFalse(mEnteredDispatchFinishTemporaryDetach);
3643                 assertFalse(mExitedDispatchFinishTemporaryDetach);
3644                 assertFalse(mCalledOnStartTemporaryDetach);
3645                 assertFalse(mCalledOnFinishTemporaryDetach);
3646                 mEnteredDispatchStartTemporaryDetach = true;
3647 
3648                 assertFalse(isTemporarilyDetached());
3649 
3650                 super.dispatchStartTemporaryDetach();
3651 
3652                 assertTrue(isTemporarilyDetached());
3653 
3654                 assertTrue(mEnteredDispatchStartTemporaryDetach);
3655                 assertFalse(mExitedDispatchStartTemporaryDetach);
3656                 assertFalse(mEnteredDispatchFinishTemporaryDetach);
3657                 assertFalse(mExitedDispatchFinishTemporaryDetach);
3658                 assertTrue(mCalledOnStartTemporaryDetach);
3659                 assertFalse(mCalledOnFinishTemporaryDetach);
3660                 mExitedDispatchStartTemporaryDetach = true;
3661                 exitedDispatchStartTemporaryDetach.set(true);
3662             }
3663 
3664             @Override
3665             public void dispatchFinishTemporaryDetach() {
3666                 assertTrue(mEnteredDispatchStartTemporaryDetach);
3667                 assertTrue(mExitedDispatchStartTemporaryDetach);
3668                 assertFalse(mEnteredDispatchFinishTemporaryDetach);
3669                 assertFalse(mExitedDispatchFinishTemporaryDetach);
3670                 assertTrue(mCalledOnStartTemporaryDetach);
3671                 assertFalse(mCalledOnFinishTemporaryDetach);
3672                 mEnteredDispatchFinishTemporaryDetach = true;
3673 
3674                 assertTrue(isTemporarilyDetached());
3675 
3676                 super.dispatchFinishTemporaryDetach();
3677 
3678                 assertFalse(isTemporarilyDetached());
3679 
3680                 assertTrue(mEnteredDispatchStartTemporaryDetach);
3681                 assertTrue(mExitedDispatchStartTemporaryDetach);
3682                 assertTrue(mEnteredDispatchFinishTemporaryDetach);
3683                 assertFalse(mExitedDispatchFinishTemporaryDetach);
3684                 assertTrue(mCalledOnStartTemporaryDetach);
3685                 assertTrue(mCalledOnFinishTemporaryDetach);
3686                 mExitedDispatchFinishTemporaryDetach = true;
3687                 exitedDispatchFinishTemporaryDetach.set(true);
3688             }
3689 
3690             @Override
3691             public void onStartTemporaryDetach() {
3692                 assertTrue(mEnteredDispatchStartTemporaryDetach);
3693                 assertFalse(mExitedDispatchStartTemporaryDetach);
3694                 assertFalse(mEnteredDispatchFinishTemporaryDetach);
3695                 assertFalse(mExitedDispatchFinishTemporaryDetach);
3696                 assertFalse(mCalledOnStartTemporaryDetach);
3697                 assertFalse(mCalledOnFinishTemporaryDetach);
3698 
3699                 assertTrue(isTemporarilyDetached());
3700 
3701                 mCalledOnStartTemporaryDetach = true;
3702             }
3703 
3704             @Override
3705             public void onFinishTemporaryDetach() {
3706                 assertTrue(mEnteredDispatchStartTemporaryDetach);
3707                 assertTrue(mExitedDispatchStartTemporaryDetach);
3708                 assertTrue(mEnteredDispatchFinishTemporaryDetach);
3709                 assertFalse(mExitedDispatchFinishTemporaryDetach);
3710                 assertTrue(mCalledOnStartTemporaryDetach);
3711                 assertFalse(mCalledOnFinishTemporaryDetach);
3712 
3713                 assertFalse(isTemporarilyDetached());
3714 
3715                 mCalledOnFinishTemporaryDetach = true;
3716             }
3717         };
3718 
3719         assertFalse(view.isTemporarilyDetached());
3720 
3721         runTestOnUiThread(new Runnable() {
3722             @Override
3723             public void run() {
3724                 view.dispatchStartTemporaryDetach();
3725             }
3726         });
3727         getInstrumentation().waitForIdleSync();
3728 
3729         assertTrue(view.isTemporarilyDetached());
3730         assertTrue(exitedDispatchStartTemporaryDetach.get());
3731         assertFalse(exitedDispatchFinishTemporaryDetach.get());
3732 
3733         runTestOnUiThread(new Runnable() {
3734             @Override
3735             public void run() {
3736                 view.dispatchFinishTemporaryDetach();
3737             }
3738         });
3739         getInstrumentation().waitForIdleSync();
3740 
3741         assertFalse(view.isTemporarilyDetached());
3742         assertTrue(exitedDispatchStartTemporaryDetach.get());
3743         assertTrue(exitedDispatchFinishTemporaryDetach.get());
3744     }
3745 
testKeyPreIme()3746     public void testKeyPreIme() throws Throwable {
3747         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
3748 
3749         runTestOnUiThread(new Runnable() {
3750             @Override
3751             public void run() {
3752                 view.setFocusable(true);
3753                 view.requestFocus();
3754             }
3755         });
3756         getInstrumentation().waitForIdleSync();
3757 
3758         getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
3759         assertTrue(view.hasCalledDispatchKeyEventPreIme());
3760         assertTrue(view.hasCalledOnKeyPreIme());
3761     }
3762 
testHapticFeedback()3763     public void testHapticFeedback() {
3764         Vibrator vib = (Vibrator) mActivity.getSystemService(Context.VIBRATOR_SERVICE);
3765         boolean hasVibrator = vib.hasVibrator();
3766 
3767         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
3768         final int LONG_PRESS = HapticFeedbackConstants.LONG_PRESS;
3769         final int FLAG_IGNORE_VIEW_SETTING = HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING;
3770         final int FLAG_IGNORE_GLOBAL_SETTING = HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
3771         final int ALWAYS = FLAG_IGNORE_VIEW_SETTING | FLAG_IGNORE_GLOBAL_SETTING;
3772 
3773         view.setHapticFeedbackEnabled(false);
3774         assertFalse(view.isHapticFeedbackEnabled());
3775         assertFalse(view.performHapticFeedback(LONG_PRESS));
3776         assertFalse(view.performHapticFeedback(LONG_PRESS, FLAG_IGNORE_GLOBAL_SETTING));
3777         assertEquals(hasVibrator, view.performHapticFeedback(LONG_PRESS, ALWAYS));
3778 
3779         view.setHapticFeedbackEnabled(true);
3780         assertTrue(view.isHapticFeedbackEnabled());
3781         assertEquals(hasVibrator, view.performHapticFeedback(LONG_PRESS, FLAG_IGNORE_GLOBAL_SETTING));
3782     }
3783 
testInputConnection()3784     public void testInputConnection() throws Throwable {
3785         final InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(
3786                 Context.INPUT_METHOD_SERVICE);
3787         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
3788         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
3789         final MockEditText editText = new MockEditText(mActivity);
3790 
3791         runTestOnUiThread(new Runnable() {
3792             @Override
3793             public void run() {
3794                 viewGroup.addView(editText);
3795                 editText.requestFocus();
3796             }
3797         });
3798         getInstrumentation().waitForIdleSync();
3799         assertTrue(editText.isFocused());
3800 
3801         runTestOnUiThread(new Runnable() {
3802             @Override
3803             public void run() {
3804                 imm.showSoftInput(editText, 0);
3805             }
3806         });
3807         getInstrumentation().waitForIdleSync();
3808 
3809         new PollingCheck(TIMEOUT_DELTA) {
3810             @Override
3811             protected boolean check() {
3812                 return editText.hasCalledOnCreateInputConnection();
3813             }
3814         }.run();
3815 
3816         assertTrue(editText.hasCalledOnCheckIsTextEditor());
3817 
3818         runTestOnUiThread(new Runnable() {
3819             @Override
3820             public void run() {
3821                 assertTrue(imm.isActive(editText));
3822                 assertFalse(editText.hasCalledCheckInputConnectionProxy());
3823                 imm.isActive(view);
3824                 assertTrue(editText.hasCalledCheckInputConnectionProxy());
3825             }
3826         });
3827     }
3828 
testFilterTouchesWhenObscured()3829     public void testFilterTouchesWhenObscured() throws Throwable {
3830         OnTouchListenerImpl touchListener = new OnTouchListenerImpl();
3831         View view = new View(mActivity);
3832         view.setOnTouchListener(touchListener);
3833 
3834         MotionEvent.PointerProperties[] props = new MotionEvent.PointerProperties[] {
3835                 new MotionEvent.PointerProperties()
3836         };
3837         MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[] {
3838                 new MotionEvent.PointerCoords()
3839         };
3840         MotionEvent obscuredTouch = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN,
3841                 1, props, coords, 0, 0, 0, 0, -1, 0, InputDevice.SOURCE_TOUCHSCREEN,
3842                 MotionEvent.FLAG_WINDOW_IS_OBSCURED);
3843         MotionEvent unobscuredTouch = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN,
3844                 1, props, coords, 0, 0, 0, 0, -1, 0, InputDevice.SOURCE_TOUCHSCREEN,
3845                 0);
3846 
3847         // Initially filter touches is false so all touches are dispatched.
3848         assertFalse(view.getFilterTouchesWhenObscured());
3849 
3850         view.dispatchTouchEvent(unobscuredTouch);
3851         assertTrue(touchListener.hasOnTouch());
3852         touchListener.reset();
3853         view.dispatchTouchEvent(obscuredTouch);
3854         assertTrue(touchListener.hasOnTouch());
3855         touchListener.reset();
3856 
3857         // Set filter touches to true so only unobscured touches are dispatched.
3858         view.setFilterTouchesWhenObscured(true);
3859         assertTrue(view.getFilterTouchesWhenObscured());
3860 
3861         view.dispatchTouchEvent(unobscuredTouch);
3862         assertTrue(touchListener.hasOnTouch());
3863         touchListener.reset();
3864         view.dispatchTouchEvent(obscuredTouch);
3865         assertFalse(touchListener.hasOnTouch());
3866         touchListener.reset();
3867 
3868         // Set filter touches to false so all touches are dispatched.
3869         view.setFilterTouchesWhenObscured(false);
3870         assertFalse(view.getFilterTouchesWhenObscured());
3871 
3872         view.dispatchTouchEvent(unobscuredTouch);
3873         assertTrue(touchListener.hasOnTouch());
3874         touchListener.reset();
3875         view.dispatchTouchEvent(obscuredTouch);
3876         assertTrue(touchListener.hasOnTouch());
3877         touchListener.reset();
3878     }
3879 
testBackgroundTint()3880     public void testBackgroundTint() {
3881         View inflatedView = mActivity.findViewById(R.id.background_tint);
3882 
3883         assertEquals("Background tint inflated correctly",
3884                 Color.WHITE, inflatedView.getBackgroundTintList().getDefaultColor());
3885         assertEquals("Background tint mode inflated correctly",
3886                 PorterDuff.Mode.SRC_OVER, inflatedView.getBackgroundTintMode());
3887 
3888         MockDrawable bg = new MockDrawable();
3889         View view = new View(mActivity);
3890 
3891         view.setBackground(bg);
3892         assertFalse("No background tint applied by default", bg.hasCalledSetTint());
3893 
3894         view.setBackgroundTintList(ColorStateList.valueOf(Color.WHITE));
3895         assertTrue("Background tint applied when setBackgroundTints() called after setBackground()",
3896                 bg.hasCalledSetTint());
3897 
3898         bg.reset();
3899         view.setBackground(null);
3900         view.setBackground(bg);
3901         assertTrue("Background tint applied when setBackgroundTints() called before setBackground()",
3902                 bg.hasCalledSetTint());
3903     }
3904 
testStartActionModeWithParent()3905     public void testStartActionModeWithParent() {
3906         View view = new View(mActivity);
3907         MockViewGroup parent = new MockViewGroup(mActivity);
3908         parent.addView(view);
3909 
3910         ActionMode mode = view.startActionMode(null);
3911 
3912         assertNotNull(mode);
3913         assertEquals(NO_OP_ACTION_MODE, mode);
3914         assertTrue(parent.isStartActionModeForChildCalled);
3915         assertEquals(ActionMode.TYPE_PRIMARY, parent.startActionModeForChildType);
3916     }
3917 
testStartActionModeWithoutParent()3918     public void testStartActionModeWithoutParent() {
3919         View view = new View(mActivity);
3920 
3921         ActionMode mode = view.startActionMode(null);
3922 
3923         assertNull(mode);
3924     }
3925 
testStartActionModeTypedWithParent()3926     public void testStartActionModeTypedWithParent() {
3927         View view = new View(mActivity);
3928         MockViewGroup parent = new MockViewGroup(mActivity);
3929         parent.addView(view);
3930 
3931         ActionMode mode = view.startActionMode(null, ActionMode.TYPE_FLOATING);
3932 
3933         assertNotNull(mode);
3934         assertEquals(NO_OP_ACTION_MODE, mode);
3935         assertTrue(parent.isStartActionModeForChildCalled);
3936         assertEquals(ActionMode.TYPE_FLOATING, parent.startActionModeForChildType);
3937     }
3938 
testStartActionModeTypedWithoutParent()3939     public void testStartActionModeTypedWithoutParent() {
3940         View view = new View(mActivity);
3941 
3942         ActionMode mode = view.startActionMode(null, ActionMode.TYPE_FLOATING);
3943 
3944         assertNull(mode);
3945     }
3946 
testVisibilityAggregated()3947     public void testVisibilityAggregated() throws Throwable {
3948         final View grandparent = mActivity.findViewById(R.id.viewlayout_root);
3949         final View parent = mActivity.findViewById(R.id.aggregate_visibility_parent);
3950         final MockView mv = (MockView) mActivity.findViewById(R.id.mock_view_aggregate_visibility);
3951 
3952         assertEquals(parent, mv.getParent());
3953         assertEquals(grandparent, parent.getParent());
3954 
3955         assertTrue(mv.hasCalledOnVisibilityAggregated());
3956         assertTrue(mv.getLastAggregatedVisibility());
3957 
3958         final Runnable reset = new Runnable() {
3959             @Override
3960             public void run() {
3961                 grandparent.setVisibility(View.VISIBLE);
3962                 parent.setVisibility(View.VISIBLE);
3963                 mv.setVisibility(View.VISIBLE);
3964                 mv.reset();
3965             }
3966         };
3967 
3968         runTestOnUiThread(reset);
3969 
3970         setVisibilityOnUiThread(parent, View.GONE);
3971 
3972         assertTrue(mv.hasCalledOnVisibilityAggregated());
3973         assertFalse(mv.getLastAggregatedVisibility());
3974 
3975         runTestOnUiThread(reset);
3976 
3977         setVisibilityOnUiThread(grandparent, View.GONE);
3978 
3979         assertTrue(mv.hasCalledOnVisibilityAggregated());
3980         assertFalse(mv.getLastAggregatedVisibility());
3981 
3982         runTestOnUiThread(reset);
3983         runTestOnUiThread(new Runnable() {
3984             @Override
3985             public void run() {
3986                 grandparent.setVisibility(View.GONE);
3987                 parent.setVisibility(View.GONE);
3988                 mv.setVisibility(View.VISIBLE);
3989 
3990                 grandparent.setVisibility(View.VISIBLE);
3991             }
3992         });
3993 
3994         assertTrue(mv.hasCalledOnVisibilityAggregated());
3995         assertFalse(mv.getLastAggregatedVisibility());
3996 
3997         runTestOnUiThread(reset);
3998         runTestOnUiThread(new Runnable() {
3999             @Override
4000             public void run() {
4001                 grandparent.setVisibility(View.GONE);
4002                 parent.setVisibility(View.INVISIBLE);
4003 
4004                 grandparent.setVisibility(View.VISIBLE);
4005             }
4006         });
4007 
4008         assertTrue(mv.hasCalledOnVisibilityAggregated());
4009         assertFalse(mv.getLastAggregatedVisibility());
4010 
4011         runTestOnUiThread(new Runnable() {
4012             @Override
4013             public void run() {
4014                 parent.setVisibility(View.VISIBLE);
4015             }
4016         });
4017 
4018         assertTrue(mv.getLastAggregatedVisibility());
4019     }
4020 
testOverlappingRendering()4021     public void testOverlappingRendering() {
4022         View overlappingUnsetView = mActivity.findViewById(R.id.overlapping_rendering_unset);
4023         View overlappingFalseView = mActivity.findViewById(R.id.overlapping_rendering_false);
4024         View overlappingTrueView = mActivity.findViewById(R.id.overlapping_rendering_true);
4025 
4026         assertTrue(overlappingUnsetView.hasOverlappingRendering());
4027         assertTrue(overlappingUnsetView.getHasOverlappingRendering());
4028         overlappingUnsetView.forceHasOverlappingRendering(false);
4029         assertTrue(overlappingUnsetView.hasOverlappingRendering());
4030         assertFalse(overlappingUnsetView.getHasOverlappingRendering());
4031         overlappingUnsetView.forceHasOverlappingRendering(true);
4032         assertTrue(overlappingUnsetView.hasOverlappingRendering());
4033         assertTrue(overlappingUnsetView.getHasOverlappingRendering());
4034 
4035         assertTrue(overlappingTrueView.hasOverlappingRendering());
4036         assertTrue(overlappingTrueView.getHasOverlappingRendering());
4037 
4038         assertTrue(overlappingFalseView.hasOverlappingRendering());
4039         assertFalse(overlappingFalseView.getHasOverlappingRendering());
4040 
4041         View overridingView = new MockOverlappingRenderingSubclass(mActivity, false);
4042         assertFalse(overridingView.hasOverlappingRendering());
4043 
4044         overridingView = new MockOverlappingRenderingSubclass(mActivity, true);
4045         assertTrue(overridingView.hasOverlappingRendering());
4046         overridingView.forceHasOverlappingRendering(false);
4047         assertFalse(overridingView.getHasOverlappingRendering());
4048         assertTrue(overridingView.hasOverlappingRendering());
4049         overridingView.forceHasOverlappingRendering(true);
4050         assertTrue(overridingView.getHasOverlappingRendering());
4051         assertTrue(overridingView.hasOverlappingRendering());
4052     }
4053 
setVisibilityOnUiThread(final View view, final int visibility)4054     private void setVisibilityOnUiThread(final View view, final int visibility) throws Throwable {
4055         runTestOnUiThread(new Runnable() {
4056             @Override
4057             public void run() {
4058                 view.setVisibility(visibility);
4059             }
4060         });
4061     }
4062 
4063     private static class MockOverlappingRenderingSubclass extends View {
4064         boolean mOverlap;
4065 
MockOverlappingRenderingSubclass(Context context, boolean overlap)4066         public MockOverlappingRenderingSubclass(Context context, boolean overlap) {
4067             super(context);
4068             mOverlap = overlap;
4069         }
4070 
4071         @Override
hasOverlappingRendering()4072         public boolean hasOverlappingRendering() {
4073             return mOverlap;
4074         }
4075     }
4076 
4077     private static class MockViewGroup extends ViewGroup {
4078         boolean isStartActionModeForChildCalled = false;
4079         int startActionModeForChildType = ActionMode.TYPE_PRIMARY;
4080 
MockViewGroup(Context context)4081         public MockViewGroup(Context context) {
4082             super(context);
4083         }
4084 
4085         @Override
startActionModeForChild(View originalView, ActionMode.Callback callback)4086         public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
4087             isStartActionModeForChildCalled = true;
4088             startActionModeForChildType = ActionMode.TYPE_PRIMARY;
4089             return NO_OP_ACTION_MODE;
4090         }
4091 
4092         @Override
startActionModeForChild( View originalView, ActionMode.Callback callback, int type)4093         public ActionMode startActionModeForChild(
4094                 View originalView, ActionMode.Callback callback, int type) {
4095             isStartActionModeForChildCalled = true;
4096             startActionModeForChildType = type;
4097             return NO_OP_ACTION_MODE;
4098         }
4099 
4100         @Override
onLayout(boolean changed, int l, int t, int r, int b)4101         protected void onLayout(boolean changed, int l, int t, int r, int b) {
4102             // no-op
4103         }
4104     }
4105 
4106     private static final ActionMode NO_OP_ACTION_MODE =
4107             new ActionMode() {
4108                 @Override
4109                 public void setTitle(CharSequence title) {}
4110 
4111                 @Override
4112                 public void setTitle(int resId) {}
4113 
4114                 @Override
4115                 public void setSubtitle(CharSequence subtitle) {}
4116 
4117                 @Override
4118                 public void setSubtitle(int resId) {}
4119 
4120                 @Override
4121                 public void setCustomView(View view) {}
4122 
4123                 @Override
4124                 public void invalidate() {}
4125 
4126                 @Override
4127                 public void finish() {}
4128 
4129                 @Override
4130                 public Menu getMenu() {
4131                     return null;
4132                 }
4133 
4134                 @Override
4135                 public CharSequence getTitle() {
4136                     return null;
4137                 }
4138 
4139                 @Override
4140                 public CharSequence getSubtitle() {
4141                     return null;
4142                 }
4143 
4144                 @Override
4145                 public View getCustomView() {
4146                     return null;
4147                 }
4148 
4149                 @Override
4150                 public MenuInflater getMenuInflater() {
4151                     return null;
4152                 }
4153             };
4154 
testTranslationSetter()4155     public void testTranslationSetter() {
4156         View view = new View(mActivity);
4157         float offset = 10.0f;
4158         view.setTranslationX(offset);
4159         view.setTranslationY(offset);
4160         view.setTranslationZ(offset);
4161         view.setElevation(offset);
4162 
4163         assertEquals("Incorrect translationX", offset, view.getTranslationX());
4164         assertEquals("Incorrect translationY", offset, view.getTranslationY());
4165         assertEquals("Incorrect translationZ", offset, view.getTranslationZ());
4166         assertEquals("Incorrect elevation", offset, view.getElevation());
4167     }
4168 
testXYZ()4169     public void testXYZ() {
4170         View view = new View(mActivity);
4171         float offset = 10.0f;
4172         float start = 15.0f;
4173         view.setTranslationX(offset);
4174         view.setLeft((int) start);
4175         view.setTranslationY(offset);
4176         view.setTop((int) start);
4177         view.setTranslationZ(offset);
4178         view.setElevation(start);
4179 
4180         assertEquals("Incorrect X value", offset + start, view.getX());
4181         assertEquals("Incorrect Y value", offset + start, view.getY());
4182         assertEquals("Incorrect Z value", offset + start, view.getZ());
4183     }
4184 
4185     private static class MockDrawable extends Drawable {
4186         private boolean mCalledSetTint = false;
4187 
4188         @Override
draw(Canvas canvas)4189         public void draw(Canvas canvas) {}
4190 
4191         @Override
setAlpha(int alpha)4192         public void setAlpha(int alpha) {}
4193 
4194         @Override
setColorFilter(ColorFilter cf)4195         public void setColorFilter(ColorFilter cf) {}
4196 
4197         @Override
getOpacity()4198         public int getOpacity() {
4199             return 0;
4200         }
4201 
4202         @Override
setTintList(ColorStateList tint)4203         public void setTintList(ColorStateList tint) {
4204             super.setTintList(tint);
4205             mCalledSetTint = true;
4206         }
4207 
hasCalledSetTint()4208         public boolean hasCalledSetTint() {
4209             return mCalledSetTint;
4210         }
4211 
reset()4212         public void reset() {
4213             mCalledSetTint = false;
4214         }
4215     }
4216 
4217     private static class MockEditText extends EditText {
4218         private boolean mCalledCheckInputConnectionProxy = false;
4219         private boolean mCalledOnCreateInputConnection = false;
4220         private boolean mCalledOnCheckIsTextEditor = false;
4221 
MockEditText(Context context)4222         public MockEditText(Context context) {
4223             super(context);
4224         }
4225 
4226         @Override
checkInputConnectionProxy(View view)4227         public boolean checkInputConnectionProxy(View view) {
4228             mCalledCheckInputConnectionProxy = true;
4229             return super.checkInputConnectionProxy(view);
4230         }
4231 
hasCalledCheckInputConnectionProxy()4232         public boolean hasCalledCheckInputConnectionProxy() {
4233             return mCalledCheckInputConnectionProxy;
4234         }
4235 
4236         @Override
onCreateInputConnection(EditorInfo outAttrs)4237         public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
4238             mCalledOnCreateInputConnection = true;
4239             return super.onCreateInputConnection(outAttrs);
4240         }
4241 
hasCalledOnCreateInputConnection()4242         public boolean hasCalledOnCreateInputConnection() {
4243             return mCalledOnCreateInputConnection;
4244         }
4245 
4246         @Override
onCheckIsTextEditor()4247         public boolean onCheckIsTextEditor() {
4248             mCalledOnCheckIsTextEditor = true;
4249             return super.onCheckIsTextEditor();
4250         }
4251 
hasCalledOnCheckIsTextEditor()4252         public boolean hasCalledOnCheckIsTextEditor() {
4253             return mCalledOnCheckIsTextEditor;
4254         }
4255 
reset()4256         public void reset() {
4257             mCalledCheckInputConnectionProxy = false;
4258             mCalledOnCreateInputConnection = false;
4259             mCalledOnCheckIsTextEditor = false;
4260         }
4261     }
4262 
4263     private final static class MockViewParent extends ViewGroup {
4264         private boolean mHasRequestLayout = false;
4265         private boolean mHasCreateContextMenu = false;
4266         private boolean mHasShowContextMenuForChild = false;
4267         private boolean mHasShowContextMenuForChildXY = false;
4268         private boolean mHasChildDrawableStateChanged = false;
4269         private boolean mHasBroughtChildToFront = false;
4270 
4271         private final static int[] DEFAULT_PARENT_STATE_SET = new int[] { 789 };
4272 
4273         @Override
requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate)4274         public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
4275                 boolean immediate) {
4276             return false;
4277         }
4278 
MockViewParent(Context context)4279         public MockViewParent(Context context) {
4280             super(context);
4281         }
4282 
4283         @Override
bringChildToFront(View child)4284         public void bringChildToFront(View child) {
4285             mHasBroughtChildToFront = true;
4286         }
4287 
hasBroughtChildToFront()4288         public boolean hasBroughtChildToFront() {
4289             return mHasBroughtChildToFront;
4290         }
4291 
4292         @Override
childDrawableStateChanged(View child)4293         public void childDrawableStateChanged(View child) {
4294             mHasChildDrawableStateChanged = true;
4295         }
4296 
hasChildDrawableStateChanged()4297         public boolean hasChildDrawableStateChanged() {
4298             return mHasChildDrawableStateChanged;
4299         }
4300 
4301         @Override
dispatchSetPressed(boolean pressed)4302         public void dispatchSetPressed(boolean pressed) {
4303             super.dispatchSetPressed(pressed);
4304         }
4305 
4306         @Override
dispatchSetSelected(boolean selected)4307         public void dispatchSetSelected(boolean selected) {
4308             super.dispatchSetSelected(selected);
4309         }
4310 
4311         @Override
clearChildFocus(View child)4312         public void clearChildFocus(View child) {
4313 
4314         }
4315 
4316         @Override
createContextMenu(ContextMenu menu)4317         public void createContextMenu(ContextMenu menu) {
4318             mHasCreateContextMenu = true;
4319         }
4320 
hasCreateContextMenu()4321         public boolean hasCreateContextMenu() {
4322             return mHasCreateContextMenu;
4323         }
4324 
4325         @Override
focusSearch(View v, int direction)4326         public View focusSearch(View v, int direction) {
4327             return v;
4328         }
4329 
4330         @Override
focusableViewAvailable(View v)4331         public void focusableViewAvailable(View v) {
4332 
4333         }
4334 
4335         @Override
getChildVisibleRect(View child, Rect r, Point offset)4336         public boolean getChildVisibleRect(View child, Rect r, Point offset) {
4337             return false;
4338         }
4339 
4340         @Override
onLayout(boolean changed, int l, int t, int r, int b)4341         protected void onLayout(boolean changed, int l, int t, int r, int b) {
4342 
4343         }
4344 
4345         @Override
invalidateChildInParent(int[] location, Rect r)4346         public ViewParent invalidateChildInParent(int[] location, Rect r) {
4347             return null;
4348         }
4349 
4350         @Override
isLayoutRequested()4351         public boolean isLayoutRequested() {
4352             return false;
4353         }
4354 
4355         @Override
recomputeViewAttributes(View child)4356         public void recomputeViewAttributes(View child) {
4357 
4358         }
4359 
4360         @Override
requestChildFocus(View child, View focused)4361         public void requestChildFocus(View child, View focused) {
4362 
4363         }
4364 
4365         @Override
requestDisallowInterceptTouchEvent(boolean disallowIntercept)4366         public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
4367 
4368         }
4369 
4370         @Override
requestLayout()4371         public void requestLayout() {
4372             mHasRequestLayout = true;
4373         }
4374 
hasRequestLayout()4375         public boolean hasRequestLayout() {
4376             return mHasRequestLayout;
4377         }
4378 
4379         @Override
requestTransparentRegion(View child)4380         public void requestTransparentRegion(View child) {
4381 
4382         }
4383 
4384         @Override
showContextMenuForChild(View originalView)4385         public boolean showContextMenuForChild(View originalView) {
4386             mHasShowContextMenuForChild = true;
4387             return false;
4388         }
4389 
4390         @Override
showContextMenuForChild(View originalView, float x, float y)4391         public boolean showContextMenuForChild(View originalView, float x, float y) {
4392             mHasShowContextMenuForChildXY = true;
4393             return false;
4394         }
4395 
4396         @Override
startActionModeForChild(View originalView, ActionMode.Callback callback)4397         public ActionMode startActionModeForChild(View originalView,
4398                 ActionMode.Callback callback) {
4399             return null;
4400         }
4401 
4402         @Override
startActionModeForChild(View originalView, ActionMode.Callback callback, int type)4403         public ActionMode startActionModeForChild(View originalView,
4404                 ActionMode.Callback callback, int type) {
4405             return null;
4406         }
4407 
hasShowContextMenuForChild()4408         public boolean hasShowContextMenuForChild() {
4409             return mHasShowContextMenuForChild;
4410         }
4411 
hasShowContextMenuForChildXY()4412         public boolean hasShowContextMenuForChildXY() {
4413             return mHasShowContextMenuForChildXY;
4414         }
4415 
4416         @Override
onCreateDrawableState(int extraSpace)4417         protected int[] onCreateDrawableState(int extraSpace) {
4418             return DEFAULT_PARENT_STATE_SET;
4419         }
4420 
4421         @Override
requestSendAccessibilityEvent(View child, AccessibilityEvent event)4422         public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
4423             return false;
4424         }
4425 
reset()4426         public void reset() {
4427             mHasRequestLayout = false;
4428             mHasCreateContextMenu = false;
4429             mHasShowContextMenuForChild = false;
4430             mHasShowContextMenuForChildXY = false;
4431             mHasChildDrawableStateChanged = false;
4432             mHasBroughtChildToFront = false;
4433         }
4434 
4435         @Override
childHasTransientStateChanged(View child, boolean hasTransientState)4436         public void childHasTransientStateChanged(View child, boolean hasTransientState) {
4437 
4438         }
4439 
4440         @Override
getParentForAccessibility()4441         public ViewParent getParentForAccessibility() {
4442             return null;
4443         }
4444 
4445         @Override
notifySubtreeAccessibilityStateChanged(View child, View source, int changeType)4446         public void notifySubtreeAccessibilityStateChanged(View child,
4447             View source, int changeType) {
4448 
4449         }
4450 
4451         @Override
onStartNestedScroll(View child, View target, int nestedScrollAxes)4452         public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
4453             return false;
4454         }
4455 
4456         @Override
onNestedScrollAccepted(View child, View target, int nestedScrollAxes)4457         public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes) {
4458         }
4459 
4460         @Override
onStopNestedScroll(View target)4461         public void onStopNestedScroll(View target) {
4462         }
4463 
4464         @Override
onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)4465         public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
4466                                    int dxUnconsumed, int dyUnconsumed) {
4467         }
4468 
4469         @Override
onNestedPreScroll(View target, int dx, int dy, int[] consumed)4470         public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
4471         }
4472 
4473         @Override
onNestedFling(View target, float velocityX, float velocityY, boolean consumed)4474         public boolean onNestedFling(View target, float velocityX, float velocityY,
4475                 boolean consumed) {
4476             return false;
4477         }
4478 
4479         @Override
onNestedPreFling(View target, float velocityX, float velocityY)4480         public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
4481             return false;
4482         }
4483 
4484         @Override
onNestedPrePerformAccessibilityAction(View target, int action, Bundle args)4485         public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle args) {
4486             return false;
4487         }
4488     }
4489 
4490     private final class OnCreateContextMenuListenerImpl implements OnCreateContextMenuListener {
4491         private boolean mHasOnCreateContextMenu = false;
4492 
4493         @Override
onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)4494         public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
4495             mHasOnCreateContextMenu = true;
4496         }
4497 
hasOnCreateContextMenu()4498         public boolean hasOnCreateContextMenu() {
4499             return mHasOnCreateContextMenu;
4500         }
4501 
reset()4502         public void reset() {
4503             mHasOnCreateContextMenu = false;
4504         }
4505     }
4506 
4507     private static class MockViewGroupParent extends ViewGroup implements ViewParent {
4508         private boolean mHasRequestChildRectangleOnScreen = false;
4509         private Rect mLastRequestedChildRectOnScreen = new Rect(
4510                 Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
4511 
MockViewGroupParent(Context context)4512         public MockViewGroupParent(Context context) {
4513             super(context);
4514         }
4515 
4516         @Override
onLayout(boolean changed, int l, int t, int r, int b)4517         protected void onLayout(boolean changed, int l, int t, int r, int b) {
4518 
4519         }
4520 
4521         @Override
requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate)4522         public boolean requestChildRectangleOnScreen(View child,
4523                 Rect rectangle, boolean immediate) {
4524             mHasRequestChildRectangleOnScreen = true;
4525             mLastRequestedChildRectOnScreen.set(rectangle);
4526             return super.requestChildRectangleOnScreen(child, rectangle, immediate);
4527         }
4528 
getLastRequestedChildRectOnScreen()4529         public Rect getLastRequestedChildRectOnScreen() {
4530             return mLastRequestedChildRectOnScreen;
4531         }
4532 
hasRequestChildRectangleOnScreen()4533         public boolean hasRequestChildRectangleOnScreen() {
4534             return mHasRequestChildRectangleOnScreen;
4535         }
4536 
4537         @Override
detachViewFromParent(View child)4538         protected void detachViewFromParent(View child) {
4539             super.detachViewFromParent(child);
4540         }
4541 
reset()4542         public void reset() {
4543             mHasRequestChildRectangleOnScreen = false;
4544         }
4545     }
4546 
4547     private static final class OnClickListenerImpl implements OnClickListener {
4548         private boolean mHasOnClick = false;
4549 
4550         @Override
onClick(View v)4551         public void onClick(View v) {
4552             mHasOnClick = true;
4553         }
4554 
hasOnClick()4555         public boolean hasOnClick() {
4556             return mHasOnClick;
4557         }
4558 
reset()4559         public void reset() {
4560             mHasOnClick = false;
4561         }
4562     }
4563 
4564     private static final class OnLongClickListenerImpl implements OnLongClickListener {
4565         private boolean mHasOnLongClick = false;
4566 
hasOnLongClick()4567         public boolean hasOnLongClick() {
4568             return mHasOnLongClick;
4569         }
4570 
reset()4571         public void reset() {
4572             mHasOnLongClick = false;
4573         }
4574 
4575         @Override
onLongClick(View v)4576         public boolean onLongClick(View v) {
4577             mHasOnLongClick = true;
4578             return true;
4579         }
4580     }
4581 
4582     private static final class OnContextClickListenerImpl implements OnContextClickListener {
4583         private boolean mHasContextClick = false;
4584         private View mLastViewContextClicked;
4585 
hasOnContextClick()4586         public boolean hasOnContextClick() {
4587             return mHasContextClick;
4588         }
4589 
reset()4590         public void reset() {
4591             mHasContextClick = false;
4592             mLastViewContextClicked = null;
4593         }
4594 
4595         @Override
onContextClick(View v)4596         public boolean onContextClick(View v) {
4597             mHasContextClick = true;
4598             mLastViewContextClicked = v;
4599             return true;
4600         }
4601 
getLastViewContextClicked()4602         public View getLastViewContextClicked() {
4603             return mLastViewContextClicked;
4604         }
4605     }
4606 
4607     private static final class OnFocusChangeListenerImpl implements OnFocusChangeListener {
4608         private boolean mHasOnFocusChange = false;
4609 
4610         @Override
onFocusChange(View v, boolean hasFocus)4611         public void onFocusChange(View v, boolean hasFocus) {
4612             mHasOnFocusChange = true;
4613         }
4614 
hasOnFocusChange()4615         public boolean hasOnFocusChange() {
4616             return mHasOnFocusChange;
4617         }
4618 
reset()4619         public void reset() {
4620             mHasOnFocusChange = false;
4621         }
4622     }
4623 
4624     private static final class OnKeyListenerImpl implements OnKeyListener {
4625         private boolean mHasOnKey = false;
4626 
4627         @Override
onKey(View v, int keyCode, KeyEvent event)4628         public boolean onKey(View v, int keyCode, KeyEvent event) {
4629             mHasOnKey = true;
4630             return true;
4631         }
4632 
reset()4633         public void reset() {
4634             mHasOnKey = false;
4635         }
4636 
hasOnKey()4637         public boolean hasOnKey() {
4638             return mHasOnKey;
4639         }
4640     }
4641 
4642     private static final class OnTouchListenerImpl implements OnTouchListener {
4643         private boolean mHasOnTouch = false;
4644 
4645         @Override
onTouch(View v, MotionEvent event)4646         public boolean onTouch(View v, MotionEvent event) {
4647             mHasOnTouch = true;
4648             return true;
4649         }
4650 
reset()4651         public void reset() {
4652             mHasOnTouch = false;
4653         }
4654 
hasOnTouch()4655         public boolean hasOnTouch() {
4656             return mHasOnTouch;
4657         }
4658     }
4659 
4660     private static final class MockTouchDelegate extends TouchDelegate {
MockTouchDelegate(Rect bounds, View delegateView)4661         public MockTouchDelegate(Rect bounds, View delegateView) {
4662             super(bounds, delegateView);
4663         }
4664 
4665         private boolean mCalledOnTouchEvent = false;
4666 
4667         @Override
onTouchEvent(MotionEvent event)4668         public boolean onTouchEvent(MotionEvent event) {
4669             mCalledOnTouchEvent = true;
4670             return super.onTouchEvent(event);
4671         }
4672 
hasCalledOnTouchEvent()4673         public boolean hasCalledOnTouchEvent() {
4674             return mCalledOnTouchEvent;
4675         }
4676 
reset()4677         public void reset() {
4678             mCalledOnTouchEvent = false;
4679         }
4680     }
4681 
4682     private static final class ViewData {
4683         public int childCount;
4684         public String tag;
4685         public View firstChild;
4686     }
4687 
4688     private static final class MockRunnable implements Runnable {
4689         public boolean hasRun = false;
4690 
4691         @Override
run()4692         public void run() {
4693             hasRun = true;
4694         }
4695     }
4696 
4697     private static final Class<?> ASYNC_INFLATE_VIEWS[] = {
4698         android.app.FragmentBreadCrumbs.class,
4699 // DISABLED because it doesn't have a AppWidgetHostView(Context, AttributeSet)
4700 // constructor, so it's not inflate-able
4701 //        android.appwidget.AppWidgetHostView.class,
4702         android.gesture.GestureOverlayView.class,
4703         android.inputmethodservice.ExtractEditText.class,
4704         android.inputmethodservice.KeyboardView.class,
4705 //        android.media.tv.TvView.class,
4706 //        android.opengl.GLSurfaceView.class,
4707 //        android.view.SurfaceView.class,
4708         android.view.TextureView.class,
4709         android.view.ViewStub.class,
4710 //        android.webkit.WebView.class,
4711         android.widget.AbsoluteLayout.class,
4712         android.widget.AdapterViewFlipper.class,
4713         android.widget.AnalogClock.class,
4714         android.widget.AutoCompleteTextView.class,
4715         android.widget.Button.class,
4716         android.widget.CalendarView.class,
4717         android.widget.CheckBox.class,
4718         android.widget.CheckedTextView.class,
4719         android.widget.Chronometer.class,
4720         android.widget.DatePicker.class,
4721         android.widget.DialerFilter.class,
4722         android.widget.DigitalClock.class,
4723         android.widget.EditText.class,
4724         android.widget.ExpandableListView.class,
4725         android.widget.FrameLayout.class,
4726         android.widget.Gallery.class,
4727         android.widget.GridView.class,
4728         android.widget.HorizontalScrollView.class,
4729         android.widget.ImageButton.class,
4730         android.widget.ImageSwitcher.class,
4731         android.widget.ImageView.class,
4732         android.widget.LinearLayout.class,
4733         android.widget.ListView.class,
4734         android.widget.MediaController.class,
4735         android.widget.MultiAutoCompleteTextView.class,
4736         android.widget.NumberPicker.class,
4737         android.widget.ProgressBar.class,
4738         android.widget.QuickContactBadge.class,
4739         android.widget.RadioButton.class,
4740         android.widget.RadioGroup.class,
4741         android.widget.RatingBar.class,
4742         android.widget.RelativeLayout.class,
4743         android.widget.ScrollView.class,
4744         android.widget.SeekBar.class,
4745 // DISABLED because it has required attributes
4746 //        android.widget.SlidingDrawer.class,
4747         android.widget.Spinner.class,
4748         android.widget.StackView.class,
4749         android.widget.Switch.class,
4750         android.widget.TabHost.class,
4751         android.widget.TabWidget.class,
4752         android.widget.TableLayout.class,
4753         android.widget.TableRow.class,
4754         android.widget.TextClock.class,
4755         android.widget.TextSwitcher.class,
4756         android.widget.TextView.class,
4757         android.widget.TimePicker.class,
4758         android.widget.ToggleButton.class,
4759         android.widget.TwoLineListItem.class,
4760 //        android.widget.VideoView.class,
4761         android.widget.ViewAnimator.class,
4762         android.widget.ViewFlipper.class,
4763         android.widget.ViewSwitcher.class,
4764         android.widget.ZoomButton.class,
4765         android.widget.ZoomControls.class,
4766     };
4767 }
4768