OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 |
| 5 package org.chromium.chrome.browser.contextualsearch; |
| 6 |
| 7 import android.content.Context; |
| 8 import android.test.InstrumentationTestCase; |
| 9 import android.test.suitebuilder.annotation.SmallTest; |
| 10 import android.view.GestureDetector; |
| 11 import android.view.GestureDetector.SimpleOnGestureListener; |
| 12 import android.view.MotionEvent; |
| 13 import android.view.ViewConfiguration; |
| 14 |
| 15 import org.chromium.base.test.util.Feature; |
| 16 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.Context
ualSearchPanel; |
| 17 import org.chromium.chrome.browser.compositor.eventfilter.MockEventFilterHost; |
| 18 import org.chromium.chrome.browser.compositor.layouts.eventfilter.ContextualSear
chEventFilter; |
| 19 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilterHos
t; |
| 20 import org.chromium.chrome.browser.compositor.layouts.eventfilter.GestureHandler
; |
| 21 |
| 22 /** |
| 23 * Class responsible for testing the ContextualSearchEventFilter. |
| 24 */ |
| 25 public class ContextualSearchEventFilterTest extends InstrumentationTestCase |
| 26 implements GestureHandler { |
| 27 |
| 28 private static final float SEARCH_PANEL_ALMOST_MAXIMIZED_OFFSET_Y_DP = 50.f; |
| 29 private static final float SEARCH_BAR_HEIGHT_DP = 100.f; |
| 30 |
| 31 private float mTouchSlopDp; |
| 32 private float mDpToPx; |
| 33 |
| 34 private float mAlmostMaximizedSearchContentViewOffsetYDp; |
| 35 private float mMaximizedSearchContentViewOffsetYDp; |
| 36 |
| 37 private float mSearchContentViewVerticalScroll; |
| 38 |
| 39 private boolean mWasTapDetectedOnSearchPanel; |
| 40 private boolean mWasScrollDetectedOnSearchPanel; |
| 41 private boolean mWasTapDetectedOnSearchContentView; |
| 42 private boolean mWasScrollDetectedOnSearchContentView; |
| 43 |
| 44 private ContextualSearchPanel mContextualSearchPanel; |
| 45 private ContextualSearchEventFilterWrapper mEventFilter; |
| 46 |
| 47 private boolean mShouldLockHorizontalMotionInSearchContentView; |
| 48 private MotionEvent mEventPropagatedToSearchContentView; |
| 49 |
| 50 // -------------------------------------------------------------------------
------------------- |
| 51 // MockEventFilterHostWrapper |
| 52 // -------------------------------------------------------------------------
------------------- |
| 53 |
| 54 /** |
| 55 * Wrapper around MockEventFilterHost used to mimic the event forwarding mec
hanism |
| 56 * of the EventFilterHost. |
| 57 */ |
| 58 public class MockEventFilterHostWrapper extends MockEventFilterHost { |
| 59 GestureDetector mGestureDetector; |
| 60 |
| 61 public MockEventFilterHostWrapper(Context context) { |
| 62 mGestureDetector = new GestureDetector(context, new SimpleOnGestureL
istener() { |
| 63 @Override |
| 64 public boolean onSingleTapUp(MotionEvent e) { |
| 65 mWasTapDetectedOnSearchContentView = true; |
| 66 return true; |
| 67 } |
| 68 |
| 69 @Override |
| 70 public boolean onScroll(MotionEvent e1, MotionEvent e2, float dx
, float dy) { |
| 71 mWasScrollDetectedOnSearchContentView = true; |
| 72 return true; |
| 73 } |
| 74 }); |
| 75 } |
| 76 |
| 77 @Override |
| 78 public boolean propagateEvent(MotionEvent e) { |
| 79 // Check that the event offset is correct. |
| 80 if (!mShouldLockHorizontalMotionInSearchContentView) { |
| 81 float propagatedEventY = mEventPropagatedToSearchContentView.get
Y(); |
| 82 float offsetY = mContextualSearchPanel.getSearchContentViewOffse
tY() * mDpToPx; |
| 83 assertEquals(propagatedEventY - offsetY, e.getY()); |
| 84 } |
| 85 |
| 86 // Propagates the event to the GestureDetector in order to be able t
o tell |
| 87 // if the gesture was properly triggered in the SearchContentView. |
| 88 return mGestureDetector.onTouchEvent(e); |
| 89 } |
| 90 |
| 91 } |
| 92 |
| 93 // -------------------------------------------------------------------------
------------------- |
| 94 // ContextualSearchEventFilterWrapper |
| 95 // -------------------------------------------------------------------------
------------------- |
| 96 |
| 97 /** |
| 98 * Wrapper around ContextualSearchEventFilter used by tests. |
| 99 */ |
| 100 public class ContextualSearchEventFilterWrapper extends ContextualSearchEven
tFilter { |
| 101 public ContextualSearchEventFilterWrapper(Context context, EventFilterHo
st host, |
| 102 GestureHandler handler, ContextualSearchPanel contextualSearchPa
nel) { |
| 103 super(context, host, handler, contextualSearchPanel); |
| 104 } |
| 105 |
| 106 @Override |
| 107 protected float getSearchContentViewVerticalScroll() { |
| 108 return mSearchContentViewVerticalScroll; |
| 109 } |
| 110 |
| 111 @Override |
| 112 protected void propagateEventToSearchContentView(MotionEvent e) { |
| 113 mEventPropagatedToSearchContentView = MotionEvent.obtain(e); |
| 114 super.propagateEventToSearchContentView(e); |
| 115 mEventPropagatedToSearchContentView.recycle(); |
| 116 } |
| 117 } |
| 118 |
| 119 // -------------------------------------------------------------------------
------------------- |
| 120 // Test Suite |
| 121 // -------------------------------------------------------------------------
------------------- |
| 122 |
| 123 @Override |
| 124 protected void setUp() throws Exception { |
| 125 super.setUp(); |
| 126 |
| 127 Context context = getInstrumentation().getTargetContext(); |
| 128 |
| 129 mDpToPx = context.getResources().getDisplayMetrics().density; |
| 130 mTouchSlopDp = ViewConfiguration.get(context).getScaledTouchSlop() / mDp
ToPx; |
| 131 |
| 132 EventFilterHost eventFilterHost = new MockEventFilterHostWrapper(context
); |
| 133 mContextualSearchPanel = new ContextualSearchPanel(context, null); |
| 134 mEventFilter = new ContextualSearchEventFilterWrapper(context, eventFilt
erHost, this, |
| 135 mContextualSearchPanel); |
| 136 |
| 137 mContextualSearchPanel.setSearchBarHeightForTesting(SEARCH_BAR_HEIGHT_DP
); |
| 138 |
| 139 setSearchContentViewVerticalScroll(0); |
| 140 |
| 141 mAlmostMaximizedSearchContentViewOffsetYDp = |
| 142 SEARCH_PANEL_ALMOST_MAXIMIZED_OFFSET_Y_DP + SEARCH_BAR_HEIGHT_DP
; |
| 143 mMaximizedSearchContentViewOffsetYDp = SEARCH_BAR_HEIGHT_DP; |
| 144 |
| 145 mWasTapDetectedOnSearchPanel = false; |
| 146 mWasScrollDetectedOnSearchPanel = false; |
| 147 mWasTapDetectedOnSearchContentView = false; |
| 148 mWasScrollDetectedOnSearchContentView = false; |
| 149 |
| 150 mShouldLockHorizontalMotionInSearchContentView = false; |
| 151 } |
| 152 |
| 153 @SmallTest |
| 154 @Feature({"ContextualSearch"}) |
| 155 public void testTapSearchContentView() { |
| 156 positionSearchPanelInAlmostMaximizedState(); |
| 157 |
| 158 // Simulate tap. |
| 159 simulateActionDownEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp
+ 1.f); |
| 160 simulateActionUpEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp +
1.f); |
| 161 |
| 162 assertFalse(mWasScrollDetectedOnSearchPanel); |
| 163 assertFalse(mWasTapDetectedOnSearchPanel); |
| 164 |
| 165 assertTrue(mWasTapDetectedOnSearchContentView); |
| 166 assertFalse(mWasScrollDetectedOnSearchContentView); |
| 167 } |
| 168 |
| 169 @SmallTest |
| 170 @Feature({"ContextualSearch"}) |
| 171 public void testScrollingSearchContentViewDragsSearchPanel() { |
| 172 positionSearchPanelInAlmostMaximizedState(); |
| 173 |
| 174 // Simulate swipe up sequence. |
| 175 simulateActionDownEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp
+ 1.f); |
| 176 simulateActionMoveEvent(0.f, mMaximizedSearchContentViewOffsetYDp); |
| 177 simulateActionUpEvent(0.f, mMaximizedSearchContentViewOffsetYDp); |
| 178 |
| 179 assertTrue(mWasScrollDetectedOnSearchPanel); |
| 180 assertFalse(mWasTapDetectedOnSearchPanel); |
| 181 |
| 182 assertFalse(mWasScrollDetectedOnSearchContentView); |
| 183 assertFalse(mWasTapDetectedOnSearchContentView); |
| 184 } |
| 185 |
| 186 @SmallTest |
| 187 @Feature({"ContextualSearch"}) |
| 188 public void testScrollUpSearchContentView() { |
| 189 positionSearchPanelInMaximizedState(); |
| 190 |
| 191 // Simulate swipe up sequence. |
| 192 simulateActionDownEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp
+ 1.f); |
| 193 simulateActionMoveEvent(0.f, mMaximizedSearchContentViewOffsetYDp); |
| 194 simulateActionUpEvent(0.f, mMaximizedSearchContentViewOffsetYDp); |
| 195 |
| 196 assertFalse(mWasScrollDetectedOnSearchPanel); |
| 197 assertFalse(mWasTapDetectedOnSearchPanel); |
| 198 |
| 199 assertTrue(mWasScrollDetectedOnSearchContentView); |
| 200 assertFalse(mWasTapDetectedOnSearchContentView); |
| 201 } |
| 202 |
| 203 @SmallTest |
| 204 @Feature({"ContextualSearch"}) |
| 205 public void testScrollDownSearchContentView() { |
| 206 positionSearchPanelInMaximizedState(); |
| 207 |
| 208 // When the Panel is maximized and the scroll position is greater than z
ero, a swipe down |
| 209 // on the SearchContentView should trigger a scroll on it. |
| 210 setSearchContentViewVerticalScroll(100.f); |
| 211 |
| 212 // Simulate swipe down sequence. |
| 213 simulateActionDownEvent(0.f, mMaximizedSearchContentViewOffsetYDp + 1.f)
; |
| 214 simulateActionMoveEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp)
; |
| 215 simulateActionUpEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp); |
| 216 |
| 217 assertFalse(mWasScrollDetectedOnSearchPanel); |
| 218 assertFalse(mWasTapDetectedOnSearchPanel); |
| 219 |
| 220 assertTrue(mWasScrollDetectedOnSearchContentView); |
| 221 assertFalse(mWasTapDetectedOnSearchContentView); |
| 222 } |
| 223 |
| 224 @SmallTest |
| 225 @Feature({"ContextualSearch"}) |
| 226 public void testDragByOverscrollingSearchContentView() { |
| 227 positionSearchPanelInMaximizedState(); |
| 228 |
| 229 // When the Panel is maximized and the scroll position is zero, a swipe
down on the |
| 230 // SearchContentView should trigger a swipe on the SearchPanel. |
| 231 setSearchContentViewVerticalScroll(0.f); |
| 232 |
| 233 // Simulate swipe down sequence. |
| 234 simulateActionDownEvent(0.f, mMaximizedSearchContentViewOffsetYDp + 1.f)
; |
| 235 simulateActionMoveEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp)
; |
| 236 simulateActionUpEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp); |
| 237 |
| 238 assertTrue(mWasScrollDetectedOnSearchPanel); |
| 239 assertFalse(mWasTapDetectedOnSearchPanel); |
| 240 |
| 241 assertFalse(mWasScrollDetectedOnSearchContentView); |
| 242 assertFalse(mWasTapDetectedOnSearchContentView); |
| 243 } |
| 244 |
| 245 @SmallTest |
| 246 @Feature({"ContextualSearch"}) |
| 247 public void testUnwantedTapDoesNotHappenInSearchContentView() { |
| 248 positionSearchPanelInAlmostMaximizedState(); |
| 249 |
| 250 float searchContentViewOffsetYStart = mAlmostMaximizedSearchContentViewO
ffsetYDp + 1.f; |
| 251 float searchContentViewOffsetYEnd = mMaximizedSearchContentViewOffsetYDp
- 1.f; |
| 252 |
| 253 // Simulate swipe up to maximized position. |
| 254 simulateActionDownEvent(0.f, searchContentViewOffsetYStart); |
| 255 simulateActionMoveEvent(0.f, mMaximizedSearchContentViewOffsetYDp); |
| 256 positionSearchPanelInMaximizedState(); |
| 257 |
| 258 // Confirm that the SearchPanel got a scroll event. |
| 259 assertTrue(mWasScrollDetectedOnSearchPanel); |
| 260 |
| 261 // Continue the swipe up for one more dp. From now on, the events might
be forwarded |
| 262 // to the SearchContentView. |
| 263 simulateActionMoveEvent(0.f, searchContentViewOffsetYEnd); |
| 264 simulateActionUpEvent(0.f, searchContentViewOffsetYEnd); |
| 265 |
| 266 // But 1 dp is not enough to trigger a scroll in the SearchContentView,
and in this |
| 267 // particular case, it should also not trigger a tap because the total d
isplacement |
| 268 // of the touch gesture is greater than the touch slop. |
| 269 float searchContentViewOffsetDelta = |
| 270 searchContentViewOffsetYStart - searchContentViewOffsetYEnd; |
| 271 assertTrue(Math.abs(searchContentViewOffsetDelta) > mTouchSlopDp); |
| 272 |
| 273 assertFalse(mWasTapDetectedOnSearchPanel); |
| 274 |
| 275 assertFalse(mWasScrollDetectedOnSearchContentView); |
| 276 assertFalse(mWasTapDetectedOnSearchContentView); |
| 277 } |
| 278 |
| 279 @SmallTest |
| 280 @Feature({"ContextualSearch"}) |
| 281 public void testDragSearchPanelThenContinuouslyScrollSearchContentView() { |
| 282 positionSearchPanelInAlmostMaximizedState(); |
| 283 |
| 284 // Simulate swipe up to maximized position. |
| 285 simulateActionDownEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp
+ 1.f); |
| 286 simulateActionMoveEvent(0.f, mMaximizedSearchContentViewOffsetYDp); |
| 287 positionSearchPanelInMaximizedState(); |
| 288 |
| 289 // Confirm that the SearchPanel got a scroll event. |
| 290 assertTrue(mWasScrollDetectedOnSearchPanel); |
| 291 |
| 292 // Continue the swipe up for one more dp. From now on, the events might
be forwarded |
| 293 // to the SearchContentView. |
| 294 simulateActionMoveEvent(0.f, mMaximizedSearchContentViewOffsetYDp - 1.f)
; |
| 295 |
| 296 // Now keep swiping up an amount greater than the touch slop. In this ca
se a scroll |
| 297 // should be triggered in the SearchContentView. |
| 298 simulateActionMoveEvent(0.f, mMaximizedSearchContentViewOffsetYDp - 2 *
mTouchSlopDp); |
| 299 simulateActionUpEvent(0.f, mMaximizedSearchContentViewOffsetYDp - 2 * mT
ouchSlopDp); |
| 300 |
| 301 assertFalse(mWasTapDetectedOnSearchPanel); |
| 302 |
| 303 assertTrue(mWasScrollDetectedOnSearchContentView); |
| 304 assertFalse(mWasTapDetectedOnSearchContentView); |
| 305 } |
| 306 |
| 307 @SmallTest |
| 308 @Feature({"ContextualSearch"}) |
| 309 public void testTapSearchPanel() { |
| 310 positionSearchPanelInAlmostMaximizedState(); |
| 311 |
| 312 // Simulate tap. |
| 313 simulateActionDownEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp
- 1.f); |
| 314 simulateActionUpEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp -
1.f); |
| 315 |
| 316 assertFalse(mWasScrollDetectedOnSearchPanel); |
| 317 assertTrue(mWasTapDetectedOnSearchPanel); |
| 318 |
| 319 assertFalse(mWasScrollDetectedOnSearchContentView); |
| 320 assertFalse(mWasTapDetectedOnSearchContentView); |
| 321 } |
| 322 |
| 323 @SmallTest |
| 324 @Feature({"ContextualSearch"}) |
| 325 public void testScrollSearchPanel() { |
| 326 positionSearchPanelInAlmostMaximizedState(); |
| 327 |
| 328 // Simulate swipe up sequence. |
| 329 simulateActionDownEvent(0.f, mAlmostMaximizedSearchContentViewOffsetYDp
- 1.f); |
| 330 simulateActionMoveEvent(0.f, mMaximizedSearchContentViewOffsetYDp); |
| 331 simulateActionUpEvent(0.f, mMaximizedSearchContentViewOffsetYDp); |
| 332 |
| 333 assertTrue(mWasScrollDetectedOnSearchPanel); |
| 334 assertFalse(mWasTapDetectedOnSearchPanel); |
| 335 |
| 336 assertFalse(mWasScrollDetectedOnSearchContentView); |
| 337 assertFalse(mWasTapDetectedOnSearchContentView); |
| 338 } |
| 339 |
| 340 // -------------------------------------------------------------------------
------------------- |
| 341 // Helpers |
| 342 // -------------------------------------------------------------------------
------------------- |
| 343 |
| 344 /** |
| 345 * Positions the SearchPanel in the almost maximized state. |
| 346 */ |
| 347 private void positionSearchPanelInAlmostMaximizedState() { |
| 348 mContextualSearchPanel.setMaximizedForTesting(false); |
| 349 mContextualSearchPanel.setOffsetYForTesting(SEARCH_PANEL_ALMOST_MAXIMIZE
D_OFFSET_Y_DP); |
| 350 } |
| 351 |
| 352 /** |
| 353 * Positions the SearchPanel in the maximized state. |
| 354 */ |
| 355 private void positionSearchPanelInMaximizedState() { |
| 356 mContextualSearchPanel.setMaximizedForTesting(true); |
| 357 mContextualSearchPanel.setOffsetYForTesting(0); |
| 358 } |
| 359 |
| 360 /** |
| 361 * Sets the vertical scroll position of the SearchContentView. |
| 362 * @param searchContentViewVerticalScroll The vertical scroll position. |
| 363 */ |
| 364 private void setSearchContentViewVerticalScroll(float searchContentViewVerti
calScroll) { |
| 365 mSearchContentViewVerticalScroll = searchContentViewVerticalScroll; |
| 366 } |
| 367 |
| 368 /** |
| 369 * Simulates a MotionEvent in the ContextualSearchEventFilter. |
| 370 * @param action The event's action. |
| 371 * @param x The event's x coordinate in dps. |
| 372 * @param y The event's y coordinate in dps. |
| 373 */ |
| 374 private void simulateEvent(int action, float x, float y) { |
| 375 MotionEvent motionEvent = MotionEvent.obtain(0, 0, action, x * mDpToPx,
y * mDpToPx, 0); |
| 376 mEventFilter.onTouchEventInternal(motionEvent); |
| 377 } |
| 378 |
| 379 /** |
| 380 * Simulates a MotionEvent.ACTION_DOWN in the ContextualSearchEventFilter. |
| 381 * @param x The event's x coordinate in dps. |
| 382 * @param y The event's y coordinate in dps. |
| 383 */ |
| 384 private void simulateActionDownEvent(float x, float y) { |
| 385 simulateEvent(MotionEvent.ACTION_DOWN, x, y); |
| 386 } |
| 387 |
| 388 /** |
| 389 * Simulates a MotionEvent.ACTION_MOVE in the ContextualSearchEventFilter. |
| 390 * @param x The event's x coordinate in dps. |
| 391 * @param y The event's y coordinate in dps. |
| 392 */ |
| 393 private void simulateActionMoveEvent(float x, float y) { |
| 394 simulateEvent(MotionEvent.ACTION_MOVE, x, y); |
| 395 } |
| 396 |
| 397 /** |
| 398 * Simulates a MotionEvent.ACTION_UP in the ContextualSearchEventFilter. |
| 399 * @param x The event's x coordinate in dps. |
| 400 * @param y The event's y coordinate in dps. |
| 401 */ |
| 402 private void simulateActionUpEvent(float x, float y) { |
| 403 simulateEvent(MotionEvent.ACTION_UP, x, y); |
| 404 } |
| 405 |
| 406 // -------------------------------------------------------------------------
------------------- |
| 407 // SearchPanel GestureHandler |
| 408 // -------------------------------------------------------------------------
------------------- |
| 409 |
| 410 @Override |
| 411 public void onDown(float x, float y) {} |
| 412 |
| 413 @Override |
| 414 public void onUpOrCancel() {} |
| 415 |
| 416 @Override |
| 417 public void drag(float x, float y, float dx, float dy, float tx, float ty) { |
| 418 mWasScrollDetectedOnSearchPanel = true; |
| 419 } |
| 420 |
| 421 @Override |
| 422 public void click(float x, float y) { |
| 423 mWasTapDetectedOnSearchPanel = true; |
| 424 } |
| 425 |
| 426 @Override |
| 427 public void fling(float x, float y, float velocityX, float velocityY) {} |
| 428 |
| 429 @Override |
| 430 public void onLongPress(float x, float y) {} |
| 431 |
| 432 @Override |
| 433 public void onPinch(float x0, float y0, float x1, float y1, boolean firstEve
nt) {} |
| 434 } |
OLD | NEW |