Sort order is sticky for session, back leaves.
Instead of persisting sort order per-directory, the order is now
sticky for that session. Any user selected sort order takes
precedence over an ordering hinted by a backend.
When a restored DocumentStack is untouched, the back key now leaves
the dialog, instead of popping from the restored stack.
Persist list/grid mode changes async.
Bug: 10659604, 10672973
Change-Id: I9f022a081c014537447c9c2af10e19d8cd9566aa
diff --git a/src/com/android/documentsui/DirectoryFragment.java b/src/com/android/documentsui/DirectoryFragment.java
index f9ac3f3..45f028d 100644
--- a/src/com/android/documentsui/DirectoryFragment.java
+++ b/src/com/android/documentsui/DirectoryFragment.java
@@ -31,6 +31,7 @@
import android.app.FragmentTransaction;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentResolver;
+import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
@@ -65,6 +66,7 @@
import android.widget.Toast;
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 com.android.internal.util.Predicate;
@@ -190,11 +192,13 @@
case TYPE_NORMAL:
contentsUri = DocumentsContract.buildChildDocumentsUri(
doc.authority, doc.documentId);
- return new DirectoryLoader(context, root, doc, contentsUri);
+ return new DirectoryLoader(
+ context, root, doc, contentsUri, state.userSortOrder);
case TYPE_SEARCH:
contentsUri = DocumentsContract.buildSearchDocumentsUri(
doc.authority, doc.documentId, query);
- return new DirectoryLoader(context, root, doc, contentsUri);
+ return new DirectoryLoader(
+ context, root, doc, contentsUri, state.userSortOrder);
case TYPE_RECENT_OPEN:
final RootsCache roots = DocumentsApplication.getRootsCache(context);
final List<RootInfo> matchingRoots = roots.getMatchingRoots(state);
@@ -212,14 +216,14 @@
// 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;
+ state.derivedMode = result.mode;
+ state.derivedSortOrder = result.sortOrder;
((DocumentsActivity) context).onStateChanged();
updateDisplayState();
- if (mLastSortOrder != result.sortOrder) {
- mLastSortOrder = result.sortOrder;
+ if (mLastSortOrder != state.derivedSortOrder) {
+ mLastSortOrder = state.derivedSortOrder;
mListView.smoothScrollToPosition(0);
mGridView.smoothScrollToPosition(0);
}
@@ -244,12 +248,36 @@
}
public void onUserSortOrderChanged() {
- // User change always triggers reload
+ // Sort order change always triggers reload; we'll trigger state change
+ // on the flip side.
getLoaderManager().restartLoader(mLoaderId, null, mCallbacks);
}
public void onUserModeChanged() {
- // Mode change is just display; no need to reload
+ final ContentResolver resolver = getActivity().getContentResolver();
+ final State state = getDisplayState(this);
+
+ final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
+ final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+
+ final Uri stateUri = RecentsProvider.buildState(
+ root.authority, root.rootId, doc.documentId);
+ final ContentValues values = new ContentValues();
+ values.put(StateColumns.MODE, state.userMode);
+
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ resolver.insert(stateUri, values);
+ return null;
+ }
+ }.execute();
+
+ // Mode change is just visual change; no need to kick loader, and
+ // deliver change event immediately.
+ state.derivedMode = state.userMode;
+ ((DocumentsActivity) getActivity()).onStateChanged();
+
updateDisplayState();
}
@@ -258,11 +286,11 @@
mFilter = new MimePredicate(state.acceptMimes);
- if (mLastMode == state.mode) return;
- mLastMode = state.mode;
+ if (mLastMode == state.derivedMode) return;
+ mLastMode = state.derivedMode;
- mListView.setVisibility(state.mode == MODE_LIST ? View.VISIBLE : View.GONE);
- mGridView.setVisibility(state.mode == MODE_GRID ? View.VISIBLE : View.GONE);
+ mListView.setVisibility(state.derivedMode == MODE_LIST ? View.VISIBLE : View.GONE);
+ mGridView.setVisibility(state.derivedMode == MODE_GRID ? View.VISIBLE : View.GONE);
final int choiceMode;
if (state.allowMultiple) {
@@ -272,7 +300,7 @@
}
final int thumbSize;
- if (state.mode == MODE_GRID) {
+ if (state.derivedMode == MODE_GRID) {
thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width);
mListView.setAdapter(null);
mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
@@ -281,7 +309,7 @@
mGridView.setNumColumns(GridView.AUTO_FIT);
mGridView.setChoiceMode(choiceMode);
mCurrentView = mGridView;
- } else if (state.mode == MODE_LIST) {
+ } else if (state.derivedMode == MODE_LIST) {
thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size);
mGridView.setAdapter(null);
mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE);
@@ -289,7 +317,7 @@
mListView.setChoiceMode(choiceMode);
mCurrentView = mListView;
} else {
- throw new IllegalStateException("Unknown state " + state.mode);
+ throw new IllegalStateException("Unknown state " + state.derivedMode);
}
mThumbSize = new Point(thumbSize, thumbSize);
@@ -505,9 +533,9 @@
if (convertView == null) {
final LayoutInflater inflater = LayoutInflater.from(context);
- if (state.mode == MODE_LIST) {
+ if (state.derivedMode == MODE_LIST) {
convertView = inflater.inflate(R.layout.item_message_list, parent, false);
- } else if (state.mode == MODE_GRID) {
+ } else if (state.derivedMode == MODE_GRID) {
convertView = inflater.inflate(R.layout.item_message_grid, parent, false);
} else {
throw new IllegalStateException();
@@ -582,9 +610,9 @@
if (convertView == null) {
final LayoutInflater inflater = LayoutInflater.from(context);
- if (state.mode == MODE_LIST) {
+ if (state.derivedMode == MODE_LIST) {
convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
- } else if (state.mode == MODE_GRID) {
+ } else if (state.derivedMode == MODE_GRID) {
convertView = inflater.inflate(R.layout.item_doc_grid, parent, false);
} else {
throw new IllegalStateException();
@@ -618,7 +646,7 @@
}
final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
- final boolean allowThumbnail = (state.mode == MODE_GRID)
+ final boolean allowThumbnail = (state.derivedMode == MODE_GRID)
|| MimePredicate.mimeMatches(LIST_THUMBNAIL_MIMES, docMimeType);
if (supportsThumbnail && allowThumbnail) {