Home | History | Annotate | Download | only in picker
      1 /*
      2  * Copyright (C) 2016 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.picker;
     18 
     19 import static junit.framework.Assert.assertTrue;
     20 
     21 import static org.junit.Assert.assertEquals;
     22 import static org.junit.Assert.assertNotNull;
     23 
     24 import android.app.Activity;
     25 import android.content.ClipData;
     26 import android.content.Intent;
     27 import android.net.Uri;
     28 import android.os.AsyncTask;
     29 import android.provider.DocumentsContract;
     30 import android.provider.DocumentsContract.Path;
     31 import android.support.test.filters.MediumTest;
     32 import android.support.test.runner.AndroidJUnit4;
     33 
     34 import com.android.documentsui.AbstractActionHandler;
     35 import com.android.documentsui.R;
     36 import com.android.documentsui.base.DocumentStack;
     37 import com.android.documentsui.base.RootInfo;
     38 import com.android.documentsui.base.Shared;
     39 import com.android.documentsui.base.State;
     40 import com.android.documentsui.base.State.ActionType;
     41 import com.android.documentsui.testing.DocumentStackAsserts;
     42 import com.android.documentsui.testing.TestEnv;
     43 import com.android.documentsui.testing.TestProvidersAccess;
     44 import com.android.documentsui.testing.TestLastAccessedStorage;
     45 import com.android.documentsui.testing.TestResolveInfo;
     46 
     47 import org.junit.AfterClass;
     48 import org.junit.Before;
     49 import org.junit.Test;
     50 import org.junit.runner.RunWith;
     51 
     52 import java.util.Arrays;
     53 
     54 @RunWith(AndroidJUnit4.class)
     55 @MediumTest
     56 public class ActionHandlerTest {
     57 
     58     private TestEnv mEnv;
     59     private TestActivity mActivity;
     60     private ActionHandler<TestActivity> mHandler;
     61     private TestLastAccessedStorage mLastAccessed;
     62 
     63     @Before
     64     public void setUp() {
     65         mEnv = TestEnv.create();
     66         mActivity = TestActivity.create(mEnv);
     67         mEnv.roots.configurePm(mActivity.packageMgr);
     68         mLastAccessed = new TestLastAccessedStorage();
     69 
     70         mHandler = new ActionHandler<>(
     71                 mActivity,
     72                 mEnv.state,
     73                 mEnv.roots,
     74                 mEnv.docs,
     75                 mEnv.searchViewManager,
     76                 mEnv::lookupExecutor,
     77                 mEnv.injector,
     78                 mLastAccessed
     79         );
     80 
     81         mEnv.dialogs.confirmNext();
     82 
     83         mEnv.selectionMgr.toggleSelection("1");
     84 
     85         AsyncTask.setDefaultExecutor(mEnv.mExecutor);
     86     }
     87 
     88     @AfterClass
     89     public static void tearDownOnce() {
     90         AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     91     }
     92 
     93     @Test
     94     public void testInitLocation_CopyDestination_DefaultsToDownloads() throws Exception {
     95         mActivity.resources.bools.put(R.bool.show_documents_root, false);
     96 
     97         Intent intent = mActivity.getIntent();
     98         intent.setAction(Shared.ACTION_PICK_COPY_DESTINATION);
     99         mHandler.initLocation(mActivity.getIntent());
    100         assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri());
    101     }
    102 
    103     @Test
    104     public void testInitLocation_CopyDestination_DocumentsRootEnabled() throws Exception {
    105         mActivity.resources.bools.put(R.bool.show_documents_root, true);
    106 
    107         Intent intent = mActivity.getIntent();
    108         intent.setAction(Shared.ACTION_PICK_COPY_DESTINATION);
    109         mHandler.initLocation(intent);
    110         assertRootPicked(TestProvidersAccess.HOME.getUri());
    111     }
    112 
    113     @Test
    114     public void testInitLocation_LaunchToDocuments() throws Exception {
    115         mEnv.docs.nextIsDocumentsUri = true;
    116         mEnv.docs.nextPath = new Path(
    117                 TestProvidersAccess.HOME.rootId,
    118                 Arrays.asList(
    119                         TestEnv.FOLDER_0.documentId,
    120                         TestEnv.FOLDER_1.documentId,
    121                         TestEnv.FILE_GIF.documentId));
    122         mEnv.docs.nextDocuments =
    123                 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1, TestEnv.FILE_GIF);
    124 
    125         mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
    126         Intent intent = mActivity.getIntent();
    127         intent.setAction(Intent.ACTION_GET_CONTENT);
    128         intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, TestEnv.FILE_GIF.derivedUri);
    129         mHandler.initLocation(intent);
    130 
    131         mEnv.beforeAsserts();
    132 
    133         DocumentStackAsserts.assertEqualsTo(mEnv.state.stack, TestProvidersAccess.HOME,
    134                 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1));
    135         mActivity.refreshCurrentRootAndDirectory.assertCalled();
    136     }
    137 
    138     @Test
    139     public void testInitLocation_RestoresLastAccessedStack() throws Exception {
    140         final DocumentStack stack =
    141                 new DocumentStack(TestProvidersAccess.HAMMY, TestEnv.FOLDER_0, TestEnv.FOLDER_1);
    142         mLastAccessed.setLastAccessed(mActivity, stack);
    143 
    144         mHandler.initLocation(mActivity.getIntent());
    145 
    146         mEnv.beforeAsserts();
    147         assertEquals(stack, mEnv.state.stack);
    148         mActivity.refreshCurrentRootAndDirectory.assertCalled();
    149     }
    150 
    151     @Test
    152     public void testInitLocation_DefaultToRecents_ActionGetContent() throws Exception {
    153         testInitLocationDefaultToRecentsOnAction(State.ACTION_GET_CONTENT);
    154     }
    155 
    156     @Test
    157     public void testInitLocation_DefaultToRecents_ActionOpen() throws Exception {
    158         testInitLocationDefaultToRecentsOnAction(State.ACTION_OPEN);
    159     }
    160 
    161     @Test
    162     public void testInitLocation_DefaultToRecents_ActionOpenTree() throws Exception {
    163         testInitLocationDefaultToRecentsOnAction(State.ACTION_OPEN_TREE);
    164     }
    165 
    166     @Test
    167     public void testInitLocation_DefaultsToDownloads_ActionCreate() throws Exception {
    168         mEnv.state.action = State.ACTION_CREATE;
    169         mActivity.resources.bools.put(R.bool.show_documents_root, false);
    170 
    171         mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
    172 
    173         mHandler.initLocation(mActivity.getIntent());
    174 
    175         assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri());
    176     }
    177 
    178     @Test
    179     public void testOpenContainerDocument() {
    180         mHandler.openContainerDocument(TestEnv.FOLDER_0);
    181 
    182         assertEquals(TestEnv.FOLDER_0, mEnv.state.stack.peek());
    183 
    184         mActivity.refreshCurrentRootAndDirectory.assertCalled();
    185     }
    186 
    187     @Test
    188     public void testPickDocument_SetsCorrectResultAndFinishes_ActionPickCopyDestination()
    189             throws Exception {
    190 
    191         mEnv.state.action = State.ACTION_PICK_COPY_DESTINATION;
    192         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    193         mEnv.state.stack.push(TestEnv.FOLDER_1);
    194         mEnv.state.stack.push(TestEnv.FOLDER_2);
    195 
    196         mActivity.finishedHandler.assertNotCalled();
    197 
    198         mHandler.pickDocument(TestEnv.FOLDER_2);
    199 
    200         mEnv.beforeAsserts();
    201 
    202         assertLastAccessedStackUpdated();
    203 
    204         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    205         final Intent result = mActivity.setResult.getLastValue().second;
    206         assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
    207         assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
    208         assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
    209         assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
    210         assertContent(result, TestEnv.FOLDER_2.derivedUri);
    211 
    212         mActivity.finishedHandler.assertCalled();
    213     }
    214 
    215     @Test
    216     public void testPickDocument_SetsCorrectResultAndFinishes_ActionOpenTree() throws Exception {
    217         mEnv.state.action = State.ACTION_OPEN_TREE;
    218         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    219         mEnv.state.stack.push(TestEnv.FOLDER_1);
    220         mEnv.state.stack.push(TestEnv.FOLDER_2);
    221 
    222         mActivity.finishedHandler.assertNotCalled();
    223 
    224         mHandler.pickDocument(TestEnv.FOLDER_2);
    225 
    226         mEnv.beforeAsserts();
    227 
    228         assertLastAccessedStackUpdated();
    229 
    230         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    231         final Intent result = mActivity.setResult.getLastValue().second;
    232         assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    233         assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    234         assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
    235         assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, true);
    236         assertContent(result, DocumentsContract.buildTreeDocumentUri(
    237                 TestProvidersAccess.HOME.authority, TestEnv.FOLDER_2.documentId));
    238 
    239         mActivity.finishedHandler.assertCalled();
    240     }
    241 
    242     @Test
    243     public void testSaveDocument_SetsCorrectResultAndFinishes() throws Exception {
    244         mEnv.state.action = State.ACTION_CREATE;
    245         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    246         mEnv.state.stack.push(TestEnv.FOLDER_1);
    247 
    248         final String mimeType = "audio/aac";
    249         final String displayName = "foobar.m4a";
    250 
    251         mHandler.saveDocument(mimeType, displayName, (boolean inProgress) -> {});
    252 
    253         mEnv.beforeAsserts();
    254 
    255         mEnv.docs.assertCreatedDocument(TestEnv.FOLDER_1, mimeType, displayName);
    256         final Uri docUri = mEnv.docs.getLastCreatedDocumentUri();
    257 
    258         assertLastAccessedStackUpdated();
    259 
    260         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    261         final Intent result = mActivity.setResult.getLastValue().second;
    262         assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    263         assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    264         assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
    265         assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
    266         assertContent(result, docUri);
    267 
    268         mActivity.finishedHandler.assertCalled();
    269     }
    270 
    271     @Test
    272     public void testSaveDocument_ConfirmsOverwrite() {
    273         mEnv.state.action = State.ACTION_CREATE;
    274         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    275         mEnv.state.stack.push(TestEnv.FOLDER_1);
    276 
    277         mHandler.saveDocument(null, TestEnv.FILE_JPG);
    278 
    279         mEnv.dialogs.assertOverwriteConfirmed(TestEnv.FILE_JPG);
    280     }
    281 
    282     @Test
    283     public void testFinishPicking_SetsCorrectResultAndFinishes_ActionGetContent() throws Exception {
    284         mEnv.state.action = State.ACTION_GET_CONTENT;
    285         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    286         mEnv.state.stack.push(TestEnv.FOLDER_1);
    287 
    288         mActivity.finishedHandler.assertNotCalled();
    289 
    290         mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri);
    291 
    292         mEnv.beforeAsserts();
    293 
    294         assertLastAccessedStackUpdated();
    295 
    296         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    297         final Intent result = mActivity.setResult.getLastValue().second;
    298         assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    299         assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
    300         assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
    301         assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
    302         assertContent(result, TestEnv.FILE_JPG.derivedUri);
    303 
    304         mActivity.finishedHandler.assertCalled();
    305     }
    306 
    307     @Test
    308     public void testFinishPicking_SetsCorrectResultAndFinishes_ActionGetContent_MultipleSelection()
    309             throws Exception {
    310         mEnv.state.action = State.ACTION_GET_CONTENT;
    311         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    312         mEnv.state.stack.push(TestEnv.FOLDER_1);
    313         mEnv.state.acceptMimes = new String[] { "image/*" };
    314 
    315         mActivity.finishedHandler.assertNotCalled();
    316 
    317         mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri, TestEnv.FILE_GIF.derivedUri);
    318 
    319         mEnv.beforeAsserts();
    320 
    321         assertLastAccessedStackUpdated();
    322 
    323         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    324         final Intent result = mActivity.setResult.getLastValue().second;
    325         assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    326         assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
    327         assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
    328         assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
    329         assertContent(result, TestEnv.FILE_JPG.derivedUri, TestEnv.FILE_GIF.derivedUri);
    330 
    331         mActivity.finishedHandler.assertCalled();
    332     }
    333 
    334     @Test
    335     public void testFinishPicking_SetsCorrectResultAndFinishes_ActionOpen() throws Exception {
    336         mEnv.state.action = State.ACTION_OPEN;
    337         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    338         mEnv.state.stack.push(TestEnv.FOLDER_1);
    339 
    340         mActivity.finishedHandler.assertNotCalled();
    341 
    342         mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri);
    343 
    344         mEnv.beforeAsserts();
    345 
    346         assertLastAccessedStackUpdated();
    347 
    348         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    349         final Intent result = mActivity.setResult.getLastValue().second;
    350         assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    351         assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    352         assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
    353         assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
    354         assertContent(result, TestEnv.FILE_JPG.derivedUri);
    355 
    356         mActivity.finishedHandler.assertCalled();
    357     }
    358 
    359     @Test
    360     public void testFinishPicking_SetsCorrectResultAndFinishes_ActionOpen_MultipleSelection()
    361             throws Exception {
    362         mEnv.state.action = State.ACTION_OPEN;
    363         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    364         mEnv.state.stack.push(TestEnv.FOLDER_1);
    365         mEnv.state.acceptMimes = new String[] { "image/*" };
    366 
    367         mActivity.finishedHandler.assertNotCalled();
    368 
    369         mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri, TestEnv.FILE_GIF.derivedUri);
    370 
    371         mEnv.beforeAsserts();
    372 
    373         assertLastAccessedStackUpdated();
    374 
    375         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    376         final Intent result = mActivity.setResult.getLastValue().second;
    377         assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    378         assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    379         assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
    380         assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
    381         assertContent(result, TestEnv.FILE_JPG.derivedUri, TestEnv.FILE_GIF.derivedUri);
    382 
    383         mActivity.finishedHandler.assertCalled();
    384     }
    385 
    386     @Test
    387     public void testFinishPicking_SetsCorrectResultAndFinishes_ActionCreate() throws Exception {
    388         mEnv.state.action = State.ACTION_CREATE;
    389         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
    390         mEnv.state.stack.push(TestEnv.FOLDER_1);
    391 
    392         mActivity.finishedHandler.assertNotCalled();
    393 
    394         mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri);
    395 
    396         mEnv.beforeAsserts();
    397 
    398         assertLastAccessedStackUpdated();
    399 
    400         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    401         final Intent result = mActivity.setResult.getLastValue().second;
    402         assertPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    403         assertPermission(result, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    404         assertPermission(result, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
    405         assertPermission(result, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
    406         assertContent(result, TestEnv.FILE_JPG.derivedUri);
    407 
    408         mActivity.finishedHandler.assertCalled();
    409     }
    410 
    411     @Test
    412     public void testOnAppPickedResult_OnOK() throws Exception {
    413         Intent intent = new Intent();
    414         mHandler.onActivityResult(AbstractActionHandler.CODE_FORWARD, Activity.RESULT_OK, intent);
    415         mActivity.finishedHandler.assertCalled();
    416         mActivity.setResult.assertCalled();
    417 
    418         assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first);
    419         assertEquals(intent, mActivity.setResult.getLastValue().second);
    420     }
    421 
    422     @Test
    423     public void testOnAppPickedResult_OnNotOK() throws Exception {
    424         Intent intent = new Intent();
    425         mHandler.onActivityResult(0, Activity.RESULT_OK, intent);
    426         mActivity.finishedHandler.assertNotCalled();
    427         mActivity.setResult.assertNotCalled();
    428 
    429         mHandler.onActivityResult(AbstractActionHandler.CODE_FORWARD, Activity.RESULT_CANCELED,
    430                 intent);
    431         mActivity.finishedHandler.assertNotCalled();
    432         mActivity.setResult.assertNotCalled();
    433     }
    434 
    435     @Test
    436     public void testOpenAppRoot() throws Exception {
    437         mHandler.openRoot(TestResolveInfo.create());
    438         assertEquals((long) mActivity.startActivityForResult.getLastValue().second,
    439                 AbstractActionHandler.CODE_FORWARD);
    440         assertNotNull(mActivity.startActivityForResult.getLastValue().first);
    441     }
    442 
    443     private void testInitLocationDefaultToRecentsOnAction(@ActionType int action)
    444             throws Exception {
    445         mEnv.state.action = action;
    446 
    447         mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
    448 
    449         mHandler.initLocation(mActivity.getIntent());
    450 
    451         mEnv.beforeAsserts();
    452         assertEquals(TestProvidersAccess.RECENTS, mEnv.state.stack.getRoot());
    453         mActivity.refreshCurrentRootAndDirectory.assertCalled();
    454     }
    455 
    456     private void assertRootPicked(Uri expectedUri) throws Exception {
    457         mEnv.beforeAsserts();
    458 
    459         mActivity.rootPicked.assertCalled();
    460         RootInfo root = mActivity.rootPicked.getLastValue();
    461         assertNotNull(root);
    462         assertEquals(expectedUri, root.getUri());
    463     }
    464 
    465     private void assertLastAccessedStackUpdated() {
    466         assertEquals(
    467                 mEnv.state.stack, mLastAccessed.getLastAccessed(mActivity, mEnv.roots, mEnv.state));
    468     }
    469 
    470     private void assertPermission(Intent intent, int permission, boolean granted) {
    471         int flags = intent.getFlags();
    472 
    473         if (granted) {
    474             assertEquals(permission, flags & permission);
    475         } else {
    476             assertEquals(0, flags & permission);
    477         }
    478     }
    479 
    480     private void assertContent(Intent intent, Uri... contents) {
    481         if (contents.length == 1) {
    482             assertEquals(contents[0], intent.getData());
    483         } else {
    484             ClipData clipData = intent.getClipData();
    485 
    486             assertNotNull(clipData);
    487             for (int i = 0; i < mEnv.state.acceptMimes.length; ++i) {
    488                 assertEquals(mEnv.state.acceptMimes[i], clipData.getDescription().getMimeType(i));
    489             }
    490             for (int i = 0; i < contents.length; ++i) {
    491                 assertEquals(contents[i], clipData.getItemAt(i).getUri());
    492             }
    493         }
    494     }
    495 }
    496