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.widget.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertSame;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26 import static org.mockito.Mockito.any;
27 import static org.mockito.Mockito.eq;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.reset;
30 import static org.mockito.Mockito.times;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.verifyZeroInteractions;
33 
34 import android.Manifest;
35 import android.app.Instrumentation;
36 import android.content.Context;
37 import android.database.DataSetObserver;
38 import android.graphics.Canvas;
39 import android.graphics.drawable.BitmapDrawable;
40 import android.graphics.drawable.Drawable;
41 import android.os.Parcelable;
42 import android.util.AttributeSet;
43 import android.util.Xml;
44 import android.view.LayoutInflater;
45 import android.view.View;
46 import android.view.ViewGroup;
47 import android.view.accessibility.AccessibilityEvent;
48 import android.view.accessibility.AccessibilityNodeInfo;
49 import android.widget.AbsListView;
50 import android.widget.ExpandableListAdapter;
51 import android.widget.ExpandableListView;
52 import android.widget.ListAdapter;
53 import android.widget.TextView;
54 import android.widget.cts.util.ExpandableListScenario;
55 
56 import androidx.test.InstrumentationRegistry;
57 import androidx.test.annotation.UiThreadTest;
58 import androidx.test.filters.MediumTest;
59 import androidx.test.rule.ActivityTestRule;
60 import androidx.test.runner.AndroidJUnit4;
61 
62 import com.android.compatibility.common.util.AdoptShellPermissionsRule;
63 import com.android.compatibility.common.util.ApiTest;
64 import com.android.compatibility.common.util.WidgetTestUtils;
65 import com.android.compatibility.common.util.WindowUtil;
66 
67 import org.junit.Before;
68 import org.junit.Rule;
69 import org.junit.Test;
70 import org.junit.runner.RunWith;
71 import org.xmlpull.v1.XmlPullParser;
72 
73 @MediumTest
74 @RunWith(AndroidJUnit4.class)
75 public class ExpandableListViewTest {
76     private Instrumentation mInstrumentation;
77     private ExpandableListScenario mActivity;
78     private ExpandableListView mExpandableListView;
79 
80     @Rule(order = 0)
81     public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule(
82             androidx.test.platform.app.InstrumentationRegistry
83                     .getInstrumentation().getUiAutomation(),
84             Manifest.permission.START_ACTIVITIES_FROM_SDK_SANDBOX);
85 
86     @Rule(order = 1)
87     public ActivityTestRule<ExpandableList> mActivityRule =
88             new ActivityTestRule<>(ExpandableList.class);
89 
90     @Before
setup()91     public void setup() {
92         mInstrumentation = InstrumentationRegistry.getInstrumentation();
93         mActivity = mActivityRule.getActivity();
94         WindowUtil.waitForFocus(mActivity);
95         mExpandableListView = mActivity.getExpandableListView();
96     }
97 
98     @Test
testConstructor()99     public void testConstructor() {
100         new ExpandableListView(mActivity);
101 
102         new ExpandableListView(mActivity, null);
103 
104         new ExpandableListView(mActivity, null, android.R.attr.expandableListViewStyle);
105 
106         new ExpandableListView(mActivity, null, 0,
107                 android.R.style.Widget_DeviceDefault_ExpandableListView);
108 
109         new ExpandableListView(mActivity, null, 0,
110                 android.R.style.Widget_DeviceDefault_Light_ExpandableListView);
111 
112         new ExpandableListView(mActivity, null, 0,
113                 android.R.style.Widget_Material_ExpandableListView);
114 
115         new ExpandableListView(mActivity, null, 0,
116                 android.R.style.Widget_Material_Light_ExpandableListView);
117 
118         XmlPullParser parser =
119                 mActivity.getResources().getXml(R.layout.expandablelistview_layout);
120         AttributeSet attrs = Xml.asAttributeSet(parser);
121         new ExpandableListView(mActivity, attrs);
122         new ExpandableListView(mActivity, attrs, 0);
123     }
124 
125     @Test(expected=NullPointerException.class)
testConstructorWithNullContext1()126     public void testConstructorWithNullContext1() {
127         new ExpandableListView(null);
128     }
129 
130     @Test(expected=NullPointerException.class)
testConstructorWithNullContext2()131     public void testConstructorWithNullContext2() {
132         new ExpandableListView(null, null);
133     }
134 
135     @Test(expected=NullPointerException.class)
testConstructorWithNullContext3()136     public void testConstructorWithNullContext3() {
137         new ExpandableListView(null, null, 0);
138     }
139 
140     @Test
testSetChildDivider()141     public void testSetChildDivider() {
142         Drawable drawable = mActivity.getResources().getDrawable(R.drawable.scenery);
143         mExpandableListView.setChildDivider(drawable);
144     }
145 
146     @Test(expected=RuntimeException.class)
testSetAdapterOfWrongType()147     public void testSetAdapterOfWrongType() {
148         mExpandableListView.setAdapter((ListAdapter) null);
149     }
150 
151     @UiThreadTest
152     @Test
testGetAdapter()153     public void testGetAdapter() {
154         assertNull(mExpandableListView.getAdapter());
155 
156         ExpandableListAdapter expandableAdapter = new MockExpandableListAdapter();
157         mExpandableListView.setAdapter(expandableAdapter);
158         assertNotNull(mExpandableListView.getAdapter());
159     }
160 
161     @UiThreadTest
162     @Test
testAccessExpandableListAdapter()163     public void testAccessExpandableListAdapter() {
164         ExpandableListAdapter expandableAdapter = new MockExpandableListAdapter();
165 
166         assertNull(mExpandableListView.getExpandableListAdapter());
167         mExpandableListView.setAdapter(expandableAdapter);
168         assertSame(expandableAdapter, mExpandableListView.getExpandableListAdapter());
169     }
170 
171     @UiThreadTest
172     @Test
testPerformItemClick()173     public void testPerformItemClick() {
174         assertFalse(mExpandableListView.performItemClick(null, 100, 99));
175 
176         ExpandableListView.OnItemClickListener mockOnItemClickListener =
177                 mock(ExpandableListView.OnItemClickListener.class);
178         mExpandableListView.setOnItemClickListener(mockOnItemClickListener);
179         assertTrue(mExpandableListView.performItemClick(null, 100, 99));
180         verify(mockOnItemClickListener, times(1)).onItemClick(eq(mExpandableListView),
181                 any(), eq(100), eq(99L));
182     }
183 
184     @Test
testSetOnItemClickListener()185     public void testSetOnItemClickListener() {
186         ExpandableListView.OnItemClickListener mockOnItemClickListener =
187                 mock(ExpandableListView.OnItemClickListener.class);
188 
189         assertNull(mExpandableListView.getOnItemClickListener());
190         mExpandableListView.setOnItemClickListener(mockOnItemClickListener);
191         assertSame(mockOnItemClickListener, mExpandableListView.getOnItemClickListener());
192     }
193 
194     @UiThreadTest
195     @ApiTest(apis = {"android.widget.ExpandableListView#onInitializeAccessibilityNodeInfoForItem"})
196     @Test
testOnInitializeAccessibilityNodeInfoForItem()197     public void testOnInitializeAccessibilityNodeInfoForItem() {
198         ExpandableListAdapter expandableAdapter = new MockExpandableListAdapter();
199         mExpandableListView.setAdapter(expandableAdapter);
200 
201         // Need a real view to be used in super.onInitializeAccessibilityNodeInfoForItem method.
202         TextView group = new TextView(mActivity);
203         final AbsListView.LayoutParams layoutParams =
204                 new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
205                         ViewGroup.LayoutParams.WRAP_CONTENT);
206         group.setLayoutParams(layoutParams);
207 
208         assertTrue(mExpandableListView.expandGroup(0));
209         AccessibilityNodeInfo expandedGroupInfo = new AccessibilityNodeInfo();
210         mExpandableListView.onInitializeAccessibilityNodeInfoForItem(group, 0, expandedGroupInfo);
211         assertTrue(expandedGroupInfo.getActionList().contains(
212                 AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE));
213         assertTrue(expandedGroupInfo.getActionList().contains(
214                 AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK));
215         assertTrue(expandedGroupInfo.isClickable());
216 
217         assertTrue(mExpandableListView.collapseGroup(0));
218         AccessibilityNodeInfo collapseGroupInfo = new AccessibilityNodeInfo();
219         mExpandableListView.onInitializeAccessibilityNodeInfoForItem(group, 0, collapseGroupInfo);
220         assertTrue(collapseGroupInfo.getActionList().contains(
221                 AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND));
222         assertTrue(collapseGroupInfo.getActionList().contains(
223                 AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK));
224         assertTrue(collapseGroupInfo.isClickable());
225     }
226 
227     @UiThreadTest
228     @ApiTest(apis = {"android.widget.ExpandableListView#performItemClick"})
229     @Test
testSendClickAccessibilityEvent()230     public void testSendClickAccessibilityEvent() {
231         View mockView = mock(View.class);
232         mExpandableListView.performItemClick(mockView, 100, 99);
233         verify(mockView).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
234     }
235 
236     @UiThreadTest
237     @Test
testExpandGroup()238     public void testExpandGroup() {
239         ExpandableListAdapter expandableAdapter = new MockExpandableListAdapter();
240         mExpandableListView.setAdapter(expandableAdapter);
241 
242         ExpandableListView.OnGroupExpandListener mockOnGroupExpandListener =
243                 mock(ExpandableListView.OnGroupExpandListener.class);
244         mExpandableListView.setOnGroupExpandListener(mockOnGroupExpandListener);
245 
246         verifyZeroInteractions(mockOnGroupExpandListener);
247 
248         assertTrue(mExpandableListView.expandGroup(0));
249         verify(mockOnGroupExpandListener, times(1)).onGroupExpand(0);
250         assertTrue(mExpandableListView.isGroupExpanded(0));
251 
252         reset(mockOnGroupExpandListener);
253         assertFalse(mExpandableListView.expandGroup(0));
254         verify(mockOnGroupExpandListener, times(1)).onGroupExpand(0);
255         assertTrue(mExpandableListView.isGroupExpanded(0));
256 
257         reset(mockOnGroupExpandListener);
258         assertTrue(mExpandableListView.expandGroup(1));
259         verify(mockOnGroupExpandListener, times(1)).onGroupExpand(1);
260         assertTrue(mExpandableListView.isGroupExpanded(1));
261 
262         reset(mockOnGroupExpandListener);
263         assertFalse(mExpandableListView.expandGroup(1));
264         verify(mockOnGroupExpandListener, times(1)).onGroupExpand(1);
265         assertTrue(mExpandableListView.isGroupExpanded(1));
266 
267         reset(mockOnGroupExpandListener);
268         mExpandableListView.setAdapter((ExpandableListAdapter) null);
269         try {
270             mExpandableListView.expandGroup(0);
271             fail("should throw NullPointerException");
272         } catch (NullPointerException e) {
273         }
274     }
275 
276     @Test
testExpandGroupSmooth()277     public void testExpandGroupSmooth() throws Throwable {
278         mActivityRule.runOnUiThread(
279                 () -> mExpandableListView.setAdapter(new MockExpandableListAdapter()));
280 
281         ExpandableListView.OnGroupExpandListener mockOnGroupExpandListener =
282                 mock(ExpandableListView.OnGroupExpandListener.class);
283         mExpandableListView.setOnGroupExpandListener(mockOnGroupExpandListener);
284 
285         verifyZeroInteractions(mockOnGroupExpandListener);
286         WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mExpandableListView,
287                 () -> assertTrue(mExpandableListView.expandGroup(0, true)));
288         verify(mockOnGroupExpandListener, times(1)).onGroupExpand(0);
289         assertTrue(mExpandableListView.isGroupExpanded(0));
290 
291         reset(mockOnGroupExpandListener);
292         WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mExpandableListView,
293                 () -> assertFalse(mExpandableListView.expandGroup(0, true)));
294         verify(mockOnGroupExpandListener, times(1)).onGroupExpand(0);
295         assertTrue(mExpandableListView.isGroupExpanded(0));
296 
297         reset(mockOnGroupExpandListener);
298         WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mExpandableListView,
299                 () -> assertTrue(mExpandableListView.expandGroup(1, true)));
300         verify(mockOnGroupExpandListener, times(1)).onGroupExpand(1);
301         assertTrue(mExpandableListView.isGroupExpanded(1));
302 
303         reset(mockOnGroupExpandListener);
304         WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mExpandableListView,
305                 () -> assertFalse(mExpandableListView.expandGroup(1, true)));
306         verify(mockOnGroupExpandListener, times(1)).onGroupExpand(1);
307         assertTrue(mExpandableListView.isGroupExpanded(1));
308 
309         reset(mockOnGroupExpandListener);
310         mActivityRule.runOnUiThread(() -> {
311             mExpandableListView.setAdapter((ExpandableListAdapter) null);
312             try {
313                 mExpandableListView.expandGroup(0);
314                 fail("should throw NullPointerException");
315             } catch (NullPointerException e) {
316             }
317         });
318     }
319 
320     @UiThreadTest
321     @Test
testCollapseGroup()322     public void testCollapseGroup() {
323         ExpandableListAdapter expandableAdapter = new MockExpandableListAdapter();
324         mExpandableListView.setAdapter(expandableAdapter);
325 
326         ExpandableListView.OnGroupCollapseListener mockOnGroupCollapseListener =
327                 mock(ExpandableListView.OnGroupCollapseListener.class);
328         mExpandableListView.setOnGroupCollapseListener(mockOnGroupCollapseListener);
329 
330         verifyZeroInteractions(mockOnGroupCollapseListener);
331         assertFalse(mExpandableListView.collapseGroup(0));
332         verify(mockOnGroupCollapseListener, times(1)).onGroupCollapse(0);
333         assertFalse(mExpandableListView.isGroupExpanded(0));
334 
335         reset(mockOnGroupCollapseListener);
336         mExpandableListView.expandGroup(0);
337         assertTrue(mExpandableListView.collapseGroup(0));
338         verify(mockOnGroupCollapseListener, times(1)).onGroupCollapse(0);
339         assertFalse(mExpandableListView.isGroupExpanded(0));
340 
341         reset(mockOnGroupCollapseListener);
342         assertFalse(mExpandableListView.collapseGroup(1));
343         verify(mockOnGroupCollapseListener, times(1)).onGroupCollapse(1);
344         assertFalse(mExpandableListView.isGroupExpanded(1));
345 
346         reset(mockOnGroupCollapseListener);
347         mExpandableListView.setAdapter((ExpandableListAdapter) null);
348         try {
349             mExpandableListView.collapseGroup(0);
350             fail("should throw NullPointerException");
351         } catch (NullPointerException e) {
352         }
353     }
354 
355     @UiThreadTest
356     @Test
testSetOnGroupClickListener()357     public void testSetOnGroupClickListener() {
358         mExpandableListView.setAdapter(new MockExpandableListAdapter());
359 
360         ExpandableListView.OnGroupClickListener mockOnGroupClickListener =
361                 mock(ExpandableListView.OnGroupClickListener.class);
362 
363         mExpandableListView.setOnGroupClickListener(mockOnGroupClickListener);
364         verifyZeroInteractions(mockOnGroupClickListener);
365 
366         mExpandableListView.performItemClick(null, 0, 0);
367         verify(mockOnGroupClickListener, times(1)).onGroupClick(eq(mExpandableListView),
368                 any(), eq(0), eq(0L));
369     }
370 
371     @UiThreadTest
372     @Test
testSetOnChildClickListener()373     public void testSetOnChildClickListener() {
374         mExpandableListView.setAdapter(new MockExpandableListAdapter());
375 
376         ExpandableListView.OnChildClickListener mockOnChildClickListener =
377                 mock(ExpandableListView.OnChildClickListener.class);
378 
379         mExpandableListView.setOnChildClickListener(mockOnChildClickListener);
380         verifyZeroInteractions(mockOnChildClickListener);
381 
382         // first let the list expand
383         mExpandableListView.expandGroup(0);
384         // click on the child list of the first group
385         mExpandableListView.performItemClick(null, 1, 0);
386         verify(mockOnChildClickListener, times(1)).onChildClick(eq(mExpandableListView),
387                 any(), eq(0), eq(0), eq(0L));
388     }
389 
390     @UiThreadTest
391     @Test
testGetExpandableListPosition()392     public void testGetExpandableListPosition() {
393         mExpandableListView.setAdapter(new MockExpandableListAdapter());
394 
395         assertEquals(0, mExpandableListView.getExpandableListPosition(0));
396 
397         // Group 0 is not expanded, position 1 is invalid
398         assertEquals(ExpandableListView.PACKED_POSITION_VALUE_NULL,
399                 mExpandableListView.getExpandableListPosition(1));
400 
401         // Position 1 becomes valid when group 0 is expanded
402         mExpandableListView.expandGroup(0);
403         assertEquals(ExpandableListView.getPackedPositionForChild(0, 0),
404                 mExpandableListView.getExpandableListPosition(1));
405 
406         // Position 2 is still invalid (only one child).
407         assertEquals(ExpandableListView.PACKED_POSITION_VALUE_NULL,
408                 mExpandableListView.getExpandableListPosition(2));
409     }
410 
411     @UiThreadTest
412     @Test
testGetFlatListPosition()413     public void testGetFlatListPosition() {
414         mExpandableListView.setAdapter(new MockExpandableListAdapter());
415 
416         try {
417             mExpandableListView.getFlatListPosition(ExpandableListView.PACKED_POSITION_VALUE_NULL);
418         } catch (NullPointerException e) {
419         }
420         assertEquals(1, mExpandableListView.getFlatListPosition(
421                 ((long) ExpandableListView.PACKED_POSITION_TYPE_CHILD)<<32L));
422         // 0x8000000100000000L means this is a child and group position is 1.
423         assertEquals(1, mExpandableListView.getFlatListPosition(0x8000000100000000L));
424     }
425 
426     @UiThreadTest
427     @Test
testGetSelectedPosition()428     public void testGetSelectedPosition() {
429         assertEquals(ExpandableListView.PACKED_POSITION_VALUE_NULL,
430                 mExpandableListView.getSelectedPosition());
431 
432         mExpandableListView.setAdapter(new MockExpandableListAdapter());
433 
434         mExpandableListView.setSelectedGroup(0);
435         assertEquals(0, mExpandableListView.getSelectedPosition());
436 
437         mExpandableListView.setSelectedGroup(1);
438         assertEquals(0, mExpandableListView.getSelectedPosition());
439     }
440 
441     @UiThreadTest
442     @Test
testGetSelectedId()443     public void testGetSelectedId() {
444         assertEquals(-1, mExpandableListView.getSelectedId());
445         mExpandableListView.setAdapter(new MockExpandableListAdapter());
446 
447         mExpandableListView.setSelectedGroup(0);
448         assertEquals(0, mExpandableListView.getSelectedId());
449 
450         mExpandableListView.setSelectedGroup(1);
451         assertEquals(0, mExpandableListView.getSelectedId());
452     }
453 
454     @UiThreadTest
455     @Test
testSetSelectedGroup()456     public void testSetSelectedGroup() {
457         mExpandableListView.setAdapter(new MockExpandableListAdapter());
458 
459         mExpandableListView.setSelectedGroup(0);
460         assertEquals(0, mExpandableListView.getSelectedPosition());
461 
462         mExpandableListView.setSelectedGroup(1);
463         assertEquals(0, mExpandableListView.getSelectedPosition());
464     }
465 
466     @UiThreadTest
467     @Test
testSetSelectedChild()468     public void testSetSelectedChild() {
469         mExpandableListView.setAdapter(new MockExpandableListAdapter());
470 
471         assertTrue(mExpandableListView.setSelectedChild(0, 0, false));
472         assertTrue(mExpandableListView.setSelectedChild(0, 1, true));
473     }
474 
475     @UiThreadTest
476     @Test
testIsGroupExpanded()477     public void testIsGroupExpanded() {
478         mExpandableListView.setAdapter(new MockExpandableListAdapter());
479 
480         mExpandableListView.expandGroup(1);
481         assertFalse(mExpandableListView.isGroupExpanded(0));
482         assertTrue(mExpandableListView.isGroupExpanded(1));
483     }
484 
485     @Test
testGetPackedPositionType()486     public void testGetPackedPositionType() {
487         assertEquals(ExpandableListView.PACKED_POSITION_TYPE_NULL,
488                 ExpandableListView.getPackedPositionType(
489                         ExpandableListView.PACKED_POSITION_VALUE_NULL));
490 
491         assertEquals(ExpandableListView.PACKED_POSITION_TYPE_GROUP,
492                 ExpandableListView.getPackedPositionType(0));
493 
494         // 0x8000000000000000L is PACKED_POSITION_MASK_TYPE, but it is private,
495         // so we just use its value.
496         assertEquals(ExpandableListView.PACKED_POSITION_TYPE_CHILD,
497                 ExpandableListView.getPackedPositionType(0x8000000000000000L));
498     }
499 
500     @Test
testGetPackedPositionGroup()501     public void testGetPackedPositionGroup() {
502         assertEquals(-1, ExpandableListView.getPackedPositionGroup(
503                 ExpandableListView.PACKED_POSITION_VALUE_NULL));
504 
505         assertEquals(0, ExpandableListView.getPackedPositionGroup(0));
506 
507         // 0x123400000000L means its group position is 0x1234
508         assertEquals(0x1234, ExpandableListView.getPackedPositionGroup(0x123400000000L));
509 
510         // 0x7FFFFFFF00000000L means its group position is 0x7FFFFFFF
511         assertEquals(0x7FFFFFFF, ExpandableListView.getPackedPositionGroup(0x7FFFFFFF00000000L));
512     }
513 
514     @Test
testGetPackedPositionChild()515     public void testGetPackedPositionChild() {
516         assertEquals(-1, ExpandableListView.getPackedPositionChild(
517                 ExpandableListView.PACKED_POSITION_VALUE_NULL));
518 
519         assertEquals(-1, ExpandableListView.getPackedPositionChild(1));
520 
521         // 0x8000000000000000L means its child position is 0
522         assertEquals(0, ExpandableListView.getPackedPositionChild(0x8000000000000000L));
523 
524         // 0x80000000ffffffffL means its child position is 0xffffffff
525         assertEquals(0xffffffff, ExpandableListView.getPackedPositionChild(0x80000000ffffffffL));
526     }
527 
528     @Test
testGetPackedPositionForChild()529     public void testGetPackedPositionForChild() {
530         assertEquals(0x8000000000000000L,
531                 ExpandableListView.getPackedPositionForChild(0, 0));
532 
533         assertEquals(0xffffffffffffffffL,
534                 ExpandableListView.getPackedPositionForChild(Integer.MAX_VALUE, 0xffffffff));
535     }
536 
537     @Test
testGetPackedPositionForGroup()538     public void testGetPackedPositionForGroup() {
539         assertEquals(0, ExpandableListView.getPackedPositionForGroup(0));
540 
541         assertEquals(0x7fffffff00000000L,
542                 ExpandableListView.getPackedPositionForGroup(Integer.MAX_VALUE));
543     }
544 
545     @Test
testSetChildIndicator()546     public void testSetChildIndicator() {
547         mExpandableListView.setChildIndicator(null);
548     }
549 
550     @Test
testSetChildIndicatorBounds()551     public void testSetChildIndicatorBounds() {
552         mExpandableListView.setChildIndicatorBounds(10, 20);
553     }
554 
555     @Test
testSetChildIndicatorBoundsRelative()556     public void testSetChildIndicatorBoundsRelative() {
557         mExpandableListView.setChildIndicatorBoundsRelative(10, 20);
558     }
559 
560     @Test
testSetGroupIndicator()561     public void testSetGroupIndicator() {
562         Drawable drawable = new BitmapDrawable();
563         mExpandableListView.setGroupIndicator(drawable);
564     }
565 
566     @Test
testSetIndicatorBounds()567     public void testSetIndicatorBounds() {
568         mExpandableListView.setIndicatorBounds(10, 30);
569     }
570 
571     @Test
testSetIndicatorBoundsRelative()572     public void testSetIndicatorBoundsRelative() {
573         mExpandableListView.setIndicatorBoundsRelative(10, 30);
574     }
575 
576     @Test
testOnSaveInstanceState()577     public void testOnSaveInstanceState() {
578         ExpandableListView src = new ExpandableListView(mActivity);
579         Parcelable p1 = src.onSaveInstanceState();
580 
581         ExpandableListView dest = new ExpandableListView(mActivity);
582         dest.onRestoreInstanceState(p1);
583         Parcelable p2 = dest.onSaveInstanceState();
584 
585         assertNotNull(p1);
586         assertNotNull(p2);
587     }
588 
589     @Test
testDispatchDraw()590     public void testDispatchDraw() {
591         MockExpandableListView expandableListView = new MockExpandableListView(mActivity);
592         expandableListView.dispatchDraw(new Canvas());
593     }
594 
595     private class MockExpandableListAdapter implements ExpandableListAdapter {
596         private final LayoutInflater mLayoutInflater;
597 
MockExpandableListAdapter()598         public MockExpandableListAdapter() {
599             mLayoutInflater = LayoutInflater.from(mActivity);
600         }
601 
registerDataSetObserver(DataSetObserver observer)602         public void registerDataSetObserver(DataSetObserver observer) {
603         }
604 
unregisterDataSetObserver(DataSetObserver observer)605         public void unregisterDataSetObserver(DataSetObserver observer) {
606         }
607 
getGroupCount()608         public int getGroupCount() {
609             return 1;
610         }
611 
getChildrenCount(int groupPosition)612         public int getChildrenCount(int groupPosition) {
613             switch (groupPosition) {
614             case 0:
615                 return 1;
616             default:
617                 return 0;
618             }
619         }
620 
getGroup(int groupPosition)621         public Object getGroup(int groupPosition) {
622             switch (groupPosition) {
623             case 0:
624                 return "Data";
625             default:
626                 return null;
627             }
628         }
629 
getChild(int groupPosition, int childPosition)630         public Object getChild(int groupPosition, int childPosition) {
631             if (groupPosition == 0 && childPosition == 0)
632                 return "child data";
633             else
634                 return null;
635         }
636 
getGroupId(int groupPosition)637         public long getGroupId(int groupPosition) {
638             return 0;
639         }
640 
getChildId(int groupPosition, int childPosition)641         public long getChildId(int groupPosition, int childPosition) {
642             return 0;
643         }
644 
hasStableIds()645         public boolean hasStableIds() {
646             return true;
647         }
648 
getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)649         public View getGroupView(int groupPosition, boolean isExpanded,
650                 View convertView, ViewGroup parent) {
651             TextView result = (TextView) convertView;
652             if (result == null) {
653                 result = (TextView) mLayoutInflater.inflate(
654                         R.layout.expandablelistview_group, parent, false);
655             }
656             result.setText("Group " + groupPosition);
657             return result;
658         }
659 
getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent)660         public View getChildView(int groupPosition, int childPosition,
661                 boolean isLastChild, View convertView, ViewGroup parent) {
662             TextView result = (TextView) convertView;
663             if (result == null) {
664                 result = (TextView) mLayoutInflater.inflate(
665                         R.layout.expandablelistview_child, parent, false);
666             }
667             result.setText("Child " + childPosition);
668             return result;
669         }
670 
isChildSelectable(int groupPosition, int childPosition)671         public boolean isChildSelectable(int groupPosition, int childPosition) {
672             return true;
673         }
674 
areAllItemsEnabled()675         public boolean areAllItemsEnabled() {
676             return true;
677         }
678 
isEmpty()679         public boolean isEmpty() {
680             return true;
681         }
682 
onGroupExpanded(int groupPosition)683         public void onGroupExpanded(int groupPosition) {
684         }
685 
onGroupCollapsed(int groupPosition)686         public void onGroupCollapsed(int groupPosition) {
687         }
688 
getCombinedChildId(long groupId, long childId)689         public long getCombinedChildId(long groupId, long childId) {
690             return 0;
691         }
692 
getCombinedGroupId(long groupId)693         public long getCombinedGroupId(long groupId) {
694             return 0;
695         }
696     }
697 
698     private class MockExpandableListView extends ExpandableListView {
MockExpandableListView(Context context)699         public MockExpandableListView(Context context) {
700             super(context);
701         }
702 
MockExpandableListView(Context context, AttributeSet attrs)703         public MockExpandableListView(Context context, AttributeSet attrs) {
704             super(context, attrs);
705         }
706 
MockExpandableListView(Context context, AttributeSet attrs, int defStyle)707         public MockExpandableListView(Context context, AttributeSet attrs, int defStyle) {
708             super(context, attrs, defStyle);
709         }
710 
711         @Override
dispatchDraw(Canvas canvas)712         protected void dispatchDraw(Canvas canvas) {
713             super.dispatchDraw(canvas);
714         }
715     }
716 }
717