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