DocumentsActivity.java revision b156f4bf8cdfe475a7116b627d84a281e1a281b7
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
1954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.app.ActionBar;
2054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.app.ActionBar.OnNavigationListener;
219e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.Activity;
229e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentManager;
23be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.content.ClipData;
24be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.content.ContentResolver;
2520d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkeyimport android.content.ContentValues;
269e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Intent;
2754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.database.Cursor;
28bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.graphics.drawable.ColorDrawable;
299e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.net.Uri;
309e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.os.Bundle;
3154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.provider.DocumentsContract.DocumentColumns;
32bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.app.ActionBarDrawerToggle;
33bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.view.GravityCompat;
34bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.widget.DrawerLayout;
35bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.support.v4.widget.DrawerLayout.DrawerListener;
369e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.util.Log;
379e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.LayoutInflater;
3854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.Menu;
3954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.MenuItem;
409e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.View;
419e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.ViewGroup;
4254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.BaseAdapter;
43bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.widget.SearchView;
44b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.widget.SearchView.OnCloseListener;
45bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkeyimport android.widget.SearchView.OnQueryTextListener;
4654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.TextView;
477e258b31e70464bb6d80b8b42f0cef8e4417bd6aJeff Sharkeyimport android.widget.Toast;
489e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
49ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport com.android.documentsui.model.Document;
50b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport com.android.documentsui.model.DocumentStack;
51ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport com.android.documentsui.model.Root;
5220d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey
53be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.Arrays;
54be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.List;
55be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey
569e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeypublic class DocumentsActivity extends Activity {
57ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    public static final String TAG = "Documents";
589e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
59b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    public static final int ACTION_OPEN = 1;
60b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    public static final int ACTION_CREATE = 2;
6154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
621482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey    private int mAction;
63be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey
64bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private SearchView mSearchView;
65bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
6666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    private View mRootsContainer;
67bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private DrawerLayout mDrawerLayout;
68bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private ActionBarDrawerToggle mDrawerToggle;
69bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
701482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey    private final DisplayState mDisplayState = new DisplayState();
711482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
72b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    /** Current user navigation stack; empty implies recents. */
73b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    private DocumentStack mStack;
74b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    /** Currently active search, overriding any stack. */
75b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    private String mCurrentSearch;
7654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
779e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey    @Override
789e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey    public void onCreate(Bundle icicle) {
799e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        super.onCreate(icicle);
809e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
81be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        final Intent intent = getIntent();
82be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        final String action = intent.getAction();
8354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) {
841482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey            mAction = ACTION_OPEN;
85ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            mDisplayState.allowMultiple = intent.getBooleanExtra(
86ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                    Intent.EXTRA_ALLOW_MULTIPLE, false);
8754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) {
881482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey            mAction = ACTION_CREATE;
891482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey            mDisplayState.allowMultiple = false;
90be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        }
91be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey
92be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
93ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            mDisplayState.acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES);
94be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        } else {
95ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            mDisplayState.acceptMimes = new String[] { intent.getType() };
9654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
9754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
98ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        if (MimePredicate.mimeMatches("image/*", mDisplayState.acceptMimes)) {
991482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey            mDisplayState.mode = DisplayState.MODE_GRID;
1001482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        } else {
1011482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey            mDisplayState.mode = DisplayState.MODE_LIST;
1021482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        }
1031482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
1049e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        setResult(Activity.RESULT_CANCELED);
10554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        setContentView(R.layout.activity);
10654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
1071482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        if (mAction == ACTION_CREATE) {
10854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final String mimeType = getIntent().getType();
10954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
11054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            SaveFragment.show(getFragmentManager(), mimeType, title);
11154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
112bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
11366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        RootsFragment.show(getFragmentManager());
11466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
11566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        mRootsContainer = findViewById(R.id.container_roots);
11666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
117bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
118bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
119bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
120bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
121bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
122bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mDrawerLayout.setDrawerListener(mDrawerListener);
123bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
124bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
12566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        mDrawerLayout.openDrawer(mRootsContainer);
126dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
127dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        // Restore last stack for calling package
128dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        // TODO: move into async loader
129dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final String packageName = getCallingPackage();
130dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final Cursor cursor = getContentResolver()
131dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey                .query(RecentsProvider.buildResume(packageName), null, null, null, null);
132dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        try {
133dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            if (cursor.moveToFirst()) {
134b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                final String raw = cursor.getString(
135dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey                        cursor.getColumnIndex(RecentsProvider.COL_PATH));
136b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                mStack = DocumentStack.deserialize(getContentResolver(), raw);
137dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            }
138dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        } finally {
139dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            cursor.close();
140dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        }
141dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
142dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        updateDirectoryFragment();
143bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    }
144bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
145bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private DrawerListener mDrawerListener = new DrawerListener() {
146bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
147bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public void onDrawerSlide(View drawerView, float slideOffset) {
148bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
149bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
150bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
151bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
152bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public void onDrawerOpened(View drawerView) {
153bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            mDrawerToggle.onDrawerOpened(drawerView);
154bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            updateActionBar();
155bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
156bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
157bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
158bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public void onDrawerClosed(View drawerView) {
159bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            mDrawerToggle.onDrawerClosed(drawerView);
160bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            updateActionBar();
161bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
162bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
163bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
164bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public void onDrawerStateChanged(int newState) {
165bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            mDrawerToggle.onDrawerStateChanged(newState);
166bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
167bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    };
168bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
169bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    @Override
170bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    protected void onPostCreate(Bundle savedInstanceState) {
171bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        super.onPostCreate(savedInstanceState);
172bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mDrawerToggle.syncState();
1739e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey    }
1749e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
17554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public void updateActionBar() {
17654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final ActionBar actionBar = getActionBar();
1779e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
178bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        actionBar.setDisplayShowHomeEnabled(true);
179bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        actionBar.setDisplayHomeAsUpEnabled(true);
1809e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
18166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        if (mDrawerLayout.isDrawerOpen(mRootsContainer)) {
18254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
183bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            actionBar.setIcon(new ColorDrawable());
18454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
1851482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey            if (mAction == ACTION_OPEN) {
18654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                actionBar.setTitle(R.string.title_open);
1871482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey            } else if (mAction == ACTION_CREATE) {
18854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                actionBar.setTitle(R.string.title_save);
18954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            }
190bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
191bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        } else {
192dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            final Root root = getCurrentRoot();
193dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            actionBar.setIcon(root != null ? root.icon : null);
194ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
195b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            if (root.isRecents) {
196ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
197ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setTitle(root.title);
198ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            } else {
199ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
200ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setTitle(null);
201ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setListNavigationCallbacks(mSortAdapter, mSortListener);
202ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                actionBar.setSelectedNavigationItem(mDisplayState.sortOrder);
203ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            }
204bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
205dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            if (mStack.size() > 1) {
206bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                mDrawerToggle.setDrawerIndicatorEnabled(false);
207bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            } else {
208bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                mDrawerToggle.setDrawerIndicatorEnabled(true);
209bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
2109e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        }
21154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
2129e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
21354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
21454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public boolean onCreateOptionsMenu(Menu menu) {
21554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        super.onCreateOptionsMenu(menu);
21654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        getMenuInflater().inflate(R.menu.activity, menu);
217bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
218bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        final MenuItem searchMenu = menu.findItem(R.id.menu_search);
219bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mSearchView = (SearchView) searchMenu.getActionView();
220bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
221bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            @Override
222bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            public boolean onQueryTextSubmit(String query) {
223b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                mCurrentSearch = query;
224b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                updateDirectoryFragment();
225bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                mSearchView.setIconified(true);
226bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                return true;
227bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
228bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
229bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            @Override
230bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            public boolean onQueryTextChange(String newText) {
231bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                return false;
232bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
233bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        });
234bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
235b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        mSearchView.setOnCloseListener(new OnCloseListener() {
236b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            @Override
237b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            public boolean onClose() {
238b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                mCurrentSearch = null;
239b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                updateDirectoryFragment();
240b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                return false;
241b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            }
242b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        });
243b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
24454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        return true;
24554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
24654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
24754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
24854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public boolean onPrepareOptionsMenu(Menu menu) {
24954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        super.onPrepareOptionsMenu(menu);
25054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
251dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final Document cwd = getCurrentDirectory();
252dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
25354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
2541482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        createDir.setVisible(mAction == ACTION_CREATE);
255dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        createDir.setEnabled(cwd != null && cwd.isCreateSupported());
25654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
257bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        // TODO: close any search in-progress when hiding
258bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        final MenuItem search = menu.findItem(R.id.menu_search);
259dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        search.setVisible(cwd != null && cwd.isSearchSupported());
260dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
261dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        if (mAction == ACTION_CREATE) {
262dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            final FragmentManager fm = getFragmentManager();
263dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
264dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        }
265bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
266b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        menu.findItem(R.id.menu_grid).setVisible(mDisplayState.mode != DisplayState.MODE_GRID);
267b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        menu.findItem(R.id.menu_list).setVisible(mDisplayState.mode != DisplayState.MODE_LIST);
268b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
26954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        return true;
2709e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey    }
2719e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
27254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
27354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public boolean onOptionsItemSelected(MenuItem item) {
274bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        if (mDrawerToggle.onOptionsItemSelected(item)) {
275bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return true;
276bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
277bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
27854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final int id = item.getItemId();
27954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        if (id == android.R.id.home) {
280dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            onBackPressed();
281bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return true;
28254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        } else if (id == R.id.menu_create_dir) {
28320d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey            CreateDirectoryFragment.show(getFragmentManager());
284bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return true;
285bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        } else if (id == R.id.menu_search) {
286bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return false;
287b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else if (id == R.id.menu_grid) {
288b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            mDisplayState.mode = DisplayState.MODE_GRID;
289b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            updateDisplayState();
290b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            invalidateOptionsMenu();
291b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            return true;
292b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else if (id == R.id.menu_list) {
293b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            mDisplayState.mode = DisplayState.MODE_LIST;
294b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            updateDisplayState();
295b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            invalidateOptionsMenu();
296b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            return true;
297b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else {
298b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            return super.onOptionsItemSelected(item);
29954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
30054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
30154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
302dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    @Override
303dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    public void onBackPressed() {
304dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final int size = mStack.size();
305dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        if (size > 1) {
306dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            mStack.pop();
307dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            updateDirectoryFragment();
30866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        } else if (size == 1 && !mDrawerLayout.isDrawerOpen(mRootsContainer)) {
309dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            // TODO: open root drawer once we can capture back key
310dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            super.onBackPressed();
311dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        } else {
312dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            super.onBackPressed();
31354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
314dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    }
31554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
316bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    // TODO: support additional sort orders
317bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private BaseAdapter mSortAdapter = new BaseAdapter() {
31854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        @Override
31954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public int getCount() {
320bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return 2;
32154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
3229e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
32354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        @Override
32454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public Object getItem(int position) {
325bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            switch (position) {
326bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                case 0:
327bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                    return getText(R.string.sort_name);
328bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                case 1:
329bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                    return getText(R.string.sort_date);
330bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                default:
331bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                    return null;
332bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
33354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
3349e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
33554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        @Override
33654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public long getItemId(int position) {
337bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return position;
3389e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        }
3399e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
3409e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        @Override
34154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public View getView(int position, View convertView, ViewGroup parent) {
34254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            if (convertView == null) {
34354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                convertView = LayoutInflater.from(parent.getContext())
344bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                        .inflate(R.layout.item_title, parent, false);
345bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
346bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
347bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
348bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
349bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
350dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            final Document cwd = getCurrentDirectory();
351dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            if (cwd != null) {
352dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey                title.setText(cwd.displayName);
353bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            } else {
354b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                // No directory means recents
355b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                title.setText(R.string.root_recent);
356bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            }
357bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
358bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            summary.setText((String) getItem(position));
359bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
360bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            return convertView;
361bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        }
362bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey
363bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        @Override
364bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey        public View getDropDownView(int position, View convertView, ViewGroup parent) {
365bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            if (convertView == null) {
366bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey                convertView = LayoutInflater.from(parent.getContext())
36754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                        .inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
3689e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey            }
3699e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
37054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);
371bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey            text1.setText((String) getItem(position));
3729e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
37354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            return convertView;
3749e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        }
37554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    };
3769e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey
377bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey    private OnNavigationListener mSortListener = new OnNavigationListener() {
3789e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey        @Override
37954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public boolean onNavigationItemSelected(int itemPosition, long itemId) {
380ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            mDisplayState.sortOrder = itemPosition;
381b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            updateDisplayState();
38254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            return true;
38354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
38454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    };
38554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
386dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    public Root getCurrentRoot() {
387b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        final Document cwd = getCurrentDirectory();
388b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        if (cwd != null) {
389b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            return RootsCache.findRoot(this, cwd);
390b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else {
391b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            return RootsCache.getRecentsRoot(this);
392b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        }
393dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    }
394dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
395dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    public Document getCurrentDirectory() {
396dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        return mStack.peek();
397dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    }
398dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
3991482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey    public DisplayState getDisplayState() {
4001482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        return mDisplayState;
4011482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey    }
4021482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
403dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    private void updateDirectoryFragment() {
404dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final FragmentManager fm = getFragmentManager();
405dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final Document cwd = getCurrentDirectory();
406b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        if (cwd == null) {
407b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            // No directory means recents
408b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            if (mAction == ACTION_CREATE) {
409b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                RecentsCreateFragment.show(fm);
410b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            } else {
411b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                DirectoryFragment.showRecentsOpen(fm);
412b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            }
413b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else {
414b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            if (mCurrentSearch != null) {
415b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                // Ongoing search
416b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                DirectoryFragment.showSearch(fm, cwd.uri, mCurrentSearch);
417b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            } else {
418b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                // Normal boring directory
419b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey                DirectoryFragment.showNormal(fm, cwd.uri);
420b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            }
42154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
422b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
423dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        updateActionBar();
42454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        invalidateOptionsMenu();
425dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        dumpStack();
42654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
42754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
428b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    private void updateDisplayState() {
429b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        // TODO: handle multiple directory stacks on tablets
430b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        DirectoryFragment.get(getFragmentManager()).updateDisplayState();
431b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    }
432b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
433b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    public void onStackPicked(DocumentStack stack) {
434b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        mStack = stack;
435b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        updateDirectoryFragment();
436b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    }
437b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
43866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public void onRootPicked(Root root, boolean closeDrawer) {
439ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        // Clear entire backstack and start in new root
440ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        mStack.clear();
441b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
442b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        if (!root.isRecents) {
443b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            onDocumentPicked(Document.fromRoot(getContentResolver(), root));
444b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        } else {
445b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            updateDirectoryFragment();
446b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        }
44766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
44866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        if (closeDrawer) {
44966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            mDrawerLayout.closeDrawers();
45066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
451ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
452ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
45354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public void onDocumentPicked(Document doc) {
45454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final FragmentManager fm = getFragmentManager();
455b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        if (doc.isDirectory()) {
456dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            mStack.push(doc);
457dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            updateDirectoryFragment();
4581482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        } else if (mAction == ACTION_OPEN) {
45954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            // Explicit file picked, return
46054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            onFinished(doc.uri);
4611482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        } else if (mAction == ACTION_CREATE) {
46254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            // Overwrite current filename
46354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            SaveFragment.get(fm).setDisplayName(doc.displayName);
46454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
46554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
46654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
467be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey    public void onDocumentsPicked(List<Document> docs) {
468be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        final int size = docs.size();
469be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        final Uri[] uris = new Uri[size];
470be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        for (int i = 0; i < size; i++) {
471be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            uris[i] = docs.get(i).uri;
472be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        }
473be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        onFinished(uris);
474be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey    }
475be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey
47654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public void onSaveRequested(String mimeType, String displayName) {
47792d7e697a864a3e18bef4ef256bb3eb339a66b4eJeff Sharkey        // TODO: handle overwrite by using last-selected GUID
47892d7e697a864a3e18bef4ef256bb3eb339a66b4eJeff Sharkey
47920d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey        final ContentValues values = new ContentValues();
48020d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey        values.put(DocumentColumns.MIME_TYPE, mimeType);
48120d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey        values.put(DocumentColumns.DISPLAY_NAME, displayName);
48220d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey
483dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final Document cwd = getCurrentDirectory();
484dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final Uri childUri = getContentResolver().insert(cwd.uri, values);
485dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        if (childUri != null) {
486dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            onFinished(childUri);
4877e258b31e70464bb6d80b8b42f0cef8e4417bd6aJeff Sharkey        } else {
4887e258b31e70464bb6d80b8b42f0cef8e4417bd6aJeff Sharkey            Toast.makeText(this, R.string.save_error, Toast.LENGTH_SHORT).show();
4897e258b31e70464bb6d80b8b42f0cef8e4417bd6aJeff Sharkey        }
49054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
49154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
492be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey    private void onFinished(Uri... uris) {
493be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        Log.d(TAG, "onFinished() " + Arrays.toString(uris));
49454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
495dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final ContentResolver resolver = getContentResolver();
496dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final ContentValues values = new ContentValues();
497dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
498b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        final String rawStack = DocumentStack.serialize(mStack);
499dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        if (mAction == ACTION_CREATE) {
500dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            // Remember stack for last create
501dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            values.clear();
502b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey            values.put(RecentsProvider.COL_PATH, rawStack);
503dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            resolver.insert(RecentsProvider.buildRecentCreate(), values);
504dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
505dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        } else if (mAction == ACTION_OPEN) {
506dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            // Remember opened items
507dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            for (Uri uri : uris) {
508dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey                values.clear();
509dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey                values.put(RecentsProvider.COL_URI, uri.toString());
510dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey                resolver.insert(RecentsProvider.buildRecentOpen(), values);
511dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            }
512dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        }
513dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
514dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        // Remember location for next app launch
515dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        final String packageName = getCallingPackage();
516dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        values.clear();
517b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        values.put(RecentsProvider.COL_PATH, rawStack);
518dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        resolver.insert(RecentsProvider.buildResume(packageName), values);
519dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey
52054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final Intent intent = new Intent();
521be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        if (uris.length == 1) {
522be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            intent.setData(uris[0]);
523be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        } else if (uris.length > 1) {
524ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            final ClipData clipData = new ClipData(
525ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey                    null, mDisplayState.acceptMimes, new ClipData.Item(uris[0]));
526be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            for (int i = 1; i < uris.length; i++) {
527be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey                clipData.addItem(new ClipData.Item(uris[i]));
528be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            }
529be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey            intent.setClipData(clipData);
530be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey        }
53154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
53220d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey        // TODO: omit WRITE and PERSIST for GET_CONTENT
53320d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
53420d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
53520d96d8aff2193d548977e23ce5158657cac94e0Jeff Sharkey                | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
53654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
53754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        setResult(Activity.RESULT_OK, intent);
53854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        finish();
53954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
54054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
5411482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey    public static class DisplayState {
542ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        public int mode = MODE_LIST;
543ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        public String[] acceptMimes;
544ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        public int sortOrder = SORT_ORDER_NAME;
545ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        public boolean allowMultiple = false;
546b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        public boolean showSize = false;
5471482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
5481482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        public static final int MODE_LIST = 0;
5491482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey        public static final int MODE_GRID = 1;
5501482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
551ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        public static final int SORT_ORDER_NAME = 0;
552ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        public static final int SORT_ORDER_DATE = 1;
5531482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey    }
5541482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey
555dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    private void dumpStack() {
556dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        Log.d(TAG, "Current stack:");
557dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        for (Document doc : mStack) {
558dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey            Log.d(TAG, "--> " + doc);
559dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey        }
560dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey    }
5619e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey}
562