diff options
author | Jeff Sharkey <jsharkey@android.com> | 2013-09-09 17:35:46 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2013-09-09 17:35:48 -0700 |
commit | fb3445c9b31c7f8401d6eec0606dabee366c8aad (patch) | |
tree | 95540ac1a3c64192787d5a1f5bd1fc4923050752 /packages | |
parent | 3f4c205fd3110345241e690f2a2e7c1b477eac76 (diff) | |
download | frameworks_base-fb3445c9b31c7f8401d6eec0606dabee366c8aad.zip frameworks_base-fb3445c9b31c7f8401d6eec0606dabee366c8aad.tar.gz frameworks_base-fb3445c9b31c7f8401d6eec0606dabee366c8aad.tar.bz2 |
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
Diffstat (limited to 'packages')
3 files changed, 86 insertions, 68 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java index f9ac3f3..45f028d 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java @@ -31,6 +31,7 @@ import android.app.FragmentManager; 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.TextView; 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 @@ public class DirectoryFragment extends Fragment { 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 @@ public class DirectoryFragment extends Fragment { // 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 class DirectoryFragment extends Fragment { } 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 @@ public class DirectoryFragment extends Fragment { 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 @@ public class DirectoryFragment extends Fragment { } 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 @@ public class DirectoryFragment extends Fragment { 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 @@ public class DirectoryFragment extends Fragment { 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 @@ public class DirectoryFragment extends Fragment { 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 @@ public class DirectoryFragment extends Fragment { 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 @@ public class DirectoryFragment extends Fragment { } 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) { diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java index 72dfa30..1471836 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java @@ -65,15 +65,18 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { private final RootInfo mRoot; private final DocumentInfo mDoc; private final Uri mUri; + private final int mUserSortOrder; private CancellationSignal mSignal; private DirectoryResult mResult; - public DirectoryLoader(Context context, RootInfo root, DocumentInfo doc, Uri uri) { + public DirectoryLoader( + Context context, RootInfo root, DocumentInfo doc, Uri uri, int userSortOrder) { super(context); mRoot = root; mDoc = doc; mUri = uri; + mUserSortOrder = userSortOrder; } @Override @@ -91,7 +94,6 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { 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; @@ -101,7 +103,6 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { 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); @@ -117,8 +118,8 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { } } - if (userSortOrder != State.SORT_ORDER_UNKNOWN) { - result.sortOrder = userSortOrder; + if (mUserSortOrder != State.SORT_ORDER_UNKNOWN) { + result.sortOrder = mUserSortOrder; } else { if ((mDoc.flags & Document.FLAG_DIR_PREFERS_LAST_MODIFIED) != 0) { result.sortOrder = State.SORT_ORDER_LAST_MODIFIED; @@ -127,7 +128,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { } } - Log.d(TAG, "userMode=" + userMode + ", userSortOrder=" + userSortOrder + " --> mode=" + Log.d(TAG, "userMode=" + userMode + ", userSortOrder=" + mUserSortOrder + " --> mode=" + result.mode + ", sortOrder=" + result.sortOrder); try { diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index fe39800..79d2443 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -171,10 +171,6 @@ public class DocumentsActivity extends Activity { mState.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(this); if (mState.action == ACTION_MANAGE) { - mState.sortOrder = SORT_ORDER_LAST_MODIFIED; - } - - if (mState.action == ACTION_MANAGE) { final Uri uri = intent.getData(); final String rootId = DocumentsContract.getRootId(uri); final RootInfo root = mRoots.getRoot(uri.getAuthority(), rootId); @@ -348,8 +344,8 @@ public class DocumentsActivity extends Activity { if (cwd != null) { sort.setVisible(true); - grid.setVisible(mState.mode != MODE_GRID); - list.setVisible(mState.mode != MODE_LIST); + grid.setVisible(mState.derivedMode != MODE_GRID); + list.setVisible(mState.derivedMode != MODE_LIST); } else { sort.setVisible(false); grid.setVisible(false); @@ -433,42 +429,25 @@ public class DocumentsActivity extends Activity { * Set state sort order based on explicit user action. */ private void setUserSortOrder(int sortOrder) { - final RootInfo root = getCurrentRoot(); - final DocumentInfo cwd = getCurrentDirectory(); - - // TODO: persist async, then trigger rebind - final Uri stateUri = RecentsProvider.buildState( - root.authority, root.rootId, cwd.documentId); - final ContentValues values = new ContentValues(); - values.put(StateColumns.SORT_ORDER, sortOrder); - getContentResolver().insert(stateUri, values); - + mState.userSortOrder = sortOrder; DirectoryFragment.get(getFragmentManager()).onUserSortOrderChanged(); - onStateChanged(); } /** * Set state mode based on explicit user action. */ private void setUserMode(int mode) { - final RootInfo root = getCurrentRoot(); - final DocumentInfo cwd = getCurrentDirectory(); - - // TODO: persist async, then trigger rebind - final Uri stateUri = RecentsProvider.buildState( - root.authority, root.rootId, cwd.documentId); - final ContentValues values = new ContentValues(); - values.put(StateColumns.MODE, mode); - getContentResolver().insert(stateUri, values); - - mState.mode = mode; - + mState.userMode = mode; DirectoryFragment.get(getFragmentManager()).onUserModeChanged(); - onStateChanged(); } @Override public void onBackPressed() { + if (!mState.stackTouched) { + super.onBackPressed(); + return; + } + final int size = mState.stack.size(); if (size > 1) { mState.stack.pop(); @@ -564,6 +543,7 @@ public class DocumentsActivity extends Activity { } while (mState.stack.size() > itemPosition + 1) { + mState.stackTouched = true; mState.stack.pop(); } onCurrentDirectoryChanged(); @@ -629,6 +609,7 @@ public class DocumentsActivity extends Activity { public void onStackPicked(DocumentStack stack) { mState.stack = stack; + mState.stackTouched = true; onCurrentDirectoryChanged(); } @@ -636,6 +617,7 @@ public class DocumentsActivity extends Activity { // Clear entire backstack and start in new root mState.stack.root = root; mState.stack.clear(); + mState.stackTouched = true; if (!mRoots.isRecentsRoot(root)) { try { @@ -664,13 +646,8 @@ public class DocumentsActivity extends Activity { public void onDocumentPicked(DocumentInfo doc) { final FragmentManager fm = getFragmentManager(); if (doc.isDirectory()) { - // TODO: query display mode user preference for this dir - if (doc.isGridPreferred()) { - mState.mode = MODE_GRID; - } else { - mState.mode = MODE_LIST; - } mState.stack.push(doc); + mState.stackTouched = true; onCurrentDirectoryChanged(); } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) { // Explicit file picked, return @@ -774,13 +751,23 @@ public class DocumentsActivity extends Activity { public static class State implements android.os.Parcelable { public int action; - public int mode = MODE_LIST; public String[] acceptMimes; - public int sortOrder = SORT_ORDER_DISPLAY_NAME; + + /** Explicit user choice */ + public int userMode = MODE_UNKNOWN; + /** Derived after loader */ + public int derivedMode = MODE_LIST; + + /** Explicit user choice */ + public int userSortOrder = SORT_ORDER_UNKNOWN; + /** Derived after loader */ + public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME; + public boolean allowMultiple = false; public boolean showSize = false; public boolean localOnly = false; public boolean showAdvanced = false; + public boolean stackTouched = false; /** Current user navigation stack; empty implies recents. */ public DocumentStack stack = new DocumentStack(); @@ -809,13 +796,14 @@ public class DocumentsActivity extends Activity { @Override public void writeToParcel(Parcel out, int flags) { out.writeInt(action); - out.writeInt(mode); + out.writeInt(userMode); out.writeStringArray(acceptMimes); - out.writeInt(sortOrder); + out.writeInt(userSortOrder); out.writeInt(allowMultiple ? 1 : 0); out.writeInt(showSize ? 1 : 0); out.writeInt(localOnly ? 1 : 0); out.writeInt(showAdvanced ? 1 : 0); + out.writeInt(stackTouched ? 1 : 0); DurableUtils.writeToParcel(out, stack); out.writeString(currentSearch); } @@ -825,13 +813,14 @@ public class DocumentsActivity extends Activity { public State createFromParcel(Parcel in) { final State state = new State(); state.action = in.readInt(); - state.mode = in.readInt(); + state.userMode = in.readInt(); state.acceptMimes = in.readStringArray(); - state.sortOrder = in.readInt(); + state.userSortOrder = in.readInt(); state.allowMultiple = in.readInt() != 0; state.showSize = in.readInt() != 0; state.localOnly = in.readInt() != 0; state.showAdvanced = in.readInt() != 0; + state.stackTouched = in.readInt() != 0; DurableUtils.readFromParcel(in, state.stack); state.currentSearch = in.readString(); return state; |