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

Commit a61dc8e0 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Separate root and document management.

Two hidden intents for managing roots and documents, used to support
Downloads UI.  Touching an item tries launching as MANAGE_DOCUMENT
first before falling back to VIEW.  Provide MIME type for roots.

Bug: 10446265, 10531347, 10599641
Change-Id: Ia5584bd6ce3e5a9b0048e8caf1447e3053664413
parent 498a5f54
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -20747,6 +20747,7 @@ package android.provider {
    method public static android.net.Uri buildChildDocumentsUri(java.lang.String, java.lang.String);
    method public static android.net.Uri buildDocumentUri(java.lang.String, java.lang.String);
    method public static android.net.Uri buildRecentDocumentsUri(java.lang.String, java.lang.String);
    method public static android.net.Uri buildRootUri(java.lang.String, java.lang.String);
    method public static android.net.Uri buildRootsUri(java.lang.String);
    method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String);
    method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
+17 −1
Original line number Diff line number Diff line
@@ -72,7 +72,9 @@ public final class DocumentsContract {
    public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER";

    /** {@hide} */
    public static final String ACTION_MANAGE_DOCUMENTS = "android.provider.action.MANAGE_DOCUMENTS";
    public static final String ACTION_MANAGE_ROOT = "android.provider.action.MANAGE_ROOT";
    /** {@hide} */
    public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";

    /**
     * Constants related to a document, including {@link Cursor} columns names
@@ -346,6 +348,9 @@ public final class DocumentsContract {
         */
        public static final String COLUMN_MIME_TYPES = "mime_types";

        /** {@hide} */
        public static final String MIME_TYPE_ITEM = "vnd.android.document/root";

        /**
         * Type of root that represents a storage service, such as a cloud-based
         * service.
@@ -461,6 +466,17 @@ public final class DocumentsContract {
                .authority(authority).appendPath(PATH_ROOT).build();
    }

    /**
     * Build Uri representing the given {@link Root#COLUMN_ROOT_ID} in a
     * document provider.
     *
     * @see #getRootId(Uri)
     */
    public static Uri buildRootUri(String authority, String rootId) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority).appendPath(PATH_ROOT).appendPath(rootId).build();
    }

    /**
     * Build Uri representing the recently modified documents of a specific
     * root. When queried, a provider will return zero or more rows with columns
+11 −7
Original line number Diff line number Diff line
@@ -75,11 +75,12 @@ import java.io.FileNotFoundException;
public abstract class DocumentsProvider extends ContentProvider {
    private static final String TAG = "DocumentsProvider";

    private static final int MATCH_ROOT = 1;
    private static final int MATCH_RECENT = 2;
    private static final int MATCH_DOCUMENT = 3;
    private static final int MATCH_CHILDREN = 4;
    private static final int MATCH_SEARCH = 5;
    private static final int MATCH_ROOTS = 1;
    private static final int MATCH_ROOT = 2;
    private static final int MATCH_RECENT = 3;
    private static final int MATCH_DOCUMENT = 4;
    private static final int MATCH_CHILDREN = 5;
    private static final int MATCH_SEARCH = 6;

    private String mAuthority;

@@ -93,7 +94,8 @@ public abstract class DocumentsProvider extends ContentProvider {
        mAuthority = info.authority;

        mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        mMatcher.addURI(mAuthority, "root", MATCH_ROOT);
        mMatcher.addURI(mAuthority, "root", MATCH_ROOTS);
        mMatcher.addURI(mAuthority, "root/*", MATCH_ROOT);
        mMatcher.addURI(mAuthority, "root/*/recent", MATCH_RECENT);
        mMatcher.addURI(mAuthority, "document/*", MATCH_DOCUMENT);
        mMatcher.addURI(mAuthority, "document/*/children", MATCH_CHILDREN);
@@ -256,7 +258,7 @@ public abstract class DocumentsProvider extends ContentProvider {
            String[] selectionArgs, String sortOrder) {
        try {
            switch (mMatcher.match(uri)) {
                case MATCH_ROOT:
                case MATCH_ROOTS:
                    return queryRoots(projection);
                case MATCH_RECENT:
                    return queryRecentDocuments(getRootId(uri), projection);
@@ -285,6 +287,8 @@ public abstract class DocumentsProvider extends ContentProvider {
    public final String getType(Uri uri) {
        try {
            switch (mMatcher.match(uri)) {
                case MATCH_ROOT:
                    return DocumentsContract.Root.MIME_TYPE_ITEM;
                case MATCH_DOCUMENT:
                    return getDocumentType(getDocumentId(uri));
                default:
+2 −3
Original line number Diff line number Diff line
@@ -30,11 +30,10 @@
                <category android:name="android.intent.category.OPENABLE" />
                <data android:mimeType="*/*" />
            </intent-filter>
            <!-- data expected to point at existing root to manage -->
            <intent-filter>
                <action android:name="android.provider.action.MANAGE_DOCUMENTS" />
                <action android:name="android.provider.action.MANAGE_ROOT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.document/directory" />
                <data android:mimeType="vnd.android.document/root" />
            </intent-filter>
        </activity>

+21 −10
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ public class DocumentsActivity extends Activity {
            mState.action = ACTION_CREATE;
        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
            mState.action = ACTION_GET_CONTENT;
        } else if (DocumentsContract.ACTION_MANAGE_DOCUMENTS.equals(action)) {
        } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
            mState.action = ACTION_MANAGE;
        }

@@ -171,12 +171,13 @@ public class DocumentsActivity extends Activity {
        }

        if (mState.action == ACTION_MANAGE) {
            final Uri rootUri = intent.getData();
            final RootInfo root = mRoots.findRoot(rootUri);
            final Uri uri = intent.getData();
            final String rootId = DocumentsContract.getRootId(uri);
            final RootInfo root = mRoots.getRoot(uri.getAuthority(), rootId);
            if (root != null) {
                onRootPicked(root, true);
            } else {
                Log.w(TAG, "Failed to find root: " + rootUri);
                Log.w(TAG, "Failed to find root: " + uri);
                finish();
            }

@@ -626,17 +627,27 @@ public class DocumentsActivity extends Activity {
            // Replace selected file
            SaveFragment.get(fm).setReplaceTarget(doc);
        } else if (mState.action == ACTION_MANAGE) {
            // Open the document
            final Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setData(doc.uri);
            // 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.uri);

            try {
                startActivity(intent);
                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.uri);

                try {
                    startActivity(view);
                } catch (ActivityNotFoundException ex2) {
                    Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    public void onDocumentsPicked(List<DocumentInfo> docs) {
        if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
Loading