Loading src/com/android/documentsui/dirlist/DirectoryFragment.java +2 −1 Original line number Diff line number Diff line Loading @@ -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); Loading src/com/android/documentsui/dirlist/DragScrollListener.java +9 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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) { Loading @@ -104,7 +105,7 @@ class DragScrollListener implements OnDragListener { } }; DragScrollListener listener = new DragScrollListener( context, autoScrollEdgeHeight, dragHandler, scrollView::getHeight, () -> { Loading tests/src/com/android/documentsui/dirlist/DragScrollListenerTest.java 0 → 100644 +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); } }; } tests/src/com/android/documentsui/testing/Views.java +11 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading
src/com/android/documentsui/dirlist/DirectoryFragment.java +2 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
src/com/android/documentsui/dirlist/DragScrollListener.java +9 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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) { Loading @@ -104,7 +105,7 @@ class DragScrollListener implements OnDragListener { } }; DragScrollListener listener = new DragScrollListener( context, autoScrollEdgeHeight, dragHandler, scrollView::getHeight, () -> { Loading
tests/src/com/android/documentsui/dirlist/DragScrollListenerTest.java 0 → 100644 +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); } }; }
tests/src/com/android/documentsui/testing/Views.java +11 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading