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