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