/**
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.accessibilityservice.cts;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Verify that gestures dispatched from an accessibility service show up in the current UI
 */
public class AccessibilityGestureDispatchTest extends
        ActivityInstrumentationTestCase2<AccessibilityGestureDispatchTest.GestureDispatchActivity> {
    private static final int GESTURE_COMPLETION_TIMEOUT = 5000; // millis
    private static final int MOTION_EVENT_TIMEOUT = 1000; // millis

    final List<MotionEvent> mMotionEvents = new ArrayList<>();
    StubGestureAccessibilityService mService;
    MyTouchListener mMyTouchListener = new MyTouchListener();
    MyGestureCallback mCallback;
    TextView mFullScreenTextView;
    Rect mViewBounds = new Rect();
    boolean mGotUpEvent;
    // Without a touch screen, there's no point in testing this feature
    boolean mHasTouchScreen;
    boolean mHasMultiTouch;

    public AccessibilityGestureDispatchTest() {
        super(GestureDispatchActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();

        PackageManager pm = getInstrumentation().getContext().getPackageManager();
        mHasTouchScreen = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
                || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
        if (!mHasTouchScreen) {
            return;
        }

        mHasMultiTouch = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)
                || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT);

        mFullScreenTextView =
                (TextView) getActivity().findViewById(R.id.full_screen_text_view);
        getInstrumentation().runOnMainSync(() -> {
            mFullScreenTextView.getGlobalVisibleRect(mViewBounds);
            mFullScreenTextView.setOnTouchListener(mMyTouchListener);
        });

        mService = StubGestureAccessibilityService.enableSelf(this);

        mMotionEvents.clear();
        mCallback = new MyGestureCallback();
        mGotUpEvent = false;
    }

    @Override
    public void tearDown() throws Exception {
        if (!mHasTouchScreen) {
            return;
        }

        mService.runOnServiceSync(() -> mService.disableSelf());
        super.tearDown();
    }

    public void testClickAt_producesDownThenUp() throws InterruptedException {
        if (!mHasTouchScreen) {
            return;
        }

        final int clickXInsideView = 10;
        final int clickYInsideView = 20;
        int clickX = clickXInsideView + mViewBounds.left;
        int clickY = clickYInsideView + mViewBounds.top;
        GestureDescription click = createClick(clickX, clickY);
        mService.runOnServiceSync(() -> mService.doDispatchGesture(click, mCallback, null));
        mCallback.assertGestureCompletes(GESTURE_COMPLETION_TIMEOUT);
        waitForMotionEvents(2);

        assertEquals(2, mMotionEvents.size());
        MotionEvent clickDown = mMotionEvents.get(0);
        MotionEvent clickUp = mMotionEvents.get(1);

        assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
        assertEquals(0, clickDown.getActionIndex());
        assertEquals(0, clickDown.getDeviceId());
        assertEquals(0, clickDown.getEdgeFlags());
        assertEquals(1F, clickDown.getXPrecision());
        assertEquals(1F, clickDown.getYPrecision());
        assertEquals(1, clickDown.getPointerCount());
        assertEquals(1F, clickDown.getPressure());
        assertEquals((float) clickXInsideView, clickDown.getX());
        assertEquals((float) clickYInsideView, clickDown.getY());
        assertEquals(clickDown.getDownTime(), clickDown.getEventTime());

        assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
        assertEquals(clickDown.getDownTime(), clickUp.getDownTime());
        assertEquals(ViewConfiguration.getTapTimeout(),
                clickUp.getEventTime() - clickUp.getDownTime());
        assertTrue(clickDown.getEventTime() + ViewConfiguration.getLongPressTimeout()
                > clickUp.getEventTime());
        assertEquals((float) clickXInsideView, clickUp.getX());
        assertEquals((float) clickYInsideView, clickUp.getY());
    }

    public void testLongClickAt_producesEventsWithLongClickTiming() throws InterruptedException {
        if (!mHasTouchScreen) {
            return;
        }

        final int clickXInsideView = 10;
        final int clickYInsideView = 20;
        int clickX = clickXInsideView + mViewBounds.left;
        int clickY = clickYInsideView + mViewBounds.top;
        GestureDescription longClick = createLongClick(clickX, clickY);
        mService.runOnServiceSync(() -> mService.doDispatchGesture(longClick, mCallback, null));
        mCallback.assertGestureCompletes(
                ViewConfiguration.getLongPressTimeout() + GESTURE_COMPLETION_TIMEOUT);

        waitForMotionEvents(2);
        MotionEvent clickDown = mMotionEvents.get(0);
        MotionEvent clickUp = mMotionEvents.get(1);

        assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());

        assertEquals((float) clickXInsideView, clickDown.getX());
        assertEquals((float) clickYInsideView, clickDown.getY());

        assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
        assertTrue(clickDown.getEventTime() + ViewConfiguration.getLongPressTimeout()
                <= clickUp.getEventTime());
        assertEquals(clickDown.getDownTime(), clickUp.getDownTime());
        assertEquals((float) clickXInsideView, clickUp.getX());
        assertEquals((float) clickYInsideView, clickUp.getY());
    }

    public void testSwipe_shouldContainPointsInALine() throws InterruptedException {
        if (!mHasTouchScreen) {
            return;
        }

        int startXInsideView = 10;
        int startYInsideView = 20;
        int endXInsideView = 20;
        int endYInsideView = 40;
        int startX = startXInsideView + mViewBounds.left;
        int startY = startYInsideView + mViewBounds.top;
        int endX = endXInsideView + mViewBounds.left;
        int endY = endYInsideView + mViewBounds.top;
        int gestureTime = 500;
        float swipeTolerance = 2.0f;

        GestureDescription swipe = createSwipe(startX, startY, endX, endY, gestureTime);
        mService.runOnServiceSync(() -> mService.doDispatchGesture(swipe, mCallback, null));
        mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
        waitForUpEvent();
        int numEvents = mMotionEvents.size();

        MotionEvent downEvent = mMotionEvents.get(0);
        assertEquals(MotionEvent.ACTION_DOWN, downEvent.getActionMasked());
        assertEquals(startXInsideView, (int) downEvent.getX());
        assertEquals(startYInsideView, (int) downEvent.getY());

        MotionEvent upEvent = mMotionEvents.get(numEvents - 1);
        assertEquals(MotionEvent.ACTION_UP, upEvent.getActionMasked());
        assertEquals(endXInsideView, (int) upEvent.getX());
        assertEquals(endYInsideView, (int) upEvent.getY());
        assertEquals(gestureTime, upEvent.getEventTime() - downEvent.getEventTime());

        long lastEventTime = downEvent.getEventTime();
        for (int i = 1; i < numEvents - 1; i++) {
            MotionEvent moveEvent = mMotionEvents.get(i);
            assertEquals(MotionEvent.ACTION_MOVE, moveEvent.getActionMasked());
            assertTrue(moveEvent.getEventTime() >= lastEventTime);
            float fractionOfSwipe =
                    ((float) (moveEvent.getEventTime() - downEvent.getEventTime())) / gestureTime;
            float fractionX = ((float) (endXInsideView - startXInsideView)) * fractionOfSwipe;
            float fractionY = ((float) (endYInsideView - startYInsideView)) * fractionOfSwipe;
            assertEquals(startXInsideView + fractionX, moveEvent.getX(), swipeTolerance);
            assertEquals(startYInsideView + fractionY, moveEvent.getY(), swipeTolerance);
            lastEventTime = moveEvent.getEventTime();
        }
    }

    public void testSlowSwipe_shouldNotContainMovesForTinyMovement() throws InterruptedException {
        if (!mHasTouchScreen) {
            return;
        }

        int startXInsideView = 10;
        int startYInsideView = 20;
        int endXInsideView = 11;
        int endYInsideView = 22;
        int startX = startXInsideView + mViewBounds.left;
        int startY = startYInsideView + mViewBounds.top;
        int endX = endXInsideView + mViewBounds.left;
        int endY = endYInsideView + mViewBounds.top;
        int gestureTime = 1000;

        GestureDescription swipe = createSwipe(startX, startY, endX, endY, gestureTime);
        mService.runOnServiceSync(() -> mService.doDispatchGesture(swipe, mCallback, null));
        mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
        waitForUpEvent();

        assertEquals(5, mMotionEvents.size());

        assertEquals(MotionEvent.ACTION_DOWN, mMotionEvents.get(0).getActionMasked());
        assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(1).getActionMasked());
        assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(2).getActionMasked());
        assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(3).getActionMasked());
        assertEquals(MotionEvent.ACTION_UP, mMotionEvents.get(4).getActionMasked());

        assertEquals(startXInsideView, (int) mMotionEvents.get(0).getX());
        assertEquals(startXInsideView, (int) mMotionEvents.get(1).getX());
        assertEquals(startXInsideView + 1, (int) mMotionEvents.get(2).getX());
        assertEquals(startXInsideView + 1, (int) mMotionEvents.get(3).getX());
        assertEquals(startXInsideView + 1, (int) mMotionEvents.get(4).getX());

        assertEquals(startYInsideView, (int) mMotionEvents.get(0).getY());
        assertEquals(startYInsideView + 1, (int) mMotionEvents.get(1).getY());
        assertEquals(startYInsideView + 1, (int) mMotionEvents.get(2).getY());
        assertEquals(startYInsideView + 2, (int) mMotionEvents.get(3).getY());
        assertEquals(startYInsideView + 2, (int) mMotionEvents.get(4).getY());
    }

    public void testAngledPinch_looksReasonable() throws InterruptedException {
        if (!(mHasTouchScreen && mHasMultiTouch)) {
            return;
        }

        int centerXInsideView = 50;
        int centerYInsideView = 60;
        int centerX = centerXInsideView + mViewBounds.left;
        int centerY = centerYInsideView + mViewBounds.top;
        int startSpacing = 100;
        int endSpacing = 50;
        int gestureTime = 500;
        float pinchTolerance = 2.0f;

        GestureDescription pinch = createPinch(centerX, centerY, startSpacing,
                endSpacing, 45.0F, gestureTime);
        mService.runOnServiceSync(() -> mService.doDispatchGesture(pinch, mCallback, null));
        mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
        waitForUpEvent();
        int numEvents = mMotionEvents.size();

        // First two events are the initial down and the pointer down
        assertEquals(MotionEvent.ACTION_DOWN, mMotionEvents.get(0).getActionMasked());
        assertEquals(MotionEvent.ACTION_POINTER_DOWN, mMotionEvents.get(1).getActionMasked());

        // The second event must have two pointers at the initial spacing along a 45 degree angle
        MotionEvent firstEventWithTwoPointers = mMotionEvents.get(1);
        assertEquals(2, firstEventWithTwoPointers.getPointerCount());
        MotionEvent.PointerCoords coords0 = new MotionEvent.PointerCoords();
        MotionEvent.PointerCoords coords1 = new MotionEvent.PointerCoords();
        firstEventWithTwoPointers.getPointerCoords(0, coords0);
        firstEventWithTwoPointers.getPointerCoords(1, coords1);
        // Verify center point
        assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
        assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
        // Verify angle
        assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView, pinchTolerance);
        assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView, pinchTolerance);
        // Verify spacing
        assertEquals(startSpacing, distance(coords0, coords1), pinchTolerance);

        // The last two events are the pointer up and the final up
        assertEquals(MotionEvent.ACTION_UP, mMotionEvents.get(numEvents - 1).getActionMasked());

        MotionEvent lastEventWithTwoPointers = mMotionEvents.get(numEvents - 2);
        assertEquals(MotionEvent.ACTION_POINTER_UP, lastEventWithTwoPointers.getActionMasked());
        lastEventWithTwoPointers.getPointerCoords(0, coords0);
        lastEventWithTwoPointers.getPointerCoords(1, coords1);
        // Verify center point
        assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
        assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
        // Verify angle
        assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView, pinchTolerance);
        assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView, pinchTolerance);
        // Verify spacing
        assertEquals(endSpacing, distance(coords0, coords1), pinchTolerance);

        float lastSpacing = startSpacing;
        for (int i = 2; i < numEvents - 2; i++) {
            MotionEvent eventInMiddle = mMotionEvents.get(i);
            assertEquals(MotionEvent.ACTION_MOVE, eventInMiddle.getActionMasked());
            eventInMiddle.getPointerCoords(0, coords0);
            eventInMiddle.getPointerCoords(1, coords1);
            // Verify center point
            assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
            assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
            // Verify angle
            assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView,
                    pinchTolerance);
            assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView,
                    pinchTolerance);
            float spacing = distance(coords0, coords1);
            assertTrue(spacing <= lastSpacing + pinchTolerance);
            assertTrue(spacing >= endSpacing - pinchTolerance);
            lastSpacing = spacing;
        }
    }

    // This test assumes device's screen contains its center (W/2, H/2) with some surroundings
    // and should work for rectangular, round and round with chin screens.
    public void testClickWhenMagnified_matchesActualTouch() throws InterruptedException {
        if (!mHasTouchScreen) {
            return;
        }

        final int clickShiftFromCenterX = 10;
        final int clickShiftFromCenterY = 20;
        final Resources res = getInstrumentation().getTargetContext().getResources();
        final DisplayMetrics metrics = res.getDisplayMetrics();
        final int centerX = metrics.widthPixels / 2;
        final int centerY = metrics.heightPixels / 2;
        final float TOUCH_TOLERANCE = 2.0f;

        StubMagnificationAccessibilityService magnificationService =
                StubMagnificationAccessibilityService.enableSelf(this);
        android.accessibilityservice.AccessibilityService.MagnificationController
                magnificationController = magnificationService.getMagnificationController();
        try {
            // Magnify screen by 2x with a magnification center in the center of the screen
            final AtomicBoolean setScale = new AtomicBoolean();
            final float magnificationFactor = 2.0f;
            magnificationService.runOnServiceSync(() -> {
                        setScale.set(magnificationController.setScale(magnificationFactor, false));
                        magnificationController.setCenter(centerX, centerY, false);
                    });
            assertTrue("Failed to set scale", setScale.get());

            final int clickMagnifiedX = (int) (centerX + magnificationFactor * clickShiftFromCenterX);
            final int clickMagnifiedY = (int) (centerY + magnificationFactor * clickShiftFromCenterY);
            GestureDescription click = createClick(clickMagnifiedX, clickMagnifiedY);
            mService.runOnServiceSync(() -> mService.doDispatchGesture(click, mCallback, null));
            mCallback.assertGestureCompletes(GESTURE_COMPLETION_TIMEOUT);
            waitForMotionEvents(3);
        } finally {
            // Reset magnification
            final AtomicBoolean result = new AtomicBoolean();
            magnificationService.runOnServiceSync(() ->
                    result.set(magnificationController.reset(false)));
            magnificationService.runOnServiceSync(() -> magnificationService.disableSelf());
            assertTrue("Failed to reset", result.get());
        }

        assertEquals(2, mMotionEvents.size());
        MotionEvent clickDown = mMotionEvents.get(0);
        MotionEvent clickUp = mMotionEvents.get(1);

        final int centerXInsideView = centerX - mViewBounds.left;
        final int centerYInsideView = centerY - mViewBounds.top;
        final int expectedClickXInsideView = centerXInsideView + clickShiftFromCenterX;
        final int expectedClickYInsideView = centerYInsideView + clickShiftFromCenterY;
        assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
        assertEquals((float) expectedClickXInsideView, clickDown.getX(), TOUCH_TOLERANCE);
        assertEquals((float) expectedClickYInsideView, clickDown.getY(), TOUCH_TOLERANCE);
        assertEquals(clickDown.getDownTime(), clickDown.getEventTime());

        assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
        assertEquals((float) expectedClickXInsideView, clickUp.getX(), TOUCH_TOLERANCE);
        assertEquals((float) expectedClickYInsideView, clickUp.getY(), TOUCH_TOLERANCE);
    }


    public static class GestureDispatchActivity extends AccessibilityTestActivity {
        public GestureDispatchActivity() {
            super();
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.full_screen_frame_layout);
        }
    }

    public static class MyGestureCallback extends AccessibilityService.GestureResultCallback {
        private boolean mCompleted;
        private boolean mCancelled;

        @Override
        public synchronized void onCompleted(GestureDescription gestureDescription) {
            mCompleted = true;
            notifyAll();
        }

        @Override
        public synchronized void onCancelled(GestureDescription gestureDescription) {
            mCancelled = true;
            notifyAll();
        }

        public synchronized void assertGestureCompletes(long timeout) {
            if (mCompleted) {
                return;
            }
            try {
                wait(timeout);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            assertTrue("Gesture did not complete.", mCompleted);
        }
    }

    private void waitForMotionEvents(int numEventsExpected) throws InterruptedException {
        synchronized (mMotionEvents) {
            long endMillis = SystemClock.uptimeMillis() + MOTION_EVENT_TIMEOUT;
            while ((mMotionEvents.size() < numEventsExpected)
                    && (SystemClock.uptimeMillis() < endMillis)) {
                mMotionEvents.wait(endMillis - SystemClock.uptimeMillis());
            }
        }
    }

    private void waitForUpEvent() throws InterruptedException {
        synchronized (mMotionEvents) {
            long endMillis = SystemClock.uptimeMillis() + MOTION_EVENT_TIMEOUT;
            while (!mGotUpEvent && (SystemClock.uptimeMillis() < endMillis)) {
                mMotionEvents.wait(endMillis - SystemClock.uptimeMillis());
            }
        }
    }

    private float distance(MotionEvent.PointerCoords point1, MotionEvent.PointerCoords point2) {
        return (float) Math.hypot((double) (point1.x - point2.x), (double) (point1.y - point2.y));
    }

    private class MyTouchListener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            synchronized (mMotionEvents) {
                if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP) {
                    mGotUpEvent = true;
                }
                mMotionEvents.add(MotionEvent.obtain(motionEvent));
                mMotionEvents.notifyAll();
                return true;
            }
        }
    }

    private GestureDescription createClick(int x, int y) {
        Path clickPath = new Path();
        clickPath.moveTo(x, y);
        GestureDescription.StrokeDescription clickStroke =
                new GestureDescription.StrokeDescription(clickPath, 0, ViewConfiguration.getTapTimeout());
        GestureDescription.Builder clickBuilder = new GestureDescription.Builder();
        clickBuilder.addStroke(clickStroke);
        return clickBuilder.build();
    }

    private GestureDescription createLongClick(int x, int y) {
        Path clickPath = new Path();
        clickPath.moveTo(x, y);
        int longPressTime = ViewConfiguration.getLongPressTimeout();

        GestureDescription.StrokeDescription longClickStroke =
                new GestureDescription.StrokeDescription(clickPath, 0, longPressTime + (longPressTime / 2));
        GestureDescription.Builder longClickBuilder = new GestureDescription.Builder();
        longClickBuilder.addStroke(longClickStroke);
        return longClickBuilder.build();
    }

    private GestureDescription createSwipe(
            int startX, int startY, int endX, int endY, long duration) {
        Path swipePath = new Path();
        swipePath.moveTo(startX, startY);
        swipePath.lineTo(endX, endY);

        GestureDescription.StrokeDescription swipeStroke = new GestureDescription.StrokeDescription(swipePath, 0, duration);
        GestureDescription.Builder swipeBuilder = new GestureDescription.Builder();
        swipeBuilder.addStroke(swipeStroke);
        return swipeBuilder.build();
    }

    private GestureDescription createPinch(int centerX, int centerY, int startSpacing,
            int endSpacing, float orientation, long duration) {
        if ((startSpacing < 0) || (endSpacing < 0)) {
            throw new IllegalArgumentException("Pinch spacing cannot be negative");
        }
        float[] startPoint1 = new float[2];
        float[] endPoint1 = new float[2];
        float[] startPoint2 = new float[2];
        float[] endPoint2 = new float[2];

        /* Build points for a horizontal gesture centered at the origin */
        startPoint1[0] = startSpacing / 2;
        startPoint1[1] = 0;
        endPoint1[0] = endSpacing / 2;
        endPoint1[1] = 0;
        startPoint2[0] = -startSpacing / 2;
        startPoint2[1] = 0;
        endPoint2[0] = -endSpacing / 2;
        endPoint2[1] = 0;

        /* Rotate and translate the points */
        Matrix matrix = new Matrix();
        matrix.setRotate(orientation);
        matrix.postTranslate(centerX, centerY);
        matrix.mapPoints(startPoint1);
        matrix.mapPoints(endPoint1);
        matrix.mapPoints(startPoint2);
        matrix.mapPoints(endPoint2);

        Path path1 = new Path();
        path1.moveTo(startPoint1[0], startPoint1[1]);
        path1.lineTo(endPoint1[0], endPoint1[1]);
        Path path2 = new Path();
        path2.moveTo(startPoint2[0], startPoint2[1]);
        path2.lineTo(endPoint2[0], endPoint2[1]);

        GestureDescription.StrokeDescription path1Stroke = new GestureDescription.StrokeDescription(path1, 0, duration);
        GestureDescription.StrokeDescription path2Stroke = new GestureDescription.StrokeDescription(path2, 0, duration);
        GestureDescription.Builder swipeBuilder = new GestureDescription.Builder();
        swipeBuilder.addStroke(path1Stroke);
        swipeBuilder.addStroke(path2Stroke);
        return swipeBuilder.build();
    }
}
