Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6120da1 authored by Tomasz Mikolajewski's avatar Tomasz Mikolajewski
Browse files

Open zip files nicely from the Download app with Files app.

Bug: 26321218
Change-Id: I8a7a7e914d290ea1b6f424ee5fbd38a4b09c362d
parent b8bcd199
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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);
+17 −21
Original line number Diff line number Diff line
@@ -182,10 +182,7 @@ public class DownloadsActivity extends BaseActivity {

    @Override
    public void onDocumentPicked(DocumentInfo doc, SiblingProvider siblings) {
        final FragmentManager fm = getFragmentManager();
        if (doc.isContainer()) {
            openContainerDocument(doc);
        } else {
        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);
@@ -194,7 +191,7 @@ public class DownloadsActivity extends BaseActivity {
        try {
            startActivity(manage);
        } catch (ActivityNotFoundException ex) {
                // Fall back to viewing
            // Fall back to viewing.
            final Intent view = new Intent(Intent.ACTION_VIEW);
            view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            view.setData(doc.derivedUri);
@@ -207,7 +204,6 @@ public class DownloadsActivity extends BaseActivity {
            }
        }
    }
    }

    @Override
    public void onDocumentsPicked(List<DocumentInfo> docs) {}
+47 −0
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+29 −0
Original line number Diff line number Diff line
@@ -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;
    }