1e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey/*
2e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project
3e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey *
4e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * you may not use this file except in compliance with the License.
6e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * You may obtain a copy of the License at
7e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey *
8e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey *
10e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
11e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * See the License for the specific language governing permissions and
14e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * limitations under the License.
15e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey */
16e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
1716e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKaypackage com.android.documentsui.picker;
18e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
19d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport static com.android.documentsui.base.State.ACTION_CREATE;
20d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport static com.android.documentsui.base.State.ACTION_GET_CONTENT;
21d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport static com.android.documentsui.base.State.ACTION_OPEN;
22d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport static com.android.documentsui.base.State.ACTION_OPEN_TREE;
23d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;
24311a7d8ef646fac19e5524da778108836df9a2dcJeff Sharkey
25b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKayimport android.app.Fragment;
26e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.app.FragmentManager;
27e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.content.Intent;
28e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.net.Uri;
29e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.os.Bundle;
30f339f25982d562e1690358eb6dc663b327960945Jeff Sharkeyimport android.provider.DocumentsContract;
31047182631669608af946480c2545a10acb2ef1bfSteve McKayimport android.support.annotation.CallSuper;
32047182631669608af946480c2545a10acb2ef1bfSteve McKayimport android.view.KeyEvent;
3309c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkeyimport android.view.Menu;
34e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
35bd9f05aa36bf19d8b34d0d73a59e9bd65d3d26ebSteve McKayimport com.android.documentsui.ActionModeController;
3616e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.BaseActivity;
3775b7b9039cf0efcb188e916c6f510328bfe099a8Ben Linimport com.android.documentsui.FocusManager;
3892ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKayimport com.android.documentsui.Injector;
3916e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.MenuManager.DirectoryDetails;
40988d8a354b00dce7e24deee187c08a4591956ac9Steve McKayimport com.android.documentsui.ProviderExecutor;
41990f76ea83a249cd8fc3c797e40626b94cd7945cSteve McKayimport com.android.documentsui.R;
42047182631669608af946480c2545a10acb2ef1bfSteve McKayimport com.android.documentsui.SharedInputHandler;
43d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.base.DocumentInfo;
4498f8c5f502e049a6b85439d773949cdbaa0f78aeSteve McKayimport com.android.documentsui.base.Features;
45d071895ec72bbb9414f6672ff808ec42b8e2d850Steve McKayimport com.android.documentsui.base.MimeTypes;
46d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.base.RootInfo;
47d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport com.android.documentsui.base.Shared;
48d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport com.android.documentsui.base.State;
49f68210e9a1e36e65e56e0c95cfe990f0145ea63fSteve McKayimport com.android.documentsui.dirlist.DirectoryFragment;
50e8b547f1a7acdd10fd1e2f5816cebae49ecfd90bSteve McKayimport com.android.documentsui.prefs.ScopedPreferences;
514f78ba643270b9d84da1952d8e408220b25ec6fdSteve McKayimport com.android.documentsui.selection.SelectionManager;
52c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKayimport com.android.documentsui.services.FileOperationService;
53d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.sidebar.RootsFragment;
54c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKayimport com.android.documentsui.ui.DialogController;
5592ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKayimport com.android.documentsui.ui.MessageBuilder;
56f7adc939ea1191816a0a7572509d18d0659161ceJeff Sharkey
570e66b9b46fac44785b4059d45933aaba7324b691Ben Kwaimport java.util.List;
580e66b9b46fac44785b4059d45933aaba7324b691Ben Kwa
5992ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKaypublic class PickActivity extends BaseActivity implements ActionHandler.Addons {
6092ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay
6192ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay    static final String PREFERENCES_SCOPE = "picker";
62990f76ea83a249cd8fc3c797e40626b94cd7945cSteve McKay
63b6006b2ef723fdbb3fef3b4a350c8d363b127d0fSteve McKay    private static final String TAG = "PickActivity";
646525a19f46eca7fbec21a71f833436823de03da3Steve McKay
6592ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay    private Injector<ActionHandler<PickActivity>> mInjector;
66047182631669608af946480c2545a10acb2ef1bfSteve McKay    private SharedInputHandler mSharedInputHandler;
674045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey
6823ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan    private LastAccessedStorage mLastAccessed;
6923ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan
7016e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay    public PickActivity() {
7118d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay        super(R.layout.documents_activity, TAG);
72b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    }
7309c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
74e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey    @Override
75e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey    public void onCreate(Bundle icicle) {
766525a19f46eca7fbec21a71f833436823de03da3Steve McKay
77fe18b6f11162f248dc7837b566f83c1695c3a9c0Steve McKay        Features features = Features.create(this);
7892ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        mInjector = new Injector<>(
79fe18b6f11162f248dc7837b566f83c1695c3a9c0Steve McKay                features,
8092ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay                new Config(),
8192ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay                ScopedPreferences.create(this, PREFERENCES_SCOPE),
8292ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay                new MessageBuilder(this),
8323ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan                DialogController.create(this, null));
846525a19f46eca7fbec21a71f833436823de03da3Steve McKay
850fbfc653868966da7fd6109b247974e0d87a2297Steve McKay        super.onCreate(icicle);
86739f94ba0dc9be264d9596dac551fd63082d2fddSteve McKay
8792ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        mInjector.selectionMgr = new SelectionManager(
884f78ba643270b9d84da1952d8e408220b25ec6fdSteve McKay                mState.allowMultiple
894f78ba643270b9d84da1952d8e408220b25ec6fdSteve McKay                        ? SelectionManager.MODE_MULTIPLE
904f78ba643270b9d84da1952d8e408220b25ec6fdSteve McKay                        : SelectionManager.MODE_SINGLE);
91047182631669608af946480c2545a10acb2ef1bfSteve McKay
9292ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        mInjector.focusManager = new FocusManager(
9398f8c5f502e049a6b85439d773949cdbaa0f78aeSteve McKay                mInjector.features,
9492ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay                mInjector.selectionMgr,
95047182631669608af946480c2545a10acb2ef1bfSteve McKay                mDrawer,
9692ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay                this::focusSidebar,
97047182631669608af946480c2545a10acb2ef1bfSteve McKay                getColor(R.color.accent_dark));
98047182631669608af946480c2545a10acb2ef1bfSteve McKay
9992ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        mInjector.menuManager = new MenuManager(mSearchManager, mState, new DirectoryDetails(this));
100e967033315ed64bca8c89d601d187fd12754f1fbGarfield Tan
10130d8c7988e15336d995e4b5033ba533a8333446fJon Mann        mInjector.actionModeController = new ActionModeController(
10230d8c7988e15336d995e4b5033ba533a8333446fJon Mann                this,
10330d8c7988e15336d995e4b5033ba533a8333446fJon Mann                mInjector.selectionMgr,
10430d8c7988e15336d995e4b5033ba533a8333446fJon Mann                mInjector.menuManager,
10530d8c7988e15336d995e4b5033ba533a8333446fJon Mann                mInjector.messages);
106e967033315ed64bca8c89d601d187fd12754f1fbGarfield Tan
10723ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan        mLastAccessed = LastAccessedStorage.create();
10892ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        mInjector.actions = new ActionHandler<>(
109988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay                this,
110988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay                mState,
1119bd4099ee27f8302a06fc66980079f29127318f8Jon Mann                mProviders,
11263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                mDocs,
11363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                mSearchManager,
114988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay                ProviderExecutor::forAuthority,
11523ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan                mInjector,
11623ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan                mLastAccessed);
1175b0a2c187a9e446b683687817d22cbe443585223Steve McKay
118e967033315ed64bca8c89d601d187fd12754f1fbGarfield Tan        mInjector.searchManager = mSearchManager;
119e967033315ed64bca8c89d601d187fd12754f1fbGarfield Tan
120988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay        Intent intent = getIntent();
121988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay
12298f8c5f502e049a6b85439d773949cdbaa0f78aeSteve McKay        mSharedInputHandler =
1230902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin                new SharedInputHandler(
1240902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin                        mInjector.focusManager,
1250902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin                        mInjector.selectionMgr,
1260902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin                        mInjector.searchManager::cancelSearch,
1270902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin                        this::popDir,
1280902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin                        mInjector.features);
129988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay        setupLayout(intent);
13092ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        mInjector.actions.initLocation(intent);
131988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay    }
132988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay
133988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay    private void setupLayout(Intent intent) {
134b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_CREATE) {
135988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay            final String mimeType = intent.getType();
136988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay            final String title = intent.getStringExtra(Intent.EXTRA_TITLE);
13709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey            SaveFragment.show(getFragmentManager(), mimeType, title);
138caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        } else if (mState.action == ACTION_OPEN_TREE ||
139ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa                   mState.action == ACTION_PICK_COPY_DESTINATION) {
1406e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            PickFragment.show(getFragmentManager());
14109c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        }
14246165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey
143b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_GET_CONTENT) {
144988d8a354b00dce7e24deee187c08a4591956ac9Steve McKay            final Intent moreApps = new Intent(intent);
1451d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            moreApps.setComponent(null);
1461d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            moreApps.setPackage(null);
1471d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            RootsFragment.show(getFragmentManager(), moreApps);
148caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        } else if (mState.action == ACTION_OPEN ||
149caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                   mState.action == ACTION_CREATE ||
150caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                   mState.action == ACTION_OPEN_TREE ||
151ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa                   mState.action == ACTION_PICK_COPY_DESTINATION) {
152821727a0fd0fa608a3046db8dad6ea588e16828fBen Lin            RootsFragment.show(getFragmentManager(), (Intent) null);
1531d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey        }
154b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey    }
155f339f25982d562e1690358eb6dc663b327960945Jeff Sharkey
1560fbfc653868966da7fd6109b247974e0d87a2297Steve McKay    @Override
15716e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay    protected void includeState(State state) {
158b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        final Intent intent = getIntent();
15978ade2b9111c69a3cb169024646577f38136bbf7Garfield Tan
16078ade2b9111c69a3cb169024646577f38136bbf7Garfield Tan        String defaultMimeType = (intent.getType() == null) ? "*/*" : intent.getType();
16178ade2b9111c69a3cb169024646577f38136bbf7Garfield Tan        state.initAcceptMimes(intent, defaultMimeType);
16278ade2b9111c69a3cb169024646577f38136bbf7Garfield Tan
163b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        final String action = intent.getAction();
164b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) {
165b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_OPEN;
166b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) {
167b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_CREATE;
168b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
169b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_GET_CONTENT;
170f4943e16a80a7ae37ee19e9301017c15061df378Jeff Sharkey        } else if (Intent.ACTION_OPEN_DOCUMENT_TREE.equals(action)) {
171b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_OPEN_TREE;
172ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa        } else if (Shared.ACTION_PICK_COPY_DESTINATION.equals(action)) {
173ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa            state.action = ACTION_PICK_COPY_DESTINATION;
174b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        }
17546165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey
176b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT) {
177b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.allowMultiple = intent.getBooleanExtra(
178b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey                    Intent.EXTRA_ALLOW_MULTIPLE, false);
179b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        }
18046165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey
18195d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski        if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT
18295d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski                || state.action == ACTION_CREATE) {
18395d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski            state.openableOnly = intent.hasCategory(Intent.CATEGORY_OPENABLE);
18495d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski        }
18595d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski
186ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa        if (state.action == ACTION_PICK_COPY_DESTINATION) {
187f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay            // Indicates that a copy operation (or move) includes a directory.
188f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay            // Why? Directory creation isn't supported by some roots (like Downloads).
189f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay            // This allows us to restrict available roots to just those with support.
190b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.directoryCopy = intent.getBooleanExtra(
191ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa                    Shared.EXTRA_DIRECTORY_COPY, false);
192f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay            state.copyOperationSubType = intent.getIntExtra(
1934833477d7d42fa79ee42956bae4aebad77074e4bGarfield, Tan                    FileOperationService.EXTRA_OPERATION_TYPE,
194c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay                    FileOperationService.OPERATION_COPY);
195f2a822d1b63215dff38e042fe52469755544cf4cDaichi Hirono        }
1968b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey    }
1978b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey
198c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay    @Override
19946165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey    protected void onPostCreate(Bundle savedInstanceState) {
20046165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey        super.onPostCreate(savedInstanceState);
20118d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay        mDrawer.update();
20218d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay        mNavigator.update();
203e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey    }
204e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
205b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    @Override
20618d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay    public String getDrawerTitle() {
20718d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay        String title = getIntent().getStringExtra(DocumentsContract.EXTRA_PROMPT);
20818d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay        if (title == null) {
20918d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay            if (mState.action == ACTION_OPEN ||
21018d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay                mState.action == ACTION_GET_CONTENT ||
21118d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay                mState.action == ACTION_OPEN_TREE) {
21218d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay                title = getResources().getString(R.string.title_open);
21318d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay            } else if (mState.action == ACTION_CREATE ||
21418d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay                       mState.action == ACTION_PICK_COPY_DESTINATION) {
21518d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay                title = getResources().getString(R.string.title_save);
21677fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski            } else {
21717f7e5891cbe86fc6cacae045a4edd3e41f8d5eeSteve McKay                // If all else fails, just call it "Documents".
21817f7e5891cbe86fc6cacae045a4edd3e41f8d5eeSteve McKay                title = getResources().getString(R.string.app_label);
21909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey            }
220e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        }
221e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
22218d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay        return title;
22309c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
224e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
22509c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    @Override
22609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    public boolean onPrepareOptionsMenu(Menu menu) {
22709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        super.onPrepareOptionsMenu(menu);
22892ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        mInjector.menuManager.updateOptionMenu(menu);
22909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
230724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey        final DocumentInfo cwd = getCurrentDirectory();
2315b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey
232e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        if (mState.action == ACTION_CREATE) {
233e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay            final FragmentManager fm = getFragmentManager();
2340fe95042025a9bcf73b0d7a6c3f027092bab825cSteve McKay            SaveFragment.get(fm).prepareForDirectory(cwd);
235e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        }
236e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay
23709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        return true;
238e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey    }
239e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
24009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    @Override
24116e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay    protected void refreshDirectory(int anim) {
2425b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        final FragmentManager fm = getFragmentManager();
243a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey        final RootInfo root = getCurrentRoot();
244724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey        final DocumentInfo cwd = getCurrentDirectory();
245c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey
246e967033315ed64bca8c89d601d187fd12754f1fbGarfield Tan        if (mState.stack.isRecents()) {
247ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan            DirectoryFragment.showRecentsOpen(fm, anim);
248ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan
249ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan            // In recents we pick layout mode based on the mimetype,
250ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan            // picking GRID for visual types. We intentionally don't
251ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan            // consult a user's saved preferences here since they are
252ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan            // set per root (not per root and per mimetype).
253ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan            boolean visualMimes = MimeTypes.mimeMatches(
254ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan                    MimeTypes.VISUAL_MIMES, mState.acceptMimes);
255ae9375844c27ee532c4a3c73d9d2297884933c1eGarfield Tan            mState.derivedMode = visualMimes ? State.MODE_GRID : State.MODE_LIST;
2562e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey        } else {
2572e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey                // Normal boring directory
2588788dadd1b13193b577812df4f9f16a642ebfbb7Aga Wronska                DirectoryFragment.showDirectory(fm, root, cwd, anim);
25909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        }
2602e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey
261c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey        // Forget any replacement target
262b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_CREATE) {
263c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            final SaveFragment save = SaveFragment.get(fm);
264c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            if (save != null) {
265c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey                save.setReplaceTarget(null);
266c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            }
267c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey        }
268c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey
269caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        if (mState.action == ACTION_OPEN_TREE ||
270ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa            mState.action == ACTION_PICK_COPY_DESTINATION) {
2716e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            final PickFragment pick = PickFragment.get(fm);
2726e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            if (pick != null) {
273f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay                pick.setPickTarget(mState.action, mState.copyOperationSubType, cwd);
2746e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            }
2756e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        }
27609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
27709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
27816e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay    @Override
27916e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay    protected void onDirectoryCreated(DocumentInfo doc) {
2800af8afd3309538dec784ed0c9c35b252a8213123Steve McKay        assert(doc.isDirectory());
28192ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        mInjector.actions.openContainerDocument(doc);
2825e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay    }
2835e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay
2844045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey    @Override
285eed2f4ec78227b5e173ff667a5517637a91b9a30Steve McKay    public void onDocumentPicked(DocumentInfo doc) {
28609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        final FragmentManager fm = getFragmentManager();
28752fe423907ac089fff5c56d84261ebd0c0506519Tomasz Mikolajewski        // Do not inline-open archives, as otherwise it would be impossible to pick
28852fe423907ac089fff5c56d84261ebd0c0506519Tomasz Mikolajewski        // archive files. Note, that picking files inside archives is not supported.
28952fe423907ac089fff5c56d84261ebd0c0506519Tomasz Mikolajewski        if (doc.isDirectory()) {
29092ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay            mInjector.actions.openContainerDocument(doc);
291b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
29209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey            // Explicit file picked, return
29323ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan            mInjector.actions.finishPicking(doc.derivedUri);
294b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        } else if (mState.action == ACTION_CREATE) {
295c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            // Replace selected file
296c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            SaveFragment.get(fm).setReplaceTarget(doc);
29709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        }
29809c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
29909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
300d0a2a2c4e061da0de1b0008b841cacd9fc4416edSteve McKay    @Override
301724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey    public void onDocumentsPicked(List<DocumentInfo> docs) {
302b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
303873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey            final int size = docs.size();
304873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey            final Uri[] uris = new Uri[size];
305873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey            for (int i = 0; i < size; i++) {
306a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey                uris[i] = docs.get(i).derivedUri;
307873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey            }
30823ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan            mInjector.actions.finishPicking(uris);
3091d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey        }
31009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
31109c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
312047182631669608af946480c2545a10acb2ef1bfSteve McKay    @CallSuper
313047182631669608af946480c2545a10acb2ef1bfSteve McKay    @Override
314047182631669608af946480c2545a10acb2ef1bfSteve McKay    public boolean onKeyDown(int keyCode, KeyEvent event) {
3150902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin        return mSharedInputHandler.onKeyDown(
3160902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin                keyCode,
3170902f07dec9cfb0bd5d7c9c6222b433b91bf2051Ben Lin                event)
318047182631669608af946480c2545a10acb2ef1bfSteve McKay                || super.onKeyDown(keyCode, event);
319047182631669608af946480c2545a10acb2ef1bfSteve McKay    }
320c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay
321894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan    @Override
322894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan    public void setResult(int resultCode, Intent intent, int notUsed) {
323894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan        setResult(resultCode, intent);
324894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan    }
325894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan
32616e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay    public static PickActivity get(Fragment fragment) {
32716e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay        return (PickActivity) fragment.getActivity();
328b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    }
329b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
33092ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay    @Override
33192ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay    public Injector<ActionHandler<PickActivity>> getInjector() {
33292ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay        return mInjector;
33392ae43d5d22331aad83e1a4302a7e1975f66354eSteve McKay    }
334e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey}
335