diff options
author | 2017-04-27 15:06:49 -0700 | |
---|---|---|
committer | 2017-04-28 15:47:44 -0700 | |
commit | 2e81db6f2030ec6c8dd758c3020ce5db8363bf25 (patch) | |
tree | dc9de05d4fc860b7e73fd7e695b7df50bb97c364 | |
parent | a14c17336595dbbd489839180198280b01b7f3aa (diff) |
Fix crash when dragging documents from Recents.
Also not allow user to move from Recents (DnD or Ctrl+X).
Bug: 37712649
Change-Id: I5d63b6359ca478e77479872832f8f759d17c92e6
22 files changed, 388 insertions, 127 deletions
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java index 12ed5d16e..67db9ee9a 100644 --- a/src/com/android/documentsui/AbstractActionHandler.java +++ b/src/com/android/documentsui/AbstractActionHandler.java @@ -500,7 +500,8 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> if (mState.stack.isRecents()) { if (DEBUG) Log.d(TAG, "Creating new loader recents."); - return new RecentsLoader(context, mProviders, mState, mInjector.features); + return new RecentsLoader( + context, mProviders, mState, mInjector.features, mExecutors); } else { diff --git a/src/com/android/documentsui/DragAndDropManager.java b/src/com/android/documentsui/DragAndDropManager.java index c6aa3e2d5..5d7756f3f 100644 --- a/src/com/android/documentsui/DragAndDropManager.java +++ b/src/com/android/documentsui/DragAndDropManager.java @@ -67,19 +67,19 @@ public interface DragAndDropManager { * @param v the view which * {@link View#startDragAndDrop(ClipData, View.DragShadowBuilder, Object, int)} will be * called. - * @param parent {@link DocumentInfo} of the container of srcs * @param srcs documents that are dragged * @param root the root in which documents being dragged are * @param invalidDest destinations that don't accept this drag and drop * @param iconHelper used to load document icons + * @param parent {@link DocumentInfo} of the container of srcs */ void startDrag( View v, - DocumentInfo parent, List<DocumentInfo> srcs, RootInfo root, List<Uri> invalidDest, - IconHelper iconHelper); + IconHelper iconHelper, + @Nullable DocumentInfo parent); /** * Checks whether the document can be spring opened. @@ -167,10 +167,6 @@ public interface DragAndDropManager { // type of file operations. private boolean mIsCtrlPressed; - // Boolean flag for current drag and drop operation. Returns true if the files can only - // be copied (ie. Read-Only files) - private boolean mMustBeCopied; - // Drag events info. These are used to derive state and update drag shadow when user changes // Ctrl key state. private View mView; @@ -179,6 +175,10 @@ public interface DragAndDropManager { private RootInfo mDestRoot; private DocumentInfo mDestDoc; + // Boolean flag for current drag and drop operation. Returns true if the files can only + // be copied (ie. files that don't support delete or remove). + private boolean mMustBeCopied; + private RuntimeDragAndDropManager(Context context, DocumentClipper clipper) { this( context.getApplicationContext(), @@ -223,11 +223,11 @@ public interface DragAndDropManager { @Override public void startDrag( View v, - DocumentInfo parent, List<DocumentInfo> srcs, RootInfo root, List<Uri> invalidDest, - IconHelper iconHelper) { + IconHelper iconHelper, + @Nullable DocumentInfo parent) { mView = v; mInvalidDest = invalidDest; @@ -235,11 +235,15 @@ public interface DragAndDropManager { List<Uri> uris = new ArrayList<>(srcs.size()); for (DocumentInfo doc : srcs) { uris.add(doc.derivedUri); - if (!doc.isRemoveSupported() && !doc.isDeleteSupported()) { + if (!doc.isRemoveSupported() + && !doc.isDeleteSupported() + && !doc.isMoveSupported()) { mMustBeCopied = true; } } - mClipData = mClipper.getClipDataForDocuments( + mClipData = (parent == null) + ? mClipper.getClipDataForDocuments(uris, FileOperationService.OPERATION_UNKNOWN) + : mClipper.getClipDataForDocuments( uris, FileOperationService.OPERATION_UNKNOWN, parent); mClipData.getDescription().getExtras() .putString(SRC_ROOT_KEY, root.getUri().toString()); diff --git a/src/com/android/documentsui/RecentsLoader.java b/src/com/android/documentsui/RecentsLoader.java index 7f00ee236..43209ec0d 100644 --- a/src/com/android/documentsui/RecentsLoader.java +++ b/src/com/android/documentsui/RecentsLoader.java @@ -24,6 +24,7 @@ import android.content.AsyncTaskLoader; import android.content.ContentProviderClient; import android.content.Context; import android.database.Cursor; +import android.database.CursorWrapper; import android.database.MatrixCursor; import android.database.MergeCursor; import android.net.Uri; @@ -35,6 +36,7 @@ import android.util.Log; import com.android.documentsui.base.Features; import com.android.documentsui.base.FilteringCursorWrapper; +import com.android.documentsui.base.Lookup; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.State; import com.android.documentsui.roots.ProvidersAccess; @@ -54,6 +56,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -84,6 +87,7 @@ public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> { private final ProvidersAccess mProviders; private final State mState; private final Features mFeatures; + private final Lookup<String, Executor> mExecutors; @GuardedBy("mTasks") /** A authority -> RecentsTask map */ @@ -94,11 +98,14 @@ public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> { private DirectoryResult mResult; - public RecentsLoader(Context context, ProvidersAccess providers, State state, Features features) { + public RecentsLoader(Context context, ProvidersAccess providers, State state, Features features, + Lookup<String, Executor> executors) { + super(context); mProviders = providers; mState = state; mFeatures = features; + mExecutors = executors; // Keep clients around on high-RAM devices, since we'd be spinning them // up moments later to fetch thumbnails anyway. @@ -127,7 +134,7 @@ public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> { mFirstPassLatch = new CountDownLatch(mTasks.size()); for (RecentsTask task : mTasks.values()) { - ProviderExecutor.forAuthority(task.authority).execute(task); + mExecutors.lookup(task.authority).execute(task); } try { @@ -196,7 +203,8 @@ public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> { merged = new MatrixCursor(new String[0]); } - final Cursor sorted = mState.sortModel.sortCursor(merged); + final Cursor notMovableMasked = new NotMovableMaskCursor(merged); + final Cursor sorted = mState.sortModel.sortCursor(notMovableMasked); // Tell the UI if this is an in-progress result. When loading is complete, another update is // sent with EXTRA_LOADING set to false. @@ -292,7 +300,7 @@ public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> { // TODO: create better transfer of ownership around cursor to ensure its // closed in all edge cases. - public class RecentsTask extends AbstractFuture<Cursor[]> implements Runnable, Closeable { + private class RecentsTask extends AbstractFuture<Cursor[]> implements Runnable, Closeable { public final String authority; public final List<String> rootIds; @@ -321,7 +329,7 @@ public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> { } } - public synchronized void runInternal() { + private synchronized void runInternal() { if (mIsClosed) { return; } @@ -379,4 +387,22 @@ public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> { mIsClosed = true; } } + + private static class NotMovableMaskCursor extends CursorWrapper { + private static final int NOT_MOVABLE_MASK = + ~(Document.FLAG_SUPPORTS_DELETE + | Document.FLAG_SUPPORTS_REMOVE + | Document.FLAG_SUPPORTS_MOVE); + + private NotMovableMaskCursor(Cursor cursor) { + super(cursor); + } + + @Override + public int getInt(int index) { + final int flagIndex = getWrappedCursor().getColumnIndex(Document.COLUMN_FLAGS); + final int value = super.getInt(index); + return (index == flagIndex) ? (value & NOT_MOVABLE_MASK) : value; + } + } } diff --git a/src/com/android/documentsui/base/DocumentFilters.java b/src/com/android/documentsui/base/DocumentFilters.java index a095b558e..f67e1c590 100644 --- a/src/com/android/documentsui/base/DocumentFilters.java +++ b/src/com/android/documentsui/base/DocumentFilters.java @@ -32,6 +32,10 @@ import java.util.function.Predicate; */ public final class DocumentFilters { + private static int MOVABLE_MASK = Document.FLAG_SUPPORTS_REMOVE + | Document.FLAG_SUPPORTS_DELETE + | Document.FLAG_SUPPORTS_MOVE; + public static final Predicate<Cursor> ANY = (Cursor c) -> { return true; }; public static final Predicate<Cursor> VIRTUAL = DocumentFilters::isVirtual; public static final Predicate<Cursor> NOT_MOVABLE = DocumentFilters::isNotMovable; @@ -77,7 +81,6 @@ public final class DocumentFilters { */ private static final boolean isNotMovable(Cursor c) { int flags = getCursorInt(c, Document.COLUMN_FLAGS); - return (flags & Document.FLAG_SUPPORTS_REMOVE) == 0 - && (flags & Document.FLAG_SUPPORTS_DELETE) == 0; + return (flags & MOVABLE_MASK) == 0; } } diff --git a/src/com/android/documentsui/base/DocumentInfo.java b/src/com/android/documentsui/base/DocumentInfo.java index 3f35ba3ae..1ea33f627 100644 --- a/src/com/android/documentsui/base/DocumentInfo.java +++ b/src/com/android/documentsui/base/DocumentInfo.java @@ -247,6 +247,10 @@ public class DocumentInfo implements Durable, Parcelable { return (flags & Document.FLAG_SUPPORTS_REMOVE) != 0; } + public boolean isMoveSupported() { + return (flags & Document.FLAG_SUPPORTS_MOVE) != 0; + } + public boolean isRenameSupported() { return (flags & Document.FLAG_SUPPORTS_RENAME) != 0; } diff --git a/src/com/android/documentsui/clipping/DocumentClipper.java b/src/com/android/documentsui/clipping/DocumentClipper.java index 3777d7a9a..bc61137fc 100644 --- a/src/com/android/documentsui/clipping/DocumentClipper.java +++ b/src/com/android/documentsui/clipping/DocumentClipper.java @@ -56,6 +56,11 @@ public interface DocumentClipper { ClipData getClipDataForDocuments(List<Uri> uris, @OpType int opType, DocumentInfo parent); /** + * Returns {@link ClipData} representing the list of {@link Uri}, or null if the list is empty. + */ + ClipData getClipDataForDocuments(List<Uri> uris, @OpType int opType); + + /** * Puts {@code ClipData} in a primary clipboard, describing a copy operation */ void clipDocumentsForCopy(Function<String, Uri> uriBuilder, Selection selection); diff --git a/src/com/android/documentsui/clipping/RuntimeDocumentClipper.java b/src/com/android/documentsui/clipping/RuntimeDocumentClipper.java index 012d3fbe5..bb9f0622d 100644 --- a/src/com/android/documentsui/clipping/RuntimeDocumentClipper.java +++ b/src/com/android/documentsui/clipping/RuntimeDocumentClipper.java @@ -115,7 +115,8 @@ final class RuntimeDocumentClipper implements DocumentClipper { return clipData; } - private ClipData getClipDataForDocuments(List<Uri> uris, @OpType int opType) { + @Override + public ClipData getClipDataForDocuments(List<Uri> uris, @OpType int opType) { return (uris.size() > Shared.MAX_DOCS_IN_INTENT) ? createJumboClipData(uris, opType) : createStandardClipData(uris, opType); diff --git a/src/com/android/documentsui/dirlist/DragStartListener.java b/src/com/android/documentsui/dirlist/DragStartListener.java index a35d1c1a0..6c23e205c 100644 --- a/src/com/android/documentsui/dirlist/DragStartListener.java +++ b/src/com/android/documentsui/dirlist/DragStartListener.java @@ -123,15 +123,19 @@ interface DragStartListener { final List<DocumentInfo> srcs = mDocsConverter.apply(selection); - final DocumentInfo parent = mState.stack.peek(); final List<Uri> invalidDest = new ArrayList<>(srcs.size() + 1); for (DocumentInfo doc : srcs) { invalidDest.add(doc.derivedUri); } - invalidDest.add(parent.derivedUri); + + final DocumentInfo parent = mState.stack.peek(); + // parent is null when we're in Recents + if (parent != null) { + invalidDest.add(parent.derivedUri); + } mDragAndDropManager.startDrag( - view, parent, srcs, mState.stack.getRoot(), invalidDest, mIconHelper); + view, srcs, mState.stack.getRoot(), invalidDest, mIconHelper, parent); return true; } diff --git a/tests/common/com/android/documentsui/TestActivity.java b/tests/common/com/android/documentsui/TestActivity.java index 73d6495e9..560d15bc8 100644 --- a/tests/common/com/android/documentsui/TestActivity.java +++ b/tests/common/com/android/documentsui/TestActivity.java @@ -19,6 +19,7 @@ package com.android.documentsui; import static junit.framework.Assert.assertEquals; import android.app.Activity; +import android.app.ActivityManager; import android.app.LoaderManager; import android.content.ComponentName; import android.content.ContentResolver; @@ -53,6 +54,7 @@ public abstract class TestActivity extends AbstractBase { public RootInfo currentRoot; public MockContentResolver contentResolver; public TestLoaderManager loaderManager; + public ActivityManager activityManager; public TestEventListener<Intent> startActivity; public TestEventListener<Intent> startService; @@ -177,6 +179,16 @@ public abstract class TestActivity extends AbstractBase { } @Override + public final Object getSystemService(String service) { + switch (service) { + case Context.ACTIVITY_SERVICE: + return activityManager; + } + + throw new IllegalArgumentException("Unknown service " + service); + } + + @Override public final void finish() { finishedHandler.accept(null); } diff --git a/tests/common/com/android/documentsui/testing/ActivityManagers.java b/tests/common/com/android/documentsui/testing/ActivityManagers.java new file mode 100644 index 000000000..e2ae9cdde --- /dev/null +++ b/tests/common/com/android/documentsui/testing/ActivityManagers.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 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.testing; + +import android.app.ActivityManager; + +import org.mockito.Mockito; + +public class ActivityManagers { + + private ActivityManagers() {} + + public static ActivityManager create(boolean lowRamDevice) { + final ActivityManager am = Mockito.mock(ActivityManager.class); + Mockito.when(am.isLowRamDevice()).thenReturn(lowRamDevice); + return am; + } +} diff --git a/tests/common/com/android/documentsui/testing/TestActionHandler.java b/tests/common/com/android/documentsui/testing/TestActionHandler.java index 94ba66523..835356956 100644 --- a/tests/common/com/android/documentsui/testing/TestActionHandler.java +++ b/tests/common/com/android/documentsui/testing/TestActionHandler.java @@ -43,7 +43,7 @@ public class TestActionHandler extends AbstractActionHandler<TestActivity> { super( TestActivity.create(env), env.state, - env.roots, + env.providers, env.docs, env.searchViewManager, (String authority) -> null, diff --git a/tests/common/com/android/documentsui/testing/TestDocumentClipper.java b/tests/common/com/android/documentsui/testing/TestDocumentClipper.java index b183f5afc..3d6c9ad38 100644 --- a/tests/common/com/android/documentsui/testing/TestDocumentClipper.java +++ b/tests/common/com/android/documentsui/testing/TestDocumentClipper.java @@ -28,6 +28,7 @@ import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService.OpType; import com.android.documentsui.services.FileOperations.Callback; +import java.util.ArrayList; import java.util.List; import java.util.function.Function; @@ -36,7 +37,10 @@ public class TestDocumentClipper implements DocumentClipper { public ClipData nextClip; public ClipData primaryClip; - public final TestEventListener<Pair<DocumentStack, ClipData>> copy = new TestEventListener<>(); + public final TestEventHandler<List<Uri>> clipForCut = new TestEventHandler<>(); + + public final TestEventListener<Pair<DocumentStack, ClipData>> copyFromClip = + new TestEventListener<>(); public final TestEventListener<Integer> opType = new TestEventListener<>(); @Override @@ -52,6 +56,12 @@ public class TestDocumentClipper implements DocumentClipper { @Override public ClipData getClipDataForDocuments(List<Uri> uris, + @FileOperationService.OpType int opType) { + return nextClip; + } + + @Override + public ClipData getClipDataForDocuments(List<Uri> uris, @FileOperationService.OpType int opType, DocumentInfo parent) { return nextClip; } @@ -63,34 +73,40 @@ public class TestDocumentClipper implements DocumentClipper { @Override public void clipDocumentsForCut(Function<String, Uri> uriBuilder, Selection selection, DocumentInfo parent) { + List<Uri> uris = new ArrayList<>(selection.size()); + for (String id : selection) { + uris.add(uriBuilder.apply(id)); + } + + clipForCut.accept(uris); } @Override public void copyFromClipboard(DocumentInfo destination, DocumentStack docStack, Callback callback) { - copy.accept(Pair.create(new DocumentStack(docStack, destination), primaryClip)); + copyFromClip.accept(Pair.create(new DocumentStack(docStack, destination), primaryClip)); } @Override public void copyFromClipboard(DocumentStack docStack, Callback callback) { - copy.accept(Pair.create(docStack, primaryClip)); + copyFromClip.accept(Pair.create(docStack, primaryClip)); } @Override public void copyFromClipData(DocumentInfo destination, DocumentStack docStack, ClipData clipData, Callback callback) { - copy.accept(Pair.create(new DocumentStack(docStack, destination), clipData)); + copyFromClip.accept(Pair.create(new DocumentStack(docStack, destination), clipData)); } @Override public void copyFromClipData(DocumentStack dstStack, ClipData clipData, @OpType int opType, Callback callback) { - copy.accept(Pair.create(dstStack, clipData)); + copyFromClip.accept(Pair.create(dstStack, clipData)); this.opType.accept(opType); } @Override public void copyFromClipData(DocumentStack docStack, ClipData clipData, Callback callback) { - copy.accept(Pair.create(docStack, clipData)); + copyFromClip.accept(Pair.create(docStack, clipData)); } } diff --git a/tests/common/com/android/documentsui/testing/TestDocumentsProvider.java b/tests/common/com/android/documentsui/testing/TestDocumentsProvider.java index 19c3c2b7a..9f30326a9 100644 --- a/tests/common/com/android/documentsui/testing/TestDocumentsProvider.java +++ b/tests/common/com/android/documentsui/testing/TestDocumentsProvider.java @@ -48,6 +48,7 @@ public class TestDocumentsProvider extends DocumentsProvider { }; private Cursor mNextChildDocuments; + private Cursor mNextRecentDocuments; public TestDocumentsProvider(String authority) { ProviderInfo info = new ProviderInfo(); @@ -84,6 +85,11 @@ public class TestDocumentsProvider extends DocumentsProvider { } @Override + public Cursor queryRecentDocuments(String rootId, String[] projection) { + return mNextRecentDocuments; + } + + @Override public boolean onCreate() { return true; } @@ -96,6 +102,10 @@ public class TestDocumentsProvider extends DocumentsProvider { mNextChildDocuments = createDocumentsCursor(docs); } + public void setNextRecentDocumentsReturns(DocumentInfo... docs) { + mNextRecentDocuments = createDocumentsCursor(docs); + } + private Cursor createDocumentsCursor(DocumentInfo... docs) { MatrixCursor cursor = new MatrixCursor(DOCUMENTS_PROJECTION); for (DocumentInfo doc : docs) { diff --git a/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java b/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java index 6f4bebea7..288552271 100644 --- a/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java +++ b/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java @@ -45,8 +45,8 @@ public class TestDragAndDropManager implements DragAndDropManager { public void onKeyEvent(KeyEvent event) {} @Override - public void startDrag(View v, DocumentInfo parent, List<DocumentInfo> srcs, RootInfo root, - List<Uri> invalidDest, IconHelper iconHelper) { + public void startDrag(View v, List<DocumentInfo> srcs, RootInfo root, + List<Uri> invalidDest, IconHelper iconHelper, @Nullable DocumentInfo parent) { startDragHandler.accept(srcs); } diff --git a/tests/common/com/android/documentsui/testing/TestEnv.java b/tests/common/com/android/documentsui/testing/TestEnv.java index 902c19fd2..8d1b8a09f 100644 --- a/tests/common/com/android/documentsui/testing/TestEnv.java +++ b/tests/common/com/android/documentsui/testing/TestEnv.java @@ -15,7 +15,6 @@ */ package com.android.documentsui.testing; -import android.content.Context; import android.provider.DocumentsContract.Document; import android.support.test.InstrumentationRegistry; import android.test.mock.MockContentResolver; @@ -59,7 +58,7 @@ public class TestEnv { public final TestScheduledExecutorService mExecutor; public final State state = new State(); - public final TestProvidersAccess roots = new TestProvidersAccess(); + public final TestProvidersAccess providers = new TestProvidersAccess(); public final TestDocumentsAccess docs = new TestDocumentsAccess(); public final TestFocusHandler focusHandler = new TestFocusHandler(); public final TestDialogController dialogs = new TestDialogController(); @@ -71,7 +70,7 @@ public class TestEnv { public final Features features; public final MockContentResolver contentResolver; - public final Map<String, TestDocumentsProvider> providers; + public final Map<String, TestDocumentsProvider> mockProviders; private TestEnv(String authority) { state.sortModel = SortModel.createModel(); @@ -95,16 +94,16 @@ public class TestEnv { injector.searchManager = searchViewManager; contentResolver = new MockContentResolver(); - providers = new HashMap<>(roots.getRootsBlocking().size()); + mockProviders = new HashMap<>(providers.getRootsBlocking().size()); registerProviders(); } private void registerProviders() { - for (RootInfo root : roots.getRootsBlocking()) { - if (!providers.containsKey(root.authority)) { + for (RootInfo root : providers.getRootsBlocking()) { + if (!mockProviders.containsKey(root.authority)) { TestDocumentsProvider provider = new TestDocumentsProvider(root.authority); contentResolver.addProvider(root.authority, provider); - providers.put(root.authority, provider); + mockProviders.put(root.authority, provider); } } } diff --git a/tests/common/com/android/documentsui/testing/TestImmediateExecutor.java b/tests/common/com/android/documentsui/testing/TestImmediateExecutor.java new file mode 100644 index 000000000..6967ab912 --- /dev/null +++ b/tests/common/com/android/documentsui/testing/TestImmediateExecutor.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2017 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.testing; + +import com.android.documentsui.base.Lookup; + +import java.util.concurrent.Executor; + +/** + * An {@link Executor} that executes command in place. + */ +public class TestImmediateExecutor implements Executor { + @Override + public void execute(Runnable command) { + command.run(); + } + + public static Lookup<String, Executor> createLookup() { + final TestImmediateExecutor executor = new TestImmediateExecutor(); + return (String authority) -> { + return executor; + }; + } +} diff --git a/tests/common/com/android/documentsui/testing/TestProvidersAccess.java b/tests/common/com/android/documentsui/testing/TestProvidersAccess.java index a410cfe8e..c5711178e 100644 --- a/tests/common/com/android/documentsui/testing/TestProvidersAccess.java +++ b/tests/common/com/android/documentsui/testing/TestProvidersAccess.java @@ -43,10 +43,18 @@ public class TestProvidersAccess implements ProvidersAccess { }}; DOWNLOADS.authority = Providers.AUTHORITY_DOWNLOADS; DOWNLOADS.rootId = Providers.ROOT_ID_DOWNLOADS; + DOWNLOADS.flags = Root.FLAG_LOCAL_ONLY + | Root.FLAG_SUPPORTS_CREATE + | Root.FLAG_SUPPORTS_IS_CHILD + | Root.FLAG_SUPPORTS_RECENTS; HOME = new RootInfo(); HOME.authority = Providers.AUTHORITY_STORAGE; HOME.rootId = Providers.ROOT_ID_HOME; + HOME.flags = Root.FLAG_LOCAL_ONLY + | Root.FLAG_SUPPORTS_CREATE + | Root.FLAG_SUPPORTS_IS_CHILD + | Root.FLAG_SUPPORTS_RECENTS; HAMMY = new RootInfo(); HAMMY.authority = "yummies"; diff --git a/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java b/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java index 99b0f3869..e094078f3 100644 --- a/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java +++ b/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java @@ -20,7 +20,6 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; -import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Parcelable; @@ -66,7 +65,7 @@ public class AbstractActionHandlerTest { mHandler = new AbstractActionHandler<TestActivity>( mActivity, mEnv.state, - mEnv.roots, + mEnv.providers, mEnv.docs, mEnv.searchViewManager, mEnv::lookupExecutor, @@ -221,7 +220,7 @@ public class AbstractActionHandlerTest { mEnv.state.sortModel.sortByUser( SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); - mEnv.providers.get(TestProvidersAccess.HOME.authority) + mEnv.mockProviders.get(TestProvidersAccess.HOME.authority) .setNextChildDocumentsReturns(TestEnv.FILE_APK, TestEnv.FILE_GIF); mHandler.loadDocumentsForCurrentStack(); @@ -237,7 +236,7 @@ public class AbstractActionHandlerTest { public void testLoadChildrenDocuments_failsWithNonRecentsAndEmptyStack() throws Exception { mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); - mEnv.providers.get(TestProvidersAccess.HOME.authority) + mEnv.mockProviders.get(TestProvidersAccess.HOME.authority) .setNextChildDocumentsReturns(TestEnv.FILE_APK, TestEnv.FILE_GIF); TestEventHandler<Model.Update> listener = new TestEventHandler<>(); diff --git a/tests/unit/com/android/documentsui/DragAndDropManagerTests.java b/tests/unit/com/android/documentsui/DragAndDropManagerTests.java index fafbccb4f..d1b5a411d 100644 --- a/tests/unit/com/android/documentsui/DragAndDropManagerTests.java +++ b/tests/unit/com/android/documentsui/DragAndDropManagerTests.java @@ -141,12 +141,26 @@ public class DragAndDropManagerTests { public void testStartDrag_SetsCorrectClipData() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); + + mStartDragListener.assertLastArgument(mClipper.nextClip); + } + + @Test + public void testStartDrag_SetsCorrectClipData_NullParent() { + mManager.startDrag( + mStartDragView, + Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), + TestProvidersAccess.HOME, + Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, + TestEnv.FILE_JPG.derivedUri), + mIconHelper, + null); mStartDragListener.assertLastArgument(mClipper.nextClip); } @@ -155,11 +169,11 @@ public class DragAndDropManagerTests { public void testStartDrag_BuildsCorrectShadow_SingleDoc() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mShadowBuilder.title.assertLastArgument(TestEnv.FILE_APK.displayName); mShadowBuilder.icon.assertLastArgument(mIconHelper.nextDocumentIcon); @@ -169,12 +183,12 @@ public class DragAndDropManagerTests { public void testStartDrag_BuildsCorrectShadow_MultipleDocs() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mShadowBuilder.title.assertLastArgument(mActivity.getResources().getQuantityString( R.plurals.elements_dragged, 2, 2)); @@ -185,12 +199,12 @@ public class DragAndDropManagerTests { public void testCanSpringOpen_ReturnsFalse_RootNotSupportCreate() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FOLDER_1, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FOLDER_1.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); assertFalse(mManager.canSpringOpen(TestProvidersAccess.HAMMY, TestEnv.FOLDER_2)); } @@ -199,12 +213,12 @@ public class DragAndDropManagerTests { public void testCanSpringOpen_ReturnsFalse_DocIsInvalidDestination() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FOLDER_1, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FOLDER_1.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); assertFalse(mManager.canSpringOpen(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1)); } @@ -213,12 +227,12 @@ public class DragAndDropManagerTests { public void testCanSpringOpen() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FOLDER_1, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FOLDER_1.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); assertTrue(mManager.canSpringOpen(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_2)); } @@ -227,12 +241,12 @@ public class DragAndDropManagerTests { public void testDefaultToUnknownState() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FOLDER_1, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FOLDER_1.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mShadowBuilder.state.assertLastArgument(DragAndDropManager.STATE_UNKNOWN); } @@ -241,12 +255,12 @@ public class DragAndDropManagerTests { public void testUpdateStateToNotAllowed() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateStateToNotAllowed(mUpdateShadowView); @@ -257,12 +271,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToNotAllowed_RootNotSupportCreate() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); final @State int state = mManager.updateState( mUpdateShadowView, TestProvidersAccess.HAMMY, TestEnv.FOLDER_2); @@ -275,12 +289,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToUnknown_RootDocIsNull() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); final @State int state = mManager.updateState( mUpdateShadowView, TestProvidersAccess.DOWNLOADS, null); @@ -293,12 +307,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToMove_SameRoot() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); final @State int state = mManager.updateState( mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1); @@ -311,12 +325,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToCopy_DifferentRoot() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); final @State int state = mManager.updateState( mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1); @@ -329,12 +343,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToCopy_SameRoot_LeftCtrlPressed() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -350,12 +364,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToCopy_SameRoot_RightCtrlPressed() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -371,12 +385,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToMove_DifferentRoot_LeftCtrlPressed() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -392,12 +406,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToMove_DifferentRoot_RightCtrlPressed() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -413,12 +427,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToMove_SameRoot_LeftCtrlReleased() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -437,12 +451,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToMove_SameRoot_RightCtrlReleased() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -461,12 +475,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToCopy_DifferentRoot_LeftCtrlReleased() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -485,12 +499,12 @@ public class DragAndDropManagerTests { public void testUpdateState_UpdatesToCopy_DifferentRoot_RightCtrlReleased() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -509,12 +523,12 @@ public class DragAndDropManagerTests { public void testResetState_UpdatesToUnknown() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateStateToNotAllowed(mUpdateShadowView); @@ -527,12 +541,12 @@ public class DragAndDropManagerTests { public void testDrop_Rejects_RootNotSupportCreate_DropOnRoot() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.HAMMY, TestEnv.FOLDER_1); @@ -548,12 +562,12 @@ public class DragAndDropManagerTests { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), root, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.HOME, TestEnv.FOLDER_0); @@ -564,12 +578,12 @@ public class DragAndDropManagerTests { public void testDrop_Fails_NotGetRootDoc() throws Exception { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1); @@ -586,12 +600,12 @@ public class DragAndDropManagerTests { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1); @@ -601,7 +615,7 @@ public class DragAndDropManagerTests { mEnv.beforeAsserts(); final DocumentStack expect = new DocumentStack(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1); - mClipper.copy.assertLastArgument(Pair.create(expect, mClipData)); + mClipper.copyFromClip.assertLastArgument(Pair.create(expect, mClipData)); mClipper.opType.assertLastArgument(FileOperationService.OPERATION_COPY); } @@ -611,12 +625,12 @@ public class DragAndDropManagerTests { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1); @@ -626,7 +640,7 @@ public class DragAndDropManagerTests { mEnv.beforeAsserts(); final DocumentStack expect = new DocumentStack(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1); - mClipper.copy.assertLastArgument(Pair.create(expect, mClipData)); + mClipper.copyFromClip.assertLastArgument(Pair.create(expect, mClipData)); mClipper.opType.assertLastArgument(FileOperationService.OPERATION_MOVE); } @@ -637,12 +651,12 @@ public class DragAndDropManagerTests { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN); mManager.onKeyEvent(event); @@ -658,7 +672,7 @@ public class DragAndDropManagerTests { mEnv.beforeAsserts(); final DocumentStack expect = new DocumentStack(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1); - mClipper.copy.assertLastArgument(Pair.create(expect, mClipData)); + mClipper.copyFromClip.assertLastArgument(Pair.create(expect, mClipData)); mClipper.opType.assertLastArgument(FileOperationService.OPERATION_COPY); } @@ -666,12 +680,12 @@ public class DragAndDropManagerTests { public void testDrop_Rejects_RootNotSupportCreate_DropOnDocument() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.HAMMY, TestEnv.FOLDER_2); @@ -684,12 +698,12 @@ public class DragAndDropManagerTests { public void testDrop_Copies_DifferentRoot_DropOnDocument() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.HOME, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_2); @@ -697,7 +711,7 @@ public class DragAndDropManagerTests { TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1, TestEnv.FOLDER_2); assertTrue(mManager.drop(mClipData, mManager, stack, mCallback)); - mClipper.copy.assertLastArgument(Pair.create(stack, mClipData)); + mClipper.copyFromClip.assertLastArgument(Pair.create(stack, mClipData)); mClipper.opType.assertLastArgument(FileOperationService.OPERATION_COPY); } @@ -705,12 +719,12 @@ public class DragAndDropManagerTests { public void testDrop_Moves_SameRoot_DropOnDocument() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri, TestEnv.FILE_JPG.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_2); @@ -718,7 +732,7 @@ public class DragAndDropManagerTests { TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1, TestEnv.FOLDER_2); assertTrue(mManager.drop(mClipData, mManager, stack, mCallback)); - mClipper.copy.assertLastArgument(Pair.create(stack, mClipData)); + mClipper.copyFromClip.assertLastArgument(Pair.create(stack, mClipData)); mClipper.opType.assertLastArgument(FileOperationService.OPERATION_MOVE); } @@ -726,11 +740,11 @@ public class DragAndDropManagerTests { public void testDrop_Copies_SameRoot_ReadOnlyFile_DropOnDocument() { mManager.startDrag( mStartDragView, - TestEnv.FOLDER_0, Arrays.asList(TestEnv.FILE_READ_ONLY), TestProvidersAccess.DOWNLOADS, Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_READ_ONLY.derivedUri), - mIconHelper); + mIconHelper, + TestEnv.FOLDER_0); mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_2); @@ -738,7 +752,7 @@ public class DragAndDropManagerTests { TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1, TestEnv.FOLDER_2); assertTrue(mManager.drop(mClipData, mManager, stack, mCallback)); - mClipper.copy.assertLastArgument(Pair.create(stack, mClipData)); + mClipper.copyFromClip.assertLastArgument(Pair.create(stack, mClipData)); mClipper.opType.assertLastArgument(FileOperationService.OPERATION_COPY); } diff --git a/tests/unit/com/android/documentsui/RecentsLoaderTests.java b/tests/unit/com/android/documentsui/RecentsLoaderTests.java new file mode 100644 index 000000000..dfdc486ae --- /dev/null +++ b/tests/unit/com/android/documentsui/RecentsLoaderTests.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2017 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; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +import android.database.Cursor; +import android.provider.DocumentsContract.Document; +import android.support.test.filters.MediumTest; +import android.support.test.runner.AndroidJUnit4; + +import com.android.documentsui.base.DocumentInfo; +import com.android.documentsui.base.State; +import com.android.documentsui.testing.ActivityManagers; +import com.android.documentsui.testing.TestEnv; +import com.android.documentsui.testing.TestFeatures; +import com.android.documentsui.testing.TestImmediateExecutor; +import com.android.documentsui.testing.TestProvidersAccess; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@MediumTest +public class RecentsLoaderTests { + + private TestEnv mEnv; + private TestActivity mActivity; + private RecentsLoader mLoader; + private TestFeatures mFeatures; + + @Before + public void setUp() { + mEnv = TestEnv.create(); + mActivity = TestActivity.create(mEnv); + mActivity.activityManager = ActivityManagers.create(false); + mFeatures = new TestFeatures(); + + mEnv.state.action = State.ACTION_BROWSE; + mEnv.state.acceptMimes = new String[] { "*/*" }; + + mLoader = new RecentsLoader(mActivity, mEnv.providers, mEnv.state, mFeatures, + TestImmediateExecutor.createLookup()); + } + + @Test + public void testDocumentsNotMovable() { + final DocumentInfo doc = mEnv.model.createFile("freddy.jpg", + Document.FLAG_SUPPORTS_MOVE + | Document.FLAG_SUPPORTS_DELETE + | Document.FLAG_SUPPORTS_REMOVE); + doc.lastModified = System.currentTimeMillis(); + mEnv.mockProviders.get(TestProvidersAccess.HOME.authority) + .setNextRecentDocumentsReturns(doc); + + final DirectoryResult result = mLoader.loadInBackground(); + + final Cursor c = result.cursor; + assertEquals(1, c.getCount()); + for (int i = 0; i < c.getCount(); ++i) { + c.moveToNext(); + final int flags = c.getInt(c.getColumnIndex(Document.COLUMN_FLAGS)); + assertEquals(0, flags & Document.FLAG_SUPPORTS_DELETE); + assertEquals(0, flags & Document.FLAG_SUPPORTS_REMOVE); + assertEquals(0, flags & Document.FLAG_SUPPORTS_MOVE); + } + } +} diff --git a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java index ef9945825..8752311f8 100644 --- a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java +++ b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java @@ -83,7 +83,7 @@ public class ActionHandlerTest { mClipper = new TestDocumentClipper(); mDragAndDropManager = new TestDragAndDropManager(); - mEnv.roots.configurePm(mActivity.packageMgr); + mEnv.providers.configurePm(mActivity.packageMgr); ((TestActivityConfig) mEnv.injector.config).nextDocumentEnabled = true; mEnv.injector.dialogs = mDialogs; @@ -124,6 +124,17 @@ public class ActionHandlerTest { } @Test + public void testCutSelectedDocuments_ContainsNonMovableItem() { + mEnv.populateStack(); + mEnv.selectDocument(TestEnv.FILE_READ_ONLY); + + mHandler.cutToClipboard(); + mDialogs.assertDocumentsClippedNotShown(); + mDialogs.assertShowOperationUnsupported(); + mClipper.clipForCut.assertNotCalled(); + } + + @Test public void testCopySelectedDocuments_NoGivenSelection() { mEnv.populateStack(); @@ -154,16 +165,6 @@ public class ActionHandlerTest { mActionModeAddons.finishOnConfirmed.assertRejected(); } - @Test - public void testCutSelectedDocuments_ContainsNonMovableItem() { - mEnv.selectDocument(TestEnv.FILE_READ_ONLY); - - mHandler.cutToClipboard(); - mDialogs.assertDocumentsClippedNotShown(); - mDialogs.assertShowOperationUnsupported(); - mActivity.startService.assertNotCalled(); - } - // Recents root means when deleting the srcParent will be null. @Test public void testDeleteSelectedDocuments_RecentsRoot() { @@ -495,7 +496,7 @@ public class ActionHandlerTest { return new ActionHandler<>( mActivity, mEnv.state, - mEnv.roots, + mEnv.providers, mEnv.docs, mEnv.searchViewManager, mEnv::lookupExecutor, diff --git a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java index 5bcc7357d..56b437433 100644 --- a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java +++ b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java @@ -62,13 +62,13 @@ public class ActionHandlerTest { public void setUp() { mEnv = TestEnv.create(); mActivity = TestActivity.create(mEnv); - mEnv.roots.configurePm(mActivity.packageMgr); + mEnv.providers.configurePm(mActivity.packageMgr); mLastAccessed = new TestLastAccessedStorage(); mHandler = new ActionHandler<>( mActivity, mEnv.state, - mEnv.roots, + mEnv.providers, mEnv.docs, mEnv.searchViewManager, mEnv::lookupExecutor, @@ -433,8 +433,8 @@ public class ActionHandlerTest { } private void assertLastAccessedStackUpdated() { - assertEquals( - mEnv.state.stack, mLastAccessed.getLastAccessed(mActivity, mEnv.roots, mEnv.state)); + assertEquals(mEnv.state.stack, mLastAccessed.getLastAccessed( + mActivity, mEnv.providers, mEnv.state)); } private void assertPermission(Intent intent, int permission, boolean granted) { |