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 android.app.Activity; 20 import android.app.Instrumentation; 21 import android.content.Context; 22 import android.graphics.Color; 23 import android.graphics.Rect; 24 import android.graphics.drawable.ColorDrawable; 25 import android.graphics.drawable.Drawable; 26 import android.os.SystemClock; 27 import android.test.ActivityInstrumentationTestCase2; 28 import android.test.UiThreadTest; 29 import android.transition.Transition; 30 import android.transition.Transition.TransitionListener; 31 import android.transition.TransitionValues; 32 import android.util.AttributeSet; 33 import android.view.Display; 34 import android.view.Gravity; 35 import android.view.MotionEvent; 36 import android.view.View; 37 import android.view.View.OnTouchListener; 38 import android.view.ViewGroup; 39 import android.view.ViewGroup.LayoutParams; 40 import android.view.WindowManager; 41 import android.widget.ImageView; 42 import android.widget.PopupWindow; 43 import android.widget.PopupWindow.OnDismissListener; 44 import android.widget.TextView; 45 import android.widget.cts.R; 46 47 import static org.mockito.Mockito.any; 48 import static org.mockito.Mockito.mock; 49 import static org.mockito.Mockito.never; 50 import static org.mockito.Mockito.times; 51 import static org.mockito.Mockito.verify; 52 import static org.mockito.Mockito.when; 53 54 public class PopupWindowTest extends 55 ActivityInstrumentationTestCase2<PopupWindowCtsActivity> { 56 private Instrumentation mInstrumentation; 57 private Activity mActivity; 58 /** The popup window. */ 59 private PopupWindow mPopupWindow; 60 61 /** 62 * Instantiates a new popup window test. 63 */ 64 public PopupWindowTest() { 65 super("android.widget.cts", PopupWindowCtsActivity.class); 66 } 67 68 /* 69 * (non-Javadoc) 70 * 71 * @see android.test.ActivityInstrumentationTestCase#setUp() 72 */ 73 @Override 74 protected void setUp() throws Exception { 75 super.setUp(); 76 mInstrumentation = getInstrumentation(); 77 mActivity = getActivity(); 78 } 79 80 public void testConstructor() { 81 new PopupWindow(mActivity); 82 83 new PopupWindow(mActivity, null); 84 85 new PopupWindow(mActivity, null, android.R.attr.popupWindowStyle); 86 87 mPopupWindow = new PopupWindow(); 88 assertEquals(0, mPopupWindow.getWidth()); 89 assertEquals(0, mPopupWindow.getHeight()); 90 91 mPopupWindow = new PopupWindow(50, 50); 92 assertEquals(50, mPopupWindow.getWidth()); 93 assertEquals(50, mPopupWindow.getHeight()); 94 95 mPopupWindow = new PopupWindow(-1, -1); 96 assertEquals(-1, mPopupWindow.getWidth()); 97 assertEquals(-1, mPopupWindow.getHeight()); 98 99 TextView contentView = new TextView(mActivity); 100 mPopupWindow = new PopupWindow(contentView); 101 assertSame(contentView, mPopupWindow.getContentView()); 102 103 mPopupWindow = new PopupWindow(contentView, 0, 0); 104 assertEquals(0, mPopupWindow.getWidth()); 105 assertEquals(0, mPopupWindow.getHeight()); 106 assertSame(contentView, mPopupWindow.getContentView()); 107 108 mPopupWindow = new PopupWindow(contentView, 50, 50); 109 assertEquals(50, mPopupWindow.getWidth()); 110 assertEquals(50, mPopupWindow.getHeight()); 111 assertSame(contentView, mPopupWindow.getContentView()); 112 113 mPopupWindow = new PopupWindow(contentView, -1, -1); 114 assertEquals(-1, mPopupWindow.getWidth()); 115 assertEquals(-1, mPopupWindow.getHeight()); 116 assertSame(contentView, mPopupWindow.getContentView()); 117 118 mPopupWindow = new PopupWindow(contentView, 0, 0, true); 119 assertEquals(0, mPopupWindow.getWidth()); 120 assertEquals(0, mPopupWindow.getHeight()); 121 assertSame(contentView, mPopupWindow.getContentView()); 122 assertTrue(mPopupWindow.isFocusable()); 123 124 mPopupWindow = new PopupWindow(contentView, 50, 50, false); 125 assertEquals(50, mPopupWindow.getWidth()); 126 assertEquals(50, mPopupWindow.getHeight()); 127 assertSame(contentView, mPopupWindow.getContentView()); 128 assertFalse(mPopupWindow.isFocusable()); 129 130 mPopupWindow = new PopupWindow(contentView, -1, -1, true); 131 assertEquals(-1, mPopupWindow.getWidth()); 132 assertEquals(-1, mPopupWindow.getHeight()); 133 assertSame(contentView, mPopupWindow.getContentView()); 134 assertTrue(mPopupWindow.isFocusable()); 135 } 136 137 public void testAccessEnterExitTransitions() { 138 PopupWindow w; 139 140 w = new PopupWindow(mActivity, null, 0, 0); 141 assertNull(w.getEnterTransition()); 142 assertNull(w.getExitTransition()); 143 144 w = new PopupWindow(mActivity, null, 0, R.style.PopupWindow_NullTransitions); 145 assertNull(w.getEnterTransition()); 146 assertNull(w.getExitTransition()); 147 148 w = new PopupWindow(mActivity, null, 0, R.style.PopupWindow_CustomTransitions); 149 assertTrue(w.getEnterTransition() instanceof CustomTransition); 150 assertTrue(w.getExitTransition() instanceof CustomTransition); 151 152 Transition enterTransition = new CustomTransition(); 153 Transition exitTransition = new CustomTransition(); 154 w = new PopupWindow(mActivity, null, 0, 0); 155 w.setEnterTransition(enterTransition); 156 w.setExitTransition(exitTransition); 157 assertEquals(enterTransition, w.getEnterTransition()); 158 assertEquals(exitTransition, w.getExitTransition()); 159 160 w.setEnterTransition(null); 161 w.setExitTransition(null); 162 assertNull(w.getEnterTransition()); 163 assertNull(w.getExitTransition()); 164 } 165 166 public static class CustomTransition extends Transition { 167 public CustomTransition() { 168 } 169 170 // This constructor is needed for reflection-based creation of a transition when 171 // the transition is defined in layout XML via attribute. 172 @SuppressWarnings("unused") 173 public CustomTransition(Context context, AttributeSet attrs) { 174 super(context, attrs); 175 } 176 177 @Override 178 public void captureStartValues(TransitionValues transitionValues) {} 179 180 @Override 181 public void captureEndValues(TransitionValues transitionValues) {} 182 } 183 184 public void testAccessBackground() { 185 mPopupWindow = new PopupWindow(mActivity); 186 187 Drawable drawable = new ColorDrawable(); 188 mPopupWindow.setBackgroundDrawable(drawable); 189 assertSame(drawable, mPopupWindow.getBackground()); 190 191 mPopupWindow.setBackgroundDrawable(null); 192 assertNull(mPopupWindow.getBackground()); 193 } 194 195 public void testAccessAnimationStyle() { 196 mPopupWindow = new PopupWindow(mActivity); 197 // default is -1 198 assertEquals(-1, mPopupWindow.getAnimationStyle()); 199 200 mPopupWindow.setAnimationStyle(android.R.style.Animation_Toast); 201 assertEquals(android.R.style.Animation_Toast, 202 mPopupWindow.getAnimationStyle()); 203 204 // abnormal values 205 mPopupWindow.setAnimationStyle(-100); 206 assertEquals(-100, mPopupWindow.getAnimationStyle()); 207 } 208 209 public void testAccessContentView() { 210 mPopupWindow = new PopupWindow(mActivity); 211 assertNull(mPopupWindow.getContentView()); 212 213 View view = new TextView(mActivity); 214 mPopupWindow.setContentView(view); 215 assertSame(view, mPopupWindow.getContentView()); 216 217 mPopupWindow.setContentView(null); 218 assertNull(mPopupWindow.getContentView()); 219 220 // can not set the content if the old content is shown 221 mPopupWindow.setContentView(view); 222 assertFalse(mPopupWindow.isShowing()); 223 showPopup(); 224 ImageView img = new ImageView(mActivity); 225 assertTrue(mPopupWindow.isShowing()); 226 mPopupWindow.setContentView(img); 227 assertSame(view, mPopupWindow.getContentView()); 228 dismissPopup(); 229 } 230 231 public void testAccessFocusable() { 232 mPopupWindow = new PopupWindow(mActivity); 233 assertFalse(mPopupWindow.isFocusable()); 234 235 mPopupWindow.setFocusable(true); 236 assertTrue(mPopupWindow.isFocusable()); 237 238 mPopupWindow.setFocusable(false); 239 assertFalse(mPopupWindow.isFocusable()); 240 } 241 242 public void testAccessHeight() { 243 mPopupWindow = new PopupWindow(mActivity); 244 assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, mPopupWindow.getHeight()); 245 246 int height = getDisplay().getHeight() / 2; 247 mPopupWindow.setHeight(height); 248 assertEquals(height, mPopupWindow.getHeight()); 249 250 height = getDisplay().getHeight(); 251 mPopupWindow.setHeight(height); 252 assertEquals(height, mPopupWindow.getHeight()); 253 254 mPopupWindow.setHeight(0); 255 assertEquals(0, mPopupWindow.getHeight()); 256 257 height = getDisplay().getHeight() * 2; 258 mPopupWindow.setHeight(height); 259 assertEquals(height, mPopupWindow.getHeight()); 260 261 height = -getDisplay().getHeight() / 2; 262 mPopupWindow.setHeight(height); 263 assertEquals(height, mPopupWindow.getHeight()); 264 } 265 266 /** 267 * Gets the display. 268 * 269 * @return the display 270 */ 271 private Display getDisplay() { 272 WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); 273 return wm.getDefaultDisplay(); 274 } 275 276 public void testAccessWidth() { 277 mPopupWindow = new PopupWindow(mActivity); 278 assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, mPopupWindow.getWidth()); 279 280 int width = getDisplay().getWidth() / 2; 281 mPopupWindow.setWidth(width); 282 assertEquals(width, mPopupWindow.getWidth()); 283 284 width = getDisplay().getWidth(); 285 mPopupWindow.setWidth(width); 286 assertEquals(width, mPopupWindow.getWidth()); 287 288 mPopupWindow.setWidth(0); 289 assertEquals(0, mPopupWindow.getWidth()); 290 291 width = getDisplay().getWidth() * 2; 292 mPopupWindow.setWidth(width); 293 assertEquals(width, mPopupWindow.getWidth()); 294 295 width = - getDisplay().getWidth() / 2; 296 mPopupWindow.setWidth(width); 297 assertEquals(width, mPopupWindow.getWidth()); 298 } 299 300 private static final int TOP = 0x00; 301 private static final int BOTTOM = 0x01; 302 303 private static final int LEFT = 0x00; 304 private static final int RIGHT = 0x01; 305 306 private static final int GREATER_THAN = 1; 307 private static final int LESS_THAN = -1; 308 private static final int EQUAL_TO = 0; 309 310 public void testShowAsDropDown() { 311 final PopupWindow popup = createPopupWindow(createPopupContent(50, 50)); 312 popup.setClipToScreenEnabled(false); 313 popup.setOverlapAnchor(false); 314 popup.setAnimationStyle(0); 315 popup.setExitTransition(null); 316 popup.setEnterTransition(null); 317 318 assertPosition(popup, R.id.anchor_upper_left, 319 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM); 320 assertPosition(popup, R.id.anchor_upper, 321 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM); 322 assertPosition(popup, R.id.anchor_upper_right, 323 RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM); 324 325 assertPosition(popup, R.id.anchor_middle_left, 326 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM); 327 assertPosition(popup, R.id.anchor_middle, 328 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM); 329 assertPosition(popup, R.id.anchor_middle_right, 330 RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM); 331 332 assertPosition(popup, R.id.anchor_lower_left, 333 LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP); 334 assertPosition(popup, R.id.anchor_lower, 335 LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP); 336 assertPosition(popup, R.id.anchor_lower_right, 337 RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP); 338 } 339 340 public void testShowAsDropDown_ClipToScreen() { 341 final PopupWindow popup = createPopupWindow(createPopupContent(50, 50)); 342 popup.setClipToScreenEnabled(true); 343 popup.setOverlapAnchor(false); 344 popup.setAnimationStyle(0); 345 popup.setExitTransition(null); 346 popup.setEnterTransition(null); 347 348 assertPosition(popup, R.id.anchor_upper_left, 349 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM); 350 assertPosition(popup, R.id.anchor_upper, 351 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM); 352 assertPosition(popup, R.id.anchor_upper_right, 353 RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM); 354 355 assertPosition(popup, R.id.anchor_middle_left, 356 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM); 357 assertPosition(popup, R.id.anchor_middle, 358 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM); 359 assertPosition(popup, R.id.anchor_middle_right, 360 RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM); 361 362 assertPosition(popup, R.id.anchor_lower_left, 363 LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP); 364 assertPosition(popup, R.id.anchor_lower, 365 LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP); 366 assertPosition(popup, R.id.anchor_lower_right, 367 RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP); 368 } 369 370 public void testShowAsDropDown_ClipToScreen_Overlap() { 371 final PopupWindow popup = createPopupWindow(createPopupContent(50, 50)); 372 popup.setClipToScreenEnabled(true); 373 popup.setOverlapAnchor(true); 374 popup.setAnimationStyle(0); 375 popup.setExitTransition(null); 376 popup.setEnterTransition(null); 377 378 assertPosition(popup, R.id.anchor_upper_left, 379 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP); 380 assertPosition(popup, R.id.anchor_upper, 381 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP); 382 assertPosition(popup, R.id.anchor_upper_right, 383 RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, TOP); 384 385 assertPosition(popup, R.id.anchor_middle_left, 386 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP); 387 assertPosition(popup, R.id.anchor_middle, 388 LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP); 389 assertPosition(popup, R.id.anchor_middle_right, 390 RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, TOP); 391 392 assertPosition(popup, R.id.anchor_lower_left, 393 LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP); 394 assertPosition(popup, R.id.anchor_lower, 395 LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP); 396 assertPosition(popup, R.id.anchor_lower_right, 397 RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP); 398 } 399 400 public void testShowAsDropDown_ClipToScreen_Overlap_Offset() { 401 final PopupWindow popup = createPopupWindow(createPopupContent(50, 50)); 402 popup.setClipToScreenEnabled(true); 403 popup.setOverlapAnchor(true); 404 popup.setAnimationStyle(0); 405 popup.setExitTransition(null); 406 popup.setEnterTransition(null); 407 408 final int offsetX = mActivity.findViewById(R.id.anchor_upper).getWidth() / 2; 409 final int offsetY = mActivity.findViewById(R.id.anchor_upper).getHeight() / 2; 410 final int gravity = Gravity.TOP | Gravity.START; 411 412 assertPosition(popup, R.id.anchor_upper_left, 413 LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP, 414 offsetX, offsetY, gravity); 415 assertPosition(popup, R.id.anchor_upper, 416 LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP, 417 offsetX, offsetY, gravity); 418 assertPosition(popup, R.id.anchor_upper_right, 419 RIGHT, EQUAL_TO, RIGHT, TOP, GREATER_THAN, TOP, 420 offsetX, offsetY, gravity); 421 422 assertPosition(popup, R.id.anchor_middle_left, 423 LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP, 424 offsetX, offsetY, gravity); 425 assertPosition(popup, R.id.anchor_middle, 426 LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP, 427 offsetX, offsetY, gravity); 428 assertPosition(popup, R.id.anchor_middle_right, 429 RIGHT, EQUAL_TO, RIGHT, TOP, GREATER_THAN, TOP, 430 offsetX, offsetY, gravity); 431 432 assertPosition(popup, R.id.anchor_lower_left, 433 LEFT, GREATER_THAN, LEFT, BOTTOM, LESS_THAN, BOTTOM, 434 offsetX, offsetY, gravity); 435 assertPosition(popup, R.id.anchor_lower, 436 LEFT, GREATER_THAN, LEFT, BOTTOM, LESS_THAN, BOTTOM, 437 offsetX, offsetY, gravity); 438 assertPosition(popup, R.id.anchor_lower_right, 439 RIGHT, EQUAL_TO, RIGHT, BOTTOM, LESS_THAN, BOTTOM, 440 offsetX, offsetY, gravity); 441 } 442 443 public void testShowAsDropDown_ClipToScreen_TooBig() { 444 final View rootView = mActivity.findViewById(R.id.anchor_upper_left).getRootView(); 445 final int width = rootView.getWidth() * 2; 446 final int height = rootView.getHeight() * 2; 447 448 final PopupWindow popup = createPopupWindow(createPopupContent(width, height)); 449 popup.setWidth(width); 450 popup.setHeight(height); 451 452 popup.setClipToScreenEnabled(true); 453 popup.setOverlapAnchor(false); 454 popup.setAnimationStyle(0); 455 popup.setExitTransition(null); 456 popup.setEnterTransition(null); 457 458 assertPosition(popup, R.id.anchor_upper_left, 459 LEFT, EQUAL_TO, LEFT, TOP, LESS_THAN, TOP); 460 assertPosition(popup, R.id.anchor_upper, 461 LEFT, LESS_THAN, LEFT, TOP, LESS_THAN, TOP); 462 assertPosition(popup, R.id.anchor_upper_right, 463 RIGHT, EQUAL_TO, RIGHT, TOP, LESS_THAN, TOP); 464 465 assertPosition(popup, R.id.anchor_middle_left, 466 LEFT, EQUAL_TO, LEFT, TOP, LESS_THAN, TOP); 467 assertPosition(popup, R.id.anchor_middle, 468 LEFT, LESS_THAN, LEFT, TOP, LESS_THAN, TOP); 469 assertPosition(popup, R.id.anchor_middle_right, 470 RIGHT, EQUAL_TO, RIGHT, TOP, LESS_THAN, TOP); 471 472 assertPosition(popup, R.id.anchor_lower_left, 473 LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, BOTTOM); 474 assertPosition(popup, R.id.anchor_lower, 475 LEFT, LESS_THAN, LEFT, BOTTOM, EQUAL_TO, BOTTOM); 476 assertPosition(popup, R.id.anchor_lower_right, 477 RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, BOTTOM); 478 } 479 480 private void assertPosition(PopupWindow popup, int anchorId, 481 int contentEdgeX, int operatorX, int anchorEdgeX, 482 int contentEdgeY, int operatorY, int anchorEdgeY) { 483 assertPosition(popup, anchorId, 484 contentEdgeX, operatorX, anchorEdgeX, 485 contentEdgeY, operatorY, anchorEdgeY, 486 0, 0, Gravity.TOP | Gravity.START); 487 } 488 489 private void assertPosition(PopupWindow popup, int anchorId, 490 int contentEdgeX, int operatorX, int anchorEdgeX, 491 int contentEdgeY, int operatorY, int anchorEdgeY, 492 int offsetX, int offsetY, int gravity) { 493 final View content = popup.getContentView(); 494 final View anchor = mActivity.findViewById(anchorId); 495 496 getInstrumentation().runOnMainSync(() -> popup.showAsDropDown( 497 anchor, offsetX, offsetY, gravity)); 498 getInstrumentation().waitForIdleSync(); 499 500 assertTrue(popup.isShowing()); 501 assertPositionX(content, contentEdgeX, operatorX, anchor, anchorEdgeX); 502 assertPositionY(content, contentEdgeY, operatorY, anchor, anchorEdgeY); 503 504 // Make sure it fits in the display frame. 505 final Rect displayFrame = new Rect(); 506 anchor.getWindowVisibleDisplayFrame(displayFrame); 507 final Rect contentFrame = new Rect(); 508 content.getBoundsOnScreen(contentFrame); 509 assertTrue("Content (" + contentFrame + ") extends outside display (" + displayFrame + ")", 510 displayFrame.contains(contentFrame)); 511 512 getInstrumentation().runOnMainSync(() -> popup.dismiss()); 513 getInstrumentation().waitForIdleSync(); 514 515 assertFalse(popup.isShowing()); 516 } 517 518 public static void assertPositionY(View content, int contentEdge, int flags, 519 View anchor, int anchorEdge) { 520 final int[] anchorOnScreenXY = new int[2]; 521 anchor.getLocationOnScreen(anchorOnScreenXY); 522 int anchorY = anchorOnScreenXY[1]; 523 if ((anchorEdge & BOTTOM) == BOTTOM) { 524 anchorY += anchor.getHeight(); 525 } 526 527 final int[] contentOnScreenXY = new int[2]; 528 content.getLocationOnScreen(contentOnScreenXY); 529 int contentY = contentOnScreenXY[1]; 530 if ((contentEdge & BOTTOM) == BOTTOM) { 531 contentY += content.getHeight(); 532 } 533 534 assertComparison(contentY, flags, anchorY); 535 } 536 537 private static void assertPositionX(View content, int contentEdge, int flags, 538 View anchor, int anchorEdge) { 539 final int[] anchorOnScreenXY = new int[2]; 540 anchor.getLocationOnScreen(anchorOnScreenXY); 541 int anchorX = anchorOnScreenXY[0]; 542 if ((anchorEdge & RIGHT) == RIGHT) { 543 anchorX += anchor.getWidth(); 544 } 545 546 final int[] contentOnScreenXY = new int[2]; 547 content.getLocationOnScreen(contentOnScreenXY); 548 int contentX = contentOnScreenXY[0]; 549 if ((contentEdge & RIGHT) == RIGHT) { 550 contentX += content.getWidth(); 551 } 552 553 assertComparison(contentX, flags, anchorX); 554 } 555 556 private static void assertComparison(int left, int operator, int right) { 557 switch (operator) { 558 case GREATER_THAN: 559 assertTrue(left + " <= " + right, left > right); 560 break; 561 case LESS_THAN: 562 assertTrue(left + " >= " + right, left < right); 563 break; 564 case EQUAL_TO: 565 assertTrue(left + " != " + right, left == right); 566 break; 567 } 568 } 569 570 public void testShowAtLocation() { 571 int[] popupContentViewInWindowXY = new int[2]; 572 int[] popupContentViewOnScreenXY = new int[2]; 573 574 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 575 // Do not attach within the decor; we will be measuring location 576 // with regard to screen coordinates. 577 mPopupWindow.setAttachedInDecor(false); 578 final View upperAnchor = mActivity.findViewById(R.id.anchor_upper); 579 580 final int xOff = 10; 581 final int yOff = 21; 582 assertFalse(mPopupWindow.isShowing()); 583 mPopupWindow.getContentView().getLocationInWindow(popupContentViewInWindowXY); 584 assertEquals(0, popupContentViewInWindowXY[0]); 585 assertEquals(0, popupContentViewInWindowXY[1]); 586 587 mInstrumentation.runOnMainSync( 588 () -> mPopupWindow.showAtLocation(upperAnchor, Gravity.NO_GRAVITY, xOff, yOff)); 589 mInstrumentation.waitForIdleSync(); 590 591 assertTrue(mPopupWindow.isShowing()); 592 mPopupWindow.getContentView().getLocationInWindow(popupContentViewInWindowXY); 593 mPopupWindow.getContentView().getLocationOnScreen(popupContentViewOnScreenXY); 594 assertTrue(popupContentViewInWindowXY[0] >= 0); 595 assertTrue(popupContentViewInWindowXY[1] >= 0); 596 assertEquals(popupContentViewInWindowXY[0] + xOff, popupContentViewOnScreenXY[0]); 597 assertEquals(popupContentViewInWindowXY[1] + yOff, popupContentViewOnScreenXY[1]); 598 599 dismissPopup(); 600 } 601 602 public void testShowAsDropDownWithOffsets() { 603 int[] anchorXY = new int[2]; 604 int[] viewOnScreenXY = new int[2]; 605 int[] viewInWindowXY = new int[2]; 606 607 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 608 final View upperAnchor = mActivity.findViewById(R.id.anchor_upper); 609 upperAnchor.getLocationOnScreen(anchorXY); 610 int height = upperAnchor.getHeight(); 611 612 final int xOff = 11; 613 final int yOff = 12; 614 615 mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(upperAnchor, xOff, yOff)); 616 mInstrumentation.waitForIdleSync(); 617 618 mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY); 619 mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY); 620 assertEquals(anchorXY[0] + xOff + viewInWindowXY[0], viewOnScreenXY[0]); 621 assertEquals(anchorXY[1] + height + yOff + viewInWindowXY[1], viewOnScreenXY[1]); 622 623 dismissPopup(); 624 } 625 626 public void testOverlapAnchor() { 627 int[] anchorXY = new int[2]; 628 int[] viewOnScreenXY = new int[2]; 629 int[] viewInWindowXY = new int[2]; 630 631 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 632 final View upperAnchor = mActivity.findViewById(R.id.anchor_upper); 633 upperAnchor.getLocationOnScreen(anchorXY); 634 635 assertFalse(mPopupWindow.getOverlapAnchor()); 636 mPopupWindow.setOverlapAnchor(true); 637 assertTrue(mPopupWindow.getOverlapAnchor()); 638 639 mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(upperAnchor, 0, 0)); 640 mInstrumentation.waitForIdleSync(); 641 642 mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY); 643 mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY); 644 assertEquals(anchorXY[0] + viewInWindowXY[0], viewOnScreenXY[0]); 645 assertEquals(anchorXY[1] + viewInWindowXY[1], viewOnScreenXY[1]); 646 } 647 648 public void testAccessWindowLayoutType() { 649 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 650 assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, 651 mPopupWindow.getWindowLayoutType()); 652 mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL); 653 assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, 654 mPopupWindow.getWindowLayoutType()); 655 } 656 657 public void testGetMaxAvailableHeight() { 658 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 659 660 View anchorView = mActivity.findViewById(R.id.anchor_upper); 661 int avaliable = getDisplay().getHeight() - anchorView.getHeight(); 662 int maxAvailableHeight = mPopupWindow.getMaxAvailableHeight(anchorView); 663 assertTrue(maxAvailableHeight > 0); 664 assertTrue(maxAvailableHeight <= avaliable); 665 int maxAvailableHeightWithOffset = mPopupWindow.getMaxAvailableHeight(anchorView, 2); 666 assertEquals(maxAvailableHeight - 2, maxAvailableHeightWithOffset); 667 maxAvailableHeightWithOffset = 668 mPopupWindow.getMaxAvailableHeight(anchorView, maxAvailableHeight); 669 assertTrue(maxAvailableHeightWithOffset > 0); 670 assertTrue(maxAvailableHeightWithOffset <= avaliable); 671 maxAvailableHeightWithOffset = 672 mPopupWindow.getMaxAvailableHeight(anchorView, maxAvailableHeight / 2 - 1); 673 assertTrue(maxAvailableHeightWithOffset > 0); 674 assertTrue(maxAvailableHeightWithOffset <= avaliable); 675 maxAvailableHeightWithOffset = mPopupWindow.getMaxAvailableHeight(anchorView, -1); 676 assertTrue(maxAvailableHeightWithOffset > 0); 677 assertTrue(maxAvailableHeightWithOffset <= avaliable); 678 679 anchorView = mActivity.findViewById(R.id.anchor_lower); 680 // On some devices the view might actually have larger size than the physical display 681 // due to chin and content will be laid out as if outside of the display. We need to use 682 // larger from the display height and the main view height. 683 avaliable = Math.max(getDisplay().getHeight(), 684 mActivity.findViewById(android.R.id.content).getHeight()) - anchorView.getHeight(); 685 maxAvailableHeight = mPopupWindow.getMaxAvailableHeight(anchorView); 686 assertTrue(maxAvailableHeight > 0); 687 assertTrue(maxAvailableHeight <= avaliable); 688 689 anchorView = mActivity.findViewById(R.id.anchor_middle_left); 690 avaliable = getDisplay().getHeight() - anchorView.getHeight() 691 - mActivity.findViewById(R.id.anchor_upper).getHeight(); 692 maxAvailableHeight = mPopupWindow.getMaxAvailableHeight(anchorView); 693 assertTrue(maxAvailableHeight > 0); 694 assertTrue(maxAvailableHeight <= avaliable); 695 } 696 697 @UiThreadTest 698 public void testDismiss() { 699 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 700 assertFalse(mPopupWindow.isShowing()); 701 View anchorView = mActivity.findViewById(R.id.anchor_upper); 702 mPopupWindow.showAsDropDown(anchorView); 703 704 mPopupWindow.dismiss(); 705 assertFalse(mPopupWindow.isShowing()); 706 707 mPopupWindow.dismiss(); 708 assertFalse(mPopupWindow.isShowing()); 709 } 710 711 public void testSetOnDismissListener() { 712 mPopupWindow = new PopupWindow(new TextView(mActivity)); 713 mPopupWindow.setOnDismissListener(null); 714 715 OnDismissListener onDismissListener = mock(OnDismissListener.class); 716 mPopupWindow.setOnDismissListener(onDismissListener); 717 showPopup(); 718 dismissPopup(); 719 verify(onDismissListener, times(1)).onDismiss(); 720 721 showPopup(); 722 dismissPopup(); 723 verify(onDismissListener, times(2)).onDismiss(); 724 725 mPopupWindow.setOnDismissListener(null); 726 showPopup(); 727 dismissPopup(); 728 verify(onDismissListener, times(2)).onDismiss(); 729 } 730 731 public void testUpdate() { 732 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 733 mPopupWindow.setBackgroundDrawable(null); 734 showPopup(); 735 736 mPopupWindow.setIgnoreCheekPress(); 737 mPopupWindow.setFocusable(true); 738 mPopupWindow.setTouchable(false); 739 mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 740 mPopupWindow.setClippingEnabled(false); 741 mPopupWindow.setOutsideTouchable(true); 742 743 WindowManager.LayoutParams p = (WindowManager.LayoutParams) 744 mPopupWindow.getContentView().getRootView().getLayoutParams(); 745 746 assertEquals(0, WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES & p.flags); 747 assertEquals(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 748 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE & p.flags); 749 assertEquals(0, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE & p.flags); 750 assertEquals(0, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH & p.flags); 751 assertEquals(0, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS & p.flags); 752 assertEquals(0, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM & p.flags); 753 754 mInstrumentation.runOnMainSync(() -> mPopupWindow.update()); 755 mInstrumentation.waitForIdleSync(); 756 757 assertEquals(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, 758 WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES & p.flags); 759 assertEquals(0, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE & p.flags); 760 assertEquals(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, 761 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE & p.flags); 762 assertEquals(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 763 WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH & p.flags); 764 assertEquals(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 765 WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS & p.flags); 766 assertEquals(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, 767 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM & p.flags); 768 } 769 770 public void testEnterExitTransition() { 771 TransitionListener enterListener = mock(TransitionListener.class); 772 Transition enterTransition = new BaseTransition(); 773 enterTransition.addListener(enterListener); 774 775 TransitionListener exitListener = mock(TransitionListener.class); 776 Transition exitTransition = new BaseTransition(); 777 exitTransition.addListener(exitListener); 778 779 OnDismissListener dismissListener = mock(OnDismissListener.class); 780 781 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 782 mPopupWindow.setEnterTransition(enterTransition); 783 mPopupWindow.setExitTransition(exitTransition); 784 mPopupWindow.setOnDismissListener(dismissListener); 785 verify(enterListener, never()).onTransitionStart(any(Transition.class)); 786 verify(exitListener, never()).onTransitionStart(any(Transition.class)); 787 verify(dismissListener, never()).onDismiss(); 788 789 final View anchorView = mActivity.findViewById(R.id.anchor_upper); 790 mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(anchorView, 0, 0)); 791 mInstrumentation.waitForIdleSync(); 792 verify(enterListener, times(1)).onTransitionStart(any(Transition.class)); 793 verify(exitListener, never()).onTransitionStart(any(Transition.class)); 794 verify(dismissListener, never()).onDismiss(); 795 796 mInstrumentation.runOnMainSync(() -> mPopupWindow.dismiss()); 797 mInstrumentation.waitForIdleSync(); 798 verify(enterListener, times(1)).onTransitionStart(any(Transition.class)); 799 verify(exitListener, times(1)).onTransitionStart(any(Transition.class)); 800 verify(dismissListener, times(1)).onDismiss(); 801 } 802 803 public void testUpdatePositionAndDimension() { 804 int[] fstXY = new int[2]; 805 int[] sndXY = new int[2]; 806 int[] viewInWindowXY = new int[2]; 807 808 mInstrumentation.runOnMainSync(() -> { 809 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 810 // Do not attach within the decor; we will be measuring location 811 // with regard to screen coordinates. 812 mPopupWindow.setAttachedInDecor(false); 813 }); 814 815 mInstrumentation.waitForIdleSync(); 816 // Do not update if it is not shown 817 assertFalse(mPopupWindow.isShowing()); 818 assertEquals(100, mPopupWindow.getWidth()); 819 assertEquals(100, mPopupWindow.getHeight()); 820 821 showPopup(); 822 mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY); 823 824 // update if it is not shown 825 mInstrumentation.runOnMainSync(() -> mPopupWindow.update(20, 50, 50, 50)); 826 827 mInstrumentation.waitForIdleSync(); 828 assertTrue(mPopupWindow.isShowing()); 829 assertEquals(50, mPopupWindow.getWidth()); 830 assertEquals(50, mPopupWindow.getHeight()); 831 832 mPopupWindow.getContentView().getLocationOnScreen(fstXY); 833 assertEquals(viewInWindowXY[0] + 20, fstXY[0]); 834 assertEquals(viewInWindowXY[1] + 50, fstXY[1]); 835 836 // ignore if width or height is -1 837 mInstrumentation.runOnMainSync(() -> mPopupWindow.update(4, 0, -1, -1, true)); 838 mInstrumentation.waitForIdleSync(); 839 840 assertTrue(mPopupWindow.isShowing()); 841 assertEquals(50, mPopupWindow.getWidth()); 842 assertEquals(50, mPopupWindow.getHeight()); 843 844 mPopupWindow.getContentView().getLocationOnScreen(sndXY); 845 assertEquals(viewInWindowXY[0] + 4, sndXY[0]); 846 assertEquals(viewInWindowXY[1], sndXY[1]); 847 848 dismissPopup(); 849 } 850 851 public void testUpdateDimensionAndAlignAnchorView() { 852 mInstrumentation.runOnMainSync( 853 () -> mPopupWindow = createPopupWindow(createPopupContent(50, 50))); 854 mInstrumentation.waitForIdleSync(); 855 856 final View anchorView = mActivity.findViewById(R.id.anchor_upper); 857 mPopupWindow.update(anchorView, 50, 50); 858 // Do not update if it is not shown 859 assertFalse(mPopupWindow.isShowing()); 860 assertEquals(100, mPopupWindow.getWidth()); 861 assertEquals(100, mPopupWindow.getHeight()); 862 863 mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(anchorView)); 864 mInstrumentation.waitForIdleSync(); 865 // update if it is shown 866 mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anchorView, 50, 50)); 867 mInstrumentation.waitForIdleSync(); 868 assertTrue(mPopupWindow.isShowing()); 869 assertEquals(50, mPopupWindow.getWidth()); 870 assertEquals(50, mPopupWindow.getHeight()); 871 872 // ignore if width or height is -1 873 mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anchorView, -1, -1)); 874 mInstrumentation.waitForIdleSync(); 875 assertTrue(mPopupWindow.isShowing()); 876 assertEquals(50, mPopupWindow.getWidth()); 877 assertEquals(50, mPopupWindow.getHeight()); 878 879 mInstrumentation.runOnMainSync(() -> mPopupWindow.dismiss()); 880 mInstrumentation.waitForIdleSync(); 881 } 882 883 public void testUpdateDimensionAndAlignAnchorViewWithOffsets() { 884 int[] anchorXY = new int[2]; 885 int[] viewInWindowOff = new int[2]; 886 int[] viewXY = new int[2]; 887 888 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 889 final View anchorView = mActivity.findViewById(R.id.anchor_upper); 890 // Do not update if it is not shown 891 assertFalse(mPopupWindow.isShowing()); 892 assertEquals(100, mPopupWindow.getWidth()); 893 assertEquals(100, mPopupWindow.getHeight()); 894 895 showPopup(); 896 anchorView.getLocationOnScreen(anchorXY); 897 mPopupWindow.getContentView().getLocationInWindow(viewInWindowOff); 898 899 // update if it is not shown 900 mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anchorView, 20, 50, 50, 50)); 901 902 mInstrumentation.waitForIdleSync(); 903 904 assertTrue(mPopupWindow.isShowing()); 905 assertEquals(50, mPopupWindow.getWidth()); 906 assertEquals(50, mPopupWindow.getHeight()); 907 908 mPopupWindow.getContentView().getLocationOnScreen(viewXY); 909 910 // The popup should appear below and to right with an offset. 911 assertEquals(anchorXY[0] + 20 + viewInWindowOff[0], viewXY[0]); 912 assertEquals(anchorXY[1] + anchorView.getHeight() + 50 + viewInWindowOff[1], viewXY[1]); 913 914 // ignore width and height but change location 915 mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anchorView, 10, 50, -1, -1)); 916 mInstrumentation.waitForIdleSync(); 917 918 assertTrue(mPopupWindow.isShowing()); 919 assertEquals(50, mPopupWindow.getWidth()); 920 assertEquals(50, mPopupWindow.getHeight()); 921 922 mPopupWindow.getContentView().getLocationOnScreen(viewXY); 923 924 // The popup should appear below and to right with an offset. 925 assertEquals(anchorXY[0] + 10 + viewInWindowOff[0], viewXY[0]); 926 assertEquals(anchorXY[1] + anchorView.getHeight() + 50 + viewInWindowOff[1], viewXY[1]); 927 928 final View anotherView = mActivity.findViewById(R.id.anchor_middle_left); 929 mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anotherView, 0, 0, 60, 60)); 930 mInstrumentation.waitForIdleSync(); 931 932 assertTrue(mPopupWindow.isShowing()); 933 assertEquals(60, mPopupWindow.getWidth()); 934 assertEquals(60, mPopupWindow.getHeight()); 935 936 int[] newXY = new int[2]; 937 anotherView.getLocationOnScreen(newXY); 938 mPopupWindow.getContentView().getLocationOnScreen(viewXY); 939 940 // The popup should appear below and to the right. 941 assertEquals(newXY[0] + viewInWindowOff[0], viewXY[0]); 942 assertEquals(newXY[1] + anotherView.getHeight() + viewInWindowOff[1], viewXY[1]); 943 944 dismissPopup(); 945 } 946 947 public void testAccessInputMethodMode() { 948 mPopupWindow = new PopupWindow(mActivity); 949 assertEquals(0, mPopupWindow.getInputMethodMode()); 950 951 mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE); 952 assertEquals(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE, mPopupWindow.getInputMethodMode()); 953 954 mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 955 assertEquals(PopupWindow.INPUT_METHOD_NEEDED, mPopupWindow.getInputMethodMode()); 956 957 mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 958 assertEquals(PopupWindow.INPUT_METHOD_NOT_NEEDED, mPopupWindow.getInputMethodMode()); 959 960 mPopupWindow.setInputMethodMode(-1); 961 assertEquals(-1, mPopupWindow.getInputMethodMode()); 962 } 963 964 public void testAccessClippingEnabled() { 965 mPopupWindow = new PopupWindow(mActivity); 966 assertTrue(mPopupWindow.isClippingEnabled()); 967 968 mPopupWindow.setClippingEnabled(false); 969 assertFalse(mPopupWindow.isClippingEnabled()); 970 } 971 972 public void testAccessOutsideTouchable() { 973 mPopupWindow = new PopupWindow(mActivity); 974 assertFalse(mPopupWindow.isOutsideTouchable()); 975 976 mPopupWindow.setOutsideTouchable(true); 977 assertTrue(mPopupWindow.isOutsideTouchable()); 978 } 979 980 public void testAccessTouchable() { 981 mPopupWindow = new PopupWindow(mActivity); 982 assertTrue(mPopupWindow.isTouchable()); 983 984 mPopupWindow.setTouchable(false); 985 assertFalse(mPopupWindow.isTouchable()); 986 } 987 988 public void testIsAboveAnchor() { 989 mInstrumentation.runOnMainSync(() -> mPopupWindow = createPopupWindow(createPopupContent(50, 990 50))); 991 mInstrumentation.waitForIdleSync(); 992 final View upperAnchor = mActivity.findViewById(R.id.anchor_upper); 993 994 mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(upperAnchor)); 995 mInstrumentation.waitForIdleSync(); 996 assertFalse(mPopupWindow.isAboveAnchor()); 997 dismissPopup(); 998 999 mPopupWindow = createPopupWindow(createPopupContent(50, 50)); 1000 final View lowerAnchor = mActivity.findViewById(R.id.anchor_lower); 1001 1002 mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(lowerAnchor, 0, 0)); 1003 mInstrumentation.waitForIdleSync(); 1004 assertTrue(mPopupWindow.isAboveAnchor()); 1005 dismissPopup(); 1006 } 1007 1008 public void testSetTouchInterceptor() { 1009 mPopupWindow = new PopupWindow(new TextView(mActivity)); 1010 1011 OnTouchListener onTouchListener = mock(OnTouchListener.class); 1012 when(onTouchListener.onTouch(any(View.class), any(MotionEvent.class))).thenReturn(true); 1013 1014 mPopupWindow.setTouchInterceptor(onTouchListener); 1015 mPopupWindow.setFocusable(true); 1016 mPopupWindow.setOutsideTouchable(true); 1017 Drawable drawable = new ColorDrawable(); 1018 mPopupWindow.setBackgroundDrawable(drawable); 1019 showPopup(); 1020 1021 int[] xy = new int[2]; 1022 mPopupWindow.getContentView().getLocationOnScreen(xy); 1023 final int viewWidth = mPopupWindow.getContentView().getWidth(); 1024 final int viewHeight = mPopupWindow.getContentView().getHeight(); 1025 final float x = xy[0] + (viewWidth / 2.0f); 1026 float y = xy[1] + (viewHeight / 2.0f); 1027 1028 long downTime = SystemClock.uptimeMillis(); 1029 long eventTime = SystemClock.uptimeMillis(); 1030 MotionEvent event = MotionEvent.obtain(downTime, eventTime, 1031 MotionEvent.ACTION_DOWN, x, y, 0); 1032 getInstrumentation().sendPointerSync(event); 1033 verify(onTouchListener, times(1)).onTouch(any(View.class), any(MotionEvent.class)); 1034 1035 downTime = SystemClock.uptimeMillis(); 1036 eventTime = SystemClock.uptimeMillis(); 1037 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0); 1038 getInstrumentation().sendPointerSync(event); 1039 verify(onTouchListener, times(2)).onTouch(any(View.class), any(MotionEvent.class)); 1040 1041 mPopupWindow.setTouchInterceptor(null); 1042 downTime = SystemClock.uptimeMillis(); 1043 eventTime = SystemClock.uptimeMillis(); 1044 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0); 1045 getInstrumentation().sendPointerSync(event); 1046 verify(onTouchListener, times(2)).onTouch(any(View.class), any(MotionEvent.class)); 1047 } 1048 1049 public void testSetWindowLayoutMode() { 1050 mPopupWindow = new PopupWindow(new TextView(mActivity)); 1051 showPopup(); 1052 1053 ViewGroup.LayoutParams p = mPopupWindow.getContentView().getRootView().getLayoutParams(); 1054 assertEquals(0, p.width); 1055 assertEquals(0, p.height); 1056 1057 mPopupWindow.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); 1058 mInstrumentation.runOnMainSync(() -> mPopupWindow.update(20, 50, 50, 50)); 1059 1060 assertEquals(LayoutParams.WRAP_CONTENT, p.width); 1061 assertEquals(LayoutParams.MATCH_PARENT, p.height); 1062 } 1063 1064 private static class BaseTransition extends Transition { 1065 @Override 1066 public void captureStartValues(TransitionValues transitionValues) {} 1067 1068 @Override 1069 public void captureEndValues(TransitionValues transitionValues) {} 1070 } 1071 1072 private View createPopupContent(int width, int height) { 1073 final View popupView = new View(mActivity); 1074 popupView.setLayoutParams(new ViewGroup.LayoutParams(width, height)); 1075 popupView.setBackgroundColor(Color.MAGENTA); 1076 1077 return popupView; 1078 } 1079 1080 private PopupWindow createPopupWindow() { 1081 PopupWindow window = new PopupWindow(mActivity); 1082 window.setWidth(100); 1083 window.setHeight(100); 1084 window.setBackgroundDrawable(new ColorDrawable(Color.YELLOW)); 1085 return window; 1086 } 1087 1088 private PopupWindow createPopupWindow(View content) { 1089 PopupWindow window = createPopupWindow(); 1090 window.setContentView(content); 1091 return window; 1092 } 1093 1094 private void showPopup() { 1095 mInstrumentation.runOnMainSync(() -> { 1096 if (mPopupWindow == null || mPopupWindow.isShowing()) { 1097 return; 1098 } 1099 View anchor = mActivity.findViewById(R.id.anchor_upper); 1100 mPopupWindow.showAsDropDown(anchor); 1101 assertTrue(mPopupWindow.isShowing()); 1102 }); 1103 mInstrumentation.waitForIdleSync(); 1104 } 1105 1106 private void dismissPopup() { 1107 mInstrumentation.runOnMainSync(() -> { 1108 if (mPopupWindow == null || !mPopupWindow.isShowing()) { 1109 return; 1110 } 1111 mPopupWindow.dismiss(); 1112 }); 1113 mInstrumentation.waitForIdleSync(); 1114 } 1115 } 1116