diff options
author | 2020-04-27 12:31:53 -0700 | |
---|---|---|
committer | 2020-04-28 16:19:31 -0700 | |
commit | 31fb830fc53ddee27f9204c4ecd845b7c994c3bd (patch) | |
tree | d58acbaefb25f2b91b2b2cf20078418b0a8c739e | |
parent | d2db36caa7e8d2120caf195e4495827c87b935e8 (diff) |
Drag drop some changes
Test: atest ItemDragListenerTest, DragHostTest, DragAndDropManagerTests
Bug: 155134389
Change-Id: Ib6d91798743544b669a4efbf2f292c6ee95faca5
7 files changed, 83 insertions, 23 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml index feb767355..a7e26cd9c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -534,4 +534,8 @@ <!-- Accessibility label to indicate the subject(e.g. file/folder) is from work profile --> <string name="a11y_work">Work</string> + + <!-- Snackbar shown when users drag and drop files from another app + to DocumentsUI. [CHAR_LIMIT=100] --> + <string name="drag_from_another_app">Drag from another app not allowed.</string> </resources> diff --git a/src/com/android/documentsui/DragAndDropManager.java b/src/com/android/documentsui/DragAndDropManager.java index d49b6894f..bed8764ae 100644 --- a/src/com/android/documentsui/DragAndDropManager.java +++ b/src/com/android/documentsui/DragAndDropManager.java @@ -16,18 +16,19 @@ package com.android.documentsui; -import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import android.content.ClipData; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.Uri; import android.provider.DocumentsContract; -import androidx.annotation.VisibleForTesting; import android.view.DragEvent; import android.view.KeyEvent; import android.view.View; +import androidx.annotation.IntDef; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + import com.android.documentsui.MenuManager.SelectionDetails; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.DocumentStack; @@ -119,6 +120,12 @@ public interface DragAndDropManager { void resetState(View v); /** + * Checks whether the drag was initiated from FilesApp. + * @return true if initiated from Files app. + */ + boolean isDragFromSameApp(); + + /** * Drops items onto the a root. * * @param clipData the clip data that contains sources information. @@ -165,6 +172,7 @@ public interface DragAndDropManager { private final Drawable mDefaultShadowIcon; private @State int mState = STATE_UNKNOWN; + private boolean mDragInitiated = false; // Key events info. This is used to derive state when user drags items into a view to derive // type of file operations. @@ -233,6 +241,7 @@ public interface DragAndDropManager { IconHelper iconHelper, @Nullable DocumentInfo parent) { + mDragInitiated = true; mView = v; mInvalidDest = invalidDest; mMustBeCopied = !selectionDetails.canDelete(); @@ -355,6 +364,11 @@ public interface DragAndDropManager { updateState(STATE_UNKNOWN); } + @Override + public boolean isDragFromSameApp() { + return mDragInitiated; + } + private void updateState(@State int state) { mState = state; @@ -461,6 +475,7 @@ public interface DragAndDropManager { mDestDoc = null; mDestRoot = null; mMustBeCopied = false; + mDragInitiated = false; } private @OpType int calculateOpType(ClipData clipData, RootInfo destRoot) { diff --git a/src/com/android/documentsui/ItemDragListener.java b/src/com/android/documentsui/ItemDragListener.java index 530b55099..284fd55de 100644 --- a/src/com/android/documentsui/ItemDragListener.java +++ b/src/com/android/documentsui/ItemDragListener.java @@ -23,9 +23,10 @@ import android.view.DragEvent; import android.view.View; import android.view.View.OnDragListener; -import com.android.documentsui.ItemDragListener.DragHost; import androidx.annotation.VisibleForTesting; +import com.android.documentsui.ItemDragListener.DragHost; + import java.util.Timer; import java.util.TimerTask; @@ -63,13 +64,9 @@ public class ItemDragListener<H extends DragHost> implements OnDragListener { @Override public boolean onDrag(final View v, DragEvent event) { - if (!mDragHost.canHandleDragEvent(v)) { - return false; - } - switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: - return true; + return mDragHost.canHandleDragEvent(v); case DragEvent.ACTION_DRAG_ENTERED: handleEnteredEvent(v, event); return true; diff --git a/src/com/android/documentsui/dirlist/DragHost.java b/src/com/android/documentsui/dirlist/DragHost.java index b08637b2b..0222ecb3e 100644 --- a/src/com/android/documentsui/dirlist/DragHost.java +++ b/src/com/android/documentsui/dirlist/DragHost.java @@ -30,12 +30,15 @@ import com.android.documentsui.AbstractActionHandler; import com.android.documentsui.AbstractDragHost; import com.android.documentsui.ActionHandler; import com.android.documentsui.DragAndDropManager; +import com.android.documentsui.R; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.DocumentStack; import com.android.documentsui.base.Lookup; import com.android.documentsui.base.State; import com.android.documentsui.ui.DialogController; +import com.google.android.material.snackbar.Snackbar; + import java.util.function.Predicate; /** @@ -105,6 +108,16 @@ class DragHost<T extends Activity & AbstractActionHandler.CommonAddons> extends mDragAndDropManager.updateState(v, mState.stack.getRoot(), mDestinationLookup.lookup(v)); } + @Override + public boolean canHandleDragEvent(View v) { + if (!mDragAndDropManager.isDragFromSameApp()) { + Snackbar.make( + v, R.string.drag_from_another_app, Snackbar.LENGTH_SHORT).show(); + return false; + } + return true; + } + boolean canSpringOpen(View v) { DocumentInfo doc = mDestinationLookup.lookup(v); return (doc != null) && mDragAndDropManager.canSpringOpen(mState.stack.getRoot(), doc); diff --git a/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java b/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java index 95f416508..7d76f53d9 100644 --- a/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java +++ b/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java @@ -16,16 +16,16 @@ package com.android.documentsui.testing; -import androidx.annotation.Nullable; import android.content.ClipData; import android.net.Uri; import android.util.Pair; import android.view.KeyEvent; import android.view.View; +import androidx.annotation.Nullable; + import com.android.documentsui.ActionHandler; import com.android.documentsui.DragAndDropManager; -import com.android.documentsui.MenuManager; import com.android.documentsui.MenuManager.SelectionDetails; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.DocumentStack; @@ -69,6 +69,11 @@ public class TestDragAndDropManager implements DragAndDropManager { public void resetState(View v) {} @Override + public boolean isDragFromSameApp() { + return true; + } + + @Override public boolean drop(ClipData clipData, Object localState, RootInfo root, ActionHandler actions, FileOperations.Callback callback) { return dropOnRootHandler.accept(Pair.create(clipData, root)); diff --git a/tests/unit/com/android/documentsui/DragAndDropManagerTests.java b/tests/unit/com/android/documentsui/DragAndDropManagerTests.java index 3c30bf391..d7a701f75 100644 --- a/tests/unit/com/android/documentsui/DragAndDropManagerTests.java +++ b/tests/unit/com/android/documentsui/DragAndDropManagerTests.java @@ -398,6 +398,44 @@ public class DragAndDropManagerTests { } @Test + public void testIsDragFromSameApp_afterStartDrag() { + mManager.startDrag( + mStartDragView, + Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), + TestProvidersAccess.DOWNLOADS, + Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, + TestEnv.FILE_JPG.derivedUri), + mDetails, + mIconHelper, + TestEnv.FOLDER_0); + + assertTrue(mManager.isDragFromSameApp()); + } + + @Test + public void testIsDragFromSameApp_beforeStartDrag() { + assertFalse(mManager.isDragFromSameApp()); + } + + @Test + public void testIsDragFromSameApp_afterStartDrag_afterDragEnded() { + mManager.startDrag( + mStartDragView, + Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), + TestProvidersAccess.DOWNLOADS, + Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, + TestEnv.FILE_JPG.derivedUri), + mDetails, + mIconHelper, + TestEnv.FOLDER_0); + assertTrue(mManager.isDragFromSameApp()); + + mManager.dragEnded(); + assertFalse(mManager.isDragFromSameApp()); + } + + + @Test public void testUpdateState_UpdatesToCopy_SameRoot_RightCtrlPressed() { mManager.startDrag( mStartDragView, diff --git a/tests/unit/com/android/documentsui/ItemDragListenerTest.java b/tests/unit/com/android/documentsui/ItemDragListenerTest.java index 94a867ac6..7407577e2 100644 --- a/tests/unit/com/android/documentsui/ItemDragListenerTest.java +++ b/tests/unit/com/android/documentsui/ItemDragListenerTest.java @@ -161,18 +161,6 @@ public class ItemDragListenerTest { } @Test - public void testDoNotHandleDragEvent() { - mTestDragHost.mLastEnteredView = null; - - mTestDragHost.mCanHandleDragEvent = false; - final boolean handled = triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED); - mTestDragHost.mCanHandleDragEvent = true; - - assertFalse(handled); - assertNull(mTestDragHost.mLastEnteredView); - } - - @Test public void testNoDropWithoutClipData() { triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED); |