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

Commit 1d890e0d authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

DocumentsUI handles GET_CONTENT; hinting, errors.

Document browser now takes over all GET_CONTENT requests that request
openable Uris. It shows both storage backends and includes other apps
that respond to GET_CONTENT. Only grants transient read permissions.

Better guarding against throwing storage backends. Send sort order
and local-only hinting to backends.

Require that OPEN/CREATE_DOC users include openable category.

Bug: 10330112, 10329976, 10340741, 10331689, 10329971
Change-Id: Ieb8768a6d71201816046f4a4c48832061a313c28
parent 8ba40bf7
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -17,11 +17,19 @@
            <intent-filter android:priority="100">
                <action android:name="android.intent.action.OPEN_DOCUMENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.OPENABLE" />
                <data android:mimeType="*/*" />
            </intent-filter>
            <intent-filter android:priority="100">
                <action android:name="android.intent.action.CREATE_DOCUMENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.OPENABLE" />
                <data android:mimeType="*/*" />
            </intent-filter>
            <intent-filter android:priority="100">
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.OPENABLE" />
                <data android:mimeType="*/*" />
            </intent-filter>
        </activity>
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
    <string name="root_type_service">Services</string>
    <string name="root_type_shortcut">Shortcuts</string>
    <string name="root_type_device">Devices</string>
    <string name="root_type_apps">More apps</string>

    <string name="pref_advanced_devices">Display advanced devices</string>
    <string name="pref_file_size">Display file size</string>
+5 −1
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ public class DirectoryFragment extends Fragment {
                final DisplayState state = getDisplayState(DirectoryFragment.this);
                mFilter = new MimePredicate(state.acceptMimes);

                final Uri contentsUri;
                Uri contentsUri;
                if (mType == TYPE_NORMAL) {
                    contentsUri = DocumentsContract.buildContentsUri(uri);
                } else if (mType == TYPE_RECENT_OPEN) {
@@ -153,6 +153,10 @@ public class DirectoryFragment extends Fragment {
                    contentsUri = uri;
                }

                if (state.localOnly) {
                    contentsUri = DocumentsContract.setLocalOnly(contentsUri);
                }

                final Comparator<Document> sortOrder;
                if (state.sortOrder == DisplayState.SORT_ORDER_DATE || mType == TYPE_RECENT_OPEN) {
                    sortOrder = new Document.DateComparator();
+34 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
import android.provider.DocumentsContract.DocumentColumns;
import android.util.Log;

import com.android.documentsui.model.Document;
@@ -38,6 +39,7 @@ import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

public class DirectoryLoader extends UriDerivativeLoader<List<Document>> {
@@ -46,6 +48,17 @@ public class DirectoryLoader extends UriDerivativeLoader<List<Document>> {
    private Predicate<Document> mFilter;
    private Comparator<Document> mSortOrder;

    /**
     * Stub result that represents an internal error.
     */
    public static class ExceptionResult extends LinkedList<Document> {
        public final Exception e;

        public ExceptionResult(Exception e) {
            this.e = e;
        }
    }

    public DirectoryLoader(Context context, Uri uri, int type, Predicate<Document> filter,
            Comparator<Document> sortOrder) {
        super(context, uri);
@@ -56,11 +69,18 @@ public class DirectoryLoader extends UriDerivativeLoader<List<Document>> {

    @Override
    public List<Document> loadInBackground(Uri uri, CancellationSignal signal) {
        try {
            return loadInBackgroundInternal(uri, signal);
        } catch (Exception e) {
            return new ExceptionResult(e);
        }
    }

    private List<Document> loadInBackgroundInternal(Uri uri, CancellationSignal signal) {
        final ArrayList<Document> result = Lists.newArrayList();

        // TODO: send selection and sorting hints to backend
        final ContentResolver resolver = getContext().getContentResolver();
        final Cursor cursor = resolver.query(uri, null, null, null, null, signal);
        final Cursor cursor = resolver.query(uri, null, null, null, getQuerySortOrder(), signal);
        try {
            while (cursor != null && cursor.moveToNext()) {
                Document doc = null;
@@ -94,4 +114,16 @@ public class DirectoryLoader extends UriDerivativeLoader<List<Document>> {

        return result;
    }

    private String getQuerySortOrder() {
        if (mSortOrder instanceof Document.DateComparator) {
            return DocumentColumns.LAST_MODIFIED + " DESC";
        } else if (mSortOrder instanceof Document.NameComparator) {
            return DocumentColumns.DISPLAY_NAME + " ASC";
        } else if (mSortOrder instanceof Document.SizeComparator) {
            return DocumentColumns.SIZE + " DESC";
        } else {
            return null;
        }
    }
}
+39 −16
Original line number Diff line number Diff line
@@ -22,9 +22,11 @@ import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
@@ -60,6 +62,7 @@ public class DocumentsActivity extends Activity {

    public static final int ACTION_OPEN = 1;
    public static final int ACTION_CREATE = 2;
    public static final int ACTION_GET_CONTENT = 3;

    private int mAction;

@@ -84,11 +87,15 @@ public class DocumentsActivity extends Activity {
        final String action = intent.getAction();
        if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) {
            mAction = ACTION_OPEN;
            mDisplayState.allowMultiple = intent.getBooleanExtra(
                    Intent.EXTRA_ALLOW_MULTIPLE, false);
        } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) {
            mAction = ACTION_CREATE;
            mDisplayState.allowMultiple = false;
        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
            mAction = ACTION_GET_CONTENT;
        }

        if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) {
            mDisplayState.allowMultiple = intent.getBooleanExtra(
                    Intent.EXTRA_ALLOW_MULTIPLE, false);
        }

        if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
@@ -97,11 +104,7 @@ public class DocumentsActivity extends Activity {
            mDisplayState.acceptMimes = new String[] { intent.getType() };
        }

        if (MimePredicate.mimeMatches("image/*", mDisplayState.acceptMimes)) {
            mDisplayState.mode = DisplayState.MODE_GRID;
        } else {
            mDisplayState.mode = DisplayState.MODE_LIST;
        }
        mDisplayState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);

        setResult(Activity.RESULT_CANCELED);
        setContentView(R.layout.activity);
@@ -112,7 +115,14 @@ public class DocumentsActivity extends Activity {
            SaveFragment.show(getFragmentManager(), mimeType, title);
        }

        RootsFragment.show(getFragmentManager());
        if (mAction == ACTION_GET_CONTENT) {
            final Intent moreApps = new Intent(getIntent());
            moreApps.setComponent(null);
            moreApps.setPackage(null);
            RootsFragment.show(getFragmentManager(), moreApps);
        } else {
            RootsFragment.show(getFragmentManager(), null);
        }

        mRootsContainer = findViewById(R.id.container_roots);

@@ -186,7 +196,7 @@ public class DocumentsActivity extends Activity {
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            actionBar.setIcon(new ColorDrawable());

            if (mAction == ACTION_OPEN) {
            if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) {
                actionBar.setTitle(R.string.title_open);
            } else if (mAction == ACTION_CREATE) {
                actionBar.setTitle(R.string.title_save);
@@ -484,12 +494,21 @@ public class DocumentsActivity extends Activity {
        }
    }

    public void onAppPicked(ResolveInfo info) {
        final Intent intent = new Intent(getIntent());
        intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
        intent.setComponent(new ComponentName(
                info.activityInfo.applicationInfo.packageName, info.activityInfo.name));
        startActivity(intent);
        finish();
    }

    public void onDocumentPicked(Document doc) {
        final FragmentManager fm = getFragmentManager();
        if (doc.isDirectory()) {
            mStack.push(doc);
            onCurrentDirectoryChanged();
        } else if (mAction == ACTION_OPEN) {
        } else if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) {
            // Explicit file picked, return
            onFinished(doc.uri);
        } else if (mAction == ACTION_CREATE) {
@@ -538,7 +557,7 @@ public class DocumentsActivity extends Activity {
            values.put(RecentsProvider.COL_PATH, rawStack);
            resolver.insert(RecentsProvider.buildRecentCreate(), values);

        } else if (mAction == ACTION_OPEN) {
        } else if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) {
            // Remember opened items
            for (Uri uri : uris) {
                values.clear();
@@ -565,10 +584,13 @@ public class DocumentsActivity extends Activity {
            intent.setClipData(clipData);
        }

        // TODO: omit WRITE and PERSIST for GET_CONTENT
        if (mAction == ACTION_GET_CONTENT) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                    | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
        }

        setResult(Activity.RESULT_OK, intent);
        finish();
@@ -580,6 +602,7 @@ public class DocumentsActivity extends Activity {
        public int sortOrder = SORT_ORDER_NAME;
        public boolean allowMultiple = false;
        public boolean showSize = false;
        public boolean localOnly = false;

        public static final int MODE_LIST = 0;
        public static final int MODE_GRID = 1;
Loading