Home | History | Annotate | Download | only in cts
      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