• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.documentsui;
18 
19 import static junit.framework.Assert.assertEquals;
20 import static junit.framework.Assert.assertFalse;
21 import static junit.framework.Assert.assertNotNull;
22 import static junit.framework.Assert.assertSame;
23 import static junit.framework.Assert.assertTrue;
24 
25 import android.content.ClipData;
26 import android.content.ClipDescription;
27 import android.graphics.drawable.Drawable;
28 import android.os.PersistableBundle;
29 import android.support.test.filters.SmallTest;
30 import android.support.test.runner.AndroidJUnit4;
31 import android.util.Pair;
32 import android.view.KeyEvent;
33 import android.view.View;
34 
35 import com.android.documentsui.DragAndDropManager.State;
36 import com.android.documentsui.DragAndDropManager.RuntimeDragAndDropManager;
37 import com.android.documentsui.base.DocumentStack;
38 import com.android.documentsui.base.RootInfo;
39 import com.android.documentsui.services.FileOperationService;
40 import com.android.documentsui.services.FileOperations;
41 import com.android.documentsui.testing.ClipDatas;
42 import com.android.documentsui.testing.KeyEvents;
43 import com.android.documentsui.testing.TestActionHandler;
44 import com.android.documentsui.testing.TestDocumentClipper;
45 import com.android.documentsui.testing.TestDrawable;
46 import com.android.documentsui.testing.TestEnv;
47 import com.android.documentsui.testing.TestEventListener;
48 import com.android.documentsui.testing.TestIconHelper;
49 import com.android.documentsui.testing.TestProvidersAccess;
50 import com.android.documentsui.testing.TestSelectionDetails;
51 import com.android.documentsui.testing.Views;
52 
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.junit.runner.RunWith;
56 import org.mockito.Mockito;
57 
58 import java.util.Arrays;
59 
60 @RunWith(AndroidJUnit4.class)
61 @SmallTest
62 public class DragAndDropManagerTests {
63 
64     private static final String PLURAL_FORMAT = "%1$d items";
65 
66     private TestEnv mEnv;
67     private TestActivity mActivity;
68     private TestDragShadowBuilder mShadowBuilder;
69     private View mStartDragView;
70     private View mUpdateShadowView;
71     private TestActionHandler mActions;
72 
73     private TestDocumentClipper mClipper;
74     private TestSelectionDetails mDetails;
75     private ClipData mClipData;
76 
77     private TestIconHelper mIconHelper;
78     private Drawable mDefaultIcon;
79 
80     private TestEventListener<ClipData> mStartDragListener;
81     private TestEventListener<Void> mShadowUpdateListener;
82     private TestEventListener<Integer> mFlagListener;
83 
84     private TestEventListener<Integer> mCallbackListener;
85     private FileOperations.Callback mCallback = new FileOperations.Callback() {
86         @Override
87         public void onOperationResult(@Status int status,
88                 @FileOperationService.OpType int opType, int docCount) {
89             mCallbackListener.accept(status);
90         }
91     };
92 
93     private DragAndDropManager mManager;
94 
95     @Before
setUp()96     public void setUp() {
97         mEnv = TestEnv.create();
98         mActivity = TestActivity.create(mEnv);
99         mActivity.resources.plurals.put(R.plurals.elements_dragged, PLURAL_FORMAT);
100 
101         mShadowBuilder = TestDragShadowBuilder.create();
102 
103         mStartDragView = Views.createTestView();
104         mUpdateShadowView = Views.createTestView();
105 
106         mActions = new TestActionHandler(mEnv);
107 
108         mClipper = new TestDocumentClipper();
109         mDetails = new TestSelectionDetails();
110         mDetails.canDelete = true;
111         ClipDescription description = new ClipDescription("", new String[]{});
112         description.setExtras(new PersistableBundle());
113         mClipData = ClipDatas.createTestClipData(description);
114         mClipper.nextClip = mClipData;
115 
116         mDefaultIcon = new TestDrawable();
117         mIconHelper = TestIconHelper.create();
118         mIconHelper.nextDocumentIcon = new TestDrawable();
119 
120         mStartDragListener = new TestEventListener<>();
121         mShadowUpdateListener = new TestEventListener<>();
122         mCallbackListener = new TestEventListener<>();
123         mFlagListener = new TestEventListener<>();
124 
125         mManager = new RuntimeDragAndDropManager(mActivity, mClipper, mShadowBuilder,
126                 mDefaultIcon) {
127             @Override
128             void startDragAndDrop(View v, ClipData clipData, DragShadowBuilder builder,
129                     Object localState, int flag) {
130                 assertSame(mStartDragView, v);
131                 assertSame(mShadowBuilder, builder);
132                 assertNotNull(localState);
133 
134                 mFlagListener.accept(flag);
135                 mStartDragListener.accept(clipData);
136             }
137 
138             @Override
139             void updateDragShadow(View v) {
140                 assertSame(mUpdateShadowView, v);
141 
142                 mShadowUpdateListener.accept(null);
143             }
144         };
145     }
146 
147     @Test
testStartDrag_SetsCorrectClipData()148     public void testStartDrag_SetsCorrectClipData() {
149         mManager.startDrag(
150                 mStartDragView,
151                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
152                 TestProvidersAccess.HOME,
153                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
154                         TestEnv.FILE_JPG.derivedUri),
155                 mDetails,
156                 mIconHelper,
157                 TestEnv.FOLDER_0);
158 
159         mStartDragListener.assertLastArgument(mClipper.nextClip);
160     }
161 
162     @Test
testStartDrag_SetsCorrectClipData_NullParent()163     public void testStartDrag_SetsCorrectClipData_NullParent() {
164         mManager.startDrag(
165                 mStartDragView,
166                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
167                 TestProvidersAccess.HOME,
168                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
169                         TestEnv.FILE_JPG.derivedUri),
170                 mDetails,
171                 mIconHelper,
172                 null);
173 
174         mStartDragListener.assertLastArgument(mClipper.nextClip);
175     }
176 
177     @Test
testStartDrag_BuildsCorrectShadow_SingleDoc()178     public void testStartDrag_BuildsCorrectShadow_SingleDoc() {
179         mManager.startDrag(
180                 mStartDragView,
181                 Arrays.asList(TestEnv.FILE_APK),
182                 TestProvidersAccess.HOME,
183                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri),
184                 mDetails,
185                 mIconHelper,
186                 TestEnv.FOLDER_0);
187 
188         mShadowBuilder.title.assertLastArgument(TestEnv.FILE_APK.displayName);
189         mShadowBuilder.icon.assertLastArgument(mIconHelper.nextDocumentIcon);
190     }
191 
192     @Test
testStartDrag_BuildsCorrectShadow_MultipleDocs()193     public void testStartDrag_BuildsCorrectShadow_MultipleDocs() {
194         mManager.startDrag(
195                 mStartDragView,
196                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
197                 TestProvidersAccess.HOME,
198                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
199                         TestEnv.FILE_JPG.derivedUri),
200                 mDetails,
201                 mIconHelper,
202                 TestEnv.FOLDER_0);
203 
204         mShadowBuilder.title.assertLastArgument(mActivity.getResources().getQuantityString(
205                 R.plurals.elements_dragged, 2, 2));
206         mShadowBuilder.icon.assertLastArgument(mDefaultIcon);
207     }
208 
209     @Test
testCanSpringOpen_ReturnsFalse_RootNotSupportCreate()210     public void testCanSpringOpen_ReturnsFalse_RootNotSupportCreate() {
211         mManager.startDrag(
212                 mStartDragView,
213                 Arrays.asList(TestEnv.FOLDER_1, TestEnv.FILE_JPG),
214                 TestProvidersAccess.HOME,
215                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FOLDER_1.derivedUri,
216                         TestEnv.FILE_JPG.derivedUri),
217                 mDetails,
218                 mIconHelper,
219                 TestEnv.FOLDER_0);
220 
221         assertFalse(mManager.canSpringOpen(TestProvidersAccess.HAMMY, TestEnv.FOLDER_2));
222     }
223 
224     @Test
testInArchiveUris_HasCorrectFlagPermission()225     public void testInArchiveUris_HasCorrectFlagPermission() {
226         mDetails.containsFilesInArchive = true;
227         mManager.startDrag(
228                 mStartDragView,
229                 Arrays.asList(TestEnv.FILE_IN_ARCHIVE),
230                 TestProvidersAccess.HOME,
231                 Arrays.asList(TestEnv.FILE_ARCHIVE.derivedUri, TestEnv.FILE_IN_ARCHIVE.derivedUri),
232                 mDetails,
233                 mIconHelper,
234                 TestEnv.FILE_ARCHIVE);
235 
236         mFlagListener.assertLastArgument(View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_OPAQUE);
237     }
238 
239     @Test
testCanSpringOpen_ReturnsFalse_DocIsInvalidDestination()240     public void testCanSpringOpen_ReturnsFalse_DocIsInvalidDestination() {
241         mManager.startDrag(
242                 mStartDragView,
243                 Arrays.asList(TestEnv.FOLDER_1, TestEnv.FILE_JPG),
244                 TestProvidersAccess.HOME,
245                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FOLDER_1.derivedUri,
246                         TestEnv.FILE_JPG.derivedUri),
247                 mDetails,
248                 mIconHelper,
249                 TestEnv.FOLDER_0);
250 
251         assertFalse(mManager.canSpringOpen(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1));
252     }
253 
254     @Test
testCanSpringOpen()255     public void testCanSpringOpen() {
256         mManager.startDrag(
257                 mStartDragView,
258                 Arrays.asList(TestEnv.FOLDER_1, TestEnv.FILE_JPG),
259                 TestProvidersAccess.HOME,
260                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FOLDER_1.derivedUri,
261                         TestEnv.FILE_JPG.derivedUri),
262                 mDetails,
263                 mIconHelper,
264                 TestEnv.FOLDER_0);
265 
266         assertTrue(mManager.canSpringOpen(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_2));
267     }
268 
269     @Test
testDefaultToUnknownState()270     public void testDefaultToUnknownState() {
271         mManager.startDrag(
272                 mStartDragView,
273                 Arrays.asList(TestEnv.FOLDER_1, TestEnv.FILE_JPG),
274                 TestProvidersAccess.HOME,
275                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FOLDER_1.derivedUri,
276                         TestEnv.FILE_JPG.derivedUri),
277                 mDetails,
278                 mIconHelper,
279                 TestEnv.FOLDER_0);
280 
281         mShadowBuilder.state.assertLastArgument(DragAndDropManager.STATE_UNKNOWN);
282     }
283 
284     @Test
testUpdateStateToNotAllowed()285     public void testUpdateStateToNotAllowed() {
286         mManager.startDrag(
287                 mStartDragView,
288                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
289                 TestProvidersAccess.HOME,
290                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
291                         TestEnv.FILE_JPG.derivedUri),
292                 mDetails,
293                 mIconHelper,
294                 TestEnv.FOLDER_0);
295 
296         mManager.updateStateToNotAllowed(mUpdateShadowView);
297 
298         assertStateUpdated(DragAndDropManager.STATE_NOT_ALLOWED);
299     }
300 
301     @Test
testUpdateState_UpdatesToNotAllowed_RootNotSupportCreate()302     public void testUpdateState_UpdatesToNotAllowed_RootNotSupportCreate() {
303         mManager.startDrag(
304                 mStartDragView,
305                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
306                 TestProvidersAccess.HOME,
307                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
308                         TestEnv.FILE_JPG.derivedUri),
309                 mDetails,
310                 mIconHelper,
311                 TestEnv.FOLDER_0);
312 
313         final @State int state = mManager.updateState(
314                 mUpdateShadowView, TestProvidersAccess.HAMMY, TestEnv.FOLDER_2);
315 
316         assertEquals(DragAndDropManager.STATE_NOT_ALLOWED, state);
317         assertStateUpdated(DragAndDropManager.STATE_NOT_ALLOWED);
318     }
319 
320     @Test
testUpdateState_UpdatesToUnknown_RootDocIsNull()321     public void testUpdateState_UpdatesToUnknown_RootDocIsNull() {
322         mManager.startDrag(
323                 mStartDragView,
324                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
325                 TestProvidersAccess.HOME,
326                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
327                         TestEnv.FILE_JPG.derivedUri),
328                 mDetails,
329                 mIconHelper,
330                 TestEnv.FOLDER_0);
331 
332         final @State int state = mManager.updateState(
333                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, null);
334 
335         assertEquals(DragAndDropManager.STATE_UNKNOWN, state);
336         assertStateUpdated(DragAndDropManager.STATE_UNKNOWN);
337     }
338 
339     @Test
testUpdateState_UpdatesToMove_SameRoot()340     public void testUpdateState_UpdatesToMove_SameRoot() {
341         mManager.startDrag(
342                 mStartDragView,
343                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
344                 TestProvidersAccess.DOWNLOADS,
345                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
346                         TestEnv.FILE_JPG.derivedUri),
347                 mDetails,
348                 mIconHelper,
349                 TestEnv.FOLDER_0);
350 
351         final @State int state = mManager.updateState(
352                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
353 
354         assertEquals(DragAndDropManager.STATE_MOVE, state);
355         assertStateUpdated(DragAndDropManager.STATE_MOVE);
356     }
357 
358     @Test
testUpdateState_UpdatesToCopy_DifferentRoot()359     public void testUpdateState_UpdatesToCopy_DifferentRoot() {
360         mManager.startDrag(
361                 mStartDragView,
362                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
363                 TestProvidersAccess.HOME,
364                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
365                         TestEnv.FILE_JPG.derivedUri),
366                 mDetails,
367                 mIconHelper,
368                 TestEnv.FOLDER_0);
369 
370         final @State int state = mManager.updateState(
371                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
372 
373         assertEquals(DragAndDropManager.STATE_COPY, state);
374         assertStateUpdated(DragAndDropManager.STATE_COPY);
375     }
376 
377     @Test
testUpdateState_UpdatesToCopy_SameRoot_LeftCtrlPressed()378     public void testUpdateState_UpdatesToCopy_SameRoot_LeftCtrlPressed() {
379         mManager.startDrag(
380                 mStartDragView,
381                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
382                 TestProvidersAccess.DOWNLOADS,
383                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
384                         TestEnv.FILE_JPG.derivedUri),
385                 mDetails,
386                 mIconHelper,
387                 TestEnv.FOLDER_0);
388 
389         KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN);
390         mManager.onKeyEvent(event);
391 
392         final @State int state = mManager.updateState(
393                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
394 
395         assertEquals(DragAndDropManager.STATE_COPY, state);
396         assertStateUpdated(DragAndDropManager.STATE_COPY);
397     }
398 
399     @Test
testUpdateState_UpdatesToCopy_SameRoot_RightCtrlPressed()400     public void testUpdateState_UpdatesToCopy_SameRoot_RightCtrlPressed() {
401         mManager.startDrag(
402                 mStartDragView,
403                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
404                 TestProvidersAccess.DOWNLOADS,
405                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
406                         TestEnv.FILE_JPG.derivedUri),
407                 mDetails,
408                 mIconHelper,
409                 TestEnv.FOLDER_0);
410 
411         KeyEvent event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_DOWN);
412         mManager.onKeyEvent(event);
413 
414         final @State int state = mManager.updateState(
415                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
416 
417         assertEquals(DragAndDropManager.STATE_COPY, state);
418         assertStateUpdated(DragAndDropManager.STATE_COPY);
419     }
420 
421     @Test
testUpdateState_UpdatesToMove_DifferentRoot_LeftCtrlPressed()422     public void testUpdateState_UpdatesToMove_DifferentRoot_LeftCtrlPressed() {
423         mManager.startDrag(
424                 mStartDragView,
425                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
426                 TestProvidersAccess.HOME,
427                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
428                         TestEnv.FILE_JPG.derivedUri),
429                 mDetails,
430                 mIconHelper,
431                 TestEnv.FOLDER_0);
432 
433         KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN);
434         mManager.onKeyEvent(event);
435 
436         final @State int state = mManager.updateState(
437                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
438 
439         assertEquals(DragAndDropManager.STATE_MOVE, state);
440         assertStateUpdated(DragAndDropManager.STATE_MOVE);
441     }
442 
443     @Test
testUpdateState_UpdatesToMove_DifferentRoot_RightCtrlPressed()444     public void testUpdateState_UpdatesToMove_DifferentRoot_RightCtrlPressed() {
445         mManager.startDrag(
446                 mStartDragView,
447                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
448                 TestProvidersAccess.HOME,
449                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
450                         TestEnv.FILE_JPG.derivedUri),
451                 mDetails,
452                 mIconHelper,
453                 TestEnv.FOLDER_0);
454 
455         KeyEvent event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_DOWN);
456         mManager.onKeyEvent(event);
457 
458         final @State int state = mManager.updateState(
459                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
460 
461         assertEquals(DragAndDropManager.STATE_MOVE, state);
462         assertStateUpdated(DragAndDropManager.STATE_MOVE);
463     }
464 
465     @Test
testUpdateState_UpdatesToMove_SameRoot_LeftCtrlReleased()466     public void testUpdateState_UpdatesToMove_SameRoot_LeftCtrlReleased() {
467         mManager.startDrag(
468                 mStartDragView,
469                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
470                 TestProvidersAccess.DOWNLOADS,
471                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
472                         TestEnv.FILE_JPG.derivedUri),
473                 mDetails,
474                 mIconHelper,
475                 TestEnv.FOLDER_0);
476 
477         KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN);
478         mManager.onKeyEvent(event);
479 
480         event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_UP);
481         mManager.onKeyEvent(event);
482 
483         final @State int state = mManager.updateState(
484                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
485 
486         assertEquals(DragAndDropManager.STATE_MOVE, state);
487         assertStateUpdated(DragAndDropManager.STATE_MOVE);
488     }
489 
490     @Test
testUpdateState_UpdatesToMove_SameRoot_RightCtrlReleased()491     public void testUpdateState_UpdatesToMove_SameRoot_RightCtrlReleased() {
492         mManager.startDrag(
493                 mStartDragView,
494                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
495                 TestProvidersAccess.DOWNLOADS,
496                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
497                         TestEnv.FILE_JPG.derivedUri),
498                 mDetails,
499                 mIconHelper,
500                 TestEnv.FOLDER_0);
501 
502         KeyEvent event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_DOWN);
503         mManager.onKeyEvent(event);
504 
505         event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_UP);
506         mManager.onKeyEvent(event);
507 
508         final @State int state = mManager.updateState(
509                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
510 
511         assertEquals(DragAndDropManager.STATE_MOVE, state);
512         assertStateUpdated(DragAndDropManager.STATE_MOVE);
513     }
514 
515     @Test
testUpdateState_UpdatesToCopy_DifferentRoot_LeftCtrlReleased()516     public void testUpdateState_UpdatesToCopy_DifferentRoot_LeftCtrlReleased() {
517         mManager.startDrag(
518                 mStartDragView,
519                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
520                 TestProvidersAccess.HOME,
521                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
522                         TestEnv.FILE_JPG.derivedUri),
523                 mDetails,
524                 mIconHelper,
525                 TestEnv.FOLDER_0);
526 
527         KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN);
528         mManager.onKeyEvent(event);
529 
530         event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_UP);
531         mManager.onKeyEvent(event);
532 
533         final @State int state = mManager.updateState(
534                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
535 
536         assertEquals(DragAndDropManager.STATE_COPY, state);
537         assertStateUpdated(DragAndDropManager.STATE_COPY);
538     }
539 
540     @Test
testUpdateState_UpdatesToCopy_DifferentRoot_RightCtrlReleased()541     public void testUpdateState_UpdatesToCopy_DifferentRoot_RightCtrlReleased() {
542         mManager.startDrag(
543                 mStartDragView,
544                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
545                 TestProvidersAccess.HOME,
546                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
547                         TestEnv.FILE_JPG.derivedUri),
548                 mDetails,
549                 mIconHelper,
550                 TestEnv.FOLDER_0);
551 
552         KeyEvent event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_DOWN);
553         mManager.onKeyEvent(event);
554 
555         event = KeyEvents.createRightCtrlKey(KeyEvent.ACTION_UP);
556         mManager.onKeyEvent(event);
557 
558         final @State int state = mManager.updateState(
559                 mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
560 
561         assertEquals(DragAndDropManager.STATE_COPY, state);
562         assertStateUpdated(DragAndDropManager.STATE_COPY);
563     }
564 
565     @Test
testResetState_UpdatesToUnknown()566     public void testResetState_UpdatesToUnknown() {
567         mManager.startDrag(
568                 mStartDragView,
569                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
570                 TestProvidersAccess.HOME,
571                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
572                         TestEnv.FILE_JPG.derivedUri),
573                 mDetails,
574                 mIconHelper,
575                 TestEnv.FOLDER_0);
576 
577         mManager.updateStateToNotAllowed(mUpdateShadowView);
578 
579         mManager.resetState(mUpdateShadowView);
580 
581         assertStateUpdated(DragAndDropManager.STATE_UNKNOWN);
582     }
583 
584     @Test
testDrop_Rejects_RootNotSupportCreate_DropOnRoot()585     public void testDrop_Rejects_RootNotSupportCreate_DropOnRoot() {
586         mManager.startDrag(
587                 mStartDragView,
588                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
589                 TestProvidersAccess.HOME,
590                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
591                         TestEnv.FILE_JPG.derivedUri),
592                 mDetails,
593                 mIconHelper,
594                 TestEnv.FOLDER_0);
595 
596         mManager.updateState(mUpdateShadowView, TestProvidersAccess.HAMMY, TestEnv.FOLDER_1);
597 
598         assertFalse(mManager.drop(
599                 mClipData, mManager, TestProvidersAccess.HAMMY, mActions, mCallback));
600     }
601 
602     @Test
testDrop_Rejects_InvalidRoot()603     public void testDrop_Rejects_InvalidRoot() {
604         RootInfo root = new RootInfo();
605         root.authority = TestProvidersAccess.HOME.authority;
606         root.documentId = TestEnv.FOLDER_0.documentId;
607 
608         mManager.startDrag(
609                 mStartDragView,
610                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
611                 root,
612                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
613                         TestEnv.FILE_JPG.derivedUri),
614                 mDetails,
615                 mIconHelper,
616                 TestEnv.FOLDER_0);
617 
618         mManager.updateState(mUpdateShadowView, TestProvidersAccess.HOME, TestEnv.FOLDER_0);
619 
620         assertFalse(mManager.drop(mClipData, mManager, root, mActions, mCallback));
621     }
622 
623     @Test
testDrop_Fails_NotGetRootDoc()624     public void testDrop_Fails_NotGetRootDoc() throws Exception {
625         mManager.startDrag(
626                 mStartDragView,
627                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
628                 TestProvidersAccess.HOME,
629                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
630                         TestEnv.FILE_JPG.derivedUri),
631                 mDetails,
632                 mIconHelper,
633                 TestEnv.FOLDER_0);
634 
635         mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
636 
637         mManager.drop(
638                 mClipData, mManager, TestProvidersAccess.DOWNLOADS, mActions, mCallback);
639 
640         mEnv.beforeAsserts();
641         mCallbackListener.assertLastArgument(FileOperations.Callback.STATUS_FAILED);
642     }
643 
644     @Test
testDrop_Copies_DifferentRoot_DropOnRoot()645     public void testDrop_Copies_DifferentRoot_DropOnRoot() throws Exception {
646         mActions.nextRootDocument = TestEnv.FOLDER_1;
647 
648         mManager.startDrag(
649                 mStartDragView,
650                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
651                 TestProvidersAccess.HOME,
652                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
653                         TestEnv.FILE_JPG.derivedUri),
654                 mDetails,
655                 mIconHelper,
656                 TestEnv.FOLDER_0);
657 
658         mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
659 
660         mManager.drop(
661                 mClipData, mManager, TestProvidersAccess.DOWNLOADS, mActions, mCallback);
662 
663         mEnv.beforeAsserts();
664         final DocumentStack expect =
665                 new DocumentStack(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
666         mClipper.copyFromClip.assertLastArgument(Pair.create(expect, mClipData));
667         mClipper.opType.assertLastArgument(FileOperationService.OPERATION_COPY);
668     }
669 
670     @Test
testDrop_Moves_SameRoot_DropOnRoot()671     public void testDrop_Moves_SameRoot_DropOnRoot() throws Exception {
672         mActions.nextRootDocument = TestEnv.FOLDER_1;
673 
674         mManager.startDrag(
675                 mStartDragView,
676                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
677                 TestProvidersAccess.DOWNLOADS,
678                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
679                         TestEnv.FILE_JPG.derivedUri),
680                 mDetails,
681                 mIconHelper,
682                 TestEnv.FOLDER_0);
683 
684         mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
685 
686         mManager.drop(
687                 mClipData, mManager, TestProvidersAccess.DOWNLOADS, mActions, mCallback);
688 
689         mEnv.beforeAsserts();
690         final DocumentStack expect =
691                 new DocumentStack(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
692         mClipper.copyFromClip.assertLastArgument(Pair.create(expect, mClipData));
693         mClipper.opType.assertLastArgument(FileOperationService.OPERATION_MOVE);
694     }
695 
696     @Test
testDrop_Copies_SameRoot_DropOnRoot_ReleasesCtrlBeforeGettingRootDocument()697     public void testDrop_Copies_SameRoot_DropOnRoot_ReleasesCtrlBeforeGettingRootDocument()
698             throws Exception{
699         mActions.nextRootDocument = TestEnv.FOLDER_1;
700 
701         mManager.startDrag(
702                 mStartDragView,
703                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
704                 TestProvidersAccess.DOWNLOADS,
705                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
706                         TestEnv.FILE_JPG.derivedUri),
707                 mDetails,
708                 mIconHelper,
709                 TestEnv.FOLDER_0);
710 
711         KeyEvent event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_DOWN);
712         mManager.onKeyEvent(event);
713 
714         mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
715 
716         mManager.drop(
717                 mClipData, mManager, TestProvidersAccess.DOWNLOADS, mActions, mCallback);
718 
719         event = KeyEvents.createLeftCtrlKey(KeyEvent.ACTION_UP);
720         mManager.onKeyEvent(event);
721 
722         mEnv.beforeAsserts();
723         final DocumentStack expect =
724                 new DocumentStack(TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1);
725         mClipper.copyFromClip.assertLastArgument(Pair.create(expect, mClipData));
726         mClipper.opType.assertLastArgument(FileOperationService.OPERATION_COPY);
727     }
728 
729     @Test
testDrop_Rejects_RootNotSupportCreate_DropOnDocument()730     public void testDrop_Rejects_RootNotSupportCreate_DropOnDocument() {
731         mManager.startDrag(
732                 mStartDragView,
733                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
734                 TestProvidersAccess.HOME,
735                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
736                         TestEnv.FILE_JPG.derivedUri),
737                 mDetails,
738                 mIconHelper,
739                 TestEnv.FOLDER_0);
740 
741         mManager.updateState(mUpdateShadowView, TestProvidersAccess.HAMMY, TestEnv.FOLDER_2);
742 
743         final DocumentStack stack = new DocumentStack(
744                 TestProvidersAccess.HAMMY, TestEnv.FOLDER_1, TestEnv.FOLDER_2);
745         assertFalse(mManager.drop(mClipData, mManager, stack, mCallback));
746     }
747 
748     @Test
testDrop_Copies_DifferentRoot_DropOnDocument()749     public void testDrop_Copies_DifferentRoot_DropOnDocument() {
750         mManager.startDrag(
751                 mStartDragView,
752                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
753                 TestProvidersAccess.HOME,
754                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
755                         TestEnv.FILE_JPG.derivedUri),
756                 mDetails,
757                 mIconHelper,
758                 TestEnv.FOLDER_0);
759 
760         mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_2);
761 
762         final DocumentStack stack = new DocumentStack(
763                 TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1, TestEnv.FOLDER_2);
764         assertTrue(mManager.drop(mClipData, mManager, stack, mCallback));
765 
766         mClipper.copyFromClip.assertLastArgument(Pair.create(stack, mClipData));
767         mClipper.opType.assertLastArgument(FileOperationService.OPERATION_COPY);
768     }
769 
770     @Test
testDrop_Moves_SameRoot_DropOnDocument()771     public void testDrop_Moves_SameRoot_DropOnDocument() {
772         mManager.startDrag(
773                 mStartDragView,
774                 Arrays.asList(TestEnv.FILE_APK, TestEnv.FILE_JPG),
775                 TestProvidersAccess.DOWNLOADS,
776                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_APK.derivedUri,
777                         TestEnv.FILE_JPG.derivedUri),
778                 mDetails,
779                 mIconHelper,
780                 TestEnv.FOLDER_0);
781 
782         mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_2);
783 
784         final DocumentStack stack = new DocumentStack(
785                 TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1, TestEnv.FOLDER_2);
786         assertTrue(mManager.drop(mClipData, mManager, stack, mCallback));
787 
788         mClipper.copyFromClip.assertLastArgument(Pair.create(stack, mClipData));
789         mClipper.opType.assertLastArgument(FileOperationService.OPERATION_MOVE);
790     }
791 
792     @Test
testDrop_Copies_SameRoot_ReadOnlyFile_DropOnDocument()793     public void testDrop_Copies_SameRoot_ReadOnlyFile_DropOnDocument() {
794         mDetails.canDelete = false;
795         mManager.startDrag(
796                 mStartDragView,
797                 Arrays.asList(TestEnv.FILE_READ_ONLY),
798                 TestProvidersAccess.DOWNLOADS,
799                 Arrays.asList(TestEnv.FOLDER_0.derivedUri, TestEnv.FILE_READ_ONLY.derivedUri),
800                 mDetails,
801                 mIconHelper,
802                 TestEnv.FOLDER_0);
803 
804         mManager.updateState(mUpdateShadowView, TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_2);
805 
806         final DocumentStack stack = new DocumentStack(
807                 TestProvidersAccess.DOWNLOADS, TestEnv.FOLDER_1, TestEnv.FOLDER_2);
808         assertTrue(mManager.drop(mClipData, mManager, stack, mCallback));
809 
810         mClipper.copyFromClip.assertLastArgument(Pair.create(stack, mClipData));
811         mClipper.opType.assertLastArgument(FileOperationService.OPERATION_COPY);
812     }
813 
assertStateUpdated(@tate int expected)814     private void assertStateUpdated(@State int expected) {
815         mShadowBuilder.state.assertLastArgument(expected);
816         mShadowUpdateListener.assertCalled();
817     }
818 
819     public static class TestDragShadowBuilder extends DragShadowBuilder {
820 
821         public TestEventListener<String> title;
822         public TestEventListener<Drawable> icon;
823         public TestEventListener<Integer> state;
824 
TestDragShadowBuilder()825         private TestDragShadowBuilder() {
826             super(null);
827         }
828 
829         @Override
updateTitle(String title)830         void updateTitle(String title) {
831             this.title.accept(title);
832         }
833 
834         @Override
updateIcon(Drawable icon)835         void updateIcon(Drawable icon) {
836             this.icon.accept(icon);
837         }
838 
839         @Override
onStateUpdated(@tate int state)840         void onStateUpdated(@State int state) {
841             this.state.accept(state);
842         }
843 
create()844         public static TestDragShadowBuilder create() {
845             TestDragShadowBuilder builder =
846                     Mockito.mock(TestDragShadowBuilder.class, Mockito.CALLS_REAL_METHODS);
847 
848             builder.title = new TestEventListener<>();
849             builder.icon = new TestEventListener<>();
850             builder.state = new TestEventListener<>();
851 
852             return builder;
853         }
854     }
855 }
856