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