blob: b00f89c47858d76c164e5faec402a5509b98ee2d [file] [log] [blame]
Jeff Sharkeye22d02e2013-04-26 16:54:55 -07001/*
2 * Copyright (C) 2013 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
17package com.android.documentsui;
18
Jeff Sharkey311a7d82015-04-11 21:27:21 -070019import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070020import static com.android.documentsui.BaseActivity.State.ACTION_CREATE;
21import static com.android.documentsui.BaseActivity.State.ACTION_GET_CONTENT;
22import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE;
23import static com.android.documentsui.BaseActivity.State.ACTION_OPEN;
Daichi Hironocaadd412015-04-10 15:50:38 +090024import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_COPY_DESTINATION;
Steve McKayb68dd222015-04-20 17:18:15 -070025import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE;
Jeff Sharkey311a7d82015-04-11 21:27:21 -070026import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
27import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
Jeff Sharkey311a7d82015-04-11 21:27:21 -070028import static com.android.documentsui.DirectoryFragment.ANIM_UP;
29
Steve McKayb68dd222015-04-20 17:18:15 -070030import java.util.Arrays;
31import java.util.List;
32
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070033import android.app.Activity;
Steve McKayb68dd222015-04-20 17:18:15 -070034import android.app.Fragment;
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070035import android.app.FragmentManager;
Jeff Sharkey873daa32013-08-18 17:38:20 -070036import android.content.ActivityNotFoundException;
Jeff Sharkeyc317af82013-07-01 16:56:54 -070037import android.content.ClipData;
Jeff Sharkey1d890e02013-08-15 11:24:03 -070038import android.content.ComponentName;
Jeff Sharkey3fd11772013-09-30 14:26:27 -070039import android.content.ContentProviderClient;
Jeff Sharkeyc317af82013-07-01 16:56:54 -070040import android.content.ContentResolver;
Jeff Sharkeyf7adc932013-07-30 17:08:39 -070041import android.content.ContentValues;
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -070042import android.content.Context;
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070043import android.content.Intent;
Jeff Sharkey1d890e02013-08-15 11:24:03 -070044import android.content.pm.ResolveInfo;
Jeff Sharkey7d58fc62013-09-12 16:25:02 -070045import android.content.res.Resources;
Jeff Sharkey7d58fc62013-09-12 16:25:02 -070046import android.graphics.Point;
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070047import android.net.Uri;
Jeff Sharkey8b997042013-09-19 15:25:56 -070048import android.os.AsyncTask;
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070049import android.os.Bundle;
Tomasz Mikolajewski2023fcf2015-04-10 10:30:33 +090050import android.os.Parcelable;
Jeff Sharkeyf339f252013-08-15 16:17:41 -070051import android.provider.DocumentsContract;
Jeff Sharkey0e8c8712013-09-12 21:59:06 -070052import android.provider.DocumentsContract.Root;
Jeff Sharkey46165b52013-07-31 20:53:22 -070053import android.support.v4.app.ActionBarDrawerToggle;
Jeff Sharkey46165b52013-07-31 20:53:22 -070054import android.support.v4.widget.DrawerLayout;
55import android.support.v4.widget.DrawerLayout.DrawerListener;
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070056import android.util.Log;
Jeff Sharkey09c10bf2013-06-30 20:02:59 -070057import android.view.Menu;
58import android.view.MenuItem;
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070059import android.view.View;
Jeff Sharkey7d58fc62013-09-12 16:25:02 -070060import android.view.WindowManager;
Jeff Sharkey09c10bf2013-06-30 20:02:59 -070061import android.widget.BaseAdapter;
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -070062import android.widget.Spinner;
Jeff Sharkey78278212013-08-01 11:01:47 -070063import android.widget.Toast;
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -070064import android.widget.Toolbar;
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070065
Jeff Sharkeya4d1f222013-09-07 14:45:03 -070066import com.android.documentsui.RecentsProvider.RecentColumns;
67import com.android.documentsui.RecentsProvider.ResumeColumns;
Jeff Sharkey724deeb2013-08-31 15:02:20 -070068import com.android.documentsui.model.DocumentInfo;
Jeff Sharkeyb3620442013-09-01 18:41:04 -070069import com.android.documentsui.model.DurableUtils;
Jeff Sharkey724deeb2013-08-31 15:02:20 -070070import com.android.documentsui.model.RootInfo;
Jeff Sharkeyf7adc932013-07-30 17:08:39 -070071
Steve McKayd0a2a2c2015-03-25 14:35:33 -070072public class DocumentsActivity extends BaseActivity {
Steve McKayb68dd222015-04-20 17:18:15 -070073 private static final int CODE_FORWARD = 42;
Jeff Sharkeya5defe32013-08-05 17:56:48 -070074 public static final String TAG = "Documents";
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070075
Jeff Sharkey7d58fc62013-09-12 16:25:02 -070076 private boolean mShowAsDialog;
77
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -070078 private Toolbar mToolbar;
79 private Spinner mToolbarStack;
80
81 private Toolbar mRootsToolbar;
82
Jeff Sharkey7d58fc62013-09-12 16:25:02 -070083 private DrawerLayout mDrawerLayout;
84 private ActionBarDrawerToggle mDrawerToggle;
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -070085 private View mRootsDrawer;
Jeff Sharkey7d58fc62013-09-12 16:25:02 -070086
Jeff Sharkeyc8ae7a52013-09-18 16:26:49 -070087 private DirectoryContainerView mDirectoryContainer;
88
Jeff Sharkeyb3620442013-09-01 18:41:04 -070089 private State mState;
Jeff Sharkey09c10bf2013-06-30 20:02:59 -070090
Steve McKayb68dd222015-04-20 17:18:15 -070091 private ItemSelectedListener mStackListener;
92 private BaseAdapter mStackAdapter;
93
94 public DocumentsActivity() {
95 super(TAG);
96 }
97
Jeff Sharkeye22d02e2013-04-26 16:54:55 -070098 @Override
99 public void onCreate(Bundle icicle) {
100 super.onCreate(icicle);
101
Jeff Sharkeye22d02e2013-04-26 16:54:55 -0700102 setResult(Activity.RESULT_CANCELED);
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700103 setContentView(R.layout.activity);
104
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700105 final Context context = this;
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700106 final Resources res = getResources();
107 mShowAsDialog = res.getBoolean(R.bool.show_as_dialog);
Jeff Sharkey76112212013-08-06 11:26:10 -0700108
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700109 if (mShowAsDialog) {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700110 // Strongly define our horizontal dimension; we leave vertical as
111 // WRAP_CONTENT so that system resizes us when IME is showing.
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700112 final WindowManager.LayoutParams a = getWindow().getAttributes();
Jeff Sharkey46165b52013-07-31 20:53:22 -0700113
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700114 final Point size = new Point();
115 getWindowManager().getDefaultDisplay().getSize(size);
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700116 a.width = (int) res.getFraction(R.dimen.dialog_width, size.x, size.x);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700117
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700118 getWindow().setAttributes(a);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700119
120 } else {
121 // Non-dialog means we have a drawer
122 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
123
124 mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700125 R.drawable.ic_hamburger, R.string.drawer_open, R.string.drawer_close);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700126
127 mDrawerLayout.setDrawerListener(mDrawerListener);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700128
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700129 mRootsDrawer = findViewById(R.id.drawer_roots);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700130 }
Jeff Sharkey46165b52013-07-31 20:53:22 -0700131
Jeff Sharkeyc8ae7a52013-09-18 16:26:49 -0700132 mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
133
Steve McKayb68dd222015-04-20 17:18:15 -0700134 mState = (icicle != null)
135 ? icicle.<State>getParcelable(EXTRA_STATE)
136 : buildDefaultState();
Jeff Sharkey5b535922013-08-02 15:55:26 -0700137
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700138 mToolbar = (Toolbar) findViewById(R.id.toolbar);
139 mToolbar.setTitleTextAppearance(context,
140 android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
141
Steve McKayb68dd222015-04-20 17:18:15 -0700142 mStackAdapter = new StackAdapter();
143 mStackListener = new ItemSelectedListener();
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700144 mToolbarStack = (Spinner) findViewById(R.id.stack);
145 mToolbarStack.setOnItemSelectedListener(mStackListener);
146
147 mRootsToolbar = (Toolbar) findViewById(R.id.roots_toolbar);
148 if (mRootsToolbar != null) {
149 mRootsToolbar.setTitleTextAppearance(context,
150 android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
151 }
152
Jeff Sharkeyeff65d32014-07-29 16:32:36 -0700153 setActionBar(mToolbar);
154
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700155 // Hide roots when we're managing a specific root
Jeff Sharkey311a7d82015-04-11 21:27:21 -0700156 if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700157 if (mShowAsDialog) {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700158 findViewById(R.id.container_roots).setVisibility(View.GONE);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700159 } else {
160 mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
161 }
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700162 }
163
164 if (mState.action == ACTION_CREATE) {
165 final String mimeType = getIntent().getType();
166 final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
167 SaveFragment.show(getFragmentManager(), mimeType, title);
Daichi Hironocaadd412015-04-10 15:50:38 +0900168 } else if (mState.action == ACTION_OPEN_TREE ||
169 mState.action == ACTION_OPEN_COPY_DESTINATION) {
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700170 PickFragment.show(getFragmentManager());
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700171 }
172
173 if (mState.action == ACTION_GET_CONTENT) {
174 final Intent moreApps = new Intent(getIntent());
175 moreApps.setComponent(null);
176 moreApps.setPackage(null);
177 RootsFragment.show(getFragmentManager(), moreApps);
Daichi Hironocaadd412015-04-10 15:50:38 +0900178 } else if (mState.action == ACTION_OPEN ||
179 mState.action == ACTION_CREATE ||
180 mState.action == ACTION_OPEN_TREE ||
181 mState.action == ACTION_OPEN_COPY_DESTINATION) {
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700182 RootsFragment.show(getFragmentManager(), null);
183 }
184
Jeff Sharkey8b997042013-09-19 15:25:56 -0700185 if (!mState.restored) {
Jeff Sharkey311a7d82015-04-11 21:27:21 -0700186 if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
Jeff Sharkey8b997042013-09-19 15:25:56 -0700187 final Uri rootUri = getIntent().getData();
Jeff Sharkeyf63b7772013-10-01 17:57:41 -0700188 new RestoreRootTask(rootUri).executeOnExecutor(getCurrentExecutor());
Jeff Sharkey8b997042013-09-19 15:25:56 -0700189 } else {
190 new RestoreStackTask().execute();
191 }
192 } else {
193 onCurrentDirectoryChanged(ANIM_NONE);
194 }
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700195 }
196
Steve McKayb68dd222015-04-20 17:18:15 -0700197 private State buildDefaultState() {
198 State state = new State();
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700199
200 final Intent intent = getIntent();
201 final String action = intent.getAction();
202 if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) {
Steve McKayb68dd222015-04-20 17:18:15 -0700203 state.action = ACTION_OPEN;
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700204 } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) {
Steve McKayb68dd222015-04-20 17:18:15 -0700205 state.action = ACTION_CREATE;
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700206 } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
Steve McKayb68dd222015-04-20 17:18:15 -0700207 state.action = ACTION_GET_CONTENT;
Jeff Sharkeyf4943e12014-06-04 16:42:47 -0700208 } else if (Intent.ACTION_OPEN_DOCUMENT_TREE.equals(action)) {
Steve McKayb68dd222015-04-20 17:18:15 -0700209 state.action = ACTION_OPEN_TREE;
Jeff Sharkey91a101c2013-09-05 17:14:14 -0700210 } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
Steve McKayb68dd222015-04-20 17:18:15 -0700211 state.action = ACTION_MANAGE;
Jeff Sharkey938528d2015-04-12 21:52:24 -0700212 } else if (DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT.equals(action)) {
Steve McKayb68dd222015-04-20 17:18:15 -0700213 state.action = ACTION_BROWSE;
Daichi Hirono22574ed2015-04-15 13:41:18 +0900214 } else if (DocumentsIntent.ACTION_OPEN_COPY_DESTINATION.equals(action)) {
Steve McKayb68dd222015-04-20 17:18:15 -0700215 state.action = ACTION_OPEN_COPY_DESTINATION;
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700216 }
217
Steve McKayb68dd222015-04-20 17:18:15 -0700218 if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT) {
219 state.allowMultiple = intent.getBooleanExtra(
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700220 Intent.EXTRA_ALLOW_MULTIPLE, false);
221 }
222
Steve McKayb68dd222015-04-20 17:18:15 -0700223 if (state.action == ACTION_MANAGE || state.action == ACTION_BROWSE) {
224 state.acceptMimes = new String[] { "*/*" };
225 state.allowMultiple = true;
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700226 } else if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
Steve McKayb68dd222015-04-20 17:18:15 -0700227 state.acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES);
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700228 } else {
Steve McKayb68dd222015-04-20 17:18:15 -0700229 state.acceptMimes = new String[] { intent.getType() };
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700230 }
231
Steve McKayb68dd222015-04-20 17:18:15 -0700232 state.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);
233 state.forceAdvanced = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false);
234 state.showAdvanced = state.forceAdvanced
Jeff Sharkeye8d13ea2014-08-08 15:10:03 -0700235 | LocalPreferences.getDisplayAdvancedDevices(this);
236
Steve McKayb68dd222015-04-20 17:18:15 -0700237 if (state.action == ACTION_MANAGE || state.action == ACTION_BROWSE) {
238 state.showSize = true;
Jeff Sharkeye8d13ea2014-08-08 15:10:03 -0700239 } else {
Steve McKayb68dd222015-04-20 17:18:15 -0700240 state.showSize = LocalPreferences.getDisplayFileSize(this);
Jeff Sharkeye8d13ea2014-08-08 15:10:03 -0700241 }
Steve McKayb68dd222015-04-20 17:18:15 -0700242 if (state.action == ACTION_OPEN_COPY_DESTINATION) {
243 state.directoryCopy = intent.getBooleanExtra(
Daichi Hirono22574ed2015-04-15 13:41:18 +0900244 BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false);
Ben Kwacb4461f2015-05-05 11:50:11 -0700245 state.transferMode = intent.getIntExtra(CopyService.EXTRA_TRANSFER_MODE,
246 CopyService.TRANSFER_MODE_NONE);
Daichi Hironof2a822d2015-04-14 17:12:54 +0900247 }
Steve McKayb68dd222015-04-20 17:18:15 -0700248
249 return state;
Jeff Sharkey8b997042013-09-19 15:25:56 -0700250 }
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700251
Jeff Sharkey8b997042013-09-19 15:25:56 -0700252 private class RestoreRootTask extends AsyncTask<Void, Void, RootInfo> {
253 private Uri mRootUri;
254
255 public RestoreRootTask(Uri rootUri) {
256 mRootUri = rootUri;
257 }
258
259 @Override
260 protected RootInfo doInBackground(Void... params) {
261 final String rootId = DocumentsContract.getRootId(mRootUri);
262 return mRoots.getRootOneshot(mRootUri.getAuthority(), rootId);
263 }
264
265 @Override
266 protected void onPostExecute(RootInfo root) {
267 if (isDestroyed()) return;
268 mState.restored = true;
269
Jeff Sharkeyf339f252013-08-15 16:17:41 -0700270 if (root != null) {
Steve McKayb68dd222015-04-20 17:18:15 -0700271 onRootPicked(root);
Jeff Sharkeyf339f252013-08-15 16:17:41 -0700272 } else {
Jeff Sharkey8b997042013-09-19 15:25:56 -0700273 Log.w(TAG, "Failed to find root: " + mRootUri);
Jeff Sharkeyf339f252013-08-15 16:17:41 -0700274 finish();
Jeff Sharkey5b535922013-08-02 15:55:26 -0700275 }
Jeff Sharkey8b997042013-09-19 15:25:56 -0700276 }
277 }
Jeff Sharkey5b535922013-08-02 15:55:26 -0700278
Steve McKayb68dd222015-04-20 17:18:15 -0700279 @Override
280 void onStackRestored(boolean restored, boolean external) {
281 // Show drawer when no stack restored, but only when requesting
282 // non-visual content. However, if we last used an external app,
283 // drawer is always shown.
Jeff Sharkey8b997042013-09-19 15:25:56 -0700284
Steve McKayb68dd222015-04-20 17:18:15 -0700285 boolean showDrawer = false;
286 if (!restored) {
287 showDrawer = true;
288 }
289 if (MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) {
290 showDrawer = false;
291 }
292 if (external && mState.action == ACTION_GET_CONTENT) {
293 showDrawer = true;
Jeff Sharkey8b997042013-09-19 15:25:56 -0700294 }
295
Steve McKayb68dd222015-04-20 17:18:15 -0700296 if (showDrawer) {
297 setRootsDrawerOpen(true);
298 }
299 }
Jeff Sharkey8b997042013-09-19 15:25:56 -0700300
Steve McKayb68dd222015-04-20 17:18:15 -0700301 public void onAppPicked(ResolveInfo info) {
302 final Intent intent = new Intent(getIntent());
303 intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
304 intent.setComponent(new ComponentName(
305 info.activityInfo.applicationInfo.packageName, info.activityInfo.name));
306 startActivityForResult(intent, CODE_FORWARD);
307 }
Jeff Sharkey38ec2522013-09-24 12:07:12 -0700308
Steve McKayb68dd222015-04-20 17:18:15 -0700309 @Override
310 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
311 Log.d(TAG, "onActivityResult() code=" + resultCode);
Jeff Sharkey38ec2522013-09-24 12:07:12 -0700312
Steve McKayb68dd222015-04-20 17:18:15 -0700313 // Only relay back results when not canceled; otherwise stick around to
314 // let the user pick another app/backend.
315 if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) {
Jeff Sharkey8b997042013-09-19 15:25:56 -0700316
Steve McKayb68dd222015-04-20 17:18:15 -0700317 // Remember that we last picked via external app
318 final String packageName = getCallingPackageMaybeExtra();
319 final ContentValues values = new ContentValues();
320 values.put(ResumeColumns.EXTERNAL, 1);
321 getContentResolver().insert(RecentsProvider.buildResume(packageName), values);
322
323 // Pass back result to original caller
324 setResult(resultCode, data);
325 finish();
326 } else {
327 super.onActivityResult(requestCode, resultCode, data);
Jeff Sharkeyf339f252013-08-15 16:17:41 -0700328 }
329 }
330
Jeff Sharkey46165b52013-07-31 20:53:22 -0700331 private DrawerListener mDrawerListener = new DrawerListener() {
332 @Override
333 public void onDrawerSlide(View drawerView, float slideOffset) {
334 mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
335 }
336
337 @Override
338 public void onDrawerOpened(View drawerView) {
339 mDrawerToggle.onDrawerOpened(drawerView);
Jeff Sharkey46165b52013-07-31 20:53:22 -0700340 }
341
342 @Override
343 public void onDrawerClosed(View drawerView) {
344 mDrawerToggle.onDrawerClosed(drawerView);
Jeff Sharkey46165b52013-07-31 20:53:22 -0700345 }
346
347 @Override
348 public void onDrawerStateChanged(int newState) {
349 mDrawerToggle.onDrawerStateChanged(newState);
350 }
351 };
352
353 @Override
354 protected void onPostCreate(Bundle savedInstanceState) {
355 super.onPostCreate(savedInstanceState);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700356 if (mDrawerToggle != null) {
357 mDrawerToggle.syncState();
358 }
Jeff Sharkeyb58b3d32014-11-24 10:00:00 -0800359 updateActionBar();
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700360 }
361
362 public void setRootsDrawerOpen(boolean open) {
363 if (!mShowAsDialog) {
364 if (open) {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700365 mDrawerLayout.openDrawer(mRootsDrawer);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700366 } else {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700367 mDrawerLayout.closeDrawer(mRootsDrawer);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700368 }
369 }
370 }
371
372 private boolean isRootsDrawerOpen() {
373 if (mShowAsDialog) {
374 return false;
375 } else {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700376 return mDrawerLayout.isDrawerOpen(mRootsDrawer);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700377 }
Jeff Sharkeye22d02e2013-04-26 16:54:55 -0700378 }
379
Steve McKayb68dd222015-04-20 17:18:15 -0700380 @Override
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700381 public void updateActionBar() {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700382 if (mRootsToolbar != null) {
Daichi Hironocaadd412015-04-10 15:50:38 +0900383 if (mState.action == ACTION_OPEN ||
384 mState.action == ACTION_GET_CONTENT ||
385 mState.action == ACTION_OPEN_TREE) {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700386 mRootsToolbar.setTitle(R.string.title_open);
Daichi Hironocaadd412015-04-10 15:50:38 +0900387 } else if (mState.action == ACTION_CREATE ||
388 mState.action == ACTION_OPEN_COPY_DESTINATION) {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700389 mRootsToolbar.setTitle(R.string.title_save);
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700390 }
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700391 }
Jeff Sharkeya5defe32013-08-05 17:56:48 -0700392
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700393 final RootInfo root = getCurrentRoot();
Jeff Sharkey311a7d82015-04-11 21:27:21 -0700394 final boolean showRootIcon = mShowAsDialog
395 || (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE);
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700396 if (showRootIcon) {
Jeff Sharkey34c54092014-08-08 13:08:56 -0700397 mToolbar.setNavigationIcon(
398 root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
Jeff Sharkey738d8a52014-10-13 12:53:13 -0700399 mToolbar.setNavigationContentDescription(R.string.drawer_open);
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700400 mToolbar.setNavigationOnClickListener(null);
401 } else {
402 mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
Jeff Sharkey738d8a52014-10-13 12:53:13 -0700403 mToolbar.setNavigationContentDescription(R.string.drawer_open);
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700404 mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
405 @Override
406 public void onClick(View v) {
407 setRootsDrawerOpen(true);
408 }
409 });
410 }
411
Steve McKayb68dd222015-04-20 17:18:15 -0700412 if (mSearchManager.isExpanded()) {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700413 mToolbar.setTitle(null);
414 mToolbarStack.setVisibility(View.GONE);
415 mToolbarStack.setAdapter(null);
416 } else {
Jeff Sharkey4c5fe522013-09-03 14:17:06 -0700417 if (mState.stack.size() <= 1) {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700418 mToolbar.setTitle(root.title);
419 mToolbarStack.setVisibility(View.GONE);
420 mToolbarStack.setAdapter(null);
Jeff Sharkeya5defe32013-08-05 17:56:48 -0700421 } else {
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700422 mToolbar.setTitle(null);
423 mToolbarStack.setVisibility(View.VISIBLE);
424 mToolbarStack.setAdapter(mStackAdapter);
425
Steve McKayb68dd222015-04-20 17:18:15 -0700426 mStackListener.mIgnoreNextNavigation = true;
Jeff Sharkeye6fcceb2014-07-28 16:38:52 -0700427 mToolbarStack.setSelection(mStackAdapter.getCount() - 1);
Jeff Sharkey46165b52013-07-31 20:53:22 -0700428 }
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700429 }
430 }
431
432 @Override
433 public boolean onCreateOptionsMenu(Menu menu) {
Steve McKayb68dd222015-04-20 17:18:15 -0700434 boolean showMenu = super.onCreateOptionsMenu(menu);
435
Jeff Sharkeye8d13ea2014-08-08 15:10:03 -0700436 // Most actions are visible when showing as dialog
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700437 if (mShowAsDialog) {
Steve McKayb68dd222015-04-20 17:18:15 -0700438 expandMenus(menu);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700439 }
Steve McKayb68dd222015-04-20 17:18:15 -0700440 return showMenu;
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700441 }
442
443 @Override
444 public boolean onPrepareOptionsMenu(Menu menu) {
445 super.onPrepareOptionsMenu(menu);
446
Jeff Sharkey0e8c8712013-09-12 21:59:06 -0700447 final RootInfo root = getCurrentRoot();
Jeff Sharkey724deeb2013-08-31 15:02:20 -0700448 final DocumentInfo cwd = getCurrentDirectory();
Jeff Sharkey5b535922013-08-02 15:55:26 -0700449
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700450 final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
Jeff Sharkey4c5fe522013-09-03 14:17:06 -0700451 final MenuItem grid = menu.findItem(R.id.menu_grid);
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700452 final MenuItem list = menu.findItem(R.id.menu_list);
Jeff Sharkeye8d13ea2014-08-08 15:10:03 -0700453 final MenuItem advanced = menu.findItem(R.id.menu_advanced);
454 final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
Jeff Sharkey938528d2015-04-12 21:52:24 -0700455 final MenuItem settings = menu.findItem(R.id.menu_settings);
Jeff Sharkey5b535922013-08-02 15:55:26 -0700456
Jeff Sharkey311a7d82015-04-11 21:27:21 -0700457 boolean fileSizeVisible = !(mState.action == ACTION_MANAGE
458 || mState.action == ACTION_BROWSE);
Jeff Sharkeyf4943e12014-06-04 16:42:47 -0700459 if (mState.action == ACTION_CREATE || mState.action == ACTION_OPEN_TREE) {
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700460 createDir.setVisible(cwd != null && cwd.isCreateSupported());
Steve McKayb68dd222015-04-20 17:18:15 -0700461 mSearchManager.showMenu(false);
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700462
463 // No display options in recent directories
464 if (cwd == null) {
465 grid.setVisible(false);
466 list.setVisible(false);
Jeff Sharkey524811c2014-10-23 13:59:54 -0700467 fileSizeVisible = false;
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700468 }
469
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700470 if (mState.action == ACTION_CREATE) {
Steve McKay7bd32e12015-04-30 16:12:59 -0700471 final FragmentManager fm = getFragmentManager();
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700472 SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
473 }
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700474 } else {
475 createDir.setVisible(false);
Jeff Sharkey5b535922013-08-02 15:55:26 -0700476 }
Jeff Sharkey46165b52013-07-31 20:53:22 -0700477
Jeff Sharkey311a7d82015-04-11 21:27:21 -0700478 advanced.setVisible(!(mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE));
Jeff Sharkey524811c2014-10-23 13:59:54 -0700479 fileSize.setVisible(fileSizeVisible);
Jeff Sharkeyf339f252013-08-15 16:17:41 -0700480
Jeff Sharkey938528d2015-04-12 21:52:24 -0700481 settings.setVisible((mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE)
482 && (root.flags & Root.FLAG_HAS_SETTINGS) != 0);
483
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700484 return true;
485 }
486
487 @Override
488 public boolean onOptionsItemSelected(MenuItem item) {
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700489 if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
Jeff Sharkey46165b52013-07-31 20:53:22 -0700490 return true;
491 }
Steve McKayb68dd222015-04-20 17:18:15 -0700492 return super.onOptionsItemSelected(item);
Jeff Sharkey4be51f12013-10-23 15:46:38 -0700493 }
494
Jeff Sharkey5b535922013-08-02 15:55:26 -0700495 @Override
496 public void onBackPressed() {
Jeff Sharkeyd10f0492013-09-09 17:35:46 -0700497 if (!mState.stackTouched) {
498 super.onBackPressed();
499 return;
500 }
501
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700502 final int size = mState.stack.size();
Jeff Sharkey5b535922013-08-02 15:55:26 -0700503 if (size > 1) {
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700504 mState.stack.pop();
Jeff Sharkeyc8ae7a52013-09-18 16:26:49 -0700505 onCurrentDirectoryChanged(ANIM_UP);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700506 } else if (size == 1 && !isRootsDrawerOpen()) {
Jeff Sharkey5b535922013-08-02 15:55:26 -0700507 // TODO: open root drawer once we can capture back key
508 super.onBackPressed();
509 } else {
510 super.onBackPressed();
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700511 }
Jeff Sharkey5b535922013-08-02 15:55:26 -0700512 }
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700513
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700514 @Override
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700515 public State getDisplayState() {
516 return mState;
Jeff Sharkey3c28b792013-07-01 17:22:02 -0700517 }
518
Steve McKayb68dd222015-04-20 17:18:15 -0700519 @Override
520 void onDirectoryChanged(int anim) {
Jeff Sharkey5b535922013-08-02 15:55:26 -0700521 final FragmentManager fm = getFragmentManager();
Jeff Sharkeya4d1f222013-09-07 14:45:03 -0700522 final RootInfo root = getCurrentRoot();
Jeff Sharkey724deeb2013-08-31 15:02:20 -0700523 final DocumentInfo cwd = getCurrentDirectory();
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700524
Jeff Sharkeyc8ae7a52013-09-18 16:26:49 -0700525 mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN);
526
Jeff Sharkey2e694f82013-08-06 16:26:14 -0700527 if (cwd == null) {
528 // No directory means recents
Daichi Hironocaadd412015-04-10 15:50:38 +0900529 if (mState.action == ACTION_CREATE ||
530 mState.action == ACTION_OPEN_TREE ||
531 mState.action == ACTION_OPEN_COPY_DESTINATION) {
Jeff Sharkey2e694f82013-08-06 16:26:14 -0700532 RecentsCreateFragment.show(fm);
533 } else {
Jeff Sharkeyc8ae7a52013-09-18 16:26:49 -0700534 DirectoryFragment.showRecentsOpen(fm, anim);
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700535
Jeff Sharkey38ec2522013-09-24 12:07:12 -0700536 // Start recents in grid when requesting visual things
537 final boolean visualMimes = MimePredicate.mimeMatches(
538 MimePredicate.VISUAL_MIMES, mState.acceptMimes);
Steve McKayb68dd222015-04-20 17:18:15 -0700539 mState.userMode = visualMimes ? State.MODE_GRID : State.MODE_LIST;
Jeff Sharkey7d58fc62013-09-12 16:25:02 -0700540 mState.derivedMode = mState.userMode;
Jeff Sharkey2e694f82013-08-06 16:26:14 -0700541 }
542 } else {
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700543 if (mState.currentSearch != null) {
Jeff Sharkey2e694f82013-08-06 16:26:14 -0700544 // Ongoing search
Jeff Sharkeyc8ae7a52013-09-18 16:26:49 -0700545 DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
Jeff Sharkey2e694f82013-08-06 16:26:14 -0700546 } else {
547 // Normal boring directory
Jeff Sharkeyc8ae7a52013-09-18 16:26:49 -0700548 DirectoryFragment.showNormal(fm, root, cwd, anim);
Jeff Sharkey2e694f82013-08-06 16:26:14 -0700549 }
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700550 }
Jeff Sharkey2e694f82013-08-06 16:26:14 -0700551
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700552 // Forget any replacement target
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700553 if (mState.action == ACTION_CREATE) {
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700554 final SaveFragment save = SaveFragment.get(fm);
555 if (save != null) {
556 save.setReplaceTarget(null);
557 }
558 }
559
Daichi Hironocaadd412015-04-10 15:50:38 +0900560 if (mState.action == ACTION_OPEN_TREE ||
561 mState.action == ACTION_OPEN_COPY_DESTINATION) {
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700562 final PickFragment pick = PickFragment.get(fm);
563 if (pick != null) {
564 final CharSequence displayName = (mState.stack.size() <= 1) ? root.title
565 : cwd.displayName;
Daichi Hirono676453c2015-04-14 12:16:59 +0900566 pick.setPickTarget(mState.action, cwd, displayName);
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700567 }
568 }
Steve McKayb68dd222015-04-20 17:18:15 -0700569 }
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700570
Steve McKayb68dd222015-04-20 17:18:15 -0700571 void onSaveRequested(DocumentInfo replaceTarget) {
572 new ExistingFinishTask(replaceTarget.derivedUri).executeOnExecutor(getCurrentExecutor());
573 }
Jeff Sharkey42d26792013-09-06 13:22:09 -0700574
Steve McKayb68dd222015-04-20 17:18:15 -0700575 void onSaveRequested(String mimeType, String displayName) {
576 new CreateFinishTask(mimeType, displayName).executeOnExecutor(getCurrentExecutor());
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700577 }
578
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700579 @Override
Steve McKayb68dd222015-04-20 17:18:15 -0700580 void onRootPicked(RootInfo root) {
581 super.onRootPicked(root);
582 setRootsDrawerOpen(false);
Jeff Sharkey1d890e02013-08-15 11:24:03 -0700583 }
584
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700585 @Override
Jeff Sharkey724deeb2013-08-31 15:02:20 -0700586 public void onDocumentPicked(DocumentInfo doc) {
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700587 final FragmentManager fm = getFragmentManager();
Jeff Sharkey2e694f82013-08-06 16:26:14 -0700588 if (doc.isDirectory()) {
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700589 mState.stack.push(doc);
Jeff Sharkeyd10f0492013-09-09 17:35:46 -0700590 mState.stackTouched = true;
Jeff Sharkeyc8ae7a52013-09-18 16:26:49 -0700591 onCurrentDirectoryChanged(ANIM_DOWN);
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700592 } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700593 // Explicit file picked, return
Jeff Sharkeyf63b7772013-10-01 17:57:41 -0700594 new ExistingFinishTask(doc.derivedUri).executeOnExecutor(getCurrentExecutor());
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700595 } else if (mState.action == ACTION_CREATE) {
Jeff Sharkeyc6cbdf12013-08-07 16:22:02 -0700596 // Replace selected file
597 SaveFragment.get(fm).setReplaceTarget(doc);
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700598 } else if (mState.action == ACTION_MANAGE) {
Jeff Sharkey91a101c2013-09-05 17:14:14 -0700599 // First try managing the document; we expect manager to filter
600 // based on authority, so we don't grant.
601 final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
Jeff Sharkeya4d1f222013-09-07 14:45:03 -0700602 manage.setData(doc.derivedUri);
Jeff Sharkey91a101c2013-09-05 17:14:14 -0700603
Jeff Sharkey873daa32013-08-18 17:38:20 -0700604 try {
Jeff Sharkey91a101c2013-09-05 17:14:14 -0700605 startActivity(manage);
Jeff Sharkey873daa32013-08-18 17:38:20 -0700606 } catch (ActivityNotFoundException ex) {
Jeff Sharkey91a101c2013-09-05 17:14:14 -0700607 // Fall back to viewing
608 final Intent view = new Intent(Intent.ACTION_VIEW);
609 view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Jeff Sharkeya4d1f222013-09-07 14:45:03 -0700610 view.setData(doc.derivedUri);
Jeff Sharkey91a101c2013-09-05 17:14:14 -0700611
612 try {
613 startActivity(view);
614 } catch (ActivityNotFoundException ex2) {
615 Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
616 }
Jeff Sharkey873daa32013-08-18 17:38:20 -0700617 }
Jeff Sharkey311a7d82015-04-11 21:27:21 -0700618 } else if (mState.action == ACTION_BROWSE) {
619 // Go straight to viewing
620 final Intent view = new Intent(Intent.ACTION_VIEW);
621 view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
622 view.setData(doc.derivedUri);
623
624 try {
625 startActivity(view);
626 } catch (ActivityNotFoundException ex) {
627 Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
628 }
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700629 }
630 }
631
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700632 @Override
Jeff Sharkey724deeb2013-08-31 15:02:20 -0700633 public void onDocumentsPicked(List<DocumentInfo> docs) {
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700634 if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
Jeff Sharkey873daa32013-08-18 17:38:20 -0700635 final int size = docs.size();
636 final Uri[] uris = new Uri[size];
637 for (int i = 0; i < size; i++) {
Jeff Sharkeya4d1f222013-09-07 14:45:03 -0700638 uris[i] = docs.get(i).derivedUri;
Jeff Sharkey873daa32013-08-18 17:38:20 -0700639 }
Jeff Sharkeyf63b7772013-10-01 17:57:41 -0700640 new ExistingFinishTask(uris).executeOnExecutor(getCurrentExecutor());
Jeff Sharkeyc317af82013-07-01 16:56:54 -0700641 }
Jeff Sharkey09c10bf2013-06-30 20:02:59 -0700642 }
643
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700644 public void onPickRequested(DocumentInfo pickTarget) {
Daichi Hironocaadd412015-04-10 15:50:38 +0900645 Uri result;
646 if (mState.action == ACTION_OPEN_TREE) {
647 result = DocumentsContract.buildTreeDocumentUri(
648 pickTarget.authority, pickTarget.documentId);
649 } else if (mState.action == ACTION_OPEN_COPY_DESTINATION) {
650 result = pickTarget.derivedUri;
651 } else {
652 // Should not be reached.
653 throw new IllegalStateException("Invalid mState.action.");
654 }
655 new PickFinishTask(result).executeOnExecutor(getCurrentExecutor());
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700656 }
657
Steve McKayb68dd222015-04-20 17:18:15 -0700658 @Override
659 void saveStackBlocking() {
Jeff Sharkey5b535922013-08-02 15:55:26 -0700660 final ContentResolver resolver = getContentResolver();
661 final ContentValues values = new ContentValues();
662
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700663 final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
Daichi Hironocaadd412015-04-10 15:50:38 +0900664 if (mState.action == ACTION_CREATE ||
665 mState.action == ACTION_OPEN_TREE ||
666 mState.action == ACTION_OPEN_COPY_DESTINATION) {
Jeff Sharkey5b535922013-08-02 15:55:26 -0700667 // Remember stack for last create
668 values.clear();
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700669 values.put(RecentColumns.KEY, mState.stack.buildKey());
Jeff Sharkeya4d1f222013-09-07 14:45:03 -0700670 values.put(RecentColumns.STACK, rawStack);
671 resolver.insert(RecentsProvider.buildRecent(), values);
Jeff Sharkey5b535922013-08-02 15:55:26 -0700672 }
673
674 // Remember location for next app launch
Jeff Sharkey0b744d82013-10-09 13:52:17 -0700675 final String packageName = getCallingPackageMaybeExtra();
Jeff Sharkey5b535922013-08-02 15:55:26 -0700676 values.clear();
Jeff Sharkeya4d1f222013-09-07 14:45:03 -0700677 values.put(ResumeColumns.STACK, rawStack);
Jeff Sharkey38ec2522013-09-24 12:07:12 -0700678 values.put(ResumeColumns.EXTERNAL, 0);
Jeff Sharkey5b535922013-08-02 15:55:26 -0700679 resolver.insert(RecentsProvider.buildResume(packageName), values);
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700680 }
681
Steve McKayb68dd222015-04-20 17:18:15 -0700682 @Override
683 void onTaskFinished(Uri... uris) {
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700684 Log.d(TAG, "onFinished() " + Arrays.toString(uris));
Jeff Sharkey5b535922013-08-02 15:55:26 -0700685
Jeff Sharkeye22d02e2013-04-26 16:54:55 -0700686 final Intent intent = new Intent();
Jeff Sharkeyc317af82013-07-01 16:56:54 -0700687 if (uris.length == 1) {
688 intent.setData(uris[0]);
689 } else if (uris.length > 1) {
Jeff Sharkeya5defe32013-08-05 17:56:48 -0700690 final ClipData clipData = new ClipData(
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700691 null, mState.acceptMimes, new ClipData.Item(uris[0]));
Jeff Sharkeyc317af82013-07-01 16:56:54 -0700692 for (int i = 1; i < uris.length; i++) {
693 clipData.addItem(new ClipData.Item(uris[i]));
694 }
695 intent.setClipData(clipData);
696 }
Jeff Sharkeye22d02e2013-04-26 16:54:55 -0700697
Jeff Sharkeyb3620442013-09-01 18:41:04 -0700698 if (mState.action == ACTION_GET_CONTENT) {
Jeff Sharkey1d890e02013-08-15 11:24:03 -0700699 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Daichi Hironocaadd412015-04-10 15:50:38 +0900700 } else if (mState.action == ACTION_OPEN_TREE ||
701 mState.action == ACTION_OPEN_COPY_DESTINATION) {
Jeff Sharkey6e565ff2014-04-05 19:05:24 -0700702 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
703 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
704 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
705 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
Tomasz Mikolajewski2023fcf2015-04-10 10:30:33 +0900706 // TODO: Move passing the stack to the separate ACTION_COPY action once it's implemented.
707 intent.putExtra(CopyService.EXTRA_STACK, (Parcelable)mState.stack);
Ben Kwacb4461f2015-05-05 11:50:11 -0700708 intent.putExtra(CopyService.EXTRA_TRANSFER_MODE, mState.transferMode);
Jeff Sharkey1d890e02013-08-15 11:24:03 -0700709 } else {
710 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
711 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
Jeff Sharkey13d369f2013-09-20 14:30:59 -0700712 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
Jeff Sharkey1d890e02013-08-15 11:24:03 -0700713 }
Jeff Sharkeye22d02e2013-04-26 16:54:55 -0700714
715 setResult(Activity.RESULT_OK, intent);
716 finish();
717 }
718
Steve McKayb68dd222015-04-20 17:18:15 -0700719 public static DocumentsActivity get(Fragment fragment) {
720 return (DocumentsActivity) fragment.getActivity();
721 }
722
723 private final class PickFinishTask extends AsyncTask<Void, Void, Void> {
724 private final Uri mUri;
725
726 public PickFinishTask(Uri uri) {
727 mUri = uri;
728 }
729
730 @Override
731 protected Void doInBackground(Void... params) {
732 saveStackBlocking();
733 return null;
734 }
735
736 @Override
737 protected void onPostExecute(Void result) {
738 onTaskFinished(mUri);
739 }
740 }
741
742 final class ExistingFinishTask extends AsyncTask<Void, Void, Void> {
743 private final Uri[] mUris;
744
745 public ExistingFinishTask(Uri... uris) {
746 mUris = uris;
747 }
748
749 @Override
750 protected Void doInBackground(Void... params) {
751 saveStackBlocking();
752 return null;
753 }
754
755 @Override
756 protected void onPostExecute(Void result) {
757 onTaskFinished(mUris);
758 }
759 }
760
761 /**
762 * Task that creates a new document in the background.
763 */
764 final class CreateFinishTask extends AsyncTask<Void, Void, Uri> {
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700765 private final String mMimeType;
766 private final String mDisplayName;
767
768 public CreateFinishTask(String mimeType, String displayName) {
769 mMimeType = mimeType;
770 mDisplayName = displayName;
771 }
772
773 @Override
Jeff Sharkey4be51f12013-10-23 15:46:38 -0700774 protected void onPreExecute() {
775 setPending(true);
776 }
777
778 @Override
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700779 protected Uri doInBackground(Void... params) {
Jeff Sharkey3fd11772013-09-30 14:26:27 -0700780 final ContentResolver resolver = getContentResolver();
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700781 final DocumentInfo cwd = getCurrentDirectory();
Jeff Sharkey3fd11772013-09-30 14:26:27 -0700782
783 ContentProviderClient client = null;
784 Uri childUri = null;
785 try {
786 client = DocumentsApplication.acquireUnstableProviderOrThrow(
787 resolver, cwd.derivedUri.getAuthority());
788 childUri = DocumentsContract.createDocument(
789 client, cwd.derivedUri, mMimeType, mDisplayName);
790 } catch (Exception e) {
791 Log.w(TAG, "Failed to create document", e);
792 } finally {
793 ContentProviderClient.releaseQuietly(client);
794 }
795
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700796 if (childUri != null) {
797 saveStackBlocking();
798 }
Jeff Sharkey3fd11772013-09-30 14:26:27 -0700799
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700800 return childUri;
801 }
802
803 @Override
804 protected void onPostExecute(Uri result) {
805 if (result != null) {
Steve McKayb68dd222015-04-20 17:18:15 -0700806 onTaskFinished(result);
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700807 } else {
808 Toast.makeText(DocumentsActivity.this, R.string.save_error, Toast.LENGTH_SHORT)
809 .show();
810 }
Jeff Sharkey4be51f12013-10-23 15:46:38 -0700811
812 setPending(false);
Jeff Sharkey9dd02622013-09-27 16:44:11 -0700813 }
814 }
Jeff Sharkeye22d02e2013-04-26 16:54:55 -0700815}