blob: 6ca4d30b9db5dc36b35f4ed9496972688449ba5b [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.test;
import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
import static org.chromium.chrome.browser.ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.view.ViewGroup;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.BottomSheetContent;
import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.StateChangeReason;
import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
/**
* Junit4 rule for tests testing the bottom sheet. This rule creates a new, separate bottom sheet
* to test with.
*/
@CommandLineFlags.Add({DISABLE_FIRST_RUN_EXPERIENCE})
public class BottomSheetTestRule extends ChromeTabbedActivityTestRule {
/** An observer used to record events that occur with respect to the bottom sheet. */
public static class Observer extends EmptyBottomSheetObserver {
/** A {@link CallbackHelper} that can wait for the bottom sheet to be closed. */
public final CallbackHelper mClosedCallbackHelper = new CallbackHelper();
/** A {@link CallbackHelper} that can wait for the bottom sheet to be opened. */
public final CallbackHelper mOpenedCallbackHelper = new CallbackHelper();
/** A {@link CallbackHelper} that can wait for the onTransitionPeekToHalf event. */
public final CallbackHelper mPeekToHalfCallbackHelper = new CallbackHelper();
/** A {@link CallbackHelper} that can wait for the onOffsetChanged event. */
public final CallbackHelper mOffsetChangedCallbackHelper = new CallbackHelper();
/** A {@link CallbackHelper} that can wait for the onSheetContentChanged event. */
public final CallbackHelper mContentChangedCallbackHelper = new CallbackHelper();
/** The last value that the onTransitionPeekToHalf event sent. */
private float mLastPeekToHalfValue;
/** The last value that the onOffsetChanged event sent. */
private float mLastOffsetChangedValue;
@Override
public void onTransitionPeekToHalf(float fraction) {
mLastPeekToHalfValue = fraction;
mPeekToHalfCallbackHelper.notifyCalled();
}
@Override
public void onSheetOffsetChanged(float heightFraction, float offsetPx) {
mLastOffsetChangedValue = heightFraction;
mOffsetChangedCallbackHelper.notifyCalled();
}
@Override
public void onSheetOpened(@StateChangeReason int reason) {
mOpenedCallbackHelper.notifyCalled();
}
@Override
public void onSheetClosed(@StateChangeReason int reason) {
mClosedCallbackHelper.notifyCalled();
}
@Override
public void onSheetContentChanged(BottomSheetContent newContent) {
mContentChangedCallbackHelper.notifyCalled();
}
/** @return The last value passed in to {@link #onTransitionPeekToHalf(float)}. */
public float getLastPeekToHalfValue() {
return mLastPeekToHalfValue;
}
/** @return The last value passed in to {@link #onSheetOffsetChanged(float)}. */
public float getLastOffsetChangedValue() {
return mLastOffsetChangedValue;
}
}
/** A bottom sheet to test with. */
private BottomSheet mBottomSheet;
/** A handle to the sheet's observer. */
private Observer mObserver;
private @BottomSheet.SheetState int mStartingBottomSheetState = BottomSheet.SheetState.FULL;
protected void afterStartingActivity() {
TestThreadUtils.runOnUiThreadBlocking(() -> {
ViewGroup coordinator = getActivity().findViewById(R.id.coordinator);
mBottomSheet = getActivity()
.getLayoutInflater()
.inflate(R.layout.bottom_sheet, coordinator)
.findViewById(R.id.bottom_sheet);
mBottomSheet.init(coordinator, getActivity());
});
mObserver = new Observer();
getBottomSheet().addObserver(mObserver);
if (mStartingBottomSheetState == BottomSheet.SheetState.PEEK) return;
setSheetState(mStartingBottomSheetState, /* animate = */ false);
}
public void startMainActivityOnBottomSheet(@BottomSheet.SheetState int startingSheetState)
throws InterruptedException {
mStartingBottomSheetState = startingSheetState;
startMainActivityOnBlankPage();
}
// TODO (aberent): The Chrome test rules currently bypass ActivityTestRule.launchActivity, hence
// don't call beforeActivityLaunched and afterActivityLaunched as defined in the
// ActivityTestRule interface. To work round this override the methods that start activities.
// See https://crbug.com/726444.
@Override
public void startMainActivityOnBlankPage() throws InterruptedException {
super.startMainActivityOnBlankPage();
afterStartingActivity();
}
public Observer getObserver() {
return mObserver;
}
public BottomSheet getBottomSheet() {
return mBottomSheet;
}
/**
* Set the bottom sheet's state on the UI thread.
*
* @param state The state to set the sheet to.
* @param animate If the sheet should animate to the provided state.
*/
public void setSheetState(int state, boolean animate) {
TestThreadUtils.runOnUiThreadBlocking(() -> getBottomSheet().setSheetState(state, animate));
}
/**
* Set the bottom sheet's offset from the bottom of the screen on the UI thread.
*
* @param offset The offset from the bottom that the sheet should be.
*/
public void setSheetOffsetFromBottom(float offset) {
TestThreadUtils.runOnUiThreadBlocking(
() -> getBottomSheet().setSheetOffsetFromBottomForTesting(offset));
}
public BottomSheetContent getBottomSheetContent() {
return getBottomSheet().getCurrentSheetContent();
}
/**
* Wait for an update to start and finish.
*/
public static void waitForWindowUpdates() {
final long maxWindowUpdateTimeMs = scaleTimeout(1000);
UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.waitForWindowUpdate(null, maxWindowUpdateTimeMs);
device.waitForIdle(maxWindowUpdateTimeMs);
}
}