PickActivity.java revision d080506e3aa8547605cd4783eb660775d7d2b8ee
1e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey/* 2e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project 3e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * 4e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * you may not use this file except in compliance with the License. 6e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * You may obtain a copy of the License at 7e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * 8e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * 10e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * See the License for the specific language governing permissions and 14e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey * limitations under the License. 15e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey */ 16e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey 1716e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKaypackage com.android.documentsui.picker; 18e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey 19c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKayimport static com.android.documentsui.Shared.DEBUG; 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_TREE; 24b8a5e08119c75b65ccecea8b6a59f2c87ea8ff32Ben Kwaimport static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION; 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; 34e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.content.Intent; 351d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkeyimport android.content.pm.ResolveInfo; 36e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.net.Uri; 37e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.os.Bundle; 382023fcf5a16503524ca8ad1bfb8445a67d27d0a6Tomasz Mikolajewskiimport android.os.Parcelable; 39f339f25982d562e1690358eb6dc663b327960945Jeff Sharkeyimport android.provider.DocumentsContract; 40c4693349d1a49dec8fd203f2c7adce18eee28b0aBen Kwaimport android.support.design.widget.Snackbar; 41e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkeyimport android.util.Log; 4209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkeyimport android.view.Menu; 43e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey 4416e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.BaseActivity; 4516e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.DocumentsApplication; 4616e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.DocumentsMenuManager; 4716e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.MenuManager; 4816e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.MenuManager.DirectoryDetails; 49d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.base.DocumentInfo; 50d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.base.PairedTask; 51d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.base.RootInfo; 5216e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.MimePredicate; 5316e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.R; 5416e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.Shared; 5516e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.Snackbars; 5616e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKayimport com.android.documentsui.State; 57f68210e9a1e36e65e56e0c95cfe990f0145ea63fSteve McKayimport com.android.documentsui.dirlist.DirectoryFragment; 587c35b036cb0de801a093df62da92c4a94399c26cBen Linimport com.android.documentsui.dirlist.FragmentTuner; 597c35b036cb0de801a093df62da92c4a94399c26cBen Linimport com.android.documentsui.dirlist.FragmentTuner.DocumentsTuner; 60d71bd61114e7bd71bac0100187faf75b2284092bTomasz Mikolajewskiimport com.android.documentsui.dirlist.Model; 61d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.picker.LastAccessedProvider.Columns; 62c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKayimport com.android.documentsui.services.FileOperationService; 63d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.sidebar.RootsFragment; 64f7adc939ea1191816a0a7572509d18d0659161ceJeff Sharkey 650e66b9b46fac44785b4059d45933aaba7324b691Ben Kwaimport java.util.Arrays; 660e66b9b46fac44785b4059d45933aaba7324b691Ben Kwaimport java.util.List; 670e66b9b46fac44785b4059d45933aaba7324b691Ben Kwa 6816e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKaypublic class PickActivity extends BaseActivity { 694045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey private static final int CODE_FORWARD = 42; 700574b18a7a95b29fab3cdb9ced6e5b46e24030feBen Kwa private static final String TAG = "DocumentsActivity"; 717c35b036cb0de801a093df62da92c4a94399c26cBen Lin private DocumentsMenuManager mMenuManager; 727c35b036cb0de801a093df62da92c4a94399c26cBen Lin private DirectoryDetails mDetails; 734045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey 7416e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay public PickActivity() { 7518d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay super(R.layout.documents_activity, TAG); 76b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 7709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey 78e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey @Override 79e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey public void onCreate(Bundle icicle) { 800fbfc653868966da7fd6109b247974e0d87a2297Steve McKay super.onCreate(icicle); 817c35b036cb0de801a093df62da92c4a94399c26cBen Lin mMenuManager = new DocumentsMenuManager(mSearchManager, getDisplayState()); 827c35b036cb0de801a093df62da92c4a94399c26cBen Lin mDetails = new DirectoryDetails(this); 83b243af7203b9f158bf95c1bf697856d1ee175a10Oren Blasberg 84b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey if (mState.action == ACTION_CREATE) { 8509c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey final String mimeType = getIntent().getType(); 8609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE); 8709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey SaveFragment.show(getFragmentManager(), mimeType, title); 88caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono } else if (mState.action == ACTION_OPEN_TREE || 89ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa mState.action == ACTION_PICK_COPY_DESTINATION) { 906e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey PickFragment.show(getFragmentManager()); 9109c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey } 9246165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey 93b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey if (mState.action == ACTION_GET_CONTENT) { 941d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey final Intent moreApps = new Intent(getIntent()); 951d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey moreApps.setComponent(null); 961d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey moreApps.setPackage(null); 971d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey RootsFragment.show(getFragmentManager(), moreApps); 98caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono } else if (mState.action == ACTION_OPEN || 99caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono mState.action == ACTION_CREATE || 100caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono mState.action == ACTION_OPEN_TREE || 101ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa mState.action == ACTION_PICK_COPY_DESTINATION) { 102821727a0fd0fa608a3046db8dad6ea588e16828fBen Lin RootsFragment.show(getFragmentManager(), (Intent) null); 1031d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey } 104761122118b2437aee3a44e9263b73766986c12b8Jeff Sharkey 105fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay if (mState.restored) { 106a4cb878fa5a7b5253784ca712c824aaae3472585Aga Wronska if (DEBUG) Log.d(TAG, "Stack already resolved"); 107fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay } else { 108fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay // We set the activity title in AsyncTask.onPostExecute(). 109fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay // To prevent talkback from reading aloud the default title, we clear it here. 110fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay setTitle(""); 111fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay 112fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay // As a matter of policy we don't load the last used stack for the copy 113fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay // destination picker (user is already in Files app). 114fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay // Concensus was that the experice was too confusing. 115fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay // In all other cases, where the user is visiting us from another app 116fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay // we restore the stack as last used from that app. 117fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay if (mState.action == ACTION_PICK_COPY_DESTINATION) { 118fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay if (DEBUG) Log.d(TAG, "Launching directly into Home directory."); 11964ae1f4e0236cf9ff06e19887c491bf08ee8adceAga Wronska loadRoot(getDefaultRoot()); 120fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay } else { 121fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay if (DEBUG) Log.d(TAG, "Attempting to load last used stack for calling package."); 1227232bf030839be0584824f0b38586360ba365051Ben Lin new LoadLastAccessedStackTask(this).execute(); 123fd8425ae34b73879ca14d244e63381c9400b48d7Steve McKay } 1248b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey } 125b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey } 126f339f25982d562e1690358eb6dc663b327960945Jeff Sharkey 1270fbfc653868966da7fd6109b247974e0d87a2297Steve McKay @Override 12816e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay protected void includeState(State state) { 129b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey final Intent intent = getIntent(); 130b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey final String action = intent.getAction(); 131b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) { 132b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay state.action = ACTION_OPEN; 133b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) { 134b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay state.action = ACTION_CREATE; 135b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey } else if (Intent.ACTION_GET_CONTENT.equals(action)) { 136b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay state.action = ACTION_GET_CONTENT; 137f4943e16a80a7ae37ee19e9301017c15061df378Jeff Sharkey } else if (Intent.ACTION_OPEN_DOCUMENT_TREE.equals(action)) { 138b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay state.action = ACTION_OPEN_TREE; 139ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa } else if (Shared.ACTION_PICK_COPY_DESTINATION.equals(action)) { 140ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa state.action = ACTION_PICK_COPY_DESTINATION; 141b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey } 14246165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey 143b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT) { 144b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay state.allowMultiple = intent.getBooleanExtra( 145b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey Intent.EXTRA_ALLOW_MULTIPLE, false); 146b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey } 14746165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey 14895d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT 14995d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski || state.action == ACTION_CREATE) { 15095d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski state.openableOnly = intent.hasCategory(Intent.CATEGORY_OPENABLE); 15195d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski } 15295d9c2514fd469b47390fd585819c7478e227221Tomasz Mikolajewski 153ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa if (state.action == ACTION_PICK_COPY_DESTINATION) { 154f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay // Indicates that a copy operation (or move) includes a directory. 155f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay // Why? Directory creation isn't supported by some roots (like Downloads). 156f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay // This allows us to restrict available roots to just those with support. 157b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay state.directoryCopy = intent.getBooleanExtra( 158ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa Shared.EXTRA_DIRECTORY_COPY, false); 159f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay state.copyOperationSubType = intent.getIntExtra( 1604833477d7d42fa79ee42956bae4aebad77074e4bGarfield, Tan FileOperationService.EXTRA_OPERATION_TYPE, 161c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay FileOperationService.OPERATION_COPY); 162f2a822d1b63215dff38e042fe52469755544cf4cDaichi Hirono } 1638b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey } 1648b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey 165b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay public void onAppPicked(ResolveInfo info) { 166b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay final Intent intent = new Intent(getIntent()); 167b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT); 168b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay intent.setComponent(new ComponentName( 169b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay info.activityInfo.applicationInfo.packageName, info.activityInfo.name)); 170b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay startActivityForResult(intent, CODE_FORWARD); 171b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 1728b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey 173b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay @Override 174b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay protected void onActivityResult(int requestCode, int resultCode, Intent data) { 175543a29231a88ac332d1b1c03ccf0cb605b6aebfeBen Kwa if (DEBUG) Log.d(TAG, "onActivityResult() code=" + resultCode); 17638ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey 177b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay // Only relay back results when not canceled; otherwise stick around to 178b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay // let the user pick another app/backend. 179b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) { 18038ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey 181b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay // Remember that we last picked via external app 182b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay final String packageName = getCallingPackageMaybeExtra(); 183b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay final ContentValues values = new ContentValues(); 1847232bf030839be0584824f0b38586360ba365051Ben Lin values.put(Columns.EXTERNAL, 1); 1857232bf030839be0584824f0b38586360ba365051Ben Lin getContentResolver().insert(LastAccessedProvider.buildLastAccessed(packageName), values); 1868b9970489d03ee0bda3d8d4773bf672c182922c6Jeff Sharkey 187b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay // Pass back result to original caller 188b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay setResult(resultCode, data); 189b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay finish(); 190b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } else { 191b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay super.onActivityResult(requestCode, resultCode, data); 1925b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey } 193f339f25982d562e1690358eb6dc663b327960945Jeff Sharkey } 1945b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey 19546165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey @Override 19646165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey protected void onPostCreate(Bundle savedInstanceState) { 19746165b507883ff67a790a04d74b8d62de60ba227Jeff Sharkey super.onPostCreate(savedInstanceState); 19818d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay mDrawer.update(); 19918d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay mNavigator.update(); 200e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey } 201e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey 202b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay @Override 20318d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay public String getDrawerTitle() { 20418d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay String title = getIntent().getStringExtra(DocumentsContract.EXTRA_PROMPT); 20518d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay if (title == null) { 20618d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay if (mState.action == ACTION_OPEN || 20718d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay mState.action == ACTION_GET_CONTENT || 20818d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay mState.action == ACTION_OPEN_TREE) { 20918d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay title = getResources().getString(R.string.title_open); 21018d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay } else if (mState.action == ACTION_CREATE || 21118d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay mState.action == ACTION_PICK_COPY_DESTINATION) { 21218d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay title = getResources().getString(R.string.title_save); 21377fd402217fc708895158c64ccfdd280dfc1a57fTomasz Mikolajewski } else { 21417f7e5891cbe86fc6cacae045a4edd3e41f8d5eeSteve McKay // If all else fails, just call it "Documents". 21517f7e5891cbe86fc6cacae045a4edd3e41f8d5eeSteve McKay title = getResources().getString(R.string.app_label); 21609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey } 217e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey } 218e6fcceb3a65896401450ded1d3fbd13024730873Jeff Sharkey 21918d01e8d21376475cc9882dfcdce4a3d75f66690Steve McKay return title; 22009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey } 221e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey 22209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey @Override 22309c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey public boolean onPrepareOptionsMenu(Menu menu) { 22409c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey super.onPrepareOptionsMenu(menu); 2257c35b036cb0de801a093df62da92c4a94399c26cBen Lin mMenuManager.updateOptionMenu(menu, mDetails); 22609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey 227724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey final DocumentInfo cwd = getCurrentDirectory(); 2285b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey 229e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay if (mState.action == ACTION_CREATE) { 230e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay final FragmentManager fm = getFragmentManager(); 2310fe95042025a9bcf73b0d7a6c3f027092bab825cSteve McKay SaveFragment.get(fm).prepareForDirectory(cwd); 232e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay } 233e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay 23409c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey return true; 235e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey } 236e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey 23709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey @Override 23816e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay protected void refreshDirectory(int anim) { 2395b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey final FragmentManager fm = getFragmentManager(); 240a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey final RootInfo root = getCurrentRoot(); 241724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey final DocumentInfo cwd = getCurrentDirectory(); 242c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey 2432e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey if (cwd == null) { 2442e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey // No directory means recents 245caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono if (mState.action == ACTION_CREATE || 246ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa mState.action == ACTION_PICK_COPY_DESTINATION) { 2477232bf030839be0584824f0b38586360ba365051Ben Lin loadRoot(getDefaultRoot()); 2482e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey } else { 249c8ae7a5cc51c220c9e0aa2b9c3d128f803f0df16Jeff Sharkey DirectoryFragment.showRecentsOpen(fm, anim); 2507d58fc6e8875ccc3dbbb34bcd379a0f9c9ee481eJeff Sharkey 2517776aa5f01b3aa9f7b401ba4f78735a4e028dda4Steve McKay // In recents we pick layout mode based on the mimetype, 2527776aa5f01b3aa9f7b401ba4f78735a4e028dda4Steve McKay // picking GRID for visual types. We intentionally don't 2537776aa5f01b3aa9f7b401ba4f78735a4e028dda4Steve McKay // consult a user's saved preferences here since they are 2547776aa5f01b3aa9f7b401ba4f78735a4e028dda4Steve McKay // set per root (not per root and per mimetype). 2557776aa5f01b3aa9f7b401ba4f78735a4e028dda4Steve McKay boolean visualMimes = MimePredicate.mimeMatches( 25638ec252f93f0798d81b11fce0a4064214928d969Jeff Sharkey MimePredicate.VISUAL_MIMES, mState.acceptMimes); 2577776aa5f01b3aa9f7b401ba4f78735a4e028dda4Steve McKay mState.derivedMode = visualMimes ? State.MODE_GRID : State.MODE_LIST; 2582e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey } 2592e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey } else { 2602e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey // Normal boring directory 2618788dadd1b13193b577812df4f9f16a642ebfbb7Aga Wronska DirectoryFragment.showDirectory(fm, root, cwd, anim); 26209c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey } 2632e694f88bd2088765403f01f8951d1fb4c7244c5Jeff Sharkey 264c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey // Forget any replacement target 265b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey if (mState.action == ACTION_CREATE) { 266c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey final SaveFragment save = SaveFragment.get(fm); 267c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey if (save != null) { 268c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey save.setReplaceTarget(null); 269c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey } 270c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey } 271c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey 272caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono if (mState.action == ACTION_OPEN_TREE || 273ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa mState.action == ACTION_PICK_COPY_DESTINATION) { 2746e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey final PickFragment pick = PickFragment.get(fm); 2756e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey if (pick != null) { 276f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay pick.setPickTarget(mState.action, mState.copyOperationSubType, cwd); 2776e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey } 2786e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey } 27909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey } 28009c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey 281b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay void onSaveRequested(DocumentInfo replaceTarget) { 282c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay new ExistingFinishTask(this, replaceTarget.derivedUri) 283c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay .executeOnExecutor(getExecutorForCurrentDirectory()); 2849dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2859dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2865e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay @Override 28716e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay public void setPending(boolean pending) { 28816e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay final SaveFragment save = SaveFragment.get(getFragmentManager()); 28916e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay if (save != null) { 29016e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay save.setPending(pending); 29116e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay } 29216e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay } 29316e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay 29416e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay @Override 29516e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay protected void onDirectoryCreated(DocumentInfo doc) { 2960af8afd3309538dec784ed0c9c35b252a8213123Steve McKay assert(doc.isDirectory()); 2975e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay openContainerDocument(doc); 2985e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 2995e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 300b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay void onSaveRequested(String mimeType, String displayName) { 301c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay new CreateFinishTask(this, mimeType, displayName) 302c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay .executeOnExecutor(getExecutorForCurrentDirectory()); 3034045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey } 3044045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey 3054045780fb2336d23588546da473c462e9634e0a1Jeff Sharkey @Override 306d71bd61114e7bd71bac0100187faf75b2284092bTomasz Mikolajewski public void onDocumentPicked(DocumentInfo doc, Model model) { 30709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey final FragmentManager fm = getFragmentManager(); 308734936aaddd080946a92e80bc65dc3d11a93f2d1Tomasz Mikolajewski if (doc.isContainer()) { 309734936aaddd080946a92e80bc65dc3d11a93f2d1Tomasz Mikolajewski openContainerDocument(doc); 310b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) { 31109c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey // Explicit file picked, return 312c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay new ExistingFinishTask(this, doc.derivedUri) 313c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay .executeOnExecutor(getExecutorForCurrentDirectory()); 314b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey } else if (mState.action == ACTION_CREATE) { 315c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey // Replace selected file 316c6cbdf11d976ff5845d12c46fb2d601ca7fb0ab2Jeff Sharkey SaveFragment.get(fm).setReplaceTarget(doc); 31709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey } 31809c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey } 31909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey 320d0a2a2c4e061da0de1b0008b841cacd9fc4416edSteve McKay @Override 321724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public void onDocumentsPicked(List<DocumentInfo> docs) { 322b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) { 323873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey final int size = docs.size(); 324873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey final Uri[] uris = new Uri[size]; 325873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey for (int i = 0; i < size; i++) { 326a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey uris[i] = docs.get(i).derivedUri; 327873daa3bd4d88e91fccf0dd6f05bacc5f2b1fef5Jeff Sharkey } 328c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay new ExistingFinishTask(this, uris) 329c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay .executeOnExecutor(getExecutorForCurrentDirectory()); 330c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey } 331c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey } 332c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey 3336e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey public void onPickRequested(DocumentInfo pickTarget) { 334caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono Uri result; 335caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono if (mState.action == ACTION_OPEN_TREE) { 336caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono result = DocumentsContract.buildTreeDocumentUri( 337caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono pickTarget.authority, pickTarget.documentId); 338ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa } else if (mState.action == ACTION_PICK_COPY_DESTINATION) { 339caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono result = pickTarget.derivedUri; 340caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono } else { 341caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono // Should not be reached. 342caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono throw new IllegalStateException("Invalid mState.action."); 343caadd41756cf53d71a735c8cf4ec16e7224de146Daichi Hirono } 344c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay new PickFinishTask(this, result).executeOnExecutor(getExecutorForCurrentDirectory()); 3456e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey } 3466e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey 3477232bf030839be0584824f0b38586360ba365051Ben Lin void updateLastAccessed() { 3487232bf030839be0584824f0b38586360ba365051Ben Lin LastAccessedProvider.setLastAccessed( 3497232bf030839be0584824f0b38586360ba365051Ben Lin getContentResolver(), getCallingPackageMaybeExtra(), mState.stack); 3509dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 3519dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 352b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay @Override 35316e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay protected void onTaskFinished(Uri... uris) { 354543a29231a88ac332d1b1c03ccf0cb605b6aebfeBen Kwa if (DEBUG) Log.d(TAG, "onFinished() " + Arrays.toString(uris)); 3555b53592dc3d9691ea96af39ed37246169bcc74c3Jeff Sharkey 35609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey final Intent intent = new Intent(); 357c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey if (uris.length == 1) { 358c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey intent.setData(uris[0]); 359c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey } else if (uris.length > 1) { 360a5defe39d4eea635f9e2fac1822ff9c8d48a474aJeff Sharkey final ClipData clipData = new ClipData( 361b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey null, mState.acceptMimes, new ClipData.Item(uris[0])); 362c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey for (int i = 1; i < uris.length; i++) { 363c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey clipData.addItem(new ClipData.Item(uris[i])); 364c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey } 365c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey intent.setClipData(clipData); 366c317af8d44d225b63e5e8879b218f1a7575604d7Jeff Sharkey } 36709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey 368b36204422c05de753a17ea9f53a422bf4e4acffcJeff Sharkey if (mState.action == ACTION_GET_CONTENT) { 3691d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 3706c3164ded0ff721997f388783a6d2fd436e22366Jeff Sharkey } else if (mState.action == ACTION_OPEN_TREE) { 3716e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION 3726e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 3736e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 3746e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 375ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa } else if (mState.action == ACTION_PICK_COPY_DESTINATION) { 3766c3164ded0ff721997f388783a6d2fd436e22366Jeff Sharkey // Picking a copy destination is only used internally by us, so we 3776c3164ded0ff721997f388783a6d2fd436e22366Jeff Sharkey // don't need to extend permissions to the caller. 3784d0255f79cc92a5675d14b20f9cdf06ecb8d7109Steve McKay intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack); 3794833477d7d42fa79ee42956bae4aebad77074e4bGarfield, Tan intent.putExtra(FileOperationService.EXTRA_OPERATION_TYPE, mState.copyOperationSubType); 3801d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey } else { 3811d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION 3821d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 38313d369f702aeed957db63858e942b2f1c117bffdJeff Sharkey | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 3841d890e0daf2f46dc83580280cfa22031dfebc216Jeff Sharkey } 38509c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey 38609c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey setResult(Activity.RESULT_OK, intent); 38709c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey finish(); 38809c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey } 38909c10bf0b982cda69fadc182841c23d6792f0471Jeff Sharkey 390c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay 39116e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay public static PickActivity get(Fragment fragment) { 39216e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay return (PickActivity) fragment.getActivity(); 393b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 394b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 3957c35b036cb0de801a093df62da92c4a94399c26cBen Lin @Override 3967c35b036cb0de801a093df62da92c4a94399c26cBen Lin public FragmentTuner createFragmentTuner() { 3977c35b036cb0de801a093df62da92c4a94399c26cBen Lin // Currently DocumentsTuner maintains a state specific to the fragment instance. Because of 3987c35b036cb0de801a093df62da92c4a94399c26cBen Lin // that, we create a new instance everytime it is needed 3999de0da60f46dbdf6939f371a619d4d2018949d36Steve McKay return new DocumentsTuner(this, getDisplayState(), mSortController); 4007c35b036cb0de801a093df62da92c4a94399c26cBen Lin } 4017c35b036cb0de801a093df62da92c4a94399c26cBen Lin 4027c35b036cb0de801a093df62da92c4a94399c26cBen Lin @Override 4037c35b036cb0de801a093df62da92c4a94399c26cBen Lin public MenuManager getMenuManager() { 4047c35b036cb0de801a093df62da92c4a94399c26cBen Lin return mMenuManager; 4057c35b036cb0de801a093df62da92c4a94399c26cBen Lin } 4067c35b036cb0de801a093df62da92c4a94399c26cBen Lin 407ebf2a172b69cfa9105cb5807e7b76f58425be76cBen Lin @Override 408ebf2a172b69cfa9105cb5807e7b76f58425be76cBen Lin public DirectoryDetails getDirectoryDetails() { 409ebf2a172b69cfa9105cb5807e7b76f58425be76cBen Lin return mDetails; 410ebf2a172b69cfa9105cb5807e7b76f58425be76cBen Lin } 411ebf2a172b69cfa9105cb5807e7b76f58425be76cBen Lin 41216e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay private static final class PickFinishTask extends PairedTask<PickActivity, Void, Void> { 413b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay private final Uri mUri; 414b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 41516e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay public PickFinishTask(PickActivity activity, Uri uri) { 416c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay super(activity); 417b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay mUri = uri; 418b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 419b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 420b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay @Override 421c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay protected Void run(Void... params) { 4227232bf030839be0584824f0b38586360ba365051Ben Lin mOwner.updateLastAccessed(); 423b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay return null; 424b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 425b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 426b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay @Override 427c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay protected void finish(Void result) { 428c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay mOwner.onTaskFinished(mUri); 429b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 430b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 431b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 43216e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay private static final class ExistingFinishTask extends PairedTask<PickActivity, Void, Void> { 433b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay private final Uri[] mUris; 434b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 43516e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay public ExistingFinishTask(PickActivity activity, Uri... uris) { 436c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay super(activity); 437b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay mUris = uris; 438b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 439b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 440b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay @Override 441c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay protected Void run(Void... params) { 4427232bf030839be0584824f0b38586360ba365051Ben Lin mOwner.updateLastAccessed(); 443b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay return null; 444b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 445b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 446b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay @Override 447c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay protected void finish(Void result) { 448c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay mOwner.onTaskFinished(mUris); 449b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 450b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay } 451b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay 452b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay /** 453b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay * Task that creates a new document in the background. 454b68dd223b2623c22793f5dcd0f658de0aa92f80dSteve McKay */ 45516e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay private static final class CreateFinishTask extends PairedTask<PickActivity, Void, Uri> { 4569dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey private final String mMimeType; 4579dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey private final String mDisplayName; 4589dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 45916e0c1fcf2be1ac7daafa6cb2c1c97d751ca3e66Steve McKay public CreateFinishTask(PickActivity activity, String mimeType, String displayName) { 460c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay super(activity); 4619dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey mMimeType = mimeType; 4629dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey mDisplayName = displayName; 4639dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 4649dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 4659dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey @Override 466c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay protected void prepare() { 467c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay mOwner.setPending(true); 4684be51f196d60ba23856b646de3091364230258b0Jeff Sharkey } 4694be51f196d60ba23856b646de3091364230258b0Jeff Sharkey 4704be51f196d60ba23856b646de3091364230258b0Jeff Sharkey @Override 471c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay protected Uri run(Void... params) { 472c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay final ContentResolver resolver = mOwner.getContentResolver(); 473c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay final DocumentInfo cwd = mOwner.getCurrentDirectory(); 4743fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey 4753fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey ContentProviderClient client = null; 4763fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey Uri childUri = null; 4773fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey try { 4783fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey client = DocumentsApplication.acquireUnstableProviderOrThrow( 4793fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey resolver, cwd.derivedUri.getAuthority()); 4803fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey childUri = DocumentsContract.createDocument( 4813fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey client, cwd.derivedUri, mMimeType, mDisplayName); 4823fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey } catch (Exception e) { 4833fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey Log.w(TAG, "Failed to create document", e); 4843fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey } finally { 4853fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey ContentProviderClient.releaseQuietly(client); 4863fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey } 4873fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey 4889dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey if (childUri != null) { 4897232bf030839be0584824f0b38586360ba365051Ben Lin mOwner.updateLastAccessed(); 4909dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 4913fd11777c7eab734919efa4d8e7755aef803c19fJeff Sharkey 4929dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey return childUri; 4939dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 4949dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 4959dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey @Override 496c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay protected void finish(Uri result) { 4979dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey if (result != null) { 498c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay mOwner.onTaskFinished(result); 4999dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else { 500e980927578d51373a53a3aa9531bc73fb773fff8Steve McKay Snackbars.makeSnackbar( 501c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay mOwner, R.string.save_error, Snackbar.LENGTH_SHORT).show(); 5029dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 5034be51f196d60ba23856b646de3091364230258b0Jeff Sharkey 504c7dc0cfe6f990a8589f37ef593378a691d379c94Steve McKay mOwner.setPending(false); 5059dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 5069dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 507e22d02ecf489473c9983c554de308306e2741b7Jeff Sharkey} 508