18a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev/*
28a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * Copyright (C) 2016 The Android Open Source Project
38a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev *
48a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * Licensed under the Apache License, Version 2.0 (the "License");
58a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * you may not use this file except in compliance with the License.
68a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * You may obtain a copy of the License at
78a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev *
88a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev *      http://www.apache.org/licenses/LICENSE-2.0
98a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev *
108a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * Unless required by applicable law or agreed to in writing, software
118a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * distributed under the License is distributed on an "AS IS" BASIS,
128a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * See the License for the specific language governing permissions and
148a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev * limitations under the License.
158a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev */
168a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.core.view;
188a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
198a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Matchers.any;
208a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Matchers.argThat;
218a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Matchers.eq;
228a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Mockito.inOrder;
238a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Mockito.mock;
248a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Mockito.times;
258a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Mockito.verify;
268a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Mockito.verifyNoMoreInteractions;
278a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport static org.mockito.Mockito.when;
288a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
298a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.app.Instrumentation;
308a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.graphics.Point;
318a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.os.SystemClock;
328a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.support.test.InstrumentationRegistry;
3335232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikasimport android.support.test.filters.LargeTest;
348a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.support.test.filters.SmallTest;
358a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.support.test.rule.ActivityTestRule;
368a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.support.test.runner.AndroidJUnit4;
378a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.view.InputDevice;
388a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.view.MotionEvent;
398a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.view.View;
408a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport android.view.ViewConfiguration;
418a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
429dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikasimport androidx.annotation.NonNull;
439dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikasimport androidx.core.test.R;
449dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikas
458a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport org.junit.Before;
468a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport org.junit.Rule;
478a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport org.junit.Test;
488a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport org.junit.runner.RunWith;
498a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport org.mockito.ArgumentMatcher;
508a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevimport org.mockito.InOrder;
518a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
528a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev@RunWith(AndroidJUnit4.class)
538a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheevpublic class DragStartHelperTest {
548a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
558a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Rule
568a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public ActivityTestRule<DragStartHelperTestActivity> mActivityRule =
578a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            new ActivityTestRule<>(DragStartHelperTestActivity.class);
588a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
598a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private Instrumentation mInstrumentation;
608a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private View mDragSource;
618a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
628a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    interface DragStartListener {
638a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        boolean onDragStart(View view, DragStartHelper helper, Point touchPosition);
648a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
658a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
668a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @NonNull
678a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private DragStartListener createListener(boolean returnValue) {
688a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = mock(DragStartListener.class);
698a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        when(listener.onDragStart(any(View.class), any(DragStartHelper.class), any(Point.class)))
708a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                .thenReturn(returnValue);
718a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        return listener;
728a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
738a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
748a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @NonNull
758a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private DragStartHelper createDragStartHelper(final DragStartListener listener) {
768a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        return new DragStartHelper(mDragSource, new DragStartHelper.OnDragStartListener() {
778a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            @Override
788a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            public boolean onDragStart(View v, DragStartHelper helper) {
798a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                Point touchPosition = new Point();
808a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                helper.getTouchPosition(touchPosition);
818a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                return listener.onDragStart(v, helper, touchPosition);
828a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            }
838a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        });
848a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
858a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
868a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private static int[] getViewCenter(View view) {
878a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final int[] xy = new int[2];
888a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        view.getLocationOnScreen(xy);
898a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        xy[0] += view.getWidth() / 2;
908a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        xy[1] += view.getHeight() / 2;
918a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        return xy;
928a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
938a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
948a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private static MotionEvent obtainTouchEvent(
958a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            int action, View anchor, int offsetX, int offsetY) {
968a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final long eventTime = SystemClock.uptimeMillis();
978a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final int[] xy = getViewCenter(anchor);
988a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        return MotionEvent.obtain(
998a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eventTime, eventTime, action, xy[0] + offsetX, xy[1] + offsetY, 0);
1008a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
1018a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1028a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private void sendTouchEvent(int action, View anchor, int offsetX, int offsetY) {
1038a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        mInstrumentation.sendPointerSync(obtainTouchEvent(action, anchor, offsetX, offsetY));
1048a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
1058a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1068a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private static MotionEvent obtainMouseEvent(
1078a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            int action, int buttonState, View anchor, int offsetX, int offsetY) {
1088a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final long eventTime = SystemClock.uptimeMillis();
1098a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1108a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final int[] xy = getViewCenter(anchor);
1118a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1128a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        MotionEvent.PointerProperties[] props = new MotionEvent.PointerProperties[] {
1138a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                new MotionEvent.PointerProperties()
1148a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        };
1158a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        props[0].id = 0;
1168a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        props[0].toolType = MotionEvent.TOOL_TYPE_MOUSE;
1178a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1188a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[] {
1198a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                new MotionEvent.PointerCoords()
1208a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        };
1218a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        coords[0].x = xy[0] + offsetX;
1228a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        coords[0].y = xy[1] + offsetY;
1238a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1248a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        return MotionEvent.obtain(eventTime, eventTime, action, 1, props, coords, 0,
1258a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                buttonState, 0, 0, -1, 0, InputDevice.SOURCE_MOUSE, 0);
1268a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
1278a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1288a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private void sendMouseEvent(
1298a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            int action, int buttonState, View anchor, int offsetX, int offsetY) {
1308a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        mInstrumentation.sendPointerSync(obtainMouseEvent(
1318a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                action, buttonState, anchor, offsetX, offsetY));
1328a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
1338a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
134963facb8fce35022f296c38fadafd9a959ab1655Aurimas Liutikas    static class TouchPositionMatcher implements ArgumentMatcher<Point> {
1358a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1368a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        private final Point mExpectedPosition;
1378a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1388a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        TouchPositionMatcher(int x, int y) {
1398a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            mExpectedPosition = new Point(x, y);
1408a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        }
1418a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1428a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        TouchPositionMatcher(View anchor, int x, int y) {
1438a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            this(anchor.getWidth() / 2 + x, anchor.getHeight() / 2 + y);
1448a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        }
1458a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
146e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas        @Override
147963facb8fce35022f296c38fadafd9a959ab1655Aurimas Liutikas        public boolean matches(Point actual) {
1488a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            return mExpectedPosition.equals(actual);
1498a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        }
1508a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
151e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas        @Override
152963facb8fce35022f296c38fadafd9a959ab1655Aurimas Liutikas        public String toString() {
153963facb8fce35022f296c38fadafd9a959ab1655Aurimas Liutikas            return "TouchPositionMatcher: " + mExpectedPosition;
1548a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        }
1558a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
1568a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1578a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    private void waitForLongPress() {
1588a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        SystemClock.sleep(ViewConfiguration.getLongPressTimeout() * 2);
1598a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
1608a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
1618a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Before
1628a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void setUp() {
1638a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        mInstrumentation = InstrumentationRegistry.getInstrumentation();
1648a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        mDragSource = mActivityRule.getActivity().findViewById(R.id.drag_source);
1658a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
1668a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
16735232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @SmallTest
1688a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Test
16971e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    public void mouseClick() throws Throwable {
17071e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        final DragStartListener listener = createListener(true);
17171e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
17271e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        helper.attach();
17371e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
17471e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_DOWN, MotionEvent.BUTTON_PRIMARY, mDragSource, 0, 0);
17571e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_UP, MotionEvent.BUTTON_PRIMARY, mDragSource, 0, 0);
17671e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
17771e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        // A simple mouse click does not trigger OnDragStart.
17871e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        verifyNoMoreInteractions(listener);
17971e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    }
18071e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
18135232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @SmallTest
18271e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    @Test
18371e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    public void mousePressWithSecondaryButton() throws Throwable {
18471e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        final DragStartListener listener = createListener(true);
18571e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
18671e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        helper.attach();
18771e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
18871e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_DOWN, MotionEvent.BUTTON_PRIMARY, mDragSource, 0, 0);
18971e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE,
19071e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev                MotionEvent.BUTTON_PRIMARY | MotionEvent.BUTTON_SECONDARY, mDragSource, 0, 0);
19171e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 0, 0);
19271e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
19371e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        // ACTION_MOVE with the same position does not trigger OnDragStart.
19471e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        verifyNoMoreInteractions(listener);
19571e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    }
19671e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
19735232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @SmallTest
19871e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    @Test
1998a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void mouseDrag() throws Throwable {
2008a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = createListener(true);
2018a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
2028a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        helper.attach();
2038a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2048a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_DOWN, MotionEvent.BUTTON_PRIMARY, mDragSource, 0, 0);
2058a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 1, 2);
2068a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 3, 4);
2078a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 5, 6);
2088a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2098a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        // Returning true from the callback prevents further callbacks.
2108a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verify(listener, times(1)).onDragStart(
2118a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eq(mDragSource), eq(helper), argThat(new TouchPositionMatcher(mDragSource, 1, 2)));
2128a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verifyNoMoreInteractions(listener);
2138a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
2148a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
21535232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @SmallTest
2168a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Test
2178a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void mouseDragWithNonprimaryButton() throws Throwable {
2188a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = createListener(true);
2198a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
2208a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        helper.attach();
2218a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2228a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_DOWN, MotionEvent.BUTTON_SECONDARY, mDragSource, 0, 0);
2238a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_SECONDARY, mDragSource, 1, 2);
2248a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_UP, MotionEvent.BUTTON_SECONDARY, mDragSource, 3, 4);
2258a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2268a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_DOWN, MotionEvent.BUTTON_TERTIARY, mDragSource, 0, 0);
2278a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_TERTIARY, mDragSource, 1, 2);
2288a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_UP, MotionEvent.BUTTON_TERTIARY, mDragSource, 3, 4);
2298a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
23071e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        // Dragging mouse with a non-primary button down does not trigger OnDragStart.
2318a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verifyNoMoreInteractions(listener);
2328a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
2338a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
23435232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @SmallTest
2358a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Test
2368a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void mouseDragUsingTouchListener() throws Throwable {
2378a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = createListener(true);
2388a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
2398a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2408a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        mDragSource.setOnTouchListener(new View.OnTouchListener() {
2418a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            @Override
2428a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            public boolean onTouch(View view, MotionEvent motionEvent) {
2438a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                helper.onTouch(view, motionEvent);
2448a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                return true;
2458a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            }
2468a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        });
2478a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2488a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_DOWN, MotionEvent.BUTTON_PRIMARY, mDragSource, 0, 0);
2498a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 1, 2);
2508a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 3, 4);
2518a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 5, 6);
2528a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2538a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        // Returning true from the callback prevents further callbacks.
2548a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verify(listener, times(1)).onDragStart(
2558a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eq(mDragSource), eq(helper), argThat(new TouchPositionMatcher(mDragSource, 1, 2)));
2568a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verifyNoMoreInteractions(listener);
2578a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
2588a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
25935232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @SmallTest
2608a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Test
2618a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void mouseDragWhenListenerReturnsFalse() throws Throwable {
2628a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = createListener(false);
2638a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
2648a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        helper.attach();
2658a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2668a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_DOWN, MotionEvent.BUTTON_PRIMARY, mDragSource, 0, 0);
2678a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 1, 2);
2688a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 3, 4);
2698a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_MOVE, MotionEvent.BUTTON_PRIMARY, mDragSource, 5, 6);
2708a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2718a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        // When the listener returns false every ACTION_MOVE triggers OnDragStart.
2728a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        InOrder inOrder = inOrder(listener);
2738a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        inOrder.verify(listener, times(1)).onDragStart(
2748a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eq(mDragSource), eq(helper), argThat(new TouchPositionMatcher(mDragSource, 1, 2)));
2758a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        inOrder.verify(listener, times(1)).onDragStart(
2768a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eq(mDragSource), eq(helper), argThat(new TouchPositionMatcher(mDragSource, 3, 4)));
2778a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        inOrder.verify(listener, times(1)).onDragStart(
2788a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eq(mDragSource), eq(helper), argThat(new TouchPositionMatcher(mDragSource, 5, 6)));
2798a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        inOrder.verifyNoMoreInteractions();
2808a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
2818a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
28235232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @LargeTest
2838a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Test
2848a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void mouseLongPress() throws Throwable {
2858a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = createListener(true);
2868a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
2878a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        helper.attach();
2888a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2898a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendMouseEvent(MotionEvent.ACTION_DOWN, MotionEvent.BUTTON_PRIMARY, mDragSource, 1, 2);
2908a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        waitForLongPress();
2918a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
2928a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        // Long press triggers OnDragStart.
2938a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verify(listener, times(1)).onDragStart(
2948a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eq(mDragSource), eq(helper), argThat(new TouchPositionMatcher(mDragSource, 1, 2)));
2958a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verifyNoMoreInteractions(listener);
2968a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
2978a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
29835232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @SmallTest
2998a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Test
3008a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void touchDrag() throws Throwable {
3018a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = createListener(false);
3028a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
3038a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        helper.attach();
3048a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
3058a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendTouchEvent(MotionEvent.ACTION_DOWN, mDragSource, 0, 0);
3068a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendTouchEvent(MotionEvent.ACTION_MOVE, mDragSource, 1, 2);
3078a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendTouchEvent(MotionEvent.ACTION_MOVE, mDragSource, 3, 4);
3088a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendTouchEvent(MotionEvent.ACTION_MOVE, mDragSource, 5, 6);
3098a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
3108a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        // Touch and drag (without delay) does not trigger OnDragStart.
3118a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verifyNoMoreInteractions(listener);
3128a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
3138a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
31435232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @SmallTest
3158a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Test
31671e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    public void touchTap() throws Throwable {
31771e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        final DragStartListener listener = createListener(false);
31871e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
31971e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        helper.attach();
32071e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
32171e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        sendTouchEvent(MotionEvent.ACTION_DOWN, mDragSource, 0, 0);
32271e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        sendTouchEvent(MotionEvent.ACTION_UP, mDragSource, 0, 0);
32371e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
32471e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        // A simple tap does not trigger OnDragStart.
32571e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev        verifyNoMoreInteractions(listener);
32671e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    }
32771e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev
32835232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @LargeTest
32971e918dd8d07e3338240e9a4ca0910814e19c47dVladislav Kaznacheev    @Test
3308a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void touchLongPress() throws Throwable {
3318a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = createListener(true);
3328a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
3338a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        helper.attach();
3348a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
3358a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendTouchEvent(MotionEvent.ACTION_DOWN, mDragSource, 1, 2);
3368a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        waitForLongPress();
3378a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
3388a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        // Long press triggers OnDragStart.
3398a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verify(listener, times(1)).onDragStart(
3408a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eq(mDragSource), eq(helper), argThat(new TouchPositionMatcher(mDragSource, 1, 2)));
3418a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verifyNoMoreInteractions(listener);
3428a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
3438a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
34435232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas    @LargeTest
3458a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    @Test
3468a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    public void touchLongPressUsingLongClickListener() throws Throwable {
3478a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartListener listener = createListener(true);
3488a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
3498a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        final DragStartHelper helper = createDragStartHelper(listener);
3508a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        mDragSource.setOnLongClickListener(new View.OnLongClickListener() {
3518a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            @Override
3528a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            public boolean onLongClick(View view) {
3538a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                return helper.onLongClick(view);
3548a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev            }
3558a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        });
3568a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
3578a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        sendTouchEvent(MotionEvent.ACTION_DOWN, mDragSource, 1, 2);
3588a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        waitForLongPress();
3598a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev
3608a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        // Long press triggers OnDragStart.
3618a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        // Since ACTION_DOWN is not handled, the touch offset is not available.
3628a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verify(listener, times(1)).onDragStart(
3638a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev                eq(mDragSource), eq(helper), argThat(new TouchPositionMatcher(0, 0)));
3648a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev        verifyNoMoreInteractions(listener);
3658a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev    }
3668a771cded580e2b83a0eb158cae7ee13ce0b85cdVladislav Kaznacheev}
367