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