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.compositor.layouts; |
| 6 |
| 7 import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_E
ND_DEVICE; |
| 8 import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_PHONE; |
| 9 |
| 10 import android.content.Context; |
| 11 import android.graphics.PointF; |
| 12 import android.test.suitebuilder.annotation.SmallTest; |
| 13 import android.util.Log; |
| 14 import android.view.MotionEvent; |
| 15 import android.view.MotionEvent.PointerCoords; |
| 16 import android.view.MotionEvent.PointerProperties; |
| 17 import android.widget.FrameLayout; |
| 18 |
| 19 import org.chromium.base.ThreadUtils; |
| 20 import org.chromium.base.library_loader.LibraryProcessType; |
| 21 import org.chromium.base.library_loader.ProcessInitException; |
| 22 import org.chromium.base.test.util.Feature; |
| 23 import org.chromium.base.test.util.Restriction; |
| 24 import org.chromium.chrome.browser.Tab; |
| 25 import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; |
| 26 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeEvent
Filter.ScrollDirection; |
| 27 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandl
er; |
| 28 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter; |
| 29 import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; |
| 30 import org.chromium.chrome.browser.compositor.layouts.phone.stack.Stack; |
| 31 import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackTab; |
| 32 import org.chromium.chrome.browser.tab.ChromeTab; |
| 33 import org.chromium.chrome.browser.tabmodel.TabModel; |
| 34 import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
| 35 import org.chromium.chrome.browser.tabmodel.TabModelUtils; |
| 36 import org.chromium.chrome.browser.util.MathUtils; |
| 37 import org.chromium.chrome.test.RestrictedInstrumentationTestCase; |
| 38 import org.chromium.chrome.test.util.browser.tabmodel.MockTabModel.MockTabModelD
elegate; |
| 39 import org.chromium.chrome.test.util.browser.tabmodel.MockTabModelSelector; |
| 40 import org.chromium.content.browser.BrowserStartupController; |
| 41 |
| 42 /** |
| 43 * Unit tests for {@link org.chromium.chrome.browser.compositor.layouts.LayoutMa
nagerChrome} |
| 44 */ |
| 45 public class LayoutManagerTest extends RestrictedInstrumentationTestCase |
| 46 implements MockTabModelDelegate { |
| 47 private static final String TAG = "LayoutManagerTest"; |
| 48 |
| 49 private long mLastDownTime = 0; |
| 50 |
| 51 private TabModelSelector mTabModelSelector; |
| 52 private LayoutManagerChrome mManager; |
| 53 private LayoutManagerChromePhone mManagerPhone; |
| 54 |
| 55 private final PointerProperties[] mProperties = new PointerProperties[2]; |
| 56 private final PointerCoords[] mPointerCoords = new PointerCoords[2]; |
| 57 |
| 58 private float mDpToPx; |
| 59 |
| 60 private void initializeMotionEvent() { |
| 61 mProperties[0] = new PointerProperties(); |
| 62 mProperties[0].id = 0; |
| 63 mProperties[0].toolType = MotionEvent.TOOL_TYPE_FINGER; |
| 64 mProperties[1] = new PointerProperties(); |
| 65 mProperties[1].id = 1; |
| 66 mProperties[1].toolType = MotionEvent.TOOL_TYPE_FINGER; |
| 67 |
| 68 mPointerCoords[0] = new PointerCoords(); |
| 69 mPointerCoords[0].x = 0; |
| 70 mPointerCoords[0].y = 0; |
| 71 mPointerCoords[0].pressure = 1; |
| 72 mPointerCoords[0].size = 1; |
| 73 mPointerCoords[1] = new PointerCoords(); |
| 74 mPointerCoords[1].x = 0; |
| 75 mPointerCoords[1].y = 0; |
| 76 mPointerCoords[1].pressure = 1; |
| 77 mPointerCoords[1].size = 1; |
| 78 } |
| 79 |
| 80 /** |
| 81 * Simulates time so the animation updates. |
| 82 * @param layoutManager The {@link LayoutManagerChrome} to update. |
| 83 * @param maxFrameCount The maximum number of frames to simulate before the
motion ends. |
| 84 * @return Whether the maximum number of frames was enough for
the |
| 85 * {@link LayoutManagerChrome} to reach the end of the
animations. |
| 86 */ |
| 87 private static boolean simulateTime(LayoutManagerChrome layoutManager, int m
axFrameCount) { |
| 88 // Simulating time |
| 89 int frame = 0; |
| 90 long time = 0; |
| 91 final long dt = 16; |
| 92 while (layoutManager.onUpdate(time, dt) && frame < maxFrameCount) { |
| 93 time += dt; |
| 94 frame++; |
| 95 } |
| 96 Log.w(TAG, "simulateTime frame " + frame); |
| 97 return frame < maxFrameCount; |
| 98 } |
| 99 |
| 100 private void initializeLayoutManagerPhone(int standardTabCount, int incognit
oTabCount) { |
| 101 initializeLayoutManagerPhone(standardTabCount, incognitoTabCount, |
| 102 TabModel.INVALID_TAB_INDEX, TabModel.INVALID_TAB_INDEX, false); |
| 103 } |
| 104 |
| 105 private void initializeLayoutManagerPhone(int standardTabCount, int incognit
oTabCount, |
| 106 int standardIndexSelected, int incognitoIndexSelected, boolean incog
nitoSelected) { |
| 107 Context context = new MockContextForLayout(getInstrumentation().getConte
xt()); |
| 108 |
| 109 mDpToPx = context.getResources().getDisplayMetrics().density; |
| 110 |
| 111 mTabModelSelector = new MockTabModelSelector(standardTabCount, incognito
TabCount, this); |
| 112 if (standardIndexSelected != TabModel.INVALID_TAB_INDEX) { |
| 113 TabModelUtils.setIndex(mTabModelSelector.getModel(false), standardIn
dexSelected); |
| 114 } |
| 115 if (incognitoIndexSelected != TabModel.INVALID_TAB_INDEX) { |
| 116 TabModelUtils.setIndex(mTabModelSelector.getModel(true), incognitoIn
dexSelected); |
| 117 } |
| 118 mTabModelSelector.selectModel(incognitoSelected); |
| 119 LayoutManagerHost layoutManagerHost = new MockLayoutHost(context); |
| 120 |
| 121 // Build a fake content container |
| 122 FrameLayout parentContainer = new FrameLayout(context); |
| 123 FrameLayout container = new FrameLayout(context); |
| 124 parentContainer.addView(container); |
| 125 |
| 126 mManagerPhone = new LayoutManagerChromePhone( |
| 127 layoutManagerHost, new LayoutManagerChromePhone.OverviewLayoutFa
ctoryDelegate() { |
| 128 @Override |
| 129 public Layout createOverviewLayout(Context context, LayoutUp
dateHost updateHost, |
| 130 LayoutRenderHost renderHost, EventFilter eventFilter
) { |
| 131 return new StackLayout(context, updateHost, renderHost,
eventFilter); |
| 132 } |
| 133 }); |
| 134 mManager = mManagerPhone; |
| 135 mManager.init(mTabModelSelector, null, null, container, null, null); |
| 136 initializeMotionEvent(); |
| 137 } |
| 138 |
| 139 private void eventDown(long time, PointF p) { |
| 140 mLastDownTime = time; |
| 141 |
| 142 mPointerCoords[0].x = p.x * mDpToPx; |
| 143 mPointerCoords[0].y = p.y * mDpToPx; |
| 144 |
| 145 MotionEvent event = MotionEvent.obtain(mLastDownTime, time, MotionEvent.
ACTION_DOWN, |
| 146 1, mProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, 0, 0); |
| 147 assertTrue("Down event not intercepted", mManager.onInterceptTouchEvent(
event, false)); |
| 148 assertTrue("Down event not handled", mManager.onTouchEvent(event)); |
| 149 } |
| 150 |
| 151 private void eventDown1(long time, PointF p) { |
| 152 mPointerCoords[1].x = p.x * mDpToPx; |
| 153 mPointerCoords[1].y = p.y * mDpToPx; |
| 154 |
| 155 assertTrue("Down_1 event not handled", mManager.onTouchEvent( |
| 156 MotionEvent.obtain(mLastDownTime, time, |
| 157 MotionEvent.ACTION_POINTER_DOWN | (0x1 << MotionEvent.ACTION_POI
NTER_INDEX_SHIFT), |
| 158 2, mProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, 0, 0))); |
| 159 } |
| 160 |
| 161 private void eventMove(long time, PointF p) { |
| 162 mPointerCoords[0].x = p.x * mDpToPx; |
| 163 mPointerCoords[0].y = p.y * mDpToPx; |
| 164 |
| 165 assertTrue("Move event not handled", mManager.onTouchEvent( |
| 166 MotionEvent.obtain(mLastDownTime, time, MotionEvent.ACTION_MOVE, |
| 167 1, mProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, 0, 0))); |
| 168 } |
| 169 |
| 170 private void eventUp(long time, PointF p) { |
| 171 mPointerCoords[0].x = p.x * mDpToPx; |
| 172 mPointerCoords[0].y = p.y * mDpToPx; |
| 173 |
| 174 assertTrue("Up event not handled", mManager.onTouchEvent( |
| 175 MotionEvent.obtain(mLastDownTime, time, MotionEvent.ACTION_UP, |
| 176 1, mProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, 0, 0))); |
| 177 } |
| 178 |
| 179 private void eventUp1(long time, PointF p) { |
| 180 mPointerCoords[1].x = p.x * mDpToPx; |
| 181 mPointerCoords[1].y = p.y * mDpToPx; |
| 182 |
| 183 assertTrue("Up_1 event not handled", mManager.onTouchEvent( |
| 184 MotionEvent.obtain(mLastDownTime, time, |
| 185 MotionEvent.ACTION_POINTER_UP | (0x1 << MotionEvent.ACTION_POINT
ER_INDEX_SHIFT), |
| 186 2, mProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, 0, 0))); |
| 187 } |
| 188 |
| 189 private void eventMoveBoth(long time, PointF p0, PointF p1) { |
| 190 mPointerCoords[0].x = p0.x * mDpToPx; |
| 191 mPointerCoords[0].y = p0.y * mDpToPx; |
| 192 mPointerCoords[1].x = p1.x * mDpToPx; |
| 193 mPointerCoords[1].y = p1.y * mDpToPx; |
| 194 |
| 195 assertTrue("Move event not handled", mManager.onTouchEvent( |
| 196 MotionEvent.obtain(mLastDownTime, time, MotionEvent.ACTION_MOVE,
2, |
| 197 mProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, 0, 0))); |
| 198 } |
| 199 |
| 200 @SmallTest |
| 201 @Feature({"Android-TabSwitcher"}) |
| 202 @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE}) |
| 203 public void testCreation() { |
| 204 initializeLayoutManagerPhone(0, 0); |
| 205 } |
| 206 |
| 207 @SmallTest |
| 208 @Feature({"Android-TabSwitcher"}) |
| 209 @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE}) |
| 210 public void testStack() throws Exception { |
| 211 initializeLayoutManagerPhone(3, 0); |
| 212 mManagerPhone.showOverview(true); |
| 213 assertTrue("layoutManager is way too long to end motion", simulateTime(m
Manager, 1000)); |
| 214 assertTrue("The activate layout type is expected to be StackLayout", |
| 215 mManager.getActiveLayout() instanceof StackLayout); |
| 216 mManagerPhone.hideOverview(true); |
| 217 assertTrue("layoutManager is way too long to end motion", simulateTime(m
Manager, 1000)); |
| 218 } |
| 219 |
| 220 @SmallTest |
| 221 @Feature({"Android-TabSwitcher"}) |
| 222 @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE}) |
| 223 public void testStackNoAnimation() throws Exception { |
| 224 initializeLayoutManagerPhone(1, 0); |
| 225 mManagerPhone.showOverview(false); |
| 226 assertTrue("The activate layout type is expected to be StackLayout", |
| 227 mManager.getActiveLayout() instanceof StackLayout); |
| 228 mManagerPhone.hideOverview(false); |
| 229 } |
| 230 |
| 231 /** |
| 232 * Tests the tab pinching behavior with two finger. |
| 233 * This test is still under development. |
| 234 */ |
| 235 @SmallTest |
| 236 @Feature({"Android-TabSwitcher"}) |
| 237 @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE}) |
| 238 public void testStackPinch() throws Exception { |
| 239 initializeLayoutManagerPhone(5, 0); |
| 240 // Setting the index to the second to last element ensure the stack can
be scrolled in both |
| 241 // directions. |
| 242 mManager.tabSelected(mTabModelSelector.getCurrentModel().getTabAt(3).get
Id(), |
| 243 Tab.INVALID_TAB_ID, false); |
| 244 |
| 245 mManagerPhone.showOverview(false); |
| 246 // Basic verifications |
| 247 assertTrue("The activate layout type is expected to be StackLayout", |
| 248 mManager.getActiveLayout() instanceof StackLayout); |
| 249 |
| 250 StackLayout layout = (StackLayout) mManager.getActiveLayout(); |
| 251 Stack stack = layout.getTabStack(false); |
| 252 StackTab[] tabs = stack.getTabs(); |
| 253 |
| 254 long time = 0; |
| 255 // At least one update is necessary to get updated positioning of Layout
Tabs. |
| 256 mManager.onUpdate(time, 16); |
| 257 time++; |
| 258 |
| 259 LayoutTab tab1 = tabs[1].getLayoutTab(); |
| 260 LayoutTab tab3 = tabs[3].getLayoutTab(); |
| 261 |
| 262 float fingerOffset = Math.min(tab1.getClippedHeight() / 2, tab3.getClipp
edHeight() / 2); |
| 263 |
| 264 PointF finger0 = new PointF(tab1.getX() + tab1.getFinalContentWidth() /
2, |
| 265 tab1.getY() + fingerOffset); |
| 266 |
| 267 // Initiate finger 0 |
| 268 eventDown(time, finger0); |
| 269 mManager.onUpdate(time, 16); |
| 270 time++; |
| 271 |
| 272 // Move finger 0: Y to simulate a scroll |
| 273 final float scrollOffset1 = (tab3.getY() - tab1.getY()) / 8.0f; |
| 274 finger0.y += scrollOffset1; |
| 275 |
| 276 eventMove(time, finger0); |
| 277 mManager.onUpdate(time, 16); |
| 278 time++; |
| 279 |
| 280 finger0.y -= scrollOffset1; |
| 281 |
| 282 eventMove(time, finger0); |
| 283 mManager.onUpdate(time, 16); |
| 284 time++; |
| 285 |
| 286 float expectedTab1X = tab1.getX(); |
| 287 float expectedTab1Y = tab1.getY(); |
| 288 |
| 289 // Initiate the pinch with finger 1 |
| 290 PointF finger1 = new PointF(tab3.getX() + tab3.getFinalContentWidth() /
2, |
| 291 tab3.getY() + fingerOffset); |
| 292 eventDown1(time, finger1); |
| 293 mManager.onUpdate(time, 16); |
| 294 time++; |
| 295 |
| 296 final float delta = 0.001f; |
| 297 assertEquals("Wrong x offset for tab 1", expectedTab1X, tab1.getX(), del
ta); |
| 298 assertEquals("Wrong y offset for tab 1", expectedTab1Y, tab1.getY(), del
ta); |
| 299 float expectedTab3X = tab3.getX(); |
| 300 float expectedTab3Y = tab3.getY(); |
| 301 |
| 302 // Move Finger 0: Y only |
| 303 finger0.y += scrollOffset1; |
| 304 expectedTab1Y += scrollOffset1; |
| 305 |
| 306 eventMoveBoth(time, finger0, finger1); |
| 307 mManager.onUpdate(time, 16); |
| 308 time++; |
| 309 |
| 310 assertEquals("Wrong x offset for tab 1", expectedTab1X, tab1.getX(), del
ta); |
| 311 assertEquals("Wrong y offset for tab 1", expectedTab1Y, tab1.getY(), del
ta); |
| 312 assertEquals("Wrong x offset for tab 3", expectedTab3X, tab3.getX(), del
ta); |
| 313 assertEquals("Wrong y offset for tab 3", expectedTab3Y, tab3.getY(), del
ta); |
| 314 |
| 315 // Move finger 0: Y and X |
| 316 finger0.y += scrollOffset1; |
| 317 finger0.x += tab1.getFinalContentWidth() / 8.0f; |
| 318 expectedTab1Y += scrollOffset1; |
| 319 |
| 320 eventMoveBoth(time, finger0, finger1); |
| 321 mManager.onUpdate(time, 16); |
| 322 time++; |
| 323 |
| 324 assertEquals("Wrong x offset for tab 1", expectedTab1X, tab1.getX(), del
ta); |
| 325 assertEquals("Wrong y offset for tab 1", expectedTab1Y, tab1.getY(), del
ta); |
| 326 assertEquals("Wrong x offset for tab 3", expectedTab3X, tab3.getX(), del
ta); |
| 327 assertEquals("Wrong y offset for tab 3", expectedTab3Y, tab3.getY(), del
ta); |
| 328 |
| 329 // Move finger 1: Y and X |
| 330 final float scrollOffset3 = (tab3.getY() - layout.getHeight()) / 8.0f; |
| 331 finger1.y += scrollOffset3; |
| 332 finger1.x += tab3.getFinalContentWidth() / 8.0f; |
| 333 expectedTab3Y += scrollOffset3; |
| 334 |
| 335 eventMoveBoth(time, finger0, finger1); |
| 336 mManager.onUpdate(time, 16); |
| 337 time++; |
| 338 |
| 339 assertEquals("Wrong x offset for tab 1", expectedTab1X, tab1.getX(), del
ta); |
| 340 assertEquals("Wrong y offset for tab 1", expectedTab1Y, tab1.getY(), del
ta); |
| 341 assertEquals("Wrong x offset for tab 3", expectedTab3X, tab3.getX(), del
ta); |
| 342 assertEquals("Wrong y offset for tab 3", expectedTab3Y, tab3.getY(), del
ta); |
| 343 |
| 344 // Move finger 0 and 1: Y and X |
| 345 finger0.y += scrollOffset1; |
| 346 finger0.x += tab1.getFinalContentWidth() / 8.0f; |
| 347 expectedTab1Y += scrollOffset1; |
| 348 finger1.y += scrollOffset3; |
| 349 finger1.x += tab3.getFinalContentWidth() / 8.0f; |
| 350 expectedTab3Y += scrollOffset3; |
| 351 |
| 352 eventMoveBoth(time, finger0, finger1); |
| 353 mManager.onUpdate(time, 16); |
| 354 time++; |
| 355 |
| 356 assertEquals("Wrong x offset for tab 1", expectedTab1X, tab1.getX(), del
ta); |
| 357 assertEquals("Wrong y offset for tab 1", expectedTab1Y, tab1.getY(), del
ta); |
| 358 assertEquals("Wrong x offset for tab 3", expectedTab3X, tab3.getX(), del
ta); |
| 359 assertEquals("Wrong y offset for tab 3", expectedTab3Y, tab3.getY(), del
ta); |
| 360 |
| 361 // Done |
| 362 eventUp1(time, finger1); |
| 363 eventUp(time, finger0); |
| 364 |
| 365 assertEquals("Wrong x offset for tab 1", expectedTab1X, tab1.getX(), del
ta); |
| 366 assertEquals("Wrong y offset for tab 1", expectedTab1Y, tab1.getY(), del
ta); |
| 367 assertEquals("Wrong x offset for tab 3", expectedTab3X, tab3.getX(), del
ta); |
| 368 assertEquals("Wrong y offset for tab 3", expectedTab3Y, tab3.getY(), del
ta); |
| 369 |
| 370 mManagerPhone.hideOverview(false); |
| 371 } |
| 372 |
| 373 @SmallTest |
| 374 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 375 @Feature({"Android-TabSwitcher"}) |
| 376 public void testToolbarSideSwipeOnlyTab() throws Exception { |
| 377 initializeLayoutManagerPhone(1, 0, 0, TabModel.INVALID_TAB_INDEX, false)
; |
| 378 assertEquals(mTabModelSelector.getModel(false).index(), 0); |
| 379 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 0); |
| 380 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0); |
| 381 } |
| 382 |
| 383 @SmallTest |
| 384 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 385 @Feature({"Android-TabSwitcher"}) |
| 386 public void testToolbarSideSwipeOnlyTabIncognito() throws Exception { |
| 387 initializeLayoutManagerPhone(0, 1, TabModel.INVALID_TAB_INDEX, 0, true); |
| 388 assertEquals(mTabModelSelector.getModel(true).index(), 0); |
| 389 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 0); |
| 390 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0); |
| 391 } |
| 392 |
| 393 @SmallTest |
| 394 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 395 @Feature({"Android-TabSwitcher"}) |
| 396 public void testToolbarSideSwipeNextTab() throws Exception { |
| 397 initializeLayoutManagerPhone(2, 0, 0, TabModel.INVALID_TAB_INDEX, false)
; |
| 398 assertEquals(mTabModelSelector.getModel(false).index(), 0); |
| 399 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 1); |
| 400 } |
| 401 |
| 402 @SmallTest |
| 403 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 404 @Feature({"Android-TabSwitcher"}) |
| 405 public void testToolbarSideSwipePrevTab() throws Exception { |
| 406 initializeLayoutManagerPhone(2, 0, 1, TabModel.INVALID_TAB_INDEX, false)
; |
| 407 assertEquals(mTabModelSelector.getModel(false).index(), 1); |
| 408 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0); |
| 409 } |
| 410 |
| 411 @SmallTest |
| 412 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 413 @Feature({"Android-TabSwitcher"}) |
| 414 public void testToolbarSideSwipeNextTabNone() throws Exception { |
| 415 initializeLayoutManagerPhone(2, 0, 1, TabModel.INVALID_TAB_INDEX, false)
; |
| 416 assertEquals(mTabModelSelector.getModel(false).index(), 1); |
| 417 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 1); |
| 418 } |
| 419 |
| 420 @SmallTest |
| 421 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 422 @Feature({"Android-TabSwitcher"}) |
| 423 public void testToolbarSideSwipePrevTabNone() throws Exception { |
| 424 initializeLayoutManagerPhone(2, 0, 0, TabModel.INVALID_TAB_INDEX, false)
; |
| 425 assertEquals(mTabModelSelector.getModel(false).index(), 0); |
| 426 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0); |
| 427 } |
| 428 |
| 429 @SmallTest |
| 430 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 431 @Feature({"Android-TabSwitcher"}) |
| 432 public void testToolbarSideSwipeNextTabIncognito() throws Exception { |
| 433 initializeLayoutManagerPhone(0, 2, TabModel.INVALID_TAB_INDEX, 0, true); |
| 434 assertEquals(mTabModelSelector.getModel(true).index(), 0); |
| 435 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 1); |
| 436 } |
| 437 |
| 438 @SmallTest |
| 439 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 440 @Feature({"Android-TabSwitcher"}) |
| 441 public void testToolbarSideSwipePrevTabIncognito() throws Exception { |
| 442 initializeLayoutManagerPhone(0, 2, TabModel.INVALID_TAB_INDEX, 1, true); |
| 443 assertEquals(mTabModelSelector.getModel(true).index(), 1); |
| 444 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0); |
| 445 } |
| 446 |
| 447 @SmallTest |
| 448 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 449 @Feature({"Android-TabSwitcher"}) |
| 450 public void testToolbarSideSwipeNextTabNoneIncognito() throws Exception { |
| 451 initializeLayoutManagerPhone(0, 2, TabModel.INVALID_TAB_INDEX, 1, true); |
| 452 assertEquals(mTabModelSelector.getModel(true).index(), 1); |
| 453 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 1); |
| 454 } |
| 455 |
| 456 @SmallTest |
| 457 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) |
| 458 @Feature({"Android-TabSwitcher"}) |
| 459 public void testToolbarSideSwipePrevTabNoneIncognito() throws Exception { |
| 460 initializeLayoutManagerPhone(0, 2, TabModel.INVALID_TAB_INDEX, 0, true); |
| 461 assertEquals(mTabModelSelector.getModel(true).index(), 0); |
| 462 runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0); |
| 463 } |
| 464 |
| 465 @Override |
| 466 protected void setUp() throws Exception { |
| 467 super.setUp(); |
| 468 |
| 469 // Load the browser process. |
| 470 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 471 @Override |
| 472 public void run() { |
| 473 try { |
| 474 BrowserStartupController.get( |
| 475 getInstrumentation().getTargetContext(), |
| 476 LibraryProcessType.PROCESS_BROWSER) |
| 477 .startBrowserProcessesSync(false); |
| 478 } catch (ProcessInitException e) { |
| 479 fail("Failed to load browser"); |
| 480 } |
| 481 } |
| 482 }); |
| 483 } |
| 484 |
| 485 private void runToolbarSideSwipeTestOnCurrentModel(ScrollDirection direction
, int finalIndex) { |
| 486 final TabModel model = mTabModelSelector.getCurrentModel(); |
| 487 final int finalId = model.getTabAt(finalIndex).getId(); |
| 488 |
| 489 performToolbarSideSwipe(direction); |
| 490 |
| 491 assertEquals("Unexpected model change after side swipe", model.isIncogni
to(), |
| 492 mTabModelSelector.isIncognitoSelected()); |
| 493 |
| 494 assertEquals("Wrong index after side swipe", finalIndex, model.index()); |
| 495 assertEquals("Wrong current tab id", finalId, TabModelUtils.getCurrentTa
b(model).getId()); |
| 496 assertTrue("LayoutManager#getActiveLayout() should be StaticLayout", |
| 497 mManager.getActiveLayout() instanceof StaticLayout); |
| 498 } |
| 499 |
| 500 private void performToolbarSideSwipe(ScrollDirection direction) { |
| 501 assertTrue("Unexpected direction for side swipe " + direction, |
| 502 direction == ScrollDirection.LEFT || direction == ScrollDirectio
n.RIGHT); |
| 503 |
| 504 final Layout layout = mManager.getActiveLayout(); |
| 505 final EdgeSwipeHandler eventHandler = mManager.getTopSwipeHandler(); |
| 506 |
| 507 assertNotNull("LayoutManager#getTopSwipeHandler() returned null", eventH
andler); |
| 508 assertNotNull("LayoutManager#getActiveLayout() returned null", layout); |
| 509 |
| 510 final float layoutWidth = layout.getWidth(); |
| 511 final boolean scrollLeft = direction == ScrollDirection.LEFT; |
| 512 final float deltaX = MathUtils.flipSignIf(layoutWidth / 2.f, scrollLeft)
; |
| 513 |
| 514 eventHandler.swipeStarted(direction, layoutWidth, 0); |
| 515 eventHandler.swipeUpdated(deltaX, 0.f, deltaX, 0.f, deltaX, 0.f); |
| 516 eventHandler.swipeFinished(); |
| 517 |
| 518 assertTrue("LayoutManager#getActiveLayout() should be ToolbarSwipeLayout
", |
| 519 mManager.getActiveLayout() instanceof ToolbarSwipeLayout); |
| 520 assertTrue("LayoutManager took too long to finish the animations", |
| 521 simulateTime(mManager, 1000)); |
| 522 } |
| 523 |
| 524 @Override |
| 525 public Tab createTab(int id, boolean incognito) { |
| 526 return new ChromeTab(id, incognito); |
| 527 } |
| 528 } |
OLD | NEW |