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

Commit 00971e00 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Stronger DocumentsProvider contract." into klp-dev

parents 5579bc7b b6a7f2cd
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -35,9 +35,9 @@
            </intent-filter>
            <!-- data expected to point at existing root to manage -->
            <intent-filter>
                <action android:name="android.intent.action.MANAGE_DOCUMENT" />
                <action android:name="android.provider.action.MANAGE_DOCUMENTS" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/root" />
                <data android:mimeType="vnd.android.doc/dir" />
            </intent-filter>
        </activity>

+14 −15
Original line number Diff line number Diff line
@@ -20,14 +20,14 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract.DocumentColumns;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Documents;
import android.view.LayoutInflater;
import android.view.View;
@@ -36,8 +36,6 @@ import android.widget.Toast;

import com.android.documentsui.model.Document;

import java.io.FileNotFoundException;

/**
 * Dialog to create a new directory.
 */
@@ -68,24 +66,25 @@ public class CreateDirectoryFragment extends DialogFragment {
            public void onClick(DialogInterface dialog, int which) {
                final String displayName = text1.getText().toString();

                final ContentValues values = new ContentValues();
                values.put(DocumentColumns.MIME_TYPE, Documents.MIME_TYPE_DIR);
                values.put(DocumentColumns.DISPLAY_NAME, displayName);

                final DocumentsActivity activity = (DocumentsActivity) getActivity();
                final Document cwd = activity.getCurrentDirectory();

                Uri childUri = resolver.insert(cwd.uri, values);
                final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                        cwd.uri.getAuthority());
                try {
                    final String docId = DocumentsContract.createDocument(client,
                            DocumentsContract.getDocId(cwd.uri), Documents.MIME_TYPE_DIR,
                            displayName);

                    // Navigate into newly created child
                    final Uri childUri = DocumentsContract.buildDocumentUri(
                            cwd.uri.getAuthority(), docId);
                    final Document childDoc = Document.fromUri(resolver, childUri);
                    activity.onDocumentPicked(childDoc);
                } catch (FileNotFoundException e) {
                    childUri = null;
                }

                if (childUri == null) {
                } catch (Exception e) {
                    Toast.makeText(context, R.string.save_error, Toast.LENGTH_SHORT).show();
                } finally {
                    ContentProviderClient.closeQuietly(client);
                }
            }
        });
+12 −47
Original line number Diff line number Diff line
@@ -20,8 +20,8 @@ import static com.android.documentsui.DocumentsActivity.TAG;
import static com.android.documentsui.DocumentsActivity.DisplayState.ACTION_MANAGE;
import static com.android.documentsui.DocumentsActivity.DisplayState.MODE_GRID;
import static com.android.documentsui.DocumentsActivity.DisplayState.MODE_LIST;
import static com.android.documentsui.DocumentsActivity.DisplayState.SORT_ORDER_DATE;
import static com.android.documentsui.DocumentsActivity.DisplayState.SORT_ORDER_NAME;
import static com.android.documentsui.DocumentsActivity.DisplayState.SORT_ORDER_DISPLAY_NAME;
import static com.android.documentsui.DocumentsActivity.DisplayState.SORT_ORDER_LAST_MODIFIED;
import static com.android.documentsui.DocumentsActivity.DisplayState.SORT_ORDER_SIZE;

import android.app.Fragment;
@@ -32,7 +32,6 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.net.Uri;
@@ -55,7 +54,6 @@ import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
@@ -64,7 +62,6 @@ import android.widget.Toast;

import com.android.documentsui.DocumentsActivity.DisplayState;
import com.android.documentsui.model.Document;
import com.android.documentsui.model.Root;
import com.android.internal.util.Predicate;
import com.google.android.collect.Lists;

@@ -81,7 +78,6 @@ public class DirectoryFragment extends Fragment {
    private View mEmptyView;
    private ListView mListView;
    private GridView mGridView;
    private Button mMoreView;

    private AbsListView mCurrentView;

@@ -110,7 +106,8 @@ public class DirectoryFragment extends Fragment {
    }

    public static void showSearch(FragmentManager fm, Uri uri, String query) {
        final Uri searchUri = DocumentsContract.buildSearchUri(uri, query);
        final Uri searchUri = DocumentsContract.buildSearchUri(
                uri.getAuthority(), DocumentsContract.getDocId(uri), query);
        show(fm, TYPE_SEARCH, searchUri);
    }

@@ -153,8 +150,6 @@ public class DirectoryFragment extends Fragment {
        mGridView.setOnItemClickListener(mItemListener);
        mGridView.setMultiChoiceModeListener(mMultiListener);

        mMoreView = (Button) view.findViewById(R.id.more);

        mAdapter = new DocumentsAdapter();

        final Uri uri = getArguments().getParcelable(EXTRA_URI);
@@ -168,22 +163,19 @@ public class DirectoryFragment extends Fragment {

                Uri contentsUri;
                if (mType == TYPE_NORMAL) {
                    contentsUri = DocumentsContract.buildContentsUri(uri);
                    contentsUri = DocumentsContract.buildChildrenUri(
                            uri.getAuthority(), DocumentsContract.getDocId(uri));
                } else if (mType == TYPE_RECENT_OPEN) {
                    contentsUri = RecentsProvider.buildRecentOpen();
                } else {
                    contentsUri = uri;
                }

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

                final Comparator<Document> sortOrder;
                if (state.sortOrder == SORT_ORDER_DATE || mType == TYPE_RECENT_OPEN) {
                    sortOrder = new Document.DateComparator();
                } else if (state.sortOrder == SORT_ORDER_NAME) {
                    sortOrder = new Document.NameComparator();
                if (state.sortOrder == SORT_ORDER_LAST_MODIFIED || mType == TYPE_RECENT_OPEN) {
                    sortOrder = new Document.LastModifiedComparator();
                } else if (state.sortOrder == SORT_ORDER_DISPLAY_NAME) {
                    sortOrder = new Document.DisplayNameComparator();
                } else if (state.sortOrder == SORT_ORDER_SIZE) {
                    sortOrder = new Document.SizeComparator();
                } else {
@@ -196,28 +188,6 @@ public class DirectoryFragment extends Fragment {
            @Override
            public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
                mAdapter.swapDocuments(result.contents);

                final Cursor cursor = result.cursor;
                if (cursor != null && cursor.getExtras()
                        .getBoolean(DocumentsContract.EXTRA_HAS_MORE, false)) {
                    mMoreView.setText(R.string.more);
                    mMoreView.setVisibility(View.VISIBLE);
                    mMoreView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mMoreView.setText(R.string.loading);
                            final Bundle bundle = new Bundle();
                            bundle.putBoolean(DocumentsContract.EXTRA_REQUEST_MORE, true);
                            try {
                                cursor.respond(bundle);
                            } catch (Exception e) {
                                Log.w(TAG, "Failed to respond: " + e);
                            }
                        }
                    });
                } else {
                    mMoreView.setVisibility(View.GONE);
                }
            }

            @Override
@@ -489,8 +459,7 @@ public class DirectoryFragment extends Fragment {
                    task.execute(doc.uri);
                }
            } else {
                icon.setImageDrawable(roots.resolveDocumentIcon(
                        context, doc.uri.getAuthority(), doc.mimeType));
                icon.setImageDrawable(RootsCache.resolveDocumentIcon(context, doc.mimeType));
            }

            title.setText(doc.displayName);
@@ -504,11 +473,7 @@ public class DirectoryFragment extends Fragment {
                    summary.setVisibility(View.INVISIBLE);
                }
            } else if (mType == TYPE_RECENT_OPEN) {
                final Root root = roots.findRoot(doc);
                icon1.setVisibility(View.VISIBLE);
                icon1.setImageDrawable(root.icon);
                summary.setText(root.getDirectoryString());
                summary.setVisibility(View.VISIBLE);
                // TODO: resolve storage root
            }

            if (summaryGrid != null) {
+3 −15
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ 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;
@@ -77,9 +76,10 @@ public class DirectoryLoader extends UriDerivativeLoader<Uri, DirectoryResult> {
    }

    private void loadInBackgroundInternal(
            DirectoryResult result, Uri uri, CancellationSignal signal) {
            DirectoryResult result, Uri uri, CancellationSignal signal) throws RuntimeException {
        // TODO: switch to using unstable CPC
        final ContentResolver resolver = getContext().getContentResolver();
        final Cursor cursor = resolver.query(uri, null, null, null, getQuerySortOrder(), signal);
        final Cursor cursor = resolver.query(uri, null, null, null, null, signal);
        result.cursor = cursor;
        result.cursor.registerContentObserver(mObserver);

@@ -110,16 +110,4 @@ public class DirectoryLoader extends UriDerivativeLoader<Uri, DirectoryResult> {
            Collections.sort(result.contents, mSortOrder);
        }
    }

    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;
        }
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -21,12 +21,11 @@ import static com.android.documentsui.DocumentsActivity.TAG;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.DocumentsContract.DocumentRoot;
import android.util.Log;

import com.android.documentsui.model.Root;

/**
 * Handles {@link Root} changes which invalidate cached data.
 * Handles {@link DocumentRoot} changes which invalidate cached data.
 */
public class DocumentChangedReceiver extends BroadcastReceiver {
    @Override
Loading