• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package android.app.cts;
17 
18 import java.lang.ref.WeakReference;
19 import com.android.cts.stub.R;
20 import android.app.Dialog;
21 import android.app.Instrumentation;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.DialogInterface.OnCancelListener;
25 import android.content.DialogInterface.OnDismissListener;
26 import android.content.DialogInterface.OnKeyListener;
27 import android.content.pm.ActivityInfo;
28 import android.content.res.Resources;
29 import android.content.res.TypedArray;
30 import android.graphics.Canvas;
31 import android.graphics.ColorFilter;
32 import android.graphics.drawable.Drawable;
33 import android.net.Uri;
34 import android.os.Handler;
35 import android.os.HandlerThread;
36 import android.os.Looper;
37 import android.os.Message;
38 import android.test.ActivityInstrumentationTestCase2;
39 import android.view.KeyEvent;
40 import android.view.LayoutInflater;
41 import android.view.MenuItem;
42 import android.view.MotionEvent;
43 import android.view.View;
44 import android.view.ViewGroup;
45 import android.view.Window;
46 import android.view.WindowManager;
47 import android.widget.LinearLayout;
48 import dalvik.annotation.TestLevel;
49 import dalvik.annotation.TestTargetClass;
50 import dalvik.annotation.TestTargetNew;
51 import dalvik.annotation.TestTargets;
52 import dalvik.annotation.ToBeFixed;
53 
54 @TestTargetClass(Dialog.class)
55 public class DialogTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
56 
57     protected static final long SLEEP_TIME = 200;
58     private static final long MOTION_DOWN_TIME = 0L;
59     private static final long MOTION_EVENT_TIME = 0L;
60     private static final float MOTION_X = -20.0f;
61     private static final float MOTION_Y = -20.0f;
62     private static final String STUB_ACTIVITY_PACKAGE = "com.android.cts.stub";
63 
64     /**
65      *  please refer to Dialog
66      */
67     private static final int DISMISS = 0x43;
68     private static final int CANCEL = 0x44;
69 
70     private boolean mCalledCallback;
71     private boolean mIsKey0Listened;
72     private boolean mIsKey1Listened;
73     private boolean mOnCancelListenerCalled;
74 
75     private Instrumentation mInstrumentation;
76     private Context mContext;
77     private DialogStubActivity mActivity;
78 
79 
DialogTest()80     public DialogTest() {
81         super(STUB_ACTIVITY_PACKAGE, DialogStubActivity.class);
82     }
83 
84     @Override
setUp()85     protected void setUp() throws Exception {
86         super.setUp();
87 
88         mInstrumentation = getInstrumentation();
89         mContext = mInstrumentation.getContext();
90         mActivity = getActivity();
91     }
92 
93     @Override
tearDown()94     protected void tearDown() throws Exception {
95         super.tearDown();
96 
97         if (mActivity != null) {
98             mActivity.finish();
99         }
100     }
101 
popDialog(int index)102     protected void popDialog(int index) {
103         assertTrue(index >= 0);
104 
105         while (index != 0) {
106             sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
107             index--;
108         }
109 
110         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
111     }
112 
113     @TestTargets({
114         @TestTargetNew(
115             level = TestLevel.COMPLETE,
116             method = "Dialog",
117             args = {android.content.Context.class}
118         ),
119         @TestTargetNew(
120             level = TestLevel.COMPLETE,
121             method = "Dialog",
122             args = {android.content.Context.class, int.class}
123         ),
124         @TestTargetNew(
125             level = TestLevel.COMPLETE,
126             notes = "test Dialog protected Constructors through mock dialog",
127             method = "Dialog",
128             args = {android.content.Context.class, boolean.class,
129                     android.content.DialogInterface.OnCancelListener.class}
130         ),
131         @TestTargetNew(
132             level = TestLevel.COMPLETE,
133             method = "getContext",
134             args = {}
135         ),
136         @TestTargetNew(
137             level = TestLevel.COMPLETE,
138             method = "getWindow",
139             args = {}
140         )
141     })
testDialog()142     public void testDialog(){
143         new Dialog(mContext);
144         Dialog d = new Dialog(mContext, 0);
145         // According to javadoc of constructors, it will set theme to system default theme,
146         // when we set no theme id or set it theme id to 0.
147         // But CTS can no assert dialog theme equals system internal theme.
148 
149         d = new Dialog(mContext, R.style.TextAppearance);
150         TypedArray ta =
151             d.getContext().getTheme().obtainStyledAttributes(R.styleable.TextAppearance);
152         assertTextAppearanceStyle(ta);
153 
154         final Window w = d.getWindow();
155         ta = w.getContext().getTheme().obtainStyledAttributes(R.styleable.TextAppearance);
156         assertTextAppearanceStyle(ta);
157 
158         // test protected constructor
159         // Dialog(Context context, boolean cancelable, OnCancelListener cancelListener)
160         mActivity.onCancelListenerCalled = false;
161         popDialog(DialogStubActivity.TEST_PROTECTED_CANCELABLE);
162         sendKeys(KeyEvent.KEYCODE_BACK);
163         assertTrue(mActivity.onCancelListenerCalled);
164 
165         // open DialogStubActivity.TEST_PROTECTED_NOT_CANCELABLE
166         sendKeys(KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
167         mActivity.onCancelListenerCalled = false;
168         sendKeys(KeyEvent.KEYCODE_BACK);
169         assertFalse(mActivity.onCancelListenerCalled);
170     }
171 
assertTextAppearanceStyle(TypedArray ta)172     private void assertTextAppearanceStyle(TypedArray ta) {
173         final int defValue = -1;
174         // get Theme and assert
175         final Resources.Theme expected = mContext.getResources().newTheme();
176         expected.setTo(mContext.getTheme());
177         expected.applyStyle(R.style.TextAppearance, true);
178         TypedArray expectedTa = expected.obtainStyledAttributes(R.styleable.TextAppearance);
179         assertEquals(expectedTa.getIndexCount(), ta.getIndexCount());
180         assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColor, defValue),
181                 ta.getColor(R.styleable.TextAppearance_textColor, defValue));
182         assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorHint, defValue),
183                 ta.getColor(R.styleable.TextAppearance_textColorHint, defValue));
184         assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorLink, defValue),
185                 ta.getColor(R.styleable.TextAppearance_textColorLink, defValue));
186         assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorHighlight, defValue),
187                 ta.getColor(R.styleable.TextAppearance_textColorHighlight, defValue));
188         assertEquals(expectedTa.getDimension(R.styleable.TextAppearance_textSize, defValue),
189                 ta.getDimension(R.styleable.TextAppearance_textSize, defValue));
190         assertEquals(expectedTa.getInt(R.styleable.TextAppearance_textStyle, defValue),
191                 ta.getInt(R.styleable.TextAppearance_textStyle, defValue));
192     }
193 
194     @TestTargets({
195         @TestTargetNew(
196             level = TestLevel.COMPLETE,
197             method = "onStart",
198             args = {}
199         ),
200         @TestTargetNew(
201             level = TestLevel.COMPLETE,
202             method = "onCreate",
203             args = {android.os.Bundle.class}
204         ),
205         @TestTargetNew(
206             level = TestLevel.COMPLETE,
207             method = "onStop",
208             args = {}
209         )
210     })
testOnStartCreateStop()211     public void testOnStartCreateStop(){
212         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
213         final TestDialog d = (TestDialog) mActivity.getDialog();
214 
215         assertTrue(d.isOnStartCalled);
216         assertTrue(d.isOnCreateCalled);
217 
218         assertFalse(d.isOnStopCalled);
219         sendKeys(KeyEvent.KEYCODE_BACK);
220         assertTrue(d.isOnStopCalled);
221     }
222 
223     @TestTargets({
224         @TestTargetNew(
225             level = TestLevel.COMPLETE,
226             method = "setOwnerActivity",
227             args = {android.app.Activity.class}
228         ),
229         @TestTargetNew(
230             level = TestLevel.COMPLETE,
231             method = "getOwnerActivity",
232             args = {}
233         ),
234         @TestTargetNew(
235             level = TestLevel.COMPLETE,
236             method = "setVolumeControlStream",
237             args = {int.class}
238         ),
239         @TestTargetNew(
240             level = TestLevel.COMPLETE,
241             method = "getVolumeControlStream",
242             args = {}
243         )
244     })
testAccessOwnerActivity()245     public void testAccessOwnerActivity() {
246         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
247         Dialog d = mActivity.getDialog();
248         assertNotNull(d);
249         assertSame(mActivity, d.getOwnerActivity());
250         d.setVolumeControlStream(d.getVolumeControlStream() + 1);
251         assertEquals(d.getOwnerActivity().getVolumeControlStream() + 1, d.getVolumeControlStream());
252 
253         try {
254             d.setOwnerActivity(null);
255             fail("Should throw NullPointerException");
256         } catch (NullPointerException e) {
257             // expected
258         }
259 
260         d = new Dialog(mContext);
261         assertNull(d.getOwnerActivity());
262     }
263 
264     @TestTargets({
265         @TestTargetNew(
266             level = TestLevel.COMPLETE,
267             method = "show",
268             args = {}
269         ),
270         @TestTargetNew(
271             level = TestLevel.COMPLETE,
272             method = "hide",
273             args = {}
274         ),
275         @TestTargetNew(
276             level = TestLevel.COMPLETE,
277             method = "isShowing",
278             args = {}
279         ),
280         @TestTargetNew(
281             level = TestLevel.COMPLETE,
282             method = "dismiss",
283             args = {}
284         )
285     })
testShow()286     public void testShow() throws Throwable {
287         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
288         final Dialog d = mActivity.getDialog();
289         final View decor = d.getWindow().getDecorView();
290 
291         runTestOnUiThread(new Runnable() {
292             public void run() {
293                 d.hide();
294             }
295         });
296         mInstrumentation.waitForIdleSync();
297 
298         assertEquals(View.GONE, decor.getVisibility());
299         assertTrue(d.isShowing());
300 
301         runTestOnUiThread(new Runnable() {
302             public void run() {
303                 d.show();
304             }
305         });
306         mInstrumentation.waitForIdleSync();
307 
308         assertEquals(View.VISIBLE, decor.getVisibility());
309         assertTrue(d.isShowing());
310         dialogDismiss(d);
311         assertFalse(d.isShowing());
312     }
313 
314     @TestTargets({
315         @TestTargetNew(
316             level = TestLevel.COMPLETE,
317             method = "onRestoreInstanceState",
318             args = {android.os.Bundle.class}
319         ),
320         @TestTargetNew(
321             level = TestLevel.COMPLETE,
322             method = "onSaveInstanceState",
323             args = {}
324         )
325     })
testOnSaveInstanceState()326     public void testOnSaveInstanceState() {
327         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
328         final TestDialog d = (TestDialog) mActivity.getDialog();
329         mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
330         mInstrumentation.waitForIdleSync();
331         mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
332         mInstrumentation.waitForIdleSync();
333         assertTrue(d.isOnSaveInstanceStateCalled);
334         assertTrue(TestDialog.isOnRestoreInstanceStateCalled);
335     }
336 
337     @TestTargetNew(
338         level = TestLevel.COMPLETE,
339         method = "getCurrentFocus",
340         args = {}
341     )
testGetCurrentFocus()342     public void testGetCurrentFocus() throws Throwable {
343         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
344         final TestDialog d = (TestDialog) mActivity.getDialog();
345         assertNull(d.getCurrentFocus());
346         runTestOnUiThread(new Runnable() {
347             public void run() {
348                 d.takeKeyEvents(true);
349                 d.setContentView(R.layout.alert_dialog_text_entry);
350             }
351         });
352         mInstrumentation.waitForIdleSync();
353 
354         sendKeys(KeyEvent.KEYCODE_0);
355         // When mWindow is not null getCUrrentFocus is the view in dialog
356         assertEquals(d.getWindow().getCurrentFocus(), d.getCurrentFocus());
357     }
358 
359     @TestTargets({
360         @TestTargetNew(
361             level = TestLevel.COMPLETE,
362             method = "setContentView",
363             args = {int.class}
364         ),
365         @TestTargetNew(
366             level = TestLevel.COMPLETE,
367             method = "setContentView",
368             args = {android.view.View.class}
369         ),
370         @TestTargetNew(
371             level = TestLevel.COMPLETE,
372             method = "setContentView",
373             args = {android.view.View.class, android.view.ViewGroup.LayoutParams.class}
374         ),
375         @TestTargetNew(
376             level = TestLevel.COMPLETE,
377             method = "findViewById",
378             args = {int.class}
379         ),
380         @TestTargetNew(
381             level = TestLevel.COMPLETE,
382             method = "addContentView",
383             args = {android.view.View.class, android.view.ViewGroup.LayoutParams.class}
384         )
385     })
testSetContentView()386     public void testSetContentView() throws Throwable {
387         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
388         final Dialog d = mActivity.getDialog();
389         assertNotNull(d);
390 
391         // set content view to a four elements layout
392         runTestOnUiThread(new Runnable() {
393             public void run() {
394                 d.setContentView(R.layout.alert_dialog_text_entry);
395             }
396         });
397         mInstrumentation.waitForIdleSync();
398 
399         // check if four elements are right there
400         assertNotNull(d.findViewById(R.id.username_view));
401         assertNotNull(d.findViewById(R.id.username_edit));
402         assertNotNull(d.findViewById(R.id.password_view));
403         assertNotNull(d.findViewById(R.id.password_edit));
404 
405         final LayoutInflater inflate1 = d.getLayoutInflater();
406 
407         // set content view to a two elements layout
408         runTestOnUiThread(new Runnable() {
409             public void run() {
410                 d.setContentView(inflate1.inflate(R.layout.alert_dialog_text_entry_2, null));
411             }
412         });
413         mInstrumentation.waitForIdleSync();
414 
415         // check if only two elements are right there
416         assertNotNull(d.findViewById(R.id.username_view));
417         assertNotNull(d.findViewById(R.id.username_edit));
418         assertNull(d.findViewById(R.id.password_view));
419         assertNull(d.findViewById(R.id.password_edit));
420 
421         final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
422         final LayoutInflater inflate2 = mActivity.getLayoutInflater();
423 
424         // set content view to a four elements layout
425         runTestOnUiThread(new Runnable() {
426             public void run() {
427                 d.setContentView(inflate2.inflate(R.layout.alert_dialog_text_entry, null), lp);
428             }
429         });
430         mInstrumentation.waitForIdleSync();
431 
432         // check if four elements are right there
433         assertNotNull(d.findViewById(R.id.username_view));
434         assertNotNull(d.findViewById(R.id.username_edit));
435         assertNotNull(d.findViewById(R.id.password_view));
436         assertNotNull(d.findViewById(R.id.password_edit));
437 
438         final WindowManager.LayoutParams lp2 = d.getWindow().getAttributes();
439         final LayoutInflater inflate3 = mActivity.getLayoutInflater();
440         lp2.height = ViewGroup.LayoutParams.WRAP_CONTENT;
441         lp2.width = ViewGroup.LayoutParams.WRAP_CONTENT;
442 
443         // add a check box view
444         runTestOnUiThread(new Runnable() {
445             public void run() {
446                 d.addContentView(inflate3.inflate(R.layout.checkbox_layout, null), lp2);
447             }
448         });
449         mInstrumentation.waitForIdleSync();
450 
451         // check if four elements are right there, and new add view there.
452         assertNotNull(d.findViewById(R.id.check_box));
453         assertNotNull(d.findViewById(R.id.username_view));
454         assertNotNull(d.findViewById(R.id.username_edit));
455         assertNotNull(d.findViewById(R.id.password_view));
456         assertNotNull(d.findViewById(R.id.password_edit));
457     }
458 
459     @TestTargets({
460         @TestTargetNew(
461             level = TestLevel.COMPLETE,
462             method = "setTitle",
463             args = {java.lang.CharSequence.class}
464         ),
465         @TestTargetNew(
466             level = TestLevel.COMPLETE,
467             method = "setTitle",
468             args = {int.class}
469         )
470     })
testSetTitle()471     public void testSetTitle() {
472         final String expectedTitle = "Test Dialog Without theme";
473         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
474 
475         assertNotNull(mActivity.getDialog());
476         mActivity.setUpTitle(expectedTitle);
477         mInstrumentation.waitForIdleSync();
478 
479         final Dialog d = mActivity.getDialog();
480         assertEquals(expectedTitle, (String) d.getWindow().getAttributes().getTitle());
481 
482         mActivity.setUpTitle(R.string.hello_android);
483         mInstrumentation.waitForIdleSync();
484         assertEquals(mActivity.getResources().getString(R.string.hello_android),
485                 (String) d.getWindow().getAttributes().getTitle());
486     }
487 
488     @TestTargets({
489         @TestTargetNew(
490             level = TestLevel.COMPLETE,
491             method = "onKeyDown",
492             args = {int.class, android.view.KeyEvent.class}
493         ),
494         @TestTargetNew(
495             level = TestLevel.COMPLETE,
496             method = "onKeyUp",
497             args = {int.class, android.view.KeyEvent.class}
498         )
499     })
testOnKeyDownKeyUp()500     public void testOnKeyDownKeyUp() {
501         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
502         final TestDialog d = (TestDialog) mActivity.getDialog();
503         assertFalse(d.isOnKeyDownCalled);
504         assertFalse(d.isOnKeyUpCalled);
505 
506         // send key 0 down and up events, onKeyDown return false
507         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
508         assertTrue(d.isOnKeyDownCalled);
509         assertTrue(d.isOnKeyUpCalled);
510         assertEquals(KeyEvent.KEYCODE_0, d.keyDownCode);
511         assertFalse(d.onKeyDownReturn);
512 
513         // send key back down and up events, onKeyDown return true
514         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
515         assertEquals(KeyEvent.KEYCODE_BACK, d.keyDownCode);
516         assertTrue(d.onKeyDownReturn);
517     }
518 
519     @TestTargetNew(
520         level = TestLevel.COMPLETE,
521         method = "onKeyMultiple",
522         args = {int.class, int.class, android.view.KeyEvent.class}
523     )
testOnKeyMultiple()524     public void testOnKeyMultiple() {
525         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
526         final TestDialog d = (TestDialog) mActivity.getDialog();
527 
528         // System call onTouchEvent
529         assertNull(d.keyMultipleEvent);
530         mInstrumentation.sendKeySync(
531                 new KeyEvent(KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_UNKNOWN));
532         assertTrue(d.isOnKeyMultipleCalled);
533         assertFalse(d.onKeyMultipleReturn);
534         assertEquals(KeyEvent.KEYCODE_UNKNOWN, d.keyMultipleEvent.getKeyCode());
535         assertEquals(KeyEvent.ACTION_MULTIPLE, d.keyMultipleEvent.getAction());
536     }
537 
538     @TestTargets({
539         @TestTargetNew(
540             level = TestLevel.COMPLETE,
541             method = "onTouchEvent",
542             args = {android.view.MotionEvent.class}
543         ),
544         @TestTargetNew(
545             level = TestLevel.COMPLETE,
546             method = "setCanceledOnTouchOutside",
547             args = {boolean.class}
548         ),
549         @TestTargetNew(
550             level = TestLevel.COMPLETE,
551             method = "dispatchTouchEvent",
552             args = {android.view.MotionEvent.class}
553         )
554     })
testTouchEvent()555     public void testTouchEvent() {
556         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
557         final TestDialog d = (TestDialog) mActivity.getDialog();
558 
559         assertNull(d.onTouchEvent);
560         assertNull(d.touchEvent);
561         assertFalse(d.isOnTouchEventCalled);
562 
563         MotionEvent touchMotionEvent = MotionEvent.obtain(MOTION_DOWN_TIME,
564                 MOTION_EVENT_TIME, MotionEvent.ACTION_DOWN,
565                 MOTION_X, MOTION_Y, 0);
566         // send a touch motion event, and System will call onTouchEvent
567         mInstrumentation.sendPointerSync(touchMotionEvent);
568 
569         assertFalse(d.dispatchTouchEventResult);
570         assertMotionEventEquals(touchMotionEvent, d.touchEvent);
571 
572         assertTrue(d.isOnTouchEventCalled);
573         assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
574         d.isOnTouchEventCalled = false;
575         assertTrue(d.isShowing());
576 
577         // set cancel on touch out side
578         d.setCanceledOnTouchOutside(true);
579         touchMotionEvent = MotionEvent.obtain(MOTION_DOWN_TIME + 1,
580                 MOTION_EVENT_TIME, MotionEvent.ACTION_DOWN,
581                 MOTION_X, MOTION_Y, 0);
582         // send a out side touch motion event, then the dialog will dismiss
583         mInstrumentation.sendPointerSync(touchMotionEvent);
584 
585         assertTrue(d.dispatchTouchEventResult);
586         assertMotionEventEquals(touchMotionEvent, d.touchEvent);
587 
588         assertTrue(d.isOnTouchEventCalled);
589         assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
590         assertFalse(d.isShowing());
591     }
592 
593     @TestTargets({
594         @TestTargetNew(
595             level = TestLevel.COMPLETE,
596             method = "onTrackballEvent",
597             args = {android.view.MotionEvent.class}
598         ),
599         @TestTargetNew(
600             level = TestLevel.COMPLETE,
601             method = "dispatchTrackballEvent",
602             args = {android.view.MotionEvent.class}
603         )
604     })
testTrackballEvent()605     public void testTrackballEvent() {
606         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
607         final TestDialog d = (TestDialog) mActivity.getDialog();
608         final MotionEvent trackBallEvent = MotionEvent.obtain(MOTION_DOWN_TIME, MOTION_EVENT_TIME,
609                 MotionEvent.ACTION_DOWN, MOTION_X, MOTION_Y, 0);
610 
611         assertNull(d.trackballEvent);
612         assertNull(d.onTrackballEvent);
613 
614         assertFalse(d.isOnTrackballEventCalled);
615         mInstrumentation.sendTrackballEventSync(trackBallEvent);
616         assertTrue(d.isOnTrackballEventCalled);
617         assertMotionEventEquals(trackBallEvent, d.trackballEvent);
618         assertMotionEventEquals(trackBallEvent, d.onTrackballEvent);
619 
620     }
621 
assertMotionEventEquals(final MotionEvent expected, final MotionEvent actual)622     private void assertMotionEventEquals(final MotionEvent expected, final MotionEvent actual) {
623         assertEquals(expected.getDownTime(), actual.getDownTime());
624         assertEquals(expected.getEventTime(), actual.getEventTime());
625         assertEquals(expected.getAction(), actual.getAction());
626         assertEquals(expected.getMetaState(), actual.getMetaState());
627         assertEquals(expected.getSize(), actual.getSize());
628         // As MotionEvent doc says the value of X and Y coordinate may have
629         // a fraction for input devices that are sub-pixel precise,
630         // so we won't assert them here.
631     }
632 
633     @TestTargetNew(
634         level = TestLevel.COMPLETE,
635         method = "onWindowAttributesChanged",
636         args = {android.view.WindowManager.LayoutParams.class}
637     )
testOnWindowAttributesChanged()638     public void testOnWindowAttributesChanged() throws Throwable {
639         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
640         final TestDialog d = (TestDialog) mActivity.getDialog();
641 
642         assertTrue(d.isOnWindowAttributesChangedCalled);
643         d.isOnWindowAttributesChangedCalled = false;
644 
645         final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
646         lp.setTitle("test OnWindowAttributesChanged");
647         runTestOnUiThread(new Runnable() {
648             public void run() {
649                 d.getWindow().setAttributes(lp);
650             }
651         });
652         mInstrumentation.waitForIdleSync();
653 
654         assertTrue(d.isOnWindowAttributesChangedCalled);
655         assertSame(lp, d.getWindow().getAttributes());
656     }
657 
658     @TestTargetNew(
659         level = TestLevel.COMPLETE,
660         method = "onContentChanged",
661         args = {}
662     )
testOnContentChanged()663     public void testOnContentChanged() throws Throwable {
664         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
665         final TestDialog d = (TestDialog) mActivity.getDialog();
666         assertNotNull(d);
667 
668         assertFalse(d.isOnContentChangedCalled);
669 
670         runTestOnUiThread(new Runnable() {
671             public void run() {
672                 d.setContentView(R.layout.alert_dialog_text_entry);
673             }
674         });
675         mInstrumentation.waitForIdleSync();
676 
677         assertTrue(d.isOnContentChangedCalled);
678     }
679 
680     @TestTargetNew(
681         level = TestLevel.COMPLETE,
682         method = "onWindowFocusChanged",
683         args = {boolean.class}
684     )
testOnWindowFocusChanged()685     public void testOnWindowFocusChanged() throws Throwable {
686         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
687         final TestDialog d = (TestDialog) mActivity.getDialog();
688         assertTrue(d.isOnWindowFocusChangedCalled);
689         d.isOnWindowFocusChangedCalled = false;
690 
691         // show a new dialog, the new dialog get focus
692         runTestOnUiThread(new Runnable() {
693             public void run() {
694                 mActivity.showDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
695             }
696         });
697         mInstrumentation.waitForIdleSync();
698 
699         assertTrue(d.isOnWindowFocusChangedCalled);
700     }
701 
702     @TestTargets({
703         @TestTargetNew(
704             level = TestLevel.COMPLETE,
705             method = "dispatchKeyEvent",
706             args = {android.view.KeyEvent.class}
707         ),
708         @TestTargetNew(
709             level = TestLevel.COMPLETE,
710             method = "setOnKeyListener",
711             args = {android.content.DialogInterface.OnKeyListener.class}
712         )
713     })
testDispatchKeyEvent()714     public void testDispatchKeyEvent() {
715         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
716         final TestDialog d = (TestDialog) mActivity.getDialog();
717 
718         sendKeys(KeyEvent.KEYCODE_0);
719         assertFalse(d.dispatchKeyEventResult);
720         assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
721 
722         d.setOnKeyListener(new OnKeyListener() {
723             public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
724                 if (KeyEvent.ACTION_DOWN == event.getAction()) {
725                     if (KeyEvent.KEYCODE_0 == keyCode) {
726                         mIsKey0Listened = true;
727                         return true;
728                     }
729 
730                     if (KeyEvent.KEYCODE_1 == keyCode) {
731                         mIsKey1Listened = true;
732                         return true;
733                     }
734                 }
735 
736                 return false;
737             }
738         });
739 
740         mIsKey1Listened = false;
741         sendKeys(KeyEvent.KEYCODE_1);
742         assertTrue(mIsKey1Listened);
743 
744         mIsKey0Listened = false;
745         sendKeys(KeyEvent.KEYCODE_0);
746         assertTrue(mIsKey0Listened);
747     }
748 
749     /*
750      * Test point
751      * 1. First open a option menu will make onMenuOpened onCreatePanelView onCreatePanelMenu
752      * and onPreparePanel to be called.
753      * 2. When first open the option menu onCreatePanelMenu will calls through to
754      * the new onCreateOptionsMenu method.
755      * 3. When open the option menu onPreparePanel will calls through to
756      * the new onPrepareOptionsMenu method.
757      * 4. Closed option menu will make onPanelClosed to be called,
758      * and onPanelClosed will calls through to the new onPanelClosed method.
759      * 5. Every time open option menu will make onCreatePanelView and  onPreparePanel to be called.
760      * 6. Selected a item on the option menu will make onMenuItemSelected to be called,
761      * and onMenuItemSelected will calls through to the new onOptionsItemSelected method.
762      */
763     @TestTargets({
764         @TestTargetNew(
765             level = TestLevel.COMPLETE,
766             method = "openOptionsMenu",
767             args = {}
768         ),
769         @TestTargetNew(
770             level = TestLevel.COMPLETE,
771             method = "closeOptionsMenu",
772             args = {}
773         ),
774         @TestTargetNew(
775             level = TestLevel.COMPLETE,
776             method = "onMenuOpened",
777             args = {int.class, android.view.Menu.class}
778         ),
779         @TestTargetNew(
780             level = TestLevel.COMPLETE,
781             method = "onCreatePanelView",
782             args = {int.class}
783         ),
784         @TestTargetNew(
785             level = TestLevel.COMPLETE,
786             method = "onCreatePanelMenu",
787             args = {int.class, android.view.Menu.class}
788         ),
789         @TestTargetNew(
790             level = TestLevel.COMPLETE,
791             method = "onCreateOptionsMenu",
792             args = {android.view.Menu.class}
793         ),
794         @TestTargetNew(
795             level = TestLevel.COMPLETE,
796             method = "onPreparePanel",
797             args = {int.class, android.view.View.class, android.view.Menu.class}
798         ),
799         @TestTargetNew(
800             level = TestLevel.COMPLETE,
801             method = "onPrepareOptionsMenu",
802             args = {android.view.Menu.class}
803         ),
804         @TestTargetNew(
805             level = TestLevel.PARTIAL,
806             method = "onPanelClosed",
807             args = {int.class, android.view.Menu.class}
808         ),
809         @TestTargetNew(
810             level = TestLevel.PARTIAL,
811             notes = "onOptionsMenuClosed should be called when onPanelClosed Called.",
812             method = "onOptionsMenuClosed",
813             args = {android.view.Menu.class}
814         ),
815         @TestTargetNew(
816             level = TestLevel.PARTIAL,
817             method = "onMenuItemSelected",
818             args = {int.class, android.view.MenuItem.class}
819         ),
820         @TestTargetNew(
821             level = TestLevel.PARTIAL,
822             method = "onOptionsItemSelected",
823             args = {MenuItem.class}
824         )
825     })
826     @ToBeFixed(bug = "1716918", explanation = "As Javadoc of onMenuItemSelected() and "
827             + "onPanelClosed(), onOptionsItemSelected() and onContextItemSelected() should be "
828             + "called in onMenuItemSelected() source code, onOptionMenuClosed() and "
829             + "onContextMenuClosed() should be called in onPanelClosed() source code, "
830             + "but now onMenuItemSelected() and onPanelClosed() method are empty, is this a bug?")
testOptionMenu()831     public void testOptionMenu() throws Throwable {
832         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
833         final TestDialog d = (TestDialog) mActivity.getDialog();
834         assertFalse(d.isOnMenuOpenedCalled);
835         assertFalse(d.isOnCreatePanelViewCalled);
836         assertFalse(d.isOnCreatePanelMenuCalled);
837         assertFalse(d.isOnCreateOptionsMenuCalled);
838         assertFalse(d.isOnPreparePanelCalled);
839         assertFalse(d.isOnPrepareOptionsMenuCalled);
840         // first open option menu
841         dialogOpenOptionMenu(d);
842 
843         assertTrue(d.isOnMenuOpenedCalled);
844         assertTrue(d.isOnCreatePanelViewCalled);
845         assertTrue(d.isOnCreatePanelMenuCalled);
846         assertTrue(d.isOnCreateOptionsMenuCalled);
847         assertTrue(d.isOnPreparePanelCalled);
848         assertTrue(d.isOnPrepareOptionsMenuCalled);
849 
850         assertFalse(d.isOnPanelClosedCalled);
851         // closed option menu
852         runTestOnUiThread(new Runnable() {
853             public void run() {
854                 d.closeOptionsMenu();
855             }
856         });
857         mInstrumentation.waitForIdleSync();
858 
859         assertTrue(d.isOnPanelClosedCalled);
860 
861         d.isOnCreatePanelViewCalled = false;
862         d.isOnCreatePanelMenuCalled = false;
863         d.isOnPreparePanelCalled = false;
864         assertFalse(d.isOnOptionsMenuClosedCalled);
865         // open option menu again
866         dialogOpenOptionMenu(d);
867 
868         assertTrue(d.isOnCreatePanelViewCalled);
869         assertFalse(d.isOnCreatePanelMenuCalled);
870         assertTrue(d.isOnPreparePanelCalled);
871         // Here isOnOptionsMenuClosedCalled should be true, see bug 1716918.
872         assertFalse(d.isOnOptionsMenuClosedCalled);
873 
874         assertFalse(d.isOnMenuItemSelectedCalled);
875         assertFalse(d.isOnOptionsItemSelectedCalled);
876         // selected a item of option menu
877         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
878         assertTrue(d.isOnMenuItemSelectedCalled);
879         // Here isOnOptionsItemSelectedCalled should be true, see bug 1716918.
880         assertFalse(d.isOnOptionsItemSelectedCalled);
881     }
882 
dialogOpenOptionMenu(final Dialog d)883     private void dialogOpenOptionMenu(final Dialog d) throws Throwable {
884         runTestOnUiThread(new Runnable() {
885             public void run() {
886                 d.openOptionsMenu();
887             }
888         });
889         mInstrumentation.waitForIdleSync();
890     }
891 
892     /*
893      * Test point
894      * 1. registerForContextMenu() will OnCreateContextMenuListener on the view to this activity,
895      * so onCreateContextMenu() will be called when it is time to show the context menu.
896      * 2. Close context menu will make onPanelClosed to be called,
897      * and onPanelClosed will calls through to the new onPanelClosed method.
898      * 3. unregisterForContextMenu() will remove the OnCreateContextMenuListener on the view,
899      * so onCreateContextMenu() will not be called when try to open context menu.
900      * 4. Selected a item of context menu will make onMenuItemSelected() to be called,
901      * and onMenuItemSelected will calls through to the new onContextItemSelected method.
902      * 5. onContextMenuClosed is called whenever the context menu is being closed (either by
903      * the user canceling the menu with the back/menu button, or when an item is selected).
904      */
905     @TestTargets({
906         @TestTargetNew(
907             level = TestLevel.COMPLETE,
908             method = "registerForContextMenu",
909             args = {android.view.View.class}
910         ),
911         @TestTargetNew(
912             level = TestLevel.COMPLETE,
913             method = "unregisterForContextMenu",
914             args = {android.view.View.class}
915         ),
916         @TestTargetNew(
917             level = TestLevel.COMPLETE,
918             method = "onCreateContextMenu",
919             args = {android.view.ContextMenu.class, android.view.View.class,
920                     android.view.ContextMenu.ContextMenuInfo.class}
921         ),
922         @TestTargetNew(
923             level = TestLevel.COMPLETE,
924             method = "openContextMenu",
925             args = {android.view.View.class}
926         ),
927         @TestTargetNew(
928             level = TestLevel.PARTIAL,
929             notes = "test method: onContextItemSelected",
930             method = "onContextItemSelected",
931             args = {android.view.MenuItem.class}
932          ),
933          @TestTargetNew(
934              level = TestLevel.COMPLETE,
935              notes = "test method: onContextMenuClosed",
936              method = "onContextMenuClosed",
937              args = {android.view.Menu.class}
938          )
939     })
940     @ToBeFixed(bug = "1716918", explanation = "As Javadoc of onMenuItemSelected() and "
941             + "onPanelClosed(), onOptionsItemSelected() and onContextItemSelected() should be "
942             + "called in onMenuItemSelected() source code, onOptionMenuClosed() and "
943             + "onContextMenuClosed() should be called in onPanelClosed() source code, "
944             + "but now onMenuItemSelected() and onPanelClosed() method are empty, is this a bug?")
testContextMenu()945     public void testContextMenu() throws Throwable {
946         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
947         final TestDialog d = (TestDialog) mActivity.getDialog();
948         final LinearLayout parent = new LinearLayout(mContext);
949         final MockView v = new MockView(mContext);
950         parent.addView(v);
951         assertFalse(v.isShowContextMenuCalled);
952         // Register for context menu and open it
953         runTestOnUiThread(new Runnable() {
954             public void run() {
955                 d.addContentView(parent, new LinearLayout.LayoutParams(
956                         ViewGroup.LayoutParams.FILL_PARENT,
957                         ViewGroup.LayoutParams.WRAP_CONTENT));
958                 d.registerForContextMenu(v);
959                 d.openContextMenu(v);
960             }
961         });
962         mInstrumentation.waitForIdleSync();
963 
964         assertTrue(v.isShowContextMenuCalled);
965         assertTrue(d.isOnCreateContextMenuCalled);
966 
967         assertFalse(d.isOnPanelClosedCalled);
968         assertFalse(d.isOnContextMenuClosedCalled);
969         // Closed context menu
970         sendKeys(KeyEvent.KEYCODE_BACK);
971         assertTrue(d.isOnPanelClosedCalled);
972         // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
973         assertFalse(d.isOnContextMenuClosedCalled);
974 
975         v.isShowContextMenuCalled = false;
976         d.isOnCreateContextMenuCalled = false;
977         // Unregister for context menu, and try to open it
978         runTestOnUiThread(new Runnable() {
979             public void run() {
980                 d.unregisterForContextMenu(v);
981             }
982         });
983         mInstrumentation.waitForIdleSync();
984 
985         runTestOnUiThread(new Runnable() {
986             public void run() {
987                 d.openContextMenu(v);
988             }
989         });
990         mInstrumentation.waitForIdleSync();
991 
992         assertTrue(v.isShowContextMenuCalled);
993         assertFalse(d.isOnCreateContextMenuCalled);
994 
995         // Register for context menu and open it again
996         runTestOnUiThread(new Runnable() {
997             public void run() {
998                 d.registerForContextMenu(v);
999                 d.openContextMenu(v);
1000             }
1001         });
1002         mInstrumentation.waitForIdleSync();
1003 
1004         assertFalse(d.isOnContextItemSelectedCalled);
1005         assertFalse(d.isOnMenuItemSelectedCalled);
1006         d.isOnPanelClosedCalled = false;
1007         assertFalse(d.isOnContextMenuClosedCalled);
1008         // select a context menu item
1009         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
1010         assertTrue(d.isOnMenuItemSelectedCalled);
1011         // Here isOnContextItemSelectedCalled should be true, see bug 1716918.
1012         assertFalse(d.isOnContextItemSelectedCalled);
1013         assertTrue(d.isOnPanelClosedCalled);
1014         // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
1015         assertFalse(d.isOnContextMenuClosedCalled);
1016     }
1017 
1018     @TestTargetNew(
1019         level = TestLevel.NOT_FEASIBLE,
1020         method = "onSearchRequested",
1021         args = {}
1022     )
1023     @ToBeFixed(bug = "1695243", explanation = "From the javadoc of onSearchRequested,"
1024             + "we see it will be called when the user signals the desire to start a search."
1025             + "But there is a comment in it source code says \"not during dialogs, no.\","
1026             + "But onSearchRequested() didn't be called after start search.")
testOnSearchRequested()1027     public void testOnSearchRequested() {
1028     }
1029 
1030     @TestTargetNew(
1031         level = TestLevel.PARTIAL,
1032         method = "takeKeyEvents",
1033         args = {boolean.class}
1034     )
1035     @ToBeFixed(bug = "1695243",
1036             explanation = "It still get KeyEvent while set takeKeyEvents to false")
testTakeKeyEvents()1037     public void testTakeKeyEvents() throws Throwable {
1038         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
1039         final TestDialog d = (TestDialog) mActivity.getDialog();
1040         final View v = d.getWindow().getDecorView();
1041         assertNull(d.getCurrentFocus());
1042         takeKeyEvents(d, true);
1043         assertTrue(v.isFocusable());
1044         sendKeys(KeyEvent.KEYCODE_0);
1045         assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
1046         d.keyEvent = null;
1047 
1048         takeKeyEvents(d, false);
1049         assertNull(d.getCurrentFocus());
1050         assertFalse(v.isFocusable());
1051         sendKeys(KeyEvent.KEYCODE_0);
1052         // d.keyEvent should be null
1053     }
1054 
takeKeyEvents(final Dialog d, final boolean get)1055     private void takeKeyEvents(final Dialog d, final boolean get) throws Throwable {
1056         runTestOnUiThread(new Runnable() {
1057             public void run() {
1058                 d.takeKeyEvents(get);
1059             }
1060         });
1061         mInstrumentation.waitForIdleSync();
1062     }
1063 
1064     @TestTargetNew(
1065         level = TestLevel.COMPLETE,
1066         method = "requestWindowFeature",
1067         args = {int.class}
1068     )
testRequestWindowFeature()1069     public void testRequestWindowFeature() {
1070         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
1071         // called requestWindowFeature at TestDialog onCreate method
1072         assertTrue(((TestDialog) mActivity.getDialog()).isRequestWindowFeature);
1073     }
1074 
1075     @TestTargetNew(
1076         level = TestLevel.NOT_FEASIBLE,
1077         notes = "There is no way to assert whether the drawable resource is properly shown."
1078             + "So we only call setFeatureDrawableResource once, with no asserts.",
1079         method = "setFeatureDrawableResource",
1080         args = {int.class, int.class}
1081     )
testSetFeatureDrawableResource()1082     public void testSetFeatureDrawableResource() throws Throwable {
1083         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
1084         runTestOnUiThread(new Runnable() {
1085             public void run() {
1086                 mActivity.getDialog().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
1087                         R.drawable.robot);
1088             }
1089         });
1090         mInstrumentation.waitForIdleSync();
1091     }
1092 
1093     @TestTargetNew(
1094         level = TestLevel.NOT_FEASIBLE,
1095         notes = "There is no way to assert whether the drawable resource is properly shown."
1096             + "So we only call setFeatureDrawableUri once, with no asserts.",
1097         method = "setFeatureDrawableUri",
1098         args = {int.class, android.net.Uri.class}
1099     )
testSetFeatureDrawableUri()1100     public void testSetFeatureDrawableUri() {
1101         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
1102         mActivity.getDialog().setFeatureDrawableUri(0, Uri.parse("http://www.google.com"));
1103     }
1104 
1105     @TestTargetNew(
1106         level = TestLevel.NOT_FEASIBLE,
1107         notes = "There is no way to assert whether the drawable resource is properly shown."
1108             + "So we only call setFeatureDrawable once, with no asserts.",
1109         method = "setFeatureDrawable",
1110         args = {int.class, android.graphics.drawable.Drawable.class}
1111     )
testSetFeatureDrawable()1112     public void testSetFeatureDrawable() {
1113         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
1114         mActivity.getDialog().setFeatureDrawable(0, new MockDrawable());
1115     }
1116 
1117     @TestTargetNew(
1118         level = TestLevel.NOT_FEASIBLE,
1119         notes = "There is no way to assert whether the drawable resource is properly shown."
1120             + "So we only call setFeatureDrawableAlpha once, with no asserts.",
1121         method = "setFeatureDrawableAlpha",
1122         args = {int.class, int.class}
1123     )
testSetFeatureDrawableAlpha()1124     public void testSetFeatureDrawableAlpha() {
1125         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
1126         mActivity.getDialog().setFeatureDrawableAlpha(0, 0);
1127     }
1128 
1129     @TestTargetNew(
1130         level = TestLevel.COMPLETE,
1131         method = "getLayoutInflater",
1132         args = {}
1133     )
testGetLayoutInflater()1134     public void testGetLayoutInflater() {
1135         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
1136         final Dialog d = mActivity.getDialog();
1137         assertEquals(d.getWindow().getLayoutInflater(), d.getLayoutInflater());
1138     }
1139 
1140     @TestTargetNew(
1141         level = TestLevel.COMPLETE,
1142         method = "setCancelable",
1143         args = {boolean.class}
1144     )
testSetCancelable()1145     public void testSetCancelable() {
1146         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
1147         final Dialog d = mActivity.getDialog();
1148 
1149         d.setCancelable(true);
1150         assertTrue(d.isShowing());
1151         sendKeys(KeyEvent.KEYCODE_BACK);
1152         assertFalse(d.isShowing());
1153 
1154         d.setCancelable(false);
1155         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
1156         assertTrue(d.isShowing());
1157         sendKeys(KeyEvent.KEYCODE_BACK);
1158         assertTrue(d.isShowing());
1159     }
1160 
1161     /*
1162      * Test point
1163      * 1. Cancel the dialog.
1164      * 2. Set a listener to be invoked when the dialog is canceled.
1165      */
1166     @TestTargets({
1167         @TestTargetNew(
1168             level = TestLevel.COMPLETE,
1169             method = "cancel",
1170             args = {}
1171         ),
1172         @TestTargetNew(
1173             level = TestLevel.COMPLETE,
1174             method = "setOnCancelListener",
1175             args = {android.content.DialogInterface.OnCancelListener.class}
1176         )
1177     })
testCancel()1178     public void testCancel() throws Throwable {
1179         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
1180         final Dialog d = mActivity.getDialog();
1181 
1182         assertTrue(d.isShowing());
1183         mOnCancelListenerCalled = false;
1184         d.setOnCancelListener(new OnCancelListener() {
1185             public void onCancel(DialogInterface dialog) {
1186                 mOnCancelListenerCalled = true;
1187             }
1188         });
1189         dialogCancel(d);
1190 
1191         assertFalse(d.isShowing());
1192         assertTrue(mOnCancelListenerCalled);
1193 
1194         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
1195         assertTrue(d.isShowing());
1196         mOnCancelListenerCalled = false;
1197         d.setOnCancelListener(null);
1198         dialogCancel(d);
1199 
1200         assertFalse(d.isShowing());
1201         assertFalse(mOnCancelListenerCalled);
1202     }
1203 
1204     @TestTargetNew(
1205         level = TestLevel.COMPLETE,
1206         notes = "test method: setCancelMessage",
1207         method = "setCancelMessage",
1208         args = {android.os.Message.class}
1209     )
testSetCancelMessage()1210     public void testSetCancelMessage() throws Exception {
1211         mCalledCallback = false;
1212         popDialog(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
1213         final TestDialog d = (TestDialog) mActivity.getDialog();
1214         final HandlerThread ht = new HandlerThread("DialogTest");
1215         ht.start();
1216 
1217         d.setCancelMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(CANCEL,
1218                 new OnCancelListener() {
1219                     public void onCancel(DialogInterface dialog) {
1220                         mCalledCallback = true;
1221                     }
1222                 }));
1223         assertTrue(d.isShowing());
1224         assertFalse(mCalledCallback);
1225         sendKeys(KeyEvent.KEYCODE_BACK);
1226         assertTrue(mCalledCallback);
1227         assertFalse(d.isShowing());
1228 
1229         ht.join(100);
1230     }
1231 
1232     /*
1233      * Test point
1234      * 1. Set a listener to be invoked when the dialog is dismissed.
1235      * 2. set onDismissListener to null, it will not changed flag after dialog dismissed.
1236      */
1237     @TestTargetNew(
1238         level = TestLevel.COMPLETE,
1239         method = "setOnDismissListener",
1240         args = {android.content.DialogInterface.OnDismissListener.class}
1241     )
testSetOnDismissListener()1242     public void testSetOnDismissListener() throws Throwable {
1243         mCalledCallback = false;
1244         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
1245         final Dialog d = mActivity.getDialog();
1246 
1247         d.setOnDismissListener(new OnDismissListener() {
1248             public void onDismiss(DialogInterface dialog) {
1249                 mCalledCallback = true;
1250             }
1251         });
1252 
1253         assertTrue(d.isShowing());
1254         assertFalse(mCalledCallback);
1255         dialogDismiss(d);
1256         assertTrue(mCalledCallback);
1257         assertFalse(d.isShowing());
1258 
1259         // show the dialog again
1260         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
1261         assertTrue(d.isShowing());
1262         mCalledCallback = false;
1263         d.setOnDismissListener(null);
1264         dialogDismiss(d);
1265         assertFalse(mCalledCallback);
1266         assertFalse(d.isShowing());
1267     }
1268 
1269     @TestTargetNew(
1270         level = TestLevel.COMPLETE,
1271         method = "setDismissMessage",
1272         args = {android.os.Message.class}
1273     )
testSetDismissMessage()1274     public void testSetDismissMessage() throws Throwable {
1275         mCalledCallback = false;
1276         popDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
1277         final Dialog d = mActivity.getDialog();
1278 
1279         final HandlerThread ht = new HandlerThread("DialogTest");
1280         ht.start();
1281 
1282         d.setDismissMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(DISMISS,
1283                 new OnDismissListener() {
1284                     public void onDismiss(DialogInterface dialog) {
1285                         mCalledCallback = true;
1286                     }
1287                 }));
1288         assertTrue(d.isShowing());
1289         assertFalse(mCalledCallback);
1290         dialogDismiss(d);
1291         assertTrue(mCalledCallback);
1292         assertFalse(d.isShowing());
1293 
1294         ht.join(100);
1295     }
1296 
dialogDismiss(final Dialog d)1297     private void dialogDismiss(final Dialog d) throws Throwable {
1298         runTestOnUiThread(new Runnable() {
1299             public void run() {
1300                 d.dismiss();
1301             }
1302         });
1303         mInstrumentation.waitForIdleSync();
1304     }
1305 
dialogCancel(final Dialog d)1306     private void dialogCancel(final Dialog d) throws Throwable {
1307         runTestOnUiThread(new Runnable() {
1308             public void run() {
1309                 d.cancel();
1310             }
1311         });
1312         mInstrumentation.waitForIdleSync();
1313     }
1314 
1315     private static class MockDismissCancelHandler extends Handler {
1316         private WeakReference<DialogInterface> mDialog;
1317 
MockDismissCancelHandler(Dialog dialog, Looper looper)1318         public MockDismissCancelHandler(Dialog dialog, Looper looper) {
1319             super(looper);
1320 
1321             mDialog = new WeakReference<DialogInterface>(dialog);
1322         }
1323 
1324         @Override
handleMessage(Message msg)1325         public void handleMessage(Message msg) {
1326             switch (msg.what) {
1327             case DISMISS:
1328                 ((OnDismissListener) msg.obj).onDismiss(mDialog.get());
1329                 break;
1330             case CANCEL:
1331                 ((OnCancelListener) msg.obj).onCancel(mDialog.get());
1332                 break;
1333             }
1334         }
1335     }
1336 
1337     private static class MockDrawable extends Drawable {
1338         @Override
draw(Canvas canvas)1339         public void draw(Canvas canvas) {
1340         }
1341 
1342         @Override
getOpacity()1343         public int getOpacity() {
1344             return 0;
1345         }
1346 
1347         @Override
setAlpha(int alpha)1348         public void setAlpha(int alpha) {
1349         }
1350 
1351         @Override
setColorFilter(ColorFilter cf)1352         public void setColorFilter(ColorFilter cf) {
1353         }
1354     }
1355 
1356     private static class MockView extends View {
1357         public boolean isShowContextMenuCalled;
1358 
MockView(Context context)1359         public MockView(Context context) {
1360             super(context);
1361         }
1362 
getOnCreateContextMenuListener()1363         public OnCreateContextMenuListener getOnCreateContextMenuListener() {
1364             return mOnCreateContextMenuListener;
1365         }
1366 
1367         @Override
showContextMenu()1368         public boolean showContextMenu() {
1369             isShowContextMenuCalled = true;
1370             return super.showContextMenu();
1371         }
1372     }
1373 }
1374