PopupZoomerTest.java revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.browser;
6
7import android.content.Context;
8import android.graphics.Bitmap;
9import android.graphics.Canvas;
10import android.graphics.Rect;
11import android.os.SystemClock;
12import android.test.suitebuilder.annotation.SmallTest;
13import android.view.MotionEvent;
14import android.view.View;
15
16import org.chromium.base.test.util.Feature;
17import org.chromium.content_shell_apk.ContentShellTestBase;
18
19/**
20 * Tests for PopupZoomer.
21 */
22public class PopupZoomerTest extends ContentShellTestBase {
23    private CustomCanvasPopupZoomer mPopupZoomer;
24    private ContentViewCore mContentViewCore;
25
26    private static class CustomCanvasPopupZoomer extends PopupZoomer {
27        Canvas mCanvas;
28        long mPendingDraws = 0;
29
30        CustomCanvasPopupZoomer(Context context, Canvas c) {
31            super(context);
32            mCanvas = c;
33        }
34
35        @Override
36        public void invalidate() {
37            mPendingDraws++;
38        }
39
40        @Override
41        public void onDraw(Canvas c) {
42            mPendingDraws--;
43            super.onDraw(c);
44        }
45
46        // Test doesn't attach PopupZoomer to the view hierarchy,
47        // but onDraw() should still go on.
48        @Override
49        protected boolean acceptZeroSizeView() {
50            return true;
51        }
52
53        public void finishPendingDraws() {
54            // Finish all pending draw calls. A draw call may change mPendingDraws.
55            while (mPendingDraws > 0) {
56                onDraw(mCanvas);
57            }
58        }
59
60    }
61
62    private CustomCanvasPopupZoomer createPopupZoomerForTest(Context context) {
63        return new CustomCanvasPopupZoomer(
64                context, new Canvas(Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8)));
65    }
66
67    private void sendSingleTapTouchEventOnView(View view, float x, float y) {
68        final long downEvent = SystemClock.uptimeMillis();
69        view.onTouchEvent(
70                MotionEvent.obtain(downEvent, downEvent, MotionEvent.ACTION_DOWN, x, y, 0));
71        view.onTouchEvent(
72                MotionEvent.obtain(downEvent, downEvent + 10, MotionEvent.ACTION_UP, x, y, 0));
73    }
74
75    @Override
76    public void setUp() throws Exception {
77        super.setUp();
78        mPopupZoomer = createPopupZoomerForTest(getInstrumentation().getTargetContext());
79        mContentViewCore = new ContentViewCore(getActivity());
80        mContentViewCore.setPopupZoomerForTest(mPopupZoomer);
81    }
82
83    @SmallTest
84    @Feature({"Navigation"})
85    public void testDefaultCreateState() throws Exception {
86        assertEquals(View.INVISIBLE, mPopupZoomer.getVisibility());
87        assertFalse(mPopupZoomer.isShowing());
88    }
89
90    @SmallTest
91    @Feature({"Navigation"})
92    public void testShowWithoutBitmap() throws Exception {
93        mPopupZoomer.show(new Rect(0, 0, 5, 5));
94
95        // The view should be invisible.
96        assertEquals(View.INVISIBLE, mPopupZoomer.getVisibility());
97        assertFalse(mPopupZoomer.isShowing());
98    }
99
100    @SmallTest
101    @Feature({"Navigation"})
102    public void testShowWithBitmap() throws Exception {
103        mPopupZoomer.setBitmap(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8));
104        mPopupZoomer.show(new Rect(0, 0, 5, 5));
105
106        // The view should become visible.
107        assertEquals(View.VISIBLE, mPopupZoomer.getVisibility());
108        assertTrue(mPopupZoomer.isShowing());
109    }
110
111    @SmallTest
112    @Feature({"Navigation"})
113    public void testHide() throws Exception {
114        mPopupZoomer.setBitmap(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8));
115        mPopupZoomer.show(new Rect(0, 0, 5, 5));
116
117        // The view should become visible.
118        assertEquals(View.VISIBLE, mPopupZoomer.getVisibility());
119        assertTrue(mPopupZoomer.isShowing());
120
121        // Call hide without animation.
122        mPopupZoomer.hide(false);
123
124        // The view should be invisible.
125        assertEquals(View.INVISIBLE, mPopupZoomer.getVisibility());
126        assertFalse(mPopupZoomer.isShowing());
127    }
128
129    @SmallTest
130    @Feature({"Navigation"})
131    public void testOnTouchEventOutsidePopup() throws Exception {
132        mPopupZoomer.setBitmap(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8));
133        mPopupZoomer.show(new Rect(0, 0, 5, 5));
134
135        // Wait for the show animation to finish.
136        mPopupZoomer.finishPendingDraws();
137
138        // The view should be visible.
139        assertEquals(View.VISIBLE, mPopupZoomer.getVisibility());
140        assertTrue(mPopupZoomer.isShowing());
141
142        // Send tap event at a point outside the popup.
143        // i.e. coordinates greater than 10 + PopupZoomer.ZOOM_BOUNDS_MARGIN
144        sendSingleTapTouchEventOnView(mPopupZoomer, 50, 50);
145
146        // Wait for the hide animation to finish.
147        mPopupZoomer.finishPendingDraws();
148
149        // The view should be invisible.
150        assertEquals(View.INVISIBLE, mPopupZoomer.getVisibility());
151        assertFalse(mPopupZoomer.isShowing());
152    }
153
154    @SmallTest
155    @Feature({"Navigation"})
156    public void testOnTouchEventInsidePopupNoOnTapListener() throws Exception {
157        mPopupZoomer.setBitmap(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8));
158        mPopupZoomer.show(new Rect(0, 0, 5, 5));
159
160        // Wait for the animation to finish.
161        mPopupZoomer.finishPendingDraws();
162
163        // The view should be visible.
164        assertEquals(View.VISIBLE, mPopupZoomer.getVisibility());
165        assertTrue(mPopupZoomer.isShowing());
166
167        // Send tap event at a point inside the popup.
168        // i.e. coordinates between PopupZoomer.ZOOM_BOUNDS_MARGIN and
169        // PopupZoomer.ZOOM_BOUNDS_MARGIN + 10
170        sendSingleTapTouchEventOnView(mPopupZoomer, 30, 30);
171
172        // Wait for the animation to finish (if there is any).
173        mPopupZoomer.finishPendingDraws();
174
175        // The view should still be visible as no OnTapListener is set.
176        assertEquals(View.VISIBLE, mPopupZoomer.getVisibility());
177        assertTrue(mPopupZoomer.isShowing());
178    }
179
180    @SmallTest
181    @Feature({"Navigation"})
182    public void testHidePopupOnLosingFocus() throws Exception {
183        mPopupZoomer.setBitmap(
184                        Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8));
185        mPopupZoomer.show(new Rect(0, 0, 5, 5));
186
187        // Wait for the animation to finish.
188        mPopupZoomer.finishPendingDraws();
189
190        // The view should be visible.
191        assertEquals(View.VISIBLE, mPopupZoomer.getVisibility());
192        assertTrue(mPopupZoomer.isShowing());
193
194        // Simulate losing the focus.
195        mContentViewCore.onFocusChanged(false);
196
197        // Wait for the hide animation to finish.
198        mPopupZoomer.finishPendingDraws();
199
200        // Now that another view has been focused, the view should be invisible.
201        assertEquals(View.INVISIBLE, mPopupZoomer.getVisibility());
202        assertFalse(mPopupZoomer.isShowing());
203    }
204}
205