Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b40c6b88 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "DragScrollListener test, from ag/1247908." into nyc-andromeda-dev

parents 66fb96a0 2abb4c7d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -215,8 +215,9 @@ public class DirectoryFragment extends Fragment

        mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity()));

        final int edgeHeight = (int) getResources().getDimension(R.dimen.autoscroll_edge_height);
        mOnDragListener = DragScrollListener.create(
                getActivity(), new DirectoryDragListener(this), mRecView);
                edgeHeight, new DirectoryDragListener(this), mRecView);

        // Make the recycler and the empty views responsive to drop events.
        mRecView.setOnDragListener(mOnDragListener);
+9 −8
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package com.android.documentsui.dirlist;

import android.content.Context;
import android.graphics.Point;
import android.support.annotation.VisibleForTesting;
import android.view.DragEvent;
import android.view.View;
import android.view.View.OnDragListener;
@@ -26,7 +26,6 @@ import com.android.documentsui.ItemDragListener;
import com.android.documentsui.ItemDragListener.DragHost;
import com.android.documentsui.dirlist.ViewAutoScroller.ScrollActionDelegate;
import com.android.documentsui.dirlist.ViewAutoScroller.ScrollDistanceDelegate;
import com.android.documentsui.R;

import java.util.function.BooleanSupplier;
import java.util.function.IntSupplier;
@@ -49,16 +48,16 @@ class DragScrollListener implements OnDragListener {
    private boolean mDragHappening;
    private @Nullable Point mCurrentPosition;

    private DragScrollListener(
            Context context,
    @VisibleForTesting
    DragScrollListener(
            int autoScrollEdgeHeight,
            ItemDragListener<? extends DragHost> dragHandler,
            IntSupplier heightSupplier,
            BooleanSupplier scrollUpSupplier,
            BooleanSupplier scrollDownSupplier,
            ViewAutoScroller.ScrollActionDelegate actionDelegate) {
        mDragHandler = dragHandler;
        mAutoScrollEdgeHeight = (int) context.getResources()
                .getDimension(R.dimen.autoscroll_edge_height);
        mAutoScrollEdgeHeight = autoScrollEdgeHeight;
        mHeight = heightSupplier;
        mCanScrollUp = scrollUpSupplier;
        mCanScrollDown = scrollDownSupplier;
@@ -85,7 +84,9 @@ class DragScrollListener implements OnDragListener {
    }

    static DragScrollListener create(
            Context context, ItemDragListener<? extends DragHost> dragHandler, View scrollView) {
            int autoScrollEdgeHeight,
            ItemDragListener<? extends DragHost> dragHandler,
            View scrollView) {
        ScrollActionDelegate actionDelegate = new ScrollActionDelegate() {
            @Override
            public void scrollBy(int dy) {
@@ -104,7 +105,7 @@ class DragScrollListener implements OnDragListener {
            }
        };
        DragScrollListener listener = new DragScrollListener(
                context,
                autoScrollEdgeHeight,
                dragHandler,
                scrollView::getHeight,
                () -> {
+242 −0
Original line number Diff line number Diff line
/*
 * 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 com.android.documentsui.dirlist;

import static org.junit.Assert.assertTrue;

import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.view.DragEvent;
import android.view.View;

import com.android.documentsui.ItemDragListener;
import com.android.documentsui.dirlist.ViewAutoScroller.ScrollActionDelegate;
import com.android.documentsui.testing.DragEvents;
import com.android.documentsui.testing.TestTimer;
import com.android.documentsui.testing.Views;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Timer;
import java.util.function.IntConsumer;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class DragScrollListenerTest {

    private static final int VIEW_HEIGHT = 100;
    private static final int EDGE_HEIGHT = 10;

    private View mTestView;
    private TestDragHost mTestDragHost;
    private TestTimer mTestTimer;
    private TestDragHandler mDragHandler;
    private TestScrollActionDelegate mActionDelegate = new TestScrollActionDelegate();
    private DragScrollListener mListener;
    private boolean mCanScrollUp;
    private boolean mCanScrollDown;

    @Before
    public void setUp() {
        mTestView = Views.createTestView(0, 0);
        mTestTimer = new TestTimer();
        mTestDragHost = new TestDragHost();
        mDragHandler = new TestDragHandler(mTestDragHost, mTestTimer);
        mListener = new DragScrollListener(
                EDGE_HEIGHT,
                mDragHandler,
                () -> {
                    return VIEW_HEIGHT;
                },
                () -> {
                    return mCanScrollUp;
                },
                () -> {
                    return mCanScrollDown;
                },
                mActionDelegate);
        mCanScrollUp = true;
        mCanScrollDown = true;
    }

    @Test
    public void testDragEvent_DelegateToHandler() {
        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_STARTED);

        triggerDragEvent(DragEvent.ACTION_DROP);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DROP);

        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_ENDED);

        triggerDragEvent(DragEvent.ACTION_DRAG_EXITED);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_EXITED);
    }

    @Test
    public void testDragLocationEvent_DelegateToHandler() {
        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED);

        // Not in hotspot
        triggerDragLocationEvent(0, 50);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION);

        // Can't scroll up
        mCanScrollUp = false;
        mCanScrollDown = true;
        triggerDragLocationEvent(0, 5);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION);

        // Can't scroll Down
        mCanScrollDown = false;
        mCanScrollUp = true;
        triggerDragLocationEvent(0, 95);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION);

        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED);
    }

    @Test
    public void testDragEnterEvent_DelegateToHandler() {
        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED);

        // Location Event always precedes Entered event
        triggerDragLocationEvent(0, 50);
        // If not in the hotspot, we don't want to trap the event
        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_ENTERED);

        // Can't scroll up
        mCanScrollUp = false;
        mCanScrollDown = true;
        triggerDragLocationEvent(0, 5);
        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_ENTERED);

        // Can't scroll Down
        mCanScrollDown = false;
        mCanScrollUp = true;
        triggerDragLocationEvent(0, 95);
        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_ENTERED);

        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED);
    }

    // Make sure given correct location/enter events, DragScrollListener handle them itself
    @Test
    public void testDragScrollEvent_Handled() {
        triggerDragLocationEvent(0, 5);
        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
        assertTrue(mDragHandler.mLastDropEvent == null);

        triggerDragLocationEvent(0, 95);
        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
        assertTrue(mDragHandler.mLastDropEvent == null);
    }

    // A correct Auto-scroll happens in the sequence of:
    // Started -> LocationChanged -> Scroll -> Enter -> Exit
    // This test to make sure scroll actually happens in the right direction given correct sequence
    @Test
    public void testActualDragScrolldEvents() {
        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED);

        triggerDragLocationEvent(0, 5);
        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_STARTED);
        mActionDelegate.assertScrollNegative();

        triggerDragLocationEvent(0, 95);
        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);

        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED);
        assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_ENDED);
        mActionDelegate.assertScrollPositive();
    }

    protected boolean triggerDragEvent(int actionId) {
        final DragEvent testEvent = DragEvents.createTestDragEvent(actionId);

        return mListener.onDrag(mTestView, testEvent);
    }

    protected boolean triggerDragLocationEvent(float x, float y) {
        final DragEvent testEvent = DragEvents.createTestLocationEvent(x, y);

        return mListener.onDrag(mTestView, testEvent);
    }

    private static class TestDragHandler extends ItemDragListener<TestDragHost> {

        private DragEvent mLastDropEvent;

        protected TestDragHandler(TestDragHost dragHost, Timer timer) {
            super(dragHost, timer);
        }

        @Override
        public boolean onDrag(View v, DragEvent event) {
            mLastDropEvent = event;
            return true;
        }
    }

    private static class TestDragHost implements ItemDragListener.DragHost {

        @Override
        public void setDropTargetHighlight(View v, boolean highlight) {
        }

        @Override
        public void runOnUiThread(Runnable runnable) {
        }

        @Override
        public void onViewHovered(View v) {
        }
    }

    private class TestScrollActionDelegate implements ScrollActionDelegate {

        private int mDy;

        @Override
        public void scrollBy(int dy) {
            mDy = dy;
        }

        @Override
        public void runAtNextFrame(Runnable r) {
        }

        @Override
        public void removeCallback(Runnable r) {
        }

        public void assertScrollPositive() {
            assertTrue(mDy > 0);
        }

        public void assertScrollNegative() {
            assertTrue(mDy < 0);
        }
    };
}
+11 −0
Original line number Diff line number Diff line
@@ -33,6 +33,17 @@ public final class Views {
        return view;
    }

    /*
     * Dummy View object with (x, y) coordinates
     */
    public static View createTestView(float x, float y) {
        View view = createTestView();
        Mockito.when(view.getX()).thenReturn(x);
        Mockito.when(view.getY()).thenReturn(y);

        return view;
    }

    public static void setBackground(View testView, Drawable background) {
        Mockito.when(testView.getBackground()).thenReturn(background);
    }