Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -20796,6 +20796,7 @@ package android.provider { field public static final java.lang.String COLUMN_SIZE = "_size"; field public static final java.lang.String COLUMN_SUMMARY = "summary"; field public static final int FLAG_DIR_PREFERS_GRID = 32; // 0x20 field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 64; // 0x40 field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8 field public static final int FLAG_DIR_SUPPORTS_SEARCH = 16; // 0x10 field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4 core/java/android/provider/DocumentsContract.java +9 −3 Original line number Diff line number Diff line Loading @@ -251,6 +251,15 @@ public final class DocumentsContract { * @see #COLUMN_FLAGS */ public static final int FLAG_DIR_PREFERS_GRID = 1 << 5; /** * Flag indicating that a directory prefers its contents be sorted by * {@link #COLUMN_LAST_MODIFIED}. Only valid when * {@link #COLUMN_MIME_TYPE} is {@link #MIME_TYPE_DIR}. * * @see #COLUMN_FLAGS */ public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 1 << 6; } /** Loading Loading @@ -292,9 +301,6 @@ public final class DocumentsContract { * @see #FLAG_LOCAL_ONLY * @see #FLAG_SUPPORTS_CREATE * @see #FLAG_ADVANCED * @see #FLAG_PROVIDES_AUDIO * @see #FLAG_PROVIDES_IMAGES * @see #FLAG_PROVIDES_VIDEO */ public static final String COLUMN_FLAGS = "flags"; Loading packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java +1 −1 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ public class CreateDirectoryFragment extends DialogFragment { try { final Uri childUri = DocumentsContract.createDocument( resolver, cwd.uri, Document.MIME_TYPE_DIR, displayName); resolver, cwd.derivedUri, Document.MIME_TYPE_DIR, displayName); // Navigate into newly created child final DocumentInfo childDoc = DocumentInfo.fromUri(resolver, childUri); Loading packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +64 −41 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static com.android.documentsui.DocumentsActivity.TAG; import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE; import static com.android.documentsui.DocumentsActivity.State.MODE_GRID; import static com.android.documentsui.DocumentsActivity.State.MODE_LIST; import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN; import static com.android.documentsui.model.DocumentInfo.getCursorInt; import static com.android.documentsui.model.DocumentInfo.getCursorLong; import static com.android.documentsui.model.DocumentInfo.getCursorString; Loading Loading @@ -91,43 +93,42 @@ public class DirectoryFragment extends Fragment { private int mType = TYPE_NORMAL; private int mLastMode = MODE_UNKNOWN; private int mLastSortOrder = SORT_ORDER_UNKNOWN; private Point mThumbSize; private DocumentsAdapter mAdapter; private LoaderCallbacks<DirectoryResult> mCallbacks; private static final String EXTRA_TYPE = "type"; private static final String EXTRA_AUTHORITY = "authority"; private static final String EXTRA_ROOT_ID = "rootId"; private static final String EXTRA_DOC_ID = "docId"; private static final String EXTRA_ROOT = "root"; private static final String EXTRA_DOC = "doc"; private static final String EXTRA_QUERY = "query"; private static AtomicInteger sLoaderId = new AtomicInteger(4000); private int mLastSortOrder = -1; private final int mLoaderId = sLoaderId.incrementAndGet(); public static void showNormal(FragmentManager fm, Uri uri) { show(fm, TYPE_NORMAL, uri.getAuthority(), null, DocumentsContract.getDocumentId(uri), null); public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc) { show(fm, TYPE_NORMAL, root, doc, null); } public static void showSearch(FragmentManager fm, Uri uri, String query) { show(fm, TYPE_SEARCH, uri.getAuthority(), null, DocumentsContract.getDocumentId(uri), query); public static void showSearch( FragmentManager fm, RootInfo root, DocumentInfo doc, String query) { show(fm, TYPE_SEARCH, root, doc, query); } public static void showRecentsOpen(FragmentManager fm) { show(fm, TYPE_RECENT_OPEN, null, null, null, null); show(fm, TYPE_RECENT_OPEN, null, null, null); } private static void show(FragmentManager fm, int type, String authority, String rootId, String docId, String query) { private static void show( FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query) { final Bundle args = new Bundle(); args.putInt(EXTRA_TYPE, type); args.putString(EXTRA_AUTHORITY, authority); args.putString(EXTRA_ROOT_ID, rootId); args.putString(EXTRA_DOC_ID, docId); args.putParcelable(EXTRA_ROOT, root); args.putParcelable(EXTRA_DOC, doc); args.putString(EXTRA_QUERY, query); final DirectoryFragment fragment = new DirectoryFragment(); Loading Loading @@ -167,6 +168,7 @@ public class DirectoryFragment extends Fragment { super.onActivityCreated(savedInstanceState); final Context context = getActivity(); final State state = getDisplayState(DirectoryFragment.this); mAdapter = new DocumentsAdapter(); mType = getArguments().getInt(EXTRA_TYPE); Loading @@ -174,35 +176,48 @@ public class DirectoryFragment extends Fragment { mCallbacks = new LoaderCallbacks<DirectoryResult>() { @Override public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { final State state = getDisplayState(DirectoryFragment.this); final String authority = getArguments().getString(EXTRA_AUTHORITY); final String rootId = getArguments().getString(EXTRA_ROOT_ID); final String docId = getArguments().getString(EXTRA_DOC_ID); final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); final String query = getArguments().getString(EXTRA_QUERY); Uri contentsUri; switch (mType) { case TYPE_NORMAL: contentsUri = DocumentsContract.buildChildDocumentsUri(authority, docId); return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder); contentsUri = DocumentsContract.buildChildDocumentsUri( doc.authority, doc.documentId); return new DirectoryLoader(context, root, doc, contentsUri); case TYPE_SEARCH: contentsUri = DocumentsContract.buildSearchDocumentsUri( authority, docId, query); return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder); doc.authority, doc.documentId, query); return new DirectoryLoader(context, root, doc, contentsUri); case TYPE_RECENT_OPEN: final RootsCache roots = DocumentsApplication.getRootsCache(context); final List<RootInfo> matchingRoots = roots.getMatchingRoots(state); return new RecentLoader(context, matchingRoots); return new RecentLoader(context, matchingRoots, state.acceptMimes); default: throw new IllegalStateException("Unknown type " + mType); } } @Override public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { if (!isAdded()) return; mAdapter.swapCursor(result.cursor); // Push latest state up to UI // TODO: if mode change was racing with us, don't overwrite it state.mode = result.mode; state.sortOrder = result.sortOrder; ((DocumentsActivity) context).onStateChanged(); updateDisplayState(); if (mLastSortOrder != result.sortOrder) { mLastSortOrder = result.sortOrder; mListView.smoothScrollToPosition(0); mGridView.smoothScrollToPosition(0); } } @Override Loading @@ -211,6 +226,9 @@ public class DirectoryFragment extends Fragment { } }; // Kick off loader at least once getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); updateDisplayState(); } Loading @@ -220,22 +238,27 @@ public class DirectoryFragment extends Fragment { updateDisplayState(); } public void updateDisplayState() { final State state = getDisplayState(this); if (mLastSortOrder != state.sortOrder) { public void onUserSortOrderChanged() { // User change always triggers reload getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); mLastSortOrder = state.sortOrder; } mListView.smoothScrollToPosition(0); mGridView.smoothScrollToPosition(0); public void onUserModeChanged() { // Mode change is just display; no need to reload updateDisplayState(); } mListView.setVisibility(state.mode == MODE_LIST ? View.VISIBLE : View.GONE); mGridView.setVisibility(state.mode == MODE_GRID ? View.VISIBLE : View.GONE); private void updateDisplayState() { final State state = getDisplayState(this); mFilter = new MimePredicate(state.acceptMimes); if (mLastMode == state.mode) return; mLastMode = state.mode; mListView.setVisibility(state.mode == MODE_LIST ? View.VISIBLE : View.GONE); mGridView.setVisibility(state.mode == MODE_GRID ? View.VISIBLE : View.GONE); final int choiceMode; if (state.allowMultiple) { choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL; Loading @@ -254,14 +277,14 @@ public class DirectoryFragment extends Fragment { mGridView.setChoiceMode(choiceMode); mCurrentView = mGridView; } else if (state.mode == MODE_LIST) { thumbSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size); thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size); mGridView.setAdapter(null); mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE); mListView.setAdapter(mAdapter); mListView.setChoiceMode(choiceMode); mCurrentView = mListView; } else { throw new IllegalStateException(); throw new IllegalStateException("Unknown state " + state.mode); } mThumbSize = new Point(thumbSize, thumbSize); Loading Loading @@ -366,7 +389,7 @@ public class DirectoryFragment extends Fragment { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setType(doc.mimeType); intent.putExtra(Intent.EXTRA_STREAM, doc.uri); intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri); } else if (docs.size() > 1) { intent = new Intent(Intent.ACTION_SEND_MULTIPLE); Loading @@ -377,7 +400,7 @@ public class DirectoryFragment extends Fragment { final ArrayList<Uri> uris = Lists.newArrayList(); for (DocumentInfo doc : docs) { mimeTypes.add(doc.mimeType); uris.add(doc.uri); uris.add(doc.derivedUri); } intent.setType(findCommonMimeType(mimeTypes)); Loading @@ -403,7 +426,7 @@ public class DirectoryFragment extends Fragment { continue; } if (!DocumentsContract.deleteDocument(resolver, doc.uri)) { if (!DocumentsContract.deleteDocument(resolver, doc.derivedUri)) { Log.w(TAG, "Failed to delete " + doc); hadTrouble = true; } Loading packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java +72 −12 Original line number Diff line number Diff line Loading @@ -16,18 +16,29 @@ package com.android.documentsui; import static com.android.documentsui.DocumentsActivity.TAG; import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_DISPLAY_NAME; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_SIZE; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN; import static com.android.documentsui.model.DocumentInfo.getCursorInt; import android.content.AsyncTaskLoader; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.CancellationSignal; import android.os.OperationCanceledException; import android.provider.DocumentsContract.Document; import android.util.Log; import com.android.documentsui.DocumentsActivity.State; import com.android.documentsui.RecentsProvider.StateColumns; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; import libcore.io.IoUtils; Loading @@ -36,6 +47,9 @@ class DirectoryResult implements AutoCloseable { Cursor cursor; Exception exception; int mode = MODE_UNKNOWN; int sortOrder = SORT_ORDER_UNKNOWN; @Override public void close() { IoUtils.closeQuietly(cursor); Loading @@ -48,18 +62,18 @@ class DirectoryResult implements AutoCloseable { public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver(); private final String mRootId; private final RootInfo mRoot; private final DocumentInfo mDoc; private final Uri mUri; private final int mSortOrder; private CancellationSignal mSignal; private DirectoryResult mResult; public DirectoryLoader(Context context, String rootId, Uri uri, int sortOrder) { public DirectoryLoader(Context context, RootInfo root, DocumentInfo doc, Uri uri) { super(context); mRootId = rootId; mRoot = root; mDoc = doc; mUri = uri; mSortOrder = sortOrder; } @Override Loading @@ -70,20 +84,65 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { } mSignal = new CancellationSignal(); } final DirectoryResult result = new DirectoryResult(); final ContentResolver resolver = getContext().getContentResolver(); final String authority = mUri.getAuthority(); final DirectoryResult result = new DirectoryResult(); int userMode = State.MODE_UNKNOWN; int userSortOrder = State.SORT_ORDER_UNKNOWN; // Pick up any custom modes requested by user Cursor cursor = null; try { final Uri stateUri = RecentsProvider.buildState( mRoot.authority, mRoot.rootId, mDoc.documentId); cursor = resolver.query(stateUri, null, null, null, null); if (cursor.moveToFirst()) { userMode = getCursorInt(cursor, StateColumns.MODE); userSortOrder = getCursorInt(cursor, StateColumns.SORT_ORDER); } } finally { IoUtils.closeQuietly(cursor); } if (userMode != State.MODE_UNKNOWN) { result.mode = userMode; } else { if ((mDoc.flags & Document.FLAG_DIR_PREFERS_GRID) != 0) { result.mode = State.MODE_GRID; } else { result.mode = State.MODE_LIST; } } if (userSortOrder != State.SORT_ORDER_UNKNOWN) { result.sortOrder = userSortOrder; } else { if ((mDoc.flags & Document.FLAG_DIR_PREFERS_LAST_MODIFIED) != 0) { result.sortOrder = State.SORT_ORDER_LAST_MODIFIED; } else { result.sortOrder = State.SORT_ORDER_DISPLAY_NAME; } } Log.d(TAG, "userMode=" + userMode + ", userSortOrder=" + userSortOrder + " --> mode=" + result.mode + ", sortOrder=" + result.sortOrder); try { result.client = getContext() .getContentResolver().acquireUnstableContentProviderClient(authority); final Cursor cursor = result.client.query( mUri, null, null, null, getQuerySortOrder(mSortOrder), mSignal); result.client = resolver.acquireUnstableContentProviderClient(authority); cursor = result.client.query( mUri, null, null, null, getQuerySortOrder(result.sortOrder), mSignal); cursor.registerContentObserver(mObserver); final Cursor withRoot = new RootCursorWrapper(mUri.getAuthority(), mRootId, cursor, -1); final Cursor sorted = new SortingCursorWrapper(withRoot, mSortOrder); final Cursor withRoot = new RootCursorWrapper( mUri.getAuthority(), mRoot.rootId, cursor, -1); final Cursor sorted = new SortingCursorWrapper(withRoot, result.sortOrder); result.cursor = sorted; } catch (Exception e) { Log.d(TAG, "Failed to query", e); result.exception = e; ContentProviderClient.closeQuietly(result.client); } finally { Loading @@ -91,6 +150,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { mSignal = null; } } return result; } Loading Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -20796,6 +20796,7 @@ package android.provider { field public static final java.lang.String COLUMN_SIZE = "_size"; field public static final java.lang.String COLUMN_SUMMARY = "summary"; field public static final int FLAG_DIR_PREFERS_GRID = 32; // 0x20 field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 64; // 0x40 field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8 field public static final int FLAG_DIR_SUPPORTS_SEARCH = 16; // 0x10 field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
core/java/android/provider/DocumentsContract.java +9 −3 Original line number Diff line number Diff line Loading @@ -251,6 +251,15 @@ public final class DocumentsContract { * @see #COLUMN_FLAGS */ public static final int FLAG_DIR_PREFERS_GRID = 1 << 5; /** * Flag indicating that a directory prefers its contents be sorted by * {@link #COLUMN_LAST_MODIFIED}. Only valid when * {@link #COLUMN_MIME_TYPE} is {@link #MIME_TYPE_DIR}. * * @see #COLUMN_FLAGS */ public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 1 << 6; } /** Loading Loading @@ -292,9 +301,6 @@ public final class DocumentsContract { * @see #FLAG_LOCAL_ONLY * @see #FLAG_SUPPORTS_CREATE * @see #FLAG_ADVANCED * @see #FLAG_PROVIDES_AUDIO * @see #FLAG_PROVIDES_IMAGES * @see #FLAG_PROVIDES_VIDEO */ public static final String COLUMN_FLAGS = "flags"; Loading
packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java +1 −1 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ public class CreateDirectoryFragment extends DialogFragment { try { final Uri childUri = DocumentsContract.createDocument( resolver, cwd.uri, Document.MIME_TYPE_DIR, displayName); resolver, cwd.derivedUri, Document.MIME_TYPE_DIR, displayName); // Navigate into newly created child final DocumentInfo childDoc = DocumentInfo.fromUri(resolver, childUri); Loading
packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +64 −41 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static com.android.documentsui.DocumentsActivity.TAG; import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE; import static com.android.documentsui.DocumentsActivity.State.MODE_GRID; import static com.android.documentsui.DocumentsActivity.State.MODE_LIST; import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN; import static com.android.documentsui.model.DocumentInfo.getCursorInt; import static com.android.documentsui.model.DocumentInfo.getCursorLong; import static com.android.documentsui.model.DocumentInfo.getCursorString; Loading Loading @@ -91,43 +93,42 @@ public class DirectoryFragment extends Fragment { private int mType = TYPE_NORMAL; private int mLastMode = MODE_UNKNOWN; private int mLastSortOrder = SORT_ORDER_UNKNOWN; private Point mThumbSize; private DocumentsAdapter mAdapter; private LoaderCallbacks<DirectoryResult> mCallbacks; private static final String EXTRA_TYPE = "type"; private static final String EXTRA_AUTHORITY = "authority"; private static final String EXTRA_ROOT_ID = "rootId"; private static final String EXTRA_DOC_ID = "docId"; private static final String EXTRA_ROOT = "root"; private static final String EXTRA_DOC = "doc"; private static final String EXTRA_QUERY = "query"; private static AtomicInteger sLoaderId = new AtomicInteger(4000); private int mLastSortOrder = -1; private final int mLoaderId = sLoaderId.incrementAndGet(); public static void showNormal(FragmentManager fm, Uri uri) { show(fm, TYPE_NORMAL, uri.getAuthority(), null, DocumentsContract.getDocumentId(uri), null); public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc) { show(fm, TYPE_NORMAL, root, doc, null); } public static void showSearch(FragmentManager fm, Uri uri, String query) { show(fm, TYPE_SEARCH, uri.getAuthority(), null, DocumentsContract.getDocumentId(uri), query); public static void showSearch( FragmentManager fm, RootInfo root, DocumentInfo doc, String query) { show(fm, TYPE_SEARCH, root, doc, query); } public static void showRecentsOpen(FragmentManager fm) { show(fm, TYPE_RECENT_OPEN, null, null, null, null); show(fm, TYPE_RECENT_OPEN, null, null, null); } private static void show(FragmentManager fm, int type, String authority, String rootId, String docId, String query) { private static void show( FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query) { final Bundle args = new Bundle(); args.putInt(EXTRA_TYPE, type); args.putString(EXTRA_AUTHORITY, authority); args.putString(EXTRA_ROOT_ID, rootId); args.putString(EXTRA_DOC_ID, docId); args.putParcelable(EXTRA_ROOT, root); args.putParcelable(EXTRA_DOC, doc); args.putString(EXTRA_QUERY, query); final DirectoryFragment fragment = new DirectoryFragment(); Loading Loading @@ -167,6 +168,7 @@ public class DirectoryFragment extends Fragment { super.onActivityCreated(savedInstanceState); final Context context = getActivity(); final State state = getDisplayState(DirectoryFragment.this); mAdapter = new DocumentsAdapter(); mType = getArguments().getInt(EXTRA_TYPE); Loading @@ -174,35 +176,48 @@ public class DirectoryFragment extends Fragment { mCallbacks = new LoaderCallbacks<DirectoryResult>() { @Override public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { final State state = getDisplayState(DirectoryFragment.this); final String authority = getArguments().getString(EXTRA_AUTHORITY); final String rootId = getArguments().getString(EXTRA_ROOT_ID); final String docId = getArguments().getString(EXTRA_DOC_ID); final RootInfo root = getArguments().getParcelable(EXTRA_ROOT); final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC); final String query = getArguments().getString(EXTRA_QUERY); Uri contentsUri; switch (mType) { case TYPE_NORMAL: contentsUri = DocumentsContract.buildChildDocumentsUri(authority, docId); return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder); contentsUri = DocumentsContract.buildChildDocumentsUri( doc.authority, doc.documentId); return new DirectoryLoader(context, root, doc, contentsUri); case TYPE_SEARCH: contentsUri = DocumentsContract.buildSearchDocumentsUri( authority, docId, query); return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder); doc.authority, doc.documentId, query); return new DirectoryLoader(context, root, doc, contentsUri); case TYPE_RECENT_OPEN: final RootsCache roots = DocumentsApplication.getRootsCache(context); final List<RootInfo> matchingRoots = roots.getMatchingRoots(state); return new RecentLoader(context, matchingRoots); return new RecentLoader(context, matchingRoots, state.acceptMimes); default: throw new IllegalStateException("Unknown type " + mType); } } @Override public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { if (!isAdded()) return; mAdapter.swapCursor(result.cursor); // Push latest state up to UI // TODO: if mode change was racing with us, don't overwrite it state.mode = result.mode; state.sortOrder = result.sortOrder; ((DocumentsActivity) context).onStateChanged(); updateDisplayState(); if (mLastSortOrder != result.sortOrder) { mLastSortOrder = result.sortOrder; mListView.smoothScrollToPosition(0); mGridView.smoothScrollToPosition(0); } } @Override Loading @@ -211,6 +226,9 @@ public class DirectoryFragment extends Fragment { } }; // Kick off loader at least once getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); updateDisplayState(); } Loading @@ -220,22 +238,27 @@ public class DirectoryFragment extends Fragment { updateDisplayState(); } public void updateDisplayState() { final State state = getDisplayState(this); if (mLastSortOrder != state.sortOrder) { public void onUserSortOrderChanged() { // User change always triggers reload getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); mLastSortOrder = state.sortOrder; } mListView.smoothScrollToPosition(0); mGridView.smoothScrollToPosition(0); public void onUserModeChanged() { // Mode change is just display; no need to reload updateDisplayState(); } mListView.setVisibility(state.mode == MODE_LIST ? View.VISIBLE : View.GONE); mGridView.setVisibility(state.mode == MODE_GRID ? View.VISIBLE : View.GONE); private void updateDisplayState() { final State state = getDisplayState(this); mFilter = new MimePredicate(state.acceptMimes); if (mLastMode == state.mode) return; mLastMode = state.mode; mListView.setVisibility(state.mode == MODE_LIST ? View.VISIBLE : View.GONE); mGridView.setVisibility(state.mode == MODE_GRID ? View.VISIBLE : View.GONE); final int choiceMode; if (state.allowMultiple) { choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL; Loading @@ -254,14 +277,14 @@ public class DirectoryFragment extends Fragment { mGridView.setChoiceMode(choiceMode); mCurrentView = mGridView; } else if (state.mode == MODE_LIST) { thumbSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size); thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size); mGridView.setAdapter(null); mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE); mListView.setAdapter(mAdapter); mListView.setChoiceMode(choiceMode); mCurrentView = mListView; } else { throw new IllegalStateException(); throw new IllegalStateException("Unknown state " + state.mode); } mThumbSize = new Point(thumbSize, thumbSize); Loading Loading @@ -366,7 +389,7 @@ public class DirectoryFragment extends Fragment { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setType(doc.mimeType); intent.putExtra(Intent.EXTRA_STREAM, doc.uri); intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri); } else if (docs.size() > 1) { intent = new Intent(Intent.ACTION_SEND_MULTIPLE); Loading @@ -377,7 +400,7 @@ public class DirectoryFragment extends Fragment { final ArrayList<Uri> uris = Lists.newArrayList(); for (DocumentInfo doc : docs) { mimeTypes.add(doc.mimeType); uris.add(doc.uri); uris.add(doc.derivedUri); } intent.setType(findCommonMimeType(mimeTypes)); Loading @@ -403,7 +426,7 @@ public class DirectoryFragment extends Fragment { continue; } if (!DocumentsContract.deleteDocument(resolver, doc.uri)) { if (!DocumentsContract.deleteDocument(resolver, doc.derivedUri)) { Log.w(TAG, "Failed to delete " + doc); hadTrouble = true; } Loading
packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java +72 −12 Original line number Diff line number Diff line Loading @@ -16,18 +16,29 @@ package com.android.documentsui; import static com.android.documentsui.DocumentsActivity.TAG; import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_DISPLAY_NAME; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_SIZE; import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN; import static com.android.documentsui.model.DocumentInfo.getCursorInt; import android.content.AsyncTaskLoader; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.CancellationSignal; import android.os.OperationCanceledException; import android.provider.DocumentsContract.Document; import android.util.Log; import com.android.documentsui.DocumentsActivity.State; import com.android.documentsui.RecentsProvider.StateColumns; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; import libcore.io.IoUtils; Loading @@ -36,6 +47,9 @@ class DirectoryResult implements AutoCloseable { Cursor cursor; Exception exception; int mode = MODE_UNKNOWN; int sortOrder = SORT_ORDER_UNKNOWN; @Override public void close() { IoUtils.closeQuietly(cursor); Loading @@ -48,18 +62,18 @@ class DirectoryResult implements AutoCloseable { public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver(); private final String mRootId; private final RootInfo mRoot; private final DocumentInfo mDoc; private final Uri mUri; private final int mSortOrder; private CancellationSignal mSignal; private DirectoryResult mResult; public DirectoryLoader(Context context, String rootId, Uri uri, int sortOrder) { public DirectoryLoader(Context context, RootInfo root, DocumentInfo doc, Uri uri) { super(context); mRootId = rootId; mRoot = root; mDoc = doc; mUri = uri; mSortOrder = sortOrder; } @Override Loading @@ -70,20 +84,65 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { } mSignal = new CancellationSignal(); } final DirectoryResult result = new DirectoryResult(); final ContentResolver resolver = getContext().getContentResolver(); final String authority = mUri.getAuthority(); final DirectoryResult result = new DirectoryResult(); int userMode = State.MODE_UNKNOWN; int userSortOrder = State.SORT_ORDER_UNKNOWN; // Pick up any custom modes requested by user Cursor cursor = null; try { final Uri stateUri = RecentsProvider.buildState( mRoot.authority, mRoot.rootId, mDoc.documentId); cursor = resolver.query(stateUri, null, null, null, null); if (cursor.moveToFirst()) { userMode = getCursorInt(cursor, StateColumns.MODE); userSortOrder = getCursorInt(cursor, StateColumns.SORT_ORDER); } } finally { IoUtils.closeQuietly(cursor); } if (userMode != State.MODE_UNKNOWN) { result.mode = userMode; } else { if ((mDoc.flags & Document.FLAG_DIR_PREFERS_GRID) != 0) { result.mode = State.MODE_GRID; } else { result.mode = State.MODE_LIST; } } if (userSortOrder != State.SORT_ORDER_UNKNOWN) { result.sortOrder = userSortOrder; } else { if ((mDoc.flags & Document.FLAG_DIR_PREFERS_LAST_MODIFIED) != 0) { result.sortOrder = State.SORT_ORDER_LAST_MODIFIED; } else { result.sortOrder = State.SORT_ORDER_DISPLAY_NAME; } } Log.d(TAG, "userMode=" + userMode + ", userSortOrder=" + userSortOrder + " --> mode=" + result.mode + ", sortOrder=" + result.sortOrder); try { result.client = getContext() .getContentResolver().acquireUnstableContentProviderClient(authority); final Cursor cursor = result.client.query( mUri, null, null, null, getQuerySortOrder(mSortOrder), mSignal); result.client = resolver.acquireUnstableContentProviderClient(authority); cursor = result.client.query( mUri, null, null, null, getQuerySortOrder(result.sortOrder), mSignal); cursor.registerContentObserver(mObserver); final Cursor withRoot = new RootCursorWrapper(mUri.getAuthority(), mRootId, cursor, -1); final Cursor sorted = new SortingCursorWrapper(withRoot, mSortOrder); final Cursor withRoot = new RootCursorWrapper( mUri.getAuthority(), mRoot.rootId, cursor, -1); final Cursor sorted = new SortingCursorWrapper(withRoot, result.sortOrder); result.cursor = sorted; } catch (Exception e) { Log.d(TAG, "Failed to query", e); result.exception = e; ContentProviderClient.closeQuietly(result.client); } finally { Loading @@ -91,6 +150,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { mSignal = null; } } return result; } Loading