summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tomasz Mikolajewski <mtomasz@google.com> 2016-01-27 17:36:51 +0900
committer Tomasz Mikolajewski <mtomasz@google.com> 2016-02-03 11:56:54 +0900
commita6120da1e37a4457bac58f8900bffa795dc8e7cb (patch)
tree4f0ae9e38c275590345a5f699a031631f9ce92e8
parentb8bcd19975e5b1de26297682d214f2f2c216e20b (diff)
Open zip files nicely from the Download app with Files app.
Bug: 26321218 Change-Id: I8a7a7e914d290ea1b6f424ee5fbd38a4b09c362d
-rw-r--r--packages/DocumentsUI/AndroidManifest.xml13
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java2
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java38
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java47
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootsCache.java29
5 files changed, 107 insertions, 22 deletions
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index fa9ff0153c87..9ac929ba9b28 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -75,6 +75,19 @@
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.document/root" />
</intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="application/zip"
+ android:host="com.android.providers.downloads.documents"
+ android:scheme="content" />
+ <data android:mimeType="application/x-zip"
+ android:host="com.android.providers.downloads.documents"
+ android:scheme="content" />
+ <data android:mimeType="application/x-zip-compressed"
+ android:host="com.android.providers.downloads.documents"
+ android:scheme="content" />
+ </intent-filter>
</activity>
<activity
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 0fed6410b2cd..9dfe631d6e9b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -541,7 +541,7 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
}
}
- private DocumentInfo getRootDocumentBlocking(RootInfo root) {
+ DocumentInfo getRootDocumentBlocking(RootInfo root) {
try {
final Uri uri = DocumentsContract.buildDocumentUri(
root.authority, root.documentId);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
index b6ded6c3fbd7..5cc677c4f008 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
@@ -182,29 +182,25 @@ public class DownloadsActivity extends BaseActivity {
@Override
public void onDocumentPicked(DocumentInfo doc, SiblingProvider siblings) {
- final FragmentManager fm = getFragmentManager();
- if (doc.isContainer()) {
- openContainerDocument(doc);
- } else {
- // First try managing the document; we expect manager to filter
- // based on authority, so we don't grant.
- final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
- manage.setData(doc.derivedUri);
+ Preconditions.checkArgument(!doc.isDirectory());
+ // First try managing the document; we expect manager to filter
+ // based on authority, so we don't grant.
+ final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
+ manage.setData(doc.derivedUri);
+
+ try {
+ startActivity(manage);
+ } catch (ActivityNotFoundException ex) {
+ // Fall back to viewing.
+ final Intent view = new Intent(Intent.ACTION_VIEW);
+ view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ view.setData(doc.derivedUri);
try {
- startActivity(manage);
- } catch (ActivityNotFoundException ex) {
- // Fall back to viewing
- final Intent view = new Intent(Intent.ACTION_VIEW);
- view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- view.setData(doc.derivedUri);
-
- try {
- startActivity(view);
- } catch (ActivityNotFoundException ex2) {
- Snackbars.makeSnackbar(this, R.string.toast_no_application, Snackbar.LENGTH_SHORT)
- .show();
- }
+ startActivity(view);
+ } catch (ActivityNotFoundException ex2) {
+ Snackbars.makeSnackbar(this, R.string.toast_no_application, Snackbar.LENGTH_SHORT)
+ .show();
}
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index f0df3a2ce823..59463bf2b087 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -30,6 +30,7 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.DocumentsContract;
@@ -53,8 +54,10 @@ import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
import com.android.documentsui.services.FileOperationService;
+import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
/**
@@ -109,6 +112,10 @@ public class FilesActivity extends BaseActivity {
if (DEBUG) Log.d(TAG, "Launching with non-empty stack.");
checkState(uri == null || LauncherActivity.isLaunchUri(uri));
refreshCurrentRootAndDirectory(ANIM_NONE);
+ } else if (intent.getAction() == Intent.ACTION_VIEW) {
+ checkArgument(uri != null);
+ new OpenUriForViewTask().executeOnExecutor(
+ ProviderExecutor.forAuthority(uri.getAuthority()), uri);
} else if (DocumentsContract.isRootUri(this, uri)) {
if (DEBUG) Log.d(TAG, "Launching with root URI.");
// If we've got a specific root to display, restore that root using a dedicated
@@ -447,4 +454,44 @@ public class FilesActivity extends BaseActivity {
setResult(Activity.RESULT_OK, intent);
finish();
}
+
+ /**
+ * Builds a stack for the specific Uris. Multi roots are not supported, as it's impossible
+ * to know which root to select. Also, the stack doesn't contain intermediate directories.
+ * It's primarly used for opening ZIP archives from Downloads app.
+ */
+ final class OpenUriForViewTask extends AsyncTask<Uri, Void, Void> {
+ @Override
+ protected Void doInBackground(Uri... params) {
+ final Uri uri = params[0];
+
+ final RootsCache rootsCache = DocumentsApplication.getRootsCache(FilesActivity.this);
+ final String authority = uri.getAuthority();
+
+ final Collection<RootInfo> roots =
+ rootsCache.getRootsForAuthorityBlocking(authority);
+ if (roots.isEmpty()) {
+ Log.e(TAG, "Failed to find root for the requested Uri: " + uri);
+ return null;
+ }
+
+ final RootInfo root = roots.iterator().next();
+ mState.stack.root = root;
+ try {
+ mState.stack.add(DocumentInfo.fromUri(getContentResolver(), uri));
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Failed to resolve DocumentInfo from Uri: " + uri);
+ }
+ mState.stack.add(getRootDocumentBlocking(root));
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ if (isDestroyed()) {
+ return;
+ }
+ refreshCurrentRootAndDirectory(ANIM_NONE);
+ }
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index 21e756623bdd..0a280abadc47 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -48,6 +48,7 @@ import libcore.io.IoUtils;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -159,6 +160,21 @@ public class RootsCache {
}
}
+ /**
+ * Load roots from a stopped authority. Normal {@link UpdateTask} passes
+ * ignore stopped applications.
+ */
+ private void loadStoppedAuthority(String authority) {
+ final ContentResolver resolver = mContext.getContentResolver();
+ synchronized (mLock) {
+ if (DEBUG) {
+ Log.d(TAG, "Loading stopped authority " + authority);
+ }
+ mRoots.putAll(authority, loadRootsForAuthority(resolver, authority));
+ mStoppedAuthorities.remove(authority);
+ }
+ }
+
private class UpdateTask extends AsyncTask<Void, Void, Void> {
private final String mFilterPackage;
@@ -360,6 +376,19 @@ public class RootsCache {
}
}
+ /**
+ * Returns a list of roots for the specified authority. If not found, then
+ * an empty list is returned.
+ */
+ public Collection<RootInfo> getRootsForAuthorityBlocking(String authority) {
+ waitForFirstLoad();
+ loadStoppedAuthority(authority);
+ synchronized (mLock) {
+ final Collection<RootInfo> roots = mRoots.get(authority);
+ return roots != null ? roots : Collections.<RootInfo>emptyList();
+ }
+ }
+
public void setOnCacheUpdateListener(OnCacheUpdateListener cacheUpdateListener) {
mCacheUpdateListener = cacheUpdateListener;
}