DocumentsActivity.java revision e66c1778f80f4b18e29e018eca3a338f125f23b9
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;
38be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.content.ContentResolver;
3920d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkeyimport android.content.ContentValues;
409e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Intent;
4154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.pm.ResolveInfo;
4288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.content.res.Resources;
4354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.database.Cursor;
4488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.graphics.Point;
45bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.graphics.drawable.ColorDrawable;
4688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.graphics.drawable.Drawable;
4788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.graphics.drawable.InsetDrawable;
489e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.net.Uri;
49a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport android.os.AsyncTask;
509e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.os.Bundle;
51b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport android.os.Parcel;
52e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.os.Parcelable;
53a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkeyimport android.provider.DocumentsContract;
543e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkeyimport android.provider.DocumentsContract.Root;
55bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.app.ActionBarDrawerToggle;
56bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.view.GravityCompat;
57bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.widget.DrawerLayout;
58bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.widget.DrawerLayout.DrawerListener;
599e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.util.Log;
60e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.util.SparseArray;
619e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.LayoutInflater;
6254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.Menu;
6354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.MenuItem;
644ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.view.MenuItem.OnActionExpandListener;
6588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.view.MotionEvent;
669e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.View;
6788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.view.View.OnTouchListener;
689e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.ViewGroup;
6988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkeyimport android.view.WindowManager;
7054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.BaseAdapter;
7128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkeyimport android.widget.ImageView;
72bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.widget.SearchView;
73bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.widget.SearchView.OnQueryTextListener;
7454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.TextView;
757e258b31e70464bb6d80b8b42f0cef8e4417bd6aJeff Sharkeyimport android.widget.Toast;
769e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
77d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport com.android.documentsui.RecentsProvider.RecentColumns;
78d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport com.android.documentsui.RecentsProvider.ResumeColumns;
79ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo;
80b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport com.android.documentsui.model.DocumentStack;
81b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport com.android.documentsui.model.DurableUtils;
82ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.RootInfo;
83e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport com.google.common.collect.Maps;
8420d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey
85ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkeyimport libcore.io.IoUtils;
86ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey
870c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkeyimport java.io.FileNotFoundException;
88b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.IOException;
89be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.Arrays;
90a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport java.util.Collection;
915545f56f7561810187545a1817b6001dd1f9931bJeff Sharkeyimport java.util.HashMap;
92be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.List;
93be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey
949e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeypublic class DocumentsActivity extends Activity {
95ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    public static final String TAG = "Documents";
969e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
9788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    private static final String EXTRA_STATE = "state";
9888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
995545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey    private static final int CODE_FORWARD = 42;
1005545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey
10188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    private boolean mShowAsDialog;
10288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
103bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private SearchView mSearchView;
104bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
105bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private DrawerLayout mDrawerLayout;
106bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private ActionBarDrawerToggle mDrawerToggle;
10788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    private View mRootsContainer;
1081482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
109e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey    private DirectoryContainerView mDirectoryContainer;
110e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey
111ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey    private boolean mIgnoreNextNavigation;
11288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    private boolean mIgnoreNextClose;
1134ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey    private boolean mIgnoreNextCollapse;
114ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey
1154eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey    private RootsCache mRoots;
116b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    private State mState;
11754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
1189e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey    @Override
1199e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey    public void onCreate(Bundle icicle) {
1209e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        super.onCreate(icicle);
1219e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
1224eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey        mRoots = DocumentsApplication.getRootsCache(this);
1234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey
124b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        setResult(Activity.RESULT_CANCELED);
125b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        setContentView(R.layout.activity);
12654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
12788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        final Resources res = getResources();
12888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        mShowAsDialog = res.getBoolean(R.bool.show_as_dialog);
12988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
13088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (mShowAsDialog) {
13188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            // backgroundDimAmount from theme isn't applied; do it manually
13288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            final WindowManager.LayoutParams a = getWindow().getAttributes();
13388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            a.dimAmount = 0.6f;
13488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            getWindow().setAttributes(a);
13588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
13688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
13788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            getWindow().setFlags(~0, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
13888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
13988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            // Inset ourselves to look like a dialog
14088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            final Point size = new Point();
14188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            getWindowManager().getDefaultDisplay().getSize(size);
14288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
14388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            final int width = (int) res.getFraction(R.dimen.dialog_width, size.x, size.x);
14488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            final int height = (int) res.getFraction(R.dimen.dialog_height, size.y, size.y);
14588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            final int insetX = (size.x - width) / 2;
14688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            final int insetY = (size.y - height) / 2;
14788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
14888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            final Drawable before = getWindow().getDecorView().getBackground();
14988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            final Drawable after = new InsetDrawable(before, insetX, insetY, insetX, insetY);
15088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            getWindow().getDecorView().setBackground(after);
15188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
15288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            // Dismiss when touch down in the dimmed inset area
15388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            getWindow().getDecorView().setOnTouchListener(new OnTouchListener() {
15488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                @Override
15588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                public boolean onTouch(View v, MotionEvent event) {
15688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
15788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                        final float x = event.getX();
15888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                        final float y = event.getY();
15988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                        if (x < insetX || x > v.getWidth() - insetX || y < insetY
16088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                                || y > v.getHeight() - insetY) {
16188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                            finish();
16288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                            return true;
16388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                        }
16488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                    }
16588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                    return false;
16688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                }
16788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            });
16888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
16988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        } else {
17088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            // Non-dialog means we have a drawer
17188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
1724eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey
17388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
1741feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey                    R.drawable.ic_drawer_glyph, R.string.drawer_open, R.string.drawer_close);
175be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey
17688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mDrawerLayout.setDrawerListener(mDrawerListener);
17788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mDrawerLayout.setDrawerShadow(R.drawable.ic_drawer_shadow, GravityCompat.START);
178b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
17988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mRootsContainer = findViewById(R.id.container_roots);
18088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        }
181b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
182e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey        mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
183e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey
184b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (icicle != null) {
185b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState = icicle.getParcelable(EXTRA_STATE);
186be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        } else {
187b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            buildDefaultState();
18854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
18954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
19088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        // Hide roots when we're managing a specific root
191b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_MANAGE) {
19288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            if (mShowAsDialog) {
19388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                findViewById(R.id.dialog_roots).setVisibility(View.GONE);
19488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            } else {
19588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
19688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            }
197b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        }
19854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
199b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_CREATE) {
20054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final String mimeType = getIntent().getType();
20154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
20254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            SaveFragment.show(getFragmentManager(), mimeType, title);
20354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
204bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
205b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_GET_CONTENT) {
20654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final Intent moreApps = new Intent(getIntent());
20754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            moreApps.setComponent(null);
20854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            moreApps.setPackage(null);
20954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            RootsFragment.show(getFragmentManager(), moreApps);
210b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_CREATE) {
21154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            RootsFragment.show(getFragmentManager(), null);
21254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        }
21366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
214a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        if (!mState.restored) {
215a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            if (mState.action == ACTION_MANAGE) {
216a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey                final Uri rootUri = getIntent().getData();
217a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey                new RestoreRootTask(rootUri).execute();
218a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            } else {
219a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey                new RestoreStackTask().execute();
220a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            }
221a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        } else {
222a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            onCurrentDirectoryChanged(ANIM_NONE);
223a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        }
224b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    }
225a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey
226b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    private void buildDefaultState() {
227b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        mState = new State();
22866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
229b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        final Intent intent = getIntent();
230b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        final String action = intent.getAction();
231b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) {
232b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.action = ACTION_OPEN;
233b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) {
234b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.action = ACTION_CREATE;
235b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
236b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.action = ACTION_GET_CONTENT;
237a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey        } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
238b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.action = ACTION_MANAGE;
239b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        }
240bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
241b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
242b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.allowMultiple = intent.getBooleanExtra(
243b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                    Intent.EXTRA_ALLOW_MULTIPLE, false);
244b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        }
245bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
246b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_MANAGE) {
247b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.acceptMimes = new String[] { "*/*" };
248b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.allowMultiple = true;
249b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        } else if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
250b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES);
251b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        } else {
252b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.acceptMimes = new String[] { intent.getType() };
253b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        }
254bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
255b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        mState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);
256348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        mState.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(this);
257a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey    }
258a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey
259a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey    private class RestoreRootTask extends AsyncTask<Void, Void, RootInfo> {
260a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        private Uri mRootUri;
261a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey
262a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        public RestoreRootTask(Uri rootUri) {
263a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            mRootUri = rootUri;
264a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        }
265a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey
266a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        @Override
267a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        protected RootInfo doInBackground(Void... params) {
268a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            final String rootId = DocumentsContract.getRootId(mRootUri);
269a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            return mRoots.getRootOneshot(mRootUri.getAuthority(), rootId);
270a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        }
271a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey
272a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        @Override
273a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        protected void onPostExecute(RootInfo root) {
274a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            if (isDestroyed()) return;
275a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            mState.restored = true;
276a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey
277a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            if (root != null) {
278a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey                onRootPicked(root, true);
279a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            } else {
280a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey                Log.w(TAG, "Failed to find root: " + mRootUri);
281a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey                finish();
282a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            }
283a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        }
284a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey    }
285a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey
286a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey    private class RestoreStackTask extends AsyncTask<Void, Void, Void> {
287a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        private volatile boolean mRestoredStack;
288deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        private volatile boolean mExternal;
289a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey
290a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        @Override
291a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        protected Void doInBackground(Void... params) {
292a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            // Restore last stack for calling package
293a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            final String packageName = getCallingPackage();
294a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            final Cursor cursor = getContentResolver()
295a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey                    .query(RecentsProvider.buildResume(packageName), null, null, null, null);
296a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            try {
297a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey                if (cursor.moveToFirst()) {
2986a20e574116af1072782c1e87cb03eb33f05ec50Jeff Sharkey                    mExternal = cursor.getInt(cursor.getColumnIndex(ResumeColumns.EXTERNAL)) != 0;
299b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                    final byte[] rawStack = cursor.getBlob(
300d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey                            cursor.getColumnIndex(ResumeColumns.STACK));
301b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                    DurableUtils.readFromArray(rawStack, mState.stack);
302a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey                    mRestoredStack = true;
303a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey                }
304b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            } catch (IOException e) {
3056a20e574116af1072782c1e87cb03eb33f05ec50Jeff Sharkey                Log.w(TAG, "Failed to resume: " + e);
306a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            } finally {
307ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                IoUtils.closeQuietly(cursor);
308ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            }
309ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey
310deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            if (mRestoredStack) {
311deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                // Update the restored stack to ensure we have freshest data
312deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
313deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                try {
314deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                    mState.stack.updateRoot(matchingRoots);
315deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                    mState.stack.updateDocuments(getContentResolver());
316deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                } catch (FileNotFoundException e) {
317deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                    Log.w(TAG, "Failed to restore stack: " + e);
318deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                    mState.stack.reset();
319deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                    mRestoredStack = false;
320deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                }
321dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            }
322a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey
323a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            return null;
324a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        }
325a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey
326a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        @Override
327a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        protected void onPostExecute(Void result) {
328a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            if (isDestroyed()) return;
329a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            mState.restored = true;
330a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey
331deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            // Show drawer when no stack restored, but only when requesting
332deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            // non-visual content. However, if we last used an external app,
333deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            // drawer is always shown.
334deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
335deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            boolean showDrawer = false;
336deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            if (!mRestoredStack) {
337deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                showDrawer = true;
338deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            }
339deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            if (MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) {
340deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                showDrawer = false;
341deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            }
342deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            if (mExternal && mState.action == ACTION_GET_CONTENT) {
343deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                showDrawer = true;
344deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            }
345deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
346deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            if (showDrawer) {
34788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                setRootsDrawerOpen(true);
348ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            }
349a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey
350a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            onCurrentDirectoryChanged(ANIM_NONE);
351dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        }
352a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey    }
353dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
354a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey    @Override
35588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    public void onResume() {
35688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        super.onResume();
357a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey
358b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_MANAGE) {
359b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.showSize = true;
360a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        } else {
361b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.showSize = SettingsActivity.getDisplayFileSize(this);
362deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            invalidateOptionsMenu();
363a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        }
364bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    }
365bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
366bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private DrawerListener mDrawerListener = new DrawerListener() {
367bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
368bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public void onDrawerSlide(View drawerView, float slideOffset) {
369bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
370bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
371bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
372bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
373bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public void onDrawerOpened(View drawerView) {
374bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            mDrawerToggle.onDrawerOpened(drawerView);
375bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            updateActionBar();
3764ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            invalidateOptionsMenu();
377bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
378bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
379bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
380bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public void onDrawerClosed(View drawerView) {
381bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            mDrawerToggle.onDrawerClosed(drawerView);
382bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            updateActionBar();
3834ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            invalidateOptionsMenu();
384bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
385bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
386bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
387bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public void onDrawerStateChanged(int newState) {
388bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            mDrawerToggle.onDrawerStateChanged(newState);
389bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
390bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    };
391bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
392bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    @Override
393bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    protected void onPostCreate(Bundle savedInstanceState) {
394bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        super.onPostCreate(savedInstanceState);
39588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (mDrawerToggle != null) {
39688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mDrawerToggle.syncState();
39788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        }
39888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    }
39988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
40088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    public void setRootsDrawerOpen(boolean open) {
40188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (!mShowAsDialog) {
40288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            if (open) {
40388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                mDrawerLayout.openDrawer(mRootsContainer);
40488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            } else {
40588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                mDrawerLayout.closeDrawer(mRootsContainer);
40688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            }
40788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        }
40888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    }
40988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
41088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey    private boolean isRootsDrawerOpen() {
41188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (mShowAsDialog) {
41288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            return false;
41388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        } else {
41488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            return mDrawerLayout.isDrawerOpen(mRootsContainer);
41588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        }
4169e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey    }
4179e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
41854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public void updateActionBar() {
41954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final ActionBar actionBar = getActionBar();
4209e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
421bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        actionBar.setDisplayShowHomeEnabled(true);
4229e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
42388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        final boolean showIndicator = !mShowAsDialog && (mState.action != ACTION_MANAGE);
42488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        actionBar.setDisplayHomeAsUpEnabled(showIndicator);
42588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (mDrawerToggle != null) {
42688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mDrawerToggle.setDrawerIndicatorEnabled(showIndicator);
427ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        }
428ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey
42988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (isRootsDrawerOpen()) {
43054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
431bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            actionBar.setIcon(new ColorDrawable());
43254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
433b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
43454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                actionBar.setTitle(R.string.title_open);
435b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            } else if (mState.action == ACTION_CREATE) {
43654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                actionBar.setTitle(R.string.title_save);
43754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            }
438bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        } else {
439ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey            final RootInfo root = getCurrentRoot();
440aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey            actionBar.setIcon(root != null ? root.loadIcon(this) : null);
441ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
442ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            if (mState.stack.size() <= 1) {
443ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
444ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setTitle(root.title);
445ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            } else {
446ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                mIgnoreNextNavigation = true;
447ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
448ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setTitle(null);
449ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                actionBar.setListNavigationCallbacks(mStackAdapter, mStackListener);
450ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                actionBar.setSelectedNavigationItem(mStackAdapter.getCount() - 1);
451bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
4529e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        }
45354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
4549e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
45554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
45654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public boolean onCreateOptionsMenu(Menu menu) {
45754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        super.onCreateOptionsMenu(menu);
45854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        getMenuInflater().inflate(R.menu.activity, menu);
459bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
46088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        // Actions are always visible when showing as dialog
46188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (mShowAsDialog) {
46288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            for (int i = 0; i < menu.size(); i++) {
46388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                menu.getItem(i).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
46488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            }
46588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        }
46688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
467bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        final MenuItem searchMenu = menu.findItem(R.id.menu_search);
468bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mSearchView = (SearchView) searchMenu.getActionView();
469bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
470bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            @Override
471bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            public boolean onQueryTextSubmit(String query) {
472b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                mState.currentSearch = query;
47388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                mSearchView.clearFocus();
474e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                onCurrentDirectoryChanged(ANIM_NONE);
475bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                return true;
476bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
477bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
478bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            @Override
479bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            public boolean onQueryTextChange(String newText) {
480bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                return false;
481bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
482bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        });
483bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
4844ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey        searchMenu.setOnActionExpandListener(new OnActionExpandListener() {
485b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            @Override
4864ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            public boolean onMenuItemActionExpand(MenuItem item) {
4874ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey                return true;
4884ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            }
4894ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey
4904ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            @Override
4914ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            public boolean onMenuItemActionCollapse(MenuItem item) {
4924ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey                if (mIgnoreNextCollapse) {
4934ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey                    mIgnoreNextCollapse = false;
4944ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey                    return true;
4954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey                }
4964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey
497b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                mState.currentSearch = null;
498e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                onCurrentDirectoryChanged(ANIM_NONE);
4994ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey                return true;
500b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            }
501b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        });
502b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
50388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
50488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            @Override
50588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            public boolean onClose() {
50688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                if (mIgnoreNextClose) {
50788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                    mIgnoreNextClose = false;
50888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                    return false;
50988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                }
51088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
51188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                mState.currentSearch = null;
512e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                onCurrentDirectoryChanged(ANIM_NONE);
51388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                return false;
51488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            }
51588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        });
51688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
51754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        return true;
51854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
51954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
52054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
52154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public boolean onPrepareOptionsMenu(Menu menu) {
52254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        super.onPrepareOptionsMenu(menu);
52354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
5249fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        final FragmentManager fm = getFragmentManager();
5253e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey
5263e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey        final RootInfo root = getCurrentRoot();
527ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        final DocumentInfo cwd = getCurrentDirectory();
528dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
52954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
530bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        final MenuItem search = menu.findItem(R.id.menu_search);
531ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        final MenuItem sort = menu.findItem(R.id.menu_sort);
532ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        final MenuItem sortSize = menu.findItem(R.id.menu_sort_size);
533ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        final MenuItem grid = menu.findItem(R.id.menu_grid);
5349fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        final MenuItem list = menu.findItem(R.id.menu_list);
535a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        final MenuItem settings = menu.findItem(R.id.menu_settings);
536dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
5374ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey        // Open drawer means we hide most actions
53888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (isRootsDrawerOpen()) {
5394ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            createDir.setVisible(false);
5404ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            search.setVisible(false);
5414ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            sort.setVisible(false);
5424ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            grid.setVisible(false);
5434ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            list.setVisible(false);
5444ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            mIgnoreNextCollapse = true;
5454ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            search.collapseActionView();
5464ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            return true;
5474ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey        }
5484ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey
54988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        sort.setVisible(cwd != null);
55088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        grid.setVisible(mState.derivedMode != MODE_GRID);
55188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        list.setVisible(mState.derivedMode != MODE_LIST);
5529fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
5534ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey        if (mState.currentSearch != null) {
5544ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            // Search uses backend ranking; no sorting
5554ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            sort.setVisible(false);
5564ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey
5574ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            search.expandActionView();
55888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
55988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mSearchView.setIconified(false);
56088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mSearchView.clearFocus();
5614ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            mSearchView.setQuery(mState.currentSearch, false);
5624ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey        } else {
56388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mIgnoreNextClose = true;
56488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mSearchView.setIconified(true);
56588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            mSearchView.clearFocus();
56688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
5674ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            mIgnoreNextCollapse = true;
5684ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey            search.collapseActionView();
5694ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey        }
5704ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey
571ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        // Only sort by size when visible
572ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        sortSize.setVisible(mState.showSize);
573ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey
5749fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        final boolean searchVisible;
575b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_CREATE) {
5769fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            createDir.setVisible(cwd != null && cwd.isCreateSupported());
5779fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            searchVisible = false;
5789fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
5799fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            // No display options in recent directories
5809fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            if (cwd == null) {
5819fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey                grid.setVisible(false);
5829fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey                list.setVisible(false);
5839fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            }
5849fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
585dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
5869fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        } else {
5879fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            createDir.setVisible(false);
5883e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey
5893e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey            searchVisible = root != null
5903e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey                    && ((root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0);
591dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        }
592bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
5939fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        // TODO: close any search in-progress when hiding
5949fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        search.setVisible(searchVisible);
595b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
596b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        settings.setVisible(mState.action != ACTION_MANAGE);
597a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey
59854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        return true;
5999e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey    }
6009e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
60154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
60254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public boolean onOptionsItemSelected(MenuItem item) {
60388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
604bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return true;
605bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
606bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
60754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final int id = item.getItemId();
60854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        if (id == android.R.id.home) {
609dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            onBackPressed();
610bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return true;
61154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        } else if (id == R.id.menu_create_dir) {
61220d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey            CreateDirectoryFragment.show(getFragmentManager());
613bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return true;
614bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        } else if (id == R.id.menu_search) {
615bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return false;
616ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        } else if (id == R.id.menu_sort_name) {
617d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            setUserSortOrder(State.SORT_ORDER_DISPLAY_NAME);
618ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            return true;
619ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        } else if (id == R.id.menu_sort_date) {
620d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            setUserSortOrder(State.SORT_ORDER_LAST_MODIFIED);
621ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            return true;
622ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        } else if (id == R.id.menu_sort_size) {
623d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            setUserSortOrder(State.SORT_ORDER_SIZE);
624ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            return true;
625b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else if (id == R.id.menu_grid) {
626d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            setUserMode(State.MODE_GRID);
627b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            return true;
628b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else if (id == R.id.menu_list) {
629d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            setUserMode(State.MODE_LIST);
630b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            return true;
6319fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        } else if (id == R.id.menu_settings) {
6329fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            startActivity(new Intent(this, SettingsActivity.class));
6339fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            return true;
634b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else {
635b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            return super.onOptionsItemSelected(item);
63654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
63754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
63854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
639d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    /**
640d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey     * Update UI to reflect internal state changes not from user.
641d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey     */
642d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    public void onStateChanged() {
643d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        invalidateOptionsMenu();
644d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    }
645d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
646d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    /**
647d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey     * Set state sort order based on explicit user action.
648d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey     */
649d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    private void setUserSortOrder(int sortOrder) {
650fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        mState.userSortOrder = sortOrder;
651d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        DirectoryFragment.get(getFragmentManager()).onUserSortOrderChanged();
652d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    }
653d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
654d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    /**
655d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey     * Set state mode based on explicit user action.
656d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey     */
657d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    private void setUserMode(int mode) {
658fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        mState.userMode = mode;
659d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        DirectoryFragment.get(getFragmentManager()).onUserModeChanged();
660d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    }
661d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
662dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    @Override
663dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    public void onBackPressed() {
664fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        if (!mState.stackTouched) {
665fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey            super.onBackPressed();
666fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey            return;
667fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        }
668fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey
669b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        final int size = mState.stack.size();
670dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        if (size > 1) {
671b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.stack.pop();
672e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey            onCurrentDirectoryChanged(ANIM_UP);
67388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey        } else if (size == 1 && !isRootsDrawerOpen()) {
674dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            // TODO: open root drawer once we can capture back key
675dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            super.onBackPressed();
676dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        } else {
677dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            super.onBackPressed();
67854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
679dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    }
68054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
681b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    @Override
682b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    protected void onSaveInstanceState(Bundle state) {
683b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        super.onSaveInstanceState(state);
684b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        state.putParcelable(EXTRA_STATE, mState);
685b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    }
686b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
687b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    @Override
688b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    protected void onRestoreInstanceState(Bundle state) {
689b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        super.onRestoreInstanceState(state);
690b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        updateActionBar();
691b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    }
692b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
693ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey    private BaseAdapter mStackAdapter = new BaseAdapter() {
69454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        @Override
69554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public int getCount() {
696ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            return mState.stack.size();
69754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
6989e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
69954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        @Override
700ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        public DocumentInfo getItem(int position) {
701ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            return mState.stack.get(mState.stack.size() - position - 1);
70254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
7039e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
70454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        @Override
70554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public long getItemId(int position) {
706bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return position;
7079e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        }
7089e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
7099e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        @Override
71054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public View getView(int position, View convertView, ViewGroup parent) {
71154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            if (convertView == null) {
71254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                convertView = LayoutInflater.from(parent.getContext())
713bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                        .inflate(R.layout.item_title, parent, false);
714bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
715bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
716bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
717ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            final DocumentInfo doc = getItem(position);
718bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
719ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            if (position == 0) {
720ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                final RootInfo root = getCurrentRoot();
721ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                title.setText(root.title);
722bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            } else {
723ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                title.setText(doc.displayName);
724bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
725bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
72628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey            // No padding when shown in actionbar
72728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey            convertView.setPadding(0, 0, 0, 0);
728bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return convertView;
729bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
730bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
731bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
732bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public View getDropDownView(int position, View convertView, ViewGroup parent) {
733bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            if (convertView == null) {
734bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                convertView = LayoutInflater.from(parent.getContext())
73528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey                        .inflate(R.layout.item_title, parent, false);
7369e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey            }
7379e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
73828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey            final ImageView subdir = (ImageView) convertView.findViewById(R.id.subdir);
73928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
740ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            final DocumentInfo doc = getItem(position);
741ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey
742ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            if (position == 0) {
743ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                final RootInfo root = getCurrentRoot();
74428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey                title.setText(root.title);
74528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey                subdir.setVisibility(View.GONE);
746ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            } else {
74728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey                title.setText(doc.displayName);
74828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey                subdir.setVisibility(View.VISIBLE);
749ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            }
7509e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
75154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            return convertView;
7529e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        }
75354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    };
7549e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
755ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey    private OnNavigationListener mStackListener = new OnNavigationListener() {
7569e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        @Override
75754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public boolean onNavigationItemSelected(int itemPosition, long itemId) {
758ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            if (mIgnoreNextNavigation) {
759ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                mIgnoreNextNavigation = false;
760ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                return false;
761ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            }
762ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey
763ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            while (mState.stack.size() > itemPosition + 1) {
764fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey                mState.stackTouched = true;
765ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey                mState.stack.pop();
766ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            }
767e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey            onCurrentDirectoryChanged(ANIM_UP);
76854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            return true;
76954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
77054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    };
77154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
772ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public RootInfo getCurrentRoot() {
773d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        if (mState.stack.root != null) {
774d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            return mState.stack.root;
775b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else {
7764eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            return mRoots.getRecentsRoot();
777b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        }
778dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    }
779dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
780ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public DocumentInfo getCurrentDirectory() {
781b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        return mState.stack.peek();
782dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    }
783dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
784b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    public State getDisplayState() {
785b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        return mState;
7861482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey    }
7871482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
788e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey    private void onCurrentDirectoryChanged(int anim) {
789dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final FragmentManager fm = getFragmentManager();
790d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        final RootInfo root = getCurrentRoot();
791ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        final DocumentInfo cwd = getCurrentDirectory();
7929fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
793e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey        mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN);
794e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey
795b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        if (cwd == null) {
796b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            // No directory means recents
797b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            if (mState.action == ACTION_CREATE) {
798b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                RecentsCreateFragment.show(fm);
799b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            } else {
800e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                DirectoryFragment.showRecentsOpen(fm, anim);
80188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey
802deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                // Start recents in grid when requesting visual things
803deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                final boolean visualMimes = MimePredicate.mimeMatches(
804deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                        MimePredicate.VISUAL_MIMES, mState.acceptMimes);
805deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey                mState.userMode = visualMimes ? MODE_GRID : MODE_LIST;
80688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey                mState.derivedMode = mState.userMode;
807b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            }
808b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else {
809b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            if (mState.currentSearch != null) {
810b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                // Ongoing search
811e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
812b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            } else {
813b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                // Normal boring directory
814e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                DirectoryFragment.showNormal(fm, root, cwd, anim);
815b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            }
81654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
817b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
8189fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        // Forget any replacement target
819b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_CREATE) {
8209fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            final SaveFragment save = SaveFragment.get(fm);
8219fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            if (save != null) {
8229fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey                save.setReplaceTarget(null);
8239fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            }
8249fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        }
8259fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
82628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey        final RootsFragment roots = RootsFragment.get(fm);
82728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey        if (roots != null) {
82828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey            roots.onCurrentRootChanged();
82928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey        }
83028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey
831dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        updateActionBar();
83254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        invalidateOptionsMenu();
833dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        dumpStack();
83454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
83554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
836b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    public void onStackPicked(DocumentStack stack) {
837deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        try {
838deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            // Update the restored stack to ensure we have freshest data
839deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            stack.updateDocuments(getContentResolver());
840deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
841deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            mState.stack = stack;
842deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            mState.stackTouched = true;
843deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            onCurrentDirectoryChanged(ANIM_SIDE);
844deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
845deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        } catch (FileNotFoundException e) {
846deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            Log.w(TAG, "Failed to restore stack: " + e);
847deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        }
848b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    }
849b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
850ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public void onRootPicked(RootInfo root, boolean closeDrawer) {
851ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        // Clear entire backstack and start in new root
852d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        mState.stack.root = root;
853b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        mState.stack.clear();
854fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        mState.stackTouched = true;
855b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
856aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey        if (!mRoots.isRecentsRoot(root)) {
8570c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey            try {
858ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey                final Uri uri = DocumentsContract.buildDocumentUri(root.authority, root.documentId);
859e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                final DocumentInfo doc = DocumentInfo.fromUri(getContentResolver(), uri);
860e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                mState.stack.push(doc);
861e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                mState.stackTouched = true;
862e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                onCurrentDirectoryChanged(ANIM_SIDE);
8630c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey            } catch (FileNotFoundException e) {
8640c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey            }
865b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else {
866e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey            onCurrentDirectoryChanged(ANIM_SIDE);
867b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        }
86866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
86966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        if (closeDrawer) {
87088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey            setRootsDrawerOpen(false);
87166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
872ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
873ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
87454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    public void onAppPicked(ResolveInfo info) {
87554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        final Intent intent = new Intent(getIntent());
8765545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
87754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        intent.setComponent(new ComponentName(
87854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                info.activityInfo.applicationInfo.packageName, info.activityInfo.name));
8795545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        startActivityForResult(intent, CODE_FORWARD);
8805545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey    }
8815545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey
8825545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey    @Override
8835545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
8845545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        Log.d(TAG, "onActivityResult() code=" + resultCode);
8855545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey
8865545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        // Only relay back results when not canceled; otherwise stick around to
8875545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        // let the user pick another app/backend.
8885545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) {
889deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
890deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            // Remember that we last picked via external app
891deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            final String packageName = getCallingPackage();
892deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            final ContentValues values = new ContentValues();
893deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            values.put(ResumeColumns.EXTERNAL, 1);
894deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            getContentResolver().insert(RecentsProvider.buildResume(packageName), values);
895deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
896deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            // Pass back result to original caller
8975545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey            setResult(resultCode, data);
8985545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey            finish();
8995545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        } else {
9005545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey            super.onActivityResult(requestCode, resultCode, data);
9015545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        }
90254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    }
90354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
904ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public void onDocumentPicked(DocumentInfo doc) {
90554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final FragmentManager fm = getFragmentManager();
906b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        if (doc.isDirectory()) {
907b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            mState.stack.push(doc);
908fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey            mState.stackTouched = true;
909e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey            onCurrentDirectoryChanged(ANIM_DOWN);
910b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
91154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            // Explicit file picked, return
912d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            onFinished(doc.derivedUri);
913b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        } else if (mState.action == ACTION_CREATE) {
9149fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            // Replace selected file
9159fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            SaveFragment.get(fm).setReplaceTarget(doc);
916b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        } else if (mState.action == ACTION_MANAGE) {
917a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey            // First try managing the document; we expect manager to filter
918a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey            // based on authority, so we don't grant.
919a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey            final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
920d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            manage.setData(doc.derivedUri);
921a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey
9224eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            try {
923a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                startActivity(manage);
9244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            } catch (ActivityNotFoundException ex) {
925a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                // Fall back to viewing
926a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                final Intent view = new Intent(Intent.ACTION_VIEW);
927a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
928d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey                view.setData(doc.derivedUri);
929a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey
930a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                try {
931a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                    startActivity(view);
932a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                } catch (ActivityNotFoundException ex2) {
933a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                    Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
934a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey                }
9354eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            }
93654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
93754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
93854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
939ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public void onDocumentsPicked(List<DocumentInfo> docs) {
940b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
9414eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            final int size = docs.size();
9424eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            final Uri[] uris = new Uri[size];
9434eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            for (int i = 0; i < size; i++) {
944d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey                uris[i] = docs.get(i).derivedUri;
9454eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            }
9464eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey            onFinished(uris);
947be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        }
948be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey    }
949be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey
950ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public void onSaveRequested(DocumentInfo replaceTarget) {
951d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        onFinished(replaceTarget.derivedUri);
9529fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey    }
95392d7e697a864a3e18bef4ef256bb3eb339a66b4eJeff Sharkey
9549fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey    public void onSaveRequested(String mimeType, String displayName) {
955ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        final DocumentInfo cwd = getCurrentDirectory();
956aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey
957ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        final Uri childUri = DocumentsContract.createDocument(
958d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey                getContentResolver(), cwd.derivedUri, mimeType, displayName);
959ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        if (childUri != null) {
960dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            onFinished(childUri);
961ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey        } else {
9627e258b31e70464bb6d80b8b42f0cef8e4417bd6aJeff Sharkey            Toast.makeText(this, R.string.save_error, Toast.LENGTH_SHORT).show();
9637e258b31e70464bb6d80b8b42f0cef8e4417bd6aJeff Sharkey        }
96454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
96554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
966be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey    private void onFinished(Uri... uris) {
967be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        Log.d(TAG, "onFinished() " + Arrays.toString(uris));
96854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
969dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final ContentResolver resolver = getContentResolver();
970dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final ContentValues values = new ContentValues();
971dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
972b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
973b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_CREATE) {
974dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            // Remember stack for last create
975dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            values.clear();
976d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            values.put(RecentColumns.STACK, rawStack);
977d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            resolver.insert(RecentsProvider.buildRecent(), values);
978dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        }
979dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
980dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        // Remember location for next app launch
981dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final String packageName = getCallingPackage();
982dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        values.clear();
983d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        values.put(ResumeColumns.STACK, rawStack);
984deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        values.put(ResumeColumns.EXTERNAL, 0);
985dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        resolver.insert(RecentsProvider.buildResume(packageName), values);
986dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
98754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final Intent intent = new Intent();
988be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        if (uris.length == 1) {
989be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            intent.setData(uris[0]);
990be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        } else if (uris.length > 1) {
991ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            final ClipData clipData = new ClipData(
992b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                    null, mState.acceptMimes, new ClipData.Item(uris[0]));
993be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            for (int i = 1; i < uris.length; i++) {
994be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey                clipData.addItem(new ClipData.Item(uris[i]));
995be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            }
996be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            intent.setClipData(clipData);
997be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        }
99854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
999b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        if (mState.action == ACTION_GET_CONTENT) {
100054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
100154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        } else {
100254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
100354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
1004e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
100554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        }
100654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
100754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        setResult(Activity.RESULT_OK, intent);
100854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        finish();
100954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
101054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
1011b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    public static class State implements android.os.Parcelable {
10124eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey        public int action;
1013ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        public String[] acceptMimes;
1014fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey
1015fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        /** Explicit user choice */
1016fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        public int userMode = MODE_UNKNOWN;
1017fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        /** Derived after loader */
1018fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        public int derivedMode = MODE_LIST;
1019fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey
1020fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        /** Explicit user choice */
1021fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        public int userSortOrder = SORT_ORDER_UNKNOWN;
1022fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        /** Derived after loader */
1023fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME;
1024fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey
1025ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        public boolean allowMultiple = false;
1026b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        public boolean showSize = false;
102754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        public boolean localOnly = false;
1028348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        public boolean showAdvanced = false;
1029fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey        public boolean stackTouched = false;
1030a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey        public boolean restored = false;
10311482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
1032b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        /** Current user navigation stack; empty implies recents. */
1033b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        public DocumentStack stack = new DocumentStack();
1034b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        /** Currently active search, overriding any stack. */
1035b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        public String currentSearch;
1036b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
1037e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey        /** Instance state for every shown directory */
1038e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey        public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap();
1039e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey
10404eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey        public static final int ACTION_OPEN = 1;
10414eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey        public static final int ACTION_CREATE = 2;
10424eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey        public static final int ACTION_GET_CONTENT = 3;
10434eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey        public static final int ACTION_MANAGE = 4;
10444eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey
1045d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public static final int MODE_UNKNOWN = 0;
1046d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public static final int MODE_LIST = 1;
1047d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public static final int MODE_GRID = 2;
10481482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
1049d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public static final int SORT_ORDER_UNKNOWN = 0;
1050d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public static final int SORT_ORDER_DISPLAY_NAME = 1;
1051d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public static final int SORT_ORDER_LAST_MODIFIED = 2;
1052d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public static final int SORT_ORDER_SIZE = 3;
1053b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
1054b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        @Override
1055b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        public int describeContents() {
1056b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            return 0;
1057b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        }
1058b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
1059b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        @Override
1060b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        public void writeToParcel(Parcel out, int flags) {
1061b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            out.writeInt(action);
1062fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey            out.writeInt(userMode);
1063b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            out.writeStringArray(acceptMimes);
1064fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey            out.writeInt(userSortOrder);
1065b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            out.writeInt(allowMultiple ? 1 : 0);
1066b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            out.writeInt(showSize ? 1 : 0);
1067b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            out.writeInt(localOnly ? 1 : 0);
1068348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey            out.writeInt(showAdvanced ? 1 : 0);
1069fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey            out.writeInt(stackTouched ? 1 : 0);
1070a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey            out.writeInt(restored ? 1 : 0);
1071b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            DurableUtils.writeToParcel(out, stack);
1072b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            out.writeString(currentSearch);
1073e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey            out.writeMap(dirState);
1074b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        }
1075b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
1076b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        public static final Creator<State> CREATOR = new Creator<State>() {
1077b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            @Override
1078b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            public State createFromParcel(Parcel in) {
1079b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                final State state = new State();
1080b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                state.action = in.readInt();
1081fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey                state.userMode = in.readInt();
1082b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                state.acceptMimes = in.readStringArray();
1083fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey                state.userSortOrder = in.readInt();
1084b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                state.allowMultiple = in.readInt() != 0;
1085b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                state.showSize = in.readInt() != 0;
1086b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                state.localOnly = in.readInt() != 0;
1087348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey                state.showAdvanced = in.readInt() != 0;
1088fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey                state.stackTouched = in.readInt() != 0;
1089a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey                state.restored = in.readInt() != 0;
1090b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                DurableUtils.readFromParcel(in, state.stack);
1091b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                state.currentSearch = in.readString();
1092e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey                in.readMap(state.dirState, null);
1093b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                return state;
1094b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            }
1095b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
1096b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            @Override
1097b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            public State[] newArray(int size) {
1098b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                return new State[size];
1099b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            }
1100b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        };
11011482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey    }
11021482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
1103dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    private void dumpStack() {
1104d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        Log.d(TAG, "Current stack: ");
1105d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        Log.d(TAG, " * " + mState.stack.root);
1106b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        for (DocumentInfo doc : mState.stack) {
1107d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            Log.d(TAG, " +-- " + doc);
1108dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        }
1109dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    }
11109fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
11119fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey    public static DocumentsActivity get(Fragment fragment) {
11129fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        return (DocumentsActivity) fragment.getActivity();
11139fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey    }
11149e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey}
1115