DocumentsActivity.java revision 7aa7601c09ab5d87cc15a0ed9a8f511d494a4cbc
19e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey/* 29e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project 39e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 49e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 59e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * you may not use this file except in compliance with the License. 69e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * You may obtain a copy of the License at 79e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 89e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 99e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 109e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 119e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 129e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * See the License for the specific language governing permissions and 149e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * limitations under the License. 159e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey */ 169e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 179e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeypackage com.android.documentsui; 189e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 19e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport static com.android.documentsui.DirectoryFragment.ANIM_DOWN; 20e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport static com.android.documentsui.DirectoryFragment.ANIM_NONE; 21e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport static com.android.documentsui.DirectoryFragment.ANIM_SIDE; 22e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport static com.android.documentsui.DirectoryFragment.ANIM_UP; 23b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.ACTION_CREATE; 24b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.ACTION_GET_CONTENT; 25b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE; 26b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.ACTION_OPEN; 27b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_GRID; 28b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_LIST; 294eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 3054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.app.ActionBar; 3154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.app.ActionBar.OnNavigationListener; 329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.Activity; 339fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkeyimport android.app.Fragment; 349e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentManager; 354eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.ActivityNotFoundException; 36be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.content.ClipData; 3754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.ComponentName; 387aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.content.ContentProviderClient; 39be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.content.ContentResolver; 4020d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkeyimport android.content.ContentValues; 419e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Intent; 4254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.pm.ResolveInfo; 4388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.content.res.Resources; 4454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.database.Cursor; 4588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.graphics.Point; 46bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.graphics.drawable.ColorDrawable; 4788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.graphics.drawable.Drawable; 4888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.graphics.drawable.InsetDrawable; 499e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.net.Uri; 50a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport android.os.AsyncTask; 519e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.os.Bundle; 52b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport android.os.Parcel; 53e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.os.Parcelable; 54a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkeyimport android.provider.DocumentsContract; 553e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkeyimport android.provider.DocumentsContract.Root; 56bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.app.ActionBarDrawerToggle; 57bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.view.GravityCompat; 58bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.widget.DrawerLayout; 59bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.widget.DrawerLayout.DrawerListener; 609e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.util.Log; 61e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.util.SparseArray; 629e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.LayoutInflater; 6354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.Menu; 6454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.MenuItem; 654ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.view.MenuItem.OnActionExpandListener; 6688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.view.MotionEvent; 679e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.View; 6888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.view.View.OnTouchListener; 699e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.ViewGroup; 7088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.view.WindowManager; 7154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.BaseAdapter; 7228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkeyimport android.widget.ImageView; 73bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.widget.SearchView; 74bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.widget.SearchView.OnQueryTextListener; 7554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.TextView; 767e258b31e70464bb6d80b8b42f0cef8e4417bd6aJeff Sharkeyimport android.widget.Toast; 779e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 78d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport com.android.documentsui.RecentsProvider.RecentColumns; 79d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport com.android.documentsui.RecentsProvider.ResumeColumns; 80ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo; 81b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport com.android.documentsui.model.DocumentStack; 82b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport com.android.documentsui.model.DurableUtils; 83ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.RootInfo; 84e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport com.google.common.collect.Maps; 8520d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey 86ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkeyimport libcore.io.IoUtils; 87ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey 880c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkeyimport java.io.FileNotFoundException; 89b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.IOException; 90be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.Arrays; 91a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport java.util.Collection; 925545f56f7561810187545a1817b6001dd1f9931bJeff Sharkeyimport java.util.HashMap; 93be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.List; 94be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 959e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeypublic class DocumentsActivity extends Activity { 96ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final String TAG = "Documents"; 979e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 9888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey private static final String EXTRA_STATE = "state"; 9988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 1005545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey private static final int CODE_FORWARD = 42; 1015545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey 10288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey private boolean mShowAsDialog; 10388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 104bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey private SearchView mSearchView; 105bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 106bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey private DrawerLayout mDrawerLayout; 107bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey private ActionBarDrawerToggle mDrawerToggle; 10888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey private View mRootsContainer; 1091482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey 110e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private DirectoryContainerView mDirectoryContainer; 111e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 112ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey private boolean mIgnoreNextNavigation; 11388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey private boolean mIgnoreNextClose; 1144ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private boolean mIgnoreNextCollapse; 115ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey 1164eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private RootsCache mRoots; 117b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private State mState; 11854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1199e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 1209e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey public void onCreate(Bundle icicle) { 1219e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey super.onCreate(icicle); 1229e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 1234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mRoots = DocumentsApplication.getRootsCache(this); 1244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 125b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey setResult(Activity.RESULT_CANCELED); 126b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey setContentView(R.layout.activity); 12754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 12888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final Resources res = getResources(); 12988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mShowAsDialog = res.getBoolean(R.bool.show_as_dialog); 13088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 13188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (mShowAsDialog) { 13288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // backgroundDimAmount from theme isn't applied; do it manually 13388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final WindowManager.LayoutParams a = getWindow().getAttributes(); 13488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey a.dimAmount = 0.6f; 13588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey getWindow().setAttributes(a); 13688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 13788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 13888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey getWindow().setFlags(~0, WindowManager.LayoutParams.FLAG_DIM_BEHIND); 13988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 14088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // Inset ourselves to look like a dialog 14188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final Point size = new Point(); 14288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey getWindowManager().getDefaultDisplay().getSize(size); 14388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 14488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final int width = (int) res.getFraction(R.dimen.dialog_width, size.x, size.x); 14588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final int height = (int) res.getFraction(R.dimen.dialog_height, size.y, size.y); 14688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final int insetX = (size.x - width) / 2; 14788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final int insetY = (size.y - height) / 2; 14888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 14988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final Drawable before = getWindow().getDecorView().getBackground(); 15088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final Drawable after = new InsetDrawable(before, insetX, insetY, insetX, insetY); 15188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey getWindow().getDecorView().setBackground(after); 15288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 15388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // Dismiss when touch down in the dimmed inset area 15488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey getWindow().getDecorView().setOnTouchListener(new OnTouchListener() { 15588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey @Override 15688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public boolean onTouch(View v, MotionEvent event) { 15788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (event.getAction() == MotionEvent.ACTION_DOWN) { 15888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final float x = event.getX(); 15988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final float y = event.getY(); 16088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (x < insetX || x > v.getWidth() - insetX || y < insetY 16188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey || y > v.getHeight() - insetY) { 16288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey finish(); 16388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return true; 16488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 16588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 16688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return false; 16788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 16888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey }); 16988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 17088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 17188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // Non-dialog means we have a drawer 17288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 1734eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 17488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 1751feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey R.drawable.ic_drawer_glyph, R.string.drawer_open, R.string.drawer_close); 176be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 17788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerLayout.setDrawerListener(mDrawerListener); 17888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerLayout.setDrawerShadow(R.drawable.ic_drawer_shadow, GravityCompat.START); 179b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 18088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mRootsContainer = findViewById(R.id.container_roots); 18188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 182b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 183e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory); 184e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 185b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (icicle != null) { 186b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState = icicle.getParcelable(EXTRA_STATE); 187be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 188b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey buildDefaultState(); 18954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 19054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 19188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // Hide roots when we're managing a specific root 192b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_MANAGE) { 19388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (mShowAsDialog) { 19488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey findViewById(R.id.dialog_roots).setVisibility(View.GONE); 19588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 19688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); 19788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 198b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 19954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 200b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_CREATE) { 20154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final String mimeType = getIntent().getType(); 20254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE); 20354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey SaveFragment.show(getFragmentManager(), mimeType, title); 20454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 205bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 206b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_GET_CONTENT) { 20754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final Intent moreApps = new Intent(getIntent()); 20854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey moreApps.setComponent(null); 20954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey moreApps.setPackage(null); 21054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey RootsFragment.show(getFragmentManager(), moreApps); 211b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (mState.action == ACTION_OPEN || mState.action == ACTION_CREATE) { 21254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey RootsFragment.show(getFragmentManager(), null); 21354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 21466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 215a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (!mState.restored) { 216a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (mState.action == ACTION_MANAGE) { 217a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final Uri rootUri = getIntent().getData(); 218a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey new RestoreRootTask(rootUri).execute(); 219a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } else { 220a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey new RestoreStackTask().execute(); 221a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 222a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } else { 223a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey onCurrentDirectoryChanged(ANIM_NONE); 224a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 225b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 226a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey 227b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private void buildDefaultState() { 228b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState = new State(); 22966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 230b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final Intent intent = getIntent(); 231b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final String action = intent.getAction(); 232b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) { 233b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.action = ACTION_OPEN; 234b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) { 235b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.action = ACTION_CREATE; 236b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (Intent.ACTION_GET_CONTENT.equals(action)) { 237b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.action = ACTION_GET_CONTENT; 238a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) { 239b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.action = ACTION_MANAGE; 240b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 241bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 242b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) { 243b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.allowMultiple = intent.getBooleanExtra( 244b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey Intent.EXTRA_ALLOW_MULTIPLE, false); 245b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 246bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 247b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_MANAGE) { 248b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.acceptMimes = new String[] { "*/*" }; 249b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.allowMultiple = true; 250b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) { 251b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES); 252b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else { 253b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.acceptMimes = new String[] { intent.getType() }; 254b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 255bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 256b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false); 257348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey mState.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(this); 258a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 259a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 260a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey private class RestoreRootTask extends AsyncTask<Void, Void, RootInfo> { 261a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey private Uri mRootUri; 262a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 263a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public RestoreRootTask(Uri rootUri) { 264a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mRootUri = rootUri; 265a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 266a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 267a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 268a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey protected RootInfo doInBackground(Void... params) { 269a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final String rootId = DocumentsContract.getRootId(mRootUri); 270a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey return mRoots.getRootOneshot(mRootUri.getAuthority(), rootId); 271a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 272a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 273a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 274a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey protected void onPostExecute(RootInfo root) { 275a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (isDestroyed()) return; 276a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mState.restored = true; 277a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey 278a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey if (root != null) { 279a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey onRootPicked(root, true); 280a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } else { 281a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey Log.w(TAG, "Failed to find root: " + mRootUri); 282a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey finish(); 283a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 284a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 285a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 286a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey 287a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey private class RestoreStackTask extends AsyncTask<Void, Void, Void> { 288a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey private volatile boolean mRestoredStack; 289deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey private volatile boolean mExternal; 290a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 291a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 292a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey protected Void doInBackground(Void... params) { 293a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey // Restore last stack for calling package 294a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey final String packageName = getCallingPackage(); 295a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey final Cursor cursor = getContentResolver() 296a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey .query(RecentsProvider.buildResume(packageName), null, null, null, null); 297a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey try { 298a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey if (cursor.moveToFirst()) { 2996a20e574116af1072782c1e87cb03eb33f05ec50Jeff Sharkey mExternal = cursor.getInt(cursor.getColumnIndex(ResumeColumns.EXTERNAL)) != 0; 300b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final byte[] rawStack = cursor.getBlob( 301d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey cursor.getColumnIndex(ResumeColumns.STACK)); 302b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey DurableUtils.readFromArray(rawStack, mState.stack); 303a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mRestoredStack = true; 304a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 305b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } catch (IOException e) { 3066a20e574116af1072782c1e87cb03eb33f05ec50Jeff Sharkey Log.w(TAG, "Failed to resume: " + e); 307a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } finally { 308ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey IoUtils.closeQuietly(cursor); 309ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } 310ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey 311deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey if (mRestoredStack) { 312deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Update the restored stack to ensure we have freshest data 313deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState); 314deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey try { 315deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState.stack.updateRoot(matchingRoots); 316deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState.stack.updateDocuments(getContentResolver()); 317deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } catch (FileNotFoundException e) { 318deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey Log.w(TAG, "Failed to restore stack: " + e); 319deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState.stack.reset(); 320deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mRestoredStack = false; 321deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } 322dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 323a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey 324a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey return null; 325a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 326a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 327a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 328a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey protected void onPostExecute(Void result) { 329a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (isDestroyed()) return; 330a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mState.restored = true; 331a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 332deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Show drawer when no stack restored, but only when requesting 333deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // non-visual content. However, if we last used an external app, 334deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // drawer is always shown. 335deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 336deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey boolean showDrawer = false; 337deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey if (!mRestoredStack) { 338deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey showDrawer = true; 339deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } 340deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey if (MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) { 341deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey showDrawer = false; 342deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } 343deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey if (mExternal && mState.action == ACTION_GET_CONTENT) { 344deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey showDrawer = true; 345deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } 346deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 347deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey if (showDrawer) { 34888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey setRootsDrawerOpen(true); 349ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } 350a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 351a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey onCurrentDirectoryChanged(ANIM_NONE); 352dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 353a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 354dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 355a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey @Override 35688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public void onResume() { 35788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey super.onResume(); 358a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey 359b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_MANAGE) { 360b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.showSize = true; 361a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } else { 362b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.showSize = SettingsActivity.getDisplayFileSize(this); 363deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey invalidateOptionsMenu(); 364a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 365bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 366bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 367bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey private DrawerListener mDrawerListener = new DrawerListener() { 368bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey @Override 369bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey public void onDrawerSlide(View drawerView, float slideOffset) { 370bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey mDrawerToggle.onDrawerSlide(drawerView, slideOffset); 371bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 372bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 373bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey @Override 374bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey public void onDrawerOpened(View drawerView) { 375bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey mDrawerToggle.onDrawerOpened(drawerView); 376bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey updateActionBar(); 3774ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey invalidateOptionsMenu(); 378bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 379bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 380bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey @Override 381bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey public void onDrawerClosed(View drawerView) { 382bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey mDrawerToggle.onDrawerClosed(drawerView); 383bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey updateActionBar(); 3844ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey invalidateOptionsMenu(); 385bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 386bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 387bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey @Override 388bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey public void onDrawerStateChanged(int newState) { 389bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey mDrawerToggle.onDrawerStateChanged(newState); 390bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 391bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey }; 392bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 393bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey @Override 394bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey protected void onPostCreate(Bundle savedInstanceState) { 395bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey super.onPostCreate(savedInstanceState); 39688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (mDrawerToggle != null) { 39788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerToggle.syncState(); 39888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 39988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 40088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 40188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public void setRootsDrawerOpen(boolean open) { 40288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (!mShowAsDialog) { 40388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (open) { 40488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerLayout.openDrawer(mRootsContainer); 40588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 40688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerLayout.closeDrawer(mRootsContainer); 40788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 40888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 40988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 41088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 41188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey private boolean isRootsDrawerOpen() { 41288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (mShowAsDialog) { 41388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return false; 41488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 41588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return mDrawerLayout.isDrawerOpen(mRootsContainer); 41688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 4179e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 4189e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 41954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public void updateActionBar() { 42054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final ActionBar actionBar = getActionBar(); 4219e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 422bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey actionBar.setDisplayShowHomeEnabled(true); 4239e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 42488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final boolean showIndicator = !mShowAsDialog && (mState.action != ACTION_MANAGE); 42588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey actionBar.setDisplayHomeAsUpEnabled(showIndicator); 42688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (mDrawerToggle != null) { 42788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mDrawerToggle.setDrawerIndicatorEnabled(showIndicator); 428ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } 429ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey 43088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (isRootsDrawerOpen()) { 43154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 432bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey actionBar.setIcon(new ColorDrawable()); 43354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 434b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) { 43554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey actionBar.setTitle(R.string.title_open); 436b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (mState.action == ACTION_CREATE) { 43754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey actionBar.setTitle(R.string.title_save); 43854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 439bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } else { 440ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final RootInfo root = getCurrentRoot(); 441aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey actionBar.setIcon(root != null ? root.loadIcon(this) : null); 442ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 443ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey if (mState.stack.size() <= 1) { 444ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 445ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey actionBar.setTitle(root.title); 446ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } else { 447ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey mIgnoreNextNavigation = true; 448ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 449ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey actionBar.setTitle(null); 450ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey actionBar.setListNavigationCallbacks(mStackAdapter, mStackListener); 451ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey actionBar.setSelectedNavigationItem(mStackAdapter.getCount() - 1); 452bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 4539e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 45454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 4559e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 45654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 45754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public boolean onCreateOptionsMenu(Menu menu) { 45854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey super.onCreateOptionsMenu(menu); 45954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey getMenuInflater().inflate(R.menu.activity, menu); 460bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 46188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // Actions are always visible when showing as dialog 46288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (mShowAsDialog) { 46388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey for (int i = 0; i < menu.size(); i++) { 46488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey menu.getItem(i).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 46588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 46688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 46788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 468bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey final MenuItem searchMenu = menu.findItem(R.id.menu_search); 469bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey mSearchView = (SearchView) searchMenu.getActionView(); 470bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey mSearchView.setOnQueryTextListener(new OnQueryTextListener() { 471bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey @Override 472bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey public boolean onQueryTextSubmit(String query) { 473b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.currentSearch = query; 47488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mSearchView.clearFocus(); 475e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey onCurrentDirectoryChanged(ANIM_NONE); 476bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey return true; 477bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 478bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 479bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey @Override 480bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey public boolean onQueryTextChange(String newText) { 481bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey return false; 482bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 483bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey }); 484bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 4854ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey searchMenu.setOnActionExpandListener(new OnActionExpandListener() { 486b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 4874ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public boolean onMenuItemActionExpand(MenuItem item) { 4884ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey return true; 4894ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 4904ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 4914ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey @Override 4924ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public boolean onMenuItemActionCollapse(MenuItem item) { 4934ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (mIgnoreNextCollapse) { 4944ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIgnoreNextCollapse = false; 4954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey return true; 4964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 4974ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 498b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.currentSearch = null; 499e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey onCurrentDirectoryChanged(ANIM_NONE); 5004ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey return true; 501b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 502b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey }); 503b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 50488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mSearchView.setOnCloseListener(new SearchView.OnCloseListener() { 50588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey @Override 50688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public boolean onClose() { 50788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (mIgnoreNextClose) { 50888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mIgnoreNextClose = false; 50988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return false; 51088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 51188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 51288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mState.currentSearch = null; 513e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey onCurrentDirectoryChanged(ANIM_NONE); 51488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return false; 51588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 51688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey }); 51788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 51854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey return true; 51954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 52054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 52154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 52254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public boolean onPrepareOptionsMenu(Menu menu) { 52354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey super.onPrepareOptionsMenu(menu); 52454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 5259fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey final FragmentManager fm = getFragmentManager(); 5263e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey 5273e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey final RootInfo root = getCurrentRoot(); 528ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final DocumentInfo cwd = getCurrentDirectory(); 529dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 53054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final MenuItem createDir = menu.findItem(R.id.menu_create_dir); 531bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey final MenuItem search = menu.findItem(R.id.menu_search); 532ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey final MenuItem sort = menu.findItem(R.id.menu_sort); 533ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey final MenuItem sortSize = menu.findItem(R.id.menu_sort_size); 534ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey final MenuItem grid = menu.findItem(R.id.menu_grid); 5359fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey final MenuItem list = menu.findItem(R.id.menu_list); 536a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey final MenuItem settings = menu.findItem(R.id.menu_settings); 537dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 5384ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // Open drawer means we hide most actions 53988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (isRootsDrawerOpen()) { 5404ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey createDir.setVisible(false); 5414ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey search.setVisible(false); 5424ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey sort.setVisible(false); 5434ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey grid.setVisible(false); 5444ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey list.setVisible(false); 5454ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIgnoreNextCollapse = true; 5464ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey search.collapseActionView(); 5474ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey return true; 5484ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5494ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 55088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey sort.setVisible(cwd != null); 55188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey grid.setVisible(mState.derivedMode != MODE_GRID); 55288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey list.setVisible(mState.derivedMode != MODE_LIST); 5539fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 5544ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (mState.currentSearch != null) { 5554ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // Search uses backend ranking; no sorting 5564ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey sort.setVisible(false); 5574ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 5584ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey search.expandActionView(); 55988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 56088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mSearchView.setIconified(false); 56188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mSearchView.clearFocus(); 5624ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mSearchView.setQuery(mState.currentSearch, false); 5634ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } else { 56488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mIgnoreNextClose = true; 56588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mSearchView.setIconified(true); 56688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mSearchView.clearFocus(); 56788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 5684ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIgnoreNextCollapse = true; 5694ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey search.collapseActionView(); 5704ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5714ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 572ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey // Only sort by size when visible 573ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey sortSize.setVisible(mState.showSize); 574ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey 5759fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey final boolean searchVisible; 576b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_CREATE) { 5779fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey createDir.setVisible(cwd != null && cwd.isCreateSupported()); 5789fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey searchVisible = false; 5799fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 5809fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey // No display options in recent directories 5819fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey if (cwd == null) { 5829fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey grid.setVisible(false); 5839fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey list.setVisible(false); 5849fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 5859fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 586dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported()); 5879fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } else { 5889fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey createDir.setVisible(false); 5893e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey 5903e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey searchVisible = root != null 5913e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey && ((root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0); 592dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 593bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 5949fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey // TODO: close any search in-progress when hiding 5959fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey search.setVisible(searchVisible); 596b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 597b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey settings.setVisible(mState.action != ACTION_MANAGE); 598a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey 59954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey return true; 6009e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 6019e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 60254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 60354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public boolean onOptionsItemSelected(MenuItem item) { 60488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) { 605bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey return true; 606bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 607bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 60854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final int id = item.getItemId(); 60954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey if (id == android.R.id.home) { 610dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey onBackPressed(); 611bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey return true; 61254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } else if (id == R.id.menu_create_dir) { 61320d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey CreateDirectoryFragment.show(getFragmentManager()); 614bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey return true; 615bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } else if (id == R.id.menu_search) { 616bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey return false; 617ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } else if (id == R.id.menu_sort_name) { 618d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey setUserSortOrder(State.SORT_ORDER_DISPLAY_NAME); 619ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey return true; 620ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } else if (id == R.id.menu_sort_date) { 621d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey setUserSortOrder(State.SORT_ORDER_LAST_MODIFIED); 622ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey return true; 623ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } else if (id == R.id.menu_sort_size) { 624d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey setUserSortOrder(State.SORT_ORDER_SIZE); 625ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey return true; 626b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else if (id == R.id.menu_grid) { 627d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey setUserMode(State.MODE_GRID); 628b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return true; 629b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else if (id == R.id.menu_list) { 630d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey setUserMode(State.MODE_LIST); 631b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return true; 6329fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } else if (id == R.id.menu_settings) { 6339fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey startActivity(new Intent(this, SettingsActivity.class)); 6349fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey return true; 635b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 636b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return super.onOptionsItemSelected(item); 63754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 63854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 63954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 640d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey /** 641d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey * Update UI to reflect internal state changes not from user. 642d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey */ 643d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onStateChanged() { 644d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey invalidateOptionsMenu(); 645d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 646d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 647d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey /** 648d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey * Set state sort order based on explicit user action. 649d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey */ 650d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private void setUserSortOrder(int sortOrder) { 651fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mState.userSortOrder = sortOrder; 652d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey DirectoryFragment.get(getFragmentManager()).onUserSortOrderChanged(); 653d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 654d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 655d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey /** 656d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey * Set state mode based on explicit user action. 657d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey */ 658d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private void setUserMode(int mode) { 659fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mState.userMode = mode; 660d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey DirectoryFragment.get(getFragmentManager()).onUserModeChanged(); 661d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 662d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 663dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey @Override 664dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey public void onBackPressed() { 665fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (!mState.stackTouched) { 666fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey super.onBackPressed(); 667fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return; 668fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } 669fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 670b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final int size = mState.stack.size(); 671dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey if (size > 1) { 672b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.stack.pop(); 673e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey onCurrentDirectoryChanged(ANIM_UP); 67488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else if (size == 1 && !isRootsDrawerOpen()) { 675dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey // TODO: open root drawer once we can capture back key 676dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey super.onBackPressed(); 677dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } else { 678dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey super.onBackPressed(); 67954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 680dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 68154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 682b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 683b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey protected void onSaveInstanceState(Bundle state) { 684b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey super.onSaveInstanceState(state); 685b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey state.putParcelable(EXTRA_STATE, mState); 686b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 687b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 688b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 689b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey protected void onRestoreInstanceState(Bundle state) { 690b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey super.onRestoreInstanceState(state); 691b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey updateActionBar(); 692b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 693b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 694ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey private BaseAdapter mStackAdapter = new BaseAdapter() { 69554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 69654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public int getCount() { 697ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey return mState.stack.size(); 69854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 6999e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 70054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 701ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey public DocumentInfo getItem(int position) { 702ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey return mState.stack.get(mState.stack.size() - position - 1); 70354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 7049e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 70554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 70654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public long getItemId(int position) { 707bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey return position; 7089e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 7099e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 7109e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 71154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 71254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey if (convertView == null) { 71354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey convertView = LayoutInflater.from(parent.getContext()) 714bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey .inflate(R.layout.item_title, parent, false); 715bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 716bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 717bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 718ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey final DocumentInfo doc = getItem(position); 719bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 720ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey if (position == 0) { 721ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey final RootInfo root = getCurrentRoot(); 722ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey title.setText(root.title); 723bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } else { 724ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey title.setText(doc.displayName); 725bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 726bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 72728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey // No padding when shown in actionbar 72828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey convertView.setPadding(0, 0, 0, 0); 729bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey return convertView; 730bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey } 731bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 732bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey @Override 733bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey public View getDropDownView(int position, View convertView, ViewGroup parent) { 734bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey if (convertView == null) { 735bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey convertView = LayoutInflater.from(parent.getContext()) 73628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey .inflate(R.layout.item_title, parent, false); 7379e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 7389e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 73928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey final ImageView subdir = (ImageView) convertView.findViewById(R.id.subdir); 74028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 741ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey final DocumentInfo doc = getItem(position); 742ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey 743ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey if (position == 0) { 744ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey final RootInfo root = getCurrentRoot(); 74528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey title.setText(root.title); 74628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey subdir.setVisibility(View.GONE); 747ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } else { 74828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey title.setText(doc.displayName); 74928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey subdir.setVisibility(View.VISIBLE); 750ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } 7519e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 75254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey return convertView; 7539e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 75454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey }; 7559e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 756ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey private OnNavigationListener mStackListener = new OnNavigationListener() { 7579e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 75854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public boolean onNavigationItemSelected(int itemPosition, long itemId) { 759ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey if (mIgnoreNextNavigation) { 760ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey mIgnoreNextNavigation = false; 761ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey return false; 762ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } 763ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey 764ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey while (mState.stack.size() > itemPosition + 1) { 765fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mState.stackTouched = true; 766ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey mState.stack.pop(); 767ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey } 768e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey onCurrentDirectoryChanged(ANIM_UP); 76954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey return true; 77054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 77154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey }; 77254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 773ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public RootInfo getCurrentRoot() { 774d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey if (mState.stack.root != null) { 775d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey return mState.stack.root; 776b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 7774eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return mRoots.getRecentsRoot(); 778b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 779dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 780dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 781ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public DocumentInfo getCurrentDirectory() { 782b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return mState.stack.peek(); 783dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 784dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 785b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public State getDisplayState() { 786b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return mState; 7871482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey } 7881482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey 789e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private void onCurrentDirectoryChanged(int anim) { 790dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey final FragmentManager fm = getFragmentManager(); 791d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final RootInfo root = getCurrentRoot(); 792ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final DocumentInfo cwd = getCurrentDirectory(); 7939fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 794e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN); 795e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 796b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (cwd == null) { 797b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey // No directory means recents 798b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_CREATE) { 799b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey RecentsCreateFragment.show(fm); 800b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 801e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey DirectoryFragment.showRecentsOpen(fm, anim); 80288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 803deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Start recents in grid when requesting visual things 804deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final boolean visualMimes = MimePredicate.mimeMatches( 805deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey MimePredicate.VISUAL_MIMES, mState.acceptMimes); 806deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState.userMode = visualMimes ? MODE_GRID : MODE_LIST; 80788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey mState.derivedMode = mState.userMode; 808b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 809b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 810b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.currentSearch != null) { 811b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey // Ongoing search 812e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim); 813b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 814b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey // Normal boring directory 815e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey DirectoryFragment.showNormal(fm, root, cwd, anim); 816b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 81754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 818b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 8199fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey // Forget any replacement target 820b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_CREATE) { 8219fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey final SaveFragment save = SaveFragment.get(fm); 8229fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey if (save != null) { 8239fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey save.setReplaceTarget(null); 8249fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 8259fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 8269fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 82728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey final RootsFragment roots = RootsFragment.get(fm); 82828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey if (roots != null) { 82928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey roots.onCurrentRootChanged(); 83028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 83128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 832dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey updateActionBar(); 83354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey invalidateOptionsMenu(); 834dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey dumpStack(); 83554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 83654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 837b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onStackPicked(DocumentStack stack) { 838deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey try { 839deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Update the restored stack to ensure we have freshest data 840deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey stack.updateDocuments(getContentResolver()); 841deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 842deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState.stack = stack; 843deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState.stackTouched = true; 844deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey onCurrentDirectoryChanged(ANIM_SIDE); 845deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 846deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } catch (FileNotFoundException e) { 847deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey Log.w(TAG, "Failed to restore stack: " + e); 848deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } 849b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 850b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 851ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public void onRootPicked(RootInfo root, boolean closeDrawer) { 852ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey // Clear entire backstack and start in new root 853d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mState.stack.root = root; 854b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.stack.clear(); 855fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mState.stackTouched = true; 856b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 857aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (!mRoots.isRecentsRoot(root)) { 8586efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey new PickRootTask(root).execute(); 859b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 860e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey onCurrentDirectoryChanged(ANIM_SIDE); 861b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 86266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 86366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey if (closeDrawer) { 86488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey setRootsDrawerOpen(false); 86566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 866ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 867ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 8686efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private class PickRootTask extends AsyncTask<Void, Void, DocumentInfo> { 8696efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private RootInfo mRoot; 8706efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 8716efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public PickRootTask(RootInfo root) { 8726efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mRoot = root; 8736efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 8746efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 8756efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 8766efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey protected DocumentInfo doInBackground(Void... params) { 8776efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey try { 8786efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey final Uri uri = DocumentsContract.buildDocumentUri( 8796efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mRoot.authority, mRoot.documentId); 8806efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return DocumentInfo.fromUri(getContentResolver(), uri); 8816efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } catch (FileNotFoundException e) { 8827aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey Log.w(TAG, "Failed to find root", e); 8836efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return null; 8846efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 8856efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 8866efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 8876efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 8886efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey protected void onPostExecute(DocumentInfo result) { 8896efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (result != null) { 8906efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mState.stack.push(result); 8916efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mState.stackTouched = true; 8926efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey onCurrentDirectoryChanged(ANIM_SIDE); 8936efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 8946efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 8956efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 8966efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 89754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey public void onAppPicked(ResolveInfo info) { 89854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final Intent intent = new Intent(getIntent()); 8995545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT); 90054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey intent.setComponent(new ComponentName( 90154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey info.activityInfo.applicationInfo.packageName, info.activityInfo.name)); 9025545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey startActivityForResult(intent, CODE_FORWARD); 9035545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey } 9045545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey 9055545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey @Override 9065545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey protected void onActivityResult(int requestCode, int resultCode, Intent data) { 9075545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey Log.d(TAG, "onActivityResult() code=" + resultCode); 9085545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey 9095545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey // Only relay back results when not canceled; otherwise stick around to 9105545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey // let the user pick another app/backend. 9115545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) { 912deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 913deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Remember that we last picked via external app 914deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final String packageName = getCallingPackage(); 915deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final ContentValues values = new ContentValues(); 916deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey values.put(ResumeColumns.EXTERNAL, 1); 917deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey getContentResolver().insert(RecentsProvider.buildResume(packageName), values); 918deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 919deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Pass back result to original caller 9205545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey setResult(resultCode, data); 9215545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey finish(); 9225545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey } else { 9235545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey super.onActivityResult(requestCode, resultCode, data); 9245545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey } 92554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 92654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 927ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public void onDocumentPicked(DocumentInfo doc) { 92854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final FragmentManager fm = getFragmentManager(); 929b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (doc.isDirectory()) { 930b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mState.stack.push(doc); 931fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mState.stackTouched = true; 932e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey onCurrentDirectoryChanged(ANIM_DOWN); 933b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) { 93454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey // Explicit file picked, return 9356efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey new ExistingFinishTask(doc.derivedUri).execute(); 936b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (mState.action == ACTION_CREATE) { 9379fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey // Replace selected file 9389fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey SaveFragment.get(fm).setReplaceTarget(doc); 939b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (mState.action == ACTION_MANAGE) { 940a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey // First try managing the document; we expect manager to filter 941a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey // based on authority, so we don't grant. 942a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT); 943d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey manage.setData(doc.derivedUri); 944a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey 9454eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey try { 946a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey startActivity(manage); 9474eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } catch (ActivityNotFoundException ex) { 948a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey // Fall back to viewing 949a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey final Intent view = new Intent(Intent.ACTION_VIEW); 950a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 951d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey view.setData(doc.derivedUri); 952a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey 953a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey try { 954a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey startActivity(view); 955a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey } catch (ActivityNotFoundException ex2) { 956a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show(); 957a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey } 9584eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 95954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 96054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 96154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 962ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public void onDocumentsPicked(List<DocumentInfo> docs) { 963b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) { 9644eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int size = docs.size(); 9654eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final Uri[] uris = new Uri[size]; 9664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey for (int i = 0; i < size; i++) { 967d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey uris[i] = docs.get(i).derivedUri; 9684eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 9696efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey new ExistingFinishTask(uris).execute(); 970be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 971be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 972be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 973ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public void onSaveRequested(DocumentInfo replaceTarget) { 9746efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey new ExistingFinishTask(replaceTarget.derivedUri).execute(); 9759fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 97692d7e697a864a3e18bef4ef256bb3eb339a66b4eJeff Sharkey 9779fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey public void onSaveRequested(String mimeType, String displayName) { 9786efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey new CreateFinishTask(mimeType, displayName).execute(); 97954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 98054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 9816efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private void saveStackBlocking() { 982dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey final ContentResolver resolver = getContentResolver(); 983dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey final ContentValues values = new ContentValues(); 984dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 985b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack); 986b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_CREATE) { 987dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey // Remember stack for last create 988dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey values.clear(); 9896efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey values.put(RecentColumns.KEY, mState.stack.buildKey()); 990d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey values.put(RecentColumns.STACK, rawStack); 991d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey resolver.insert(RecentsProvider.buildRecent(), values); 992dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 993dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 994dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey // Remember location for next app launch 995dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey final String packageName = getCallingPackage(); 996dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey values.clear(); 997d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey values.put(ResumeColumns.STACK, rawStack); 998deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey values.put(ResumeColumns.EXTERNAL, 0); 999dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey resolver.insert(RecentsProvider.buildResume(packageName), values); 10006efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10016efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 10026efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private void onFinished(Uri... uris) { 10036efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey Log.d(TAG, "onFinished() " + Arrays.toString(uris)); 1004dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 100554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final Intent intent = new Intent(); 1006be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey if (uris.length == 1) { 1007be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey intent.setData(uris[0]); 1008be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else if (uris.length > 1) { 1009ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final ClipData clipData = new ClipData( 1010b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey null, mState.acceptMimes, new ClipData.Item(uris[0])); 1011be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey for (int i = 1; i < uris.length; i++) { 1012be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey clipData.addItem(new ClipData.Item(uris[i])); 1013be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 1014be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey intent.setClipData(clipData); 1015be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 101654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1017b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (mState.action == ACTION_GET_CONTENT) { 101854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 101954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } else { 102054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION 102154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 1022e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 102354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 102454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 102554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey setResult(Activity.RESULT_OK, intent); 102654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey finish(); 102754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 102854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 10296efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private class CreateFinishTask extends AsyncTask<Void, Void, Uri> { 10306efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private final String mMimeType; 10316efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private final String mDisplayName; 10326efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 10336efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public CreateFinishTask(String mimeType, String displayName) { 10346efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mMimeType = mimeType; 10356efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mDisplayName = displayName; 10366efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10376efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 10386efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 10396efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey protected Uri doInBackground(Void... params) { 10407aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey final ContentResolver resolver = getContentResolver(); 10416efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey final DocumentInfo cwd = getCurrentDirectory(); 10427aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 10437aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient client = null; 10447aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey Uri childUri = null; 10457aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey try { 10467aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey client = DocumentsApplication.acquireUnstableProviderOrThrow( 10477aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey resolver, cwd.derivedUri.getAuthority()); 10487aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey childUri = DocumentsContract.createDocument( 10497aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey client, cwd.derivedUri, mMimeType, mDisplayName); 10507aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } catch (Exception e) { 10517aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey Log.w(TAG, "Failed to create document", e); 10527aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } finally { 10537aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient.releaseQuietly(client); 10547aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } 10557aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 10566efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (childUri != null) { 10576efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey saveStackBlocking(); 10586efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10597aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 10606efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return childUri; 10616efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10626efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 10636efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 10646efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey protected void onPostExecute(Uri result) { 10656efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (result != null) { 10666efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey onFinished(result); 10676efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } else { 10686efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey Toast.makeText(DocumentsActivity.this, R.string.save_error, Toast.LENGTH_SHORT) 10696efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey .show(); 10706efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10716efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10726efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10736efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 10746efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private class ExistingFinishTask extends AsyncTask<Void, Void, Void> { 10756efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private final Uri[] mUris; 10766efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 10776efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public ExistingFinishTask(Uri... uris) { 10786efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mUris = uris; 10796efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10806efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 10816efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 10826efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey protected Void doInBackground(Void... params) { 10836efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey saveStackBlocking(); 10846efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return null; 10856efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10866efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 10876efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 10886efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey protected void onPostExecute(Void result) { 10896efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey onFinished(mUris); 10906efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10916efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 10926efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 1093b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public static class State implements android.os.Parcelable { 10944eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public int action; 1095ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public String[] acceptMimes; 1096fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 1097fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey /** Explicit user choice */ 1098fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey public int userMode = MODE_UNKNOWN; 1099fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey /** Derived after loader */ 1100fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey public int derivedMode = MODE_LIST; 1101fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 1102fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey /** Explicit user choice */ 1103fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey public int userSortOrder = SORT_ORDER_UNKNOWN; 1104fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey /** Derived after loader */ 1105fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME; 1106fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 1107ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public boolean allowMultiple = false; 1108b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public boolean showSize = false; 110954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey public boolean localOnly = false; 1110348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey public boolean showAdvanced = false; 1111fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey public boolean stackTouched = false; 1112a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public boolean restored = false; 11131482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey 1114b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey /** Current user navigation stack; empty implies recents. */ 1115b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public DocumentStack stack = new DocumentStack(); 1116b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey /** Currently active search, overriding any stack. */ 1117b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public String currentSearch; 1118b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1119e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey /** Instance state for every shown directory */ 1120e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap(); 1121e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 11224eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public static final int ACTION_OPEN = 1; 11234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public static final int ACTION_CREATE = 2; 11244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public static final int ACTION_GET_CONTENT = 3; 11254eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public static final int ACTION_MANAGE = 4; 11264eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 1127d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static final int MODE_UNKNOWN = 0; 1128d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static final int MODE_LIST = 1; 1129d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static final int MODE_GRID = 2; 11301482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey 1131d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static final int SORT_ORDER_UNKNOWN = 0; 1132d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static final int SORT_ORDER_DISPLAY_NAME = 1; 1133d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static final int SORT_ORDER_LAST_MODIFIED = 2; 1134d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static final int SORT_ORDER_SIZE = 3; 1135b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1136b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 1137b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public int describeContents() { 1138b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return 0; 1139b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1140b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1141b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 1142b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public void writeToParcel(Parcel out, int flags) { 1143b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeInt(action); 1144fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey out.writeInt(userMode); 1145b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeStringArray(acceptMimes); 1146fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey out.writeInt(userSortOrder); 1147b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeInt(allowMultiple ? 1 : 0); 1148b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeInt(showSize ? 1 : 0); 1149b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeInt(localOnly ? 1 : 0); 1150348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey out.writeInt(showAdvanced ? 1 : 0); 1151fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey out.writeInt(stackTouched ? 1 : 0); 1152a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey out.writeInt(restored ? 1 : 0); 1153b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey DurableUtils.writeToParcel(out, stack); 1154b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeString(currentSearch); 1155e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey out.writeMap(dirState); 1156b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1157b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1158b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public static final Creator<State> CREATOR = new Creator<State>() { 1159b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 1160b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public State createFromParcel(Parcel in) { 1161b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = new State(); 1162b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey state.action = in.readInt(); 1163fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.userMode = in.readInt(); 1164b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey state.acceptMimes = in.readStringArray(); 1165fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.userSortOrder = in.readInt(); 1166b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey state.allowMultiple = in.readInt() != 0; 1167b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey state.showSize = in.readInt() != 0; 1168b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey state.localOnly = in.readInt() != 0; 1169348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey state.showAdvanced = in.readInt() != 0; 1170fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.stackTouched = in.readInt() != 0; 1171a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey state.restored = in.readInt() != 0; 1172b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey DurableUtils.readFromParcel(in, state.stack); 1173b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey state.currentSearch = in.readString(); 1174e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey in.readMap(state.dirState, null); 1175b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return state; 1176b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1177b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1178b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 1179b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public State[] newArray(int size) { 1180b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return new State[size]; 1181b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1182b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey }; 11831482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey } 11841482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey 1185dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey private void dumpStack() { 1186d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey Log.d(TAG, "Current stack: "); 1187d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey Log.d(TAG, " * " + mState.stack.root); 1188b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (DocumentInfo doc : mState.stack) { 1189d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey Log.d(TAG, " +-- " + doc); 1190dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 1191dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey } 11929fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 11939fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey public static DocumentsActivity get(Fragment fragment) { 11949fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey return (DocumentsActivity) fragment.getActivity(); 11959fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 11969e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey} 1197