Home | History | Annotate | Download | only in files
      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.files;
     18 
     19 import static com.android.documentsui.testing.IntentAsserts.assertHasAction;
     20 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraIntent;
     21 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraList;
     22 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraUri;
     23 import static org.junit.Assert.assertEquals;
     24 import static org.junit.Assert.assertFalse;
     25 import static org.junit.Assert.assertNotNull;
     26 import static org.junit.Assert.assertNull;
     27 import static org.junit.Assert.assertSame;
     28 import static org.junit.Assert.assertTrue;
     29 
     30 import android.app.Activity;
     31 import android.app.PendingIntent;
     32 import android.content.ClipData;
     33 import android.content.Intent;
     34 import android.net.Uri;
     35 import android.os.Parcelable;
     36 import android.provider.DocumentsContract;
     37 import android.provider.DocumentsContract.Path;
     38 import android.support.test.filters.MediumTest;
     39 import android.support.test.InstrumentationRegistry;
     40 import android.support.test.runner.AndroidJUnit4;
     41 import android.view.DragEvent;
     42 
     43 import com.android.documentsui.AbstractActionHandler;
     44 import com.android.documentsui.R;
     45 import com.android.documentsui.TestActionModeAddons;
     46 import com.android.documentsui.archives.ArchivesProvider;
     47 import com.android.documentsui.base.DocumentInfo;
     48 import com.android.documentsui.base.DocumentStack;
     49 import com.android.documentsui.base.RootInfo;
     50 import com.android.documentsui.base.Shared;
     51 import com.android.documentsui.testing.ClipDatas;
     52 import com.android.documentsui.testing.DocumentStackAsserts;
     53 import com.android.documentsui.testing.Roots;
     54 import com.android.documentsui.testing.TestActivityConfig;
     55 import com.android.documentsui.testing.TestConfirmationCallback;
     56 import com.android.documentsui.testing.TestDocumentClipper;
     57 import com.android.documentsui.testing.TestEnv;
     58 import com.android.documentsui.testing.TestProvidersAccess;
     59 import com.android.documentsui.ui.TestDialogController;
     60 
     61 import org.junit.Before;
     62 import org.junit.Test;
     63 import org.junit.runner.RunWith;
     64 
     65 import java.util.ArrayList;
     66 import java.util.Arrays;
     67 import java.util.List;
     68 
     69 @RunWith(AndroidJUnit4.class)
     70 @MediumTest
     71 public class ActionHandlerTest {
     72 
     73     private TestEnv mEnv;
     74     private TestActivity mActivity;
     75     private TestActionModeAddons mActionModeAddons;
     76     private TestDialogController mDialogs;
     77     private TestConfirmationCallback mCallback;
     78     private ActionHandler<TestActivity> mHandler;
     79     private TestDocumentClipper mClipper;
     80     private boolean refreshAnswer = false;
     81 
     82     @Before
     83     public void setUp() {
     84         mEnv = TestEnv.create();
     85         mActivity = TestActivity.create(mEnv);
     86         mActionModeAddons = new TestActionModeAddons();
     87         mDialogs = new TestDialogController();
     88         mCallback = new TestConfirmationCallback();
     89         mEnv.roots.configurePm(mActivity.packageMgr);
     90         ((TestActivityConfig) mEnv.injector.config).nextDocumentEnabled = true;
     91         mEnv.injector.dialogs = mDialogs;
     92         mClipper = new TestDocumentClipper();
     93 
     94         mHandler = createHandler();
     95 
     96         mDialogs.confirmNext();
     97 
     98         mEnv.selectDocument(TestEnv.FILE_GIF);
     99     }
    100 
    101     @Test
    102     public void testOpenSelectedInNewWindow() {
    103         mHandler.openSelectedInNewWindow();
    104 
    105         DocumentStack path = new DocumentStack(Roots.create("123"), mEnv.model.getDocument("1"));
    106 
    107         Intent expected = LauncherActivity.createLaunchIntent(mActivity);
    108         expected.putExtra(Shared.EXTRA_STACK, (Parcelable) path);
    109 
    110         Intent actual = mActivity.startActivity.getLastValue();
    111         assertEquals(expected.toString(), actual.toString());
    112     }
    113 
    114     @Test
    115     public void testSpringOpenDirectory() {
    116         mHandler.springOpenDirectory(TestEnv.FOLDER_0);
    117         assertTrue(mActionModeAddons.finishActionModeCalled);
    118         assertEquals(TestEnv.FOLDER_0, mEnv.state.stack.peek());
    119     }
    120 
    121     @Test
    122     public void testCutSelectedDocuments_NoGivenSelection() {
    123         mEnv.populateStack();
    124 
    125         mEnv.selectionMgr.clearSelection();
    126         mHandler.cutToClipboard();
    127         mDialogs.assertDocumentsClippedNotShown();
    128     }
    129 
    130     @Test
    131     public void testCopySelectedDocuments_NoGivenSelection() {
    132         mEnv.populateStack();
    133 
    134         mEnv.selectionMgr.clearSelection();
    135         mHandler.copyToClipboard();
    136         mDialogs.assertDocumentsClippedNotShown();
    137     }
    138 
    139     @Test
    140     public void testDeleteSelectedDocuments_NoSelection() {
    141         mEnv.populateStack();
    142 
    143         mEnv.selectionMgr.clearSelection();
    144         mHandler.deleteSelectedDocuments();
    145         mDialogs.assertNoFileFailures();
    146         mActivity.startService.assertNotCalled();
    147         mActionModeAddons.finishOnConfirmed.assertNeverCalled();
    148     }
    149 
    150     @Test
    151     public void testDeleteSelectedDocuments_Cancelable() {
    152         mEnv.populateStack();
    153 
    154         mDialogs.rejectNext();
    155         mHandler.deleteSelectedDocuments();
    156         mDialogs.assertNoFileFailures();
    157         mActivity.startService.assertNotCalled();
    158         mActionModeAddons.finishOnConfirmed.assertRejected();
    159     }
    160 
    161     // Recents root means when deleting the srcParent will be null.
    162     @Test
    163     public void testDeleteSelectedDocuments_RecentsRoot() {
    164         mEnv.state.stack.changeRoot(TestProvidersAccess.RECENTS);
    165 
    166         mHandler.deleteSelectedDocuments();
    167         mDialogs.assertNoFileFailures();
    168         mActivity.startService.assertCalled();
    169         mActionModeAddons.finishOnConfirmed.assertCalled();
    170     }
    171 
    172     @Test
    173     public void testShareSelectedDocuments_ShowsChooser() {
    174         mActivity.resources.strings.put(R.string.share_via, "Sharezilla!");
    175         mHandler.shareSelectedDocuments();
    176 
    177         mActivity.assertActivityStarted(Intent.ACTION_CHOOSER);
    178     }
    179 
    180     @Test
    181     public void testShareSelectedDocuments_Single() {
    182         mActivity.resources.strings.put(R.string.share_via, "Sharezilla!");
    183         mHandler.shareSelectedDocuments();
    184 
    185         Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue());
    186         assertHasAction(intent, Intent.ACTION_SEND);
    187         assertFalse(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE));
    188         assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE));
    189         assertHasExtraUri(intent, Intent.EXTRA_STREAM);
    190     }
    191 
    192     @Test
    193     public void testShareSelectedDocuments_ArchivedFile() {
    194         mEnv = TestEnv.create(ArchivesProvider.AUTHORITY);
    195         mHandler = createHandler();
    196 
    197         mActivity.resources.strings.put(R.string.share_via, "Sharezilla!");
    198         mEnv.selectionMgr.clearSelection();
    199         mEnv.selectDocument(TestEnv.FILE_PDF);
    200         mHandler.shareSelectedDocuments();
    201 
    202         Intent intent = mActivity.startActivity.getLastValue();
    203         assertNull(intent);
    204     }
    205 
    206     @Test
    207     public void testShareSelectedDocuments_Multiple() {
    208         mActivity.resources.strings.put(R.string.share_via, "Sharezilla!");
    209         mEnv.selectDocument(TestEnv.FILE_PDF);
    210         mHandler.shareSelectedDocuments();
    211 
    212         Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue());
    213         assertHasAction(intent, Intent.ACTION_SEND_MULTIPLE);
    214         assertFalse(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE));
    215         assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE));
    216         assertHasExtraList(intent, Intent.EXTRA_STREAM, 2);
    217     }
    218 
    219     @Test
    220     public void testShareSelectedDocuments_VirtualFiles() {
    221         mActivity.resources.strings.put(R.string.share_via, "Sharezilla!");
    222         mEnv.selectionMgr.clearSelection();
    223         mEnv.selectDocument(TestEnv.FILE_VIRTUAL);
    224         mHandler.shareSelectedDocuments();
    225 
    226         Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue());
    227         assertHasAction(intent, Intent.ACTION_SEND);
    228         assertTrue(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE));
    229         assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE));
    230         assertHasExtraUri(intent, Intent.EXTRA_STREAM);
    231     }
    232 
    233     @Test
    234     public void testShareSelectedDocuments_RegularAndVirtualFiles() {
    235         mActivity.resources.strings.put(R.string.share_via, "Sharezilla!");
    236         mEnv.selectDocument(TestEnv.FILE_PNG);
    237         mEnv.selectDocument(TestEnv.FILE_VIRTUAL);
    238         mHandler.shareSelectedDocuments();
    239 
    240         Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue());
    241         assertHasAction(intent, Intent.ACTION_SEND_MULTIPLE);
    242         assertTrue(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE));
    243         assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE));
    244         assertHasExtraList(intent, Intent.EXTRA_STREAM, 3);
    245     }
    246 
    247     @Test
    248     public void testShareSelectedDocuments_OmitsPartialFiles() {
    249         mActivity.resources.strings.put(R.string.share_via, "Sharezilla!");
    250         mEnv.selectDocument(TestEnv.FILE_PARTIAL);
    251         mEnv.selectDocument(TestEnv.FILE_PNG);
    252         mHandler.shareSelectedDocuments();
    253 
    254         Intent intent = assertHasExtraIntent(mActivity.startActivity.getLastValue());
    255         assertHasAction(intent, Intent.ACTION_SEND_MULTIPLE);
    256         assertFalse(intent.hasCategory(Intent.CATEGORY_TYPED_OPENABLE));
    257         assertFalse(intent.hasCategory(Intent.CATEGORY_OPENABLE));
    258         assertHasExtraList(intent, Intent.EXTRA_STREAM, 2);
    259     }
    260 
    261     @Test
    262     public void testDocumentPicked_DefaultsToView() throws Exception {
    263         mActivity.currentRoot = TestProvidersAccess.HOME;
    264 
    265         mHandler.openDocument(TestEnv.FILE_GIF, ActionHandler.VIEW_TYPE_PREVIEW,
    266                 ActionHandler.VIEW_TYPE_REGULAR);
    267         mActivity.assertActivityStarted(Intent.ACTION_VIEW);
    268     }
    269 
    270     @Test
    271     public void testDocumentPicked_InArchive_QuickViewable() throws Exception {
    272         mActivity.resources.setQuickViewerPackage("corptropolis.viewer");
    273         mActivity.currentRoot = TestProvidersAccess.HOME;
    274 
    275         mHandler.openDocument(TestEnv.FILE_IN_ARCHIVE, ActionHandler.VIEW_TYPE_PREVIEW,
    276                 ActionHandler.VIEW_TYPE_REGULAR);
    277         mActivity.assertActivityStarted(Intent.ACTION_QUICK_VIEW);
    278     }
    279 
    280     @Test
    281     public void testDocumentPicked_InArchive_Unopenable() throws Exception {
    282         mActivity.currentRoot = TestProvidersAccess.HOME;
    283 
    284         mHandler.openDocument(TestEnv.FILE_IN_ARCHIVE, ActionHandler.VIEW_TYPE_PREVIEW,
    285                 ActionHandler.VIEW_TYPE_REGULAR);
    286         mDialogs.assertViewInArchivesShownUnsupported();
    287     }
    288 
    289     @Test
    290     public void testDocumentPicked_PreviewsWhenResourceSet() throws Exception {
    291         mActivity.resources.setQuickViewerPackage("corptropolis.viewer");
    292         mActivity.currentRoot = TestProvidersAccess.HOME;
    293 
    294         mHandler.openDocument(TestEnv.FILE_GIF, ActionHandler.VIEW_TYPE_PREVIEW,
    295                 ActionHandler.VIEW_TYPE_REGULAR);
    296         mActivity.assertActivityStarted(Intent.ACTION_QUICK_VIEW);
    297     }
    298 
    299     @Test
    300     public void testDocumentPicked_Downloads_ManagesApks() throws Exception {
    301         mActivity.currentRoot = TestProvidersAccess.DOWNLOADS;
    302 
    303         mHandler.openDocument(TestEnv.FILE_APK, ActionHandler.VIEW_TYPE_PREVIEW,
    304                 ActionHandler.VIEW_TYPE_REGULAR);
    305         mActivity.assertActivityStarted(DocumentsContract.ACTION_MANAGE_DOCUMENT);
    306     }
    307 
    308     @Test
    309     public void testDocumentPicked_Downloads_ManagesPartialFiles() throws Exception {
    310         mActivity.currentRoot = TestProvidersAccess.DOWNLOADS;
    311 
    312         mHandler.openDocument(TestEnv.FILE_PARTIAL, ActionHandler.VIEW_TYPE_PREVIEW,
    313                 ActionHandler.VIEW_TYPE_REGULAR);
    314         mActivity.assertActivityStarted(DocumentsContract.ACTION_MANAGE_DOCUMENT);
    315     }
    316 
    317     @Test
    318     public void testDocumentPicked_OpensArchives() throws Exception {
    319         mActivity.currentRoot = TestProvidersAccess.HOME;
    320         mEnv.docs.nextDocument = TestEnv.FILE_ARCHIVE;
    321 
    322         mHandler.openDocument(TestEnv.FILE_ARCHIVE, ActionHandler.VIEW_TYPE_PREVIEW,
    323                 ActionHandler.VIEW_TYPE_REGULAR);
    324         assertEquals(TestEnv.FILE_ARCHIVE, mEnv.state.stack.peek());
    325     }
    326 
    327     @Test
    328     public void testDocumentPicked_OpensDirectories() throws Exception {
    329         mActivity.currentRoot = TestProvidersAccess.HOME;
    330 
    331         mHandler.openDocument(TestEnv.FOLDER_1, ActionHandler.VIEW_TYPE_PREVIEW,
    332                 ActionHandler.VIEW_TYPE_REGULAR);
    333         assertEquals(TestEnv.FOLDER_1, mEnv.state.stack.peek());
    334     }
    335 
    336     @Test
    337     public void testShowChooser() throws Exception {
    338         mActivity.currentRoot = TestProvidersAccess.DOWNLOADS;
    339 
    340         mHandler.showChooserForDoc(TestEnv.FILE_PDF);
    341         mActivity.assertActivityStarted(Intent.ACTION_CHOOSER);
    342     }
    343 
    344     @Test
    345     public void testInitLocation_DefaultsToDownloads() throws Exception {
    346         mActivity.resources.bools.put(R.bool.show_documents_root, false);
    347 
    348         mHandler.initLocation(mActivity.getIntent());
    349         assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri());
    350     }
    351 
    352     @Test
    353     public void testInitLocation_DocumentsRootEnabled() throws Exception {
    354         mActivity.resources.bools.put(R.bool.show_documents_root, true);
    355 
    356         mHandler.initLocation(mActivity.getIntent());
    357         assertRootPicked(TestProvidersAccess.HOME.getUri());
    358     }
    359 
    360     @Test
    361     public void testInitLocation_BrowseRoot() throws Exception {
    362         Intent intent = mActivity.getIntent();
    363         intent.setAction(Intent.ACTION_VIEW);
    364         intent.setData(TestProvidersAccess.PICKLES.getUri());
    365 
    366         mHandler.initLocation(intent);
    367         assertRootPicked(TestProvidersAccess.PICKLES.getUri());
    368     }
    369 
    370     @Test
    371     public void testInitLocation_LaunchToDocuments() throws Exception {
    372         mEnv.docs.nextIsDocumentsUri = true;
    373         mEnv.docs.nextPath = new Path(
    374                 TestProvidersAccess.HOME.rootId,
    375                 Arrays.asList(
    376                         TestEnv.FOLDER_0.documentId,
    377                         TestEnv.FOLDER_1.documentId));
    378         mEnv.docs.nextDocuments =
    379                 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1);
    380 
    381         mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
    382         Intent intent = mActivity.getIntent();
    383         intent.setAction(Intent.ACTION_VIEW);
    384         intent.setData(TestEnv.FOLDER_1.derivedUri);
    385         mHandler.initLocation(intent);
    386 
    387         mEnv.beforeAsserts();
    388 
    389         DocumentStackAsserts.assertEqualsTo(mEnv.state.stack, TestProvidersAccess.HOME,
    390                 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1));
    391         mActivity.refreshCurrentRootAndDirectory.assertCalled();
    392     }
    393 
    394     @Test
    395     public void testDragAndDrop_OnReadOnlyRoot() throws Exception {
    396         RootInfo root = new RootInfo(); // root by default has no SUPPORT_CREATE flag
    397         DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, null, null, null,
    398                 null, true);
    399         assertFalse(mHandler.dropOn(event, root));
    400     }
    401 
    402     @Test
    403     public void testDragAndDrop_OnLibraryRoot() throws Exception {
    404         DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, null, null, null,
    405                 null, true);
    406         assertFalse(mHandler.dropOn(event, TestProvidersAccess.RECENTS));
    407     }
    408 
    409     @Test
    410     public void testClipper_suppliedCorrectClipData() throws Exception {
    411         // DragEvent gets recycled in Android, so it is possible that by the time the callback is
    412         // called, event.getLocalState() and event.getClipData() returns null. This tests to ensure
    413         // our Clipper is getting the original CipData passed in.
    414         mEnv.docs.nextRootDocument = TestEnv.FOLDER_0;
    415         mHandler = new ActionHandler<>(
    416                 mActivity,
    417                 mEnv.state,
    418                 mEnv.roots,
    419                 mEnv.docs,
    420                 mEnv.searchViewManager,
    421                 mEnv::lookupExecutor,
    422                 mActionModeAddons,
    423                 mClipper,
    424                 null,
    425                 mEnv.injector
    426         );
    427         Object localState = new Object();
    428         ClipData clipData = ClipDatas.createTestClipData();
    429         DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, localState, null, clipData,
    430                 null, true);
    431         assertSame(localState, event.getLocalState());
    432         assertSame(clipData, event.getClipData());
    433 
    434         mHandler.dropOn(event, TestProvidersAccess.DOWNLOADS);
    435         event.recycle();
    436 
    437         mEnv.beforeAsserts();
    438 
    439         mClipper.assertSameClipData(clipData);
    440     }
    441 
    442     @Test
    443     public void testClipper_notCalledIfDestInSelection() throws Exception {
    444         mHandler = new ActionHandler<>(
    445                 mActivity,
    446                 mEnv.state,
    447                 mEnv.roots,
    448                 mEnv.docs,
    449                 mEnv.searchViewManager,
    450                 mEnv::lookupExecutor,
    451                 mActionModeAddons,
    452                 mClipper,
    453                 null,
    454                 mEnv.injector
    455         );
    456         List<DocumentInfo> localState = new ArrayList<>();
    457         localState.add(mEnv.docs.getRootDocument(TestProvidersAccess.DOWNLOADS));
    458         ClipData clipData = ClipDatas.createTestClipData();
    459         DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, localState, null, clipData,
    460                 null, true);
    461 
    462         mHandler.dropOn(event, TestProvidersAccess.DOWNLOADS);
    463 
    464         mEnv.beforeAsserts();
    465 
    466         mClipper.assertNoClipData();
    467     }
    468 
    469     @Test
    470     public void testRefresh_nullUri() throws Exception {
    471         refreshAnswer = true;
    472         mHandler.refreshDocument(null, (boolean answer) -> {
    473             refreshAnswer = answer;
    474         });
    475 
    476         mEnv.beforeAsserts();
    477         assertFalse(refreshAnswer);
    478     }
    479 
    480     @Test
    481     public void testRefresh_emptyStack() throws Exception {
    482         refreshAnswer = true;
    483         assertTrue(mEnv.state.stack.isEmpty());
    484         mHandler.refreshDocument(new DocumentInfo(), (boolean answer) -> {
    485             refreshAnswer = answer;
    486         });
    487 
    488         mEnv.beforeAsserts();
    489         assertFalse(refreshAnswer);
    490     }
    491 
    492     @Test
    493     public void testRefresh() throws Exception {
    494         refreshAnswer = false;
    495         mEnv.populateStack();
    496         mHandler.refreshDocument(mEnv.model.getDocument("1"), (boolean answer) -> {
    497             refreshAnswer = answer;
    498         });
    499 
    500         mEnv.beforeAsserts();
    501         assertTrue(refreshAnswer);
    502     }
    503 
    504     @Test
    505     public void testAuthentication() throws Exception {
    506         PendingIntent intent = PendingIntent.getActivity(
    507                 InstrumentationRegistry.getInstrumentation().getTargetContext(), 0, new Intent(),
    508                 0);
    509 
    510         mHandler.startAuthentication(intent);
    511         assertEquals(intent.getIntentSender(), mActivity.startIntentSender.getLastValue().first);
    512         assertEquals(AbstractActionHandler.CODE_AUTHENTICATION,
    513                 mActivity.startIntentSender.getLastValue().second.intValue());
    514     }
    515 
    516     @Test
    517     public void testOnActivityResult_onOK() throws Exception {
    518         mHandler.onActivityResult(AbstractActionHandler.CODE_AUTHENTICATION, Activity.RESULT_OK,
    519                 null);
    520         mActivity.refreshCurrentRootAndDirectory.assertCalled();
    521     }
    522 
    523     @Test
    524     public void testOnActivityResult_onNotOK() throws Exception {
    525         mHandler.onActivityResult(0, Activity.RESULT_OK, null);
    526         mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
    527 
    528         mHandler.onActivityResult(AbstractActionHandler.CODE_AUTHENTICATION,
    529                 Activity.RESULT_CANCELED, null);
    530         mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
    531     }
    532 
    533     private void assertRootPicked(Uri expectedUri) throws Exception {
    534         mEnv.beforeAsserts();
    535 
    536         mActivity.rootPicked.assertCalled();
    537         RootInfo root = mActivity.rootPicked.getLastValue();
    538         assertNotNull(root);
    539         assertEquals(expectedUri, root.getUri());
    540     }
    541 
    542     private ActionHandler<TestActivity> createHandler() {
    543         return new ActionHandler<>(
    544                 mActivity,
    545                 mEnv.state,
    546                 mEnv.roots,
    547                 mEnv.docs,
    548                 mEnv.searchViewManager,
    549                 mEnv::lookupExecutor,
    550                 mActionModeAddons,
    551                 new TestDocumentClipper(),
    552                 null,  // clip storage, not utilized unless we venture into *jumbo* clip territory.
    553                 mEnv.injector
    554         );
    555     }
    556 }
    557