DirectoryFragment.java revision 3d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7
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; 344eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.ContentResolver; 35fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkeyimport android.content.ContentValues; 369e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Context; 374eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.Intent; 389e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Loader; 395dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.database.Cursor; 409d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Bitmap; 419d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Point; 424ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.graphics.drawable.Drawable; 431feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkeyimport android.graphics.drawable.InsetDrawable; 449e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.net.Uri; 459d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.os.AsyncTask; 469e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.os.Bundle; 474ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.os.CancellationSignal; 48e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.os.Parcelable; 499e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.provider.DocumentsContract; 505dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.provider.DocumentsContract.Document; 5154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.text.format.DateUtils; 52b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.text.format.Formatter; 539d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.text.format.Time; 549d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.util.Log; 55e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkeyimport android.util.SparseArray; 56be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.util.SparseBooleanArray; 57be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.view.ActionMode; 589e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.LayoutInflater; 5954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.Menu; 6054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.MenuItem; 619e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.View; 629e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.ViewGroup; 63be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView; 64be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView.MultiChoiceModeListener; 654ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.widget.AbsListView.RecyclerListener; 6654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView; 6754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView.OnItemClickListener; 68ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.widget.BaseAdapter; 691feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkeyimport android.widget.FrameLayout; 7054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.GridView; 719e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ImageView; 729e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ListView; 739e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.TextView; 744eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.widget.Toast; 759e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 76b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport com.android.documentsui.DocumentsActivity.State; 77fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkeyimport com.android.documentsui.RecentsProvider.StateColumns; 78ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo; 79251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkeyimport com.android.documentsui.model.RootInfo; 80be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport com.google.android.collect.Lists; 81be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 82be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.ArrayList; 83ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport java.util.List; 84b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport java.util.concurrent.atomic.AtomicInteger; 8554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 8654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey/** 8754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Display the documents inside a single directory. 8854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey */ 8954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeypublic class DirectoryFragment extends Fragment { 9054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 919fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey private View mEmptyView; 9254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private ListView mListView; 9354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private GridView mGridView; 9454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 95be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private AbsListView mCurrentView; 96be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 97ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_NORMAL = 1; 98ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_SEARCH = 2; 99251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey public static final int TYPE_RECENT_OPEN = 3; 100dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 101e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_NONE = 1; 102e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_SIDE = 2; 103e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_DOWN = 3; 104e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static final int ANIM_UP = 4; 105e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 106dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey private int mType = TYPE_NORMAL; 107e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private String mStateKey; 108dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 109d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private int mLastMode = MODE_UNKNOWN; 110d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private int mLastSortOrder = SORT_ORDER_UNKNOWN; 111ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey private boolean mLastShowSize = false; 112d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 113f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey private boolean mHideGridTitles = false; 114f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 1159d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private Point mThumbSize; 1169d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 1179e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey private DocumentsAdapter mAdapter; 118b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey private LoaderCallbacks<DirectoryResult> mCallbacks; 1199e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 120b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static final String EXTRA_TYPE = "type"; 121d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final String EXTRA_ROOT = "root"; 122d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final String EXTRA_DOC = "doc"; 123251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static final String EXTRA_QUERY = "query"; 124e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static final String EXTRA_IGNORE_STATE = "ignoreState"; 1259e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 126b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static AtomicInteger sLoaderId = new AtomicInteger(4000); 127b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 128b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private final int mLoaderId = sLoaderId.incrementAndGet(); 129b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 130e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { 131e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_NORMAL, root, doc, null, anim); 132b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 133b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 134e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) { 135e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_SEARCH, root, null, query, anim); 136b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 137b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 138e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public static void showRecentsOpen(FragmentManager fm, int anim) { 139e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey show(fm, TYPE_RECENT_OPEN, null, null, null, anim); 140b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 1419e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 142e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc, 143e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey String query, int anim) { 1449e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Bundle args = new Bundle(); 145b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey args.putInt(EXTRA_TYPE, type); 146d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey args.putParcelable(EXTRA_ROOT, root); 147d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey args.putParcelable(EXTRA_DOC, doc); 148251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey args.putString(EXTRA_QUERY, query); 1499e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 150e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 151e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey switch (anim) { 152e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_SIDE: 153e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey args.putBoolean(EXTRA_IGNORE_STATE, true); 154e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 155e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_DOWN: 156e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey args.putBoolean(EXTRA_IGNORE_STATE, true); 157e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen); 158e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 159e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey case ANIM_UP: 160e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up); 161e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey break; 162e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 163e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 1649e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final DirectoryFragment fragment = new DirectoryFragment(); 1659e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey fragment.setArguments(args); 1669e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 16766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.replace(R.id.container_directory, fragment); 1689e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey ft.commitAllowingStateLoss(); 1699e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 1709e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 171e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey private static String buildStateKey(RootInfo root, DocumentInfo doc) { 172e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final StringBuilder builder = new StringBuilder(); 173e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(root != null ? root.authority : "null").append(';'); 174e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(root != null ? root.rootId : "null").append(';'); 175e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey builder.append(doc != null ? doc.documentId : "null"); 176e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey return builder.toString(); 177e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 178e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 179ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static DirectoryFragment get(FragmentManager fm) { 180ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey // TODO: deal with multiple directories shown at once 18166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return (DirectoryFragment) fm.findFragmentById(R.id.container_directory); 182ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 183ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 1849e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 1859e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey public View onCreateView( 1869e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 1879e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Context context = inflater.getContext(); 18854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final View view = inflater.inflate(R.layout.fragment_directory, container, false); 18954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1909fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView = view.findViewById(android.R.id.empty); 1919fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 19254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView = (ListView) view.findViewById(R.id.list); 19354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setOnItemClickListener(mItemListener); 194be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setMultiChoiceModeListener(mMultiListener); 1954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mListView.setRecyclerListener(mRecycleListener); 19654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 19754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView = (GridView) view.findViewById(R.id.grid); 19854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setOnItemClickListener(mItemListener); 199be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setMultiChoiceModeListener(mMultiListener); 2004ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mGridView.setRecyclerListener(mRecycleListener); 20154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2025dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return view; 2035dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 20454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2055dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey @Override 2065dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public void onActivityCreated(Bundle savedInstanceState) { 2075dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey super.onActivityCreated(savedInstanceState); 2085dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 2095dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Context context = getActivity(); 210d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 2115dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 212f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); 213f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 214f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 215251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey mAdapter = new DocumentsAdapter(); 216b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mType = getArguments().getInt(EXTRA_TYPE); 217e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey mStateKey = buildStateKey(root, doc); 2189e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 219f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (mType == TYPE_RECENT_OPEN) { 220f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // Hide titles when showing recents for picking images/videos 221f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mHideGridTitles = MimePredicate.mimeMatches( 222f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey MimePredicate.VISUAL_MIMES, state.acceptMimes); 223f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } else { 224f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mHideGridTitles = (doc != null) && doc.isGridTitlesHidden(); 225f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 226f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 227b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey mCallbacks = new LoaderCallbacks<DirectoryResult>() { 2289e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 229b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { 230251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String query = getArguments().getString(EXTRA_QUERY); 231251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey 23254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey Uri contentsUri; 233251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey switch (mType) { 234251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_NORMAL: 235d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey contentsUri = DocumentsContract.buildChildDocumentsUri( 236d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey doc.authority, doc.documentId); 2374ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (state.action == ACTION_MANAGE) { 2384ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey contentsUri = DocumentsContract.setManageMode(contentsUri); 2394ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 240fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return new DirectoryLoader( 2414ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey context, mType, root, doc, contentsUri, state.userSortOrder); 242251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_SEARCH: 243251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey contentsUri = DocumentsContract.buildSearchDocumentsUri( 2443e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey root.authority, root.rootId, query); 2454ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (state.action == ACTION_MANAGE) { 2464ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey contentsUri = DocumentsContract.setManageMode(contentsUri); 2474ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 248fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return new DirectoryLoader( 2494ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey context, mType, root, doc, contentsUri, state.userSortOrder); 250251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_RECENT_OPEN: 251348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 252a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey return new RecentLoader(context, roots, state); 253251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey default: 254251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey throw new IllegalStateException("Unknown type " + mType); 255251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 2569e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2579e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2589e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 259b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { 260d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey if (!isAdded()) return; 261d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 2625dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mAdapter.swapCursor(result.cursor); 263d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 264d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // Push latest state up to UI 265d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // TODO: if mode change was racing with us, don't overwrite it 26688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (result.mode != MODE_UNKNOWN) { 26788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey state.derivedMode = result.mode; 26888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 269fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedSortOrder = result.sortOrder; 270d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey ((DocumentsActivity) context).onStateChanged(); 271d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 272d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey updateDisplayState(); 273d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 274e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey // Restore any previous instance state 275e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final SparseArray<Parcelable> container = state.dirState.remove(mStateKey); 276e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey if (container != null && !getArguments().getBoolean(EXTRA_IGNORE_STATE, false)) { 277e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey getView().restoreHierarchyState(container); 278e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } else if (mLastSortOrder != state.derivedSortOrder) { 279d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mListView.smoothScrollToPosition(0); 280d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mGridView.smoothScrollToPosition(0); 281d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 282e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 283e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey mLastSortOrder = state.derivedSortOrder; 2849e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2859e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2869e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 287b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoaderReset(Loader<DirectoryResult> loader) { 2885dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mAdapter.swapCursor(null); 2899e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2909e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey }; 2919e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 292d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // Kick off loader at least once 293d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 294d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 295b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey updateDisplayState(); 29654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 2979e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 29828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey @Override 299e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey public void onStop() { 300e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey super.onStop(); 301e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 302e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey // Remember last scroll location 303e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final SparseArray<Parcelable> container = new SparseArray<Parcelable>(); 304e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey getView().saveHierarchyState(container); 305e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey final State state = getDisplayState(this); 306e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey state.dirState.put(mStateKey, container); 307e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey } 308e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey 309e20a3acdc2d52c7eeb76940206145b3c419394a6Jeff Sharkey @Override 31088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public void onResume() { 31188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey super.onResume(); 31228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey updateDisplayState(); 31328c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 31428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 315d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onUserSortOrderChanged() { 316fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // Sort order change always triggers reload; we'll trigger state change 317fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // on the flip side. 318d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 319d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 320d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 321d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onUserModeChanged() { 322fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final ContentResolver resolver = getActivity().getContentResolver(); 323fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final State state = getDisplayState(this); 324fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 325fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); 326fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 327fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 3283e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey if (root != null && doc != null) { 32988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final Uri stateUri = RecentsProvider.buildState( 33088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey root.authority, root.rootId, doc.documentId); 33188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final ContentValues values = new ContentValues(); 33288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey values.put(StateColumns.MODE, state.userMode); 33388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey 33488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey new AsyncTask<Void, Void, Void>() { 33588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey @Override 33688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey protected Void doInBackground(Void... params) { 33788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey resolver.insert(stateUri, values); 33888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey return null; 33988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 34088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey }.execute(); 34188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 342fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 343fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // Mode change is just visual change; no need to kick loader, and 344fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // deliver change event immediately. 345fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedMode = state.userMode; 346fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey ((DocumentsActivity) getActivity()).onStateChanged(); 347fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 348d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey updateDisplayState(); 349d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 350d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 351d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private void updateDisplayState() { 352b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(this); 35354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 354ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey if (mLastMode == state.derivedMode && mLastShowSize == state.showSize) return; 355fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mLastMode = state.derivedMode; 356ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey mLastShowSize = state.showSize; 35754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 358fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mListView.setVisibility(state.derivedMode == MODE_LIST ? View.VISIBLE : View.GONE); 359fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mGridView.setVisibility(state.derivedMode == MODE_GRID ? View.VISIBLE : View.GONE); 36054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 361be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey final int choiceMode; 3621482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey if (state.allowMultiple) { 363be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL; 364be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 365be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_NONE; 366be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 367be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 3689d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final int thumbSize; 369fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_GRID) { 3709d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width); 37154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(null); 372be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(ListView.CHOICE_MODE_NONE); 37354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(mAdapter); 374be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.grid_width)); 37554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setNumColumns(GridView.AUTO_FIT); 376be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(choiceMode); 377be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mGridView; 378fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_LIST) { 379d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size); 38054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(null); 381be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE); 38254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(mAdapter); 383be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(choiceMode); 384be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mListView; 3851482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey } else { 386fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey throw new IllegalStateException("Unknown state " + state.derivedMode); 38754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 3889d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 3899d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mThumbSize = new Point(thumbSize, thumbSize); 39054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 39154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 39254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 39354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 39454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 3955dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 3963f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (cursor != null) { 3972a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 3982a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 3992a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (isDocumentEnabled(docMimeType, docFlags)) { 4002a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 4013f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey ((DocumentsActivity) getActivity()).onDocumentPicked(doc); 4023f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 403a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 40454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 40554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey }; 40654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 407be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private MultiChoiceModeListener mMultiListener = new MultiChoiceModeListener() { 408be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 409be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onCreateActionMode(ActionMode mode, Menu menu) { 410be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.getMenuInflater().inflate(R.menu.mode_directory, menu); 411be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 412be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 413be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 414be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 415be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 416b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 4174eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4184eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem open = menu.findItem(R.id.menu_open); 4194eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem share = menu.findItem(R.id.menu_share); 4204eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem delete = menu.findItem(R.id.menu_delete); 4214eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4224eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final boolean manageMode = state.action == ACTION_MANAGE; 4234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey open.setVisible(!manageMode); 4244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey share.setVisible(manageMode); 4254eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey delete.setVisible(manageMode); 4264eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 427be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 428be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 429be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 430be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 431be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 4324eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final SparseBooleanArray checked = mCurrentView.getCheckedItemPositions(); 433ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final ArrayList<DocumentInfo> docs = Lists.newArrayList(); 4344eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int size = checked.size(); 4354eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey for (int i = 0; i < size; i++) { 4364eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (checked.valueAt(i)) { 4375dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(checked.keyAt(i)); 438251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 4394eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey docs.add(doc); 440be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 4414eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4424eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4434eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int id = item.getItemId(); 4444eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (id == R.id.menu_open) { 4454eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey DocumentsActivity.get(DirectoryFragment.this).onDocumentsPicked(docs); 446b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 4474eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 448be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 4494eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_share) { 4504eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onShareDocuments(docs); 451b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 452be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 4534eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4544eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_delete) { 4554eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onDeleteDocuments(docs); 456b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 4574eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 4584eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 459be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 460be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return false; 461be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 462be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 463be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 464be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 465be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onDestroyActionMode(ActionMode mode) { 466be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey // ignored 467be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 468be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 469be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 470be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onItemCheckedStateChanged( 471be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey ActionMode mode, int position, long id, boolean checked) { 472be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey if (checked) { 4733f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Directories and footer items cannot be checked 4743f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey boolean valid = false; 4753f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4765dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 4773f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (cursor != null) { 4783f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 4792a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 4802a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (!Document.MIME_TYPE_DIR.equals(docMimeType)) { 4812a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey valid = isDocumentEnabled(docMimeType, docFlags); 4822a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 4833f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 4843f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4853f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (!valid) { 486be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView.setItemChecked(position, false); 487be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 488be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 489be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 490be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.setTitle(getResources() 491be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey .getString(R.string.mode_selected_count, mCurrentView.getCheckedItemCount())); 492be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 493be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey }; 494be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 4954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private RecyclerListener mRecycleListener = new RecyclerListener() { 4964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey @Override 4974ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public void onMovedToScrapHeap(View view) { 4984ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb); 4994ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (iconThumb != null) { 5004ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag(); 5014ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (oldTask != null) { 5024ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey oldTask.reallyCancel(); 5034ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(null); 5044ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5054ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5064ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 5074ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey }; 5084ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 509ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onShareDocuments(List<DocumentInfo> docs) { 510b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey Intent intent; 511b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (docs.size() == 1) { 512b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final DocumentInfo doc = docs.get(0); 513b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 514b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = new Intent(Intent.ACTION_SEND); 515b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 516b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 517b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(doc.mimeType); 518d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri); 5194eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 520b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (docs.size() > 1) { 5214eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent = new Intent(Intent.ACTION_SEND_MULTIPLE); 5224eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 5234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 524b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 525b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<String> mimeTypes = Lists.newArrayList(); 526b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<Uri> uris = Lists.newArrayList(); 527b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (DocumentInfo doc : docs) { 528b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mimeTypes.add(doc.mimeType); 529d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey uris.add(doc.derivedUri); 530b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 531b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 532b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(findCommonMimeType(mimeTypes)); 5334eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); 534b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 5354eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else { 536b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return; 5374eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5384eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 539b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via)); 5404eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey startActivity(intent); 5414eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5424eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 543ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onDeleteDocuments(List<DocumentInfo> docs) { 5444eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final Context context = getActivity(); 5454eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ContentResolver resolver = context.getContentResolver(); 5464eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 5474eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey boolean hadTrouble = false; 548ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey for (DocumentInfo doc : docs) { 5494eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (!doc.isDeleteSupported()) { 5504eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Log.w(TAG, "Skipping " + doc); 5514eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 5524eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey continue; 5534eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5544eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 555d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey if (!DocumentsContract.deleteDocument(resolver, doc.derivedUri)) { 556ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey Log.w(TAG, "Failed to delete " + doc); 5574eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 5584eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5594eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5604eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 5614eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (hadTrouble) { 5624eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Toast.makeText(context, R.string.toast_failed_delete, Toast.LENGTH_SHORT).show(); 5634eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5644eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 5654eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 566b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private static State getDisplayState(Fragment fragment) { 5671482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey return ((DocumentsActivity) fragment.getActivity()).getDisplayState(); 56854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 56954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 5703f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static abstract class Footer { 5713f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private final int mItemViewType; 5723f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 5733f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public Footer(int itemViewType) { 5743f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey mItemViewType = itemViewType; 5753f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 5763f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 5773f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public abstract View getView(View convertView, ViewGroup parent); 5783f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 5793f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public int getItemViewType() { 5803f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return mItemViewType; 5813f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 582954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 583954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 584ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey private class LoadingFooter extends Footer { 5853f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public LoadingFooter() { 5863f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey super(1); 5873f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 5883f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 589954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 590954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 591954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 592ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 593ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey 594954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 595954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 596ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey if (state.derivedMode == MODE_LIST) { 597ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey convertView = inflater.inflate(R.layout.item_loading_list, parent, false); 598ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 599ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey convertView = inflater.inflate(R.layout.item_loading_grid, parent, false); 600ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } else { 601ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey throw new IllegalStateException(); 602ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey } 603954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 604ed903213e6d3d75d497498c9cf95aa8e74277a9eJeff Sharkey 605954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 606954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 607954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 608954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 6093f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private class MessageFooter extends Footer { 610954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final int mIcon; 611954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final String mMessage; 612954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 6133f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public MessageFooter(int itemViewType, int icon, String message) { 6143f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey super(itemViewType); 615954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mIcon = icon; 616954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mMessage = message; 617954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 618954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 619954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 620954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 621954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 622954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 623954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 624954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 625954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 626fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_LIST) { 627954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_list, parent, false); 628fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 629954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_grid, parent, false); 630954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 631954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey throw new IllegalStateException(); 632954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 633954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 634954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 635954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 636954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 637954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey icon.setImageResource(mIcon); 638954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey title.setText(mMessage); 639954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 640954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 641954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 642954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 643ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey private class DocumentsAdapter extends BaseAdapter { 6445dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey private Cursor mCursor; 645954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private int mCursorCount; 646954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 647954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private List<Footer> mFooters = Lists.newArrayList(); 648ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 6495dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public void swapCursor(Cursor cursor) { 6505dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor = cursor; 651954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mCursorCount = cursor != null ? cursor.getCount() : 0; 652954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 653954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.clear(); 654954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 655954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Bundle extras = cursor != null ? cursor.getExtras() : null; 656954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras != null) { 657954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String info = extras.getString(DocumentsContract.EXTRA_INFO); 658954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (info != null) { 6591feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey mFooters.add(new MessageFooter(2, R.drawable.ic_dialog_info, info)); 660954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 661954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String error = extras.getString(DocumentsContract.EXTRA_ERROR); 662954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (error != null) { 6633f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey mFooters.add(new MessageFooter(3, R.drawable.ic_dialog_alert, error)); 664954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 665954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) { 666954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.add(new LoadingFooter()); 667954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 668954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 6699fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 6705dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (isEmpty()) { 6719fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.VISIBLE); 6729fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } else { 6739fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.GONE); 6749fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 6759fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 676ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey notifyDataSetChanged(); 6779e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 6789e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 6799e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 680ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 681954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 682954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return getDocumentView(position, convertView, parent); 683954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 684954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey position -= mCursorCount; 6853f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey convertView = mFooters.get(position).getView(convertView, parent); 6863f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Only the view itself is disabled; contents inside shouldn't 6873f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // be dimmed. 6883f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey convertView.setEnabled(false); 6893f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return convertView; 690954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 691954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 692954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 693954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private View getDocumentView(int position, View convertView, ViewGroup parent) { 694ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final Context context = parent.getContext(); 695b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 696ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 697f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 698f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 6994eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 7004eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 7014eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 7024eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 703ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey if (convertView == null) { 704ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 705fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_LIST) { 706ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_list, parent, false); 707fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 708ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_grid, parent, false); 7091feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey 7101feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey // Apply padding to grid items 7111feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey final FrameLayout grid = (FrameLayout) convertView; 7121feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey final int gridPadding = getResources() 7131feeddf518d31a7ff5d28000a631857442cd7161Jeff Sharkey .getDimensionPixelSize(R.dimen.grid_padding); 714deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 715deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Tricksy hobbitses! We need to fully clear the drawable so 716deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // the view doesn't clobber the new InsetDrawable callback 717deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // when setting back later. 718deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final Drawable fg = grid.getForeground(); 719deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final Drawable bg = grid.getBackground(); 720deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey grid.setForeground(null); 721deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey grid.setBackground(null); 722deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey grid.setForeground(new InsetDrawable(fg, gridPadding)); 723deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey grid.setBackground(new InsetDrawable(bg, gridPadding)); 724ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } else { 725ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey throw new IllegalStateException(); 726ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 727ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 728ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 7295dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = getItem(position); 7305dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 731251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); 732251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docRootId = getCursorString(cursor, RootCursorWrapper.COLUMN_ROOT_ID); 7335dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); 7345dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 7355dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docDisplayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME); 7365dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docLastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED); 7375dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docIcon = getCursorInt(cursor, Document.COLUMN_ICON); 7385dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 7395dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY); 7405dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE); 741ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 742f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final View line1 = convertView.findViewById(R.id.line1); 743f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final View line2 = convertView.findViewById(R.id.line2); 744f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 7454ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final View icon = convertView.findViewById(android.R.id.icon); 7464ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime); 7474ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconThumb = (ImageView) convertView.findViewById(R.id.icon_thumb); 748ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 749b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1); 750f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final ImageView icon2 = (ImageView) convertView.findViewById(android.R.id.icon2); 751ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 752b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView date = (TextView) convertView.findViewById(R.id.date); 753b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView size = (TextView) convertView.findViewById(R.id.size); 754ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 7554ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag(); 7569d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (oldTask != null) { 7574ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey oldTask.reallyCancel(); 7584ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(null); 7599d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7609d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7614ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.animate().cancel(); 7624ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.animate().cancel(); 7634ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 7643f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0; 765fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final boolean allowThumbnail = (state.derivedMode == MODE_GRID) 766f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey || MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, docMimeType); 767f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final boolean showThumbnail = supportsThumbnail && allowThumbnail; 7683f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 7694ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey boolean cacheHit = false; 770f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (showThumbnail) { 771251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId); 7725dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Bitmap cachedResult = thumbs.get(uri); 7739d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (cachedResult != null) { 7744ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setImageBitmap(cachedResult); 7754ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey cacheHit = true; 7769d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 7774ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setImageDrawable(null); 7784ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ThumbnailAsyncTask task = new ThumbnailAsyncTask( 7794ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey uri, iconMime, iconThumb, mThumbSize); 7804ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setTag(task); 7814ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 7829d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7834ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 7844ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 7854ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // Always throw MIME icon into place, even when a thumbnail is being 7864ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // loaded in background. 7874ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (cacheHit) { 7884ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setAlpha(0f); 7894ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setAlpha(1f); 7909e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } else { 7914ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setAlpha(1f); 7924ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconThumb.setAlpha(0f); 7934ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (docIcon != 0) { 7944ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setImageDrawable( 7954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey IconUtils.loadPackageIcon(context, docAuthority, docIcon)); 7964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } else { 797563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey iconMime.setImageDrawable(IconUtils.loadMimeIcon( 798563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey context, docMimeType, docAuthority, docId, state.derivedMode)); 7994ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 8009e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 8019e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 802f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey boolean hasLine1 = false; 80328c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey boolean hasLine2 = false; 80428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 805f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey final boolean hideTitle = (state.derivedMode == MODE_GRID) && mHideGridTitles; 806f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (!hideTitle) { 807f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey title.setText(docDisplayName); 808f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey hasLine1 = true; 809f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 810f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 811f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey Drawable iconDrawable = null; 812251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey if (mType == TYPE_RECENT_OPEN) { 813a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey // We've already had to enumerate roots before any results can 814a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey // be shown, so this will never block. 815a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final RootInfo root = roots.getRootBlocking(docAuthority, docRootId); 816f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey iconDrawable = root.loadIcon(context); 8174ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 81888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (summary != null) { 81988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey final boolean alwaysShowSummary = getResources() 82088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey .getBoolean(R.bool.always_show_summary); 82188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (alwaysShowSummary) { 82288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(root.getDirectoryString()); 82388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 82488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 82588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 826a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (iconDrawable != null && roots.isIconUniqueBlocking(root)) { 82788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey // No summary needed if icon speaks for itself 82888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.INVISIBLE); 82988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 83088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(root.getDirectoryString()); 83188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 83288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END); 83388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 83488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 83588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 8364ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 8375dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } else { 838f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // Directories showing thumbnails in grid mode get a little icon 839f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey // hint to remind user they're a directory. 840f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType) && state.derivedMode == MODE_GRID 841f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey && showThumbnail) { 842f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey iconDrawable = context.getResources().getDrawable(R.drawable.ic_root_folder); 843f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 844f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 84588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (summary != null) { 84688f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (docSummary != null) { 84788f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setText(docSummary); 84888f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.VISIBLE); 84988f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey hasLine2 = true; 85088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } else { 85188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey summary.setVisibility(View.INVISIBLE); 85288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 853251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 854b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 855b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 856f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon1 != null) icon1.setVisibility(View.GONE); 857f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon2 != null) icon2.setVisibility(View.GONE); 858f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 859f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (iconDrawable != null) { 860f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (hasLine1) { 861f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon1.setVisibility(View.VISIBLE); 862f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon1.setImageDrawable(iconDrawable); 863f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } else { 864f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon2.setVisibility(View.VISIBLE); 865f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey icon2.setImageDrawable(iconDrawable); 866f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 867f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 868f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey 8695dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (docLastModified == -1) { 8709d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey date.setText(null); 8719d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 8725dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey date.setText(formatTime(context, docLastModified)); 87328c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 8749d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 875b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 876b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (state.showSize) { 877b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.VISIBLE); 8785dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType) || docSize == -1) { 879b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setText(null); 880b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 8815dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey size.setText(Formatter.formatFileSize(context, docSize)); 88228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 883b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 884b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 885b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.GONE); 88654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 887ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 888f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (line1 != null) { 889f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey line1.setVisibility(hasLine1 ? View.VISIBLE : View.GONE); 890f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 89188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey if (line2 != null) { 89288f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE); 89388f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey } 89428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 8952a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final boolean enabled = isDocumentEnabled(docMimeType, docFlags); 8963f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (enabled) { 8973f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(convertView, true); 8983f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey icon.setAlpha(1f); 899f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon1 != null) icon1.setAlpha(1f); 900f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon2 != null) icon2.setAlpha(1f); 9013f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } else { 9023f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(convertView, false); 9033f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey icon.setAlpha(0.5f); 904f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon1 != null) icon1.setAlpha(0.5f); 905f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (icon2 != null) icon2.setAlpha(0.5f); 9063f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 9073f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 908ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey return convertView; 90954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 91054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 911ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 912ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public int getCount() { 913954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursorCount + mFooters.size(); 914ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 9159e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 916ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 9175dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public Cursor getItem(int position) { 918954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 9195dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor.moveToPosition(position); 920954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursor; 921954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 922954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return null; 9235dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 924ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 92554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 926ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 927ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public long getItemId(int position) { 9285dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return position; 929ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 930954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 931954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 9323f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public int getViewTypeCount() { 9333f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return 4; 9343f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 9353f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 9363f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey @Override 937954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public int getItemViewType(int position) { 938954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 939954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return 0; 940954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 9413f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey position -= mCursorCount; 9423f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return mFooters.get(position).getItemViewType(); 943954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 944954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 9459e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 9469d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9479d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> { 9484ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final Uri mUri; 9494ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final ImageView mIconMime; 9504ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final ImageView mIconThumb; 9514eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private final Point mThumbSize; 9524ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private final CancellationSignal mSignal; 9539d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9544ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public ThumbnailAsyncTask( 9554ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize) { 9564ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mUri = uri; 9574ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconMime = iconMime; 9584ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb = iconThumb; 9594eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mThumbSize = thumbSize; 9604ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mSignal = new CancellationSignal(); 9619d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 9629d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9634ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey public void reallyCancel() { 9644ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey cancel(false); 9654ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mSignal.cancel(); 9669d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 9679d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9689d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 9699d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected Bitmap doInBackground(Uri... params) { 9704ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final Context context = mIconThumb.getContext(); 9719d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9729d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Bitmap result = null; 9739d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey try { 9744ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // TODO: switch to using unstable provider 975ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey result = DocumentsContract.getDocumentThumbnail( 9764ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey context.getContentResolver(), mUri, mThumbSize, mSignal); 9779d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (result != null) { 9784eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 9794eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 9804ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey thumbs.put(mUri, result); 9819d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 9829d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } catch (Exception e) { 9839d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Log.w(TAG, "Failed to load thumbnail: " + e); 9849d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 9859d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return result; 9869d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 9879d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 9889d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 9899d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected void onPostExecute(Bitmap result) { 9904ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey if (mIconThumb.getTag() == this && result != null) { 9914ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setTag(null); 9924ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setImageBitmap(result); 9934ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 9944ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconMime.setAlpha(1f); 9954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconMime.animate().alpha(0f).start(); 9964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.setAlpha(0f); 9974ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey mIconThumb.animate().alpha(1f).start(); 9989d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 9999d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10009d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10019d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10029d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static String formatTime(Context context, long when) { 10039d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey // TODO: DateUtils should make this easier 10049d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time then = new Time(); 10059d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey then.set(when); 10069d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time now = new Time(); 10079d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey now.setToNow(); 10089d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10099d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT 10109d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey | DateUtils.FORMAT_ABBREV_ALL; 10119d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10129d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (then.year != now.year) { 10139d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE; 10149d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else if (then.yearDay != now.yearDay) { 10159d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_DATE; 10169d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 10179d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_TIME; 10189d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 10199d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 10209d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return DateUtils.formatDateTime(context, when, flags); 10219d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 1022b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1023b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private String findCommonMimeType(List<String> mimeTypes) { 1024b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] commonType = mimeTypes.get(0).split("/"); 1025b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (commonType.length != 2) { 1026b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return "*/*"; 1027b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1028b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1029b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (int i = 1; i < mimeTypes.size(); i++) { 1030b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] type = mimeTypes.get(i).split("/"); 1031b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (type.length != 2) continue; 1032b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1033b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[1].equals(type[1])) { 1034b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 1035b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1036b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1037b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[0].equals(type[0])) { 1038b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[0] = "*"; 1039b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 1040b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey break; 1041b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1042b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 1043b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 1044b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return commonType[0] + "/" + commonType[1]; 1045b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 10463f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 10473f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private void setEnabledRecursive(View v, boolean enabled) { 1048f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (v == null) return; 10493f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (v.isEnabled() == enabled) return; 10503f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey v.setEnabled(enabled); 10513f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 10523f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (v instanceof ViewGroup) { 10533f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final ViewGroup vg = (ViewGroup) v; 10543f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey for (int i = vg.getChildCount() - 1; i >= 0; i--) { 10553f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(vg.getChildAt(i), enabled); 10563f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 10573f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 10583f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 10592a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 10602a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey private boolean isDocumentEnabled(String docMimeType, int docFlags) { 10612a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 10622a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 10632a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey // Directories are always enabled 10642a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType)) { 10652a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey return true; 10662a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 10672a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey 10683d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey // Read-only files are disabled when creating 10693d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey if (state.action == ACTION_CREATE && (docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) { 10703d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey return false; 10713d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey } 10723d52dc9c3a2fd9997322ce5e28607b3f7e9bfcf7Jeff Sharkey 10732a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey return MimePredicate.mimeMatches(state.acceptMimes, docMimeType); 10742a030b05a978281147df4d1cc4f12bc8d61c0729Jeff Sharkey } 10759e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey} 1076