1 /*
2  * Copyright (C) 2016 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 package android.app.cts;
17 
18 import android.app.Instrumentation;
19 import android.app.ListActivity;
20 import android.app.stubs.MockListActivity;
21 import android.test.ActivityInstrumentationTestCase2;
22 import android.test.suitebuilder.annotation.SmallTest;
23 import android.view.View;
24 import android.view.ViewTreeObserver;
25 import android.widget.ArrayAdapter;
26 import android.widget.ListAdapter;
27 import junit.framework.Assert;
28 
29 import java.util.concurrent.Semaphore;
30 import java.util.concurrent.TimeUnit;
31 
32 @SmallTest
33 public class ListActivityTest extends ActivityInstrumentationTestCase2<MockListActivity> {
34     private ListActivity mActivity;
35 
ListActivityTest()36     public ListActivityTest() {
37         super(MockListActivity.class);
38     }
39 
40     @Override
setUp()41     protected void setUp() throws Exception {
42         super.setUp();
43         mActivity = getActivity();
44     }
45 
testAdapter()46     public void testAdapter() throws Throwable {
47         final ListAdapter listAdapter = new ArrayAdapter<String>(mActivity,
48                 android.R.layout.simple_list_item_1,
49                 new String[] { "Mercury", "Mars", "Earth", "Venus"});
50         runTestOnUiThread(new Runnable() {
51             @Override
52             public void run() {
53                 mActivity.setListAdapter(listAdapter);
54             }
55         });
56         assertEquals(listAdapter, mActivity.getListAdapter());
57         assertEquals(listAdapter, mActivity.getListView().getAdapter());
58     }
59 
testSelection()60     public void testSelection() throws Throwable {
61         final ListAdapter listAdapter = new ArrayAdapter<String>(mActivity,
62                 android.R.layout.simple_list_item_1,
63                 new String[] { "Alpha", "Bravo", "Charlie", "Delta", "Echo"});
64         runTestOnUiThread(new Runnable() {
65             @Override
66             public void run() {
67                 mActivity.setListAdapter(listAdapter);
68             }
69         });
70         assertEquals(0, mActivity.getSelectedItemPosition());
71         assertEquals(0, mActivity.getSelectedItemId());
72 
73         runOnMainAndDrawSync(getInstrumentation(), mActivity.getListView(), new Runnable() {
74             @Override
75             public void run() {
76                 mActivity.setSelection(2);
77             }
78         });
79         assertEquals(2, mActivity.getSelectedItemPosition());
80         assertEquals(2, mActivity.getSelectedItemId());
81     }
82 
testItemClick()83     public void testItemClick() throws Throwable {
84         final ListAdapter listAdapter = new ArrayAdapter<String>(mActivity,
85                 android.R.layout.simple_list_item_1,
86                 new String[] { "Froyo", "Gingerbread", "Ice Cream Sandwich" });
87         runTestOnUiThread(new Runnable() {
88             @Override
89             public void run() {
90                 mActivity.setListAdapter(listAdapter);
91             }
92         });
93 
94         final MockListActivity mockListActivity = (MockListActivity) mActivity;
95         assertFalse(mockListActivity.isOnListItemClickCalled);
96 
97         runTestOnUiThread(new Runnable() {
98             @Override
99             public void run() {
100                 mActivity.getListView().performItemClick(null, 1, 1);
101             }
102         });
103 
104         assertTrue(mockListActivity.isOnListItemClickCalled);
105         assertEquals(1, mockListActivity.itemClickCallCount);
106         assertEquals(1, mockListActivity.clickedItemPosition);
107     }
108 
runOnMainAndDrawSync(Instrumentation instrumentation, final View view, final Runnable runner)109     private static void runOnMainAndDrawSync(Instrumentation instrumentation,
110             final View view, final Runnable runner) {
111         final Semaphore token = new Semaphore(0);
112 
113         instrumentation.runOnMainSync(new Runnable() {
114             @Override
115             public void run() {
116                 final ViewTreeObserver observer = view.getViewTreeObserver();
117                 final ViewTreeObserver.OnDrawListener listener =
118                         new ViewTreeObserver.OnDrawListener() {
119                     @Override
120                     public void onDraw() {
121                         view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this));
122                         view.post(() -> token.release());
123                     }
124                 };
125 
126                 observer.addOnDrawListener(listener);
127                 runner.run();
128             }
129         });
130 
131         try {
132             Assert.assertTrue("Expected draw pass occurred within 5 seconds",
133                     token.tryAcquire(5, TimeUnit.SECONDS));
134         } catch (InterruptedException e) {
135             throw new RuntimeException(e);
136         }
137     }
138 
139 }
140