summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-09-24 12:07:12 -0700
committerJeff Sharkey <jsharkey@android.com>2013-09-24 12:57:47 -0700
commitdeffadeb7485e8660ecce12822e259d96fa06dce (patch)
tree9f0e2cac32a5a2df887259a4d18e425d23471847 /packages
parentb180a65d41adc731cbff1536c7ede15174bc08e1 (diff)
downloadframeworks_base-deffadeb7485e8660ecce12822e259d96fa06dce.zip
frameworks_base-deffadeb7485e8660ecce12822e259d96fa06dce.tar.gz
frameworks_base-deffadeb7485e8660ecce12822e259d96fa06dce.tar.bz2
Freshen restored stacks, more UX bug fixes.
When restoring a persisted stack, such as last location or a location where save occurred, freshen the DocumentStack to get the latest details from backend, and ensure the path is still valid. Filter Recent directories in create mode based on roots allowed by incoming request. Remember when user last picked an external app, and open drawer next time user launches for GET_CONTENT. Fix state list drawable ordering, and avoid clobbering Drawable callback when wrapping in InsetDrawable; tricksy hobbitses! Make grid items smaller to always fit two columns on phones. Draw grid items all the way to screen edge; don't clip to padding. Better error message when folder creation failed. Show Recents in grid mode when picking any visual content, not just images. Bug: 10846100, 10903211, 10898993, 10892808, 10892058, 10892009, 10885012 Change-Id: Ia0f88d911abc6ea03645d6fd3e04271c21d5936a
Diffstat (limited to 'packages')
-rw-r--r--packages/DocumentsUI/res/drawable/item_background.xml18
-rw-r--r--packages/DocumentsUI/res/layout/fragment_directory.xml1
-rw-r--r--packages/DocumentsUI/res/values/dimens.xml4
-rw-r--r--packages/DocumentsUI/res/values/strings.xml2
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java2
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java12
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java71
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java22
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java24
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/TestActivity.java27
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java56
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java25
12 files changed, 201 insertions, 63 deletions
diff --git a/packages/DocumentsUI/res/drawable/item_background.xml b/packages/DocumentsUI/res/drawable/item_background.xml
index 7447aa8..6fcab3c 100644
--- a/packages/DocumentsUI/res/drawable/item_background.xml
+++ b/packages/DocumentsUI/res/drawable/item_background.xml
@@ -16,18 +16,16 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:state_selected="true" android:drawable="@*android:drawable/list_selector_disabled_holo_light" />
- <item android:state_enabled="false" android:state_focused="true" android:drawable="@*android:drawable/list_selector_disabled_holo_light" />
- <item android:state_enabled="false" android:state_pressed="true" android:drawable="@*android:drawable/list_selector_disabled_holo_light" />
+ <item android:state_window_focused="false" android:drawable="@android:color/transparent" />
- <item android:state_activated="true" android:state_pressed="true" android:drawable="@*android:drawable/list_activated_holo" />
- <item android:state_activated="true" android:drawable="@*android:drawable/list_activated_holo" />
+ <item android:state_focused="true" android:state_activated="true" android:drawable="@*android:drawable/list_selected_holo_light" />
+ <item android:state_focused="false" android:state_activated="true" android:drawable="@*android:drawable/list_selected_holo_light" />
- <item android:state_focused="true" android:drawable="@*android:drawable/list_focused_holo" />
- <item android:state_selected="true" android:drawable="@*android:drawable/list_focused_holo" />
-
- <item android:state_pressed="true" android:state_focused="true" android:drawable="@*android:drawable/list_selector_background_transition_holo_light" />
- <item android:state_pressed="true" android:drawable="@*android:drawable/list_selector_background_transition_holo_light" />
+ <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@*android:drawable/list_selector_disabled_holo_light" />
+ <item android:state_focused="true" android:state_enabled="false" android:drawable="@*android:drawable/list_selector_disabled_holo_light" />
+ <item android:state_focused="true" android:state_pressed="true" android:drawable="@*android:drawable/list_selector_background_transition_holo_light" />
+ <item android:state_focused="false" android:state_pressed="true" android:drawable="@*android:drawable/list_selector_background_transition_holo_light" />
+ <item android:state_focused="true" android:drawable="@*android:drawable/list_focused_holo" />
<item android:drawable="@android:color/transparent" />
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
index 98ded34..77cdc3b 100644
--- a/packages/DocumentsUI/res/layout/fragment_directory.xml
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -42,6 +42,7 @@
android:paddingEnd="@dimen/grid_padding_horiz"
android:paddingTop="@dimen/grid_padding"
android:paddingBottom="@dimen/grid_padding"
+ android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
android:listSelector="@android:color/transparent"
android:visibility="gone" />
diff --git a/packages/DocumentsUI/res/values/dimens.xml b/packages/DocumentsUI/res/values/dimens.xml
index 4a93cdb..924a8d6 100644
--- a/packages/DocumentsUI/res/values/dimens.xml
+++ b/packages/DocumentsUI/res/values/dimens.xml
@@ -17,8 +17,8 @@
<resources>
<dimen name="icon_size">32dp</dimen>
<dimen name="root_icon_size">24dp</dimen>
- <dimen name="grid_width">180dp</dimen>
- <dimen name="grid_height">180dp</dimen>
+ <dimen name="grid_width">160dp</dimen>
+ <dimen name="grid_height">170dp</dimen>
<dimen name="grid_padding">4dp</dimen>
<dimen name="grid_padding_horiz">4dp</dimen>
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index 682ae4a..b7dcb71 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -62,6 +62,8 @@
<!-- Toast shown when saving a document failed with an error [CHAR LIMIT=48] -->
<string name="save_error">Failed to save document</string>
+ <!-- Toast shown when creating a folder failed with an error [CHAR LIMIT=48] -->
+ <string name="create_error">Failed to create folder</string>
<!-- Title of storage root location that contains recently modified or used documents [CHAR LIMIT=24] -->
<string name="root_recent">Recent</string>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index d8e60aa..9d92cd8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -76,7 +76,7 @@ public class CreateDirectoryFragment extends DialogFragment {
final DocumentInfo childDoc = DocumentInfo.fromUri(resolver, childUri);
activity.onDocumentPicked(childDoc);
} catch (Exception e) {
- Toast.makeText(context, R.string.save_error, Toast.LENGTH_SHORT).show();
+ Toast.makeText(context, R.string.create_error, Toast.LENGTH_SHORT).show();
}
}
});
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index de1f130..79ab28d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -715,8 +715,16 @@ public class DirectoryFragment extends Fragment {
final FrameLayout grid = (FrameLayout) convertView;
final int gridPadding = getResources()
.getDimensionPixelSize(R.dimen.grid_padding);
- grid.setForeground(new InsetDrawable(grid.getForeground(), gridPadding));
- grid.setBackground(new InsetDrawable(grid.getBackground(), gridPadding));
+
+ // Tricksy hobbitses! We need to fully clear the drawable so
+ // the view doesn't clobber the new InsetDrawable callback
+ // when setting back later.
+ final Drawable fg = grid.getForeground();
+ final Drawable bg = grid.getBackground();
+ grid.setForeground(null);
+ grid.setBackground(null);
+ grid.setForeground(new InsetDrawable(fg, gridPadding));
+ grid.setBackground(new InsetDrawable(bg, gridPadding));
} else {
throw new IllegalStateException();
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 6d5475d..8d55ec4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -285,6 +285,7 @@ public class DocumentsActivity extends Activity {
private class RestoreStackTask extends AsyncTask<Void, Void, Void> {
private volatile boolean mRestoredStack;
+ private volatile boolean mExternal;
@Override
protected Void doInBackground(Void... params) {
@@ -298,6 +299,7 @@ public class DocumentsActivity extends Activity {
cursor.getColumnIndex(ResumeColumns.STACK));
DurableUtils.readFromArray(rawStack, mState.stack);
mRestoredStack = true;
+ mExternal = cursor.getInt(cursor.getColumnIndex(ResumeColumns.EXTERNAL)) != 0;
}
} catch (IOException e) {
Log.w(TAG, "Failed to resume", e);
@@ -305,12 +307,17 @@ public class DocumentsActivity extends Activity {
IoUtils.closeQuietly(cursor);
}
- // If restored root isn't valid, fall back to recents
- final RootInfo root = getCurrentRoot();
- final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
- if (!matchingRoots.contains(root)) {
- mState.stack.reset();
- mRestoredStack = false;
+ if (mRestoredStack) {
+ // Update the restored stack to ensure we have freshest data
+ final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
+ try {
+ mState.stack.updateRoot(matchingRoots);
+ mState.stack.updateDocuments(getContentResolver());
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "Failed to restore stack: " + e);
+ mState.stack.reset();
+ mRestoredStack = false;
+ }
}
return null;
@@ -321,10 +328,22 @@ public class DocumentsActivity extends Activity {
if (isDestroyed()) return;
mState.restored = true;
- // Only open drawer when not restoring stack, and when not showing
- // visual content.
- if (!mRestoredStack
- && !MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) {
+ // Show drawer when no stack restored, but only when requesting
+ // non-visual content. However, if we last used an external app,
+ // drawer is always shown.
+
+ boolean showDrawer = false;
+ if (!mRestoredStack) {
+ showDrawer = true;
+ }
+ if (MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) {
+ showDrawer = false;
+ }
+ if (mExternal && mState.action == ACTION_GET_CONTENT) {
+ showDrawer = true;
+ }
+
+ if (showDrawer) {
setRootsDrawerOpen(true);
}
@@ -340,6 +359,7 @@ public class DocumentsActivity extends Activity {
mState.showSize = true;
} else {
mState.showSize = SettingsActivity.getDisplayFileSize(this);
+ invalidateOptionsMenu();
}
}
@@ -779,10 +799,10 @@ public class DocumentsActivity extends Activity {
} else {
DirectoryFragment.showRecentsOpen(fm, anim);
- // Start recents in relevant mode
- final boolean acceptImages = MimePredicate.mimeMatches(
- "image/*", mState.acceptMimes);
- mState.userMode = acceptImages ? MODE_GRID : MODE_LIST;
+ // Start recents in grid when requesting visual things
+ final boolean visualMimes = MimePredicate.mimeMatches(
+ MimePredicate.VISUAL_MIMES, mState.acceptMimes);
+ mState.userMode = visualMimes ? MODE_GRID : MODE_LIST;
mState.derivedMode = mState.userMode;
}
} else {
@@ -814,9 +834,17 @@ public class DocumentsActivity extends Activity {
}
public void onStackPicked(DocumentStack stack) {
- mState.stack = stack;
- mState.stackTouched = true;
- onCurrentDirectoryChanged(ANIM_SIDE);
+ try {
+ // Update the restored stack to ensure we have freshest data
+ stack.updateDocuments(getContentResolver());
+
+ mState.stack = stack;
+ mState.stackTouched = true;
+ onCurrentDirectoryChanged(ANIM_SIDE);
+
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "Failed to restore stack: " + e);
+ }
}
public void onRootPicked(RootInfo root, boolean closeDrawer) {
@@ -858,6 +886,14 @@ public class DocumentsActivity extends Activity {
// Only relay back results when not canceled; otherwise stick around to
// let the user pick another app/backend.
if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) {
+
+ // Remember that we last picked via external app
+ final String packageName = getCallingPackage();
+ final ContentValues values = new ContentValues();
+ values.put(ResumeColumns.EXTERNAL, 1);
+ getContentResolver().insert(RecentsProvider.buildResume(packageName), values);
+
+ // Pass back result to original caller
setResult(resultCode, data);
finish();
} else {
@@ -945,6 +981,7 @@ public class DocumentsActivity extends Activity {
final String packageName = getCallingPackage();
values.clear();
values.put(ResumeColumns.STACK, rawStack);
+ values.put(ResumeColumns.EXTERNAL, 0);
resolver.insert(RecentsProvider.buildResume(packageName), values);
final Intent intent = new Intent();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
index a396f79..670d5c0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -45,8 +45,10 @@ import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
+import com.android.documentsui.DocumentsActivity.State;
import com.android.documentsui.RecentsProvider.RecentColumns;
import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.RootInfo;
import com.google.android.collect.Lists;
import libcore.io.IoUtils;
@@ -55,6 +57,7 @@ import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
/**
@@ -89,10 +92,13 @@ public class RecentsCreateFragment extends Fragment {
mAdapter = new DocumentStackAdapter();
mListView.setAdapter(mAdapter);
+ final RootsCache roots = DocumentsApplication.getRootsCache(context);
+ final State state = ((DocumentsActivity) getActivity()).getDisplayState();
+
mCallbacks = new LoaderCallbacks<List<DocumentStack>>() {
@Override
public Loader<List<DocumentStack>> onCreateLoader(int id, Bundle args) {
- return new RecentsCreateLoader(context);
+ return new RecentsCreateLoader(context, roots, state);
}
@Override
@@ -131,12 +137,18 @@ public class RecentsCreateFragment extends Fragment {
};
public static class RecentsCreateLoader extends UriDerivativeLoader<Uri, List<DocumentStack>> {
- public RecentsCreateLoader(Context context) {
+ private final RootsCache mRoots;
+ private final State mState;
+
+ public RecentsCreateLoader(Context context, RootsCache roots, State state) {
super(context, RecentsProvider.buildRecent());
+ mRoots = roots;
+ mState = state;
}
@Override
public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) {
+ final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
final ArrayList<DocumentStack> result = Lists.newArrayList();
final ContentResolver resolver = getContext().getContentResolver();
@@ -149,6 +161,12 @@ public class RecentsCreateFragment extends Fragment {
try {
final DocumentStack stack = new DocumentStack();
stack.read(new DataInputStream(new ByteArrayInputStream(rawStack)));
+
+ // Only update root here to avoid spinning up all
+ // providers; we update the stack during the actual
+ // restore. This also filters away roots that don't
+ // match current filter.
+ stack.updateRoot(matchingRoots);
result.add(stack);
} catch (IOException e) {
Log.w(TAG, "Failed to resolve stack: " + e);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
index af79c93..7386cae 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
@@ -72,6 +72,7 @@ public class RecentsProvider extends ContentProvider {
public static final String PACKAGE_NAME = "package_name";
public static final String STACK = "stack";
public static final String TIMESTAMP = "timestamp";
+ public static final String EXTERNAL = "external";
}
public static Uri buildRecent() {
@@ -97,9 +98,10 @@ public class RecentsProvider extends ContentProvider {
private static final int VERSION_INIT = 1;
private static final int VERSION_AS_BLOB = 3;
+ private static final int VERSION_ADD_EXTERNAL = 4;
public DatabaseHelper(Context context) {
- super(context, DB_NAME, null, VERSION_AS_BLOB);
+ super(context, DB_NAME, null, VERSION_ADD_EXTERNAL);
}
@Override
@@ -121,9 +123,10 @@ public class RecentsProvider extends ContentProvider {
")");
db.execSQL("CREATE TABLE " + TABLE_RESUME + " (" +
- ResumeColumns.PACKAGE_NAME + " TEXT PRIMARY KEY ON CONFLICT REPLACE," +
- ResumeColumns.STACK + " BLOB," +
- ResumeColumns.TIMESTAMP + " INTEGER" +
+ ResumeColumns.PACKAGE_NAME + " TEXT NOT NULL PRIMARY KEY," +
+ ResumeColumns.STACK + " BLOB DEFAULT NULL," +
+ ResumeColumns.TIMESTAMP + " INTEGER," +
+ ResumeColumns.EXTERNAL + " INTEGER NOT NULL DEFAULT 0" +
")");
}
@@ -176,6 +179,7 @@ public class RecentsProvider extends ContentProvider {
@Override
public Uri insert(Uri uri, ContentValues values) {
final SQLiteDatabase db = mHelper.getWritableDatabase();
+ final ContentValues key = new ContentValues();
switch (sMatcher.match(uri)) {
case URI_RECENT:
values.put(RecentColumns.TIMESTAMP, System.currentTimeMillis());
@@ -188,7 +192,6 @@ public class RecentsProvider extends ContentProvider {
final String rootId = uri.getPathSegments().get(2);
final String documentId = uri.getPathSegments().get(3);
- final ContentValues key = new ContentValues();
key.put(StateColumns.AUTHORITY, authority);
key.put(StateColumns.ROOT_ID, rootId);
key.put(StateColumns.DOCUMENT_ID, documentId);
@@ -201,10 +204,15 @@ public class RecentsProvider extends ContentProvider {
return uri;
case URI_RESUME:
- final String packageName = uri.getPathSegments().get(1);
- values.put(ResumeColumns.PACKAGE_NAME, packageName);
values.put(ResumeColumns.TIMESTAMP, System.currentTimeMillis());
- db.insert(TABLE_RESUME, null, values);
+
+ final String packageName = uri.getPathSegments().get(1);
+ key.put(ResumeColumns.PACKAGE_NAME, packageName);
+
+ // Ensure that row exists, then update with changed values
+ db.insertWithOnConflict(TABLE_RESUME, null, key, SQLiteDatabase.CONFLICT_IGNORE);
+ db.update(TABLE_RESUME, values, ResumeColumns.PACKAGE_NAME + "=?",
+ new String[] { packageName });
return uri;
default:
throw new UnsupportedOperationException("Unsupported Uri " + uri);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java b/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java
index 7b7c3d5..1cc35a7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java
@@ -27,6 +27,7 @@ import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
+import android.widget.ScrollView;
import android.widget.TextView;
import libcore.io.IoUtils;
@@ -52,6 +53,9 @@ public class TestActivity extends Activity {
final LinearLayout view = new LinearLayout(context);
view.setOrientation(LinearLayout.VERTICAL);
+ mResult = new TextView(context);
+ view.addView(mResult);
+
final CheckBox multiple = new CheckBox(context);
multiple.setText("ALLOW_MULTIPLE");
view.addView(multiple);
@@ -156,6 +160,23 @@ public class TestActivity extends Activity {
view.addView(button);
button = new Button(context);
+ button.setText("CREATE_DOC image/png");
+ button.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("image/png");
+ intent.putExtra(Intent.EXTRA_TITLE, "mypicture.png");
+ if (localOnly.isChecked()) {
+ intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+ }
+ startActivityForResult(intent, CODE_WRITE);
+ }
+ });
+ view.addView(button);
+
+ button = new Button(context);
button.setText("GET_CONTENT */*");
button.setOnClickListener(new OnClickListener() {
@Override
@@ -174,10 +195,10 @@ public class TestActivity extends Activity {
});
view.addView(button);
- mResult = new TextView(context);
- view.addView(mResult);
+ final ScrollView scroll = new ScrollView(context);
+ scroll.addView(view);
- setContentView(view);
+ setContentView(scroll);
}
@Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 08a8c13..5091a61 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.DocumentsContract;
+import android.provider.DocumentsProvider;
import android.provider.DocumentsContract.Document;
import com.android.documentsui.RootCursorWrapper;
@@ -141,23 +142,42 @@ public class DocumentInfo implements Durable, Parcelable {
}
public static DocumentInfo fromCursor(Cursor cursor, String authority) {
- final DocumentInfo doc = new DocumentInfo();
- doc.authority = authority;
- doc.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
- doc.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
- doc.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
- doc.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
- doc.displayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
- doc.lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
- doc.flags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- doc.summary = getCursorString(cursor, Document.COLUMN_SUMMARY);
- doc.size = getCursorLong(cursor, Document.COLUMN_SIZE);
- doc.icon = getCursorInt(cursor, Document.COLUMN_ICON);
- doc.deriveFields();
- return doc;
- }
-
- public static DocumentInfo fromUri(ContentResolver resolver, Uri uri) throws FileNotFoundException {
+ final DocumentInfo info = new DocumentInfo();
+ info.updateFromCursor(cursor, authority);
+ return info;
+ }
+
+ public void updateFromCursor(Cursor cursor, String authority) {
+ this.authority = authority;
+ this.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+ this.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ this.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+ this.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ this.displayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
+ this.lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
+ this.flags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+ this.summary = getCursorString(cursor, Document.COLUMN_SUMMARY);
+ this.size = getCursorLong(cursor, Document.COLUMN_SIZE);
+ this.icon = getCursorInt(cursor, Document.COLUMN_ICON);
+ this.deriveFields();
+ }
+
+ public static DocumentInfo fromUri(ContentResolver resolver, Uri uri)
+ throws FileNotFoundException {
+ final DocumentInfo info = new DocumentInfo();
+ info.updateFromUri(resolver, uri);
+ return info;
+ }
+
+ /**
+ * Update a possibly stale restored document against a live
+ * {@link DocumentsProvider}.
+ */
+ public void updateSelf(ContentResolver resolver) throws FileNotFoundException {
+ updateFromUri(resolver, derivedUri);
+ }
+
+ public void updateFromUri(ContentResolver resolver, Uri uri) throws FileNotFoundException {
final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
uri.getAuthority());
Cursor cursor = null;
@@ -166,7 +186,7 @@ public class DocumentInfo implements Durable, Parcelable {
if (!cursor.moveToFirst()) {
throw new FileNotFoundException("Missing details for " + uri);
}
- return fromCursor(cursor, uri.getAuthority());
+ updateFromCursor(cursor, uri.getAuthority());
} catch (Throwable t) {
throw asFileNotFoundException(t);
} finally {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
index 2541440..0a378c0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
@@ -16,10 +16,15 @@
package com.android.documentsui.model;
+import android.content.ContentResolver;
+import android.provider.DocumentsProvider;
+
import java.io.DataInputStream;
import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ProtocolException;
+import java.util.Collection;
import java.util.LinkedList;
/**
@@ -46,6 +51,26 @@ public class DocumentStack extends LinkedList<DocumentInfo> implements Durable {
return size() == 0;
}
+ public void updateRoot(Collection<RootInfo> matchingRoots) throws FileNotFoundException {
+ for (RootInfo root : matchingRoots) {
+ if (root.equals(this.root)) {
+ this.root = root;
+ return;
+ }
+ }
+ throw new FileNotFoundException("Failed to find matching root for " + root);
+ }
+
+ /**
+ * Update a possibly stale restored stack against a live
+ * {@link DocumentsProvider}.
+ */
+ public void updateDocuments(ContentResolver resolver) throws FileNotFoundException {
+ for (DocumentInfo info : this) {
+ info.updateSelf(resolver);
+ }
+ }
+
@Override
public void reset() {
clear();