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