• 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 com.android.cts.app.stub.R;
19 
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.PackageManager;
28 import android.content.res.Resources;
29 import android.content.res.TypedArray;
30 import android.cts.util.PollingCheck;
31 import android.graphics.Canvas;
32 import android.graphics.ColorFilter;
33 import android.graphics.drawable.Drawable;
34 import android.net.Uri;
35 import android.os.Handler;
36 import android.os.HandlerThread;
37 import android.os.Looper;
38 import android.os.Message;
39 import android.os.SystemClock;
40 import android.test.ActivityInstrumentationTestCase2;
41 import android.test.UiThreadTest;
42 import android.view.KeyEvent;
43 import android.view.LayoutInflater;
44 import android.view.MotionEvent;
45 import android.view.View;
46 import android.view.ViewGroup;
47 import android.view.Window;
48 import android.view.WindowManager;
49 import android.widget.LinearLayout;
50 
51 import java.lang.ref.WeakReference;
52 
53 public class DialogTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
54 
55     protected static final long SLEEP_TIME = 200;
56     private static final String STUB_ACTIVITY_PACKAGE = "com.android.cts.app.stub";
57     private static final long TEST_TIMEOUT = 1000L;
58 
59     /**
60      *  please refer to Dialog
61      */
62     private static final int DISMISS = 0x43;
63     private static final int CANCEL = 0x44;
64 
65     private boolean mCalledCallback;
66     private boolean mIsKey0Listened;
67     private boolean mIsKey1Listened;
68     private boolean mOnCancelListenerCalled;
69 
70     private Instrumentation mInstrumentation;
71     private Context mContext;
72     private DialogStubActivity mActivity;
73 
74 
DialogTest()75     public DialogTest() {
76         super(STUB_ACTIVITY_PACKAGE, DialogStubActivity.class);
77     }
78 
79     @Override
setUp()80     protected void setUp() throws Exception {
81         super.setUp();
82         mInstrumentation = getInstrumentation();
83         mContext = mInstrumentation.getContext();
84     }
85 
startDialogActivity(int dialogNumber)86     private void startDialogActivity(int dialogNumber) {
87         mActivity = DialogStubActivity.startDialogActivity(this, dialogNumber);
88     }
89 
90     @UiThreadTest
testConstructor()91     public void testConstructor() {
92         new Dialog(mContext);
93         Dialog d = new Dialog(mContext, 0);
94         // According to javadoc of constructors, it will set theme to system default theme,
95         // when we set no theme id or set it theme id to 0.
96         // But CTS can no assert dialog theme equals system internal theme.
97 
98         d = new Dialog(mContext, R.style.TextAppearance);
99         TypedArray ta =
100             d.getContext().getTheme().obtainStyledAttributes(R.styleable.TextAppearance);
101         assertTextAppearanceStyle(ta);
102 
103         final Window w = d.getWindow();
104         ta = w.getContext().getTheme().obtainStyledAttributes(R.styleable.TextAppearance);
105         assertTextAppearanceStyle(ta);
106     }
107 
testConstructor_protectedCancellable()108     public void testConstructor_protectedCancellable() {
109         startDialogActivity(DialogStubActivity.TEST_PROTECTED_CANCELABLE);
110         mActivity.onCancelListenerCalled = false;
111         sendKeys(KeyEvent.KEYCODE_BACK);
112         assertTrue(mActivity.onCancelListenerCalled);
113     }
114 
testConstructor_protectedNotCancellable()115     public void testConstructor_protectedNotCancellable() {
116         startDialogActivity(DialogStubActivity.TEST_PROTECTED_NOT_CANCELABLE);
117         mActivity.onCancelListenerCalled = false;
118         sendKeys(KeyEvent.KEYCODE_BACK);
119         assertFalse(mActivity.onCancelListenerCalled);
120     }
121 
assertTextAppearanceStyle(TypedArray ta)122     private void assertTextAppearanceStyle(TypedArray ta) {
123         final int defValue = -1;
124         // get Theme and assert
125         final Resources.Theme expected = mContext.getResources().newTheme();
126         expected.setTo(mContext.getTheme());
127         expected.applyStyle(R.style.TextAppearance, true);
128         TypedArray expectedTa = expected.obtainStyledAttributes(R.styleable.TextAppearance);
129         assertEquals(expectedTa.getIndexCount(), ta.getIndexCount());
130         assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColor, defValue),
131                 ta.getColor(R.styleable.TextAppearance_textColor, defValue));
132         assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorHint, defValue),
133                 ta.getColor(R.styleable.TextAppearance_textColorHint, defValue));
134         assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorLink, defValue),
135                 ta.getColor(R.styleable.TextAppearance_textColorLink, defValue));
136         assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorHighlight, defValue),
137                 ta.getColor(R.styleable.TextAppearance_textColorHighlight, defValue));
138         assertEquals(expectedTa.getDimension(R.styleable.TextAppearance_textSize, defValue),
139                 ta.getDimension(R.styleable.TextAppearance_textSize, defValue));
140         assertEquals(expectedTa.getInt(R.styleable.TextAppearance_textStyle, defValue),
141                 ta.getInt(R.styleable.TextAppearance_textStyle, defValue));
142     }
143 
testOnStartCreateStop()144     public void testOnStartCreateStop(){
145         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
146         final TestDialog d = (TestDialog) mActivity.getDialog();
147 
148         assertTrue(d.isOnStartCalled);
149         assertTrue(d.isOnCreateCalled);
150 
151         assertFalse(d.isOnStopCalled);
152         sendKeys(KeyEvent.KEYCODE_BACK);
153         assertTrue(d.isOnStopCalled);
154     }
155 
testAccessOwnerActivity()156     public void testAccessOwnerActivity() throws Throwable {
157         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
158         Dialog d = mActivity.getDialog();
159         assertNotNull(d);
160         assertSame(mActivity, d.getOwnerActivity());
161         d.setVolumeControlStream(d.getVolumeControlStream() + 1);
162         assertEquals(d.getOwnerActivity().getVolumeControlStream() + 1, d.getVolumeControlStream());
163 
164         try {
165             d.setOwnerActivity(null);
166             fail("Should throw NullPointerException");
167         } catch (NullPointerException e) {
168             // expected
169         }
170 
171         runTestOnUiThread(new Runnable() {
172             public void run() {
173                 Dialog dialog = new Dialog(mContext);
174                 assertNull(dialog.getOwnerActivity());
175             }
176         });
177         mInstrumentation.waitForIdleSync();
178     }
179 
testShow()180     public void testShow() throws Throwable {
181         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
182         final Dialog d = mActivity.getDialog();
183         final View decor = d.getWindow().getDecorView();
184 
185         runTestOnUiThread(new Runnable() {
186             public void run() {
187                 d.hide();
188             }
189         });
190         mInstrumentation.waitForIdleSync();
191 
192         assertEquals(View.GONE, decor.getVisibility());
193         assertTrue(d.isShowing());
194 
195         runTestOnUiThread(new Runnable() {
196             public void run() {
197                 d.show();
198             }
199         });
200         mInstrumentation.waitForIdleSync();
201 
202         assertEquals(View.VISIBLE, decor.getVisibility());
203         assertTrue(d.isShowing());
204         dialogDismiss(d);
205         assertFalse(d.isShowing());
206     }
207 
testOnSaveInstanceState()208     public void testOnSaveInstanceState() {
209         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
210         final TestDialog d = (TestDialog) mActivity.getDialog();
211 
212         assertFalse(d.isOnSaveInstanceStateCalled);
213         assertFalse(TestDialog.isOnRestoreInstanceStateCalled);
214 
215         //skip if the device doesn't support both of portrait and landscape orientation screens.
216         final PackageManager pm = mContext.getPackageManager();
217         if(!(pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
218                 && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT))){
219             return;
220         }
221 
222         OrientationTestUtils.toggleOrientationSync(mActivity, mInstrumentation);
223 
224         assertTrue(d.isOnSaveInstanceStateCalled);
225         assertTrue(TestDialog.isOnRestoreInstanceStateCalled);
226     }
227 
testGetCurrentFocus()228     public void testGetCurrentFocus() throws Throwable {
229         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
230         final TestDialog d = (TestDialog) mActivity.getDialog();
231         assertNull(d.getCurrentFocus());
232         runTestOnUiThread(new Runnable() {
233             public void run() {
234                 d.takeKeyEvents(true);
235                 d.setContentView(R.layout.alert_dialog_text_entry);
236             }
237         });
238         mInstrumentation.waitForIdleSync();
239 
240         sendKeys(KeyEvent.KEYCODE_0);
241         // When mWindow is not null getCUrrentFocus is the view in dialog
242         assertEquals(d.getWindow().getCurrentFocus(), d.getCurrentFocus());
243     }
244 
testSetContentView()245     public void testSetContentView() throws Throwable {
246         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
247         final Dialog d = mActivity.getDialog();
248         assertNotNull(d);
249 
250         // set content view to a four elements layout
251         runTestOnUiThread(new Runnable() {
252             public void run() {
253                 d.setContentView(R.layout.alert_dialog_text_entry);
254             }
255         });
256         mInstrumentation.waitForIdleSync();
257 
258         // check if four elements are right there
259         assertNotNull(d.findViewById(R.id.username_view));
260         assertNotNull(d.findViewById(R.id.username_edit));
261         assertNotNull(d.findViewById(R.id.password_view));
262         assertNotNull(d.findViewById(R.id.password_edit));
263 
264         final LayoutInflater inflate1 = d.getLayoutInflater();
265 
266         // set content view to a two elements layout
267         runTestOnUiThread(new Runnable() {
268             public void run() {
269                 d.setContentView(inflate1.inflate(R.layout.alert_dialog_text_entry_2, null));
270             }
271         });
272         mInstrumentation.waitForIdleSync();
273 
274         // check if only two elements are right there
275         assertNotNull(d.findViewById(R.id.username_view));
276         assertNotNull(d.findViewById(R.id.username_edit));
277         assertNull(d.findViewById(R.id.password_view));
278         assertNull(d.findViewById(R.id.password_edit));
279 
280         final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
281         final LayoutInflater inflate2 = mActivity.getLayoutInflater();
282 
283         // set content view to a four elements layout
284         runTestOnUiThread(new Runnable() {
285             public void run() {
286                 d.setContentView(inflate2.inflate(R.layout.alert_dialog_text_entry, null), lp);
287             }
288         });
289         mInstrumentation.waitForIdleSync();
290 
291         // check if four elements are right there
292         assertNotNull(d.findViewById(R.id.username_view));
293         assertNotNull(d.findViewById(R.id.username_edit));
294         assertNotNull(d.findViewById(R.id.password_view));
295         assertNotNull(d.findViewById(R.id.password_edit));
296 
297         final WindowManager.LayoutParams lp2 = d.getWindow().getAttributes();
298         final LayoutInflater inflate3 = mActivity.getLayoutInflater();
299         lp2.height = ViewGroup.LayoutParams.WRAP_CONTENT;
300         lp2.width = ViewGroup.LayoutParams.WRAP_CONTENT;
301 
302         // add a check box view
303         runTestOnUiThread(new Runnable() {
304             public void run() {
305                 d.addContentView(inflate3.inflate(R.layout.checkbox_layout, null), lp2);
306             }
307         });
308         mInstrumentation.waitForIdleSync();
309 
310         // check if four elements are right there, and new add view there.
311         assertNotNull(d.findViewById(R.id.check_box));
312         assertNotNull(d.findViewById(R.id.username_view));
313         assertNotNull(d.findViewById(R.id.username_edit));
314         assertNotNull(d.findViewById(R.id.password_view));
315         assertNotNull(d.findViewById(R.id.password_edit));
316     }
317 
testSetTitle()318     public void testSetTitle() {
319         final String expectedTitle = "Test Dialog Without theme";
320         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
321 
322         assertNotNull(mActivity.getDialog());
323         mActivity.setUpTitle(expectedTitle);
324         mInstrumentation.waitForIdleSync();
325 
326         final Dialog d = mActivity.getDialog();
327         assertEquals(expectedTitle, (String) d.getWindow().getAttributes().getTitle());
328 
329         mActivity.setUpTitle(R.string.hello_android);
330         mInstrumentation.waitForIdleSync();
331         assertEquals(mActivity.getResources().getString(R.string.hello_android),
332                 (String) d.getWindow().getAttributes().getTitle());
333     }
334 
testOnKeyDownKeyUp()335     public void testOnKeyDownKeyUp() {
336         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
337         final TestDialog d = (TestDialog) mActivity.getDialog();
338         assertFalse(d.isOnKeyDownCalled);
339         assertFalse(d.isOnKeyUpCalled);
340 
341         // send key 0 down and up events, onKeyDown return false
342         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
343         assertTrue(d.isOnKeyDownCalled);
344         assertTrue(d.isOnKeyUpCalled);
345         assertEquals(KeyEvent.KEYCODE_0, d.keyDownCode);
346         assertFalse(d.onKeyDownReturn);
347 
348         // send key back down and up events, onKeyDown return true
349         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
350         assertEquals(KeyEvent.KEYCODE_BACK, d.keyDownCode);
351         assertTrue(d.onKeyDownReturn);
352     }
353 
testOnKeyMultiple()354      public void testOnKeyMultiple() {
355          startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
356          final TestDialog d = (TestDialog) mActivity.getDialog();
357 
358          assertNull(d.keyMultipleEvent);
359          d.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_UNKNOWN));
360          assertTrue(d.isOnKeyMultipleCalled);
361          assertFalse(d.onKeyMultipleReturn);
362          assertEquals(KeyEvent.KEYCODE_UNKNOWN, d.keyMultipleEvent.getKeyCode());
363          assertEquals(KeyEvent.ACTION_MULTIPLE, d.keyMultipleEvent.getAction());
364      }
365 
testTouchEvent()366     public void testTouchEvent() {
367         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
368         final TestDialog d = (TestDialog) mActivity.getDialog();
369 
370         assertNull(d.onTouchEvent);
371         assertNull(d.touchEvent);
372         assertFalse(d.isOnTouchEventCalled);
373 
374         // Send a touch event outside the activity.  The event will be ignored
375         // because closeOnTouchOutside is false.
376         d.setCanceledOnTouchOutside(false);
377 
378         long now = SystemClock.uptimeMillis();
379         MotionEvent touchMotionEvent = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
380                 1, 100, 0);
381         mInstrumentation.sendPointerSync(touchMotionEvent);
382 
383         new PollingCheck(TEST_TIMEOUT) {
384             protected boolean check() {
385                 return !d.dispatchTouchEventResult;
386             }
387         }.run();
388 
389         assertMotionEventEquals(touchMotionEvent, d.touchEvent);
390 
391         assertTrue(d.isOnTouchEventCalled);
392         assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
393         d.isOnTouchEventCalled = false;
394         assertTrue(d.isShowing());
395 
396         // Send a touch event outside the activity.  This time the dialog will be dismissed
397         // because closeOnTouchOutside is true.
398         d.setCanceledOnTouchOutside(true);
399 
400         touchMotionEvent = MotionEvent.obtain(now, now + 1, MotionEvent.ACTION_DOWN,
401                 1, 100, 0);
402         mInstrumentation.sendPointerSync(touchMotionEvent);
403 
404         new PollingCheck(TEST_TIMEOUT) {
405             protected boolean check() {
406                 return d.dispatchTouchEventResult;
407             }
408         }.run();
409 
410         assertMotionEventEquals(touchMotionEvent, d.touchEvent);
411 
412         assertTrue(d.isOnTouchEventCalled);
413         assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
414         assertFalse(d.isShowing());
415     }
416 
testTrackballEvent()417     public void testTrackballEvent() {
418         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
419         final TestDialog d = (TestDialog) mActivity.getDialog();
420         long eventTime = SystemClock.uptimeMillis();
421         final MotionEvent trackBallEvent = MotionEvent.obtain(eventTime, eventTime,
422                 MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0);
423 
424         assertNull(d.trackballEvent);
425         assertNull(d.onTrackballEvent);
426 
427         assertFalse(d.isOnTrackballEventCalled);
428         mInstrumentation.sendTrackballEventSync(trackBallEvent);
429         assertTrue(d.isOnTrackballEventCalled);
430         assertMotionEventEquals(trackBallEvent, d.trackballEvent);
431         assertMotionEventEquals(trackBallEvent, d.onTrackballEvent);
432 
433     }
434 
assertMotionEventEquals(final MotionEvent expected, final MotionEvent actual)435     private void assertMotionEventEquals(final MotionEvent expected, final MotionEvent actual) {
436         assertEquals(expected.getDownTime(), actual.getDownTime());
437         assertEquals(expected.getEventTime(), actual.getEventTime());
438         assertEquals(expected.getAction(), actual.getAction());
439         assertEquals(expected.getMetaState(), actual.getMetaState());
440         assertEquals(expected.getSize(), actual.getSize());
441         // As MotionEvent doc says the value of X and Y coordinate may have
442         // a fraction for input devices that are sub-pixel precise,
443         // so we won't assert them here.
444     }
445 
testOnWindowAttributesChanged()446     public void testOnWindowAttributesChanged() throws Throwable {
447         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
448         final TestDialog d = (TestDialog) mActivity.getDialog();
449 
450         assertTrue(d.isOnWindowAttributesChangedCalled);
451         d.isOnWindowAttributesChangedCalled = false;
452 
453         final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
454         lp.setTitle("test OnWindowAttributesChanged");
455         runTestOnUiThread(new Runnable() {
456             public void run() {
457                 d.getWindow().setAttributes(lp);
458             }
459         });
460         mInstrumentation.waitForIdleSync();
461 
462         assertTrue(d.isOnWindowAttributesChangedCalled);
463         assertSame(lp, d.getWindow().getAttributes());
464     }
465 
testOnContentChanged()466     public void testOnContentChanged() throws Throwable {
467         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
468         final TestDialog d = (TestDialog) mActivity.getDialog();
469         assertNotNull(d);
470 
471         assertFalse(d.isOnContentChangedCalled);
472 
473         runTestOnUiThread(new Runnable() {
474             public void run() {
475                 d.setContentView(R.layout.alert_dialog_text_entry);
476             }
477         });
478         mInstrumentation.waitForIdleSync();
479 
480         assertTrue(d.isOnContentChangedCalled);
481     }
482 
testOnWindowFocusChanged()483     public void testOnWindowFocusChanged() throws Throwable {
484         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
485         final TestDialog d = (TestDialog) mActivity.getDialog();
486         assertTrue(d.isOnWindowFocusChangedCalled);
487         d.isOnWindowFocusChangedCalled = false;
488 
489         // show a new dialog, the new dialog get focus
490         runTestOnUiThread(new Runnable() {
491             public void run() {
492                 mActivity.showDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
493             }
494         });
495         mInstrumentation.waitForIdleSync();
496 
497         // Wait until TestDialog#OnWindowFocusChanged() is called
498         new PollingCheck(TEST_TIMEOUT) {
499             protected boolean check() {
500                 return d.isOnWindowFocusChangedCalled;
501             }
502         }.run();
503     }
504 
testDispatchKeyEvent()505     public void testDispatchKeyEvent() {
506         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
507         final TestDialog d = (TestDialog) mActivity.getDialog();
508 
509         sendKeys(KeyEvent.KEYCODE_0);
510         assertFalse(d.dispatchKeyEventResult);
511         assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
512 
513         d.setOnKeyListener(new OnKeyListener() {
514             public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
515                 if (KeyEvent.ACTION_DOWN == event.getAction()) {
516                     if (KeyEvent.KEYCODE_0 == keyCode) {
517                         mIsKey0Listened = true;
518                         return true;
519                     }
520 
521                     if (KeyEvent.KEYCODE_1 == keyCode) {
522                         mIsKey1Listened = true;
523                         return true;
524                     }
525                 }
526 
527                 return false;
528             }
529         });
530 
531         mIsKey1Listened = false;
532         sendKeys(KeyEvent.KEYCODE_1);
533         assertTrue(mIsKey1Listened);
534 
535         mIsKey0Listened = false;
536         sendKeys(KeyEvent.KEYCODE_0);
537         assertTrue(mIsKey0Listened);
538     }
539 
540     /*
541      * Test point
542      * 1. registerForContextMenu() will OnCreateContextMenuListener on the view to this activity,
543      * so onCreateContextMenu() will be called when it is time to show the context menu.
544      * 2. Close context menu will make onPanelClosed to be called,
545      * and onPanelClosed will calls through to the new onPanelClosed method.
546      * 3. unregisterForContextMenu() will remove the OnCreateContextMenuListener on the view,
547      * so onCreateContextMenu() will not be called when try to open context menu.
548      * 4. Selected a item of context menu will make onMenuItemSelected() to be called,
549      * and onMenuItemSelected will calls through to the new onContextItemSelected method.
550      * 5. onContextMenuClosed is called whenever the context menu is being closed (either by
551      * the user canceling the menu with the back/menu button, or when an item is selected).
552      */
testContextMenu()553     public void testContextMenu() throws Throwable {
554         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
555         final TestDialog d = (TestDialog) mActivity.getDialog();
556         final LinearLayout parent = new LinearLayout(mContext);
557         final MockView v = new MockView(mContext);
558         parent.addView(v);
559         assertFalse(v.isShowContextMenuCalled);
560         // Register for context menu and open it
561         runTestOnUiThread(new Runnable() {
562             public void run() {
563                 d.addContentView(parent, new LinearLayout.LayoutParams(
564                         ViewGroup.LayoutParams.MATCH_PARENT,
565                         ViewGroup.LayoutParams.WRAP_CONTENT));
566                 d.registerForContextMenu(v);
567                 d.openContextMenu(v);
568             }
569         });
570         mInstrumentation.waitForIdleSync();
571 
572         assertTrue(v.isShowContextMenuCalled);
573         assertTrue(d.isOnCreateContextMenuCalled);
574 
575         assertFalse(d.isOnPanelClosedCalled);
576         assertFalse(d.isOnContextMenuClosedCalled);
577         // Closed context menu
578         sendKeys(KeyEvent.KEYCODE_BACK);
579         assertTrue(d.isOnPanelClosedCalled);
580         // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
581         assertFalse(d.isOnContextMenuClosedCalled);
582 
583         v.isShowContextMenuCalled = false;
584         d.isOnCreateContextMenuCalled = false;
585         // Unregister for context menu, and try to open it
586         runTestOnUiThread(new Runnable() {
587             public void run() {
588                 d.unregisterForContextMenu(v);
589             }
590         });
591         mInstrumentation.waitForIdleSync();
592 
593         runTestOnUiThread(new Runnable() {
594             public void run() {
595                 d.openContextMenu(v);
596             }
597         });
598         mInstrumentation.waitForIdleSync();
599 
600         assertTrue(v.isShowContextMenuCalled);
601         assertFalse(d.isOnCreateContextMenuCalled);
602 
603         // Register for context menu and open it again
604         runTestOnUiThread(new Runnable() {
605             public void run() {
606                 d.registerForContextMenu(v);
607                 d.openContextMenu(v);
608             }
609         });
610         mInstrumentation.waitForIdleSync();
611 
612         assertFalse(d.isOnContextItemSelectedCalled);
613         assertFalse(d.isOnMenuItemSelectedCalled);
614         d.isOnPanelClosedCalled = false;
615         assertFalse(d.isOnContextMenuClosedCalled);
616         // select a context menu item
617         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
618         assertTrue(d.isOnMenuItemSelectedCalled);
619         // Here isOnContextItemSelectedCalled should be true, see bug 1716918.
620         assertFalse(d.isOnContextItemSelectedCalled);
621         assertTrue(d.isOnPanelClosedCalled);
622         // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
623         assertFalse(d.isOnContextMenuClosedCalled);
624     }
625 
testOnSearchRequested()626     public void testOnSearchRequested() {
627     }
628 
testTakeKeyEvents()629     public void testTakeKeyEvents() throws Throwable {
630         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
631         final TestDialog d = (TestDialog) mActivity.getDialog();
632         final View v = d.getWindow().getDecorView();
633         assertNull(d.getCurrentFocus());
634         takeKeyEvents(d, true);
635         assertTrue(v.isFocusable());
636         sendKeys(KeyEvent.KEYCODE_0);
637         assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
638         d.keyEvent = null;
639 
640         takeKeyEvents(d, false);
641         assertNull(d.getCurrentFocus());
642         assertFalse(v.isFocusable());
643         sendKeys(KeyEvent.KEYCODE_0);
644         // d.keyEvent should be null
645     }
646 
takeKeyEvents(final Dialog d, final boolean get)647     private void takeKeyEvents(final Dialog d, final boolean get) throws Throwable {
648         runTestOnUiThread(new Runnable() {
649             public void run() {
650                 d.takeKeyEvents(get);
651             }
652         });
653         mInstrumentation.waitForIdleSync();
654     }
655 
testRequestWindowFeature()656     public void testRequestWindowFeature() {
657         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
658         // called requestWindowFeature at TestDialog onCreate method
659         assertTrue(((TestDialog) mActivity.getDialog()).isRequestWindowFeature);
660     }
661 
testSetFeatureDrawableResource()662     public void testSetFeatureDrawableResource() throws Throwable {
663         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
664         runTestOnUiThread(new Runnable() {
665             public void run() {
666                 mActivity.getDialog().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
667                         R.drawable.robot);
668             }
669         });
670         mInstrumentation.waitForIdleSync();
671     }
672 
testSetFeatureDrawableUri()673     public void testSetFeatureDrawableUri() {
674         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
675         mActivity.getDialog().setFeatureDrawableUri(0, Uri.parse("http://www.google.com"));
676     }
677 
testSetFeatureDrawable()678     public void testSetFeatureDrawable() {
679         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
680         mActivity.getDialog().setFeatureDrawable(0, new MockDrawable());
681     }
682 
testSetFeatureDrawableAlpha()683     public void testSetFeatureDrawableAlpha() {
684         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
685         mActivity.getDialog().setFeatureDrawableAlpha(0, 0);
686     }
687 
testGetLayoutInflater()688     public void testGetLayoutInflater() {
689         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
690         final Dialog d = mActivity.getDialog();
691         assertEquals(d.getWindow().getLayoutInflater(), d.getLayoutInflater());
692     }
693 
testSetCancelable_true()694     public void testSetCancelable_true() {
695         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
696         final Dialog d = mActivity.getDialog();
697 
698         d.setCancelable(true);
699         assertTrue(d.isShowing());
700         sendKeys(KeyEvent.KEYCODE_BACK);
701         assertFalse(d.isShowing());
702     }
703 
testSetCancellable_false()704     public void testSetCancellable_false() {
705         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
706         final Dialog d = mActivity.getDialog();
707 
708         d.setCancelable(false);
709         assertTrue(d.isShowing());
710         sendKeys(KeyEvent.KEYCODE_BACK);
711         assertTrue(d.isShowing());
712     }
713 
714     /*
715      * Test point
716      * 1. Cancel the dialog.
717      * 2. Set a listener to be invoked when the dialog is canceled.
718      */
testCancel_listener()719     public void testCancel_listener() throws Throwable {
720         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
721         final Dialog d = mActivity.getDialog();
722 
723         assertTrue(d.isShowing());
724         mOnCancelListenerCalled = false;
725         d.setOnCancelListener(new OnCancelListener() {
726             public void onCancel(DialogInterface dialog) {
727                 mOnCancelListenerCalled = true;
728             }
729         });
730         dialogCancel(d);
731 
732         assertFalse(d.isShowing());
733         assertTrue(mOnCancelListenerCalled);
734     }
735 
testCancel_noListener()736     public void testCancel_noListener() throws Throwable {
737         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
738         final Dialog d = mActivity.getDialog();
739 
740         assertTrue(d.isShowing());
741         mOnCancelListenerCalled = false;
742         d.setOnCancelListener(null);
743         dialogCancel(d);
744 
745         assertFalse(d.isShowing());
746         assertFalse(mOnCancelListenerCalled);
747     }
748 
testSetCancelMessage()749     public void testSetCancelMessage() throws Exception {
750         mCalledCallback = false;
751         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
752         final TestDialog d = (TestDialog) mActivity.getDialog();
753         final HandlerThread ht = new HandlerThread("DialogTest");
754         ht.start();
755 
756         d.setCancelMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(CANCEL,
757                 new OnCancelListener() {
758                     public void onCancel(DialogInterface dialog) {
759                         mCalledCallback = true;
760                     }
761                 }));
762         assertTrue(d.isShowing());
763         assertFalse(mCalledCallback);
764         sendKeys(KeyEvent.KEYCODE_BACK);
765         assertTrue(mCalledCallback);
766         assertFalse(d.isShowing());
767 
768         ht.join(100);
769     }
770 
771     /*
772      * Test point
773      * 1. Set a listener to be invoked when the dialog is dismissed.
774      * 2. set onDismissListener to null, it will not changed flag after dialog dismissed.
775      */
testSetOnDismissListener_listener()776     public void testSetOnDismissListener_listener() throws Throwable {
777         mCalledCallback = false;
778         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
779         final Dialog d = mActivity.getDialog();
780 
781         d.setOnDismissListener(new OnDismissListener() {
782             public void onDismiss(DialogInterface dialog) {
783                 mCalledCallback = true;
784             }
785         });
786 
787         assertTrue(d.isShowing());
788         assertFalse(mCalledCallback);
789         dialogDismiss(d);
790         assertTrue(mCalledCallback);
791         assertFalse(d.isShowing());
792     }
793 
testSetOnDismissListener_noListener()794     public void testSetOnDismissListener_noListener() throws Throwable {
795         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
796         final Dialog d = mActivity.getDialog();
797         assertTrue(d.isShowing());
798         mCalledCallback = false;
799         d.setOnDismissListener(null);
800         dialogDismiss(d);
801         assertFalse(mCalledCallback);
802         assertFalse(d.isShowing());
803     }
804 
testSetDismissMessage()805     public void testSetDismissMessage() throws Throwable {
806         mCalledCallback = false;
807         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
808         final Dialog d = mActivity.getDialog();
809 
810         final HandlerThread ht = new HandlerThread("DialogTest");
811         ht.start();
812 
813         d.setDismissMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(DISMISS,
814                 new OnDismissListener() {
815                     public void onDismiss(DialogInterface dialog) {
816                         mCalledCallback = true;
817                     }
818                 }));
819         assertTrue(d.isShowing());
820         assertFalse(mCalledCallback);
821         dialogDismiss(d);
822         ht.join(100);
823         assertTrue(mCalledCallback);
824         assertFalse(d.isShowing());
825     }
826 
dialogDismiss(final Dialog d)827     private void dialogDismiss(final Dialog d) throws Throwable {
828         runTestOnUiThread(new Runnable() {
829             public void run() {
830                 d.dismiss();
831             }
832         });
833         mInstrumentation.waitForIdleSync();
834     }
835 
dialogCancel(final Dialog d)836     private void dialogCancel(final Dialog d) throws Throwable {
837         runTestOnUiThread(new Runnable() {
838             public void run() {
839                 d.cancel();
840             }
841         });
842         mInstrumentation.waitForIdleSync();
843     }
844 
845     private static class MockDismissCancelHandler extends Handler {
846         private WeakReference<DialogInterface> mDialog;
847 
MockDismissCancelHandler(Dialog dialog, Looper looper)848         public MockDismissCancelHandler(Dialog dialog, Looper looper) {
849             super(looper);
850 
851             mDialog = new WeakReference<DialogInterface>(dialog);
852         }
853 
854         @Override
handleMessage(Message msg)855         public void handleMessage(Message msg) {
856             switch (msg.what) {
857             case DISMISS:
858                 ((OnDismissListener) msg.obj).onDismiss(mDialog.get());
859                 break;
860             case CANCEL:
861                 ((OnCancelListener) msg.obj).onCancel(mDialog.get());
862                 break;
863             }
864         }
865     }
866 
867     private static class MockDrawable extends Drawable {
868         @Override
draw(Canvas canvas)869         public void draw(Canvas canvas) {
870         }
871 
872         @Override
getOpacity()873         public int getOpacity() {
874             return 0;
875         }
876 
877         @Override
setAlpha(int alpha)878         public void setAlpha(int alpha) {
879         }
880 
881         @Override
setColorFilter(ColorFilter cf)882         public void setColorFilter(ColorFilter cf) {
883         }
884     }
885 
886     private static class MockView extends View {
887         public boolean isShowContextMenuCalled;
888         protected OnCreateContextMenuListener mOnCreateContextMenuListener;
889 
MockView(Context context)890         public MockView(Context context) {
891             super(context);
892         }
893 
setOnCreateContextMenuListener(OnCreateContextMenuListener l)894         public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
895             super.setOnCreateContextMenuListener(l);
896             mOnCreateContextMenuListener = l;
897         }
898 
getOnCreateContextMenuListener()899         public OnCreateContextMenuListener getOnCreateContextMenuListener() {
900             return mOnCreateContextMenuListener;
901         }
902 
903         @Override
showContextMenu()904         public boolean showContextMenu() {
905             isShowContextMenuCalled = true;
906             return super.showContextMenu();
907         }
908     }
909 }
910