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 android.content.Context;
20 import android.content.Intent;
21 import android.content.res.XmlResourceParser;
22 import android.cts.util.CTSResult;
23 import android.graphics.Bitmap;
24 import android.graphics.Bitmap.Config;
25 import android.graphics.Canvas;
26 import android.graphics.Point;
27 import android.graphics.Rect;
28 import android.graphics.Region;
29 import android.graphics.drawable.BitmapDrawable;
30 import android.os.Parcelable;
31 import android.os.SystemClock;
32 import android.test.InstrumentationTestCase;
33 import android.util.AttributeSet;
34 import android.util.DisplayMetrics;
35 import android.util.SparseArray;
36 import android.view.ActionMode;
37 import android.view.Display;
38 import android.view.KeyEvent;
39 import android.view.Menu;
40 import android.view.MenuInflater;
41 import android.view.MenuItem;
42 import android.view.MotionEvent;
43 import android.view.View;
44 import android.view.View.BaseSavedState;
45 import android.view.View.MeasureSpec;
46 import android.view.View.OnTouchListener;
47 import android.view.ViewGroup;
48 import android.view.ViewGroup.LayoutParams;
49 import android.view.ViewGroup.OnHierarchyChangeListener;
50 import android.view.WindowManager;
51 import android.view.animation.AlphaAnimation;
52 import android.view.animation.Animation;
53 import android.view.animation.Animation.AnimationListener;
54 import android.view.animation.LayoutAnimationController;
55 import android.view.animation.RotateAnimation;
56 import android.view.animation.Transformation;
57 import android.view.cts.util.XmlUtils;
58 import android.widget.TextView;
59 
60 import java.util.ArrayList;
61 
62 public class ViewGroupTest extends InstrumentationTestCase implements CTSResult{
63 
64     private Context mContext;
65     private MotionEvent mMotionEvent;
66     private int mResultCode;
67 
68     private Sync mSync = new Sync();
69     private static class Sync {
70         boolean mHasNotify;
71     }
72 
73     @Override
setUp()74     protected void setUp() throws Exception {
75         super.setUp();
76         mContext = getInstrumentation().getTargetContext();
77     }
78 
testConstructor()79     public void testConstructor() {
80         new MockViewGroup(mContext);
81         new MockViewGroup(mContext, null);
82         new MockViewGroup(mContext, null, 0);
83     }
84 
testAddFocusables()85     public void testAddFocusables() {
86         MockViewGroup vg = new MockViewGroup(mContext);
87         vg.setFocusable(true);
88 
89         ArrayList<View> list = new ArrayList<View>();
90         TextView textView = new TextView(mContext);
91         list.add(textView);
92         vg.addView(textView);
93         vg.addFocusables(list, 0);
94 
95         assertEquals(2, list.size());
96 
97         list = new ArrayList<View>();
98         list.add(textView);
99         vg.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
100         vg.setFocusable(false);
101         vg.addFocusables(list, 0);
102         assertEquals(1, list.size());
103     }
104 
testAddStatesFromChildren()105     public void testAddStatesFromChildren() {
106         MockViewGroup vg = new MockViewGroup(mContext);
107         TextView textView = new TextView(mContext);
108         vg.addView(textView);
109         assertFalse(vg.addStatesFromChildren());
110 
111         vg.setAddStatesFromChildren(true);
112         textView.performClick();
113         assertTrue(vg.addStatesFromChildren());
114         assertTrue(vg.isDrawableStateChangedCalled);
115     }
116 
testAddTouchables()117     public void testAddTouchables() {
118         MockViewGroup vg = new MockViewGroup(mContext);
119         vg.setFocusable(true);
120 
121         ArrayList<View> list = new ArrayList<View>();
122         TextView textView = new TextView(mContext);
123         textView.setVisibility(View.VISIBLE);
124         textView.setClickable(true);
125         textView.setEnabled(true);
126 
127         list.add(textView);
128         vg.addView(textView);
129         vg.addTouchables(list);
130 
131         assertEquals(2, list.size());
132 
133         View v = vg.getChildAt(0);
134         assertSame(textView, v);
135 
136         v = vg.getChildAt(-1);
137         assertNull(v);
138 
139         v = vg.getChildAt(1);
140         assertNull(v);
141 
142         v = vg.getChildAt(100);
143         assertNull(v);
144 
145         v = vg.getChildAt(-100);
146         assertNull(v);
147     }
148 
testAddView()149     public void testAddView() {
150         MockViewGroup vg = new MockViewGroup(mContext);
151         TextView textView = new TextView(mContext);
152 
153         assertEquals(0, vg.getChildCount());
154 
155         vg.addView(textView);
156         assertEquals(1, vg.getChildCount());
157     }
158 
testAddViewWithParaViewInt()159     public void testAddViewWithParaViewInt() {
160         MockViewGroup vg = new MockViewGroup(mContext);
161         TextView textView = new TextView(mContext);
162 
163         assertEquals(0, vg.getChildCount());
164 
165         vg.addView(textView, -1);
166         assertEquals(1, vg.getChildCount());
167     }
168 
testAddViewWithParaViewLayoutPara()169     public void testAddViewWithParaViewLayoutPara() {
170         MockViewGroup vg = new MockViewGroup(mContext);
171         TextView textView = new TextView(mContext);
172 
173         assertEquals(0, vg.getChildCount());
174 
175         vg.addView(textView, new ViewGroup.LayoutParams(100, 200));
176 
177         assertEquals(1, vg.getChildCount());
178     }
179 
testAddViewWithParaViewIntInt()180     public void testAddViewWithParaViewIntInt() {
181         final int width = 100;
182         final int height = 200;
183         MockViewGroup vg = new MockViewGroup(mContext);
184         TextView textView = new TextView(mContext);
185 
186         assertEquals(0, vg.getChildCount());
187 
188         vg.addView(textView, width, height);
189         assertEquals(width, textView.getLayoutParams().width);
190         assertEquals(height, textView.getLayoutParams().height);
191 
192         assertEquals(1, vg.getChildCount());
193     }
194 
testAddViewWidthParaViewIntLayoutParam()195     public void testAddViewWidthParaViewIntLayoutParam() {
196         MockViewGroup vg = new MockViewGroup(mContext);
197         TextView textView = new TextView(mContext);
198 
199         assertEquals(0, vg.getChildCount());
200 
201         vg.addView(textView, -1, new ViewGroup.LayoutParams(100, 200));
202 
203         assertEquals(1, vg.getChildCount());
204     }
205 
testAddViewInLayout()206     public void testAddViewInLayout() {
207         MockViewGroup vg = new MockViewGroup(mContext);
208         TextView textView = new TextView(mContext);
209 
210         assertEquals(0, vg.getChildCount());
211 
212         assertTrue(vg.isRequestLayoutCalled);
213         vg.isRequestLayoutCalled = false;
214         assertTrue(vg.addViewInLayout(textView, -1, new ViewGroup.LayoutParams(100, 200)));
215         assertEquals(1, vg.getChildCount());
216         // check that calling addViewInLayout() does not trigger a
217         // requestLayout() on this ViewGroup
218         assertFalse(vg.isRequestLayoutCalled);
219     }
220 
testAttachLayoutAnimationParameters()221     public void testAttachLayoutAnimationParameters() {
222         MockViewGroup vg = new MockViewGroup(mContext);
223         ViewGroup.LayoutParams param = new ViewGroup.LayoutParams(10, 10);
224 
225         vg.attachLayoutAnimationParameters(null, param, 1, 2);
226         assertEquals(2, param.layoutAnimationParameters.count);
227         assertEquals(1, param.layoutAnimationParameters.index);
228     }
229 
testAttachViewToParent()230     public void testAttachViewToParent() {
231         MockViewGroup vg = new MockViewGroup(mContext);
232         vg.setFocusable(true);
233         assertEquals(0, vg.getChildCount());
234 
235         ViewGroup.LayoutParams param = new ViewGroup.LayoutParams(10, 10);
236 
237         TextView child = new TextView(mContext);
238         child.setFocusable(true);
239         vg.attachViewToParent(child, -1, param);
240         assertSame(vg, child.getParent());
241         assertEquals(1, vg.getChildCount());
242         assertSame(child, vg.getChildAt(0));
243     }
244 
testAddViewInLayoutWithParamViewIntLayB()245     public void testAddViewInLayoutWithParamViewIntLayB() {
246         MockViewGroup vg = new MockViewGroup(mContext);
247         TextView textView = new TextView(mContext);
248 
249         assertEquals(0, vg.getChildCount());
250 
251         assertTrue(vg.isRequestLayoutCalled);
252         vg.isRequestLayoutCalled = false;
253         assertTrue(vg.addViewInLayout(textView, -1, new ViewGroup.LayoutParams(100, 200), true));
254 
255         assertEquals(1, vg.getChildCount());
256         // check that calling addViewInLayout() does not trigger a
257         // requestLayout() on this ViewGroup
258         assertFalse(vg.isRequestLayoutCalled);
259     }
260 
testBringChildToFront()261     public void testBringChildToFront() {
262         MockViewGroup vg = new MockViewGroup(mContext);
263         TextView textView1 = new TextView(mContext);
264         TextView textView2 = new TextView(mContext);
265 
266         assertEquals(0, vg.getChildCount());
267 
268         vg.addView(textView1);
269         vg.addView(textView2);
270         assertEquals(2, vg.getChildCount());
271 
272         vg.bringChildToFront(textView1);
273         assertEquals(vg, textView1.getParent());
274         assertEquals(2, vg.getChildCount());
275         assertNotNull(vg.getChildAt(0));
276         assertSame(textView2, vg.getChildAt(0));
277 
278         vg.bringChildToFront(textView2);
279         assertEquals(vg, textView2.getParent());
280         assertEquals(2, vg.getChildCount());
281         assertNotNull(vg.getChildAt(0));
282         assertSame(textView1, vg.getChildAt(0));
283     }
284 
testCanAnimate()285     public void testCanAnimate() {
286         MockViewGroup vg = new MockViewGroup(mContext);
287 
288         assertFalse(vg.canAnimate());
289 
290         RotateAnimation animation = new RotateAnimation(0.1f, 0.1f);
291         LayoutAnimationController la = new LayoutAnimationController(animation);
292         vg.setLayoutAnimation(la);
293         assertTrue(vg.canAnimate());
294     }
295 
testCheckLayoutParams()296     public void testCheckLayoutParams() {
297         MockViewGroup view = new MockViewGroup(mContext);
298         assertFalse(view.checkLayoutParams(null));
299 
300         assertTrue(view.checkLayoutParams(new ViewGroup.LayoutParams(100, 200)));
301     }
302 
testChildDrawableStateChanged()303     public void testChildDrawableStateChanged() {
304         MockViewGroup vg = new MockViewGroup(mContext);
305         vg.setAddStatesFromChildren(true);
306 
307         vg.childDrawableStateChanged(null);
308         assertTrue(vg.isRefreshDrawableStateCalled);
309     }
310 
testCleanupLayoutState()311     public void testCleanupLayoutState() {
312         MockViewGroup vg = new MockViewGroup(mContext);
313         TextView textView = new TextView(mContext);
314 
315         assertTrue(textView.isLayoutRequested());
316 
317         vg.cleanupLayoutState(textView);
318         assertFalse(textView.isLayoutRequested());
319     }
320 
testClearChildFocus()321     public void testClearChildFocus() {
322         MockViewGroup vg = new MockViewGroup(mContext);
323         TextView textView = new TextView(mContext);
324 
325         vg.addView(textView);
326         vg.requestChildFocus(textView, null);
327 
328         View focusedView = vg.getFocusedChild();
329         assertSame(textView, focusedView);
330 
331         vg.clearChildFocus(textView);
332         assertNull(vg.getFocusedChild());
333     }
334 
testClearDisappearingChildren()335     public void testClearDisappearingChildren() {
336 
337         Canvas canvas = new Canvas();
338         MockViewGroup vg = new MockViewGroup(mContext);
339         MockViewGroup child = new MockViewGroup(mContext);
340         child.setAnimation(new MockAnimation());
341         vg.addView(child);
342         assertEquals(1, vg.getChildCount());
343 
344         assertNotNull(child.getAnimation());
345         vg.dispatchDraw(canvas);
346         assertEquals(1, vg.drawChildCalledTime);
347 
348         child.setAnimation(new MockAnimation());
349         vg.removeAllViewsInLayout();
350 
351         vg.drawChildCalledTime = 0;
352         vg.dispatchDraw(canvas);
353         assertEquals(1, vg.drawChildCalledTime);
354 
355         child.setAnimation(new MockAnimation());
356         vg.clearDisappearingChildren();
357 
358         vg.drawChildCalledTime = 0;
359         vg.dispatchDraw(canvas);
360         assertEquals(0, vg.drawChildCalledTime);
361     }
362 
testClearFocus()363     public void testClearFocus() {
364         MockViewGroup vg = new MockViewGroup(mContext);
365         MockTextView textView = new MockTextView(mContext);
366 
367         vg.addView(textView);
368         vg.requestChildFocus(textView, null);
369         vg.clearFocus();
370         assertTrue(textView.isClearFocusCalled);
371     }
372 
testDetachAllViewsFromParent()373     public void testDetachAllViewsFromParent() {
374         MockViewGroup vg = new MockViewGroup(mContext);
375         TextView textView = new TextView(mContext);
376 
377         vg.addView(textView);
378         assertEquals(1, vg.getChildCount());
379         assertSame(vg, textView.getParent());
380         vg.detachAllViewsFromParent();
381         assertEquals(0, vg.getChildCount());
382         assertNull(textView.getParent());
383     }
384 
testDetachViewFromParent()385     public void testDetachViewFromParent() {
386         MockViewGroup vg = new MockViewGroup(mContext);
387         TextView textView = new TextView(mContext);
388 
389         vg.addView(textView);
390         assertEquals(1, vg.getChildCount());
391 
392         vg.detachViewFromParent(0);
393 
394         assertEquals(0, vg.getChildCount());
395         assertNull(textView.getParent());
396     }
397 
testDetachViewFromParentWithParamView()398     public void testDetachViewFromParentWithParamView() {
399         MockViewGroup vg = new MockViewGroup(mContext);
400         TextView textView = new TextView(mContext);
401 
402         vg.addView(textView);
403         assertEquals(1, vg.getChildCount());
404         assertSame(vg, textView.getParent());
405 
406         vg.detachViewFromParent(textView);
407 
408         assertEquals(0, vg.getChildCount());
409         assertNull(vg.getParent());
410     }
411 
testDetachViewsFromParent()412     public void testDetachViewsFromParent() {
413         MockViewGroup vg = new MockViewGroup(mContext);
414         TextView textView1 = new TextView(mContext);
415         TextView textView2 = new TextView(mContext);
416         TextView textView3 = new TextView(mContext);
417 
418         vg.addView(textView1);
419         vg.addView(textView2);
420         vg.addView(textView3);
421         assertEquals(3, vg.getChildCount());
422 
423         vg.detachViewsFromParent(0, 2);
424 
425         assertEquals(1, vg.getChildCount());
426         assertNull(textView1.getParent());
427         assertNull(textView2.getParent());
428     }
429 
testDispatchDraw()430     public void testDispatchDraw() {
431         MockViewGroup vg = new MockViewGroup(mContext);
432         Canvas canvas = new Canvas();
433 
434         vg.draw(canvas);
435         assertTrue(vg.isDispatchDrawCalled);
436         assertSame(canvas, vg.canvas);
437     }
438 
439     @SuppressWarnings("unchecked")
testDispatchFreezeSelfOnly()440     public void testDispatchFreezeSelfOnly() {
441         MockViewGroup vg = new MockViewGroup(mContext);
442         vg.setId(1);
443         vg.setSaveEnabled(true);
444 
445         SparseArray container = new SparseArray();
446         assertEquals(0, container.size());
447         vg.dispatchFreezeSelfOnly(container);
448         assertEquals(1, container.size());
449     }
450 
testDispatchKeyEvent()451     public void testDispatchKeyEvent() {
452         MockViewGroup vg = new MockViewGroup(mContext);
453         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER);
454         assertFalse(vg.dispatchKeyEvent(event));
455 
456         MockTextView textView = new MockTextView(mContext);
457         vg.addView(textView);
458         vg.requestChildFocus(textView, null);
459         textView.layout(1, 1, 100, 100);
460 
461         assertTrue(vg.dispatchKeyEvent(event));
462     }
463 
464     @SuppressWarnings("unchecked")
testDispatchSaveInstanceState()465     public void testDispatchSaveInstanceState() {
466         MockViewGroup vg = new MockViewGroup(mContext);
467         vg.setId(2);
468         vg.setSaveEnabled(true);
469         MockTextView textView = new MockTextView(mContext);
470         textView.setSaveEnabled(true);
471         textView.setId(1);
472         vg.addView(textView);
473 
474         SparseArray array = new SparseArray();
475         vg.dispatchSaveInstanceState(array);
476 
477         assertTrue(array.size() > 0);
478         assertNotNull(array.get(2));
479 
480         array = new SparseArray();
481         vg.dispatchRestoreInstanceState(array);
482         assertTrue(textView.isDispatchRestoreInstanceStateCalled);
483     }
484 
testDispatchSetPressed()485     public void testDispatchSetPressed() {
486         MockViewGroup vg = new MockViewGroup(mContext);
487         MockTextView textView = new MockTextView(mContext);
488         vg.addView(textView);
489 
490         vg.dispatchSetPressed(true);
491         assertTrue(textView.isPressed());
492 
493         vg.dispatchSetPressed(false);
494         assertFalse(textView.isPressed());
495     }
496 
testDispatchSetSelected()497     public void testDispatchSetSelected() {
498         MockViewGroup vg = new MockViewGroup(mContext);
499         MockTextView textView = new MockTextView(mContext);
500         vg.addView(textView);
501 
502         vg.dispatchSetSelected(true);
503         assertTrue(textView.isSelected());
504 
505         vg.dispatchSetSelected(false);
506         assertFalse(textView.isSelected());
507     }
508 
509     @SuppressWarnings("unchecked")
testDispatchThawSelfOnly()510     public void testDispatchThawSelfOnly() {
511         MockViewGroup vg = new MockViewGroup(mContext);
512         vg.setId(1);
513         SparseArray array = new SparseArray();
514         array.put(1, BaseSavedState.EMPTY_STATE);
515 
516         vg.dispatchThawSelfOnly(array);
517         assertTrue(vg.isOnRestoreInstanceStateCalled);
518 
519     }
520 
testDispatchTouchEvent()521     public void testDispatchTouchEvent() {
522         MockViewGroup vg = new MockViewGroup(mContext);
523 
524         DisplayMetrics metrics = new DisplayMetrics();
525         WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
526         Display d = wm.getDefaultDisplay();
527         d.getMetrics(metrics);
528         int screenWidth = metrics.widthPixels;
529         int screenHeight = metrics.heightPixels;
530         vg.layout(0, 0, screenWidth, screenHeight);
531         vg.setLayoutParams(new ViewGroup.LayoutParams(screenWidth, screenHeight));
532 
533         MockTextView textView = new MockTextView(mContext);
534         mMotionEvent = null;
535         textView.setOnTouchListener(new OnTouchListener() {
536             @Override
537             public boolean onTouch(View v, MotionEvent event) {
538                 mMotionEvent = event;
539                 return true;
540             }
541         });
542 
543         textView.setVisibility(View.VISIBLE);
544         textView.setEnabled(true);
545 
546         vg.addView(textView, new LayoutParams(screenWidth, screenHeight));
547 
548         vg.requestDisallowInterceptTouchEvent(true);
549         MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
550                 SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN,
551                 screenWidth / 2, screenHeight / 2, 0);
552 
553         assertFalse(vg.dispatchTouchEvent(me));
554         assertNull(mMotionEvent);
555 
556         textView.layout(0, 0, screenWidth, screenHeight);
557         assertTrue(vg.dispatchTouchEvent(me));
558         assertSame(me, mMotionEvent);
559     }
560 
testDispatchTrackballEvent()561     public void testDispatchTrackballEvent() {
562         MockViewGroup vg = new MockViewGroup(mContext);
563         MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
564                 SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 100, 100,
565                 0);
566         assertFalse(vg.dispatchTrackballEvent(me));
567 
568         MockTextView textView = new MockTextView(mContext);
569         vg.addView(textView);
570         textView.layout(1, 1, 100, 100);
571         vg.requestChildFocus(textView, null);
572         assertTrue(vg.dispatchTrackballEvent(me));
573     }
574 
testDispatchUnhandledMove()575     public void testDispatchUnhandledMove() {
576         MockViewGroup vg = new MockViewGroup(mContext);
577         MockTextView textView = new MockTextView(mContext);
578         assertFalse(vg.dispatchUnhandledMove(textView, View.FOCUS_DOWN));
579 
580         vg.addView(textView);
581         textView.layout(1, 1, 100, 100);
582         vg.requestChildFocus(textView, null);
583         assertTrue(vg.dispatchUnhandledMove(textView, View.FOCUS_DOWN));
584     }
585 
testDispatchWindowFocusChanged()586     public void testDispatchWindowFocusChanged() {
587         MockViewGroup vg = new MockViewGroup(mContext);
588         MockTextView textView = new MockTextView(mContext);
589 
590         vg.addView(textView);
591         textView.setPressed(true);
592         assertTrue(textView.isPressed());
593 
594         vg.dispatchWindowFocusChanged(false);
595         assertFalse(textView.isPressed());
596     }
597 
testDispatchWindowVisibilityChanged()598     public void testDispatchWindowVisibilityChanged() {
599         int expected = 10;
600         MockViewGroup vg = new MockViewGroup(mContext);
601         MockTextView textView = new MockTextView(mContext);
602 
603         vg.addView(textView);
604         vg.dispatchWindowVisibilityChanged(expected);
605         assertEquals(expected, textView.visibility);
606     }
607 
testDrawableStateChanged()608     public void testDrawableStateChanged() {
609         MockViewGroup vg = new MockViewGroup(mContext);
610         MockTextView textView = new MockTextView(mContext);
611         textView.setDuplicateParentStateEnabled(true);
612 
613         vg.addView(textView);
614         vg.setAddStatesFromChildren(false);
615         vg.drawableStateChanged();
616         assertTrue(textView.mIsRefreshDrawableStateCalled);
617     }
618 
testDrawChild()619     public void testDrawChild() {
620         MockViewGroup vg = new MockViewGroup(mContext);
621         MockTextView textView = new MockTextView(mContext);
622         vg.addView(textView);
623 
624         MockCanvas canvas = new MockCanvas();
625         textView.setBackgroundDrawable(new BitmapDrawable(Bitmap.createBitmap(100, 100,
626                 Config.ALPHA_8)));
627         assertFalse(vg.drawChild(canvas, textView, 100));
628         // test whether child's draw method is called.
629         assertTrue(textView.isDrawCalled);
630     }
631 
testFindFocus()632     public void testFindFocus() {
633         MockViewGroup vg = new MockViewGroup(mContext);
634 
635         assertNull(vg.findFocus());
636         vg.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
637         vg.setFocusable(true);
638         vg.setVisibility(View.VISIBLE);
639         vg.setFocusableInTouchMode(true);
640         assertTrue(vg.requestFocus(1, new Rect()));
641 
642         assertSame(vg, vg.findFocus());
643     }
644 
testFitSystemWindows()645     public void testFitSystemWindows() {
646         Rect rect = new Rect(1, 1, 100, 100);
647         MockViewGroup vg = new MockViewGroup(mContext);
648         assertFalse(vg.fitSystemWindows(rect));
649 
650         vg = new MockViewGroup(mContext, null, 0);
651         MockView mv = new MockView(mContext);
652         vg.addView(mv);
653         assertTrue(vg.fitSystemWindows(rect));
654     }
655 
656     static class MockView extends ViewGroup {
657 
658         public int mWidthMeasureSpec;
659         public int mHeightMeasureSpec;
660 
MockView(Context context)661         public MockView(Context context) {
662             super(context);
663         }
664 
665         @Override
onLayout(boolean changed, int l, int t, int r, int b)666         public void onLayout(boolean changed, int l, int t, int r, int b) {
667         }
668 
669         @Override
fitSystemWindows(Rect insets)670         public boolean fitSystemWindows(Rect insets) {
671             return true;
672         }
673 
674         @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)675         public void onMeasure(int widthMeasureSpec,
676                 int heightMeasureSpec) {
677             mWidthMeasureSpec = widthMeasureSpec;
678             mHeightMeasureSpec = heightMeasureSpec;
679             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
680         }
681     }
682 
testFocusableViewAvailable()683     public void testFocusableViewAvailable() {
684         MockViewGroup vg = new MockViewGroup(mContext);
685         MockView child = new MockView(mContext);
686         vg.addView(child);
687 
688         child.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
689         child.focusableViewAvailable(vg);
690 
691         assertTrue(vg.isFocusableViewAvailable);
692     }
693 
testFocusSearch()694     public void testFocusSearch() {
695         MockViewGroup vg = new MockViewGroup(mContext);
696         MockTextView textView = new MockTextView(mContext);
697         MockView child = new MockView(mContext);
698         vg.addView(child);
699         child.addView(textView);
700         assertNotNull(child.focusSearch(textView, 1));
701         assertSame(textView, child.focusSearch(textView, 1));
702     }
703 
testGatherTransparentRegion()704     public void testGatherTransparentRegion() {
705         Region region = new Region();
706         MockViewGroup vg = new MockViewGroup(mContext);
707         MockTextView textView = new MockTextView(mContext);
708         textView.setAnimation(new AlphaAnimation(mContext, null));
709         textView.setVisibility(100);
710         vg.addView(textView);
711         assertEquals(1, vg.getChildCount());
712 
713         assertTrue(vg.gatherTransparentRegion(region));
714         assertTrue(vg.gatherTransparentRegion(null));
715     }
716 
testGenerateDefaultLayoutParams()717     public void testGenerateDefaultLayoutParams(){
718         MockViewGroup vg = new MockViewGroup(mContext);
719         LayoutParams lp = vg.generateDefaultLayoutParams();
720 
721         assertEquals(LayoutParams.WRAP_CONTENT, lp.width);
722         assertEquals(LayoutParams.WRAP_CONTENT, lp.height);
723     }
724 
testGenerateLayoutParamsWithParaAttributeSet()725     public void testGenerateLayoutParamsWithParaAttributeSet() throws Exception{
726         MockViewGroup vg = new MockViewGroup(mContext);
727         XmlResourceParser set = mContext.getResources().getLayout(
728                 android.view.cts.R.layout.abslistview_layout);
729         XmlUtils.beginDocument(set, "ViewGroup_Layout");
730         LayoutParams lp = vg.generateLayoutParams(set);
731         assertNotNull(lp);
732         assertEquals(25, lp.height);
733         assertEquals(25, lp.width);
734     }
735 
testGenerateLayoutParams()736     public void testGenerateLayoutParams() {
737         MockViewGroup vg = new MockViewGroup(mContext);
738         LayoutParams p = new LayoutParams(LayoutParams.WRAP_CONTENT,
739                 LayoutParams.MATCH_PARENT);
740         LayoutParams generatedParams = vg.generateLayoutParams(p);
741         assertEquals(generatedParams.getClass(), p.getClass());
742         assertEquals(p.width, generatedParams.width);
743         assertEquals(p.height, generatedParams.height);
744     }
745 
testGetChildDrawingOrder()746     public void testGetChildDrawingOrder() {
747         MockViewGroup vg = new MockViewGroup(mContext);
748         assertEquals(1, vg.getChildDrawingOrder(0, 1));
749         assertEquals(2, vg.getChildDrawingOrder(0, 2));
750     }
751 
testGetChildMeasureSpec()752     public void testGetChildMeasureSpec() {
753         int spec = 1;
754         int padding = 1;
755         int childDimension = 1;
756         assertEquals(MeasureSpec.makeMeasureSpec(childDimension, MeasureSpec.EXACTLY),
757                 ViewGroup.getChildMeasureSpec(spec, padding, childDimension));
758         spec = 4;
759         padding = 6;
760         childDimension = 9;
761         assertEquals(MeasureSpec.makeMeasureSpec(childDimension, MeasureSpec.EXACTLY),
762                 ViewGroup.getChildMeasureSpec(spec, padding, childDimension));
763     }
764 
testGetChildStaticTransformation()765     public void testGetChildStaticTransformation() {
766         MockViewGroup vg = new MockViewGroup(mContext);
767         assertFalse(vg.getChildStaticTransformation(null, null));
768     }
769 
testGetChildVisibleRect()770     public void testGetChildVisibleRect() {
771         MockViewGroup vg = new MockViewGroup(mContext);
772         MockTextView textView = new MockTextView(mContext);
773 
774         textView.layout(1, 1, 100, 100);
775         Rect rect = new Rect(1, 1, 50, 50);
776         Point p = new Point();
777         assertFalse(vg.getChildVisibleRect(textView, rect, p));
778 
779         textView.layout(0, 0, 0, 0);
780         vg.layout(20, 20, 60, 60);
781         rect = new Rect(10, 10, 40, 40);
782         p = new Point();
783         assertTrue(vg.getChildVisibleRect(textView, rect, p));
784     }
785 
testGetDescendantFocusability()786     public void testGetDescendantFocusability() {
787         MockViewGroup vg = new MockViewGroup(mContext);
788         final int FLAG_MASK_FOCUSABILITY = 0x60000;
789         assertFalse((vg.getDescendantFocusability() & FLAG_MASK_FOCUSABILITY) == 0);
790 
791         vg.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
792         assertFalse((vg.getDescendantFocusability() & FLAG_MASK_FOCUSABILITY) == 0);
793     }
794 
testGetLayoutAnimation()795     public void testGetLayoutAnimation() {
796         MockViewGroup vg = new MockViewGroup(mContext);
797 
798         assertNull(vg.getLayoutAnimation());
799         RotateAnimation animation = new RotateAnimation(0.1f, 0.1f);
800         LayoutAnimationController la = new LayoutAnimationController(animation);
801         vg.setLayoutAnimation(la);
802         assertTrue(vg.canAnimate());
803         assertSame(la, vg.getLayoutAnimation());
804     }
805 
testGetLayoutAnimationListener()806     public void testGetLayoutAnimationListener() {
807         MockViewGroup vg = new MockViewGroup(mContext);
808 
809         assertNull(vg.getLayoutAnimationListener());
810 
811         AnimationListener al = new AnimationListener() {
812 
813             @Override
814             public void onAnimationEnd(Animation animation) {
815             }
816 
817             @Override
818             public void onAnimationRepeat(Animation animation) {
819             }
820 
821             @Override
822             public void onAnimationStart(Animation animation) {
823             }
824         };
825         vg.setLayoutAnimationListener(al);
826         assertSame(al, vg.getLayoutAnimationListener());
827     }
828 
testGetPersistentDrawingCache()829     public void testGetPersistentDrawingCache() {
830         MockViewGroup vg = new MockViewGroup(mContext);
831         final int mPersistentDrawingCache1 = 2;
832         final int mPersistentDrawingCache2 = 3;
833         assertEquals(mPersistentDrawingCache1, vg.getPersistentDrawingCache());
834 
835         vg.setPersistentDrawingCache(mPersistentDrawingCache2);
836         assertEquals(mPersistentDrawingCache2, vg.getPersistentDrawingCache());
837     }
838 
testHasFocus()839     public void testHasFocus() {
840         MockViewGroup vg = new MockViewGroup(mContext);
841         assertFalse(vg.hasFocus());
842 
843         TextView textView = new TextView(mContext);
844 
845         vg.addView(textView);
846         vg.requestChildFocus(textView, null);
847 
848         assertTrue(vg.hasFocus());
849     }
850 
testHasFocusable()851     public void testHasFocusable() {
852         MockViewGroup vg = new MockViewGroup(mContext);
853         assertFalse(vg.hasFocusable());
854 
855         vg.setVisibility(View.VISIBLE);
856         vg.setFocusable(true);
857         assertTrue(vg.hasFocusable());
858     }
859 
testIndexOfChild()860     public void testIndexOfChild() {
861         MockViewGroup vg = new MockViewGroup(mContext);
862         TextView textView = new TextView(mContext);
863 
864         assertEquals(-1, vg.indexOfChild(textView));
865 
866         vg.addView(textView);
867         assertEquals(0, vg.indexOfChild(textView));
868     }
869 
setupActivity(String action)870     private void setupActivity(String action) {
871 
872         Intent intent = new Intent(getInstrumentation().getTargetContext(),
873                 ViewGroupCtsActivity.class);
874         intent.setAction(action);
875         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
876         getInstrumentation().getTargetContext().startActivity(intent);
877     }
878 
testInvalidateChild()879     public void testInvalidateChild() {
880         ViewGroupCtsActivity.setResult(this);
881         setupActivity(ViewGroupCtsActivity.ACTION_INVALIDATE_CHILD);
882         waitForResult();
883         assertEquals(CTSResult.RESULT_OK, mResultCode);
884     }
885 
waitForResult()886     private void waitForResult() {
887         synchronized (mSync) {
888             while(!mSync.mHasNotify) {
889                 try {
890                     mSync.wait();
891                 } catch (InterruptedException e) {
892                 }
893             }
894         }
895     }
896 
testIsAlwaysDrawnWithCacheEnabled()897     public void testIsAlwaysDrawnWithCacheEnabled() {
898         MockViewGroup vg = new MockViewGroup(mContext);
899 
900         assertTrue(vg.isAlwaysDrawnWithCacheEnabled());
901 
902         vg.setAlwaysDrawnWithCacheEnabled(false);
903         assertFalse(vg.isAlwaysDrawnWithCacheEnabled());
904         vg.setAlwaysDrawnWithCacheEnabled(true);
905         assertTrue(vg.isAlwaysDrawnWithCacheEnabled());
906     }
907 
testIsAnimationCacheEnabled()908     public void testIsAnimationCacheEnabled() {
909         MockViewGroup vg = new MockViewGroup(mContext);
910 
911         assertTrue(vg.isAnimationCacheEnabled());
912 
913         vg.setAnimationCacheEnabled(false);
914         assertFalse(vg.isAnimationCacheEnabled());
915         vg.setAnimationCacheEnabled(true);
916         assertTrue(vg.isAnimationCacheEnabled());
917     }
918 
testIsChildrenDrawnWithCacheEnabled()919     public void testIsChildrenDrawnWithCacheEnabled() {
920         MockViewGroup vg = new MockViewGroup(mContext);
921 
922         assertFalse(vg.isChildrenDrawnWithCacheEnabled());
923 
924         vg.setChildrenDrawnWithCacheEnabled(true);
925         assertTrue(vg.isChildrenDrawnWithCacheEnabled());
926     }
927 
testMeasureChild()928     public void testMeasureChild() {
929         final int width = 100;
930         final int height = 200;
931         MockViewGroup vg = new MockViewGroup(mContext);
932         MockView child = new MockView(mContext);
933         child.setLayoutParams(new LayoutParams(width, height));
934         child.forceLayout();
935         vg.addView(child);
936 
937         final int parentWidthMeasureSpec = 1;
938         final int parentHeightMeasureSpec = 2;
939         vg.measureChild(child, parentWidthMeasureSpec, parentHeightMeasureSpec);
940         assertEquals(ViewGroup.getChildMeasureSpec(parentWidthMeasureSpec, 0, width),
941                 child.mWidthMeasureSpec);
942         assertEquals(ViewGroup.getChildMeasureSpec(parentHeightMeasureSpec, 0, height),
943                 child.mHeightMeasureSpec);
944     }
945 
testMeasureChildren()946     public void testMeasureChildren() {
947         final int widthMeasureSpec = 100;
948         final int heightMeasureSpec = 200;
949         MockViewGroup vg = new MockViewGroup(mContext);
950         MockTextView textView1 = new MockTextView(mContext);
951 
952         vg.addView(textView1);
953         vg.measureChildCalledTime = 0;
954         vg.measureChildren(widthMeasureSpec, heightMeasureSpec);
955         assertEquals(1, vg.measureChildCalledTime);
956 
957         MockTextView textView2 = new MockTextView(mContext);
958         textView2.setVisibility(View.GONE);
959         vg.addView(textView2);
960 
961         vg.measureChildCalledTime = 0;
962         vg.measureChildren(widthMeasureSpec, heightMeasureSpec);
963         assertEquals(1, vg.measureChildCalledTime);
964     }
965 
testMeasureChildWithMargins()966     public void testMeasureChildWithMargins() {
967         final int width = 10;
968         final int height = 20;
969         final int parentWidthMeasureSpec = 1;
970         final int widthUsed = 2;
971         final int parentHeightMeasureSpec = 3;
972         final int heightUsed = 4;
973         MockViewGroup vg = new MockViewGroup(mContext);
974         MockView child = new MockView(mContext);
975 
976         vg.addView(child);
977         child.setLayoutParams(new ViewGroup.LayoutParams(width, height));
978         try {
979             vg.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed,
980                     parentHeightMeasureSpec, heightUsed);
981             fail("measureChildWithMargins should throw out class cast exception");
982         } catch (RuntimeException e) {
983         }
984         child.setLayoutParams(new ViewGroup.MarginLayoutParams(width, height));
985 
986         vg.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec,
987                 heightUsed);
988         assertEquals(ViewGroup.getChildMeasureSpec(parentWidthMeasureSpec, parentHeightMeasureSpec,
989                 width), child.mWidthMeasureSpec);
990         assertEquals(ViewGroup.getChildMeasureSpec(widthUsed, heightUsed, height),
991                 child.mHeightMeasureSpec);
992     }
993 
testOffsetDescendantRectToMyCoords()994     public void testOffsetDescendantRectToMyCoords() {
995         MockViewGroup vg = new MockViewGroup(mContext);
996         MockTextView textView = new MockTextView(mContext);
997 
998         try {
999             vg.offsetDescendantRectToMyCoords(textView, new Rect());
1000             fail("offsetDescendantRectToMyCoords should throw out "
1001                     + "IllegalArgumentException");
1002         } catch (RuntimeException e) {
1003             // expected
1004         }
1005         vg.addView(textView);
1006         textView.layout(1, 2, 3, 4);
1007         Rect rect = new Rect();
1008         vg.offsetDescendantRectToMyCoords(textView, rect);
1009         assertEquals(2, rect.bottom);
1010         assertEquals(2, rect.top);
1011         assertEquals(1, rect.left);
1012         assertEquals(1, rect.right);
1013     }
1014 
testOffsetRectIntoDescendantCoords()1015     public void testOffsetRectIntoDescendantCoords() {
1016         MockViewGroup vg = new MockViewGroup(mContext);
1017         vg.layout(10, 20, 30, 40);
1018         MockTextView textView = new MockTextView(mContext);
1019 
1020         try {
1021             vg.offsetRectIntoDescendantCoords(textView, new Rect());
1022             fail("offsetRectIntoDescendantCoords should throw out "
1023                     + "IllegalArgumentException");
1024         } catch (RuntimeException e) {
1025             // expected
1026         }
1027         textView.layout(1, 2, 3, 4);
1028         vg.addView(textView);
1029 
1030         Rect rect = new Rect(5, 6, 7, 8);
1031         vg.offsetRectIntoDescendantCoords(textView, rect);
1032         assertEquals(6, rect.bottom);
1033         assertEquals(4, rect.top);
1034         assertEquals(4, rect.left);
1035         assertEquals(6, rect.right);
1036     }
1037 
testOnAnimationEnd()1038     public void testOnAnimationEnd() {
1039         // this function is a call back function it should be tested in ViewGroup#drawChild.
1040         MockViewGroup parent = new MockViewGroup(mContext);
1041         MockViewGroup child = new MockViewGroup(mContext);
1042         child.setAnimation(new MockAnimation());
1043         // this call will make mPrivateFlags |= ANIMATION_STARTED;
1044         child.onAnimationStart();
1045         parent.addView(child);
1046 
1047         MockCanvas canvas = new MockCanvas();
1048         assertFalse(parent.drawChild(canvas, child, 100));
1049         assertTrue(child.isOnAnimationEndCalled);
1050     }
1051 
1052     private class MockAnimation extends Animation {
MockAnimation()1053         public MockAnimation() {
1054             super();
1055         }
1056 
MockAnimation(Context context, AttributeSet attrs)1057         public MockAnimation(Context context, AttributeSet attrs) {
1058             super(context, attrs);
1059         }
1060 
1061         @Override
getTransformation(long currentTime, Transformation outTransformation)1062         public boolean getTransformation(long currentTime, Transformation outTransformation) {
1063            super.getTransformation(currentTime, outTransformation);
1064            return false;
1065         }
1066     }
1067 
testOnAnimationStart()1068     public void testOnAnimationStart() {
1069         // This is a call back method. It should be tested in ViewGroup#drawChild.
1070         MockViewGroup parent = new MockViewGroup(mContext);
1071         MockViewGroup child = new MockViewGroup(mContext);
1072 
1073         parent.addView(child);
1074 
1075         MockCanvas canvas = new MockCanvas();
1076         try {
1077             assertFalse(parent.drawChild(canvas, child, 100));
1078             assertFalse(child.isOnAnimationStartCalled);
1079         } catch (Exception e) {
1080             // expected
1081         }
1082 
1083         child.setAnimation(new MockAnimation());
1084         assertFalse(parent.drawChild(canvas, child, 100));
1085         assertTrue(child.isOnAnimationStartCalled);
1086     }
1087 
testOnCreateDrawableState()1088     public void testOnCreateDrawableState() {
1089         MockViewGroup vg = new MockViewGroup(mContext);
1090         // Call back function. Called in View#getDrawableState()
1091         int[] data = vg.getDrawableState();
1092         assertTrue(vg.isOnCreateDrawableStateCalled);
1093         assertEquals(1, data.length);
1094     }
1095 
testOnInterceptTouchEvent()1096     public void testOnInterceptTouchEvent() {
1097         MockViewGroup vg = new MockViewGroup(mContext);
1098         MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
1099                 SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 100, 100,
1100                 0);
1101 
1102         assertFalse(vg.dispatchTouchEvent(me));
1103         assertTrue(vg.isOnInterceptTouchEventCalled);
1104     }
1105 
testOnLayout()1106     public void testOnLayout() {
1107         final int left = 1;
1108         final int top = 2;
1109         final int right = 100;
1110         final int bottom = 200;
1111         MockViewGroup mv = new MockViewGroup(mContext);
1112         mv.layout(left, top, right, bottom);
1113         assertEquals(left, mv.left);
1114         assertEquals(top, mv.top);
1115         assertEquals(right, mv.right);
1116         assertEquals(bottom, mv.bottom);
1117     }
1118 
testOnRequestFocusInDescendants()1119     public void testOnRequestFocusInDescendants() {
1120         MockViewGroup vg = new MockViewGroup(mContext);
1121 
1122         vg.requestFocus(View.FOCUS_DOWN, new Rect());
1123         assertTrue(vg.isOnRequestFocusInDescendantsCalled);
1124     }
1125 
testRemoveAllViews()1126     public void testRemoveAllViews() {
1127         MockViewGroup vg = new MockViewGroup(mContext);
1128         MockTextView textView = new MockTextView(mContext);
1129         assertEquals(0, vg.getChildCount());
1130 
1131         vg.addView(textView);
1132         assertEquals(1, vg.getChildCount());
1133 
1134         vg.removeAllViews();
1135         assertEquals(0, vg.getChildCount());
1136         assertNull(textView.getParent());
1137     }
1138 
testRemoveAllViewsInLayout()1139     public void testRemoveAllViewsInLayout() {
1140         MockViewGroup parent = new MockViewGroup(mContext);
1141         MockViewGroup child = new MockViewGroup(mContext);
1142         MockTextView textView = new MockTextView(mContext);
1143 
1144         assertEquals(0, parent.getChildCount());
1145 
1146         child.addView(textView);
1147         parent.addView(child);
1148         assertEquals(1, parent.getChildCount());
1149 
1150         parent.removeAllViewsInLayout();
1151         assertEquals(0, parent.getChildCount());
1152         assertEquals(1, child.getChildCount());
1153         assertNull(child.getParent());
1154         assertSame(child, textView.getParent());
1155     }
1156 
testRemoveDetachedView()1157     public void testRemoveDetachedView() {
1158         MockViewGroup parent = new MockViewGroup(mContext);
1159         MockViewGroup child1 = new MockViewGroup(mContext);
1160         MockViewGroup child2 = new MockViewGroup(mContext);
1161         MockOnHierarchyChangeListener listener = new MockOnHierarchyChangeListener();
1162         parent.setOnHierarchyChangeListener(listener);
1163         parent.addView(child1);
1164         parent.addView(child2);
1165 
1166         parent.removeDetachedView(child1, false);
1167         assertSame(parent, listener.sParent);
1168         assertSame(child1, listener.sChild);
1169     }
1170 
1171     static class MockOnHierarchyChangeListener implements OnHierarchyChangeListener {
1172 
1173         public View sParent;
1174         public View sChild;
1175 
1176         @Override
onChildViewAdded(View parent, View child)1177         public void onChildViewAdded(View parent, View child) {
1178         }
1179 
1180         @Override
onChildViewRemoved(View parent, View child)1181         public void onChildViewRemoved(View parent, View child) {
1182             sParent = parent;
1183             sChild = child;
1184         }
1185     }
1186 
testRemoveView()1187     public void testRemoveView() {
1188         MockViewGroup parent = new MockViewGroup(mContext);
1189         MockViewGroup child = new MockViewGroup(mContext);
1190 
1191         assertEquals(0, parent.getChildCount());
1192 
1193         parent.addView(child);
1194         assertEquals(1, parent.getChildCount());
1195 
1196         parent.removeView(child);
1197         assertEquals(0, parent.getChildCount());
1198         assertNull(child.getParent());
1199     }
1200 
testRemoveViewAt()1201     public void testRemoveViewAt() {
1202         MockViewGroup parent = new MockViewGroup(mContext);
1203         MockViewGroup child = new MockViewGroup(mContext);
1204 
1205         assertEquals(0, parent.getChildCount());
1206 
1207         parent.addView(child);
1208         assertEquals(1, parent.getChildCount());
1209 
1210         try {
1211             parent.removeViewAt(2);
1212             fail("should throw out null pointer exception");
1213         } catch (RuntimeException e) {
1214             // expected
1215         }
1216         assertEquals(1, parent.getChildCount());
1217 
1218         parent.removeViewAt(0);
1219         assertEquals(0, parent.getChildCount());
1220         assertNull(child.getParent());
1221     }
1222 
testRemoveViewInLayout()1223     public void testRemoveViewInLayout() {
1224         MockViewGroup parent = new MockViewGroup(mContext);
1225         MockViewGroup child = new MockViewGroup(mContext);
1226 
1227         assertEquals(0, parent.getChildCount());
1228 
1229         parent.addView(child);
1230         assertEquals(1, parent.getChildCount());
1231 
1232         parent.removeViewInLayout(child);
1233         assertEquals(0, parent.getChildCount());
1234         assertNull(child.getParent());
1235     }
1236 
testRemoveViews()1237     public void testRemoveViews() {
1238         MockViewGroup parent = new MockViewGroup(mContext);
1239         MockViewGroup child1 = new MockViewGroup(mContext);
1240         MockViewGroup child2 = new MockViewGroup(mContext);
1241 
1242         assertEquals(0, parent.getChildCount());
1243         parent.addView(child1);
1244         parent.addView(child2);
1245         assertEquals(2, parent.getChildCount());
1246 
1247         try {
1248             parent.removeViews(-1, 1); // negative begin
1249             fail("should fail with IndexOutOfBoundsException");
1250         } catch (IndexOutOfBoundsException e) {}
1251 
1252         try {
1253             parent.removeViews(0, -1); // negative count
1254             fail("should fail with IndexOutOfBoundsException");
1255         } catch (IndexOutOfBoundsException e) {}
1256 
1257         try {
1258             parent.removeViews(1, 2); // past end
1259             fail("should fail with IndexOutOfBoundsException");
1260         } catch (IndexOutOfBoundsException e) {}
1261         assertEquals(2, parent.getChildCount()); // child list unmodified
1262 
1263         parent.removeViews(0, 1);
1264         assertEquals(1, parent.getChildCount());
1265         assertNull(child1.getParent());
1266 
1267         parent.removeViews(0, 1);
1268         assertEquals(0, parent.getChildCount());
1269         assertNull(child2.getParent());
1270     }
1271 
testRemoveViewsInLayout()1272     public void testRemoveViewsInLayout() {
1273         MockViewGroup parent = new MockViewGroup(mContext);
1274         MockViewGroup child1 = new MockViewGroup(mContext);
1275         MockViewGroup child2 = new MockViewGroup(mContext);
1276 
1277         assertEquals(0, parent.getChildCount());
1278         parent.addView(child1);
1279         parent.addView(child2);
1280         assertEquals(2, parent.getChildCount());
1281 
1282         try {
1283             parent.removeViewsInLayout(-1, 1); // negative begin
1284             fail("should fail with IndexOutOfBoundsException");
1285         } catch (IndexOutOfBoundsException e) {}
1286 
1287         try {
1288             parent.removeViewsInLayout(0, -1); // negative count
1289             fail("should fail with IndexOutOfBoundsException");
1290         } catch (IndexOutOfBoundsException e) {}
1291 
1292         try {
1293             parent.removeViewsInLayout(1, 2); // past end
1294             fail("should fail with IndexOutOfBoundsException");
1295         } catch (IndexOutOfBoundsException e) {}
1296         assertEquals(2, parent.getChildCount()); // child list unmodified
1297 
1298         parent.removeViewsInLayout(0, 1);
1299         assertEquals(1, parent.getChildCount());
1300         assertNull(child1.getParent());
1301 
1302         parent.removeViewsInLayout(0, 1);
1303         assertEquals(0, parent.getChildCount());
1304         assertNull(child2.getParent());
1305     }
1306 
testRequestChildFocus()1307     public void testRequestChildFocus() {
1308         MockViewGroup vg = new MockViewGroup(mContext);
1309         TextView textView = new TextView(mContext);
1310 
1311         vg.addView(textView);
1312         vg.requestChildFocus(textView, null);
1313 
1314         assertNotNull(vg.getFocusedChild());
1315 
1316         vg.clearChildFocus(textView);
1317         assertNull(vg.getFocusedChild());
1318     }
1319 
testRequestChildRectangleOnScreen()1320     public void testRequestChildRectangleOnScreen() {
1321         MockViewGroup vg = new MockViewGroup(mContext);
1322         assertFalse(vg.requestChildRectangleOnScreen(null, null, false));
1323     }
1324 
testRequestDisallowInterceptTouchEvent()1325     public void testRequestDisallowInterceptTouchEvent() {
1326         MockViewGroup parent = new MockViewGroup(mContext);
1327         MockView child = new MockView(mContext);
1328 
1329         parent.addView(child);
1330         child.requestDisallowInterceptTouchEvent(true);
1331         child.requestDisallowInterceptTouchEvent(false);
1332         assertTrue(parent.isRequestDisallowInterceptTouchEventCalled);
1333     }
1334 
testRequestFocus()1335     public void testRequestFocus() {
1336         MockViewGroup vg = new MockViewGroup(mContext);
1337 
1338         vg.requestFocus(View.FOCUS_DOWN, new Rect());
1339         assertTrue(vg.isOnRequestFocusInDescendantsCalled);
1340     }
1341 
testRequestTransparentRegion()1342     public void testRequestTransparentRegion() {
1343         MockViewGroup parent = new MockViewGroup(mContext);
1344         MockView child1 = new MockView(mContext);
1345         MockView child2 = new MockView(mContext);
1346         child1.addView(child2);
1347         parent.addView(child1);
1348         child1.requestTransparentRegion(child2);
1349         assertTrue(parent.isRequestTransparentRegionCalled);
1350     }
1351 
testScheduleLayoutAnimation()1352     public void testScheduleLayoutAnimation() {
1353         MockViewGroup vg = new MockViewGroup(mContext);
1354         Animation animation = new AlphaAnimation(mContext, null);
1355 
1356         MockLayoutAnimationController al = new MockLayoutAnimationController(animation);
1357         vg.setLayoutAnimation(al);
1358         vg.scheduleLayoutAnimation();
1359         vg.dispatchDraw(new Canvas());
1360         assertTrue(al.mIsStartCalled);
1361     }
1362 
1363     static class MockLayoutAnimationController extends LayoutAnimationController {
1364 
1365         public boolean mIsStartCalled;
1366 
MockLayoutAnimationController(Animation animation)1367         public MockLayoutAnimationController(Animation animation) {
1368             super(animation);
1369         }
1370 
1371         @Override
start()1372         public void start() {
1373             mIsStartCalled = true;
1374             super.start();
1375         }
1376     }
1377 
testSetAddStatesFromChildren()1378     public void testSetAddStatesFromChildren() {
1379         MockViewGroup vg = new MockViewGroup(mContext);
1380         vg.setAddStatesFromChildren(true);
1381         assertTrue(vg.addStatesFromChildren());
1382 
1383         vg.setAddStatesFromChildren(false);
1384         assertFalse(vg.addStatesFromChildren());
1385     }
1386 
testSetChildrenDrawingCacheEnabled()1387     public void testSetChildrenDrawingCacheEnabled() {
1388         MockViewGroup vg = new MockViewGroup(mContext);
1389 
1390         assertTrue(vg.isAnimationCacheEnabled());
1391 
1392         vg.setAnimationCacheEnabled(false);
1393         assertFalse(vg.isAnimationCacheEnabled());
1394 
1395         vg.setAnimationCacheEnabled(true);
1396         assertTrue(vg.isAnimationCacheEnabled());
1397     }
1398 
testSetChildrenDrawnWithCacheEnabled()1399     public void testSetChildrenDrawnWithCacheEnabled() {
1400         MockViewGroup vg = new MockViewGroup(mContext);
1401 
1402         assertFalse(vg.isChildrenDrawnWithCacheEnabled());
1403 
1404         vg.setChildrenDrawnWithCacheEnabled(true);
1405         assertTrue(vg.isChildrenDrawnWithCacheEnabled());
1406 
1407         vg.setChildrenDrawnWithCacheEnabled(false);
1408         assertFalse(vg.isChildrenDrawnWithCacheEnabled());
1409     }
1410 
testSetClipChildren()1411     public void testSetClipChildren() {
1412         Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
1413 
1414         MockViewGroup vg = new MockViewGroup(mContext);
1415         MockTextView textView = new MockTextView(mContext);
1416         textView.layout(1, 2, 30, 40);
1417         vg.layout(1, 1, 100, 200);
1418         vg.setClipChildren(true);
1419 
1420         MockCanvas canvas = new MockCanvas(bitmap);
1421         vg.drawChild(canvas, textView, 100);
1422         Rect rect = canvas.getClipBounds();
1423         assertEquals(0, rect.top);
1424         assertEquals(100, rect.bottom);
1425         assertEquals(0, rect.left);
1426         assertEquals(100, rect.right);
1427     }
1428 
1429     class MockCanvas extends Canvas {
1430 
1431         public boolean mIsSaveCalled;
1432         public int mLeft;
1433         public int mTop;
1434         public int mRight;
1435         public int mBottom;
1436 
MockCanvas()1437         public MockCanvas() {
1438             super(Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888));
1439         }
1440 
MockCanvas(Bitmap bitmap)1441         public MockCanvas(Bitmap bitmap) {
1442             super(bitmap);
1443         }
1444 
1445         @Override
quickReject(float left, float top, float right, float bottom, EdgeType type)1446         public boolean quickReject(float left, float top, float right,
1447                 float bottom, EdgeType type) {
1448             super.quickReject(left, top, right, bottom, type);
1449             return false;
1450         }
1451 
1452         @Override
save()1453         public int save() {
1454             mIsSaveCalled = true;
1455             return super.save();
1456         }
1457 
1458         @Override
clipRect(int left, int top, int right, int bottom)1459         public boolean clipRect(int left, int top, int right, int bottom) {
1460             mLeft = left;
1461             mTop = top;
1462             mRight = right;
1463             mBottom = bottom;
1464             return super.clipRect(left, top, right, bottom);
1465         }
1466     }
1467 
testSetClipToPadding()1468     public void testSetClipToPadding() {
1469         final int frameLeft = 1;
1470         final int frameTop = 2;
1471         final int frameRight = 100;
1472         final int frameBottom = 200;
1473         MockViewGroup vg = new MockViewGroup(mContext);
1474         vg.layout(frameLeft, frameTop, frameRight, frameBottom);
1475 
1476         vg.setClipToPadding(true);
1477         MockCanvas canvas = new MockCanvas();
1478         final int paddingLeft = 10;
1479         final int paddingTop = 20;
1480         final int paddingRight = 100;
1481         final int paddingBottom = 200;
1482         vg.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
1483         vg.dispatchDraw(canvas);
1484         //check that the clip region does not contain the padding area
1485         assertTrue(canvas.mIsSaveCalled);
1486         assertEquals(10, canvas.mLeft);
1487         assertEquals(20, canvas.mTop);
1488         assertEquals(-frameLeft, canvas.mRight);
1489         assertEquals(-frameTop, canvas.mBottom);
1490 
1491         vg.setClipToPadding(false);
1492         canvas = new MockCanvas();
1493         vg.dispatchDraw(canvas);
1494         assertFalse(canvas.mIsSaveCalled);
1495         assertEquals(0, canvas.mLeft);
1496         assertEquals(0, canvas.mTop);
1497         assertEquals(0, canvas.mRight);
1498         assertEquals(0, canvas.mBottom);
1499     }
1500 
testSetDescendantFocusability()1501     public void testSetDescendantFocusability() {
1502         MockViewGroup vg = new MockViewGroup(mContext);
1503         final int FLAG_MASK_FOCUSABILITY = 0x60000;
1504         assertFalse((vg.getDescendantFocusability() & FLAG_MASK_FOCUSABILITY) == 0);
1505 
1506         vg.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
1507         assertFalse((vg.getDescendantFocusability() & FLAG_MASK_FOCUSABILITY) == 0);
1508 
1509         vg.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
1510         assertFalse((vg.getDescendantFocusability() & FLAG_MASK_FOCUSABILITY) == 0);
1511         assertFalse((vg.getDescendantFocusability() &
1512                 ViewGroup.FOCUS_BEFORE_DESCENDANTS) == 0);
1513     }
1514 
testSetOnHierarchyChangeListener()1515     public void testSetOnHierarchyChangeListener() {
1516         MockViewGroup parent = new MockViewGroup(mContext);
1517         MockViewGroup child = new MockViewGroup(mContext);
1518         MockOnHierarchyChangeListener listener = new MockOnHierarchyChangeListener();
1519         parent.setOnHierarchyChangeListener(listener);
1520         parent.addView(child);
1521 
1522         parent.removeDetachedView(child, false);
1523         assertSame(parent, listener.sParent);
1524         assertSame(child, listener.sChild);
1525     }
1526 
testSetPadding()1527     public void testSetPadding() {
1528         final int left = 1;
1529         final int top = 2;
1530         final int right = 3;
1531         final int bottom = 4;
1532 
1533         MockViewGroup vg = new MockViewGroup(mContext);
1534 
1535         assertEquals(0, vg.getPaddingBottom());
1536         assertEquals(0, vg.getPaddingTop());
1537         assertEquals(0, vg.getPaddingLeft());
1538         assertEquals(0, vg.getPaddingRight());
1539         assertEquals(0, vg.getPaddingStart());
1540         assertEquals(0, vg.getPaddingEnd());
1541 
1542         vg.setPadding(left, top, right, bottom);
1543 
1544         assertEquals(bottom, vg.getPaddingBottom());
1545         assertEquals(top, vg.getPaddingTop());
1546         assertEquals(left, vg.getPaddingLeft());
1547         assertEquals(right, vg.getPaddingRight());
1548 
1549         assertEquals(left, vg.getPaddingStart());
1550         assertEquals(right, vg.getPaddingEnd());
1551         assertEquals(false, vg.isPaddingRelative());
1552 
1553         // force RTL direction
1554         vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
1555 
1556         assertEquals(bottom, vg.getPaddingBottom());
1557         assertEquals(top, vg.getPaddingTop());
1558         assertEquals(left, vg.getPaddingLeft());
1559         assertEquals(right, vg.getPaddingRight());
1560 
1561         assertEquals(right, vg.getPaddingStart());
1562         assertEquals(left, vg.getPaddingEnd());
1563         assertEquals(false, vg.isPaddingRelative());
1564     }
1565 
testSetPaddingRelative()1566     public void testSetPaddingRelative() {
1567         final int start = 1;
1568         final int top = 2;
1569         final int end = 3;
1570         final int bottom = 4;
1571 
1572         MockViewGroup vg = new MockViewGroup(mContext);
1573 
1574         assertEquals(0, vg.getPaddingBottom());
1575         assertEquals(0, vg.getPaddingTop());
1576         assertEquals(0, vg.getPaddingLeft());
1577         assertEquals(0, vg.getPaddingRight());
1578         assertEquals(0, vg.getPaddingStart());
1579         assertEquals(0, vg.getPaddingEnd());
1580 
1581         vg.setPaddingRelative(start, top, end, bottom);
1582 
1583         assertEquals(bottom, vg.getPaddingBottom());
1584         assertEquals(top, vg.getPaddingTop());
1585         assertEquals(start, vg.getPaddingLeft());
1586         assertEquals(end, vg.getPaddingRight());
1587 
1588         assertEquals(start, vg.getPaddingStart());
1589         assertEquals(end, vg.getPaddingEnd());
1590         assertEquals(true, vg.isPaddingRelative());
1591 
1592         // force RTL direction after setting relative padding
1593         vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
1594 
1595         assertEquals(bottom, vg.getPaddingBottom());
1596         assertEquals(top, vg.getPaddingTop());
1597         assertEquals(end, vg.getPaddingLeft());
1598         assertEquals(start, vg.getPaddingRight());
1599 
1600         assertEquals(start, vg.getPaddingStart());
1601         assertEquals(end, vg.getPaddingEnd());
1602         assertEquals(true, vg.isPaddingRelative());
1603 
1604         // force RTL direction before setting relative padding
1605         vg = new MockViewGroup(mContext);
1606         vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
1607 
1608         assertEquals(0, vg.getPaddingBottom());
1609         assertEquals(0, vg.getPaddingTop());
1610         assertEquals(0, vg.getPaddingLeft());
1611         assertEquals(0, vg.getPaddingRight());
1612         assertEquals(0, vg.getPaddingStart());
1613         assertEquals(0, vg.getPaddingEnd());
1614 
1615         vg.setPaddingRelative(start, top, end, bottom);
1616 
1617         assertEquals(bottom, vg.getPaddingBottom());
1618         assertEquals(top, vg.getPaddingTop());
1619         assertEquals(end, vg.getPaddingLeft());
1620         assertEquals(start, vg.getPaddingRight());
1621 
1622         assertEquals(start, vg.getPaddingStart());
1623         assertEquals(end, vg.getPaddingEnd());
1624         assertEquals(true, vg.isPaddingRelative());
1625     }
1626 
testSetPersistentDrawingCache()1627     public void testSetPersistentDrawingCache() {
1628         MockViewGroup vg = new MockViewGroup(mContext);
1629         vg.setPersistentDrawingCache(1);
1630         assertEquals(1 & ViewGroup.PERSISTENT_ALL_CACHES, vg
1631                 .getPersistentDrawingCache());
1632     }
1633 
testShowContextMenuForChild()1634     public void testShowContextMenuForChild() {
1635         MockViewGroup parent = new MockViewGroup(mContext);
1636         MockViewGroup child = new MockViewGroup(mContext);
1637         parent.addView(child);
1638 
1639         child.showContextMenuForChild(null);
1640         assertTrue(parent.isShowContextMenuForChildCalled);
1641     }
1642 
testShowContextMenuForChild_WithXYCoords()1643     public void testShowContextMenuForChild_WithXYCoords() {
1644         MockViewGroup parent = new MockViewGroup(mContext);
1645         MockViewGroup child = new MockViewGroup(mContext);
1646         parent.addView(child);
1647 
1648         child.showContextMenuForChild(null, 48, 48);
1649         assertTrue(parent.isShowContextMenuForChildCalledWithXYCoords);
1650     }
1651 
testStartLayoutAnimation()1652     public void testStartLayoutAnimation() {
1653         MockViewGroup vg = new MockViewGroup(mContext);
1654         RotateAnimation animation = new RotateAnimation(0.1f, 0.1f);
1655         LayoutAnimationController la = new LayoutAnimationController(animation);
1656         vg.setLayoutAnimation(la);
1657 
1658         vg.layout(1, 1, 100, 100);
1659         assertFalse(vg.isLayoutRequested());
1660         vg.startLayoutAnimation();
1661         assertTrue(vg.isLayoutRequested());
1662     }
1663 
testUpdateViewLayout()1664     public void testUpdateViewLayout() {
1665         MockViewGroup parent = new MockViewGroup(mContext);
1666         MockViewGroup child = new MockViewGroup(mContext);
1667 
1668         parent.addView(child);
1669         LayoutParams param = new LayoutParams(100, 200);
1670         parent.updateViewLayout(child, param);
1671         assertEquals(param.width, child.getLayoutParams().width);
1672         assertEquals(param.height, child.getLayoutParams().height);
1673     }
1674 
testDebug()1675     public void testDebug() {
1676         final int EXPECTED = 100;
1677         MockViewGroup parent = new MockViewGroup(mContext);
1678         MockViewGroup child = new MockViewGroup(mContext);
1679         parent.addView(child);
1680 
1681         parent.debug(EXPECTED);
1682         assertEquals(EXPECTED + 1, child.debugDepth);
1683     }
1684 
testDispatchKeyEventPreIme()1685     public void testDispatchKeyEventPreIme() {
1686         MockViewGroup vg = new MockViewGroup(mContext);
1687         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER);
1688         assertFalse(vg.dispatchKeyEventPreIme(event));
1689         assertFalse(vg.dispatchKeyShortcutEvent(event));
1690         MockTextView textView = new MockTextView(mContext);
1691 
1692         vg.addView(textView);
1693         vg.requestChildFocus(textView, null);
1694         vg.layout(0, 0, 100, 200);
1695         assertFalse(vg.dispatchKeyEventPreIme(event));
1696         assertFalse(vg.dispatchKeyShortcutEvent(event));
1697 
1698         vg.requestChildFocus(textView, null);
1699         textView.layout(0, 0, 50, 50);
1700         assertTrue(vg.dispatchKeyEventPreIme(event));
1701         assertTrue(vg.dispatchKeyShortcutEvent(event));
1702 
1703         vg.setStaticTransformationsEnabled(true);
1704         Canvas canvas = new Canvas();
1705         vg.drawChild(canvas, textView, 100);
1706         assertTrue(vg.isGetChildStaticTransformationCalled);
1707         vg.isGetChildStaticTransformationCalled = false;
1708         vg.setStaticTransformationsEnabled(false);
1709         vg.drawChild(canvas, textView, 100);
1710         assertFalse(vg.isGetChildStaticTransformationCalled);
1711     }
1712 
testStartActionModeForChildRespectsSubclassModeOnPrimary()1713     public void testStartActionModeForChildRespectsSubclassModeOnPrimary() {
1714         MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
1715         MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
1716         vg.shouldReturnOwnTypelessActionMode = true;
1717         vgParent.addView(vg);
1718         MockTextView textView = new MockTextView(mContext);
1719         vg.addView(textView);
1720 
1721         textView.startActionMode(NO_OP_ACTION_MODE_CALLBACK, ActionMode.TYPE_PRIMARY);
1722 
1723         assertTrue(vg.isStartActionModeForChildTypedCalled);
1724         assertTrue(vg.isStartActionModeForChildTypelessCalled);
1725         // Call should not bubble up as we have an intercepting implementation.
1726         assertFalse(vgParent.isStartActionModeForChildTypedCalled);
1727     }
1728 
testStartActionModeForChildIgnoresSubclassModeOnFloating()1729     public void testStartActionModeForChildIgnoresSubclassModeOnFloating() {
1730         MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
1731         MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
1732         vg.shouldReturnOwnTypelessActionMode = true;
1733         vgParent.addView(vg);
1734         MockTextView textView = new MockTextView(mContext);
1735         vg.addView(textView);
1736 
1737         textView.startActionMode(NO_OP_ACTION_MODE_CALLBACK, ActionMode.TYPE_FLOATING);
1738 
1739         assertTrue(vg.isStartActionModeForChildTypedCalled);
1740         assertFalse(vg.isStartActionModeForChildTypelessCalled);
1741         // Call should bubble up as we have a floating type.
1742         assertTrue(vgParent.isStartActionModeForChildTypedCalled);
1743     }
1744 
testStartActionModeForChildTypedBubblesUpToParent()1745     public void testStartActionModeForChildTypedBubblesUpToParent() {
1746         MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
1747         MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
1748         vgParent.addView(vg);
1749         MockTextView textView = new MockTextView(mContext);
1750         vg.addView(textView);
1751 
1752         textView.startActionMode(NO_OP_ACTION_MODE_CALLBACK, ActionMode.TYPE_FLOATING);
1753 
1754         assertTrue(vg.isStartActionModeForChildTypedCalled);
1755         assertTrue(vgParent.isStartActionModeForChildTypedCalled);
1756     }
1757 
testStartActionModeForChildTypelessBubblesUpToParent()1758     public void testStartActionModeForChildTypelessBubblesUpToParent() {
1759         MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
1760         MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
1761         vgParent.addView(vg);
1762         MockTextView textView = new MockTextView(mContext);
1763         vg.addView(textView);
1764 
1765         textView.startActionMode(NO_OP_ACTION_MODE_CALLBACK);
1766 
1767         assertTrue(vg.isStartActionModeForChildTypedCalled);
1768         assertTrue(vg.isStartActionModeForChildTypelessCalled);
1769         assertTrue(vgParent.isStartActionModeForChildTypedCalled);
1770     }
1771 
testTemporaryDetach()1772     public void testTemporaryDetach() {
1773         // [vgParent]
1774         //   - [viewParent1]
1775         //   - [viewParent1]
1776         //   - [vg]
1777         //     - [view1]
1778         //     - [view2]
1779         MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
1780         TemporaryDetachingMockView viewParent1 = new TemporaryDetachingMockView(mContext);
1781         TemporaryDetachingMockView viewParent2 = new TemporaryDetachingMockView(mContext);
1782         vgParent.addView(viewParent1);
1783         vgParent.addView(viewParent2);
1784         MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
1785         vgParent.addView(vg);
1786         TemporaryDetachingMockView view1 = new TemporaryDetachingMockView(mContext);
1787         TemporaryDetachingMockView view2 = new TemporaryDetachingMockView(mContext);
1788         vg.addView(view1);
1789         vg.addView(view2);
1790 
1791         // Make sure that no View is temporarity detached in the initial state.
1792         assertFalse(viewParent1.isTemporarilyDetached());
1793         assertEquals(0, viewParent1.getDispatchStartTemporaryDetachCount());
1794         assertEquals(0, viewParent1.getDispatchFinishTemporaryDetachCount());
1795         assertEquals(0, viewParent1.getOnStartTemporaryDetachCount());
1796         assertEquals(0, viewParent1.getOnFinishTemporaryDetachCount());
1797         assertFalse(viewParent2.isTemporarilyDetached());
1798         assertEquals(0, viewParent2.getDispatchStartTemporaryDetachCount());
1799         assertEquals(0, viewParent2.getDispatchFinishTemporaryDetachCount());
1800         assertEquals(0, viewParent2.getOnStartTemporaryDetachCount());
1801         assertEquals(0, viewParent2.getOnFinishTemporaryDetachCount());
1802         assertFalse(view1.isTemporarilyDetached());
1803         assertEquals(0, view1.getDispatchStartTemporaryDetachCount());
1804         assertEquals(0, view1.getDispatchFinishTemporaryDetachCount());
1805         assertEquals(0, view1.getOnStartTemporaryDetachCount());
1806         assertEquals(0, view1.getOnFinishTemporaryDetachCount());
1807         assertFalse(view2.isTemporarilyDetached());
1808         assertEquals(0, view2.getDispatchStartTemporaryDetachCount());
1809         assertEquals(0, view2.getDispatchFinishTemporaryDetachCount());
1810         assertEquals(0, view2.getOnStartTemporaryDetachCount());
1811         assertEquals(0, view2.getOnFinishTemporaryDetachCount());
1812 
1813         // [vgParent]
1814         //   - [viewParent1]
1815         //   - [viewParent1]
1816         //   - [vg]           <- dispatchStartTemporaryDetach()
1817         //     - [view1]
1818         //     - [view2]
1819         vg.dispatchStartTemporaryDetach();
1820 
1821         assertFalse(viewParent1.isTemporarilyDetached());
1822         assertEquals(0, viewParent1.getDispatchStartTemporaryDetachCount());
1823         assertEquals(0, viewParent1.getDispatchFinishTemporaryDetachCount());
1824         assertEquals(0, viewParent1.getOnStartTemporaryDetachCount());
1825         assertEquals(0, viewParent1.getOnFinishTemporaryDetachCount());
1826         assertFalse(viewParent2.isTemporarilyDetached());
1827         assertEquals(0, viewParent2.getDispatchStartTemporaryDetachCount());
1828         assertEquals(0, viewParent2.getDispatchFinishTemporaryDetachCount());
1829         assertEquals(0, viewParent2.getOnStartTemporaryDetachCount());
1830         assertEquals(0, viewParent2.getOnFinishTemporaryDetachCount());
1831         assertTrue(view1.isTemporarilyDetached());
1832         assertEquals(1, view1.getDispatchStartTemporaryDetachCount());
1833         assertEquals(0, view1.getDispatchFinishTemporaryDetachCount());
1834         assertEquals(1, view1.getOnStartTemporaryDetachCount());
1835         assertEquals(0, view1.getOnFinishTemporaryDetachCount());
1836         assertTrue(view2.isTemporarilyDetached());
1837         assertEquals(1, view2.getDispatchStartTemporaryDetachCount());
1838         assertEquals(0, view2.getDispatchFinishTemporaryDetachCount());
1839         assertEquals(1, view2.getOnStartTemporaryDetachCount());
1840         assertEquals(0, view2.getOnFinishTemporaryDetachCount());
1841 
1842         // [vgParent]
1843         //   - [viewParent1]
1844         //   - [viewParent1]
1845         //   - [vg]           <- dispatchFinishTemporaryDetach()
1846         //     - [view1]
1847         //     - [view2]
1848         vg.dispatchFinishTemporaryDetach();
1849 
1850         assertFalse(viewParent1.isTemporarilyDetached());
1851         assertEquals(0, viewParent1.getDispatchStartTemporaryDetachCount());
1852         assertEquals(0, viewParent1.getDispatchFinishTemporaryDetachCount());
1853         assertEquals(0, viewParent1.getOnStartTemporaryDetachCount());
1854         assertEquals(0, viewParent1.getOnFinishTemporaryDetachCount());
1855         assertFalse(viewParent2.isTemporarilyDetached());
1856         assertEquals(0, viewParent2.getDispatchStartTemporaryDetachCount());
1857         assertEquals(0, viewParent2.getDispatchFinishTemporaryDetachCount());
1858         assertEquals(0, viewParent2.getOnStartTemporaryDetachCount());
1859         assertEquals(0, viewParent2.getOnFinishTemporaryDetachCount());
1860         assertFalse(view1.isTemporarilyDetached());
1861         assertEquals(1, view1.getDispatchStartTemporaryDetachCount());
1862         assertEquals(1, view1.getDispatchFinishTemporaryDetachCount());
1863         assertEquals(1, view1.getOnStartTemporaryDetachCount());
1864         assertEquals(1, view1.getOnFinishTemporaryDetachCount());
1865         assertFalse(view2.isTemporarilyDetached());
1866         assertEquals(1, view2.getDispatchStartTemporaryDetachCount());
1867         assertEquals(1, view2.getDispatchFinishTemporaryDetachCount());
1868         assertEquals(1, view2.getOnStartTemporaryDetachCount());
1869         assertEquals(1, view2.getOnFinishTemporaryDetachCount());
1870 
1871         // [vgParent]         <- dispatchStartTemporaryDetach()
1872         //   - [viewParent1]
1873         //   - [viewParent1]
1874         //   - [vg]
1875         //     - [view1]
1876         //     - [view2]
1877         vgParent.dispatchStartTemporaryDetach();
1878 
1879         assertTrue(viewParent1.isTemporarilyDetached());
1880         assertEquals(1, viewParent1.getDispatchStartTemporaryDetachCount());
1881         assertEquals(0, viewParent1.getDispatchFinishTemporaryDetachCount());
1882         assertEquals(1, viewParent1.getOnStartTemporaryDetachCount());
1883         assertEquals(0, viewParent1.getOnFinishTemporaryDetachCount());
1884         assertTrue(viewParent2.isTemporarilyDetached());
1885         assertEquals(1, viewParent2.getDispatchStartTemporaryDetachCount());
1886         assertEquals(0, viewParent2.getDispatchFinishTemporaryDetachCount());
1887         assertEquals(1, viewParent2.getOnStartTemporaryDetachCount());
1888         assertEquals(0, viewParent2.getOnFinishTemporaryDetachCount());
1889         assertTrue(view1.isTemporarilyDetached());
1890         assertEquals(2, view1.getDispatchStartTemporaryDetachCount());
1891         assertEquals(1, view1.getDispatchFinishTemporaryDetachCount());
1892         assertEquals(2, view1.getOnStartTemporaryDetachCount());
1893         assertEquals(1, view1.getOnFinishTemporaryDetachCount());
1894         assertTrue(view2.isTemporarilyDetached());
1895         assertEquals(2, view2.getDispatchStartTemporaryDetachCount());
1896         assertEquals(1, view2.getDispatchFinishTemporaryDetachCount());
1897         assertEquals(2, view2.getOnStartTemporaryDetachCount());
1898         assertEquals(1, view2.getOnFinishTemporaryDetachCount());
1899 
1900         // [vgParent]         <- dispatchFinishTemporaryDetach()
1901         //   - [viewParent1]
1902         //   - [viewParent1]
1903         //   - [vg]
1904         //     - [view1]
1905         //     - [view2]
1906         vgParent.dispatchFinishTemporaryDetach();
1907 
1908         assertFalse(viewParent1.isTemporarilyDetached());
1909         assertEquals(1, viewParent1.getDispatchStartTemporaryDetachCount());
1910         assertEquals(1, viewParent1.getDispatchFinishTemporaryDetachCount());
1911         assertEquals(1, viewParent1.getOnStartTemporaryDetachCount());
1912         assertEquals(1, viewParent1.getOnFinishTemporaryDetachCount());
1913         assertFalse(viewParent2.isTemporarilyDetached());
1914         assertEquals(1, viewParent2.getDispatchStartTemporaryDetachCount());
1915         assertEquals(1, viewParent2.getDispatchFinishTemporaryDetachCount());
1916         assertEquals(1, viewParent2.getOnStartTemporaryDetachCount());
1917         assertEquals(1, viewParent2.getOnFinishTemporaryDetachCount());
1918         assertFalse(view1.isTemporarilyDetached());
1919         assertEquals(2, view1.getDispatchStartTemporaryDetachCount());
1920         assertEquals(2, view1.getDispatchFinishTemporaryDetachCount());
1921         assertEquals(2, view1.getOnStartTemporaryDetachCount());
1922         assertEquals(2, view1.getOnFinishTemporaryDetachCount());
1923         assertFalse(view2.isTemporarilyDetached());
1924         assertEquals(2, view2.getDispatchStartTemporaryDetachCount());
1925         assertEquals(2, view2.getDispatchFinishTemporaryDetachCount());
1926         assertEquals(2, view2.getOnStartTemporaryDetachCount());
1927         assertEquals(2, view2.getOnFinishTemporaryDetachCount());
1928     }
1929 
1930     private static final ActionMode.Callback NO_OP_ACTION_MODE_CALLBACK =
1931             new ActionMode.Callback() {
1932                 @Override
1933                 public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
1934                     return false;
1935                 }
1936 
1937                 @Override
1938                 public void onDestroyActionMode(ActionMode mode) {}
1939 
1940                 @Override
1941                 public boolean onCreateActionMode(ActionMode mode, Menu menu) {
1942                     return false;
1943                 }
1944 
1945                 @Override
1946                 public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
1947                     return false;
1948                 }
1949             };
1950 
1951     private static final ActionMode NO_OP_ACTION_MODE =
1952             new ActionMode() {
1953                 @Override
1954                 public void setTitle(CharSequence title) {}
1955 
1956                 @Override
1957                 public void setTitle(int resId) {}
1958 
1959                 @Override
1960                 public void setSubtitle(CharSequence subtitle) {}
1961 
1962                 @Override
1963                 public void setSubtitle(int resId) {}
1964 
1965                 @Override
1966                 public void setCustomView(View view) {}
1967 
1968                 @Override
1969                 public void invalidate() {}
1970 
1971                 @Override
1972                 public void finish() {}
1973 
1974                 @Override
1975                 public Menu getMenu() {
1976                     return null;
1977                 }
1978 
1979                 @Override
1980                 public CharSequence getTitle() {
1981                     return null;
1982                 }
1983 
1984                 @Override
1985                 public CharSequence getSubtitle() {
1986                     return null;
1987                 }
1988 
1989                 @Override
1990                 public View getCustomView() {
1991                     return null;
1992                 }
1993 
1994                 @Override
1995                 public MenuInflater getMenuInflater() {
1996                     return null;
1997                 }
1998             };
1999 
2000     private static class MockViewGroupSubclass extends ViewGroup {
2001         boolean isStartActionModeForChildTypedCalled = false;
2002         boolean isStartActionModeForChildTypelessCalled = false;
2003         boolean shouldReturnOwnTypelessActionMode = false;
2004 
MockViewGroupSubclass(Context context)2005         public MockViewGroupSubclass(Context context) {
2006             super(context);
2007         }
2008 
2009         @Override
startActionModeForChild(View originalView, ActionMode.Callback callback)2010         public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
2011             isStartActionModeForChildTypelessCalled = true;
2012             if (shouldReturnOwnTypelessActionMode) {
2013                 return NO_OP_ACTION_MODE;
2014             }
2015             return super.startActionModeForChild(originalView, callback);
2016         }
2017 
2018         @Override
startActionModeForChild( View originalView, ActionMode.Callback callback, int type)2019         public ActionMode startActionModeForChild(
2020                 View originalView, ActionMode.Callback callback, int type) {
2021             isStartActionModeForChildTypedCalled = true;
2022             return super.startActionModeForChild(originalView, callback, type);
2023         }
2024 
2025         @Override
onLayout(boolean changed, int l, int t, int r, int b)2026         protected void onLayout(boolean changed, int l, int t, int r, int b) {
2027             // no-op
2028         }
2029     }
2030 
2031     static public int resetRtlPropertiesCount;
2032     static public int resetResolvedLayoutDirectionCount;
2033     static public int resetResolvedTextDirectionCount;
2034     static public int resetResolvedTextAlignmentCount;
2035     static public int resetResolvedPaddingCount;
2036     static public int resetResolvedDrawablesCount;
2037 
2038 
clearRtlCounters()2039     private static void clearRtlCounters() {
2040         resetRtlPropertiesCount = 0;
2041         resetResolvedLayoutDirectionCount = 0;
2042         resetResolvedTextDirectionCount = 0;
2043         resetResolvedTextAlignmentCount = 0;
2044         resetResolvedPaddingCount = 0;
2045         resetResolvedDrawablesCount = 0;
2046     }
2047 
testResetRtlProperties()2048     public void testResetRtlProperties() {
2049         clearRtlCounters();
2050 
2051         MockViewGroup vg = new MockViewGroup(mContext);
2052         MockView2 v1 = new MockView2(mContext);
2053         MockView2 v2 = new MockView2(mContext);
2054 
2055         MockViewGroup v3 = new MockViewGroup(mContext);
2056         MockView2 v4 = new MockView2(mContext);
2057 
2058         v3.addView(v4);
2059         assertEquals(1, resetRtlPropertiesCount);
2060         assertEquals(1, resetResolvedLayoutDirectionCount);
2061         assertEquals(1, resetResolvedTextDirectionCount);
2062         assertEquals(1, resetResolvedTextAlignmentCount);
2063         assertEquals(1, resetResolvedPaddingCount);
2064         assertEquals(1, resetResolvedDrawablesCount);
2065 
2066         clearRtlCounters();
2067         vg.addView(v1);
2068         vg.addView(v2);
2069         vg.addView(v3);
2070 
2071         assertEquals(3, resetRtlPropertiesCount); // for v1 / v2 / v3 only
2072         assertEquals(4, resetResolvedLayoutDirectionCount); // for v1 / v2 / v3 / v4
2073         assertEquals(4, resetResolvedTextDirectionCount);
2074         assertEquals(3, resetResolvedTextAlignmentCount); // for v1 / v2 / v3 only
2075         assertEquals(4, resetResolvedPaddingCount);
2076         assertEquals(4, resetResolvedDrawablesCount);
2077 
2078         clearRtlCounters();
2079         vg.resetRtlProperties();
2080         assertEquals(1, resetRtlPropertiesCount); // for vg only
2081         assertEquals(5, resetResolvedLayoutDirectionCount); // for all
2082         assertEquals(5, resetResolvedTextDirectionCount);
2083         assertEquals(1, resetResolvedTextAlignmentCount); // for vg only as TextAlignment is not inherited (default is Gravity)
2084         assertEquals(5, resetResolvedPaddingCount);
2085         assertEquals(5, resetResolvedDrawablesCount);
2086     }
2087 
2088     static class MockTextView extends TextView {
2089 
2090         public boolean isClearFocusCalled;
2091         public boolean isDispatchRestoreInstanceStateCalled;
2092         public int visibility;
2093         public boolean mIsRefreshDrawableStateCalled;
2094         public boolean isDrawCalled;
2095 
MockTextView(Context context)2096         public MockTextView(Context context) {
2097             super(context);
2098         }
2099 
2100         @Override
draw(Canvas canvas)2101         public void draw(Canvas canvas) {
2102             super.draw(canvas);
2103             isDrawCalled = true;
2104         }
2105 
2106         @Override
clearFocus()2107         public void clearFocus() {
2108             isClearFocusCalled = true;
2109             super.clearFocus();
2110         }
2111 
2112         @Override
dispatchKeyEvent(KeyEvent event)2113         public boolean dispatchKeyEvent(KeyEvent event) {
2114             return true;
2115         }
2116 
2117         @Override
dispatchRestoreInstanceState( SparseArray<Parcelable> container)2118         public void dispatchRestoreInstanceState(
2119                 SparseArray<Parcelable> container) {
2120             isDispatchRestoreInstanceStateCalled = true;
2121             super.dispatchRestoreInstanceState(container);
2122         }
2123 
2124         @Override
onTrackballEvent(MotionEvent event)2125         public boolean onTrackballEvent(MotionEvent event) {
2126             return true;
2127         }
2128 
2129         @Override
dispatchUnhandledMove(View focused, int direction)2130         public boolean dispatchUnhandledMove(View focused, int direction) {
2131             return true;
2132         }
2133 
2134         @Override
onWindowVisibilityChanged(int visibility)2135         public void onWindowVisibilityChanged(int visibility) {
2136             this.visibility = visibility;
2137             super.onWindowVisibilityChanged(visibility);
2138         }
2139 
2140         @Override
refreshDrawableState()2141         public void refreshDrawableState() {
2142             mIsRefreshDrawableStateCalled = true;
2143             super.refreshDrawableState();
2144         }
2145 
2146         @Override
dispatchTouchEvent(MotionEvent event)2147         public boolean dispatchTouchEvent(MotionEvent event) {
2148             super.dispatchTouchEvent(event);
2149             return true;
2150         }
2151 
2152         @Override
dispatchKeyEventPreIme(KeyEvent event)2153         public boolean dispatchKeyEventPreIme(KeyEvent event) {
2154             return true;
2155         }
2156 
2157         @Override
dispatchKeyShortcutEvent(KeyEvent event)2158         public boolean dispatchKeyShortcutEvent(KeyEvent event) {
2159             return true;
2160         }
2161     }
2162 
2163     static class MockViewGroup extends ViewGroup {
2164 
2165         public boolean isRecomputeViewAttributesCalled;
2166         public boolean isShowContextMenuForChildCalled;
2167         public boolean isShowContextMenuForChildCalledWithXYCoords;
2168         public boolean isRefreshDrawableStateCalled;
2169         public boolean isOnRestoreInstanceStateCalled;
2170         public boolean isOnCreateDrawableStateCalled;
2171         public boolean isOnInterceptTouchEventCalled;
2172         public boolean isOnRequestFocusInDescendantsCalled;
2173         public boolean isFocusableViewAvailable;
2174         public boolean isDispatchDrawCalled;
2175         public boolean isRequestDisallowInterceptTouchEventCalled;
2176         public boolean isRequestTransparentRegionCalled;
2177         public boolean isGetChildStaticTransformationCalled;
2178         public int[] location;
2179         public int measureChildCalledTime;
2180         public boolean isOnAnimationEndCalled;
2181         public boolean isOnAnimationStartCalled;
2182         public int debugDepth;
2183         public int drawChildCalledTime;
2184         public Canvas canvas;
2185         public boolean isDrawableStateChangedCalled;
2186         public boolean isRequestLayoutCalled;
2187         public boolean isOnLayoutCalled;
2188         public int left;
2189         public int top;
2190         public int right;
2191         public int bottom;
2192 
MockViewGroup(Context context, AttributeSet attrs, int defStyle)2193         public MockViewGroup(Context context, AttributeSet attrs, int defStyle) {
2194             super(context, attrs, defStyle);
2195         }
2196 
MockViewGroup(Context context, AttributeSet attrs)2197         public MockViewGroup(Context context, AttributeSet attrs) {
2198             super(context, attrs);
2199         }
2200 
MockViewGroup(Context context)2201         public MockViewGroup(Context context) {
2202             super(context);
2203         }
2204 
2205         @Override
onLayout(boolean changed, int l, int t, int r, int b)2206         public void onLayout(boolean changed, int l, int t, int r, int b) {
2207             isOnLayoutCalled = true;
2208             left = l;
2209             top = t;
2210             right = r;
2211             bottom = b;
2212         }
2213 
2214         @Override
addViewInLayout(View child, int index, ViewGroup.LayoutParams params)2215         public boolean addViewInLayout(View child, int index,
2216                 ViewGroup.LayoutParams params) {
2217             return super.addViewInLayout(child, index, params);
2218         }
2219 
2220         @Override
addViewInLayout(View child, int index, ViewGroup.LayoutParams params, boolean preventRequestLayout)2221         public boolean addViewInLayout(View child, int index,
2222                 ViewGroup.LayoutParams params, boolean preventRequestLayout) {
2223             return super.addViewInLayout(child, index, params, preventRequestLayout);
2224         }
2225 
2226         @Override
attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params, int index, int count)2227         public void attachLayoutAnimationParameters(View child,
2228                 ViewGroup.LayoutParams params, int index, int count) {
2229             super.attachLayoutAnimationParameters(child, params, index, count);
2230         }
2231 
2232         @Override
attachViewToParent(View child, int index, LayoutParams params)2233         public void attachViewToParent(View child, int index,
2234                 LayoutParams params) {
2235             super.attachViewToParent(child, index, params);
2236         }
2237 
2238         @Override
canAnimate()2239         public boolean canAnimate() {
2240             return super.canAnimate();
2241         }
2242 
2243         @Override
checkLayoutParams(LayoutParams p)2244         public boolean checkLayoutParams(LayoutParams p) {
2245             return super.checkLayoutParams(p);
2246         }
2247 
2248         @Override
refreshDrawableState()2249         public void refreshDrawableState() {
2250             isRefreshDrawableStateCalled = true;
2251             super.refreshDrawableState();
2252         }
2253 
2254         @Override
cleanupLayoutState(View child)2255         public void cleanupLayoutState(View child) {
2256             super.cleanupLayoutState(child);
2257         }
2258 
2259         @Override
detachAllViewsFromParent()2260         public void detachAllViewsFromParent() {
2261             super.detachAllViewsFromParent();
2262         }
2263 
2264         @Override
detachViewFromParent(int index)2265         public void detachViewFromParent(int index) {
2266             super.detachViewFromParent(index);
2267         }
2268 
2269         @Override
detachViewFromParent(View child)2270         public void detachViewFromParent(View child) {
2271             super.detachViewFromParent(child);
2272         }
2273         @Override
2274 
detachViewsFromParent(int start, int count)2275         public void detachViewsFromParent(int start, int count) {
2276             super.detachViewsFromParent(start, count);
2277         }
2278 
2279         @Override
dispatchDraw(Canvas canvas)2280         public void dispatchDraw(Canvas canvas) {
2281             isDispatchDrawCalled = true;
2282             super.dispatchDraw(canvas);
2283             this.canvas = canvas;
2284         }
2285 
2286         @Override
dispatchFreezeSelfOnly(SparseArray<Parcelable> container)2287         public void dispatchFreezeSelfOnly(SparseArray<Parcelable> container) {
2288             super.dispatchFreezeSelfOnly(container);
2289         }
2290 
2291         @Override
dispatchRestoreInstanceState( SparseArray<Parcelable> container)2292         public void dispatchRestoreInstanceState(
2293                 SparseArray<Parcelable> container) {
2294             super.dispatchRestoreInstanceState(container);
2295         }
2296 
2297         @Override
dispatchSaveInstanceState( SparseArray<Parcelable> container)2298         public void dispatchSaveInstanceState(
2299                 SparseArray<Parcelable> container) {
2300             super.dispatchSaveInstanceState(container);
2301         }
2302 
2303         @Override
dispatchSetPressed(boolean pressed)2304         public void dispatchSetPressed(boolean pressed) {
2305             super.dispatchSetPressed(pressed);
2306         }
2307 
2308         @Override
dispatchThawSelfOnly(SparseArray<Parcelable> container)2309         public void dispatchThawSelfOnly(SparseArray<Parcelable> container) {
2310             super.dispatchThawSelfOnly(container);
2311         }
2312 
2313         @Override
onRestoreInstanceState(Parcelable state)2314         public void onRestoreInstanceState(Parcelable state) {
2315             isOnRestoreInstanceStateCalled = true;
2316             super.onRestoreInstanceState(state);
2317         }
2318 
2319         @Override
drawableStateChanged()2320         public void drawableStateChanged() {
2321             isDrawableStateChangedCalled = true;
2322             super.drawableStateChanged();
2323         }
2324 
2325         @Override
drawChild(Canvas canvas, View child, long drawingTime)2326         public boolean drawChild(Canvas canvas, View child, long drawingTime) {
2327             drawChildCalledTime++;
2328             return super.drawChild(canvas, child, drawingTime);
2329         }
2330 
2331         @Override
fitSystemWindows(Rect insets)2332         public boolean fitSystemWindows(Rect insets) {
2333             return super.fitSystemWindows(insets);
2334         }
2335 
2336         @Override
generateDefaultLayoutParams()2337         public LayoutParams generateDefaultLayoutParams() {
2338             return super.generateDefaultLayoutParams();
2339         }
2340 
2341         @Override
generateLayoutParams(LayoutParams p)2342         public LayoutParams generateLayoutParams(LayoutParams p) {
2343             return super.generateLayoutParams(p);
2344         }
2345 
2346         @Override
getChildDrawingOrder(int childCount, int i)2347         public int getChildDrawingOrder(int childCount, int i) {
2348             return super.getChildDrawingOrder(childCount, i);
2349         }
2350 
2351         @Override
getChildStaticTransformation(View child, Transformation t)2352         public boolean getChildStaticTransformation(View child,
2353                 Transformation t) {
2354             isGetChildStaticTransformationCalled = true;
2355             return super.getChildStaticTransformation(child, t);
2356         }
2357 
2358         @Override
measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec)2359         public void measureChild(View child, int parentWidthMeasureSpec,
2360                 int parentHeightMeasureSpec) {
2361             measureChildCalledTime++;
2362             super.measureChild(child, parentWidthMeasureSpec, parentHeightMeasureSpec);
2363         }
2364 
2365         @Override
measureChildren(int widthMeasureSpec, int heightMeasureSpec)2366         public void measureChildren(int widthMeasureSpec,
2367                 int heightMeasureSpec) {
2368             super.measureChildren(widthMeasureSpec, heightMeasureSpec);
2369         }
2370 
2371         @Override
measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)2372         public void measureChildWithMargins(View child,
2373                 int parentWidthMeasureSpec, int widthUsed,
2374                 int parentHeightMeasureSpec, int heightUsed) {
2375             super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed,
2376                     parentHeightMeasureSpec, heightUsed);
2377         }
2378 
2379         @Override
onAnimationEnd()2380         public void onAnimationEnd() {
2381             isOnAnimationEndCalled = true;
2382             super.onAnimationEnd();
2383         }
2384 
2385         @Override
onAnimationStart()2386         public void onAnimationStart() {
2387             super.onAnimationStart();
2388             isOnAnimationStartCalled = true;
2389         }
2390 
2391         @Override
onCreateDrawableState(int extraSpace)2392         public int[] onCreateDrawableState(int extraSpace) {
2393             isOnCreateDrawableStateCalled = true;
2394             return super.onCreateDrawableState(extraSpace);
2395         }
2396 
2397         @Override
onInterceptTouchEvent(MotionEvent ev)2398         public boolean onInterceptTouchEvent(MotionEvent ev) {
2399             isOnInterceptTouchEventCalled = true;
2400             return super.onInterceptTouchEvent(ev);
2401         }
2402 
2403         @Override
onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect)2404         public boolean onRequestFocusInDescendants(int direction,
2405                 Rect previouslyFocusedRect) {
2406             isOnRequestFocusInDescendantsCalled = true;
2407             return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
2408         }
2409 
2410         @Override
recomputeViewAttributes(View child)2411         public void recomputeViewAttributes(View child) {
2412             isRecomputeViewAttributesCalled = true;
2413             super.recomputeViewAttributes(child);
2414         }
2415 
2416         @Override
removeDetachedView(View child, boolean animate)2417         public void removeDetachedView(View child, boolean animate) {
2418             super.removeDetachedView(child, animate);
2419         }
2420 
2421         @Override
showContextMenuForChild(View originalView)2422         public boolean showContextMenuForChild(View originalView) {
2423             isShowContextMenuForChildCalled = true;
2424             return super.showContextMenuForChild(originalView);
2425         }
2426 
2427         @Override
showContextMenuForChild(View originalView, float x, float y)2428         public boolean showContextMenuForChild(View originalView, float x, float y) {
2429             isShowContextMenuForChildCalledWithXYCoords = true;
2430             return super.showContextMenuForChild(originalView, x, y);
2431         }
2432 
2433         @Override
isInTouchMode()2434         public boolean isInTouchMode() {
2435             super.isInTouchMode();
2436             return false;
2437         }
2438 
2439         @Override
focusableViewAvailable(View v)2440         public void focusableViewAvailable(View v) {
2441             isFocusableViewAvailable = true;
2442             super.focusableViewAvailable(v);
2443         }
2444 
2445         @Override
focusSearch(View focused, int direction)2446         public View focusSearch(View focused, int direction) {
2447             super.focusSearch(focused, direction);
2448             return focused;
2449         }
2450 
2451         @Override
requestDisallowInterceptTouchEvent(boolean disallowIntercept)2452         public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
2453             isRequestDisallowInterceptTouchEventCalled = true;
2454             super.requestDisallowInterceptTouchEvent(disallowIntercept);
2455         }
2456 
2457         @Override
requestTransparentRegion(View child)2458         public void requestTransparentRegion(View child) {
2459             isRequestTransparentRegionCalled = true;
2460             super.requestTransparentRegion(child);
2461         }
2462 
2463         @Override
debug(int depth)2464         public void debug(int depth) {
2465             debugDepth = depth;
2466             super.debug(depth);
2467         }
2468 
2469         @Override
requestLayout()2470         public void requestLayout() {
2471             isRequestLayoutCalled = true;
2472             super.requestLayout();
2473         }
2474 
2475         @Override
setStaticTransformationsEnabled(boolean enabled)2476         public void setStaticTransformationsEnabled(boolean enabled) {
2477             super.setStaticTransformationsEnabled(enabled);
2478         }
2479 
2480         @Override
resetRtlProperties()2481         public void resetRtlProperties() {
2482             super.resetRtlProperties();
2483             resetRtlPropertiesCount++;
2484         }
2485 
2486         @Override
resetResolvedLayoutDirection()2487         public void resetResolvedLayoutDirection() {
2488             super.resetResolvedLayoutDirection();
2489             resetResolvedLayoutDirectionCount++;
2490         }
2491 
2492         @Override
resetResolvedTextDirection()2493         public void resetResolvedTextDirection() {
2494             super.resetResolvedTextDirection();
2495             resetResolvedTextDirectionCount++;
2496         }
2497 
2498         @Override
resetResolvedTextAlignment()2499         public void resetResolvedTextAlignment() {
2500             super.resetResolvedTextAlignment();
2501             resetResolvedTextAlignmentCount++;
2502         }
2503 
2504         @Override
resetResolvedPadding()2505         public void resetResolvedPadding() {
2506             super.resetResolvedPadding();
2507             resetResolvedPaddingCount++;
2508         }
2509 
2510         @Override
resetResolvedDrawables()2511         protected void resetResolvedDrawables() {
2512             super.resetResolvedDrawables();
2513             resetResolvedDrawablesCount++;
2514         }
2515 
2516         @Override
setFrame(int left, int top, int right, int bottom)2517         public boolean setFrame(int left, int top, int right, int bottom) {
2518             return super.setFrame(left, top, right, bottom);
2519         }
2520 
2521         @Override
setChildrenDrawnWithCacheEnabled(boolean enabled)2522         public void setChildrenDrawnWithCacheEnabled(boolean enabled) {
2523             super.setChildrenDrawnWithCacheEnabled(enabled);
2524         }
2525 
2526         @Override
isChildrenDrawnWithCacheEnabled()2527         public boolean isChildrenDrawnWithCacheEnabled() {
2528             return super.isChildrenDrawnWithCacheEnabled();
2529         }
2530     }
2531 
2532     static class MockView2 extends View {
2533 
MockView2(Context context)2534         public MockView2(Context context) {
2535             super(context);
2536         }
2537 
MockView2(Context context, AttributeSet attrs)2538         public MockView2(Context context, AttributeSet attrs) {
2539             super(context, attrs);
2540         }
2541 
MockView2(Context context, AttributeSet attrs, int defStyle)2542         public MockView2(Context context, AttributeSet attrs, int defStyle) {
2543             super(context, attrs, defStyle);
2544         }
2545 
2546         @Override
resetRtlProperties()2547         public void resetRtlProperties() {
2548             super.resetRtlProperties();
2549             resetRtlPropertiesCount++;
2550         }
2551 
2552         @Override
resetResolvedLayoutDirection()2553         public void resetResolvedLayoutDirection() {
2554             super.resetResolvedLayoutDirection();
2555             resetResolvedLayoutDirectionCount++;
2556         }
2557 
2558         @Override
resetResolvedTextDirection()2559         public void resetResolvedTextDirection() {
2560             super.resetResolvedTextDirection();
2561             resetResolvedTextDirectionCount++;
2562         }
2563 
2564         @Override
resetResolvedTextAlignment()2565         public void resetResolvedTextAlignment() {
2566             super.resetResolvedTextAlignment();
2567             resetResolvedTextAlignmentCount++;
2568         }
2569 
2570         @Override
resetResolvedPadding()2571         public void resetResolvedPadding() {
2572             super.resetResolvedPadding();
2573             resetResolvedPaddingCount++;
2574         }
2575 
2576         @Override
resetResolvedDrawables()2577         protected void resetResolvedDrawables() {
2578             super.resetResolvedDrawables();
2579             resetResolvedDrawablesCount++;
2580         }
2581     }
2582 
2583     static final class TemporaryDetachingMockView extends View {
2584         private int mDispatchStartTemporaryDetachCount = 0;
2585         private int mDispatchFinishTemporaryDetachCount = 0;
2586         private int mOnStartTemporaryDetachCount = 0;
2587         private int mOnFinishTemporaryDetachCount = 0;
2588 
TemporaryDetachingMockView(Context context)2589         public TemporaryDetachingMockView(Context context) {
2590             super(context);
2591         }
2592 
2593         @Override
dispatchStartTemporaryDetach()2594         public void dispatchStartTemporaryDetach() {
2595             super.dispatchStartTemporaryDetach();
2596             mDispatchStartTemporaryDetachCount += 1;
2597         }
2598 
2599         @Override
dispatchFinishTemporaryDetach()2600         public void dispatchFinishTemporaryDetach() {
2601             super.dispatchFinishTemporaryDetach();
2602             mDispatchFinishTemporaryDetachCount += 1;
2603         }
2604 
2605         @Override
onStartTemporaryDetach()2606         public void onStartTemporaryDetach() {
2607             super.onStartTemporaryDetach();
2608             mOnStartTemporaryDetachCount += 1;
2609         }
2610 
2611         @Override
onFinishTemporaryDetach()2612         public void onFinishTemporaryDetach() {
2613             super.onFinishTemporaryDetach();
2614             mOnFinishTemporaryDetachCount += 1;
2615         }
2616 
getDispatchStartTemporaryDetachCount()2617         public int getDispatchStartTemporaryDetachCount() {
2618             return mDispatchStartTemporaryDetachCount;
2619         }
2620 
getDispatchFinishTemporaryDetachCount()2621         public int getDispatchFinishTemporaryDetachCount() {
2622             return mDispatchFinishTemporaryDetachCount;
2623         }
2624 
getOnStartTemporaryDetachCount()2625         public int getOnStartTemporaryDetachCount() {
2626             return mOnStartTemporaryDetachCount;
2627         }
2628 
getOnFinishTemporaryDetachCount()2629         public int getOnFinishTemporaryDetachCount() {
2630             return mOnFinishTemporaryDetachCount;
2631         }
2632     }
2633 
2634     @Override
setResult(int resultCode)2635     public void setResult(int resultCode) {
2636         synchronized (mSync) {
2637             mSync.mHasNotify = true;
2638             mSync.notify();
2639             mResultCode = resultCode;
2640         }
2641     }
2642 }
2643