DirectoryFragment.java revision e934ce6f8430f50d1d22bccd3b341b982f5541ee
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 199d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport static com.android.documentsui.DocumentsActivity.TAG; 20e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKayimport static com.android.documentsui.BaseActivity.State.ACTION_CREATE; 21e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKayimport static com.android.documentsui.BaseActivity.State.ACTION_MANAGE; 22e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKayimport static com.android.documentsui.BaseActivity.State.MODE_GRID; 23e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKayimport static com.android.documentsui.BaseActivity.State.MODE_LIST; 24e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKayimport static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN; 25e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKayimport static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN; 265dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorInt; 275dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorLong; 285dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorString; 299d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 30d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkeyimport android.app.ActivityManager; 3154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.app.Fragment; 329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentManager; 339e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentTransaction; 349e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.LoaderManager.LoaderCallbacks; 357aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.content.ContentProviderClient; 364eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.ContentResolver; 37fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkeyimport android.content.ContentValues; 389e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Context; 394eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.Intent; 409e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Loader; 416963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkeyimport android.content.res.Resources; 425dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.database.Cursor; 439d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Bitmap; 449d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Point; 454ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.graphics.drawable.Drawable; 461feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkeyimport android.graphics.drawable.InsetDrawable; 479e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.net.Uri; 489d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.os.AsyncTask; 499e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.os.Bundle; 504ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.os.CancellationSignal; 5133819318f61224cdda45e5e9a70dc9cdb9f33911Jeff Sharkeyimport android.os.OperationCanceledException; 52e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.os.Parcelable; 539e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.provider.DocumentsContract; 545dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.provider.DocumentsContract.Document; 5554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.text.format.DateUtils; 56b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.text.format.Formatter; 579d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.text.format.Time; 589d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.util.Log; 59e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.util.SparseArray; 60be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.util.SparseBooleanArray; 61be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.view.ActionMode; 629e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.LayoutInflater; 6354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.Menu; 6454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.MenuItem; 659e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.View; 669e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.ViewGroup; 67be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView; 68be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView.MultiChoiceModeListener; 694ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.widget.AbsListView.RecyclerListener; 7054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView; 7154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView.OnItemClickListener; 72ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.widget.BaseAdapter; 7354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.GridView; 749e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ImageView; 759e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ListView; 769e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.TextView; 774eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.widget.Toast; 789e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 79e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKayimport com.android.documentsui.BaseActivity.State; 80b3d42635aafacd80b1e1d257338ea6abb93d22c3Jeff Sharkeyimport com.android.documentsui.ProviderExecutor.Preemptable; 81fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkeyimport com.android.documentsui.RecentsProvider.StateColumns; 82ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo; 83251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkeyimport com.android.documentsui.model.RootInfo; 84be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport com.google.android.collect.Lists; 85be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 86be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.ArrayList; 87ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport java.util.List; 8854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 8954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey/** 9054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Display the documents inside a single directory. 9154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey */ 9254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeypublic class DirectoryFragment extends Fragment { 9354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 949fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey private View mEmptyView; 9554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private ListView mListView; 9654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private GridView mGridView; 9754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 98be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private AbsListView mCurrentView; 99be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 100ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_NORMAL = 1; 101ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_SEARCH = 2; 102251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey public static final int TYPE_RECENT_OPEN = 3; 103dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 104e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_NONE = 1; 105e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_SIDE = 2; 106e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_DOWN = 3; 107e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_UP = 4; 108e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 109dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey private int mType = TYPE_NORMAL; 110e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private String mStateKey; 111dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 112d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private int mLastMode = MODE_UNKNOWN; 113d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private int mLastSortOrder = SORT_ORDER_UNKNOWN; 114ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey private boolean mLastShowSize = false; 115d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 116f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey private boolean mHideGridTitles = false; 117f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 118d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey private boolean mSvelteRecents; 1199d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private Point mThumbSize; 1209d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 1219e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey private DocumentsAdapter mAdapter; 122b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey private LoaderCallbacks<DirectoryResult> mCallbacks; 1239e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 124b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static final String EXTRA_TYPE = "type"; 125d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final String EXTRA_ROOT = "root"; 126d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final String EXTRA_DOC = "doc"; 127251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static final String EXTRA_QUERY = "query"; 128e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static final String EXTRA_IGNORE_STATE = "ignoreState"; 1299e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 130db5ef125007644daa94aeaf1bd8637f4e0095e94Jeff Sharkey private final int mLoaderId = 42; 131b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 132e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { 133e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_NORMAL, root, doc, null, anim); 134b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 135b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 136e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) { 137e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_SEARCH, root, null, query, anim); 138b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 139b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 140e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showRecentsOpen(FragmentManager fm, int anim) { 141e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_RECENT_OPEN, null, null, null, anim); 142b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 1439e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 144e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc, 145e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey String query, int anim) { 1469e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Bundle args = new Bundle(); 147b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey args.putInt(EXTRA_TYPE, type); 148d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey args.putParcelable(EXTRA_ROOT, root); 149d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey args.putParcelable(EXTRA_DOC, doc); 150251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey args.putString(EXTRA_QUERY, query); 1519e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 152e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 153e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey switch (anim) { 154e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_SIDE: 155e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey args.putBoolean(EXTRA_IGNORE_STATE, true); 156e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 157e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_DOWN: 158e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey args.putBoolean(EXTRA_IGNORE_STATE, true); 159e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen); 160e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 161e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_UP: 162e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up); 163e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 164e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 165e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 1669e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final DirectoryFragment fragment = new DirectoryFragment(); 1679e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey fragment.setArguments(args); 1689e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 16966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.replace(R.id.container_directory, fragment); 1709e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey ft.commitAllowingStateLoss(); 1719e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 1729e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 173e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static String buildStateKey(RootInfo root, DocumentInfo doc) { 174e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final StringBuilder builder = new StringBuilder(); 175e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(root != null ? root.authority : "null").append(';'); 176e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(root != null ? root.rootId : "null").append(';'); 177e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(doc != null ? doc.documentId : "null"); 178e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey return builder.toString(); 179e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 180e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 181ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static DirectoryFragment get(FragmentManager fm) { 182ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey // TODO: deal with multiple directories shown at once 18366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return (DirectoryFragment) fm.findFragmentById(R.id.container_directory); 184ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 185ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 1869e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 1879e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey public View onCreateView( 1889e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 1899e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Context context = inflater.getContext(); 1906963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey final Resources res = context.getResources(); 19154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final View view = inflater.inflate(R.layout.fragment_directory, container, false); 19254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1939fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView = view.findViewById(android.R.id.empty); 1949fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 19554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView = (ListView) view.findViewById(R.id.list); 19654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setOnItemClickListener(mItemListener); 197be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setMultiChoiceModeListener(mMultiListener); 1984ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mListView.setRecyclerListener(mRecycleListener); 19954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2006963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey // Indent our list divider to align with text 2016963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey final Drawable divider = mListView.getDivider(); 2026963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey final boolean insetLeft = res.getBoolean(R.bool.list_divider_inset_left); 2036963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey final int insetSize = res.getDimensionPixelSize(R.dimen.list_divider_inset); 2046963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey if (insetLeft) { 2056963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey mListView.setDivider(new InsetDrawable(divider, insetSize, 0, 0, 0)); 2066963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey } else { 2076963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey mListView.setDivider(new InsetDrawable(divider, 0, 0, insetSize, 0)); 2086963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey } 2096963148e226dfadc48c36da7db14ee4587a62f6aJeff Sharkey 21054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView = (GridView) view.findViewById(R.id.grid); 21154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setOnItemClickListener(mItemListener); 212be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setMultiChoiceModeListener(mMultiListener); 2134ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mGridView.setRecyclerListener(mRecycleListener); 21454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2155dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return view; 2165dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 21754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2185dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey @Override 219d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey public void onDestroyView() { 220d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey super.onDestroyView(); 221d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey 222d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey // Cancel any outstanding thumbnail requests 223d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey final ViewGroup target = (mListView.getAdapter() != null) ? mListView : mGridView; 224d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey final int count = target.getChildCount(); 225d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey for (int i = 0; i < count; i++) { 226d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey final View view = target.getChildAt(i); 227d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey mRecycleListener.onMovedToScrapHeap(view); 228d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey } 229ca25db0cb3d6b9686a42c9cb99d90dc095f20cd8Jeff Sharkey 230ca25db0cb3d6b9686a42c9cb99d90dc095f20cd8Jeff Sharkey // Tear down any selection in progress 231ca25db0cb3d6b9686a42c9cb99d90dc095f20cd8Jeff Sharkey mListView.setChoiceMode(AbsListView.CHOICE_MODE_NONE); 232ca25db0cb3d6b9686a42c9cb99d90dc095f20cd8Jeff Sharkey mGridView.setChoiceMode(AbsListView.CHOICE_MODE_NONE); 233d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey } 234d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey 235d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey @Override 2365dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public void onActivityCreated(Bundle savedInstanceState) { 2375dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey super.onActivityCreated(savedInstanceState); 2385dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 2395dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Context context = getActivity(); 240d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 2415dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 242f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); 243f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 244f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 245251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey mAdapter = new DocumentsAdapter(); 246b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mType = getArguments().getInt(EXTRA_TYPE); 247e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey mStateKey = buildStateKey(root, doc); 2489e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 249f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (mType == TYPE_RECENT_OPEN) { 250f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // Hide titles when showing recents for picking images/videos 251f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mHideGridTitles = MimePredicate.mimeMatches( 252f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey MimePredicate.VISUAL_MIMES, state.acceptMimes); 253f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } else { 254f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mHideGridTitles = (doc != null) && doc.isGridTitlesHidden(); 255f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 256f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 257d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey final ActivityManager am = (ActivityManager) context.getSystemService( 258d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey Context.ACTIVITY_SERVICE); 259d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey mSvelteRecents = am.isLowRamDevice() && (mType == TYPE_RECENT_OPEN); 260d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey 261b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey mCallbacks = new LoaderCallbacks<DirectoryResult>() { 2629e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 263b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { 264251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String query = getArguments().getString(EXTRA_QUERY); 265251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey 26654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey Uri contentsUri; 267251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey switch (mType) { 268251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_NORMAL: 269d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey contentsUri = DocumentsContract.buildChildDocumentsUri( 270d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey doc.authority, doc.documentId); 2714ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (state.action == ACTION_MANAGE) { 2724ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey contentsUri = DocumentsContract.setManageMode(contentsUri); 2734ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 274fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return new DirectoryLoader( 2754ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey context, mType, root, doc, contentsUri, state.userSortOrder); 276251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_SEARCH: 277251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey contentsUri = DocumentsContract.buildSearchDocumentsUri( 2783e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey root.authority, root.rootId, query); 2794ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (state.action == ACTION_MANAGE) { 2804ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey contentsUri = DocumentsContract.setManageMode(contentsUri); 2814ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 282fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return new DirectoryLoader( 2834ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey context, mType, root, doc, contentsUri, state.userSortOrder); 284251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_RECENT_OPEN: 285348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 286a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey return new RecentLoader(context, roots, state); 287251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey default: 288251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey throw new IllegalStateException("Unknown type " + mType); 289251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 2909e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2919e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2929e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 293b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { 294d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey if (!isAdded()) return; 295d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 296d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey mAdapter.swapResult(result); 297d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 298d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // Push latest state up to UI 299d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // TODO: if mode change was racing with us, don't overwrite it 30088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (result.mode != MODE_UNKNOWN) { 30188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey state.derivedMode = result.mode; 30288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 303fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedSortOrder = result.sortOrder; 304e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay ((BaseActivity) context).onStateChanged(); 305d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 306d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey updateDisplayState(); 307d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 308a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey // When launched into empty recents, show drawer 309a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey if (mType == TYPE_RECENT_OPEN && mAdapter.isEmpty() && !state.stackTouched) { 310e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay ((BaseActivity) context).setRootsDrawerOpen(true); 311a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey } 312a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey 313e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey // Restore any previous instance state 314e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final SparseArray<Parcelable> container = state.dirState.remove(mStateKey); 315e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey if (container != null && !getArguments().getBoolean(EXTRA_IGNORE_STATE, false)) { 316e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey getView().restoreHierarchyState(container); 317e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } else if (mLastSortOrder != state.derivedSortOrder) { 318d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mListView.smoothScrollToPosition(0); 319d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mGridView.smoothScrollToPosition(0); 320d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 321e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 322e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey mLastSortOrder = state.derivedSortOrder; 3239e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 3249e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 3259e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 326b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoaderReset(Loader<DirectoryResult> loader) { 327d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey mAdapter.swapResult(null); 3289e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 3299e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey }; 3309e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 331d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // Kick off loader at least once 332d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 333d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 334b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey updateDisplayState(); 33554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 3369e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 33728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey @Override 338e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public void onStop() { 339e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey super.onStop(); 340e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 341e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey // Remember last scroll location 342e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final SparseArray<Parcelable> container = new SparseArray<Parcelable>(); 343e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey getView().saveHierarchyState(container); 344e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final State state = getDisplayState(this); 345e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey state.dirState.put(mStateKey, container); 346e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 347e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 348e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey @Override 34988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public void onResume() { 35088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey super.onResume(); 35128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey updateDisplayState(); 35228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 35328c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 354669f8e7c70c595964a1c9ca154ac123da84d99a1Jeff Sharkey public void onDisplayStateChanged() { 355669f8e7c70c595964a1c9ca154ac123da84d99a1Jeff Sharkey updateDisplayState(); 356669f8e7c70c595964a1c9ca154ac123da84d99a1Jeff Sharkey } 357669f8e7c70c595964a1c9ca154ac123da84d99a1Jeff Sharkey 358d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onUserSortOrderChanged() { 359fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // Sort order change always triggers reload; we'll trigger state change 360fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // on the flip side. 361d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 362d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 363d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 364d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onUserModeChanged() { 365fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final ContentResolver resolver = getActivity().getContentResolver(); 366fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final State state = getDisplayState(this); 367fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 368fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); 369fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 370fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 3713e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey if (root != null && doc != null) { 37288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final Uri stateUri = RecentsProvider.buildState( 37388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey root.authority, root.rootId, doc.documentId); 37488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final ContentValues values = new ContentValues(); 37588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey values.put(StateColumns.MODE, state.userMode); 37688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 37788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey new AsyncTask<Void, Void, Void>() { 37888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey @Override 37988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey protected Void doInBackground(Void... params) { 38088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey resolver.insert(stateUri, values); 38188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return null; 38288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 38388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey }.execute(); 38488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 385fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 386fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // Mode change is just visual change; no need to kick loader, and 387fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // deliver change event immediately. 388fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedMode = state.userMode; 389e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay ((BaseActivity) getActivity()).onStateChanged(); 390fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 391d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey updateDisplayState(); 392d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 393d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 394d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private void updateDisplayState() { 395b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(this); 39654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 397ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey if (mLastMode == state.derivedMode && mLastShowSize == state.showSize) return; 398fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mLastMode = state.derivedMode; 399ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey mLastShowSize = state.showSize; 40054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 401fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mListView.setVisibility(state.derivedMode == MODE_LIST ? View.VISIBLE : View.GONE); 402fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mGridView.setVisibility(state.derivedMode == MODE_GRID ? View.VISIBLE : View.GONE); 40354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 404be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey final int choiceMode; 4051482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey if (state.allowMultiple) { 406be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL; 407be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 408be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_NONE; 409be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 410be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 4119d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final int thumbSize; 412fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_GRID) { 4139d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width); 41454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(null); 415be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(ListView.CHOICE_MODE_NONE); 41654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(mAdapter); 417be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.grid_width)); 41854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setNumColumns(GridView.AUTO_FIT); 419be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(choiceMode); 420be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mGridView; 421fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_LIST) { 422d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size); 42354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(null); 424be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE); 42554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(mAdapter); 426be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(choiceMode); 427be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mListView; 4281482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey } else { 429fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey throw new IllegalStateException("Unknown state " + state.derivedMode); 43054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 4319d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 4329d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mThumbSize = new Point(thumbSize, thumbSize); 43354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 43454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 43554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 43654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 43754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 4385dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 4393f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (cursor != null) { 4402a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 4412a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 4422a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (isDocumentEnabled(docMimeType, docFlags)) { 4432a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 444e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay ((BaseActivity) getActivity()).onDocumentPicked(doc); 4453f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 446a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 44754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 44854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey }; 44954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 450be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private MultiChoiceModeListener mMultiListener = new MultiChoiceModeListener() { 451be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 452be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onCreateActionMode(ActionMode mode, Menu menu) { 453be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.getMenuInflater().inflate(R.menu.mode_directory, menu); 45422d3990273a1cb5e61360ac42d1d4e6156d762edStefan Wysocki mode.setTitle(getResources() 45522d3990273a1cb5e61360ac42d1d4e6156d762edStefan Wysocki .getString(R.string.mode_selected_count, mCurrentView.getCheckedItemCount())); 456be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 457be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 458be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 459be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 460be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 461b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 4624eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4634eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem open = menu.findItem(R.id.menu_open); 4644eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem share = menu.findItem(R.id.menu_share); 4654eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem delete = menu.findItem(R.id.menu_delete); 4664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4674eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final boolean manageMode = state.action == ACTION_MANAGE; 4684eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey open.setVisible(!manageMode); 4694eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey share.setVisible(manageMode); 4704eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey delete.setVisible(manageMode); 4714eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 472be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 473be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 474be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 475be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 476be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 4774eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final SparseBooleanArray checked = mCurrentView.getCheckedItemPositions(); 478ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final ArrayList<DocumentInfo> docs = Lists.newArrayList(); 4794eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int size = checked.size(); 4804eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey for (int i = 0; i < size; i++) { 4814eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (checked.valueAt(i)) { 4825dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(checked.keyAt(i)); 483251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 4844eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey docs.add(doc); 485be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 4864eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4874eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4884eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int id = item.getItemId(); 4894eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (id == R.id.menu_open) { 490e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay BaseActivity.get(DirectoryFragment.this).onDocumentsPicked(docs); 491b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 4924eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 493be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 4944eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_share) { 4954eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onShareDocuments(docs); 496b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 497be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 4984eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4994eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_delete) { 5004eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onDeleteDocuments(docs); 501b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 5024eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 5034eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 504be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 505be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return false; 506be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 507be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 508be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 509be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 510be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onDestroyActionMode(ActionMode mode) { 511be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey // ignored 512be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 513be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 514be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 515be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onItemCheckedStateChanged( 516be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey ActionMode mode, int position, long id, boolean checked) { 517be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey if (checked) { 5183f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Directories and footer items cannot be checked 5193f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey boolean valid = false; 5203f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 5215dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 5223f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (cursor != null) { 5233f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 5242a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 5252a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (!Document.MIME_TYPE_DIR.equals(docMimeType)) { 5262a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey valid = isDocumentEnabled(docMimeType, docFlags); 5272a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 5283f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 5293f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 5303f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (!valid) { 531be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView.setItemChecked(position, false); 532be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 533be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 534be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 535be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.setTitle(getResources() 536be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey .getString(R.string.mode_selected_count, mCurrentView.getCheckedItemCount())); 537be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 538be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey }; 539be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 5404ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private RecyclerListener mRecycleListener = new RecyclerListener() { 5414ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey @Override 5424ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public void onMovedToScrapHeap(View view) { 5434ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb); 5444ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (iconThumb != null) { 5454ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag(); 5464ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (oldTask != null) { 547b3d42635aafacd80b1e1d257338ea6abb93d22c3Jeff Sharkey oldTask.preempt(); 5484ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(null); 5494ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5504ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5514ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5524ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey }; 5534ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 554ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onShareDocuments(List<DocumentInfo> docs) { 555b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey Intent intent; 556b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (docs.size() == 1) { 557b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final DocumentInfo doc = docs.get(0); 558b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 559b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = new Intent(Intent.ACTION_SEND); 560b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 561b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 562b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(doc.mimeType); 563d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri); 5644eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 565b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (docs.size() > 1) { 5664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent = new Intent(Intent.ACTION_SEND_MULTIPLE); 5674eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 5684eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 569b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 570b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<String> mimeTypes = Lists.newArrayList(); 571b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<Uri> uris = Lists.newArrayList(); 572b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (DocumentInfo doc : docs) { 573b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mimeTypes.add(doc.mimeType); 574d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey uris.add(doc.derivedUri); 575b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 576b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 577b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(findCommonMimeType(mimeTypes)); 5784eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); 579b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 5804eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else { 581b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return; 5824eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5834eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 584b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via)); 5854eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey startActivity(intent); 5864eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5874eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 588ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onDeleteDocuments(List<DocumentInfo> docs) { 5894eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final Context context = getActivity(); 5904eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ContentResolver resolver = context.getContentResolver(); 5914eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 5924eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey boolean hadTrouble = false; 593ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey for (DocumentInfo doc : docs) { 5944eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (!doc.isDeleteSupported()) { 5954eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Log.w(TAG, "Skipping " + doc); 5964eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 5974eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey continue; 5984eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5994eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 6007aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient client = null; 6017aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey try { 6027aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey client = DocumentsApplication.acquireUnstableProviderOrThrow( 6037aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey resolver, doc.derivedUri.getAuthority()); 6047aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey DocumentsContract.deleteDocument(client, doc.derivedUri); 6057aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } catch (Exception e) { 606ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey Log.w(TAG, "Failed to delete " + doc); 6074eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 6087aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } finally { 6097aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient.releaseQuietly(client); 6104eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 6114eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 6124eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 6134eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (hadTrouble) { 6144eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Toast.makeText(context, R.string.toast_failed_delete, Toast.LENGTH_SHORT).show(); 6154eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 6164eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 6174eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 618b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private static State getDisplayState(Fragment fragment) { 619e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay return ((BaseActivity) fragment.getActivity()).getDisplayState(); 62054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 62154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 6223f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static abstract class Footer { 6233f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private final int mItemViewType; 6243f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 6253f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public Footer(int itemViewType) { 6263f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey mItemViewType = itemViewType; 6273f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 6283f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 6293f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public abstract View getView(View convertView, ViewGroup parent); 6303f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 6313f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public int getItemViewType() { 6323f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return mItemViewType; 6333f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 634954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 635954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 636ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey private class LoadingFooter extends Footer { 6373f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public LoadingFooter() { 6383f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey super(1); 6393f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 6403f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 641954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 642954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 643954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 644ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 645ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey 646954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 647954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 648ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey if (state.derivedMode == MODE_LIST) { 649ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey convertView = inflater.inflate(R.layout.item_loading_list, parent, false); 650ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 651ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey convertView = inflater.inflate(R.layout.item_loading_grid, parent, false); 652ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } else { 653ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey throw new IllegalStateException(); 654ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } 655954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 656ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey 657954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 658954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 659954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 660954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 6613f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private class MessageFooter extends Footer { 662954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final int mIcon; 663954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final String mMessage; 664954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 6653f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public MessageFooter(int itemViewType, int icon, String message) { 6663f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey super(itemViewType); 667954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mIcon = icon; 668954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mMessage = message; 669954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 670954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 671954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 672954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 673954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 674954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 675954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 676954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 677954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 678fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_LIST) { 679954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_list, parent, false); 680fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 681954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_grid, parent, false); 682954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 683954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey throw new IllegalStateException(); 684954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 685954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 686954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 687954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 688954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 689954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey icon.setImageResource(mIcon); 690954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey title.setText(mMessage); 691954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 692954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 693954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 694954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 695ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey private class DocumentsAdapter extends BaseAdapter { 6965dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey private Cursor mCursor; 697954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private int mCursorCount; 698954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 699954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private List<Footer> mFooters = Lists.newArrayList(); 700ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 701d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey public void swapResult(DirectoryResult result) { 702d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey mCursor = result != null ? result.cursor : null; 703d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey mCursorCount = mCursor != null ? mCursor.getCount() : 0; 704954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 705954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.clear(); 706954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 707d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey final Bundle extras = mCursor != null ? mCursor.getExtras() : null; 708954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras != null) { 709954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String info = extras.getString(DocumentsContract.EXTRA_INFO); 710954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (info != null) { 711c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey mFooters.add(new MessageFooter(2, R.drawable.ic_dialog_info, info)); 712954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 713954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String error = extras.getString(DocumentsContract.EXTRA_ERROR); 714954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (error != null) { 715c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey mFooters.add(new MessageFooter(3, R.drawable.ic_dialog_alert, error)); 716954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 717954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) { 718954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.add(new LoadingFooter()); 719954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 720954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 7219fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 722d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey if (result != null && result.exception != null) { 7237aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey mFooters.add(new MessageFooter( 724c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey 3, R.drawable.ic_dialog_alert, getString(R.string.query_error))); 7257aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } 7267aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 7275dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (isEmpty()) { 7289fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.VISIBLE); 7299fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } else { 7309fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.GONE); 7319fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 7329fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 733ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey notifyDataSetChanged(); 7349e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 7359e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 7369e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 737ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 738954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 739954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return getDocumentView(position, convertView, parent); 740954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 741954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey position -= mCursorCount; 7423f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey convertView = mFooters.get(position).getView(convertView, parent); 7433f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Only the view itself is disabled; contents inside shouldn't 7443f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // be dimmed. 7453f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey convertView.setEnabled(false); 7463f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return convertView; 747954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 748954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 749954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 750954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private View getDocumentView(int position, View convertView, ViewGroup parent) { 751ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final Context context = parent.getContext(); 752b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 753ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 754f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 755f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 7564eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 7574eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 7584eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 7594eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 760ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey if (convertView == null) { 761ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 762fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_LIST) { 763ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_list, parent, false); 764fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 765ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_grid, parent, false); 766ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } else { 767ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey throw new IllegalStateException(); 768ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 769ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 770ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 7715dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = getItem(position); 7725dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 773251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); 774251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docRootId = getCursorString(cursor, RootCursorWrapper.COLUMN_ROOT_ID); 7755dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); 7765dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 7775dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docDisplayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME); 7785dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docLastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED); 7795dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docIcon = getCursorInt(cursor, Document.COLUMN_ICON); 7805dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 7815dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY); 7825dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE); 783ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 784f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final View line1 = convertView.findViewById(R.id.line1); 785f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final View line2 = convertView.findViewById(R.id.line2); 786f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 7874ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime); 7884ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconThumb = (ImageView) convertView.findViewById(R.id.icon_thumb); 789ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 790b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1); 791f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final ImageView icon2 = (ImageView) convertView.findViewById(android.R.id.icon2); 792ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 793b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView date = (TextView) convertView.findViewById(R.id.date); 794b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView size = (TextView) convertView.findViewById(R.id.size); 795ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 7964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag(); 7979d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (oldTask != null) { 798b3d42635aafacd80b1e1d257338ea6abb93d22c3Jeff Sharkey oldTask.preempt(); 7994ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(null); 8009d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 8019d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 8024ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.animate().cancel(); 8034ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.animate().cancel(); 8044ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 8053f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0; 806fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final boolean allowThumbnail = (state.derivedMode == MODE_GRID) 807f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey || MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, docMimeType); 808d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey final boolean showThumbnail = supportsThumbnail && allowThumbnail && !mSvelteRecents; 8093f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 810cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey final boolean enabled = isDocumentEnabled(docMimeType, docFlags); 811cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey final float iconAlpha = (state.derivedMode == MODE_LIST && !enabled) ? 0.5f : 1f; 812cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey 8134ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey boolean cacheHit = false; 814f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (showThumbnail) { 815251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId); 8165dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Bitmap cachedResult = thumbs.get(uri); 8179d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (cachedResult != null) { 8184ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setImageBitmap(cachedResult); 8194ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey cacheHit = true; 8209d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 8214ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setImageDrawable(null); 8224ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask task = new ThumbnailAsyncTask( 823cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey uri, iconMime, iconThumb, mThumbSize, iconAlpha); 8244ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(task); 825b3d42635aafacd80b1e1d257338ea6abb93d22c3Jeff Sharkey ProviderExecutor.forAuthority(docAuthority).execute(task); 8269d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 8274ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 8284ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 8294ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // Always throw MIME icon into place, even when a thumbnail is being 8304ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // loaded in background. 8314ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (cacheHit) { 8324ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setAlpha(0f); 8336efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey iconMime.setImageDrawable(null); 8344ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setAlpha(1f); 8359e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } else { 8364ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setAlpha(1f); 8374ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setAlpha(0f); 8386efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey iconThumb.setImageDrawable(null); 8394ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (docIcon != 0) { 8404ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setImageDrawable( 8414ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey IconUtils.loadPackageIcon(context, docAuthority, docIcon)); 8424ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } else { 843563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey iconMime.setImageDrawable(IconUtils.loadMimeIcon( 844563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey context, docMimeType, docAuthority, docId, state.derivedMode)); 8454ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 8469e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 8479e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 848f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey boolean hasLine1 = false; 84928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey boolean hasLine2 = false; 85028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 851f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final boolean hideTitle = (state.derivedMode == MODE_GRID) && mHideGridTitles; 852f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (!hideTitle) { 853f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey title.setText(docDisplayName); 854f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey hasLine1 = true; 855f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 856f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 857f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey Drawable iconDrawable = null; 858251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey if (mType == TYPE_RECENT_OPEN) { 859a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey // We've already had to enumerate roots before any results can 860a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey // be shown, so this will never block. 861a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final RootInfo root = roots.getRootBlocking(docAuthority, docRootId); 862a847d79310320ae8adbedb281123a0f879c2fc6eJeff Sharkey if (state.derivedMode == MODE_GRID) { 863c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey iconDrawable = root.loadGridIcon(context); 864a847d79310320ae8adbedb281123a0f879c2fc6eJeff Sharkey } else { 865a847d79310320ae8adbedb281123a0f879c2fc6eJeff Sharkey iconDrawable = root.loadIcon(context); 866a847d79310320ae8adbedb281123a0f879c2fc6eJeff Sharkey } 8674ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 86888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (summary != null) { 86988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final boolean alwaysShowSummary = getResources() 87088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey .getBoolean(R.bool.always_show_summary); 87188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (alwaysShowSummary) { 87288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(root.getDirectoryString()); 87388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 87488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 87588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 876a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (iconDrawable != null && roots.isIconUniqueBlocking(root)) { 87788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // No summary needed if icon speaks for itself 87888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.INVISIBLE); 87988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 88088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(root.getDirectoryString()); 88188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 88288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END); 88388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 88488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 88588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 8864ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 8875dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } else { 888f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // Directories showing thumbnails in grid mode get a little icon 889f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // hint to remind user they're a directory. 890f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType) && state.derivedMode == MODE_GRID 891f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey && showThumbnail) { 892cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey iconDrawable = IconUtils.applyTintAttr(context, R.drawable.ic_doc_folder, 893c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey android.R.attr.textColorPrimaryInverse); 894f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 895f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 89688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (summary != null) { 89788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (docSummary != null) { 89888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(docSummary); 89988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 90088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 90188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 90288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.INVISIBLE); 90388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 904251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 905b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 906b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 907f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon1 != null) icon1.setVisibility(View.GONE); 908f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon2 != null) icon2.setVisibility(View.GONE); 909f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 910f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (iconDrawable != null) { 911f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (hasLine1) { 912f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon1.setVisibility(View.VISIBLE); 913f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon1.setImageDrawable(iconDrawable); 914f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } else { 915f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon2.setVisibility(View.VISIBLE); 916f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon2.setImageDrawable(iconDrawable); 917f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 918f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 919f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 9205dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (docLastModified == -1) { 9219d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey date.setText(null); 9229d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 9235dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey date.setText(formatTime(context, docLastModified)); 92428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 9259d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 926b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 927b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (state.showSize) { 928b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.VISIBLE); 9295dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType) || docSize == -1) { 930b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setText(null); 931b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 9325dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey size.setText(Formatter.formatFileSize(context, docSize)); 93328c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 934b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 935b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 936b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.GONE); 93754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 938ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 939f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (line1 != null) { 940f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey line1.setVisibility(hasLine1 ? View.VISIBLE : View.GONE); 941f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 94288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (line2 != null) { 94388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE); 94488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 94528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 946cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey setEnabledRecursive(convertView, enabled); 947cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey 948cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey iconMime.setAlpha(iconAlpha); 949cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey iconThumb.setAlpha(iconAlpha); 950cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey if (icon1 != null) icon1.setAlpha(iconAlpha); 951cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey if (icon2 != null) icon2.setAlpha(iconAlpha); 9523f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 953ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey return convertView; 95454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 95554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 956ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 957ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public int getCount() { 958954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursorCount + mFooters.size(); 959ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 9609e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 961ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 9625dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public Cursor getItem(int position) { 963954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 9645dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor.moveToPosition(position); 965954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursor; 966954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 967954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return null; 9685dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 969ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 97054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 971ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 972ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public long getItemId(int position) { 9735dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return position; 974ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 975954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 976954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 9773f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public int getViewTypeCount() { 9783f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return 4; 9793f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 9803f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 9813f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey @Override 982954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public int getItemViewType(int position) { 983954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 984954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return 0; 985954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 9863f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey position -= mCursorCount; 9873f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return mFooters.get(position).getItemViewType(); 988954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 989954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 9909e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 9919d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 992b3d42635aafacd80b1e1d257338ea6abb93d22c3Jeff Sharkey private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> 993b3d42635aafacd80b1e1d257338ea6abb93d22c3Jeff Sharkey implements Preemptable { 9944ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final Uri mUri; 9954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final ImageView mIconMime; 9964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final ImageView mIconThumb; 9974eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private final Point mThumbSize; 998cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey private final float mTargetAlpha; 9994ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final CancellationSignal mSignal; 10009d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 1001cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey public ThumbnailAsyncTask(Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize, 1002cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey float targetAlpha) { 10034ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mUri = uri; 10044ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconMime = iconMime; 10054ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb = iconThumb; 10064eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mThumbSize = thumbSize; 1007cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey mTargetAlpha = targetAlpha; 10084ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mSignal = new CancellationSignal(); 10099d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10109d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 1011b3d42635aafacd80b1e1d257338ea6abb93d22c3Jeff Sharkey @Override 1012b3d42635aafacd80b1e1d257338ea6abb93d22c3Jeff Sharkey public void preempt() { 10134ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey cancel(false); 10144ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mSignal.cancel(); 10159d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10169d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10179d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 10189d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected Bitmap doInBackground(Uri... params) { 1019d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey if (isCancelled()) return null; 1020d01571e6d4e1c403534e19142720530d324eac9bJeff Sharkey 10214ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final Context context = mIconThumb.getContext(); 10227aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey final ContentResolver resolver = context.getContentResolver(); 10239d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10247aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient client = null; 10259d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Bitmap result = null; 10269d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey try { 10277aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey client = DocumentsApplication.acquireUnstableProviderOrThrow( 10287aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey resolver, mUri.getAuthority()); 10297aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal); 10309d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (result != null) { 10314eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 10324eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 10334ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey thumbs.put(mUri, result); 10349d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10359d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } catch (Exception e) { 103633819318f61224cdda45e5e9a70dc9cdb9f33911Jeff Sharkey if (!(e instanceof OperationCanceledException)) { 103733819318f61224cdda45e5e9a70dc9cdb9f33911Jeff Sharkey Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e); 103833819318f61224cdda45e5e9a70dc9cdb9f33911Jeff Sharkey } 10397aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } finally { 10407aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient.releaseQuietly(client); 10419d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10429d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return result; 10439d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10449d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10459d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 10469d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected void onPostExecute(Bitmap result) { 10474ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (mIconThumb.getTag() == this && result != null) { 10484ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setTag(null); 10494ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setImageBitmap(result); 10504ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 1051cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey mIconMime.setAlpha(mTargetAlpha); 10524ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconMime.animate().alpha(0f).start(); 10534ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setAlpha(0f); 1054cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey mIconThumb.animate().alpha(mTargetAlpha).start(); 10559d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10569d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10579d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10589d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10599d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static String formatTime(Context context, long when) { 10609d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey // TODO: DateUtils should make this easier 10619d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time then = new Time(); 10629d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey then.set(when); 10639d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time now = new Time(); 10649d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey now.setToNow(); 10659d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10669d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT 10679d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey | DateUtils.FORMAT_ABBREV_ALL; 10689d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10699d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (then.year != now.year) { 10709d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE; 10719d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else if (then.yearDay != now.yearDay) { 10729d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_DATE; 10739d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 10749d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_TIME; 10759d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10769d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10779d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return DateUtils.formatDateTime(context, when, flags); 10789d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 1079b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1080b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private String findCommonMimeType(List<String> mimeTypes) { 1081b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] commonType = mimeTypes.get(0).split("/"); 1082b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (commonType.length != 2) { 1083b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return "*/*"; 1084b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1085b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1086b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (int i = 1; i < mimeTypes.size(); i++) { 1087b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] type = mimeTypes.get(i).split("/"); 1088b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (type.length != 2) continue; 1089b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1090b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[1].equals(type[1])) { 1091b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 1092b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1093b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1094b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[0].equals(type[0])) { 1095b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[0] = "*"; 1096b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 1097b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey break; 1098b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1099b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1100b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1101b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return commonType[0] + "/" + commonType[1]; 1102b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 11033f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 11043f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private void setEnabledRecursive(View v, boolean enabled) { 1105f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (v == null) return; 11063f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (v.isEnabled() == enabled) return; 11073f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey v.setEnabled(enabled); 11083f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 11093f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (v instanceof ViewGroup) { 11103f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final ViewGroup vg = (ViewGroup) v; 11113f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey for (int i = vg.getChildCount() - 1; i >= 0; i--) { 11123f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(vg.getChildAt(i), enabled); 11133f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 11143f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 11153f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 11162a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 11172a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey private boolean isDocumentEnabled(String docMimeType, int docFlags) { 11182a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 11192a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 11202a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey // Directories are always enabled 11212a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType)) { 11222a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey return true; 11232a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 11242a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 11253d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey // Read-only files are disabled when creating 11263d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey if (state.action == ACTION_CREATE && (docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) { 11273d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey return false; 11283d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey } 11293d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey 11302a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey return MimePredicate.mimeMatches(state.acceptMimes, docMimeType); 11312a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 11329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey} 1133