Home | History | Annotate | Download | only in cts
      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 
     75     public DialogTest() {
     76         super(STUB_ACTIVITY_PACKAGE, DialogStubActivity.class);
     77     }
     78 
     79     @Override
     80     protected void setUp() throws Exception {
     81         super.setUp();
     82         mInstrumentation = getInstrumentation();
     83         mContext = mInstrumentation.getContext();
     84     }
     85 
     86     private void startDialogActivity(int dialogNumber) {
     87         mActivity = DialogStubActivity.startDialogActivity(this, dialogNumber);
     88     }
     89 
     90     @UiThreadTest
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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         // Watch activities cover the entire screen, so there is no way to touch outside.
    397         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
    398             // Send a touch event outside the activity.  This time the dialog will be dismissed
    399             // because closeOnTouchOutside is true.
    400             d.setCanceledOnTouchOutside(true);
    401 
    402             touchMotionEvent = MotionEvent.obtain(now, now + 1, MotionEvent.ACTION_DOWN,
    403                     1, 100, 0);
    404             mInstrumentation.sendPointerSync(touchMotionEvent);
    405 
    406             new PollingCheck(TEST_TIMEOUT) {
    407                 protected boolean check() {
    408                     return d.dispatchTouchEventResult;
    409                 }
    410             }.run();
    411 
    412             assertMotionEventEquals(touchMotionEvent, d.touchEvent);
    413 
    414             assertTrue(d.isOnTouchEventCalled);
    415             assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
    416             assertFalse(d.isShowing());
    417         }
    418     }
    419 
    420     public void testTrackballEvent() {
    421         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    422         final TestDialog d = (TestDialog) mActivity.getDialog();
    423         long eventTime = SystemClock.uptimeMillis();
    424         final MotionEvent trackBallEvent = MotionEvent.obtain(eventTime, eventTime,
    425                 MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0);
    426 
    427         assertNull(d.trackballEvent);
    428         assertNull(d.onTrackballEvent);
    429 
    430         assertFalse(d.isOnTrackballEventCalled);
    431         mInstrumentation.sendTrackballEventSync(trackBallEvent);
    432         assertTrue(d.isOnTrackballEventCalled);
    433         assertMotionEventEquals(trackBallEvent, d.trackballEvent);
    434         assertMotionEventEquals(trackBallEvent, d.onTrackballEvent);
    435 
    436     }
    437 
    438     private void assertMotionEventEquals(final MotionEvent expected, final MotionEvent actual) {
    439         assertEquals(expected.getDownTime(), actual.getDownTime());
    440         assertEquals(expected.getEventTime(), actual.getEventTime());
    441         assertEquals(expected.getAction(), actual.getAction());
    442         assertEquals(expected.getMetaState(), actual.getMetaState());
    443         assertEquals(expected.getSize(), actual.getSize());
    444         // As MotionEvent doc says the value of X and Y coordinate may have
    445         // a fraction for input devices that are sub-pixel precise,
    446         // so we won't assert them here.
    447     }
    448 
    449     public void testOnWindowAttributesChanged() throws Throwable {
    450         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    451         final TestDialog d = (TestDialog) mActivity.getDialog();
    452 
    453         assertTrue(d.isOnWindowAttributesChangedCalled);
    454         d.isOnWindowAttributesChangedCalled = false;
    455 
    456         final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
    457         lp.setTitle("test OnWindowAttributesChanged");
    458         runTestOnUiThread(new Runnable() {
    459             public void run() {
    460                 d.getWindow().setAttributes(lp);
    461             }
    462         });
    463         mInstrumentation.waitForIdleSync();
    464 
    465         assertTrue(d.isOnWindowAttributesChangedCalled);
    466         assertSame(lp, d.getWindow().getAttributes());
    467     }
    468 
    469     public void testOnContentChanged() throws Throwable {
    470         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    471         final TestDialog d = (TestDialog) mActivity.getDialog();
    472         assertNotNull(d);
    473 
    474         assertFalse(d.isOnContentChangedCalled);
    475 
    476         runTestOnUiThread(new Runnable() {
    477             public void run() {
    478                 d.setContentView(R.layout.alert_dialog_text_entry);
    479             }
    480         });
    481         mInstrumentation.waitForIdleSync();
    482 
    483         assertTrue(d.isOnContentChangedCalled);
    484     }
    485 
    486     public void testOnWindowFocusChanged() throws Throwable {
    487         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    488         final TestDialog d = (TestDialog) mActivity.getDialog();
    489         assertTrue(d.isOnWindowFocusChangedCalled);
    490         d.isOnWindowFocusChangedCalled = false;
    491 
    492         // show a new dialog, the new dialog get focus
    493         runTestOnUiThread(new Runnable() {
    494             public void run() {
    495                 mActivity.showDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    496             }
    497         });
    498         mInstrumentation.waitForIdleSync();
    499 
    500         // Wait until TestDialog#OnWindowFocusChanged() is called
    501         new PollingCheck(TEST_TIMEOUT) {
    502             protected boolean check() {
    503                 return d.isOnWindowFocusChangedCalled;
    504             }
    505         }.run();
    506     }
    507 
    508     public void testDispatchKeyEvent() {
    509         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    510         final TestDialog d = (TestDialog) mActivity.getDialog();
    511 
    512         sendKeys(KeyEvent.KEYCODE_0);
    513         assertFalse(d.dispatchKeyEventResult);
    514         assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
    515 
    516         d.setOnKeyListener(new OnKeyListener() {
    517             public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
    518                 if (KeyEvent.ACTION_DOWN == event.getAction()) {
    519                     if (KeyEvent.KEYCODE_0 == keyCode) {
    520                         mIsKey0Listened = true;
    521                         return true;
    522                     }
    523 
    524                     if (KeyEvent.KEYCODE_1 == keyCode) {
    525                         mIsKey1Listened = true;
    526                         return true;
    527                     }
    528                 }
    529 
    530                 return false;
    531             }
    532         });
    533 
    534         mIsKey1Listened = false;
    535         sendKeys(KeyEvent.KEYCODE_1);
    536         assertTrue(mIsKey1Listened);
    537 
    538         mIsKey0Listened = false;
    539         sendKeys(KeyEvent.KEYCODE_0);
    540         assertTrue(mIsKey0Listened);
    541     }
    542 
    543     /*
    544      * Test point
    545      * 1. registerForContextMenu() will OnCreateContextMenuListener on the view to this activity,
    546      * so onCreateContextMenu() will be called when it is time to show the context menu.
    547      * 2. Close context menu will make onPanelClosed to be called,
    548      * and onPanelClosed will calls through to the new onPanelClosed method.
    549      * 3. unregisterForContextMenu() will remove the OnCreateContextMenuListener on the view,
    550      * so onCreateContextMenu() will not be called when try to open context menu.
    551      * 4. Selected a item of context menu will make onMenuItemSelected() to be called,
    552      * and onMenuItemSelected will calls through to the new onContextItemSelected method.
    553      * 5. onContextMenuClosed is called whenever the context menu is being closed (either by
    554      * the user canceling the menu with the back/menu button, or when an item is selected).
    555      */
    556     public void testContextMenu() throws Throwable {
    557         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    558         final TestDialog d = (TestDialog) mActivity.getDialog();
    559         final LinearLayout parent = new LinearLayout(mContext);
    560         final MockView v = new MockView(mContext);
    561         parent.addView(v);
    562         assertFalse(v.isShowContextMenuCalled);
    563         // Register for context menu and open it
    564         runTestOnUiThread(new Runnable() {
    565             public void run() {
    566                 d.addContentView(parent, new LinearLayout.LayoutParams(
    567                         ViewGroup.LayoutParams.MATCH_PARENT,
    568                         ViewGroup.LayoutParams.WRAP_CONTENT));
    569                 d.registerForContextMenu(v);
    570                 d.openContextMenu(v);
    571             }
    572         });
    573         mInstrumentation.waitForIdleSync();
    574 
    575         assertTrue(v.isShowContextMenuCalled);
    576         assertTrue(d.isOnCreateContextMenuCalled);
    577 
    578         assertFalse(d.isOnPanelClosedCalled);
    579         assertFalse(d.isOnContextMenuClosedCalled);
    580         // Closed context menu
    581         sendKeys(KeyEvent.KEYCODE_BACK);
    582         assertTrue(d.isOnPanelClosedCalled);
    583         // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
    584         assertFalse(d.isOnContextMenuClosedCalled);
    585 
    586         v.isShowContextMenuCalled = false;
    587         d.isOnCreateContextMenuCalled = false;
    588         // Unregister for context menu, and try to open it
    589         runTestOnUiThread(new Runnable() {
    590             public void run() {
    591                 d.unregisterForContextMenu(v);
    592             }
    593         });
    594         mInstrumentation.waitForIdleSync();
    595 
    596         runTestOnUiThread(new Runnable() {
    597             public void run() {
    598                 d.openContextMenu(v);
    599             }
    600         });
    601         mInstrumentation.waitForIdleSync();
    602 
    603         assertTrue(v.isShowContextMenuCalled);
    604         assertFalse(d.isOnCreateContextMenuCalled);
    605 
    606         // Register for context menu and open it again
    607         runTestOnUiThread(new Runnable() {
    608             public void run() {
    609                 d.registerForContextMenu(v);
    610                 d.openContextMenu(v);
    611             }
    612         });
    613         mInstrumentation.waitForIdleSync();
    614 
    615         assertFalse(d.isOnContextItemSelectedCalled);
    616         assertFalse(d.isOnMenuItemSelectedCalled);
    617         d.isOnPanelClosedCalled = false;
    618         assertFalse(d.isOnContextMenuClosedCalled);
    619         // select a context menu item
    620         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
    621         assertTrue(d.isOnMenuItemSelectedCalled);
    622         // Here isOnContextItemSelectedCalled should be true, see bug 1716918.
    623         assertFalse(d.isOnContextItemSelectedCalled);
    624         assertTrue(d.isOnPanelClosedCalled);
    625         // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
    626         assertFalse(d.isOnContextMenuClosedCalled);
    627     }
    628 
    629     public void testOnSearchRequested() {
    630     }
    631 
    632     public void testTakeKeyEvents() throws Throwable {
    633         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    634         final TestDialog d = (TestDialog) mActivity.getDialog();
    635         final View v = d.getWindow().getDecorView();
    636         assertNull(d.getCurrentFocus());
    637         takeKeyEvents(d, true);
    638         assertTrue(v.isFocusable());
    639         sendKeys(KeyEvent.KEYCODE_0);
    640         assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
    641         d.keyEvent = null;
    642 
    643         takeKeyEvents(d, false);
    644         assertNull(d.getCurrentFocus());
    645         assertFalse(v.isFocusable());
    646         sendKeys(KeyEvent.KEYCODE_0);
    647         // d.keyEvent should be null
    648     }
    649 
    650     private void takeKeyEvents(final Dialog d, final boolean get) throws Throwable {
    651         runTestOnUiThread(new Runnable() {
    652             public void run() {
    653                 d.takeKeyEvents(get);
    654             }
    655         });
    656         mInstrumentation.waitForIdleSync();
    657     }
    658 
    659     public void testRequestWindowFeature() {
    660         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    661         // called requestWindowFeature at TestDialog onCreate method
    662         assertTrue(((TestDialog) mActivity.getDialog()).isRequestWindowFeature);
    663     }
    664 
    665     public void testSetFeatureDrawableResource() throws Throwable {
    666         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    667         runTestOnUiThread(new Runnable() {
    668             public void run() {
    669                 mActivity.getDialog().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
    670                         R.drawable.robot);
    671             }
    672         });
    673         mInstrumentation.waitForIdleSync();
    674     }
    675 
    676     public void testSetFeatureDrawableUri() throws Throwable {
    677         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    678         runTestOnUiThread(new Runnable() {
    679             public void run() {
    680                 mActivity.getDialog().setFeatureDrawableUri(Window.FEATURE_LEFT_ICON,
    681                         Uri.parse("http://www.google.com"));
    682             }
    683         });
    684         mInstrumentation.waitForIdleSync();
    685     }
    686 
    687     public void testSetFeatureDrawable() throws Throwable {
    688         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    689         runTestOnUiThread(new Runnable() {
    690             public void run() {
    691                 mActivity.getDialog().setFeatureDrawable(Window.FEATURE_LEFT_ICON,
    692                         new MockDrawable());
    693             }
    694         });
    695         mInstrumentation.waitForIdleSync();
    696     }
    697 
    698     public void testSetFeatureDrawableAlpha() throws Throwable {
    699         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    700         runTestOnUiThread(new Runnable() {
    701             public void run() {
    702                 mActivity.getDialog().setFeatureDrawableAlpha(Window.FEATURE_LEFT_ICON, 0);
    703             }
    704         });
    705         mInstrumentation.waitForIdleSync();
    706     }
    707 
    708     public void testGetLayoutInflater() {
    709         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    710         final Dialog d = mActivity.getDialog();
    711         assertEquals(d.getWindow().getLayoutInflater(), d.getLayoutInflater());
    712     }
    713 
    714     public void testSetCancelable_true() {
    715         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    716         final Dialog d = mActivity.getDialog();
    717 
    718         d.setCancelable(true);
    719         assertTrue(d.isShowing());
    720         sendKeys(KeyEvent.KEYCODE_BACK);
    721         assertFalse(d.isShowing());
    722     }
    723 
    724     public void testSetCancellable_false() {
    725         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    726         final Dialog d = mActivity.getDialog();
    727 
    728         d.setCancelable(false);
    729         assertTrue(d.isShowing());
    730         sendKeys(KeyEvent.KEYCODE_BACK);
    731         assertTrue(d.isShowing());
    732     }
    733 
    734     /*
    735      * Test point
    736      * 1. Cancel the dialog.
    737      * 2. Set a listener to be invoked when the dialog is canceled.
    738      */
    739     public void testCancel_listener() throws Throwable {
    740         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    741         final Dialog d = mActivity.getDialog();
    742 
    743         assertTrue(d.isShowing());
    744         mOnCancelListenerCalled = false;
    745         d.setOnCancelListener(new OnCancelListener() {
    746             public void onCancel(DialogInterface dialog) {
    747                 mOnCancelListenerCalled = true;
    748             }
    749         });
    750         dialogCancel(d);
    751 
    752         assertFalse(d.isShowing());
    753         assertTrue(mOnCancelListenerCalled);
    754     }
    755 
    756     public void testCancel_noListener() throws Throwable {
    757         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    758         final Dialog d = mActivity.getDialog();
    759 
    760         assertTrue(d.isShowing());
    761         mOnCancelListenerCalled = false;
    762         d.setOnCancelListener(null);
    763         dialogCancel(d);
    764 
    765         assertFalse(d.isShowing());
    766         assertFalse(mOnCancelListenerCalled);
    767     }
    768 
    769     public void testSetCancelMessage() throws Exception {
    770         mCalledCallback = false;
    771         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
    772         final TestDialog d = (TestDialog) mActivity.getDialog();
    773         final HandlerThread ht = new HandlerThread("DialogTest");
    774         ht.start();
    775 
    776         d.setCancelMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(CANCEL,
    777                 new OnCancelListener() {
    778                     public void onCancel(DialogInterface dialog) {
    779                         mCalledCallback = true;
    780                     }
    781                 }));
    782         assertTrue(d.isShowing());
    783         assertFalse(mCalledCallback);
    784         sendKeys(KeyEvent.KEYCODE_BACK);
    785         assertTrue(mCalledCallback);
    786         assertFalse(d.isShowing());
    787 
    788         ht.join(100);
    789     }
    790 
    791     /*
    792      * Test point
    793      * 1. Set a listener to be invoked when the dialog is dismissed.
    794      * 2. set onDismissListener to null, it will not changed flag after dialog dismissed.
    795      */
    796     public void testSetOnDismissListener_listener() throws Throwable {
    797         mCalledCallback = false;
    798         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    799         final Dialog d = mActivity.getDialog();
    800 
    801         d.setOnDismissListener(new OnDismissListener() {
    802             public void onDismiss(DialogInterface dialog) {
    803                 mCalledCallback = true;
    804             }
    805         });
    806 
    807         assertTrue(d.isShowing());
    808         assertFalse(mCalledCallback);
    809         dialogDismiss(d);
    810         assertTrue(mCalledCallback);
    811         assertFalse(d.isShowing());
    812     }
    813 
    814     public void testSetOnDismissListener_noListener() throws Throwable {
    815         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    816         final Dialog d = mActivity.getDialog();
    817         assertTrue(d.isShowing());
    818         mCalledCallback = false;
    819         d.setOnDismissListener(null);
    820         dialogDismiss(d);
    821         assertFalse(mCalledCallback);
    822         assertFalse(d.isShowing());
    823     }
    824 
    825     public void testSetDismissMessage() throws Throwable {
    826         mCalledCallback = false;
    827         startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
    828         final Dialog d = mActivity.getDialog();
    829 
    830         final HandlerThread ht = new HandlerThread("DialogTest");
    831         ht.start();
    832 
    833         d.setDismissMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(DISMISS,
    834                 new OnDismissListener() {
    835                     public void onDismiss(DialogInterface dialog) {
    836                         mCalledCallback = true;
    837                     }
    838                 }));
    839         assertTrue(d.isShowing());
    840         assertFalse(mCalledCallback);
    841         dialogDismiss(d);
    842         ht.join(100);
    843         assertTrue(mCalledCallback);
    844         assertFalse(d.isShowing());
    845     }
    846 
    847     private void dialogDismiss(final Dialog d) throws Throwable {
    848         runTestOnUiThread(new Runnable() {
    849             public void run() {
    850                 d.dismiss();
    851             }
    852         });
    853         mInstrumentation.waitForIdleSync();
    854     }
    855 
    856     private void dialogCancel(final Dialog d) throws Throwable {
    857         runTestOnUiThread(new Runnable() {
    858             public void run() {
    859                 d.cancel();
    860             }
    861         });
    862         mInstrumentation.waitForIdleSync();
    863     }
    864 
    865     private static class MockDismissCancelHandler extends Handler {
    866         private WeakReference<DialogInterface> mDialog;
    867 
    868         public MockDismissCancelHandler(Dialog dialog, Looper looper) {
    869             super(looper);
    870 
    871             mDialog = new WeakReference<DialogInterface>(dialog);
    872         }
    873 
    874         @Override
    875         public void handleMessage(Message msg) {
    876             switch (msg.what) {
    877             case DISMISS:
    878                 ((OnDismissListener) msg.obj).onDismiss(mDialog.get());
    879                 break;
    880             case CANCEL:
    881                 ((OnCancelListener) msg.obj).onCancel(mDialog.get());
    882                 break;
    883             }
    884         }
    885     }
    886 
    887     private static class MockDrawable extends Drawable {
    888         @Override
    889         public void draw(Canvas canvas) {
    890         }
    891 
    892         @Override
    893         public int getOpacity() {
    894             return 0;
    895         }
    896 
    897         @Override
    898         public void setAlpha(int alpha) {
    899         }
    900 
    901         @Override
    902         public void setColorFilter(ColorFilter cf) {
    903         }
    904     }
    905 
    906     private static class MockView extends View {
    907         public boolean isShowContextMenuCalled;
    908         protected OnCreateContextMenuListener mOnCreateContextMenuListener;
    909 
    910         public MockView(Context context) {
    911             super(context);
    912         }
    913 
    914         public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
    915             super.setOnCreateContextMenuListener(l);
    916             mOnCreateContextMenuListener = l;
    917         }
    918 
    919         public OnCreateContextMenuListener getOnCreateContextMenuListener() {
    920             return mOnCreateContextMenuListener;
    921         }
    922 
    923         @Override
    924         public boolean showContextMenu() {
    925             isShowContextMenuCalled = true;
    926             return super.showContextMenu();
    927         }
    928     }
    929 }
    930