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