SwipeDismissFrameLayoutTest.java revision d5fc393a5aa24693d35b5ebd6d588613103aafdc
10bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska/*
20bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * Copyright (C) 2017 The Android Open Source Project
30bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska *
40bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * Licensed under the Apache License, Version 2.0 (the "License");
50bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * you may not use this file except in compliance with the License.
60bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * You may obtain a copy of the License at
70bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska *
80bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska *      http://www.apache.org/licenses/LICENSE-2.0
90bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska *
100bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * Unless required by applicable law or agreed to in writing, software
110bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * distributed under the License is distributed on an "AS IS" BASIS,
120bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * See the License for the specific language governing permissions and
140bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska * limitations under the License.
150bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska */
160bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
170bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskapackage android.support.wearable.view;
180bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
190bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static android.support.test.espresso.Espresso.onView;
200bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static android.support.test.espresso.action.ViewActions.swipeRight;
210bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
220bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static android.support.test.espresso.matcher.ViewMatchers.withId;
230bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static android.support.wearable.view.util.AsyncViewActions.waitForMatchingView;
24d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurskaimport static android.support.wearable.view.util.MoreViewAssertions.withPositiveVerticalScrollOffset;
250bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static android.support.wearable.view.util.MoreViewAssertions.withTranslationX;
260bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
270bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static org.hamcrest.Matchers.allOf;
280bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static org.junit.Assert.assertFalse;
290bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport static org.junit.Assert.assertTrue;
300bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
310bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.app.Activity;
320bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.content.Intent;
33d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurskaimport android.graphics.RectF;
340bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.annotation.IdRes;
350bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.InstrumentationRegistry;
360bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.espresso.ViewAction;
370bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.espresso.action.GeneralLocation;
380bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.espresso.action.GeneralSwipeAction;
390bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.espresso.action.Press;
400bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.espresso.action.Swipe;
410bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.espresso.matcher.ViewMatchers;
420bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.filters.SmallTest;
430bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.rule.ActivityTestRule;
440bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.test.runner.AndroidJUnit4;
450bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.wearable.test.R;
46d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurskaimport android.support.wearable.view.util.ArcSwipe;
470bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.support.wearable.view.util.WakeLockRule;
480bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport android.view.View;
490bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
500bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport org.junit.Rule;
510bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport org.junit.Test;
520bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskaimport org.junit.runner.RunWith;
530bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
540bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska@RunWith(AndroidJUnit4.class)
550bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurskapublic class SwipeDismissFrameLayoutTest {
560bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
570bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private static final long MAX_WAIT_TIME = 4000; //ms
580bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private final SwipeDismissFrameLayout.Callback mDismissCallback = new DismissCallback();
590bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
600bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Rule
610bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public final WakeLockRule wakeLock = new WakeLockRule();
620bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
630bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Rule
640bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public final ActivityTestRule<SwipeDismissFrameLayoutTestActivity> activityRule =
650bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            new ActivityTestRule<>(
660bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                    SwipeDismissFrameLayoutTestActivity.class,
670bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                    true, /** initial touch mode */
680bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                    false /** launchActivity */
690bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            );
700bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
710bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private int mLayoutWidth;
72d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    private int mLayoutHeight;
730bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
740bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
750bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
760bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testCanScrollHorizontally() {
770bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout
780bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSimpleLayout();
790bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        Activity activity = activityRule.getActivity();
800bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        SwipeDismissFrameLayout testLayout =
810bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
820bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we check that the layout is horizontally scrollable from left to right.
830bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is found to be horizontally swipeable from left to right.
840bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertTrue(testLayout.canScrollHorizontally(-20));
850bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // AND the layout is found to NOT be horizontally swipeable from right to left.
860bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertFalse(testLayout.canScrollHorizontally(20));
870bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
880bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we switch off the swipe-to-dismiss functionality for the layout
890bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        testLayout.setSwipeable(false);
900bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is found NOT to be horizontally swipeable from left to right.
910bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertFalse(testLayout.canScrollHorizontally(-20));
920bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // AND the layout is found to NOT be horizontally swipeable from right to left.
930bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertFalse(testLayout.canScrollHorizontally(20));
940bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
950bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
960bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
970bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
980bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void canScrollHorizontallyShouldBeFalseWhenInvisible() {
990bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout
1000bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSimpleLayout();
1010bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        Activity activity = activityRule.getActivity();
1020bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        final SwipeDismissFrameLayout testLayout =
1030bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
1040bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN the layout is invisible
1050bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // Note: We have to run this on the main thread, because of thread checks in View.java.
1060bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
1070bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            @Override
1080bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            public void run() {
1090bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                testLayout.setVisibility(View.INVISIBLE);
1100bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            }
1110bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        });
1120bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we check that the layout is horizontally scrollable
1130bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is found to be NOT horizontally swipeable from left to right.
1140bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertFalse(testLayout.canScrollHorizontally(-20));
1150bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // AND the layout is found to NOT be horizontally swipeable from right to left.
1160bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertFalse(testLayout.canScrollHorizontally(20));
1170bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
1180bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
1190bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
1200bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
1210bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void canScrollHorizontallyShouldBeFalseWhenGone() {
1220bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout
1230bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSimpleLayout();
1240bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        Activity activity = activityRule.getActivity();
1250bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        final SwipeDismissFrameLayout testLayout =
1260bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
1270bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN the layout is gone
1280bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // Note: We have to run this on the main thread, because of thread checks in View.java.
1290bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
1300bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            @Override
1310bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            public void run() {
1320bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                testLayout.setVisibility(View.GONE);
1330bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            }
1340bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        });
1350bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we check that the layout is horizontally scrollable
1360bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is found to be NOT horizontally swipeable from left to right.
1370bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertFalse(testLayout.canScrollHorizontally(-20));
1380bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // AND the layout is found to NOT be horizontally swipeable from right to left.
1390bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertFalse(testLayout.canScrollHorizontally(20));
1400bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
1410bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
1420bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
1430bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
1440bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testSwipeDismissEnabledByDefault() {
1450bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout
1460bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSimpleLayout();
1470bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        Activity activity = activityRule.getActivity();
1480bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        SwipeDismissFrameLayout testLayout =
1490bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
1500bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we check that the layout is dismissible
1510bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is find to be dismissible
1520bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertTrue(testLayout.isSwipeable());
1530bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
1540bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
1550bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
1560bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
1570bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testSwipeDismissesViewIfEnabled() {
1580bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout
1590bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSimpleLayout();
1600bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we perform a swipe to dismiss
1610bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(R.id.swipe_dismiss_root)).perform(swipeRight());
1620bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is dismissed
1630bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertDismissed(R.id.swipe_dismiss_root);
1640bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertHidden(R.id.swipe_dismiss_root);
1650bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
1660bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
1670bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
1680bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
1690bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testSwipeDoesNotDismissViewIfDisabled() {
1700bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout with dismiss turned off.
1710bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSimpleLayout();
1720bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        Activity activity = activityRule.getActivity();
1730bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        SwipeDismissFrameLayout testLayout =
1740bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
1750bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        testLayout.setSwipeable(false);
1760bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we perform a swipe to dismiss
1770bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(R.id.swipe_dismiss_root)).perform(swipeRight());
1780bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is not dismissed and not hidden
1790bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertNotHidden(R.id.swipe_dismiss_root);
1800bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
1810bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
1820bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
1830bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
1840bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testAddRemoveCallback() {
1850bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout
1860bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSimpleLayout();
1870bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        Activity activity = activityRule.getActivity();
1880bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        SwipeDismissFrameLayout testLayout =
1890bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
1900bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we remove the swipe callback
1910bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        testLayout.removeCallback(mDismissCallback);
1920bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(R.id.swipe_dismiss_root)).perform(swipeRight());
1930bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is dismissed, but no hidden
1940bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertDismissed(R.id.swipe_dismiss_root);
1950bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertNotHidden(R.id.swipe_dismiss_root);
1960bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
1970bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
1980bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
1990bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
2000bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testSwipeDoesNotDismissViewIfScrollable() {
2010bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout with dismiss turned off.
202d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        setUpSwipeDismissWithHorizontalRecyclerView();
2030bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we perform a swipe to dismiss from the center of the screen.
2040bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(R.id.swipe_dismiss_root)).perform(swipeRightFromCenter());
2050bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is not dismissed and not hidden
2060bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertNotHidden(R.id.swipe_dismiss_root);
2070bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
2080bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
2090bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
2100bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
2110bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testEdgeSwipeDoesDismissViewIfScrollable() {
2120bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout with dismiss turned off.
213d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        setUpSwipeDismissWithHorizontalRecyclerView();
2140bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we perform a swipe to dismiss from the left edge of the screen.
2150bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(R.id.swipe_dismiss_root)).perform(swipeRightFromLeftEdge());
2160bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is dismissed and hidden
2170bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertHidden(R.id.swipe_dismiss_root);
2180bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertDismissed(R.id.swipe_dismiss_root);
2190bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
2200bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
2210bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
2220bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
2230bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testSwipeDoesNotDismissViewIfStartsInWrongPosition() {
2240bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout with dismiss turned on, but only for an
2255504220f38bb0552e1d8def09fb1b9a118264b45Aga Madurska        // inner circle.
2260bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSwipeableRegion();
2270bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we perform a swipe to dismiss from the left edge of the screen.
2280bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(R.id.swipe_dismiss_root)).perform(swipeRightFromLeftEdge());
2290bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is not dismissed and not hidden
2300bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertNotHidden(R.id.swipe_dismiss_root);
2310bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
2320bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
2330bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @Test
2340bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    @SmallTest
2350bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    public void testSwipeDoesDismissViewIfStartsInRightPosition() {
2360bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout with dismiss turned on, but only for an
2375504220f38bb0552e1d8def09fb1b9a118264b45Aga Madurska        // inner circle.
2380bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setUpSwipeableRegion();
2390bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // WHEN we perform a swipe to dismiss from the center of the screen.
2400bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(R.id.swipe_dismiss_root)).perform(swipeRightFromCenter());
2410bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        // THEN the layout is dismissed and hidden
2420bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertHidden(R.id.swipe_dismiss_root);
2430bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        assertDismissed(R.id.swipe_dismiss_root);
2440bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
2450bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
2460bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    /**
2470bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     @Test public void testSwipeInPreferenceFragmentAndNavDrawer() {
2480bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     // GIVEN a freshly setup SwipeDismissFrameLayout with dismiss turned on, but only for an inner
2490bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     // circle.
2500bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     setUpPreferenceFragmentAndNavDrawer();
2510bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     // WHEN we perform a swipe to dismiss from the center of the screen to the bottom.
2520bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     onView(withId(R.id.drawer_layout)).perform(swipeBottomFromCenter());
2530bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     // THEN the navigation drawer is shown.
2540bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     assertPeeking(R.id.top_drawer);
2550bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     }*/
2560bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
257d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    @Test
258d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    @SmallTest
259d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    public void testArcSwipeDoesNotTriggerDismiss() throws Throwable {
260d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        // GIVEN a freshly setup SwipeDismissFrameLayout with vertically scrollable content
261d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        setUpSwipeDismissWithVerticalRecyclerView();
262d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        int center = mLayoutHeight / 2;
263d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        int halfBound = mLayoutWidth / 2;
264d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        RectF bounds = new RectF(0, center - halfBound, mLayoutWidth, center + halfBound);
265d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        // WHEN the view is scrolled on an arc from top to bottom.
266d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        onView(withId(R.id.swipe_dismiss_root)).perform(swipeTopFromBottomOnArc(bounds));
267d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        // THEN the layout is not dismissed and not hidden.
268d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        assertNotHidden(R.id.swipe_dismiss_root);
269d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        // AND the content view is scrolled.
270d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        assertScrolledY(R.id.recycler_container);
271d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    }
272d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska
2730bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    /**
2740bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * Set ups the simplest possible layout for test cases - a {@link SwipeDismissFrameLayout} with
2750bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * a single static child.
2760bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     */
2770bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private void setUpSimpleLayout() {
2780bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        activityRule.launchActivity(
2790bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                new Intent()
2800bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        .putExtra(
2810bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
2820bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                R.layout.swipe_dismiss_layout_testcase_1));
2830bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setDismissCallback();
2840bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
2850bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
286d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska
2870bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    /**
2880bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * Sets up a slightly more involved layout for testing swipe-to-dismiss with scrollable
289d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska     * containers. This layout contains a {@link SwipeDismissFrameLayout} with a horizontal {@link
290d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska     * android.support.v7.widget.RecyclerView} as a child, ready to accept an adapter.
2910bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     */
292d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    private void setUpSwipeDismissWithHorizontalRecyclerView() {
293d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        Intent launchIntent = new Intent();
294d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        launchIntent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
295d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                R.layout.swipe_dismiss_layout_testcase_2);
296d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        launchIntent.putExtra(SwipeDismissFrameLayoutTestActivity.EXTRA_LAYOUT_HORIZONTAL, true);
297d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        activityRule.launchActivity(launchIntent);
298d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        setDismissCallback();
299d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    }
300d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska
301d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    /**
302d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska     * Sets up a slightly more involved layout for testing swipe-to-dismiss with scrollable
303d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska     * containers. This layout contains a {@link SwipeDismissFrameLayout} with a vertical {@link
304d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska     * WearableRecyclerView} as a child, ready to accept an adapter.
305d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska     */
306d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    private void setUpSwipeDismissWithVerticalRecyclerView() {
307d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        Intent launchIntent = new Intent();
308d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        launchIntent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
309d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                R.layout.swipe_dismiss_layout_testcase_2);
310d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        launchIntent.putExtra(SwipeDismissFrameLayoutTestActivity.EXTRA_LAYOUT_HORIZONTAL, false);
311d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        activityRule.launchActivity(launchIntent);
3120bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setDismissCallback();
3130bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
3140bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
3150bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    /**
3160bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * Sets up a {@link SwipeDismissFrameLayout} in which only a certain region is allowed to react
3170bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * to swipe-dismiss gestures.
3180bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     */
3190bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private void setUpSwipeableRegion() {
3200bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        activityRule.launchActivity(
3210bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                new Intent()
3220bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        .putExtra(
3230bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
3240bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                R.layout.swipe_dismiss_layout_testcase_1));
3250bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setCallback(
3260bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                new DismissCallback() {
3270bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                    @Override
3280bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                    public boolean onPreSwipeStart(float x, float y) {
3290bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        float normalizedX = x - mLayoutWidth / 2;
3300bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        float normalizedY = y - mLayoutWidth / 2;
3310bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        float squareX = normalizedX * normalizedX;
3320bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        float squareY = normalizedY * normalizedY;
3330bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        // 30 is an arbitrary number limiting the circle.
3340bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        return Math.sqrt(squareX + squareY) < (mLayoutWidth / 2 - 30);
3350bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                    }
3360bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                });
3370bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
3380bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
3390bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    /**
3400bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * Sets up a more involved test case where the layout consists of a
3410bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * {@link WearableNavigationDrawer} and a
3420bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * {@link android.support.wearable.internal.view.SwipeDismissPreferenceFragment}
3430bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     */
3440bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska  /*
3450bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska  private void setUpPreferenceFragmentAndNavDrawer() {
3460bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    activityRule.launchActivity(
3470bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska      new Intent()
3480bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska          .putExtra(
3490bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska              LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
3500bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska              R.layout.swipe_dismiss_layout_testcase_3));
3510bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    Activity activity = activityRule.getActivity();
3520bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
3530bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska      WearableNavigationDrawer wearableNavigationDrawer =
3540bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska              (WearableNavigationDrawer) activity.findViewById(R.id.top_drawer);
3550bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska      wearableNavigationDrawer.setAdapter(
3560bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska              new WearableNavigationDrawer.WearableNavigationDrawerAdapter() {
3570bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                @Override
3580bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                public String getItemText(int pos) {
3590bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                  return "test";
3600bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                }
3610bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
3620bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                @Override
3630bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                public Drawable getItemDrawable(int pos) {
3640bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                  return null;
3650bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                }
3660bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
3670bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                @Override
3680bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                public void onItemSelected(int pos) {
3690bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                  return;
3700bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                }
3710bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
3720bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                @Override
3730bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                public int getCount() {
3740bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                  return 3;
3750bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                }
3760bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska              });
3770bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    });
3780bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska  }*/
3790bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private void setDismissCallback() {
3800bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        setCallback(mDismissCallback);
3810bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
3820bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
3830bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private void setCallback(SwipeDismissFrameLayout.Callback callback) {
3840bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        Activity activity = activityRule.getActivity();
3850bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        SwipeDismissFrameLayout testLayout =
3860bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
3870bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        mLayoutWidth = testLayout.getWidth();
388d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        mLayoutHeight = testLayout.getHeight();
3890bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        testLayout.addCallback(callback);
3900bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
3910bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
3920bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private void assertDismissed(@IdRes int layoutId) {
3930bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(layoutId))
3940bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                .perform(
3950bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        waitForMatchingView(
3960bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                allOf(withId(layoutId), withTranslationX(mLayoutWidth)),
3970bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                MAX_WAIT_TIME));
3980bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
3990bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
4000bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    /**
4010bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * private void assertPeeking(@IdRes int layoutId) {
4020bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * onView(withId(layoutId))
4030bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * .perform(
4040bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * waitForMatchingView(
4050bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * allOf(withId(layoutId), isOpened(true)), MAX_WAIT_TIME));
4060bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     * }
4070bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska     */
4080bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
4090bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private void assertHidden(@IdRes int layoutId) {
4100bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(layoutId))
4110bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                .perform(
4120bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        waitForMatchingView(
4130bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                allOf(withId(layoutId),
4140bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                        withEffectiveVisibility(ViewMatchers.Visibility.GONE)),
4150bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                MAX_WAIT_TIME));
4160bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
4170bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
4180bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private void assertNotHidden(@IdRes int layoutId) {
4190bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        onView(withId(layoutId))
4200bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                .perform(
4210bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                        waitForMatchingView(
4220bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                allOf(withId(layoutId),
4230bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                        withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)),
4240bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                                MAX_WAIT_TIME));
4250bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
4260bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
427d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    private static void assertScrolledY(@IdRes int layoutId) {
428d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska        onView(withId(layoutId))
429d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                .perform(
430d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                        waitForMatchingView(
431d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                                allOf(withId(layoutId), withPositiveVerticalScrollOffset()),
432d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                                MAX_WAIT_TIME));
433d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    }
434d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska
4350bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private static ViewAction swipeRightFromCenter() {
4360bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        return new GeneralSwipeAction(
4370bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                Swipe.SLOW, GeneralLocation.CENTER, GeneralLocation.CENTER_RIGHT, Press.FINGER);
4380bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
4390bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
4400bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private static ViewAction swipeRightFromLeftEdge() {
4410bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        return new GeneralSwipeAction(
4420bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                Swipe.SLOW, GeneralLocation.CENTER_LEFT, GeneralLocation.CENTER_RIGHT,
4430bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                Press.FINGER);
4440bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
4450bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
446d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska    private static ViewAction swipeTopFromBottomOnArc(RectF bounds) {
4470bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        return new GeneralSwipeAction(
448d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                new ArcSwipe(ArcSwipe.Gesture.SLOW_ANTICLOCKWISE, bounds),
449d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                GeneralLocation.BOTTOM_CENTER,
450d5fc393a5aa24693d35b5ebd6d588613103aafdcAga Madurska                GeneralLocation.TOP_CENTER,
4510bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska                Press.FINGER);
4520bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
4530bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
4540bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    /** Helper class hiding the view after a successful swipe-to-dismiss. */
4550bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    private static class DismissCallback extends SwipeDismissFrameLayout.Callback {
4560bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska
4570bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        @Override
4580bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        public void onDismissed(SwipeDismissFrameLayout layout) {
4590bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska            layout.setVisibility(View.GONE);
4600bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska        }
4610bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska    }
4620bb1bb33c39fa5eef545f8513753a8e3b8dfede7Aga Madurska}
463