DirectoryFragment.java revision fb3445c9b31c7f8401d6eec0606dabee366c8aad
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; 20b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE; 21b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_GRID; 22b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_LIST; 23d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN; 24d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN; 255dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorInt; 265dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorLong; 275dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorString; 289d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 2954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.app.Fragment; 309e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentManager; 319e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentTransaction; 329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.LoaderManager.LoaderCallbacks; 334eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.ContentResolver; 34fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkeyimport android.content.ContentValues; 359e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Context; 364eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.Intent; 379e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Loader; 385dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.database.Cursor; 399d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Bitmap; 409d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Point; 419e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.net.Uri; 429d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.os.AsyncTask; 439e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.os.Bundle; 449e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.provider.DocumentsContract; 455dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.provider.DocumentsContract.Document; 4654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.text.format.DateUtils; 47b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.text.format.Formatter; 489d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.text.format.Time; 499d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.util.Log; 50be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.util.SparseBooleanArray; 51be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.view.ActionMode; 529e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.LayoutInflater; 5354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.Menu; 5454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.MenuItem; 559e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.View; 569e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.ViewGroup; 57be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView; 58be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView.MultiChoiceModeListener; 5954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView; 6054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView.OnItemClickListener; 61ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.widget.BaseAdapter; 6254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.GridView; 639e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ImageView; 649e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ListView; 659e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.TextView; 664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.widget.Toast; 679e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 68b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport com.android.documentsui.DocumentsActivity.State; 69fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkeyimport com.android.documentsui.RecentsProvider.StateColumns; 70ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo; 71251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkeyimport com.android.documentsui.model.RootInfo; 72ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport com.android.internal.util.Predicate; 73be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport com.google.android.collect.Lists; 74be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 75be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.ArrayList; 76ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport java.util.List; 77b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport java.util.concurrent.atomic.AtomicInteger; 7854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 7954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey/** 8054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Display the documents inside a single directory. 8154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey */ 8254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeypublic class DirectoryFragment extends Fragment { 8354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 849fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey private View mEmptyView; 8554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private ListView mListView; 8654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private GridView mGridView; 8754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 88be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private AbsListView mCurrentView; 89be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 90ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private Predicate<DocumentInfo> mFilter; 919fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 92ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_NORMAL = 1; 93ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_SEARCH = 2; 94251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey public static final int TYPE_RECENT_OPEN = 3; 95dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 96dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey private int mType = TYPE_NORMAL; 97dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 98d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private int mLastMode = MODE_UNKNOWN; 99d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private int mLastSortOrder = SORT_ORDER_UNKNOWN; 100d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 1019d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private Point mThumbSize; 1029d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 1039e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey private DocumentsAdapter mAdapter; 104b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey private LoaderCallbacks<DirectoryResult> mCallbacks; 1059e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 106b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static final String EXTRA_TYPE = "type"; 107d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final String EXTRA_ROOT = "root"; 108d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final String EXTRA_DOC = "doc"; 109251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static final String EXTRA_QUERY = "query"; 1109e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 1113f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey /** 1123f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey * MIME types that should always show thumbnails in list mode. 1133f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey */ 1143f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static final String[] LIST_THUMBNAIL_MIMES = new String[] { "image/*", "video/*" }; 1153f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 116b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static AtomicInteger sLoaderId = new AtomicInteger(4000); 117b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 118b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private final int mLoaderId = sLoaderId.incrementAndGet(); 119b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 120d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc) { 121d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey show(fm, TYPE_NORMAL, root, doc, null); 122b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 123b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 124d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static void showSearch( 125d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey FragmentManager fm, RootInfo root, DocumentInfo doc, String query) { 126d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey show(fm, TYPE_SEARCH, root, doc, query); 127b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 128b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 129b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public static void showRecentsOpen(FragmentManager fm) { 130d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey show(fm, TYPE_RECENT_OPEN, null, null, null); 131b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 1329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 133d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static void show( 134d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query) { 1359e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Bundle args = new Bundle(); 136b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey args.putInt(EXTRA_TYPE, type); 137d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey args.putParcelable(EXTRA_ROOT, root); 138d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey args.putParcelable(EXTRA_DOC, doc); 139251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey args.putString(EXTRA_QUERY, query); 1409e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 1419e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final DirectoryFragment fragment = new DirectoryFragment(); 1429e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey fragment.setArguments(args); 1439e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 1449e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 14566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.replace(R.id.container_directory, fragment); 1469e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey ft.commitAllowingStateLoss(); 1479e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 1489e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 149ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static DirectoryFragment get(FragmentManager fm) { 150ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey // TODO: deal with multiple directories shown at once 15166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return (DirectoryFragment) fm.findFragmentById(R.id.container_directory); 152ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 153ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 1549e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 1559e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey public View onCreateView( 1569e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 1579e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Context context = inflater.getContext(); 15854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final View view = inflater.inflate(R.layout.fragment_directory, container, false); 15954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1609fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView = view.findViewById(android.R.id.empty); 1619fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 16254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView = (ListView) view.findViewById(R.id.list); 16354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setOnItemClickListener(mItemListener); 164be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setMultiChoiceModeListener(mMultiListener); 16554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 16654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView = (GridView) view.findViewById(R.id.grid); 16754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setOnItemClickListener(mItemListener); 168be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setMultiChoiceModeListener(mMultiListener); 16954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1705dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return view; 1715dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 17254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1735dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey @Override 1745dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public void onActivityCreated(Bundle savedInstanceState) { 1755dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey super.onActivityCreated(savedInstanceState); 1765dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 1775dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Context context = getActivity(); 178d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 1795dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 180251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey mAdapter = new DocumentsAdapter(); 181b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mType = getArguments().getInt(EXTRA_TYPE); 1829e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 183b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey mCallbacks = new LoaderCallbacks<DirectoryResult>() { 1849e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 185b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { 186d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); 187d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 188251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String query = getArguments().getString(EXTRA_QUERY); 189251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey 19054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey Uri contentsUri; 191251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey switch (mType) { 192251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_NORMAL: 193d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey contentsUri = DocumentsContract.buildChildDocumentsUri( 194d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey doc.authority, doc.documentId); 195fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return new DirectoryLoader( 196fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey context, root, doc, contentsUri, state.userSortOrder); 197251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_SEARCH: 198251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey contentsUri = DocumentsContract.buildSearchDocumentsUri( 199d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey doc.authority, doc.documentId, query); 200fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return new DirectoryLoader( 201fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey context, root, doc, contentsUri, state.userSortOrder); 202251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_RECENT_OPEN: 203348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 204348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey final List<RootInfo> matchingRoots = roots.getMatchingRoots(state); 205d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey return new RecentLoader(context, matchingRoots, state.acceptMimes); 206251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey default: 207251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey throw new IllegalStateException("Unknown type " + mType); 208251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 2099e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2109e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2119e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 212b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { 213d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey if (!isAdded()) return; 214d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 2155dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mAdapter.swapCursor(result.cursor); 216d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 217d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // Push latest state up to UI 218d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // TODO: if mode change was racing with us, don't overwrite it 219fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedMode = result.mode; 220fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedSortOrder = result.sortOrder; 221d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey ((DocumentsActivity) context).onStateChanged(); 222d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 223d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey updateDisplayState(); 224d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 225fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (mLastSortOrder != state.derivedSortOrder) { 226fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mLastSortOrder = state.derivedSortOrder; 227d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mListView.smoothScrollToPosition(0); 228d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mGridView.smoothScrollToPosition(0); 229d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 2309e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2319e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 233b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoaderReset(Loader<DirectoryResult> loader) { 2345dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mAdapter.swapCursor(null); 2359e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2369e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey }; 2379e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 238d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey // Kick off loader at least once 239d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 240d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 241b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey updateDisplayState(); 24254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 2439e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 24428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey @Override 24528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey public void onStart() { 24628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey super.onStart(); 24728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey updateDisplayState(); 24828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 24928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 250d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onUserSortOrderChanged() { 251fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // Sort order change always triggers reload; we'll trigger state change 252fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // on the flip side. 253d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 254d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 255d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 256d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void onUserModeChanged() { 257fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final ContentResolver resolver = getActivity().getContentResolver(); 258fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final State state = getDisplayState(this); 259fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 260fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); 261fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); 262fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 263fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final Uri stateUri = RecentsProvider.buildState( 264fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey root.authority, root.rootId, doc.documentId); 265fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final ContentValues values = new ContentValues(); 266fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey values.put(StateColumns.MODE, state.userMode); 267fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 268fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey new AsyncTask<Void, Void, Void>() { 269fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey @Override 270fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey protected Void doInBackground(Void... params) { 271fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey resolver.insert(stateUri, values); 272fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey return null; 273fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } 274fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey }.execute(); 275fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 276fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // Mode change is just visual change; no need to kick loader, and 277fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey // deliver change event immediately. 278fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey state.derivedMode = state.userMode; 279fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey ((DocumentsActivity) getActivity()).onStateChanged(); 280fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey 281d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey updateDisplayState(); 282d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 283d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 284d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private void updateDisplayState() { 285b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(this); 28654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 287d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey mFilter = new MimePredicate(state.acceptMimes); 2885dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 289fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (mLastMode == state.derivedMode) return; 290fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mLastMode = state.derivedMode; 29154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 292fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mListView.setVisibility(state.derivedMode == MODE_LIST ? View.VISIBLE : View.GONE); 293fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey mGridView.setVisibility(state.derivedMode == MODE_GRID ? View.VISIBLE : View.GONE); 29454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 295be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey final int choiceMode; 2961482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey if (state.allowMultiple) { 297be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL; 298be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 299be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_NONE; 300be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 301be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 3029d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final int thumbSize; 303fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_GRID) { 3049d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width); 30554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(null); 306be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(ListView.CHOICE_MODE_NONE); 30754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(mAdapter); 308be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.grid_width)); 30954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setNumColumns(GridView.AUTO_FIT); 310be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(choiceMode); 311be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mGridView; 312fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_LIST) { 313d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size); 31454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(null); 315be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE); 31654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(mAdapter); 317be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(choiceMode); 318be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mListView; 3191482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey } else { 320fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey throw new IllegalStateException("Unknown state " + state.derivedMode); 32154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 3229d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 3239d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mThumbSize = new Point(thumbSize, thumbSize); 32454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 32554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 32654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 32754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 32854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 3295dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 3303f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (cursor != null) { 3313f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 3323f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (mFilter.apply(doc)) { 3333f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey ((DocumentsActivity) getActivity()).onDocumentPicked(doc); 3343f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 335a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 33654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 33754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey }; 33854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 339be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private MultiChoiceModeListener mMultiListener = new MultiChoiceModeListener() { 340be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 341be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onCreateActionMode(ActionMode mode, Menu menu) { 342be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.getMenuInflater().inflate(R.menu.mode_directory, menu); 343be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 344be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 345be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 346be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 347be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 348b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 3494eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 3504eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem open = menu.findItem(R.id.menu_open); 3514eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem share = menu.findItem(R.id.menu_share); 3524eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem delete = menu.findItem(R.id.menu_delete); 3534eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 3544eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final boolean manageMode = state.action == ACTION_MANAGE; 3554eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey open.setVisible(!manageMode); 3564eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey share.setVisible(manageMode); 3574eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey delete.setVisible(manageMode); 3584eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 359be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 360be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 361be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 362be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 363be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 3644eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final SparseBooleanArray checked = mCurrentView.getCheckedItemPositions(); 365ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final ArrayList<DocumentInfo> docs = Lists.newArrayList(); 3664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int size = checked.size(); 3674eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey for (int i = 0; i < size; i++) { 3684eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (checked.valueAt(i)) { 3695dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(checked.keyAt(i)); 370251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 3714eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey docs.add(doc); 372be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 3734eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 3744eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 3754eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int id = item.getItemId(); 3764eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (id == R.id.menu_open) { 3774eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey DocumentsActivity.get(DirectoryFragment.this).onDocumentsPicked(docs); 378b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 3794eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 380be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 3814eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_share) { 3824eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onShareDocuments(docs); 383b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 384be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 3854eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 3864eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_delete) { 3874eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onDeleteDocuments(docs); 388b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 3894eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 3904eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 391be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 392be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return false; 393be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 394be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 395be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 396be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 397be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onDestroyActionMode(ActionMode mode) { 398be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey // ignored 399be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 400be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 401be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 402be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onItemCheckedStateChanged( 403be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey ActionMode mode, int position, long id, boolean checked) { 404be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey if (checked) { 4053f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Directories and footer items cannot be checked 4063f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey boolean valid = false; 4073f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4085dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 4093f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (cursor != null) { 4103f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 4113f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4123f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Only valid if non-directory matches filter 4133f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 4143f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey valid = !Document.MIME_TYPE_DIR.equals(docMimeType) 4153f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey && MimePredicate.mimeMatches(state.acceptMimes, docMimeType); 4163f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 4173f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4183f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (!valid) { 419be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView.setItemChecked(position, false); 420be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 421be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 422be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 423be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.setTitle(getResources() 424be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey .getString(R.string.mode_selected_count, mCurrentView.getCheckedItemCount())); 425be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 426be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey }; 427be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 428ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onShareDocuments(List<DocumentInfo> docs) { 429b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey Intent intent; 430b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (docs.size() == 1) { 431b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final DocumentInfo doc = docs.get(0); 432b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 433b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = new Intent(Intent.ACTION_SEND); 434b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 435b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 436b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(doc.mimeType); 437d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri); 4384eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 439b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (docs.size() > 1) { 4404eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent = new Intent(Intent.ACTION_SEND_MULTIPLE); 4414eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 4424eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 443b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 444b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<String> mimeTypes = Lists.newArrayList(); 445b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<Uri> uris = Lists.newArrayList(); 446b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (DocumentInfo doc : docs) { 447b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mimeTypes.add(doc.mimeType); 448d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey uris.add(doc.derivedUri); 449b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 450b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 451b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(findCommonMimeType(mimeTypes)); 4524eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); 453b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 4544eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else { 455b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return; 4564eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4574eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 458b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via)); 4594eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey startActivity(intent); 4604eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4614eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 462ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onDeleteDocuments(List<DocumentInfo> docs) { 4634eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final Context context = getActivity(); 4644eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ContentResolver resolver = context.getContentResolver(); 4654eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey boolean hadTrouble = false; 467ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey for (DocumentInfo doc : docs) { 4684eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (!doc.isDeleteSupported()) { 4694eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Log.w(TAG, "Skipping " + doc); 4704eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 4714eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey continue; 4724eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4734eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 474d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey if (!DocumentsContract.deleteDocument(resolver, doc.derivedUri)) { 475ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey Log.w(TAG, "Failed to delete " + doc); 4764eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 4774eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4784eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4794eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4804eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (hadTrouble) { 4814eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Toast.makeText(context, R.string.toast_failed_delete, Toast.LENGTH_SHORT).show(); 4824eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4834eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4844eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 485b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private static State getDisplayState(Fragment fragment) { 4861482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey return ((DocumentsActivity) fragment.getActivity()).getDisplayState(); 48754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 48854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 4893f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static abstract class Footer { 4903f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private final int mItemViewType; 4913f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4923f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public Footer(int itemViewType) { 4933f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey mItemViewType = itemViewType; 4943f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 4953f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4963f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public abstract View getView(View convertView, ViewGroup parent); 4973f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 4983f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public int getItemViewType() { 4993f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return mItemViewType; 5003f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 501954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 502954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 5033f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static class LoadingFooter extends Footer { 5043f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public LoadingFooter() { 5053f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey super(1); 5063f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 5073f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 508954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 509954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 510954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 511954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 512954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 513954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_loading, parent, false); 514954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 515954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 516954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 517954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 518954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 5193f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private class MessageFooter extends Footer { 520954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final int mIcon; 521954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final String mMessage; 522954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 5233f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public MessageFooter(int itemViewType, int icon, String message) { 5243f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey super(itemViewType); 525954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mIcon = icon; 526954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mMessage = message; 527954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 528954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 529954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 530954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 531954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 532954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 533954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 534954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 535954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 536fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_LIST) { 537954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_list, parent, false); 538fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 539954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_grid, parent, false); 540954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 541954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey throw new IllegalStateException(); 542954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 543954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 544954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 545954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 546954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 547954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey icon.setImageResource(mIcon); 548954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey title.setText(mMessage); 549954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 550954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 551954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 552954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 553ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey private class DocumentsAdapter extends BaseAdapter { 5545dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey private Cursor mCursor; 555954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private int mCursorCount; 556954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 557954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private List<Footer> mFooters = Lists.newArrayList(); 558ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 5595dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public void swapCursor(Cursor cursor) { 5605dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor = cursor; 561954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mCursorCount = cursor != null ? cursor.getCount() : 0; 562954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 563954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.clear(); 564954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 565954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Bundle extras = cursor != null ? cursor.getExtras() : null; 566954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras != null) { 567954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String info = extras.getString(DocumentsContract.EXTRA_INFO); 568954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (info != null) { 5693f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey mFooters.add(new MessageFooter(2, R.drawable.ic_dialog_alert, info)); 570954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 571954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String error = extras.getString(DocumentsContract.EXTRA_ERROR); 572954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (error != null) { 5733f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey mFooters.add(new MessageFooter(3, R.drawable.ic_dialog_alert, error)); 574954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 575954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) { 576954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.add(new LoadingFooter()); 577954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 578954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 5799fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 5805dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (isEmpty()) { 5819fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.VISIBLE); 5829fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } else { 5839fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.GONE); 5849fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 5859fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 586ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey notifyDataSetChanged(); 5879e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 5889e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 5899e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 590ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 591954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 592954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return getDocumentView(position, convertView, parent); 593954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 594954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey position -= mCursorCount; 5953f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey convertView = mFooters.get(position).getView(convertView, parent); 5963f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // Only the view itself is disabled; contents inside shouldn't 5973f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey // be dimmed. 5983f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey convertView.setEnabled(false); 5993f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return convertView; 600954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 601954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 602954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 603954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private View getDocumentView(int position, View convertView, ViewGroup parent) { 604ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final Context context = parent.getContext(); 605b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 606ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 6074eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 6084eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 6094eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 6104eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 611ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey if (convertView == null) { 612ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 613fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey if (state.derivedMode == MODE_LIST) { 614ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_list, parent, false); 615fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey } else if (state.derivedMode == MODE_GRID) { 616ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_grid, parent, false); 617ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } else { 618ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey throw new IllegalStateException(); 619ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 620ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 621ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 6225dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = getItem(position); 6235dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 624251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); 625251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docRootId = getCursorString(cursor, RootCursorWrapper.COLUMN_ROOT_ID); 6265dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); 6275dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 6285dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docDisplayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME); 6295dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docLastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED); 6305dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docIcon = getCursorInt(cursor, Document.COLUMN_ICON); 6315dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 6325dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY); 6335dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE); 634ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 635b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 636ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 63728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey final View line2 = convertView.findViewById(R.id.line2); 638b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1); 639ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 640b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView date = (TextView) convertView.findViewById(R.id.date); 641b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView size = (TextView) convertView.findViewById(R.id.size); 642ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 6439d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) icon.getTag(); 6449d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (oldTask != null) { 6459d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey oldTask.cancel(false); 6469d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 6479d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 6483f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0; 649fb3445c9b31c7f8401d6eec0606dabee366c8aadJeff Sharkey final boolean allowThumbnail = (state.derivedMode == MODE_GRID) 6503f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey || MimePredicate.mimeMatches(LIST_THUMBNAIL_MIMES, docMimeType); 6513f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 6523f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (supportsThumbnail && allowThumbnail) { 653251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId); 6545dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Bitmap cachedResult = thumbs.get(uri); 6559d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (cachedResult != null) { 6569d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey icon.setImageBitmap(cachedResult); 6579d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 6589d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final ThumbnailAsyncTask task = new ThumbnailAsyncTask(icon, mThumbSize); 6599d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey icon.setImageBitmap(null); 6609d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey icon.setTag(task); 6613f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, uri); 6629d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 6635dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } else if (docIcon != 0) { 6640b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey icon.setImageDrawable(IconUtils.loadPackageIcon(context, docAuthority, docIcon)); 6659e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } else { 6660b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey icon.setImageDrawable(IconUtils.loadMimeIcon(context, docMimeType)); 6679e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 6689e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 6695dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey title.setText(docDisplayName); 670b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 67128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey boolean hasLine2 = false; 67228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 673251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey if (mType == TYPE_RECENT_OPEN) { 674251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final RootInfo root = roots.getRoot(docAuthority, docRootId); 675251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey icon1.setVisibility(View.VISIBLE); 676251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey icon1.setImageDrawable(root.loadIcon(context)); 677251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey summary.setText(root.getDirectoryString()); 6785dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey summary.setVisibility(View.VISIBLE); 67928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END); 68028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 6815dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } else { 682251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey icon1.setVisibility(View.GONE); 683251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey if (docSummary != null) { 684251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey summary.setText(docSummary); 685251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey summary.setVisibility(View.VISIBLE); 68628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 687251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } else { 688251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey summary.setVisibility(View.INVISIBLE); 689251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 690b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 691b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 6925dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (docLastModified == -1) { 6939d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey date.setText(null); 6949d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 6955dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey date.setText(formatTime(context, docLastModified)); 69628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 6979d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 698b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 699b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (state.showSize) { 700b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.VISIBLE); 7015dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType) || docSize == -1) { 702b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setText(null); 703b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 7045dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey size.setText(Formatter.formatFileSize(context, docSize)); 70528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 706b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 707b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 708b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.GONE); 70954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 710ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 71128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE); 71228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 7133f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final boolean enabled = Document.MIME_TYPE_DIR.equals(docMimeType) 7143f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey || MimePredicate.mimeMatches(state.acceptMimes, docMimeType); 7153f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (enabled) { 7163f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(convertView, true); 7173f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey icon.setAlpha(1f); 7183f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey icon1.setAlpha(1f); 7193f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } else { 7203f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(convertView, false); 7213f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey icon.setAlpha(0.5f); 7223f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey icon1.setAlpha(0.5f); 7233f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 7243f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 725ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey return convertView; 72654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 72754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 728ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 729ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public int getCount() { 730954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursorCount + mFooters.size(); 731ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 7329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 733ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 7345dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public Cursor getItem(int position) { 735954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 7365dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor.moveToPosition(position); 737954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursor; 738954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 739954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return null; 7405dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 741ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 74254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 743ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 744ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public long getItemId(int position) { 7455dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return position; 746ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 747954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 748954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 7493f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey public int getViewTypeCount() { 7503f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return 4; 7513f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 7523f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 7533f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey @Override 754954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public int getItemViewType(int position) { 755954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 756954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return 0; 757954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 7583f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey position -= mCursorCount; 7593f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey return mFooters.get(position).getItemViewType(); 760954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 761954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 7629e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 7639d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7649d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> { 7659d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private final ImageView mTarget; 7664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private final Point mThumbSize; 7679d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7684eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public ThumbnailAsyncTask(ImageView target, Point thumbSize) { 7699d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mTarget = target; 7704eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mThumbSize = thumbSize; 7719d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7729d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7739d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 7749d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected void onPreExecute() { 7759d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mTarget.setTag(this); 7769d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7779d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7789d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 7799d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected Bitmap doInBackground(Uri... params) { 7809d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final Context context = mTarget.getContext(); 7819d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final Uri uri = params[0]; 7829d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7839d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Bitmap result = null; 7849d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey try { 785ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey result = DocumentsContract.getDocumentThumbnail( 786ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey context.getContentResolver(), uri, mThumbSize, null); 7879d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (result != null) { 7884eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 7894eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 7904eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey thumbs.put(uri, result); 7919d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7929d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } catch (Exception e) { 7939d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Log.w(TAG, "Failed to load thumbnail: " + e); 7949d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7959d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return result; 7969d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7979d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7989d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 7999d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected void onPostExecute(Bitmap result) { 8009d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (mTarget.getTag() == this) { 8019d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mTarget.setImageBitmap(result); 8029d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mTarget.setTag(null); 8039d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 8049d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 8059d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 8069d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 8079d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static String formatTime(Context context, long when) { 8089d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey // TODO: DateUtils should make this easier 8099d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time then = new Time(); 8109d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey then.set(when); 8119d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time now = new Time(); 8129d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey now.setToNow(); 8139d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 8149d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT 8159d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey | DateUtils.FORMAT_ABBREV_ALL; 8169d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 8179d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (then.year != now.year) { 8189d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE; 8199d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else if (then.yearDay != now.yearDay) { 8209d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_DATE; 8219d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 8229d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_TIME; 8239d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 8249d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 8259d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return DateUtils.formatDateTime(context, when, flags); 8269d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 827b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 828b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private String findCommonMimeType(List<String> mimeTypes) { 829b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] commonType = mimeTypes.get(0).split("/"); 830b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (commonType.length != 2) { 831b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return "*/*"; 832b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 833b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 834b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (int i = 1; i < mimeTypes.size(); i++) { 835b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] type = mimeTypes.get(i).split("/"); 836b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (type.length != 2) continue; 837b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 838b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[1].equals(type[1])) { 839b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 840b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 841b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 842b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[0].equals(type[0])) { 843b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[0] = "*"; 844b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 845b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey break; 846b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 847b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 848b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 849b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return commonType[0] + "/" + commonType[1]; 850b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 8513f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 8523f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private void setEnabledRecursive(View v, boolean enabled) { 8533f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (v.isEnabled() == enabled) return; 8543f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey v.setEnabled(enabled); 8553f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 8563f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey if (v instanceof ViewGroup) { 8573f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final ViewGroup vg = (ViewGroup) v; 8583f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey for (int i = vg.getChildCount() - 1; i >= 0; i--) { 8593f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey setEnabledRecursive(vg.getChildAt(i), enabled); 8603f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 8613f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 8623f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 8639e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey} 864