PickActivity.java revision e980927578d51373a53a3aa9531bc73fb773fff8
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
17e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeypackage com.android.documentsui;
18e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
19311a7d8ef646fac19e5524da778108836df9a2dcJeff Sharkeyimport static com.android.documentsui.DirectoryFragment.ANIM_NONE;
20f8a5e08bfb793e0b1ec7e3ac455a6158ff968afcSteve McKayimport static com.android.documentsui.State.ACTION_CREATE;
21f8a5e08bfb793e0b1ec7e3ac455a6158ff968afcSteve McKayimport static com.android.documentsui.State.ACTION_GET_CONTENT;
22f8a5e08bfb793e0b1ec7e3ac455a6158ff968afcSteve McKayimport static com.android.documentsui.State.ACTION_OPEN;
23f8a5e08bfb793e0b1ec7e3ac455a6158ff968afcSteve McKayimport static com.android.documentsui.State.ACTION_OPEN_COPY_DESTINATION;
24f8a5e08bfb793e0b1ec7e3ac455a6158ff968afcSteve McKayimport static com.android.documentsui.State.ACTION_OPEN_TREE;
25311a7d8ef646fac19e5524da778108836df9a2dcJeff Sharkey
26e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.app.Activity;
27b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKayimport android.app.Fragment;
28e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.app.FragmentManager;
29c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkeyimport android.content.ClipData;
301d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkeyimport android.content.ComponentName;
313fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkeyimport android.content.ContentProviderClient;
32c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkeyimport android.content.ContentResolver;
33f7adc939ea1191816a0a7572509d18d0659161ceJeff Sharkeyimport android.content.ContentValues;
34e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkeyimport android.content.Context;
35e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.content.Intent;
361d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkeyimport android.content.pm.ResolveInfo;
377d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkeyimport android.content.res.Resources;
387d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkeyimport android.graphics.Point;
39e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.net.Uri;
408b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkeyimport android.os.AsyncTask;
41e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.os.Bundle;
422023fcf5a16503524ca8ad1bfb8445a67d27d0a6Tomasz Mikolajewskiimport android.os.Parcelable;
43f339f25982d562e1690358eb6dc663b327960945Jeff Sharkeyimport android.provider.DocumentsContract;
44c4693349d1a49dec8fd203f2c7adce18eee28b0aBen Kwaimport android.support.design.widget.Snackbar;
45e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.util.Log;
4609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkeyimport android.view.Menu;
4709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkeyimport android.view.MenuItem;
48e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.view.View;
497d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkeyimport android.view.WindowManager;
5009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkeyimport android.widget.BaseAdapter;
51e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkeyimport android.widget.Spinner;
52e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkeyimport android.widget.Toolbar;
53e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
54a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport com.android.documentsui.RecentsProvider.RecentColumns;
55a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport com.android.documentsui.RecentsProvider.ResumeColumns;
56724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo;
57b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkeyimport com.android.documentsui.model.DurableUtils;
58724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkeyimport com.android.documentsui.model.RootInfo;
59f7adc939ea1191816a0a7572509d18d0659161ceJeff Sharkey
600e66b9b46fac44785b4059d45933aaba7324b691Ben Kwaimport java.util.Arrays;
610e66b9b46fac44785b4059d45933aaba7324b691Ben Kwaimport java.util.List;
620e66b9b46fac44785b4059d45933aaba7324b691Ben Kwa
63d0a2a2c4e061da0de1b0008b841cacd9fc4416edSteve McKaypublic class DocumentsActivity extends BaseActivity {
644045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey    private static final int CODE_FORWARD = 42;
650574b18a7a95b29fab3cdb9ced6e5b46e24030feBen Kwa    private static final String TAG = "DocumentsActivity";
664045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey
677d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey    private boolean mShowAsDialog;
687d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey
69e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey    private Toolbar mToolbar;
70e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey    private Spinner mToolbarStack;
71e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
72e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey    private Toolbar mRootsToolbar;
73e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
74b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    private ItemSelectedListener mStackListener;
75b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    private BaseAdapter mStackAdapter;
76e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
77b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    public DocumentsActivity() {
787f395011c4478fd273351be8d9de95baa3a29704Steve McKay        super(R.layout.docs_activity, TAG);
79b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    }
8009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
81e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey    @Override
82e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey    public void onCreate(Bundle icicle) {
830fbfc653868966da7fd6109b247974e0d87a2297Steve McKay        super.onCreate(icicle);
84b243af7203b9f158bf95c1bf697856d1ee175a10Oren Blasberg
85b243af7203b9f158bf95c1bf697856d1ee175a10Oren Blasberg        final Resources res = getResources();
86459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay        mShowAsDialog = res.getBoolean(R.bool.show_as_dialog);
876bbed4d41c5e175fcbce4e625920188b1f5258bdSteve McKay
88b243af7203b9f158bf95c1bf697856d1ee175a10Oren Blasberg        if (!mShowAsDialog) {
89b243af7203b9f158bf95c1bf697856d1ee175a10Oren Blasberg            setTheme(R.style.DocumentsNonDialogTheme);
90b243af7203b9f158bf95c1bf697856d1ee175a10Oren Blasberg        }
91b243af7203b9f158bf95c1bf697856d1ee175a10Oren Blasberg
927d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey        if (mShowAsDialog) {
936bbed4d41c5e175fcbce4e625920188b1f5258bdSteve McKay            mDrawer = DrawerController.createDummy();
946bbed4d41c5e175fcbce4e625920188b1f5258bdSteve McKay
95e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            // Strongly define our horizontal dimension; we leave vertical as
96e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            // WRAP_CONTENT so that system resizes us when IME is showing.
977d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey            final WindowManager.LayoutParams a = getWindow().getAttributes();
987d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey
997d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey            final Point size = new Point();
1007d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey            getWindowManager().getDefaultDisplay().getSize(size);
101e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            a.width = (int) res.getFraction(R.dimen.dialog_width, size.x, size.x);
1027d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey
103e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            getWindow().setAttributes(a);
1047d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey
1057d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey        } else {
1066bbed4d41c5e175fcbce4e625920188b1f5258bdSteve McKay            mDrawer = DrawerController.create(this);
1077d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey        }
108b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey
109e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        mToolbar = (Toolbar) findViewById(R.id.toolbar);
110e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
111b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        mStackAdapter = new StackAdapter();
112b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        mStackListener = new ItemSelectedListener();
113e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        mToolbarStack = (Spinner) findViewById(R.id.stack);
114e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        mToolbarStack.setOnItemSelectedListener(mStackListener);
115e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
116e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        mRootsToolbar = (Toolbar) findViewById(R.id.roots_toolbar);
117e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
118eff65d353dec9e3b8cdabc99a40fbb8d2ef2bf81Jeff Sharkey        setActionBar(mToolbar);
119eff65d353dec9e3b8cdabc99a40fbb8d2ef2bf81Jeff Sharkey
120b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_CREATE) {
12109c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey            final String mimeType = getIntent().getType();
12209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey            final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
12309c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey            SaveFragment.show(getFragmentManager(), mimeType, title);
124caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        } else if (mState.action == ACTION_OPEN_TREE ||
125caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                   mState.action == ACTION_OPEN_COPY_DESTINATION) {
1266e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            PickFragment.show(getFragmentManager());
12709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        }
12846165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey
129b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_GET_CONTENT) {
1301d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            final Intent moreApps = new Intent(getIntent());
1311d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            moreApps.setComponent(null);
1321d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            moreApps.setPackage(null);
1331d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            RootsFragment.show(getFragmentManager(), moreApps);
134caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        } else if (mState.action == ACTION_OPEN ||
135caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                   mState.action == ACTION_CREATE ||
136caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                   mState.action == ACTION_OPEN_TREE ||
137caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                   mState.action == ACTION_OPEN_COPY_DESTINATION) {
1381d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            RootsFragment.show(getFragmentManager(), null);
1391d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey        }
140761122118b2437aee3a44e9263b73766986c12b8Jeff Sharkey
1418b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey        if (!mState.restored) {
1424f99622c953db6d9ae26f4efe540c3a1c08fa37fMakoto Onuki            // In this case, we set the activity title in AsyncTask.onPostExecute().  To prevent
1434f99622c953db6d9ae26f4efe540c3a1c08fa37fMakoto Onuki            // talkback from reading aloud the default title, we clear it here.
1444f99622c953db6d9ae26f4efe540c3a1c08fa37fMakoto Onuki            setTitle("");
145459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay            new RestoreStackTask().execute();
1468b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey        } else {
1478b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey            onCurrentDirectoryChanged(ANIM_NONE);
1488b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey        }
149b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey    }
150f339f25982d562e1690358eb6dc663b327960945Jeff Sharkey
1510fbfc653868966da7fd6109b247974e0d87a2297Steve McKay    @Override
1520574b18a7a95b29fab3cdb9ced6e5b46e24030feBen Kwa    State buildState() {
1530574b18a7a95b29fab3cdb9ced6e5b46e24030feBen Kwa        State state = buildDefaultState();
154761122118b2437aee3a44e9263b73766986c12b8Jeff Sharkey
155b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        final Intent intent = getIntent();
156b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        final String action = intent.getAction();
157b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) {
158b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_OPEN;
159b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) {
160b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_CREATE;
161b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
162b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_GET_CONTENT;
163f4943e16a80a7ae37ee19e9301017c15061df378Jeff Sharkey        } else if (Intent.ACTION_OPEN_DOCUMENT_TREE.equals(action)) {
164b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_OPEN_TREE;
16522574ed9fd6954bba42e206f8cd3bbb07169ebdaDaichi Hirono        } else if (DocumentsIntent.ACTION_OPEN_COPY_DESTINATION.equals(action)) {
166b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.action = ACTION_OPEN_COPY_DESTINATION;
167b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        }
16846165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey
169b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT) {
170b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.allowMultiple = intent.getBooleanExtra(
171b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey                    Intent.EXTRA_ALLOW_MULTIPLE, false);
172b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        }
17346165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey
174b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (state.action == ACTION_OPEN_COPY_DESTINATION) {
175b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            state.directoryCopy = intent.getBooleanExtra(
17622574ed9fd6954bba42e206f8cd3bbb07169ebdaDaichi Hirono                    BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false);
177cb4461f872a92a5b2420e8655d12654aac1349ffBen Kwa            state.transferMode = intent.getIntExtra(CopyService.EXTRA_TRANSFER_MODE,
178cb4461f872a92a5b2420e8655d12654aac1349ffBen Kwa                    CopyService.TRANSFER_MODE_NONE);
179f2a822d1b63215dff38e042fe52469755544cf4cDaichi Hirono        }
180b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
181b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        return state;
1828b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey    }
1838b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey
184b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    @Override
185b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    void onStackRestored(boolean restored, boolean external) {
186b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        // Show drawer when no stack restored, but only when requesting
187b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        // non-visual content. However, if we last used an external app,
188b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        // drawer is always shown.
1894c5fe52c750e0c5b6aefdac1b5970d56fd437746Jeff Sharkey
190b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        boolean showDrawer = false;
191b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (!restored) {
192b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            showDrawer = true;
193b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
194b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) {
195b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            showDrawer = false;
196b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
197b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (external && mState.action == ACTION_GET_CONTENT) {
198b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            showDrawer = true;
199b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
200f339f25982d562e1690358eb6dc663b327960945Jeff Sharkey
201b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (showDrawer) {
202b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            setRootsDrawerOpen(true);
2038b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey        }
204b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    }
2058b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey
206b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    public void onAppPicked(ResolveInfo info) {
207b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        final Intent intent = new Intent(getIntent());
208b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
209b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        intent.setComponent(new ComponentName(
210b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay                info.activityInfo.applicationInfo.packageName, info.activityInfo.name));
211b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        startActivityForResult(intent, CODE_FORWARD);
212b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    }
2138b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey
214b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    @Override
215b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
216b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        Log.d(TAG, "onActivityResult() code=" + resultCode);
21738ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey
218b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        // Only relay back results when not canceled; otherwise stick around to
219b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        // let the user pick another app/backend.
220b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) {
22138ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey
222b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            // Remember that we last picked via external app
223b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            final String packageName = getCallingPackageMaybeExtra();
224b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            final ContentValues values = new ContentValues();
225b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            values.put(ResumeColumns.EXTERNAL, 1);
226b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            getContentResolver().insert(RecentsProvider.buildResume(packageName), values);
2278b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey
228b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            // Pass back result to original caller
229b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            setResult(resultCode, data);
230b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            finish();
231b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        } else {
232b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            super.onActivityResult(requestCode, resultCode, data);
2335b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        }
234f339f25982d562e1690358eb6dc663b327960945Jeff Sharkey    }
2355b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey
23646165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey    @Override
23746165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey    protected void onPostCreate(Bundle savedInstanceState) {
23846165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey        super.onPostCreate(savedInstanceState);
2396bbed4d41c5e175fcbce4e625920188b1f5258bdSteve McKay        mDrawer.syncState();
240b58b3d3ee7f7b853593162f2f90cc4cc02615e32Jeff Sharkey        updateActionBar();
2417d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey    }
2427d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey
2437d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey    public void setRootsDrawerOpen(boolean open) {
2446bbed4d41c5e175fcbce4e625920188b1f5258bdSteve McKay        mDrawer.setOpen(open);
245e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey    }
246e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
247b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    @Override
24809c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    public void updateActionBar() {
249e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        if (mRootsToolbar != null) {
25077fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski            final String prompt = getIntent().getStringExtra(DocumentsContract.EXTRA_PROMPT);
25177fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski            if (prompt != null) {
25277fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                mRootsToolbar.setTitle(prompt);
25377fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski            } else {
25477fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                if (mState.action == ACTION_OPEN ||
25577fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                    mState.action == ACTION_GET_CONTENT ||
25677fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                    mState.action == ACTION_OPEN_TREE) {
25777fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                    mRootsToolbar.setTitle(R.string.title_open);
25877fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                } else if (mState.action == ACTION_CREATE ||
25977fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                           mState.action == ACTION_OPEN_COPY_DESTINATION) {
26077fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                    mRootsToolbar.setTitle(R.string.title_save);
26177fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski                }
26209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey            }
263e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        }
264e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
2656bbed4d41c5e175fcbce4e625920188b1f5258bdSteve McKay        if (!mShowAsDialog && mDrawer.isUnlocked()) {
266e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
267738d8a56cceb3f8d2f6ced4c043b014b1eb48f07Jeff Sharkey            mToolbar.setNavigationContentDescription(R.string.drawer_open);
268e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
269e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                @Override
270e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                public void onClick(View v) {
271e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                    setRootsDrawerOpen(true);
272e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                }
273e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            });
2742cadb1db7b6009729fa52866d10e757d1f2747edTomasz Mikolajewski        } else {
2752cadb1db7b6009729fa52866d10e757d1f2747edTomasz Mikolajewski            mToolbar.setNavigationIcon(null);
2762cadb1db7b6009729fa52866d10e757d1f2747edTomasz Mikolajewski            mToolbar.setNavigationContentDescription(R.string.drawer_open);
2772cadb1db7b6009729fa52866d10e757d1f2747edTomasz Mikolajewski            mToolbar.setNavigationOnClickListener(null);
278e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        }
279a5defe39d4eea635f9e2fac1822ff9c8d48a474aJeff Sharkey
280b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        if (mSearchManager.isExpanded()) {
281e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            mToolbar.setTitle(null);
282e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            mToolbarStack.setVisibility(View.GONE);
283e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey            mToolbarStack.setAdapter(null);
284e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey        } else {
2854c5fe52c750e0c5b6aefdac1b5970d56fd437746Jeff Sharkey            if (mState.stack.size() <= 1) {
2862cadb1db7b6009729fa52866d10e757d1f2747edTomasz Mikolajewski                mToolbar.setTitle(getCurrentRoot().title);
287e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                mToolbarStack.setVisibility(View.GONE);
288e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                mToolbarStack.setAdapter(null);
289a5defe39d4eea635f9e2fac1822ff9c8d48a474aJeff Sharkey            } else {
290e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                mToolbar.setTitle(null);
291e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                mToolbarStack.setVisibility(View.VISIBLE);
292e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                mToolbarStack.setAdapter(mStackAdapter);
293e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey
294b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay                mStackListener.mIgnoreNextNavigation = true;
295e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey                mToolbarStack.setSelection(mStackAdapter.getCount() - 1);
29646165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey            }
297e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey        }
29809c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
299e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
30009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    @Override
30109c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    public boolean onCreateOptionsMenu(Menu menu) {
302b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        boolean showMenu = super.onCreateOptionsMenu(menu);
303b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
304e8d13ea5fbd07e9a9c0d2867a0eb3e6d761815cfJeff Sharkey        // Most actions are visible when showing as dialog
3057d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey        if (mShowAsDialog) {
306b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            expandMenus(menu);
3077d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey        }
308b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        return showMenu;
30909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
31009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
31109c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    @Override
31209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    public boolean onPrepareOptionsMenu(Menu menu) {
31309c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        super.onPrepareOptionsMenu(menu);
31409c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
315724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey        final DocumentInfo cwd = getCurrentDirectory();
3165b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey
31709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
3184c5fe52c750e0c5b6aefdac1b5970d56fd437746Jeff Sharkey        final MenuItem grid = menu.findItem(R.id.menu_grid);
319c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey        final MenuItem list = menu.findItem(R.id.menu_list);
320e8d13ea5fbd07e9a9c0d2867a0eb3e6d761815cfJeff Sharkey        final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
321938528d28017fe12740f32a56b1039c9950878bcJeff Sharkey        final MenuItem settings = menu.findItem(R.id.menu_settings);
3225b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey
323e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        boolean recents = cwd == null;
324e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        boolean picking = mState.action == ACTION_CREATE
3250873f8a4d6c418b0ad1d5ec48ebca93288e766a7Steve McKay                || mState.action == ACTION_OPEN_TREE
326e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay                || mState.action == ACTION_OPEN_COPY_DESTINATION;
327c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey
328e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        createDir.setVisible(picking && !recents && cwd.isCreateSupported());
329e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        mSearchManager.showMenu(!picking);
33046165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey
331e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        // No display options in recent directories
332e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        grid.setVisible(!(picking && recents));
333e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        list.setVisible(!(picking && recents));
334e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay
335e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        fileSize.setVisible(fileSize.isVisible() && !picking);
336459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay        settings.setVisible(false);
337938528d28017fe12740f32a56b1039c9950878bcJeff Sharkey
338e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        if (mState.action == ACTION_CREATE) {
339e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay            final FragmentManager fm = getFragmentManager();
340e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay            SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
341e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        }
342e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay
343e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay        Menus.disableHiddenItems(menu);
344e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay
34509c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        return true;
346e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey    }
347e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey
34809c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    @Override
34909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    public boolean onOptionsItemSelected(MenuItem item) {
3506bbed4d41c5e175fcbce4e625920188b1f5258bdSteve McKay        return mDrawer.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
3514be51f196d60ba23856b646de3091364230258b0Jeff Sharkey    }
3524be51f196d60ba23856b646de3091364230258b0Jeff Sharkey
3535b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey    @Override
354b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    void onDirectoryChanged(int anim) {
3555b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        final FragmentManager fm = getFragmentManager();
356a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey        final RootInfo root = getCurrentRoot();
357724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey        final DocumentInfo cwd = getCurrentDirectory();
358c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey
3592e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey        if (cwd == null) {
3602e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey            // No directory means recents
361caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono            if (mState.action == ACTION_CREATE ||
362caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                mState.action == ACTION_OPEN_TREE ||
363caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                mState.action == ACTION_OPEN_COPY_DESTINATION) {
3642e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey                RecentsCreateFragment.show(fm);
3652e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey            } else {
366c8ae7a5cc51c220c9e0aa2b9c3d128f803f0df16Jeff Sharkey                DirectoryFragment.showRecentsOpen(fm, anim);
3677d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey
36838ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey                // Start recents in grid when requesting visual things
36938ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey                final boolean visualMimes = MimePredicate.mimeMatches(
37038ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey                        MimePredicate.VISUAL_MIMES, mState.acceptMimes);
371b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay                mState.userMode = visualMimes ? State.MODE_GRID : State.MODE_LIST;
3727d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey                mState.derivedMode = mState.userMode;
3732e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey            }
3742e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey        } else {
375b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey            if (mState.currentSearch != null) {
3762e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey                // Ongoing search
377c8ae7a5cc51c220c9e0aa2b9c3d128f803f0df16Jeff Sharkey                DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
3782e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey            } else {
3792e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey                // Normal boring directory
380c8ae7a5cc51c220c9e0aa2b9c3d128f803f0df16Jeff Sharkey                DirectoryFragment.showNormal(fm, root, cwd, anim);
3812e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey            }
38209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        }
3832e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey
384c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey        // Forget any replacement target
385b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_CREATE) {
386c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            final SaveFragment save = SaveFragment.get(fm);
387c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            if (save != null) {
388c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey                save.setReplaceTarget(null);
389c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            }
390c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey        }
391c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey
392caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        if (mState.action == ACTION_OPEN_TREE ||
393caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono            mState.action == ACTION_OPEN_COPY_DESTINATION) {
3946e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            final PickFragment pick = PickFragment.get(fm);
3956e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            if (pick != null) {
3964e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono                pick.setPickTarget(mState.action, mState.transferMode, cwd);
3976e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            }
3986e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        }
39909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
40009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
401b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    void onSaveRequested(DocumentInfo replaceTarget) {
402459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay        new ExistingFinishTask(replaceTarget.derivedUri).executeOnExecutor(getExecutorForCurrentDirectory());
4039dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey    }
4049dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey
405b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    void onSaveRequested(String mimeType, String displayName) {
406459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay        new CreateFinishTask(mimeType, displayName).executeOnExecutor(getExecutorForCurrentDirectory());
4074045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey    }
4084045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey
4094045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey    @Override
410b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    void onRootPicked(RootInfo root) {
411b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        super.onRootPicked(root);
412b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        setRootsDrawerOpen(false);
4131d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey    }
4141d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey
415d0a2a2c4e061da0de1b0008b841cacd9fc4416edSteve McKay    @Override
416351a749751bc501c9d7c0f03ee5b542f0e7a7d7cSteve McKay    public void onDocumentPicked(DocumentInfo doc, DocumentContext context) {
41709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        final FragmentManager fm = getFragmentManager();
4182e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey        if (doc.isDirectory()) {
419351a749751bc501c9d7c0f03ee5b542f0e7a7d7cSteve McKay            openDirectory(doc);
420b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
42109c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey            // Explicit file picked, return
422459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay            new ExistingFinishTask(doc.derivedUri).executeOnExecutor(getExecutorForCurrentDirectory());
423b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        } else if (mState.action == ACTION_CREATE) {
424c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            // Replace selected file
425c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey            SaveFragment.get(fm).setReplaceTarget(doc);
42609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        }
42709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
42809c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
429d0a2a2c4e061da0de1b0008b841cacd9fc4416edSteve McKay    @Override
430724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey    public void onDocumentsPicked(List<DocumentInfo> docs) {
431b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
432873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey            final int size = docs.size();
433873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey            final Uri[] uris = new Uri[size];
434873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey            for (int i = 0; i < size; i++) {
435a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey                uris[i] = docs.get(i).derivedUri;
436873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey            }
437459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay            new ExistingFinishTask(uris).executeOnExecutor(getExecutorForCurrentDirectory());
438c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey        }
439c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey    }
440c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey
4416e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    public void onPickRequested(DocumentInfo pickTarget) {
442caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        Uri result;
443caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        if (mState.action == ACTION_OPEN_TREE) {
444caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono            result = DocumentsContract.buildTreeDocumentUri(
445caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono                    pickTarget.authority, pickTarget.documentId);
446caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        } else if (mState.action == ACTION_OPEN_COPY_DESTINATION) {
447caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono            result = pickTarget.derivedUri;
448caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        } else {
449caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono            // Should not be reached.
450caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono            throw new IllegalStateException("Invalid mState.action.");
451caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        }
452459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay        new PickFinishTask(result).executeOnExecutor(getExecutorForCurrentDirectory());
4536e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    }
4546e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
455b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    @Override
456b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    void saveStackBlocking() {
4575b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        final ContentResolver resolver = getContentResolver();
4585b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        final ContentValues values = new ContentValues();
4595b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey
460b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
461caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono        if (mState.action == ACTION_CREATE ||
462caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono            mState.action == ACTION_OPEN_TREE ||
463caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono            mState.action == ACTION_OPEN_COPY_DESTINATION) {
4645b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey            // Remember stack for last create
4655b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey            values.clear();
4669dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            values.put(RecentColumns.KEY, mState.stack.buildKey());
467a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey            values.put(RecentColumns.STACK, rawStack);
468a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey            resolver.insert(RecentsProvider.buildRecent(), values);
4695b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        }
4705b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey
4715b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        // Remember location for next app launch
4720b744d82744e24563002b69ad3ef5904d6bddbdfJeff Sharkey        final String packageName = getCallingPackageMaybeExtra();
4735b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        values.clear();
474a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey        values.put(ResumeColumns.STACK, rawStack);
47538ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey        values.put(ResumeColumns.EXTERNAL, 0);
4765b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey        resolver.insert(RecentsProvider.buildResume(packageName), values);
4779dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey    }
4789dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey
479b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    @Override
480b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    void onTaskFinished(Uri... uris) {
4819dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        Log.d(TAG, "onFinished() " + Arrays.toString(uris));
4825b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey
48309c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        final Intent intent = new Intent();
484c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey        if (uris.length == 1) {
485c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey            intent.setData(uris[0]);
486c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey        } else if (uris.length > 1) {
487a5defe39d4eea635f9e2fac1822ff9c8d48a474aJeff Sharkey            final ClipData clipData = new ClipData(
488b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey                    null, mState.acceptMimes, new ClipData.Item(uris[0]));
489c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey            for (int i = 1; i < uris.length; i++) {
490c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey                clipData.addItem(new ClipData.Item(uris[i]));
491c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey            }
492c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey            intent.setClipData(clipData);
493c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey        }
49409c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
495b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey        if (mState.action == ACTION_GET_CONTENT) {
4961d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
4976c3164ded0ff721997f388783a6d2fd436e22366Jeff Sharkey        } else if (mState.action == ACTION_OPEN_TREE) {
4986e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
4996e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
5006e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
5016e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
5026c3164ded0ff721997f388783a6d2fd436e22366Jeff Sharkey        } else if (mState.action == ACTION_OPEN_COPY_DESTINATION) {
5036c3164ded0ff721997f388783a6d2fd436e22366Jeff Sharkey            // Picking a copy destination is only used internally by us, so we
5046c3164ded0ff721997f388783a6d2fd436e22366Jeff Sharkey            // don't need to extend permissions to the caller.
5054d0255f79cc92a5675d14b20f9cdf06ecb8d7109Steve McKay            intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
506cb4461f872a92a5b2420e8655d12654aac1349ffBen Kwa            intent.putExtra(CopyService.EXTRA_TRANSFER_MODE, mState.transferMode);
5071d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey        } else {
5081d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
5091d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
51013d369f702aeed957db63858e942b2f1c117bffdJeff Sharkey                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
5111d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey        }
51209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
51309c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        setResult(Activity.RESULT_OK, intent);
51409c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey        finish();
51509c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey    }
51609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey
517b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    public static DocumentsActivity get(Fragment fragment) {
518b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        return (DocumentsActivity) fragment.getActivity();
519b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    }
520b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
521b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    private final class PickFinishTask extends AsyncTask<Void, Void, Void> {
522b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        private final Uri mUri;
523b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
524b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        public PickFinishTask(Uri uri) {
525b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            mUri = uri;
526b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
527b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
528b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        @Override
529b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        protected Void doInBackground(Void... params) {
530b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            saveStackBlocking();
531b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            return null;
532b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
533b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
534b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        @Override
535b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        protected void onPostExecute(Void result) {
536b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            onTaskFinished(mUri);
537b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
538b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    }
539b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
540b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    final class ExistingFinishTask extends AsyncTask<Void, Void, Void> {
541b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        private final Uri[] mUris;
542b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
543b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        public ExistingFinishTask(Uri... uris) {
544b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            mUris = uris;
545b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
546b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
547b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        @Override
548b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        protected Void doInBackground(Void... params) {
549b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            saveStackBlocking();
550b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            return null;
551b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
552b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
553b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        @Override
554b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        protected void onPostExecute(Void result) {
555b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay            onTaskFinished(mUris);
556b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay        }
557b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    }
558b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay
559b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    /**
560b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay     * Task that creates a new document in the background.
561b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay     */
562b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay    final class CreateFinishTask extends AsyncTask<Void, Void, Uri> {
5639dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        private final String mMimeType;
5649dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        private final String mDisplayName;
5659dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey
5669dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        public CreateFinishTask(String mimeType, String displayName) {
5679dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            mMimeType = mimeType;
5689dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            mDisplayName = displayName;
5699dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        }
5709dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey
5719dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        @Override
5724be51f196d60ba23856b646de3091364230258b0Jeff Sharkey        protected void onPreExecute() {
5734be51f196d60ba23856b646de3091364230258b0Jeff Sharkey            setPending(true);
5744be51f196d60ba23856b646de3091364230258b0Jeff Sharkey        }
5754be51f196d60ba23856b646de3091364230258b0Jeff Sharkey
5764be51f196d60ba23856b646de3091364230258b0Jeff Sharkey        @Override
5779dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        protected Uri doInBackground(Void... params) {
5783fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey            final ContentResolver resolver = getContentResolver();
5799dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            final DocumentInfo cwd = getCurrentDirectory();
5803fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey
5813fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey            ContentProviderClient client = null;
5823fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey            Uri childUri = null;
5833fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey            try {
5843fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey                client = DocumentsApplication.acquireUnstableProviderOrThrow(
5853fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey                        resolver, cwd.derivedUri.getAuthority());
5863fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey                childUri = DocumentsContract.createDocument(
5873fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey                        client, cwd.derivedUri, mMimeType, mDisplayName);
5883fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey            } catch (Exception e) {
5893fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey                Log.w(TAG, "Failed to create document", e);
5903fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey            } finally {
5913fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey                ContentProviderClient.releaseQuietly(client);
5923fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey            }
5933fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey
5949dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            if (childUri != null) {
5959dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey                saveStackBlocking();
5969dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            }
5973fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey
5989dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            return childUri;
5999dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        }
6009dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey
6019dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        @Override
6029dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        protected void onPostExecute(Uri result) {
6039dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            if (result != null) {
604b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay                onTaskFinished(result);
6059dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            } else {
606e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay                Snackbars.makeSnackbar(
607c4693349d1a49dec8fd203f2c7adce18eee28b0aBen Kwa                    DocumentsActivity.this, R.string.save_error, Snackbar.LENGTH_SHORT).show();
6089dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey            }
6094be51f196d60ba23856b646de3091364230258b0Jeff Sharkey
6104be51f196d60ba23856b646de3091364230258b0Jeff Sharkey            setPending(false);
6119dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey        }
6129dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey    }
613e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey}
614