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 17 package android.widget.cts; 18 19 import com.android.cts.widget.R; 20 21 22 import android.app.Activity; 23 import android.app.Instrumentation; 24 import android.content.Context; 25 import android.graphics.Color; 26 import android.graphics.drawable.ColorDrawable; 27 import android.graphics.drawable.Drawable; 28 import android.os.Debug; 29 import android.os.SystemClock; 30 import android.test.ActivityInstrumentationTestCase2; 31 import android.test.UiThreadTest; 32 import android.view.Display; 33 import android.view.Gravity; 34 import android.view.MotionEvent; 35 import android.view.View; 36 import android.view.ViewGroup; 37 import android.view.WindowManager; 38 import android.view.View.OnTouchListener; 39 import android.view.ViewGroup.LayoutParams; 40 import android.widget.ImageView; 41 import android.widget.PopupWindow; 42 import android.widget.TextView; 43 import android.widget.PopupWindow.OnDismissListener; 44 45 public class PopupWindowTest extends 46 ActivityInstrumentationTestCase2<MockPopupWindowCtsActivity> { 47 private Instrumentation mInstrumentation; 48 private Activity mActivity; 49 /** The popup window. */ 50 private PopupWindow mPopupWindow; 51 52 /** 53 * Instantiates a new popup window test. 54 */ 55 public PopupWindowTest() { 56 super("com.android.cts.widget", MockPopupWindowCtsActivity.class); 57 } 58 59 /* 60 * (non-Javadoc) 61 * 62 * @see android.test.ActivityInstrumentationTestCase#setUp() 63 */ 64 @Override 65 protected void setUp() throws Exception { 66 super.setUp(); 67 mInstrumentation = getInstrumentation(); 68 mActivity = getActivity(); 69 } 70 71 public void testConstructor() { 72 new PopupWindow(mActivity); 73 74 new PopupWindow(mActivity, null); 75 76 new PopupWindow(mActivity, null, com.android.internal.R.attr.popupWindowStyle); 77 78 mPopupWindow = new PopupWindow(); 79 assertEquals(0, mPopupWindow.getWidth()); 80 assertEquals(0, mPopupWindow.getHeight()); 81 82 mPopupWindow = new PopupWindow(50, 50); 83 assertEquals(50, mPopupWindow.getWidth()); 84 assertEquals(50, mPopupWindow.getHeight()); 85 86 mPopupWindow = new PopupWindow(-1, -1); 87 assertEquals(-1, mPopupWindow.getWidth()); 88 assertEquals(-1, mPopupWindow.getHeight()); 89 90 TextView contentView = new TextView(mActivity); 91 mPopupWindow = new PopupWindow(contentView); 92 assertSame(contentView, mPopupWindow.getContentView()); 93 94 mPopupWindow = new PopupWindow(contentView, 0, 0); 95 assertEquals(0, mPopupWindow.getWidth()); 96 assertEquals(0, mPopupWindow.getHeight()); 97 assertSame(contentView, mPopupWindow.getContentView()); 98 99 mPopupWindow = new PopupWindow(contentView, 50, 50); 100 assertEquals(50, mPopupWindow.getWidth()); 101 assertEquals(50, mPopupWindow.getHeight()); 102 assertSame(contentView, mPopupWindow.getContentView()); 103 104 mPopupWindow = new PopupWindow(contentView, -1, -1); 105 assertEquals(-1, mPopupWindow.getWidth()); 106 assertEquals(-1, mPopupWindow.getHeight()); 107 assertSame(contentView, mPopupWindow.getContentView()); 108 109 mPopupWindow = new PopupWindow(contentView, 0, 0, true); 110 assertEquals(0, mPopupWindow.getWidth()); 111 assertEquals(0, mPopupWindow.getHeight()); 112 assertSame(contentView, mPopupWindow.getContentView()); 113 assertTrue(mPopupWindow.isFocusable()); 114 115 mPopupWindow = new PopupWindow(contentView, 50, 50, false); 116 assertEquals(50, mPopupWindow.getWidth()); 117 assertEquals(50, mPopupWindow.getHeight()); 118 assertSame(contentView, mPopupWindow.getContentView()); 119 assertFalse(mPopupWindow.isFocusable()); 120 121 mPopupWindow = new PopupWindow(contentView, -1, -1, true); 122 assertEquals(-1, mPopupWindow.getWidth()); 123 assertEquals(-1, mPopupWindow.getHeight()); 124 assertSame(contentView, mPopupWindow.getContentView()); 125 assertTrue(mPopupWindow.isFocusable()); 126 } 127 128 public void testAccessBackground() { 129 mPopupWindow = new PopupWindow(mActivity); 130 131 Drawable drawable = new ColorDrawable(); 132 mPopupWindow.setBackgroundDrawable(drawable); 133 assertSame(drawable, mPopupWindow.getBackground()); 134 135 mPopupWindow.setBackgroundDrawable(null); 136 assertNull(mPopupWindow.getBackground()); 137 } 138 139 public void testAccessAnimationStyle() { 140 mPopupWindow = new PopupWindow(mActivity); 141 // default is -1 142 assertEquals(-1, mPopupWindow.getAnimationStyle()); 143 144 mPopupWindow.setAnimationStyle(com.android.internal.R.style.Animation_Toast); 145 assertEquals(com.android.internal.R.style.Animation_Toast, 146 mPopupWindow.getAnimationStyle()); 147 148 mPopupWindow.setAnimationStyle(com.android.internal.R.style.Animation_DropDownDown); 149 assertEquals(com.android.internal.R.style.Animation_DropDownDown, 150 mPopupWindow.getAnimationStyle()); 151 152 // abnormal values 153 mPopupWindow.setAnimationStyle(-100); 154 assertEquals(-100, mPopupWindow.getAnimationStyle()); 155 } 156 157 public void testAccessContentView() { 158 mPopupWindow = new PopupWindow(mActivity); 159 assertNull(mPopupWindow.getContentView()); 160 161 View view = new TextView(mActivity); 162 mPopupWindow.setContentView(view); 163 assertSame(view, mPopupWindow.getContentView()); 164 165 mPopupWindow.setContentView(null); 166 assertNull(mPopupWindow.getContentView()); 167 168 // can not set the content if the old content is shown 169 mPopupWindow.setContentView(view); 170 assertFalse(mPopupWindow.isShowing()); 171 showPopup(); 172 ImageView img = new ImageView(mActivity); 173 assertTrue(mPopupWindow.isShowing()); 174 mPopupWindow.setContentView(img); 175 assertSame(view, mPopupWindow.getContentView()); 176 dismissPopup(); 177 } 178 179 public void testAccessFocusable() { 180 mPopupWindow = new PopupWindow(mActivity); 181 assertFalse(mPopupWindow.isFocusable()); 182 183 mPopupWindow.setFocusable(true); 184 assertTrue(mPopupWindow.isFocusable()); 185 186 mPopupWindow.setFocusable(false); 187 assertFalse(mPopupWindow.isFocusable()); 188 } 189 190 public void testAccessHeight() { 191 mPopupWindow = new PopupWindow(mActivity); 192 // default is 0 193 assertEquals(0, mPopupWindow.getHeight()); 194 195 int height = getDisplay().getHeight() / 2; 196 mPopupWindow.setHeight(height); 197 assertEquals(height, mPopupWindow.getHeight()); 198 199 height = getDisplay().getHeight(); 200 mPopupWindow.setHeight(height); 201 assertEquals(height, mPopupWindow.getHeight()); 202 203 mPopupWindow.setHeight(0); 204 assertEquals(0, mPopupWindow.getHeight()); 205 206 height = getDisplay().getHeight() * 2; 207 mPopupWindow.setHeight(height); 208 assertEquals(height, mPopupWindow.getHeight()); 209 210 height = -getDisplay().getHeight() / 2; 211 mPopupWindow.setHeight(height); 212 assertEquals(height, mPopupWindow.getHeight()); 213 } 214 215 /** 216 * Gets the display. 217 * 218 * @return the display 219 */ 220 private Display getDisplay() { 221 WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); 222 return wm.getDefaultDisplay(); 223 } 224 225 public void testAccessWidth() { 226 mPopupWindow = new PopupWindow(mActivity); 227 assertEquals(0, mPopupWindow.getWidth()); 228 229 int width = getDisplay().getWidth() / 2; 230 mPopupWindow.setWidth(width); 231 assertEquals(width, mPopupWindow.getWidth()); 232 233 width = getDisplay().getWidth(); 234 mPopupWindow.setWidth(width); 235 assertEquals(width, mPopupWindow.getWidth()); 236 237 mPopupWindow.setWidth(0); 238 assertEquals(0, mPopupWindow.getWidth()); 239 240 width = getDisplay().getWidth() * 2; 241 mPopupWindow.setWidth(width); 242 assertEquals(width, mPopupWindow.getWidth()); 243 244 width = - getDisplay().getWidth() / 2; 245 mPopupWindow.setWidth(width); 246 assertEquals(width, mPopupWindow.getWidth()); 247 } 248 249 public void testShowAsDropDown() { 250 int[] anchorXY = new int[2]; 251 int[] viewOnScreenXY = new int[2]; 252 int[] viewInWindowXY = new int[2]; 253 254 mPopupWindow = createPopupWindow(createPopupContent()); 255 final View upperAnchor = mActivity.findViewById(R.id.anchor_upper); 256 257 mInstrumentation.runOnMainSync(new Runnable() { 258 public void run() { 259 mPopupWindow.showAsDropDown(upperAnchor); 260 } 261 }); 262 mInstrumentation.waitForIdleSync(); 263 264 assertTrue(mPopupWindow.isShowing()); 265 266 mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY); 267 upperAnchor.getLocationOnScreen(anchorXY); 268 mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY); 269 assertEquals(anchorXY[0] + viewInWindowXY[0], viewOnScreenXY[0]); 270 assertEquals(anchorXY[1] + viewInWindowXY[1] + upperAnchor.getHeight(), viewOnScreenXY[1]); 271 272 dismissPopup(); 273 } 274 275 public void testShowAtLocation() { 276 int[] viewInWindowXY = new int[2]; 277 int[] viewOnScreenXY = new int[2]; 278 279 mPopupWindow = createPopupWindow(createPopupContent()); 280 final View upperAnchor = mActivity.findViewById(R.id.anchor_upper); 281 282 final int xOff = 10; 283 final int yOff = 21; 284 assertFalse(mPopupWindow.isShowing()); 285 mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY); 286 assertEquals(0, viewInWindowXY[0]); 287 assertEquals(0, viewInWindowXY[1]); 288 289 mInstrumentation.runOnMainSync(new Runnable() { 290 public void run() { 291 mPopupWindow.showAtLocation(upperAnchor, Gravity.NO_GRAVITY, xOff, yOff); 292 } 293 }); 294 mInstrumentation.waitForIdleSync(); 295 296 assertTrue(mPopupWindow.isShowing()); 297 mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY); 298 mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY); 299 assertTrue(viewInWindowXY[0] >= 0); 300 assertTrue(viewInWindowXY[1] >= 0); 301 assertEquals(viewInWindowXY[0] + xOff, viewOnScreenXY[0]); 302 assertEquals(viewInWindowXY[1] + yOff, viewOnScreenXY[1]); 303 304 dismissPopup(); 305 } 306 307 public void testShowAsDropDownWithOffsets() { 308 int[] anchorXY = new int[2]; 309 int[] viewOnScreenXY = new int[2]; 310 int[] viewInWindowXY = new int[2]; 311 312 mPopupWindow = createPopupWindow(createPopupContent()); 313 final View upperAnchor = mActivity.findViewById(R.id.anchor_upper); 314 upperAnchor.getLocationOnScreen(anchorXY); 315 int height = upperAnchor.getHeight(); 316 317 final int xOff = 11; 318 final int yOff = 12; 319 320 mInstrumentation.runOnMainSync(new Runnable() { 321 public void run() { 322 mPopupWindow.showAsDropDown(upperAnchor, xOff, yOff); 323 } 324 }); 325 mInstrumentation.waitForIdleSync(); 326 327 mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY); 328 mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY); 329 assertEquals(anchorXY[0] + xOff + viewInWindowXY[0], viewOnScreenXY[0]); 330 assertEquals(anchorXY[1] + height + yOff + viewInWindowXY[1], viewOnScreenXY[1]); 331 332 dismissPopup(); 333 } 334 335 public void testGetMaxAvailableHeight() { 336 mPopupWindow = createPopupWindow(createPopupContent()); 337 338 View anchorView = mActivity.findViewById(R.id.anchor_upper); 339 int avaliable = getDisplay().getHeight() - anchorView.getHeight(); 340 int maxAvailableHeight = mPopupWindow.getMaxAvailableHeight(anchorView); 341 assertTrue(maxAvailableHeight > 0); 342 assertTrue(maxAvailableHeight <= avaliable); 343 int maxAvailableHeightWithOffset = mPopupWindow.getMaxAvailableHeight(anchorView, 2); 344 assertEquals(maxAvailableHeight - 2, maxAvailableHeightWithOffset); 345 maxAvailableHeightWithOffset = 346 mPopupWindow.getMaxAvailableHeight(anchorView, maxAvailableHeight); 347 assertTrue(maxAvailableHeightWithOffset > 0); 348 assertTrue(maxAvailableHeightWithOffset <= avaliable); 349 maxAvailableHeightWithOffset = 350 mPopupWindow.getMaxAvailableHeight(anchorView, maxAvailableHeight / 2 - 1); 351 assertTrue(maxAvailableHeightWithOffset > 0); 352 assertTrue(maxAvailableHeightWithOffset <= avaliable); 353 maxAvailableHeightWithOffset = mPopupWindow.getMaxAvailableHeight(anchorView, -1); 354 assertTrue(maxAvailableHeightWithOffset > 0); 355 assertTrue(maxAvailableHeightWithOffset <= avaliable); 356 357 anchorView = mActivity.findViewById(R.id.anchor_lower); 358 avaliable = getDisplay().getHeight() - anchorView.getHeight(); 359 maxAvailableHeight = mPopupWindow.getMaxAvailableHeight(anchorView); 360 assertTrue(maxAvailableHeight > 0); 361 assertTrue(maxAvailableHeight <= avaliable); 362 363 anchorView = mActivity.findViewById(R.id.anchor_middle_left); 364 avaliable = getDisplay().getHeight() - anchorView.getHeight() 365 - mActivity.findViewById(R.id.anchor_upper).getHeight(); 366 maxAvailableHeight = mPopupWindow.getMaxAvailableHeight(anchorView); 367 assertTrue(maxAvailableHeight > 0); 368 assertTrue(maxAvailableHeight <= avaliable); 369 } 370 371 @UiThreadTest 372 public void testDismiss() { 373 mPopupWindow = createPopupWindow(createPopupContent()); 374 assertFalse(mPopupWindow.isShowing()); 375 View anchorView = mActivity.findViewById(R.id.anchor_upper); 376 mPopupWindow.showAsDropDown(anchorView); 377 378 mPopupWindow.dismiss(); 379 assertFalse(mPopupWindow.isShowing()); 380 381 mPopupWindow.dismiss(); 382 assertFalse(mPopupWindow.isShowing()); 383 } 384 385 public void testSetOnDismissListener() { 386 mPopupWindow = new PopupWindow(new TextView(mActivity)); 387 mPopupWindow.setOnDismissListener(null); 388 389 MockOnDismissListener onDismissListener = new MockOnDismissListener(); 390 mPopupWindow.setOnDismissListener(onDismissListener); 391 showPopup(); 392 dismissPopup(); 393 assertEquals(1, onDismissListener.getOnDismissCalledCount()); 394 395 showPopup(); 396 dismissPopup(); 397 assertEquals(2, onDismissListener.getOnDismissCalledCount()); 398 399 mPopupWindow.setOnDismissListener(null); 400 showPopup(); 401 dismissPopup(); 402 assertEquals(2, onDismissListener.getOnDismissCalledCount()); 403 } 404 405 public void testUpdate() { 406 mPopupWindow = createPopupWindow(createPopupContent()); 407 mPopupWindow.setBackgroundDrawable(null); 408 showPopup(); 409 410 mPopupWindow.setIgnoreCheekPress(); 411 mPopupWindow.setFocusable(true); 412 mPopupWindow.setTouchable(false); 413 mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 414 mPopupWindow.setClippingEnabled(false); 415 mPopupWindow.setOutsideTouchable(true); 416 417 WindowManager.LayoutParams p = (WindowManager.LayoutParams) 418 mPopupWindow.getContentView().getLayoutParams(); 419 420 assertEquals(0, WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES & p.flags); 421 assertEquals(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 422 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE & p.flags); 423 assertEquals(0, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE & p.flags); 424 assertEquals(0, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH & p.flags); 425 assertEquals(0, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS & p.flags); 426 assertEquals(0, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM & p.flags); 427 428 mInstrumentation.runOnMainSync(new Runnable() { 429 public void run() { 430 mPopupWindow.update(); 431 } 432 }); 433 mInstrumentation.waitForIdleSync(); 434 435 assertEquals(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, 436 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES & p.flags); 437 assertEquals(0, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE & p.flags); 438 assertEquals(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, 439 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE & p.flags); 440 assertEquals(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 441 WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH & p.flags); 442 assertEquals(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 443 WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS & p.flags); 444 assertEquals(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, 445 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM & p.flags); 446 } 447 448 public void testUpdatePositionAndDimension() { 449 int[] fstXY = new int[2]; 450 int[] sndXY = new int[2]; 451 int[] viewInWindowXY = new int[2]; 452 453 mInstrumentation.runOnMainSync(new Runnable() { 454 public void run() { 455 mPopupWindow = createPopupWindow(createPopupContent()); 456 } 457 }); 458 459 mInstrumentation.waitForIdleSync(); 460 // Do not update if it is not shown 461 assertFalse(mPopupWindow.isShowing()); 462 assertEquals(100, mPopupWindow.getWidth()); 463 assertEquals(100, mPopupWindow.getHeight()); 464 465 showPopup(); 466 mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY); 467 468 // update if it is not shown 469 mInstrumentation.runOnMainSync(new Runnable() { 470 public void run() { 471 mPopupWindow.update(20, 50, 50, 50); 472 } 473 }); 474 475 mInstrumentation.waitForIdleSync(); 476 assertTrue(mPopupWindow.isShowing()); 477 assertEquals(50, mPopupWindow.getWidth()); 478 assertEquals(50, mPopupWindow.getHeight()); 479 480 mPopupWindow.getContentView().getLocationOnScreen(fstXY); 481 assertEquals(viewInWindowXY[0] + 20, fstXY[0]); 482 assertEquals(viewInWindowXY[1] + 50, fstXY[1]); 483 484 // ignore if width or height is -1 485 mInstrumentation.runOnMainSync(new Runnable() { 486 public void run() { 487 mPopupWindow.update(4, 0, -1, -1, true); 488 } 489 }); 490 mInstrumentation.waitForIdleSync(); 491 492 assertTrue(mPopupWindow.isShowing()); 493 assertEquals(50, mPopupWindow.getWidth()); 494 assertEquals(50, mPopupWindow.getHeight()); 495 496 mPopupWindow.getContentView().getLocationOnScreen(sndXY); 497 assertEquals(viewInWindowXY[0] + 4, sndXY[0]); 498 assertEquals(viewInWindowXY[1], sndXY[1]); 499 500 dismissPopup(); 501 } 502 503 public void testUpdateDimensionAndAlignAnchorView() { 504 mInstrumentation.runOnMainSync(new Runnable() { 505 public void run() { 506 mPopupWindow = createPopupWindow(createPopupContent()); 507 } 508 }); 509 mInstrumentation.waitForIdleSync(); 510 511 final View anchorView = mActivity.findViewById(R.id.anchor_upper); 512 mPopupWindow.update(anchorView, 50, 50); 513 // Do not update if it is not shown 514 assertFalse(mPopupWindow.isShowing()); 515 assertEquals(100, mPopupWindow.getWidth()); 516 assertEquals(100, mPopupWindow.getHeight()); 517 518 mInstrumentation.runOnMainSync(new Runnable() { 519 public void run() { 520 mPopupWindow.showAsDropDown(anchorView); 521 } 522 }); 523 mInstrumentation.waitForIdleSync(); 524 // update if it is shown 525 mInstrumentation.runOnMainSync(new Runnable() { 526 public void run() { 527 mPopupWindow.update(anchorView, 50, 50); 528 } 529 }); 530 mInstrumentation.waitForIdleSync(); 531 assertTrue(mPopupWindow.isShowing()); 532 assertEquals(50, mPopupWindow.getWidth()); 533 assertEquals(50, mPopupWindow.getHeight()); 534 535 // ignore if width or height is -1 536 mInstrumentation.runOnMainSync(new Runnable() { 537 public void run() { 538 mPopupWindow.update(anchorView, -1, -1); 539 } 540 }); 541 mInstrumentation.waitForIdleSync(); 542 assertTrue(mPopupWindow.isShowing()); 543 assertEquals(50, mPopupWindow.getWidth()); 544 assertEquals(50, mPopupWindow.getHeight()); 545 546 mInstrumentation.runOnMainSync(new Runnable() { 547 public void run() { 548 mPopupWindow.dismiss(); 549 } 550 }); 551 mInstrumentation.waitForIdleSync(); 552 } 553 554 public void testUpdateDimensionAndAlignAnchorViewWithOffsets() { 555 int[] anchorXY = new int[2]; 556 int[] viewInWindowOff = new int[2]; 557 int[] viewXY = new int[2]; 558 559 mPopupWindow = createPopupWindow(createPopupContent()); 560 final View anchorView = mActivity.findViewById(R.id.anchor_upper); 561 // Do not update if it is not shown 562 assertFalse(mPopupWindow.isShowing()); 563 assertEquals(100, mPopupWindow.getWidth()); 564 assertEquals(100, mPopupWindow.getHeight()); 565 566 showPopup(); 567 anchorView.getLocationOnScreen(anchorXY); 568 mPopupWindow.getContentView().getLocationInWindow(viewInWindowOff); 569 570 // update if it is not shown 571 mInstrumentation.runOnMainSync(new Runnable() { 572 public void run() { 573 mPopupWindow.update(anchorView, 20, 50, 50, 50); 574 } 575 }); 576 577 mInstrumentation.waitForIdleSync(); 578 579 assertTrue(mPopupWindow.isShowing()); 580 assertEquals(50, mPopupWindow.getWidth()); 581 assertEquals(50, mPopupWindow.getHeight()); 582 583 mPopupWindow.getContentView().getLocationOnScreen(viewXY); 584 585 // The popup should appear below and to right with an offset. 586 assertEquals(anchorXY[0] + 20 + viewInWindowOff[0], viewXY[0]); 587 assertEquals(anchorXY[1] + anchorView.getHeight() + 50 + viewInWindowOff[1], viewXY[1]); 588 589 // ignore width and height but change location 590 mInstrumentation.runOnMainSync(new Runnable() { 591 public void run() { 592 mPopupWindow.update(anchorView, 10, 50, -1, -1); 593 } 594 }); 595 mInstrumentation.waitForIdleSync(); 596 597 assertTrue(mPopupWindow.isShowing()); 598 assertEquals(50, mPopupWindow.getWidth()); 599 assertEquals(50, mPopupWindow.getHeight()); 600 601 mPopupWindow.getContentView().getLocationOnScreen(viewXY); 602 603 // The popup should appear below and to right with an offset. 604 assertEquals(anchorXY[0] + 10 + viewInWindowOff[0], viewXY[0]); 605 assertEquals(anchorXY[1] + anchorView.getHeight() + 50 + viewInWindowOff[1], viewXY[1]); 606 607 final View anotherView = mActivity.findViewById(R.id.anchor_middle_left); 608 mInstrumentation.runOnMainSync(new Runnable() { 609 public void run() { 610 mPopupWindow.update(anotherView, 0, 0, 60, 60); 611 } 612 }); 613 mInstrumentation.waitForIdleSync(); 614 615 assertTrue(mPopupWindow.isShowing()); 616 assertEquals(60, mPopupWindow.getWidth()); 617 assertEquals(60, mPopupWindow.getHeight()); 618 619 int[] newXY = new int[2]; 620 anotherView.getLocationOnScreen(newXY); 621 mPopupWindow.getContentView().getLocationOnScreen(viewXY); 622 623 // The popup should appear below and to the right. 624 assertEquals(newXY[0] + viewInWindowOff[0], viewXY[0]); 625 assertEquals(newXY[1] + anotherView.getHeight() + viewInWindowOff[1], viewXY[1]); 626 627 dismissPopup(); 628 } 629 630 public void testAccessInputMethodMode() { 631 mPopupWindow = new PopupWindow(mActivity); 632 assertEquals(0, mPopupWindow.getInputMethodMode()); 633 634 mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE); 635 assertEquals(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE, mPopupWindow.getInputMethodMode()); 636 637 mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 638 assertEquals(PopupWindow.INPUT_METHOD_NEEDED, mPopupWindow.getInputMethodMode()); 639 640 mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 641 assertEquals(PopupWindow.INPUT_METHOD_NOT_NEEDED, mPopupWindow.getInputMethodMode()); 642 643 mPopupWindow.setInputMethodMode(-1); 644 assertEquals(-1, mPopupWindow.getInputMethodMode()); 645 } 646 647 public void testAccessClippingEnabled() { 648 mPopupWindow = new PopupWindow(mActivity); 649 assertTrue(mPopupWindow.isClippingEnabled()); 650 651 mPopupWindow.setClippingEnabled(false); 652 assertFalse(mPopupWindow.isClippingEnabled()); 653 } 654 655 public void testAccessOutsideTouchable() { 656 mPopupWindow = new PopupWindow(mActivity); 657 assertFalse(mPopupWindow.isOutsideTouchable()); 658 659 mPopupWindow.setOutsideTouchable(true); 660 assertTrue(mPopupWindow.isOutsideTouchable()); 661 } 662 663 public void testAccessTouchable() { 664 mPopupWindow = new PopupWindow(mActivity); 665 assertTrue(mPopupWindow.isTouchable()); 666 667 mPopupWindow.setTouchable(false); 668 assertFalse(mPopupWindow.isTouchable()); 669 } 670 671 public void testIsAboveAnchor() { 672 mInstrumentation.runOnMainSync(new Runnable() { 673 public void run() { 674 mPopupWindow = createPopupWindow(createPopupContent()); 675 } 676 }); 677 mInstrumentation.waitForIdleSync(); 678 final View upperAnchor = mActivity.findViewById(R.id.anchor_upper); 679 680 mInstrumentation.runOnMainSync(new Runnable() { 681 public void run() { 682 mPopupWindow.showAsDropDown(upperAnchor); 683 } 684 }); 685 mInstrumentation.waitForIdleSync(); 686 assertFalse(mPopupWindow.isAboveAnchor()); 687 dismissPopup(); 688 689 mPopupWindow = createPopupWindow(createPopupContent()); 690 final View lowerAnchor = mActivity.findViewById(R.id.anchor_lower); 691 692 mInstrumentation.runOnMainSync(new Runnable() { 693 public void run() { 694 mPopupWindow.showAsDropDown(lowerAnchor, 0, 0); 695 } 696 }); 697 mInstrumentation.waitForIdleSync(); 698 assertTrue(mPopupWindow.isAboveAnchor()); 699 dismissPopup(); 700 } 701 702 public void testSetTouchInterceptor() { 703 mPopupWindow = new PopupWindow(new TextView(mActivity)); 704 705 MockOnTouchListener onTouchListener = new MockOnTouchListener(); 706 mPopupWindow.setTouchInterceptor(onTouchListener); 707 mPopupWindow.setFocusable(true); 708 mPopupWindow.setOutsideTouchable(true); 709 Drawable drawable = new ColorDrawable(); 710 mPopupWindow.setBackgroundDrawable(drawable); 711 showPopup(); 712 713 int[] xy = new int[2]; 714 mPopupWindow.getContentView().getLocationOnScreen(xy); 715 final int viewWidth = mPopupWindow.getContentView().getWidth(); 716 final int viewHeight = mPopupWindow.getContentView().getHeight(); 717 final float x = xy[0] + (viewWidth / 2.0f); 718 float y = xy[1] + (viewHeight / 2.0f); 719 720 long downTime = SystemClock.uptimeMillis(); 721 long eventTime = SystemClock.uptimeMillis(); 722 MotionEvent event = MotionEvent.obtain(downTime, eventTime, 723 MotionEvent.ACTION_DOWN, x, y, 0); 724 getInstrumentation().sendPointerSync(event); 725 assertEquals(1, onTouchListener.getOnTouchCalledCount()); 726 727 downTime = SystemClock.uptimeMillis(); 728 eventTime = SystemClock.uptimeMillis(); 729 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0); 730 getInstrumentation().sendPointerSync(event); 731 assertEquals(2, onTouchListener.getOnTouchCalledCount()); 732 733 mPopupWindow.setTouchInterceptor(null); 734 downTime = SystemClock.uptimeMillis(); 735 eventTime = SystemClock.uptimeMillis(); 736 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0); 737 getInstrumentation().sendPointerSync(event); 738 assertEquals(2, onTouchListener.getOnTouchCalledCount()); 739 } 740 741 public void testSetWindowLayoutMode() { 742 mPopupWindow = new PopupWindow(new TextView(mActivity)); 743 showPopup(); 744 745 ViewGroup.LayoutParams p = mPopupWindow.getContentView().getLayoutParams(); 746 assertEquals(0, p.width); 747 assertEquals(0, p.height); 748 749 mPopupWindow.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); 750 mInstrumentation.runOnMainSync(new Runnable() { 751 public void run() { 752 mPopupWindow.update(20, 50, 50, 50); 753 } 754 }); 755 756 assertEquals(LayoutParams.WRAP_CONTENT, p.width); 757 assertEquals(LayoutParams.MATCH_PARENT, p.height); 758 } 759 760 /** 761 * The listener interface for receiving OnDismiss events. The class that is 762 * interested in processing a OnDismiss event implements this interface, and 763 * the object created with that class is registered with a component using 764 * the component's <code>setOnDismissListener<code> method. When 765 * the OnDismiss event occurs, that object's appropriate 766 * method is invoked. 767 */ 768 private static class MockOnDismissListener implements OnDismissListener { 769 770 /** The Ondismiss called count. */ 771 private int mOnDismissCalledCount; 772 773 /** 774 * Gets the onDismiss() called count. 775 * 776 * @return the on dismiss called count 777 */ 778 public int getOnDismissCalledCount() { 779 return mOnDismissCalledCount; 780 } 781 782 /* 783 * (non-Javadoc) 784 * 785 * @see android.widget.PopupWindow.OnDismissListener#onDismiss() 786 */ 787 public void onDismiss() { 788 mOnDismissCalledCount++; 789 } 790 791 } 792 793 /** 794 * The listener interface for receiving touch events. 795 */ 796 private static class MockOnTouchListener implements OnTouchListener { 797 798 /** The onTouch called count. */ 799 private int mOnTouchCalledCount; 800 801 /** 802 * Gets the onTouch() called count. 803 * 804 * @return the onTouch() called count 805 */ 806 public int getOnTouchCalledCount() { 807 return mOnTouchCalledCount; 808 } 809 810 /* 811 * (non-Javadoc) 812 * 813 * @see android.widget.PopupWindow.OnTouchListener#onDismiss() 814 */ 815 public boolean onTouch(View v, MotionEvent event) { 816 mOnTouchCalledCount++; 817 return true; 818 } 819 } 820 821 private View createPopupContent() { 822 View popupView = new View(mActivity); 823 popupView.setLayoutParams(new ViewGroup.LayoutParams(50, 50)); 824 popupView.setBackgroundColor(Color.WHITE); 825 826 return popupView; 827 } 828 829 private PopupWindow createPopupWindow() { 830 PopupWindow window = new PopupWindow(mActivity); 831 window.setWidth(100); 832 window.setHeight(100); 833 return window; 834 } 835 836 private PopupWindow createPopupWindow(View content) { 837 PopupWindow window = createPopupWindow(); 838 window.setContentView(content); 839 return window; 840 } 841 842 /** 843 * Show PopupWindow. 844 */ 845 // FIXME: logcat info complains that there is window leakage due to that mPopupWindow is not 846 // clean up. Need to fix it. 847 private void showPopup() { 848 mInstrumentation.runOnMainSync(new Runnable() { 849 public void run() { 850 if (mPopupWindow == null || mPopupWindow.isShowing()) { 851 return; 852 } 853 View anchor = mActivity.findViewById(R.id.anchor_upper); 854 mPopupWindow.showAsDropDown(anchor); 855 assertTrue(mPopupWindow.isShowing()); 856 } 857 }); 858 mInstrumentation.waitForIdleSync(); 859 } 860 861 /** 862 * Dismiss PopupWindow. 863 */ 864 private void dismissPopup() { 865 mInstrumentation.runOnMainSync(new Runnable() { 866 public void run() { 867 if (mPopupWindow == null || !mPopupWindow.isShowing()) 868 return; 869 mPopupWindow.dismiss(); 870 } 871 }); 872 mInstrumentation.waitForIdleSync(); 873 } 874 } 875