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.app.cts;
18 
19 import static androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.Mockito.*;
25 
26 import android.app.Activity;
27 import android.app.AlertDialog;
28 import android.app.AlertDialog.Builder;
29 import android.app.Instrumentation;
30 import android.app.stubs.DialogStubActivity;
31 import android.app.stubs.R;
32 import android.content.Context;
33 import android.content.DialogInterface;
34 import android.content.DialogInterface.OnCancelListener;
35 import android.content.DialogInterface.OnClickListener;
36 import android.content.DialogInterface.OnDismissListener;
37 import android.content.DialogInterface.OnKeyListener;
38 import android.content.DialogInterface.OnMultiChoiceClickListener;
39 import android.content.res.TypedArray;
40 import android.graphics.drawable.Drawable;
41 import android.os.SystemClock;
42 import android.view.KeyEvent;
43 import android.view.LayoutInflater;
44 import android.view.View;
45 import android.widget.AdapterView.OnItemSelectedListener;
46 import android.widget.ArrayAdapter;
47 import android.widget.Button;
48 import android.widget.ListAdapter;
49 import android.widget.ListView;
50 
51 import androidx.test.filters.SmallTest;
52 import androidx.test.platform.app.InstrumentationRegistry;
53 import androidx.test.rule.ActivityTestRule;
54 
55 import com.android.compatibility.common.util.PollingCheck;
56 
57 import org.junit.Before;
58 import org.junit.Rule;
59 import org.junit.Test;
60 import org.junit.runner.RunWith;
61 import org.junit.runners.JUnit4;
62 import org.mockito.ArgumentCaptor;
63 
64 @SmallTest
65 @RunWith(JUnit4.class)
66 public class AlertDialog_BuilderTest  {
67     private Builder mBuilder;
68     private Instrumentation mInstrumentation;
69     private final CharSequence mTitle = "title";
70     private Drawable mDrawable;
71     private AlertDialog mDialog;
72     private Button mButton;
73     private CharSequence mSelectedItem;
74 
75     private View mView;
76     private ListView mListView;
77 
78     private OnClickListener mOnClickListener = mock(OnClickListener.class);
79 
80     private OnCancelListener mOnCancelListener = mock(OnCancelListener.class);
81 
82     private OnDismissListener mOnDismissListener = mock(OnDismissListener.class);
83 
84     private OnKeyListener mOnKeyListener = mock(OnKeyListener.class);
85 
86     private OnItemSelectedListener mOnItemSelectedListener = mock(OnItemSelectedListener.class);
87 
88     @Rule
89     public ActivityTestRule<DialogStubActivity> mActivityRule =
90             new ActivityTestRule<>(DialogStubActivity.class);
91 
92     private Context mContext;
93 
94     private OnMultiChoiceClickListener mOnMultiChoiceClickListener =
95             mock(OnMultiChoiceClickListener.class);
96 
97     @Before
setUp()98     public void setUp() throws Exception {
99         mInstrumentation = InstrumentationRegistry.getInstrumentation();
100         Activity activity = mActivityRule.getActivity();
101         mContext = activity;
102         PollingCheck.waitFor(activity::hasWindowFocus);
103     }
104 
105     @Test
testConstructor()106     public void testConstructor() {
107         new AlertDialog.Builder(mContext);
108     }
109 
110     @Test
testConstructorWithThemeId()111     public void testConstructorWithThemeId() {
112         mBuilder = new AlertDialog.Builder(mContext, R.style.DialogTheme_Test);
113 
114         // Get the context from the builder and attempt to resolve a custom attribute
115         // set on our theme. This way we verify that our theme has been applied to the
116         // builder.
117         final Context themedContext = mBuilder.getContext();
118         int[] attrs = new int[] { R.attr.themeInteger };
119         TypedArray ta = themedContext.obtainStyledAttributes(attrs);
120         assertEquals(20, ta.getInt(0, 0));
121     }
122 
123     @Test
testSetIconWithParamInt()124     public void testSetIconWithParamInt() throws Throwable {
125         runOnUiThread(new Runnable() {
126             public void run() {
127                 mDrawable = mContext.getResources().getDrawable(android.R.drawable.btn_default);
128                 mBuilder = new AlertDialog.Builder(mContext);
129                 mBuilder.setIcon(android.R.drawable.btn_default);
130                 mDialog = mBuilder.show();
131             }
132         });
133         mInstrumentation.waitForIdleSync();
134     }
135 
136     @Test
testSetIconWithParamDrawable()137     public void testSetIconWithParamDrawable() throws Throwable {
138         runOnUiThread(new Runnable() {
139             public void run() {
140                 mDrawable = mContext.getResources().getDrawable(android.R.drawable.btn_default);
141                 mBuilder = new AlertDialog.Builder(mContext);
142                 mBuilder.setIcon(mDrawable);
143                 mDialog = mBuilder.show();
144             }
145         });
146         mInstrumentation.waitForIdleSync();
147     }
148 
149     @Test
testSetIconAttribute()150     public void testSetIconAttribute() throws Throwable {
151         runOnUiThread(new Runnable() {
152             public void run() {
153                 mDrawable = mContext.getResources().getDrawable(android.R.drawable.btn_default);
154                 mBuilder = new AlertDialog.Builder(mContext);
155                 mBuilder.setIconAttribute(android.R.attr.alertDialogIcon);
156                 mDialog = mBuilder.show();
157             }
158         });
159         mInstrumentation.waitForIdleSync();
160     }
161 
162     @Test
testSetPositiveButtonWithParamInt()163     public void testSetPositiveButtonWithParamInt() throws Throwable {
164        runOnUiThread(new Runnable() {
165             public void run() {
166                 mBuilder = new AlertDialog.Builder(mContext);
167                 mBuilder.setPositiveButton(android.R.string.yes, mOnClickListener);
168                 mBuilder.setOnDismissListener(mOnDismissListener);
169                 mDialog = mBuilder.show();
170                 mButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
171                 mButton.performClick();
172             }
173         });
174         mInstrumentation.waitForIdleSync();
175 
176         assertEquals(mContext.getText(android.R.string.yes), mButton.getText());
177         verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_POSITIVE);
178         verifyNoMoreInteractions(mOnClickListener);
179         // Button click should also dismiss the dialog and notify the listener
180         verify(mOnDismissListener, times(1)).onDismiss(mDialog);
181         verifyNoMoreInteractions(mOnDismissListener);
182     }
183 
184     @Test
testSetPositiveButtonWithParamCharSequence()185     public void testSetPositiveButtonWithParamCharSequence() throws Throwable {
186         runOnUiThread(new Runnable() {
187             public void run() {
188                 mBuilder = new AlertDialog.Builder(mContext);
189                 mBuilder.setPositiveButton(android.R.string.yes, mOnClickListener);
190                 mBuilder.setOnDismissListener(mOnDismissListener);
191                 mDialog = mBuilder.show();
192                 mButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
193                 mButton.performClick();
194             }
195         });
196         mInstrumentation.waitForIdleSync();
197         assertEquals(mContext.getText(android.R.string.yes), mButton.getText());
198         verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_POSITIVE);
199         verifyNoMoreInteractions(mOnClickListener);
200         // Button click should also dismiss the dialog and notify the listener
201         verify(mOnDismissListener, times(1)).onDismiss(mDialog);
202         verifyNoMoreInteractions(mOnDismissListener);
203     }
204 
205     @Test
testSetNegativeButtonWithParamCharSequence()206     public void testSetNegativeButtonWithParamCharSequence() throws Throwable {
207         runOnUiThread(new Runnable() {
208             public void run() {
209                 mBuilder = new AlertDialog.Builder(mContext);
210                 mBuilder.setNegativeButton(mTitle, mOnClickListener);
211                 mBuilder.setOnDismissListener(mOnDismissListener);
212                 mDialog = mBuilder.show();
213                 mButton = mDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
214                 mButton.performClick();
215             }
216         });
217         mInstrumentation.waitForIdleSync();
218         assertEquals(mTitle, mButton.getText());
219         verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_NEGATIVE);
220         verifyNoMoreInteractions(mOnClickListener);
221         // Button click should also dismiss the dialog and notify the listener
222         verify(mOnDismissListener, times(1)).onDismiss(mDialog);
223         verifyNoMoreInteractions(mOnDismissListener);
224     }
225 
226     @Test
testSetNegativeButtonWithParamInt()227     public void testSetNegativeButtonWithParamInt() throws Throwable {
228         runOnUiThread(new Runnable() {
229             public void run() {
230                 mBuilder = new AlertDialog.Builder(mContext);
231                 mBuilder.setNegativeButton(R.string.notify, mOnClickListener);
232                 mBuilder.setOnDismissListener(mOnDismissListener);
233                 mDialog = mBuilder.show();
234                 mButton = mDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
235                 mButton.performClick();
236             }
237         });
238         mInstrumentation.waitForIdleSync();
239         assertEquals(mContext.getText(R.string.notify), mButton.getText());
240         verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_NEGATIVE);
241         verifyNoMoreInteractions(mOnClickListener);
242         // Button click should also dismiss the dialog and notify the listener
243         verify(mOnDismissListener, times(1)).onDismiss(mDialog);
244         verifyNoMoreInteractions(mOnDismissListener);
245     }
246 
247     @Test
testSetNeutralButtonWithParamInt()248     public void testSetNeutralButtonWithParamInt() throws Throwable {
249         runOnUiThread(new Runnable() {
250             public void run() {
251                 mBuilder = new AlertDialog.Builder(mContext);
252                 mBuilder.setNeutralButton(R.string.notify, mOnClickListener);
253                 mBuilder.setOnDismissListener(mOnDismissListener);
254                 mDialog = mBuilder.show();
255                 mButton = mDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
256                 mButton.performClick();
257             }
258         });
259         mInstrumentation.waitForIdleSync();
260         assertEquals(mContext.getText(R.string.notify), mButton.getText());
261         verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_NEUTRAL);
262         verifyNoMoreInteractions(mOnClickListener);
263         // Button click should also dismiss the dialog and notify the listener
264         verify(mOnDismissListener, times(1)).onDismiss(mDialog);
265         verifyNoMoreInteractions(mOnDismissListener);
266     }
267 
268     @Test
testSetNeutralButtonWithParamCharSequence()269     public void testSetNeutralButtonWithParamCharSequence() throws Throwable {
270         runOnUiThread(new Runnable() {
271             public void run() {
272                 mBuilder = new AlertDialog.Builder(mContext);
273                 mBuilder.setNeutralButton(mTitle, mOnClickListener);
274                 mBuilder.setOnDismissListener(mOnDismissListener);
275                 mDialog = mBuilder.show();
276                 mButton = mDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
277                 mButton.performClick();
278             }
279         });
280         mInstrumentation.waitForIdleSync();
281         assertEquals(mTitle, mButton.getText());
282         verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_NEUTRAL);
283         verifyNoMoreInteractions(mOnClickListener);
284         // Button click should also dismiss the dialog and notify the listener
285         verify(mOnDismissListener, times(1)).onDismiss(mDialog);
286         verifyNoMoreInteractions(mOnDismissListener);
287     }
288 
testCancelable(final boolean cancelable)289     private void testCancelable(final boolean cancelable) throws Throwable {
290         runOnUiThread(new Runnable() {
291             public void run() {
292                 mBuilder = new AlertDialog.Builder(mContext);
293                 mBuilder.setCancelable(cancelable);
294                 mDialog = mBuilder.show();
295             }
296         });
297         mInstrumentation.waitForIdleSync();
298         PollingCheck.waitFor(mDialog::isShowing);
299         sendKeySync(KeyEvent.KEYCODE_BACK);
300         mInstrumentation.waitForIdleSync();
301         new PollingCheck() {
302             @Override
303             protected boolean check() {
304                 boolean showing = mDialog.isShowing();
305                 if (cancelable) {
306                     // if the dialog is cancelable, then pressing back
307                     // should cancel it. Thus it should not be showing
308                     return !showing;
309                 } else {
310                     // if the dialog is not cancelable, pressing back
311                     // should so nothing and it should still be showing
312                     return showing;
313                 }
314             }
315         }.run();
316     }
317 
318     @Test
testSetCancelable()319     public void testSetCancelable() throws Throwable {
320         testCancelable(true);
321     }
322 
323     @Test
testDisableCancelable()324     public void testDisableCancelable() throws Throwable {
325         testCancelable(false);
326     }
327 
328     @Test
testSetOnCancelListener()329     public void testSetOnCancelListener() throws Throwable {
330         runOnUiThread(new Runnable() {
331             public void run() {
332                 mBuilder = new AlertDialog.Builder(mContext);
333                 mBuilder.setOnCancelListener(mOnCancelListener);
334                 mDialog = mBuilder.show();
335                 mDialog.cancel();
336             }
337         });
338         mInstrumentation.waitForIdleSync();
339         verify(mOnCancelListener, times(1)).onCancel(mDialog);
340         verifyNoMoreInteractions(mOnCancelListener);
341     }
342 
343     @Test
testSetOnDismissListener()344     public void testSetOnDismissListener() throws Throwable {
345         runOnUiThread(new Runnable() {
346             public void run() {
347                 mBuilder = new AlertDialog.Builder(mContext);
348                 mBuilder.setOnDismissListener(mOnDismissListener);
349                 mDialog = mBuilder.show();
350                 mDialog.dismiss();
351             }
352         });
353         mInstrumentation.waitForIdleSync();
354         verify(mOnDismissListener, times(1)).onDismiss(mDialog);
355         verifyNoMoreInteractions(mOnDismissListener);
356     }
357 
358     @Test
testSetOnKeyListener()359     public void testSetOnKeyListener() throws Throwable {
360         runOnUiThread(new Runnable() {
361             public void run() {
362                 mBuilder = new AlertDialog.Builder(mContext);
363                 mBuilder.setOnKeyListener(mOnKeyListener);
364                 mDialog = mBuilder.show();
365             }
366         });
367         mInstrumentation.waitForIdleSync();
368         sendKeySync(KeyEvent.KEYCODE_0);
369         sendKeySync(KeyEvent.KEYCODE_1);
370         mInstrumentation.waitForIdleSync();
371         // Use Mockito captures so that we can verify that each "sent" key code resulted
372         // in one DOWN event and one UP event.
373         ArgumentCaptor<KeyEvent> keyEvent0Captor = ArgumentCaptor.forClass(KeyEvent.class);
374         ArgumentCaptor<KeyEvent> keyEvent1Captor = ArgumentCaptor.forClass(KeyEvent.class);
375         verify(mOnKeyListener, times(2)).onKey(eq(mDialog), eq(KeyEvent.KEYCODE_0),
376                 keyEvent0Captor.capture());
377         verify(mOnKeyListener, times(2)).onKey(eq(mDialog), eq(KeyEvent.KEYCODE_1),
378                 keyEvent1Captor.capture());
379         verifyNoMoreInteractions(mOnKeyListener);
380         assertEquals(KeyEvent.ACTION_DOWN, keyEvent0Captor.getAllValues().get(0).getAction());
381         assertEquals(KeyEvent.ACTION_UP, keyEvent0Captor.getAllValues().get(1).getAction());
382         assertEquals(KeyEvent.ACTION_DOWN, keyEvent1Captor.getAllValues().get(0).getAction());
383         assertEquals(KeyEvent.ACTION_UP, keyEvent1Captor.getAllValues().get(1).getAction());
384     }
385 
386     @Test
testSetItemsWithParamInt()387     public void testSetItemsWithParamInt() throws Throwable {
388         runOnUiThread(new Runnable() {
389             public void run() {
390                 mBuilder = new AlertDialog.Builder(mContext);
391                 mBuilder.setItems(R.array.difficultyLevel, mOnClickListener);
392                 mDialog = mBuilder.show();
393                 mListView = mDialog.getListView();
394             }
395         });
396         mInstrumentation.waitForIdleSync();
397 
398         final CharSequence[] levels = mContext.getResources().getTextArray(
399                 R.array.difficultyLevel);
400         assertEquals(levels[0], mListView.getItemAtPosition(0));
401     }
402 
403     @Test
testSetItemsWithParamCharSequence()404     public void testSetItemsWithParamCharSequence() throws Throwable {
405         final CharSequence[] expect = mContext.getResources().getTextArray(
406                 R.array.difficultyLevel);
407 
408         runOnUiThread(new Runnable() {
409             public void run() {
410                 mBuilder = new AlertDialog.Builder(mContext);
411                 mBuilder.setItems(expect, mOnClickListener);
412                 mDialog = mBuilder.show();
413                 mListView = mDialog.getListView();
414             }
415         });
416         mInstrumentation.waitForIdleSync();
417         assertEquals(expect[0], mListView.getItemAtPosition(0));
418     }
419 
420     @Test
testSetAdapter()421     public void testSetAdapter() throws Throwable {
422         final ListAdapter adapter = new AdapterTest();
423         runOnUiThread(new Runnable() {
424             public void run() {
425                 mBuilder = new AlertDialog.Builder(mContext);
426                 mBuilder.setAdapter(adapter, mOnClickListener);
427                 mDialog = mBuilder.show();
428                 mListView = mDialog.getListView();
429             }
430         });
431         mInstrumentation.waitForIdleSync();
432         assertEquals(adapter, mListView.getAdapter());
433     }
434 
435     @Test
testSetMultiChoiceItemsWithParamInt()436     public void testSetMultiChoiceItemsWithParamInt() throws Throwable {
437 
438         final CharSequence[] items = mContext.getResources().getTextArray(
439                 R.array.difficultyLevel);
440 
441         runOnUiThread(new Runnable() {
442             public void run() {
443                 mBuilder = new AlertDialog.Builder(mContext);
444                 mBuilder.setMultiChoiceItems(R.array.difficultyLevel, null,
445                         mOnMultiChoiceClickListener);
446                 mDialog = mBuilder.show();
447                 mListView = mDialog.getListView();
448                 mSelectedItem = (CharSequence)mListView.getSelectedItem();
449                 mListView.performItemClick(null, 0, 0);
450                 mListView.performItemClick(null, 1, 0);
451             }
452         });
453         mInstrumentation.waitForIdleSync();
454         assertEquals(items[0], mSelectedItem);
455         verify(mOnMultiChoiceClickListener, times(1)).onClick(mDialog, 0, true);
456         verify(mOnMultiChoiceClickListener, times(1)).onClick(mDialog, 1, true);
457         verifyNoMoreInteractions(mOnMultiChoiceClickListener);
458         assertEquals(items[0], mListView.getItemAtPosition(0));
459     }
460 
461     @Test
testSetMultiChoiceItemsWithParamCharSequence()462     public void testSetMultiChoiceItemsWithParamCharSequence() throws Throwable {
463         final CharSequence[] items = mContext.getResources().getTextArray(
464                 R.array.difficultyLevel);
465 
466         runOnUiThread(new Runnable() {
467             public void run() {
468                 mBuilder = new AlertDialog.Builder(mContext);
469                 mBuilder.setMultiChoiceItems(items, null, mOnMultiChoiceClickListener);
470                 mDialog = mBuilder.show();
471                 mListView = mDialog.getListView();
472                 mSelectedItem = (CharSequence)mListView.getSelectedItem();
473                 mListView.performItemClick(null, 0, 0);
474                 mListView.performItemClick(null, 1, 0);
475             }
476         });
477         mInstrumentation.waitForIdleSync();
478         assertEquals(items[0], mSelectedItem);
479         verify(mOnMultiChoiceClickListener, times(1)).onClick(mDialog, 0, true);
480         verify(mOnMultiChoiceClickListener, times(1)).onClick(mDialog, 1, true);
481         verifyNoMoreInteractions(mOnMultiChoiceClickListener);
482         assertEquals(items[0], mListView.getItemAtPosition(0));
483     }
484 
485     @Test
testSetSingleChoiceItemsWithParamInt()486     public void testSetSingleChoiceItemsWithParamInt() throws Throwable {
487         final CharSequence[] items = mContext.getResources().getTextArray(
488                 R.array.difficultyLevel);
489 
490         runOnUiThread(new Runnable() {
491             public void run() {
492                 mBuilder = new AlertDialog.Builder(mContext);
493                 mBuilder.setSingleChoiceItems(R.array.difficultyLevel, 0,
494                         mOnClickListener);
495                 mDialog = mBuilder.show();
496                 mListView = mDialog.getListView();
497                 mSelectedItem = (CharSequence)mListView.getSelectedItem();
498                 mListView.performItemClick(null, 0, 0);
499             }
500         });
501         mInstrumentation.waitForIdleSync();
502         assertEquals(items[0], mSelectedItem);
503         assertEquals(items[0], mListView.getItemAtPosition(0));
504         verify(mOnClickListener, times(1)).onClick(mDialog, 0);
505         verifyNoMoreInteractions(mOnClickListener);
506     }
507 
508     @Test
testSetSingleChoiceItemsWithParamCharSequence()509     public void testSetSingleChoiceItemsWithParamCharSequence() throws Throwable {
510         final CharSequence[] items = mContext.getResources().getTextArray(
511                 R.array.difficultyLevel);
512 
513         runOnUiThread(new Runnable() {
514             public void run() {
515                 mBuilder = new AlertDialog.Builder(mContext);
516                 mBuilder.setSingleChoiceItems(items, 0, mOnClickListener);
517                 mDialog = mBuilder.show();
518                 mListView = mDialog.getListView();
519                 mSelectedItem = (CharSequence)mListView.getSelectedItem();
520                 mListView.performItemClick(null, 0, 0);
521             }
522         });
523         mInstrumentation.waitForIdleSync();
524         assertEquals(items[0], mSelectedItem);
525         assertEquals(items[0], mListView.getItemAtPosition(0));
526         verify(mOnClickListener, times(1)).onClick(mDialog, 0);
527         verifyNoMoreInteractions(mOnClickListener);
528     }
529 
530     @Test
testSetSingleChoiceItems()531     public void testSetSingleChoiceItems() throws Throwable {
532         final CharSequence[] items = mContext.getResources().getTextArray(
533                 R.array.difficultyLevel);
534 
535         runOnUiThread(new Runnable() {
536             public void run() {
537                 mBuilder = new AlertDialog.Builder(mContext);
538                 mBuilder.setSingleChoiceItems(new ArrayAdapter<CharSequence>(mContext,
539                         android.R.layout.select_dialog_singlechoice, android.R.id.text1, items), 0,
540                         mOnClickListener);
541                 mDialog = mBuilder.show();
542                 mListView = mDialog.getListView();
543                 mSelectedItem = (CharSequence)mListView.getSelectedItem();
544                 mListView.performItemClick(null, 0, 0);
545             }
546         });
547         mInstrumentation.waitForIdleSync();
548         assertEquals(items[0], mSelectedItem);
549         assertEquals(items[0], mListView.getItemAtPosition(0));
550         verify(mOnClickListener, times(1)).onClick(mDialog, 0);
551         verifyNoMoreInteractions(mOnClickListener);
552     }
553 
554     @Test
testSetOnItemSelectedListener()555     public void testSetOnItemSelectedListener() throws Throwable {
556         runOnUiThread(new Runnable() {
557             public void run() {
558                 mBuilder = new AlertDialog.Builder(mContext);
559                 mBuilder.setOnItemSelectedListener(mOnItemSelectedListener);
560                 mBuilder.setItems(R.array.difficultyLevel, mOnClickListener);
561                 mDialog = mBuilder.show();
562                 mListView = mDialog.getListView();
563                 mListView.pointToPosition(0, 0);
564             }
565         });
566         mInstrumentation.waitForIdleSync();
567         verify(mOnItemSelectedListener, times(1)).onItemSelected(eq(mListView), any(View.class),
568                 eq(0), any(Long.class));
569         verifyNoMoreInteractions(mOnItemSelectedListener);
570     }
571 
572     @Test
testSetView()573     public void testSetView() throws Throwable {
574         final View view = new View(mContext);
575         view.setId(100);
576         runOnUiThread(new Runnable() {
577             public void run() {
578                 mBuilder = new AlertDialog.Builder(mContext);
579                 mBuilder.setView(view);
580                 mDialog = mBuilder.show();
581                 mView = mDialog.getWindow().findViewById(100);
582             }
583         });
584         mInstrumentation.waitForIdleSync();
585         assertEquals(view, mView);
586     }
587 
588     @Test
testSetViewFromInflater()589     public void testSetViewFromInflater() throws Throwable {
590         runOnUiThread(new Runnable() {
591             public void run() {
592                 mBuilder = new AlertDialog.Builder(mContext);
593                 mBuilder.setView(LayoutInflater.from(mBuilder.getContext()).inflate(
594                         R.layout.alert_dialog_text_entry_2, null, false));
595                 mDialog = mBuilder.show();
596                 mView = mDialog.getWindow().findViewById(R.id.username_form);
597             }
598         });
599         mInstrumentation.waitForIdleSync();
600         assertNotNull(mView);
601         assertNotNull(mView.findViewById(R.id.username_view));
602         assertNotNull(mView.findViewById(R.id.username_edit));
603     }
604 
605     @Test
testSetViewById()606     public void testSetViewById() throws Throwable {
607         runOnUiThread(new Runnable() {
608             public void run() {
609                 mBuilder = new AlertDialog.Builder(mContext);
610                 mBuilder.setView(R.layout.alert_dialog_text_entry_2);
611                 mDialog = mBuilder.show();
612                 mView = mDialog.getWindow().findViewById(R.id.username_form);
613             }
614         });
615         mInstrumentation.waitForIdleSync();
616         assertNotNull(mView);
617         assertNotNull(mView.findViewById(R.id.username_view));
618         assertNotNull(mView.findViewById(R.id.username_edit));
619     }
620 
621     @Test
testSetCustomTitle()622     public void testSetCustomTitle() throws Throwable {
623         runOnUiThread(new Runnable() {
624             public void run() {
625                 mBuilder = new AlertDialog.Builder(mContext);
626                 mBuilder.setCustomTitle(LayoutInflater.from(mBuilder.getContext()).inflate(
627                         R.layout.alertdialog_custom_title, null, false));
628                 mDialog = mBuilder.show();
629             }
630         });
631         mInstrumentation.waitForIdleSync();
632     }
633 
634     @Test
testSetInverseBackgroundForced()635     public void testSetInverseBackgroundForced() throws Throwable {
636         runOnUiThread(new Runnable() {
637             public void run() {
638                 mBuilder = new AlertDialog.Builder(mContext);
639                 mBuilder.setInverseBackgroundForced(true);
640                 mDialog = mBuilder.create();
641                 mDialog.show();
642             }
643         });
644         mInstrumentation.waitForIdleSync();
645     }
646 
647     @Test
testCreate()648     public void testCreate() throws Throwable {
649         runOnUiThread(new Runnable() {
650             public void run() {
651                 mBuilder = new AlertDialog.Builder(mContext);
652                 mDialog = mBuilder.create();
653                 mDialog.show();
654             }
655         });
656         mInstrumentation.waitForIdleSync();
657         assertNotNull(mDialog);
658         assertTrue(mDialog.isShowing());
659     }
660 
661     @Test
testShow()662     public void testShow() throws Throwable {
663         runOnUiThread(new Runnable() {
664             public void run() {
665                 mBuilder = new AlertDialog.Builder(mContext);
666                 mDialog = mBuilder.show();
667             }
668         });
669         mInstrumentation.waitForIdleSync();
670         assertTrue(mDialog.isShowing());
671     }
672 
sendKeySync(int keyCode)673     private void sendKeySync(int keyCode) {
674         final long downTime = SystemClock.uptimeMillis();
675         final KeyEvent downEvent =
676                 new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode, 0);
677         mInstrumentation.getUiAutomation().injectInputEvent(downEvent, true /*sync*/);
678 
679         final KeyEvent upEvent =
680                 new KeyEvent(downTime, SystemClock.uptimeMillis(), KeyEvent.ACTION_UP, keyCode, 0);
681         mInstrumentation.getUiAutomation().injectInputEvent(upEvent, true /*sync*/);
682     }
683 
684     private static class AdapterTest implements android.widget.ListAdapter {
areAllItemsEnabled()685         public boolean areAllItemsEnabled() {
686             return true;
687         }
688 
isEnabled(int position)689         public boolean isEnabled(int position) {
690             return false;
691         }
692 
getCount()693         public int getCount() {
694             return 0;
695         }
696 
getItem(int position)697         public Object getItem(int position) {
698             return null;
699         }
700 
getItemId(int position)701         public long getItemId(int position) {
702             return 0;
703         }
704 
getItemViewType(int position)705         public int getItemViewType(int position) {
706             return 0;
707         }
708 
getView( int position, android.view.View convertView, android.view.ViewGroup parent)709         public android.view.View getView( int position,
710                                           android.view.View convertView,
711                                           android.view.ViewGroup parent){
712             return null;
713         }
714 
getViewTypeCount()715         public int getViewTypeCount() {
716             return 1;
717         }
718 
hasStableIds()719         public boolean hasStableIds() {
720             return false;
721         }
722 
isEmpty()723         public boolean isEmpty() {
724             return true;
725         }
726 
registerDataSetObserver( android.database.DataSetObserver observer)727         public void registerDataSetObserver(
728             android.database.DataSetObserver observer) {
729         }
730 
unregisterDataSetObserver( android.database.DataSetObserver observer)731         public void unregisterDataSetObserver(
732             android.database.DataSetObserver observer) {
733         }
734     }
735 }
736