DirectoryFragment.java revision 7aa7601c09ab5d87cc15a0ed9a8f511d494a4cbc
19e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey/* 29e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project 39e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 49e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 59e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * you may not use this file except in compliance with the License. 69e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * You may obtain a copy of the License at 79e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 89e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 99e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 109e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 119e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 129e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * See the License for the specific language governing permissions and 149e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * limitations under the License. 159e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey */ 169e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 179e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeypackage com.android.documentsui; 189e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 199d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport static com.android.documentsui.DocumentsActivity.TAG; 20b180a65d41adc731cbff1536c7ede15174bc08e1Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.ACTION_CREATE; 21b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE; 22b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_GRID; 23b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_LIST; 24d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN; 25d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.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 3054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.app.Fragment; 319e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentManager; 329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentTransaction; 339e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.LoaderManager.LoaderCallbacks; 347aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.content.ContentProviderClient; 354eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.ContentResolver; 36fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkeyimport android.content.ContentValues; 379e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Context; 384eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.Intent; 399e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Loader; 405dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.database.Cursor; 419d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Bitmap; 429d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Point; 434ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.graphics.drawable.Drawable; 441feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkeyimport android.graphics.drawable.InsetDrawable; 459e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.net.Uri; 469d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.os.AsyncTask; 479e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.os.Bundle; 484ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.os.CancellationSignal; 49e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.os.Parcelable; 509e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.provider.DocumentsContract; 515dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.provider.DocumentsContract.Document; 5254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.text.format.DateUtils; 53b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.text.format.Formatter; 549d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.text.format.Time; 559d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.util.Log; 56e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.util.SparseArray; 57be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.util.SparseBooleanArray; 58be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.view.ActionMode; 599e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.LayoutInflater; 6054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.Menu; 6154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.MenuItem; 629e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.View; 639e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.ViewGroup; 64be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView; 65be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView.MultiChoiceModeListener; 664ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.widget.AbsListView.RecyclerListener; 6754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView; 6854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView.OnItemClickListener; 69ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.widget.BaseAdapter; 701feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkeyimport android.widget.FrameLayout; 7154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.GridView; 729e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ImageView; 739e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ListView; 749e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.TextView; 754eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.widget.Toast; 769e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 77b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport com.android.documentsui.DocumentsActivity.State; 78fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkeyimport com.android.documentsui.RecentsProvider.StateColumns; 79ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo; 80251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkeyimport com.android.documentsui.model.RootInfo; 81be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport com.google.android.collect.Lists; 82be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 83be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.ArrayList; 84ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport java.util.List; 85b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport java.util.concurrent.atomic.AtomicInteger; 8654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 8754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey/** 8854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Display the documents inside a single directory. 8954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey */ 9054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeypublic class DirectoryFragment extends Fragment { 9154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 929fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey private View mEmptyView; 9354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private ListView mListView; 9454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private GridView mGridView; 9554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 96be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private AbsListView mCurrentView; 97be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 98ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_NORMAL = 1; 99ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_SEARCH = 2; 100251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey public static final int TYPE_RECENT_OPEN = 3; 101dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 102e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_NONE = 1; 103e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_SIDE = 2; 104e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_DOWN = 3; 105e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_UP = 4; 106e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 107dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey private int mType = TYPE_NORMAL; 108e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private String mStateKey; 109dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 110d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private int mLastMode = MODE_UNKNOWN; 111d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private int mLastSortOrder = SORT_ORDER_UNKNOWN; 112ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey private boolean mLastShowSize = false; 113d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 114f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey private boolean mHideGridTitles = false; 115f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 1169d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private Point mThumbSize; 1179d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 1189e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey private DocumentsAdapter mAdapter; 119b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey private LoaderCallbacks<DirectoryResult> mCallbacks; 1209e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 121b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static final String EXTRA_TYPE = "type"; 122d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final String EXTRA_ROOT = "root"; 123d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final String EXTRA_DOC = "doc"; 124251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static final String EXTRA_QUERY = "query"; 125e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static final String EXTRA_IGNORE_STATE = "ignoreState"; 1269e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 127b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static AtomicInteger sLoaderId = new AtomicInteger(4000); 128b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 129b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private final int mLoaderId = sLoaderId.incrementAndGet(); 130b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 131e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { 132e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_NORMAL, root, doc, null, anim); 133b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 134b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 135e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) { 136e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_SEARCH, root, null, query, anim); 137b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 138b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 139e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showRecentsOpen(FragmentManager fm, int anim) { 140e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_RECENT_OPEN, null, null, null, anim); 141b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 1429e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 143e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc, 144e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey String query, int anim) { 1459e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Bundle args = new Bundle(); 146b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey args.putInt(EXTRA_TYPE, type); 147d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey args.putParcelable(EXTRA_ROOT, root); 148d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey args.putParcelable(EXTRA_DOC, doc); 149251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey args.putString(EXTRA_QUERY, query); 1509e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 151e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 152e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey switch (anim) { 153e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_SIDE: 154e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey args.putBoolean(EXTRA_IGNORE_STATE, true); 155e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 156e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_DOWN: 157e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey args.putBoolean(EXTRA_IGNORE_STATE, true); 158e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen); 159e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 160e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_UP: 161e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up); 162e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 163e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 164e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 1659e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final DirectoryFragment fragment = new DirectoryFragment(); 1669e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey fragment.setArguments(args); 1679e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 16866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.replace(R.id.container_directory, fragment); 1699e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey ft.commitAllowingStateLoss(); 1709e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 1719e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 172e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static String buildStateKey(RootInfo root, DocumentInfo doc) { 173e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final StringBuilder builder = new StringBuilder(); 174e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(root != null ? root.authority : "null").append(';'); 175e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(root != null ? root.rootId : "null").append(';'); 176e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(doc != null ? doc.documentId : "null"); 177e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey return builder.toString(); 178e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 179e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 180ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static DirectoryFragment get(FragmentManager fm) { 181ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey // TODO: deal with multiple directories shown at once 18266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return (DirectoryFragment) fm.findFragmentById(R.id.container_directory); 183ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 184ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 1859e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 1869e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey public View onCreateView( 1879e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 1889e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Context context = inflater.getContext(); 18954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final View view = inflater.inflate(R.layout.fragment_directory, container, false); 19054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1919fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView = view.findViewById(android.R.id.empty); 1929fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 19354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView = (ListView) view.findViewById(R.id.list); 19454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setOnItemClickListener(mItemListener); 195be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setMultiChoiceModeListener(mMultiListener); 1964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mListView.setRecyclerListener(mRecycleListener); 19754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 19854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView = (GridView) view.findViewById(R.id.grid); 19954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setOnItemClickListener(mItemListener); 200be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setMultiChoiceModeListener(mMultiListener); 2014ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mGridView.setRecyclerListener(mRecycleListener); 20254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2035dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return view; 2045dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 20554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2065dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey @Override 2075dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public void onActivityCreated(Bundle savedInstanceState) { 2085dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey super.onActivityCreated(savedInstanceState); 2095dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 2105dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Context context = getActivity(); 211d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 2125dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 213f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); 214f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 215f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 216251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey mAdapter = new DocumentsAdapter(); 217b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mType = getArguments().getInt(EXTRA_TYPE); 218e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey mStateKey = buildStateKey(root, doc); 2199e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 220f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (mType == TYPE_RECENT_OPEN) { 221f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // Hide titles when showing recents for picking images/videos 222f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mHideGridTitles = MimePredicate.mimeMatches( 223f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey MimePredicate.VISUAL_MIMES, state.acceptMimes); 224f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } else { 225f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mHideGridTitles = (doc != null) && doc.isGridTitlesHidden(); 226f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 227f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 228b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey mCallbacks = new LoaderCallbacks<DirectoryResult>() { 2299e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 230b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { 231251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String query = getArguments().getString(EXTRA_QUERY); 232251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey 23354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey Uri contentsUri; 234251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey switch (mType) { 235251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_NORMAL: 236d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey contentsUri = DocumentsContract.buildChildDocumentsUri( 237d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey doc.authority, doc.documentId); 2384ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (state.action == ACTION_MANAGE) { 2394ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey contentsUri = DocumentsContract.setManageMode(contentsUri); 2404ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 241fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return new DirectoryLoader( 2424ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey context, mType, root, doc, contentsUri, state.userSortOrder); 243251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_SEARCH: 244251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey contentsUri = DocumentsContract.buildSearchDocumentsUri( 2453e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey root.authority, root.rootId, query); 2464ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (state.action == ACTION_MANAGE) { 2474ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey contentsUri = DocumentsContract.setManageMode(contentsUri); 2484ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 249fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return new DirectoryLoader( 2504ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey context, mType, root, doc, contentsUri, state.userSortOrder); 251251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_RECENT_OPEN: 252348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 253a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey return new RecentLoader(context, roots, state); 254251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey default: 255251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey throw new IllegalStateException("Unknown type " + mType); 256251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 2579e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2589e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2599e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 260b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { 261d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey if (!isAdded()) return; 262d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 2637aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey mAdapter.swapResult(result.cursor, result.exception); 264d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 265d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // Push latest state up to UI 266d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // TODO: if mode change was racing with us, don't overwrite it 26788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (result.mode != MODE_UNKNOWN) { 26888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey state.derivedMode = result.mode; 26988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 270fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedSortOrder = result.sortOrder; 271d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey ((DocumentsActivity) context).onStateChanged(); 272d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 273d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey updateDisplayState(); 274d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 275e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey // Restore any previous instance state 276e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final SparseArray<Parcelable> container = state.dirState.remove(mStateKey); 277e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey if (container != null && !getArguments().getBoolean(EXTRA_IGNORE_STATE, false)) { 278e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey getView().restoreHierarchyState(container); 279e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } else if (mLastSortOrder != state.derivedSortOrder) { 280d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mListView.smoothScrollToPosition(0); 281d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mGridView.smoothScrollToPosition(0); 282d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 283e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 284e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey mLastSortOrder = state.derivedSortOrder; 2859e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2869e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2879e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 288b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoaderReset(Loader<DirectoryResult> loader) { 2897aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey mAdapter.swapResult(null, null); 2909e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2919e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey }; 2929e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 293d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // Kick off loader at least once 294d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 295d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 296b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey updateDisplayState(); 29754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 2989e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 29928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey @Override 300e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public void onStop() { 301e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey super.onStop(); 302e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 303e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey // Remember last scroll location 304e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final SparseArray<Parcelable> container = new SparseArray<Parcelable>(); 305e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey getView().saveHierarchyState(container); 306e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final State state = getDisplayState(this); 307e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey state.dirState.put(mStateKey, container); 308e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 309e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 310e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey @Override 31188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public void onResume() { 31288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey super.onResume(); 31328c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey updateDisplayState(); 31428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 31528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 316d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onUserSortOrderChanged() { 317fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // Sort order change always triggers reload; we'll trigger state change 318fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // on the flip side. 319d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 320d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 321d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 322d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onUserModeChanged() { 323fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final ContentResolver resolver = getActivity().getContentResolver(); 324fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final State state = getDisplayState(this); 325fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 326fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); 327fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 328fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 3293e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey if (root != null && doc != null) { 33088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final Uri stateUri = RecentsProvider.buildState( 33188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey root.authority, root.rootId, doc.documentId); 33288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final ContentValues values = new ContentValues(); 33388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey values.put(StateColumns.MODE, state.userMode); 33488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 33588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey new AsyncTask<Void, Void, Void>() { 33688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey @Override 33788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey protected Void doInBackground(Void... params) { 33888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey resolver.insert(stateUri, values); 33988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return null; 34088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 34188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey }.execute(); 34288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 343fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 344fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // Mode change is just visual change; no need to kick loader, and 345fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // deliver change event immediately. 346fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedMode = state.userMode; 347fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey ((DocumentsActivity) getActivity()).onStateChanged(); 348fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 349d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey updateDisplayState(); 350d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 351d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 352d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private void updateDisplayState() { 353b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(this); 35454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 355ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey if (mLastMode == state.derivedMode && mLastShowSize == state.showSize) return; 356fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mLastMode = state.derivedMode; 357ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey mLastShowSize = state.showSize; 35854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 359fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mListView.setVisibility(state.derivedMode == MODE_LIST ? View.VISIBLE : View.GONE); 360fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mGridView.setVisibility(state.derivedMode == MODE_GRID ? View.VISIBLE : View.GONE); 36154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 362be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey final int choiceMode; 3631482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey if (state.allowMultiple) { 364be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL; 365be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 366be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_NONE; 367be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 368be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 3699d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final int thumbSize; 370fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_GRID) { 3719d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width); 37254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(null); 373be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(ListView.CHOICE_MODE_NONE); 37454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(mAdapter); 375be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.grid_width)); 37654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setNumColumns(GridView.AUTO_FIT); 377be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(choiceMode); 378be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mGridView; 379fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_LIST) { 380d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size); 38154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(null); 382be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE); 38354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(mAdapter); 384be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(choiceMode); 385be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mListView; 3861482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey } else { 387fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey throw new IllegalStateException("Unknown state " + state.derivedMode); 38854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 3899d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 3909d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mThumbSize = new Point(thumbSize, thumbSize); 39154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 39254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 39354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 39454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 39554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 3965dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 3973f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (cursor != null) { 3982a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 3992a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 4002a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (isDocumentEnabled(docMimeType, docFlags)) { 4012a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 4023f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey ((DocumentsActivity) getActivity()).onDocumentPicked(doc); 4033f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 404a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 40554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 40654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey }; 40754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 408be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private MultiChoiceModeListener mMultiListener = new MultiChoiceModeListener() { 409be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 410be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onCreateActionMode(ActionMode mode, Menu menu) { 411be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.getMenuInflater().inflate(R.menu.mode_directory, menu); 412be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 413be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 414be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 415be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 416be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 417b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 4184eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4194eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem open = menu.findItem(R.id.menu_open); 4204eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem share = menu.findItem(R.id.menu_share); 4214eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem delete = menu.findItem(R.id.menu_delete); 4224eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final boolean manageMode = state.action == ACTION_MANAGE; 4244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey open.setVisible(!manageMode); 4254eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey share.setVisible(manageMode); 4264eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey delete.setVisible(manageMode); 4274eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 428be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 429be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 430be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 431be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 432be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 4334eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final SparseBooleanArray checked = mCurrentView.getCheckedItemPositions(); 434ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final ArrayList<DocumentInfo> docs = Lists.newArrayList(); 4354eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int size = checked.size(); 4364eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey for (int i = 0; i < size; i++) { 4374eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (checked.valueAt(i)) { 4385dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(checked.keyAt(i)); 439251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 4404eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey docs.add(doc); 441be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 4424eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4434eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4444eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int id = item.getItemId(); 4454eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (id == R.id.menu_open) { 4464eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey DocumentsActivity.get(DirectoryFragment.this).onDocumentsPicked(docs); 447b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 4484eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 449be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 4504eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_share) { 4514eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onShareDocuments(docs); 452b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 453be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 4544eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4554eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_delete) { 4564eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onDeleteDocuments(docs); 457b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 4584eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 4594eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 460be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 461be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return false; 462be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 463be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 464be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 465be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 466be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onDestroyActionMode(ActionMode mode) { 467be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey // ignored 468be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 469be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 470be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 471be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onItemCheckedStateChanged( 472be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey ActionMode mode, int position, long id, boolean checked) { 473be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey if (checked) { 4743f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Directories and footer items cannot be checked 4753f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey boolean valid = false; 4763f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4775dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 4783f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (cursor != null) { 4793f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 4802a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 4812a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (!Document.MIME_TYPE_DIR.equals(docMimeType)) { 4822a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey valid = isDocumentEnabled(docMimeType, docFlags); 4832a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 4843f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 4853f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4863f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (!valid) { 487be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView.setItemChecked(position, false); 488be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 489be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 490be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 491be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.setTitle(getResources() 492be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey .getString(R.string.mode_selected_count, mCurrentView.getCheckedItemCount())); 493be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 494be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey }; 495be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 4964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private RecyclerListener mRecycleListener = new RecyclerListener() { 4974ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey @Override 4984ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public void onMovedToScrapHeap(View view) { 4994ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb); 5004ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (iconThumb != null) { 5014ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag(); 5024ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (oldTask != null) { 5034ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey oldTask.reallyCancel(); 5044ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(null); 5054ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5064ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5074ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5084ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey }; 5094ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 510ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onShareDocuments(List<DocumentInfo> docs) { 511b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey Intent intent; 512b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (docs.size() == 1) { 513b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final DocumentInfo doc = docs.get(0); 514b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 515b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = new Intent(Intent.ACTION_SEND); 516b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 517b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 518b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(doc.mimeType); 519d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri); 5204eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 521b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (docs.size() > 1) { 5224eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent = new Intent(Intent.ACTION_SEND_MULTIPLE); 5234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 5244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 525b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 526b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<String> mimeTypes = Lists.newArrayList(); 527b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<Uri> uris = Lists.newArrayList(); 528b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (DocumentInfo doc : docs) { 529b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mimeTypes.add(doc.mimeType); 530d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey uris.add(doc.derivedUri); 531b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 532b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 533b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(findCommonMimeType(mimeTypes)); 5344eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); 535b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 5364eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else { 537b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return; 5384eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5394eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 540b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via)); 5414eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey startActivity(intent); 5424eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5434eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 544ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onDeleteDocuments(List<DocumentInfo> docs) { 5454eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final Context context = getActivity(); 5464eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ContentResolver resolver = context.getContentResolver(); 5474eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 5484eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey boolean hadTrouble = false; 549ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey for (DocumentInfo doc : docs) { 5504eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (!doc.isDeleteSupported()) { 5514eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Log.w(TAG, "Skipping " + doc); 5524eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 5534eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey continue; 5544eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5554eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 5567aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient client = null; 5577aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey try { 5587aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey client = DocumentsApplication.acquireUnstableProviderOrThrow( 5597aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey resolver, doc.derivedUri.getAuthority()); 5607aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey DocumentsContract.deleteDocument(client, doc.derivedUri); 5617aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } catch (Exception e) { 562ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey Log.w(TAG, "Failed to delete " + doc); 5634eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 5647aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } finally { 5657aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient.releaseQuietly(client); 5664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5674eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5684eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 5694eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (hadTrouble) { 5704eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Toast.makeText(context, R.string.toast_failed_delete, Toast.LENGTH_SHORT).show(); 5714eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5724eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5734eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 574b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private static State getDisplayState(Fragment fragment) { 5751482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey return ((DocumentsActivity) fragment.getActivity()).getDisplayState(); 57654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 57754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 5783f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static abstract class Footer { 5793f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private final int mItemViewType; 5803f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 5813f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public Footer(int itemViewType) { 5823f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey mItemViewType = itemViewType; 5833f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 5843f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 5853f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public abstract View getView(View convertView, ViewGroup parent); 5863f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 5873f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public int getItemViewType() { 5883f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return mItemViewType; 5893f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 590954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 591954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 592ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey private class LoadingFooter extends Footer { 5933f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public LoadingFooter() { 5943f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey super(1); 5953f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 5963f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 597954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 598954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 599954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 600ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 601ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey 602954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 603954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 604ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey if (state.derivedMode == MODE_LIST) { 605ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey convertView = inflater.inflate(R.layout.item_loading_list, parent, false); 606ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 607ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey convertView = inflater.inflate(R.layout.item_loading_grid, parent, false); 608ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } else { 609ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey throw new IllegalStateException(); 610ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } 611954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 612ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey 613954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 614954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 615954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 616954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 6173f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private class MessageFooter extends Footer { 618954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final int mIcon; 619954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final String mMessage; 620954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 6213f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public MessageFooter(int itemViewType, int icon, String message) { 6223f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey super(itemViewType); 623954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mIcon = icon; 624954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mMessage = message; 625954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 626954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 627954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 628954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 629954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 630954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 631954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 632954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 633954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 634fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_LIST) { 635954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_list, parent, false); 636fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 637954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_grid, parent, false); 638954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 639954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey throw new IllegalStateException(); 640954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 641954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 642954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 643954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 644954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 645954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey icon.setImageResource(mIcon); 646954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey title.setText(mMessage); 647954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 648954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 649954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 650954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 651ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey private class DocumentsAdapter extends BaseAdapter { 6525dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey private Cursor mCursor; 653954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private int mCursorCount; 654954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 655954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private List<Footer> mFooters = Lists.newArrayList(); 656ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 6577aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey public void swapResult(Cursor cursor, Exception e) { 6585dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor = cursor; 659954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mCursorCount = cursor != null ? cursor.getCount() : 0; 660954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 661954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.clear(); 662954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 663954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Bundle extras = cursor != null ? cursor.getExtras() : null; 664954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras != null) { 665954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String info = extras.getString(DocumentsContract.EXTRA_INFO); 666954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (info != null) { 6671feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey mFooters.add(new MessageFooter(2, R.drawable.ic_dialog_info, info)); 668954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 669954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String error = extras.getString(DocumentsContract.EXTRA_ERROR); 670954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (error != null) { 6713f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey mFooters.add(new MessageFooter(3, R.drawable.ic_dialog_alert, error)); 672954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 673954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) { 674954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.add(new LoadingFooter()); 675954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 676954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 6779fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 6787aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey if (e != null) { 6797aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey mFooters.add(new MessageFooter( 6807aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 3, R.drawable.ic_dialog_alert, getString(R.string.query_error))); 6817aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } 6827aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 6835dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (isEmpty()) { 6849fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.VISIBLE); 6859fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } else { 6869fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.GONE); 6879fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 6889fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 689ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey notifyDataSetChanged(); 6909e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 6919e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 6929e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 693ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 694954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 695954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return getDocumentView(position, convertView, parent); 696954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 697954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey position -= mCursorCount; 6983f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey convertView = mFooters.get(position).getView(convertView, parent); 6993f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Only the view itself is disabled; contents inside shouldn't 7003f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // be dimmed. 7013f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey convertView.setEnabled(false); 7023f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return convertView; 703954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 704954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 705954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 706954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private View getDocumentView(int position, View convertView, ViewGroup parent) { 707ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final Context context = parent.getContext(); 708b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 709ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 710f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 711f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 7124eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 7134eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 7144eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 7154eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 716ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey if (convertView == null) { 717ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 718fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_LIST) { 719ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_list, parent, false); 720fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 721ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_grid, parent, false); 7221feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey 7231feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey // Apply padding to grid items 7241feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey final FrameLayout grid = (FrameLayout) convertView; 7251feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey final int gridPadding = getResources() 7261feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey .getDimensionPixelSize(R.dimen.grid_padding); 727deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 728deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Tricksy hobbitses! We need to fully clear the drawable so 729deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // the view doesn't clobber the new InsetDrawable callback 730deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // when setting back later. 731deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final Drawable fg = grid.getForeground(); 732deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final Drawable bg = grid.getBackground(); 733deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey grid.setForeground(null); 734deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey grid.setBackground(null); 735deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey grid.setForeground(new InsetDrawable(fg, gridPadding)); 736deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey grid.setBackground(new InsetDrawable(bg, gridPadding)); 737ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } else { 738ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey throw new IllegalStateException(); 739ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 740ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 741ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 7425dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = getItem(position); 7435dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 744251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); 745251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docRootId = getCursorString(cursor, RootCursorWrapper.COLUMN_ROOT_ID); 7465dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); 7475dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 7485dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docDisplayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME); 7495dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docLastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED); 7505dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docIcon = getCursorInt(cursor, Document.COLUMN_ICON); 7515dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 7525dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY); 7535dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE); 754ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 755f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final View line1 = convertView.findViewById(R.id.line1); 756f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final View line2 = convertView.findViewById(R.id.line2); 757f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 7584ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime); 7594ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconThumb = (ImageView) convertView.findViewById(R.id.icon_thumb); 760ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 761b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1); 762f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final ImageView icon2 = (ImageView) convertView.findViewById(android.R.id.icon2); 763ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 764b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView date = (TextView) convertView.findViewById(R.id.date); 765b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView size = (TextView) convertView.findViewById(R.id.size); 766ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 7674ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag(); 7689d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (oldTask != null) { 7694ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey oldTask.reallyCancel(); 7704ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(null); 7719d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7729d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7734ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.animate().cancel(); 7744ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.animate().cancel(); 7754ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 7763f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0; 777fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final boolean allowThumbnail = (state.derivedMode == MODE_GRID) 778f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey || MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, docMimeType); 779f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final boolean showThumbnail = supportsThumbnail && allowThumbnail; 7803f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 7814ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey boolean cacheHit = false; 782f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (showThumbnail) { 783251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId); 7845dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Bitmap cachedResult = thumbs.get(uri); 7859d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (cachedResult != null) { 7864ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setImageBitmap(cachedResult); 7874ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey cacheHit = true; 7889d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 7894ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setImageDrawable(null); 7904ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask task = new ThumbnailAsyncTask( 7914ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey uri, iconMime, iconThumb, mThumbSize); 7924ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(task); 7934ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 7949d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 7964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 7974ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // Always throw MIME icon into place, even when a thumbnail is being 7984ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // loaded in background. 7994ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (cacheHit) { 8004ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setAlpha(0f); 8016efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey iconMime.setImageDrawable(null); 8024ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setAlpha(1f); 8039e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } else { 8044ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setAlpha(1f); 8054ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setAlpha(0f); 8066efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey iconThumb.setImageDrawable(null); 8074ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (docIcon != 0) { 8084ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setImageDrawable( 8094ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey IconUtils.loadPackageIcon(context, docAuthority, docIcon)); 8104ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } else { 811563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey iconMime.setImageDrawable(IconUtils.loadMimeIcon( 812563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey context, docMimeType, docAuthority, docId, state.derivedMode)); 8134ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 8149e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 8159e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 816f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey boolean hasLine1 = false; 81728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey boolean hasLine2 = false; 81828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 819f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final boolean hideTitle = (state.derivedMode == MODE_GRID) && mHideGridTitles; 820f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (!hideTitle) { 821f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey title.setText(docDisplayName); 822f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey hasLine1 = true; 823f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 824f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 825f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey Drawable iconDrawable = null; 826251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey if (mType == TYPE_RECENT_OPEN) { 827a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey // We've already had to enumerate roots before any results can 828a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey // be shown, so this will never block. 829a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final RootInfo root = roots.getRootBlocking(docAuthority, docRootId); 830f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey iconDrawable = root.loadIcon(context); 8314ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 83288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (summary != null) { 83388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final boolean alwaysShowSummary = getResources() 83488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey .getBoolean(R.bool.always_show_summary); 83588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (alwaysShowSummary) { 83688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(root.getDirectoryString()); 83788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 83888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 83988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 840a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (iconDrawable != null && roots.isIconUniqueBlocking(root)) { 84188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // No summary needed if icon speaks for itself 84288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.INVISIBLE); 84388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 84488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(root.getDirectoryString()); 84588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 84688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END); 84788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 84888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 84988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 8504ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 8515dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } else { 852f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // Directories showing thumbnails in grid mode get a little icon 853f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // hint to remind user they're a directory. 854f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType) && state.derivedMode == MODE_GRID 855f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey && showThumbnail) { 856f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey iconDrawable = context.getResources().getDrawable(R.drawable.ic_root_folder); 857f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 858f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 85988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (summary != null) { 86088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (docSummary != null) { 86188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(docSummary); 86288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 86388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 86488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 86588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.INVISIBLE); 86688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 867251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 868b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 869b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 870f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon1 != null) icon1.setVisibility(View.GONE); 871f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon2 != null) icon2.setVisibility(View.GONE); 872f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 873f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (iconDrawable != null) { 874f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (hasLine1) { 875f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon1.setVisibility(View.VISIBLE); 876f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon1.setImageDrawable(iconDrawable); 877f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } else { 878f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon2.setVisibility(View.VISIBLE); 879f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon2.setImageDrawable(iconDrawable); 880f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 881f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 882f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 8835dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (docLastModified == -1) { 8849d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey date.setText(null); 8859d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 8865dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey date.setText(formatTime(context, docLastModified)); 88728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 8889d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 889b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 890b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (state.showSize) { 891b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.VISIBLE); 8925dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType) || docSize == -1) { 893b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setText(null); 894b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 8955dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey size.setText(Formatter.formatFileSize(context, docSize)); 89628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 897b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 898b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 899b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.GONE); 90054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 901ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 902f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (line1 != null) { 903f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey line1.setVisibility(hasLine1 ? View.VISIBLE : View.GONE); 904f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 90588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (line2 != null) { 90688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE); 90788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 90828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 9092a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final boolean enabled = isDocumentEnabled(docMimeType, docFlags); 9103f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (enabled) { 9113f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(convertView, true); 9126efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey iconMime.setAlpha(1f); 9136efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey iconThumb.setAlpha(1f); 914f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon1 != null) icon1.setAlpha(1f); 915f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon2 != null) icon2.setAlpha(1f); 9163f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } else { 9173f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(convertView, false); 9186efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey iconMime.setAlpha(0.5f); 9196efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey iconThumb.setAlpha(0.5f); 920f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon1 != null) icon1.setAlpha(0.5f); 921f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon2 != null) icon2.setAlpha(0.5f); 9223f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 9233f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 924ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey return convertView; 92554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 92654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 927ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 928ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public int getCount() { 929954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursorCount + mFooters.size(); 930ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 9319e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 932ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 9335dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public Cursor getItem(int position) { 934954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 9355dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor.moveToPosition(position); 936954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursor; 937954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 938954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return null; 9395dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 940ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 94154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 942ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 943ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public long getItemId(int position) { 9445dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return position; 945ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 946954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 947954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 9483f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public int getViewTypeCount() { 9493f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return 4; 9503f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 9513f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 9523f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey @Override 953954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public int getItemViewType(int position) { 954954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 955954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return 0; 956954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 9573f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey position -= mCursorCount; 9583f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return mFooters.get(position).getItemViewType(); 959954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 960954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 9619e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 9629d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9639d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> { 9644ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final Uri mUri; 9654ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final ImageView mIconMime; 9664ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final ImageView mIconThumb; 9674eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private final Point mThumbSize; 9684ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final CancellationSignal mSignal; 9699d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9704ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public ThumbnailAsyncTask( 9714ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize) { 9724ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mUri = uri; 9734ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconMime = iconMime; 9744ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb = iconThumb; 9754eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mThumbSize = thumbSize; 9764ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mSignal = new CancellationSignal(); 9779d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 9789d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9794ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public void reallyCancel() { 9804ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey cancel(false); 9814ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mSignal.cancel(); 9829d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 9839d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9849d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 9859d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected Bitmap doInBackground(Uri... params) { 9864ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final Context context = mIconThumb.getContext(); 9877aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey final ContentResolver resolver = context.getContentResolver(); 9889d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9897aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient client = null; 9909d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Bitmap result = null; 9919d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey try { 9927aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey client = DocumentsApplication.acquireUnstableProviderOrThrow( 9937aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey resolver, mUri.getAuthority()); 9947aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal); 9959d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (result != null) { 9964eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 9974eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 9984ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey thumbs.put(mUri, result); 9999d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10009d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } catch (Exception e) { 10017aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e); 10027aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } finally { 10037aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient.releaseQuietly(client); 10049d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10059d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return result; 10069d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10079d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10089d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 10099d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected void onPostExecute(Bitmap result) { 10104ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (mIconThumb.getTag() == this && result != null) { 10114ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setTag(null); 10124ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setImageBitmap(result); 10134ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 10146efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey final float targetAlpha = mIconMime.isEnabled() ? 1f : 0.5f; 10156efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mIconMime.setAlpha(targetAlpha); 10164ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconMime.animate().alpha(0f).start(); 10174ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setAlpha(0f); 10186efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mIconThumb.animate().alpha(targetAlpha).start(); 10199d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10209d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10219d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10229d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10239d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static String formatTime(Context context, long when) { 10249d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey // TODO: DateUtils should make this easier 10259d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time then = new Time(); 10269d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey then.set(when); 10279d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time now = new Time(); 10289d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey now.setToNow(); 10299d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10309d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT 10319d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey | DateUtils.FORMAT_ABBREV_ALL; 10329d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10339d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (then.year != now.year) { 10349d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE; 10359d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else if (then.yearDay != now.yearDay) { 10369d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_DATE; 10379d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 10389d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_TIME; 10399d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10409d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10419d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return DateUtils.formatDateTime(context, when, flags); 10429d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 1043b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1044b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private String findCommonMimeType(List<String> mimeTypes) { 1045b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] commonType = mimeTypes.get(0).split("/"); 1046b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (commonType.length != 2) { 1047b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return "*/*"; 1048b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1049b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1050b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (int i = 1; i < mimeTypes.size(); i++) { 1051b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] type = mimeTypes.get(i).split("/"); 1052b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (type.length != 2) continue; 1053b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1054b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[1].equals(type[1])) { 1055b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 1056b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1057b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1058b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[0].equals(type[0])) { 1059b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[0] = "*"; 1060b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 1061b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey break; 1062b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1063b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1064b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1065b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return commonType[0] + "/" + commonType[1]; 1066b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 10673f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 10683f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private void setEnabledRecursive(View v, boolean enabled) { 1069f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (v == null) return; 10703f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (v.isEnabled() == enabled) return; 10713f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey v.setEnabled(enabled); 10723f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 10733f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (v instanceof ViewGroup) { 10743f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final ViewGroup vg = (ViewGroup) v; 10753f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey for (int i = vg.getChildCount() - 1; i >= 0; i--) { 10763f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(vg.getChildAt(i), enabled); 10773f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 10783f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 10793f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 10802a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 10812a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey private boolean isDocumentEnabled(String docMimeType, int docFlags) { 10822a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 10832a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 10842a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey // Directories are always enabled 10852a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType)) { 10862a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey return true; 10872a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 10882a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 10893d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey // Read-only files are disabled when creating 10903d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey if (state.action == ACTION_CREATE && (docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) { 10913d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey return false; 10923d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey } 10933d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey 10942a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey return MimePredicate.mimeMatches(state.acceptMimes, docMimeType); 10952a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 10969e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey} 1097