/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.provider;

import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull;
import static com.android.internal.util.Preconditions.checkCollectionNotEmpty;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.MimeTypeFilter;
import android.content.pm.ResolveInfo;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.ImageDecoder;
import android.graphics.Point;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.OnCloseListener;
import android.os.Parcelable;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;

import com.android.internal.util.Preconditions;

import dalvik.system.VMRuntime;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Defines the contract between a documents provider and the platform.
 * <p>
 * To create a document provider, extend {@link DocumentsProvider}, which
 * provides a foundational implementation of this contract.
 * <p>
 * All client apps must hold a valid URI permission grant to access documents,
 * typically issued when a user makes a selection through
 * {@link Intent#ACTION_OPEN_DOCUMENT}, {@link Intent#ACTION_CREATE_DOCUMENT},
 * or {@link Intent#ACTION_OPEN_DOCUMENT_TREE}.
 *
 * @see DocumentsProvider
 */
public final class DocumentsContract {
    private static final String TAG = "DocumentsContract";

    // content://com.example/root/
    // content://com.example/root/sdcard/
    // content://com.example/root/sdcard/recent/
    // content://com.example/root/sdcard/search/?query=pony
    // content://com.example/document/12/
    // content://com.example/document/12/children/
    // content://com.example/tree/12/document/24/
    // content://com.example/tree/12/document/24/children/

    private DocumentsContract() {
    }

    /**
     * Intent action used to identify {@link DocumentsProvider} instances. This
     * is used in the {@code <intent-filter>} of a {@code <provider>}.
     */
    public static final String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";

    /** {@hide} */
    @Deprecated
    public static final String EXTRA_PACKAGE_NAME = Intent.EXTRA_PACKAGE_NAME;

    /**
     * The value is decide whether to show advance mode or not.
     * If the value is true, the local/device storage root must be
     * visible in DocumentsUI.
     *
     * {@hide}
     */
    @SystemApi
    public static final String EXTRA_SHOW_ADVANCED = "android.provider.extra.SHOW_ADVANCED";

    /** {@hide} */
    public static final String EXTRA_TARGET_URI = "android.content.extra.TARGET_URI";

    /**
     * Key for {@link DocumentsProvider} to query display name is matched.
     * The match of display name is partial matching and case-insensitive.
     * Ex: The value is "o", the display name of the results will contain
     * both "foo" and "Open".
     *
     * @see DocumentsProvider#querySearchDocuments(String, String[],
     *      Bundle)
     */
    public static final String QUERY_ARG_DISPLAY_NAME = "android:query-arg-display-name";

    /**
     * Key for {@link DocumentsProvider} to query mime types is matched.
     * The value is a string array, it can support different mime types.
     * Each items will be treated as "OR" condition. Ex: {"image/*" ,
     * "video/*"}. The mime types of the results will contain both image
     * type and video type.
     *
     * @see DocumentsProvider#querySearchDocuments(String, String[],
     *      Bundle)
     */
    public static final String QUERY_ARG_MIME_TYPES = "android:query-arg-mime-types";

    /**
     * Key for {@link DocumentsProvider} to query the file size in bytes is
     * larger than the value.
     *
     * @see DocumentsProvider#querySearchDocuments(String, String[],
     *      Bundle)
     */
    public static final String QUERY_ARG_FILE_SIZE_OVER = "android:query-arg-file-size-over";

    /**
     * Key for {@link DocumentsProvider} to query the last modified time
     * is newer than the value. The unit is in milliseconds since
     * January 1, 1970 00:00:00.0 UTC.
     *
     * @see DocumentsProvider#querySearchDocuments(String, String[],
     *      Bundle)
     * @see Document#COLUMN_LAST_MODIFIED
     */
    public static final String QUERY_ARG_LAST_MODIFIED_AFTER =
            "android:query-arg-last-modified-after";

    /**
     * Key for {@link DocumentsProvider} to decide whether the files that
     * have been added to MediaStore should be excluded. If the value is
     * true, exclude them. Otherwise, include them.
     *
     * @see DocumentsProvider#querySearchDocuments(String, String[],
     *      Bundle)
     */
    public static final String QUERY_ARG_EXCLUDE_MEDIA = "android:query-arg-exclude-media";

    /**
     * Sets the desired initial location visible to user when file chooser is shown.
     *
     * <p>Applicable to {@link Intent} with actions:
     * <ul>
     *      <li>{@link Intent#ACTION_OPEN_DOCUMENT}</li>
     *      <li>{@link Intent#ACTION_CREATE_DOCUMENT}</li>
     *      <li>{@link Intent#ACTION_OPEN_DOCUMENT_TREE}</li>
     * </ul>
     *
     * <p>Location should specify a document URI or a tree URI with document ID. If
     * this URI identifies a non-directory, document navigator will attempt to use the parent
     * of the document as the initial location.
     *
     * <p>The initial location is system specific if this extra is missing or document navigator
     * failed to locate the desired initial location.
     */
    public static final String EXTRA_INITIAL_URI = "android.provider.extra.INITIAL_URI";

    /**
     * Set this in a DocumentsUI intent to cause a package's own roots to be
     * excluded from the roots list.
     */
    public static final String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";

    /**
     * An extra number of degrees that an image should be rotated during the
     * decode process to be presented correctly.
     *
     * @see AssetFileDescriptor#getExtras()
     * @see android.provider.MediaStore.Images.ImageColumns#ORIENTATION
     */
    public static final String EXTRA_ORIENTATION = "android.provider.extra.ORIENTATION";

    /**
     * Overrides the default prompt text in DocumentsUI when set in an intent.
     */
    public static final String EXTRA_PROMPT = "android.provider.extra.PROMPT";

    /**
     * Action of intent issued by DocumentsUI when user wishes to open/configure/manage a particular
     * document in the provider application.
     *
     * <p>When issued, the intent will include the URI of the document as the intent data.
     *
     * <p>A provider wishing to provide support for this action should do two things.
     * <li>Add an {@code <intent-filter>} matching this action.
     * <li>When supplying information in {@link DocumentsProvider#queryChildDocuments}, include
     * {@link Document#FLAG_SUPPORTS_SETTINGS} in the flags for each document that supports
     * settings.
     */
    public static final String
            ACTION_DOCUMENT_SETTINGS = "android.provider.action.DOCUMENT_SETTINGS";

    /**
     * The action to manage document in Downloads root in DocumentsUI.
     *  {@hide}
     */
    @SystemApi
    public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";

    /**
     * The action to launch the settings of this root.
     * {@hide}
     */
    @SystemApi
    public static final String
            ACTION_DOCUMENT_ROOT_SETTINGS = "android.provider.action.DOCUMENT_ROOT_SETTINGS";

    /** {@hide} */
    public static final String EXTERNAL_STORAGE_PROVIDER_AUTHORITY =
            "com.android.externalstorage.documents";

    /** {@hide} */
    public static final String EXTERNAL_STORAGE_PRIMARY_EMULATED_ROOT_ID = "primary";

    /** {@hide} */
    public static final String PACKAGE_DOCUMENTS_UI = "com.android.documentsui";

    /**
     * Get string array identifies the type or types of metadata returned
     * using DocumentsContract#getDocumentMetadata.
     *
     * @see #getDocumentMetadata(ContentResolver, Uri)
     */
    public static final String METADATA_TYPES = "android:documentMetadataTypes";

    /**
     * Get Exif information using DocumentsContract#getDocumentMetadata.
     *
     * @see #getDocumentMetadata(ContentResolver, Uri)
     */
    public static final String METADATA_EXIF = "android:documentExif";

    /**
     * Get total count of all documents currently stored under the given
     * directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
     *
     * @see #getDocumentMetadata(ContentResolver, Uri)
     */
    public static final String METADATA_TREE_COUNT = "android:metadataTreeCount";

    /**
     * Get total size of all documents currently stored under the given
     * directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
     *
     * @see #getDocumentMetadata(ContentResolver, Uri)
     */
    public static final String METADATA_TREE_SIZE = "android:metadataTreeSize";

    /**
     * Constants related to a document, including {@link Cursor} column names
     * and flags.
     * <p>
     * A document can be either an openable stream (with a specific MIME type),
     * or a directory containing additional documents (with the
     * {@link #MIME_TYPE_DIR} MIME type). A directory represents the top of a
     * subtree containing zero or more documents, which can recursively contain
     * even more documents and directories.
     * <p>
     * All columns are <em>read-only</em> to client applications.
     */
    public final static class Document {
        private Document() {
        }

        /**
         * Unique ID of a document. This ID is both provided by and interpreted
         * by a {@link DocumentsProvider}, and should be treated as an opaque
         * value by client applications. This column is required.
         * <p>
         * Each document must have a unique ID within a provider, but that
         * single document may be included as a child of multiple directories.
         * <p>
         * A provider must always return durable IDs, since they will be used to
         * issue long-term URI permission grants when an application interacts
         * with {@link Intent#ACTION_OPEN_DOCUMENT} and
         * {@link Intent#ACTION_CREATE_DOCUMENT}.
         * <p>
         * Type: STRING
         */
        public static final String COLUMN_DOCUMENT_ID = "document_id";

        /**
         * Concrete MIME type of a document. For example, "image/png" or
         * "application/pdf" for openable files. A document can also be a
         * directory containing additional documents, which is represented with
         * the {@link #MIME_TYPE_DIR} MIME type. This column is required.
         * <p>
         * Type: STRING
         *
         * @see #MIME_TYPE_DIR
         */
        public static final String COLUMN_MIME_TYPE = "mime_type";

        /**
         * Display name of a document, used as the primary title displayed to a
         * user. This column is required.
         * <p>
         * Type: STRING
         */
        public static final String COLUMN_DISPLAY_NAME = OpenableColumns.DISPLAY_NAME;

        /**
         * Summary of a document, which may be shown to a user. This column is
         * optional, and may be {@code null}.
         * <p>
         * Type: STRING
         */
        public static final String COLUMN_SUMMARY = "summary";

        /**
         * Timestamp when a document was last modified, in milliseconds since
         * January 1, 1970 00:00:00.0 UTC. This column is required, and may be
         * {@code null} if unknown. A {@link DocumentsProvider} can update this
         * field using events from {@link OnCloseListener} or other reliable
         * {@link ParcelFileDescriptor} transports.
         * <p>
         * Type: INTEGER (long)
         *
         * @see System#currentTimeMillis()
         */
        public static final String COLUMN_LAST_MODIFIED = "last_modified";

        /**
         * Specific icon resource ID for a document. This column is optional,
         * and may be {@code null} to use a platform-provided default icon based
         * on {@link #COLUMN_MIME_TYPE}.
         * <p>
         * Type: INTEGER (int)
         */
        public static final String COLUMN_ICON = "icon";

        /**
         * Flags that apply to a document. This column is required.
         * <p>
         * Type: INTEGER (int)
         *
         * @see #FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE
         * @see #FLAG_DIR_PREFERS_GRID
         * @see #FLAG_DIR_PREFERS_LAST_MODIFIED
         * @see #FLAG_DIR_SUPPORTS_CREATE
         * @see #FLAG_PARTIAL
         * @see #FLAG_SUPPORTS_COPY
         * @see #FLAG_SUPPORTS_DELETE
         * @see #FLAG_SUPPORTS_METADATA
         * @see #FLAG_SUPPORTS_MOVE
         * @see #FLAG_SUPPORTS_REMOVE
         * @see #FLAG_SUPPORTS_RENAME
         * @see #FLAG_SUPPORTS_SETTINGS
         * @see #FLAG_SUPPORTS_THUMBNAIL
         * @see #FLAG_SUPPORTS_WRITE
         * @see #FLAG_VIRTUAL_DOCUMENT
         * @see #FLAG_WEB_LINKABLE
         */
        public static final String COLUMN_FLAGS = "flags";

        /**
         * Size of a document, in bytes, or {@code null} if unknown. This column
         * is required.
         * <p>
         * Type: INTEGER (long)
         */
        public static final String COLUMN_SIZE = OpenableColumns.SIZE;

        /**
         * MIME type of a document which is a directory that may contain
         * additional documents.
         *
         * @see #COLUMN_MIME_TYPE
         */
        public static final String MIME_TYPE_DIR = "vnd.android.document/directory";

        /**
         * Flag indicating that a document can be represented as a thumbnail.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#getDocumentThumbnail(ContentResolver, Uri,
         *      Point, CancellationSignal)
         * @see DocumentsProvider#openDocumentThumbnail(String, Point,
         *      android.os.CancellationSignal)
         */
        public static final int FLAG_SUPPORTS_THUMBNAIL = 1;

        /**
         * Flag indicating that a document supports writing.
         * <p>
         * When a document is opened with {@link Intent#ACTION_OPEN_DOCUMENT},
         * the calling application is granted both
         * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and
         * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}. However, the actual
         * writability of a document may change over time, for example due to
         * remote access changes. This flag indicates that a document client can
         * expect {@link ContentResolver#openOutputStream(Uri)} to succeed.
         *
         * @see #COLUMN_FLAGS
         */
        public static final int FLAG_SUPPORTS_WRITE = 1 << 1;

        /**
         * Flag indicating that a document is deletable.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#deleteDocument(ContentResolver, Uri)
         * @see DocumentsProvider#deleteDocument(String)
         */
        public static final int FLAG_SUPPORTS_DELETE = 1 << 2;

        /**
         * Flag indicating that a document is a directory that supports creation
         * of new files within it. Only valid when {@link #COLUMN_MIME_TYPE} is
         * {@link #MIME_TYPE_DIR}.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsProvider#createDocument(String, String, String)
         */
        public static final int FLAG_DIR_SUPPORTS_CREATE = 1 << 3;

        /**
         * Flag indicating that a directory prefers its contents be shown in a
         * larger format grid. Usually suitable when a directory contains mostly
         * pictures. Only valid when {@link #COLUMN_MIME_TYPE} is
         * {@link #MIME_TYPE_DIR}.
         *
         * @see #COLUMN_FLAGS
         */
        public static final int FLAG_DIR_PREFERS_GRID = 1 << 4;

        /**
         * Flag indicating that a directory prefers its contents be sorted by
         * {@link #COLUMN_LAST_MODIFIED}. Only valid when
         * {@link #COLUMN_MIME_TYPE} is {@link #MIME_TYPE_DIR}.
         *
         * @see #COLUMN_FLAGS
         */
        public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 1 << 5;

        /**
         * Flag indicating that a document can be renamed.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#renameDocument(ContentResolver, Uri, String)
         * @see DocumentsProvider#renameDocument(String, String)
         */
        public static final int FLAG_SUPPORTS_RENAME = 1 << 6;

        /**
         * Flag indicating that a document can be copied to another location
         * within the same document provider.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#copyDocument(ContentResolver, Uri, Uri)
         * @see DocumentsProvider#copyDocument(String, String)
         */
        public static final int FLAG_SUPPORTS_COPY = 1 << 7;

        /**
         * Flag indicating that a document can be moved to another location
         * within the same document provider.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#moveDocument(ContentResolver, Uri, Uri, Uri)
         * @see DocumentsProvider#moveDocument(String, String, String)
         */
        public static final int FLAG_SUPPORTS_MOVE = 1 << 8;

        /**
         * Flag indicating that a document is virtual, and doesn't have byte
         * representation in the MIME type specified as {@link #COLUMN_MIME_TYPE}.
         *
         * <p><em>Virtual documents must have at least one alternative streamable
         * format via {@link DocumentsProvider#openTypedDocument}</em>
         *
         * @see #COLUMN_FLAGS
         * @see #COLUMN_MIME_TYPE
         * @see DocumentsProvider#openTypedDocument(String, String, Bundle,
         *      android.os.CancellationSignal)
         * @see DocumentsProvider#getDocumentStreamTypes(String, String)
         */
        public static final int FLAG_VIRTUAL_DOCUMENT = 1 << 9;

        /**
         * Flag indicating that a document can be removed from a parent.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#removeDocument(ContentResolver, Uri, Uri)
         * @see DocumentsProvider#removeDocument(String, String)
         */
        public static final int FLAG_SUPPORTS_REMOVE = 1 << 10;

        /**
         * Flag indicating that a document has settings that can be configured by user.
         *
         * @see #COLUMN_FLAGS
         * @see #ACTION_DOCUMENT_SETTINGS
         */
        public static final int FLAG_SUPPORTS_SETTINGS = 1 << 11;

        /**
         * Flag indicating that a Web link can be obtained for the document.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsProvider#createWebLinkIntent(String, Bundle)
         */
        public static final int FLAG_WEB_LINKABLE = 1 << 12;

        /**
         * Flag indicating that a document is not complete, likely its
         * contents are being downloaded. Partial files cannot be opened,
         * copied, moved in the UI. But they can be deleted and retried
         * if they represent a failed download.
         *
         * @see #COLUMN_FLAGS
         */
        public static final int FLAG_PARTIAL = 1 << 13;

        /**
         * Flag indicating that a document has available metadata that can be read
         * using DocumentsContract#getDocumentMetadata
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#getDocumentMetadata(ContentResolver, Uri)
         */
        public static final int FLAG_SUPPORTS_METADATA = 1 << 14;

        /**
         * Flag indicating that a document is a directory that wants to block itself
         * from being selected when the user launches an {@link Intent#ACTION_OPEN_DOCUMENT_TREE}
         * intent. Individual files can still be selected when launched via other intents
         * like {@link Intent#ACTION_OPEN_DOCUMENT} and {@link Intent#ACTION_GET_CONTENT}.
         * Only valid when {@link #COLUMN_MIME_TYPE} is {@link #MIME_TYPE_DIR}.
         * <p>
         * Note that this flag <em>only</em> applies to the single directory to which it is
         * applied. It does <em>not</em> block the user from selecting either a parent or
         * child directory during an {@link Intent#ACTION_OPEN_DOCUMENT_TREE} request.
         * In particular, the only way to guarantee that a specific directory can never
         * be granted via an {@link Intent#ACTION_OPEN_DOCUMENT_TREE} request is to ensure
         * that both it and <em>all of its parent directories</em> have set this flag.
         *
         * @see Intent#ACTION_OPEN_DOCUMENT_TREE
         * @see #COLUMN_FLAGS
         */
        public static final int FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE = 1 << 15;
    }

    /**
     * Constants related to a root of documents, including {@link Cursor} column
     * names and flags. A root is the start of a tree of documents, such as a
     * physical storage device, or an account. Each root starts at the directory
     * referenced by {@link Root#COLUMN_DOCUMENT_ID}, which can recursively
     * contain both documents and directories.
     * <p>
     * All columns are <em>read-only</em> to client applications.
     */
    public final static class Root {
        private Root() {
        }

        /**
         * Unique ID of a root. This ID is both provided by and interpreted by a
         * {@link DocumentsProvider}, and should be treated as an opaque value
         * by client applications. This column is required.
         * <p>
         * Type: STRING
         */
        public static final String COLUMN_ROOT_ID = "root_id";

        /**
         * Flags that apply to a root. This column is required.
         * <p>
         * Type: INTEGER (int)
         *
         * @see #FLAG_LOCAL_ONLY
         * @see #FLAG_SUPPORTS_CREATE
         * @see #FLAG_SUPPORTS_RECENTS
         * @see #FLAG_SUPPORTS_SEARCH
         */
        public static final String COLUMN_FLAGS = "flags";

        /**
         * Icon resource ID for a root. This column is required.
         * <p>
         * Type: INTEGER (int)
         */
        public static final String COLUMN_ICON = "icon";

        /**
         * Title for a root, which will be shown to a user. This column is
         * required. For a single storage service surfacing multiple accounts as
         * different roots, this title should be the name of the service.
         * <p>
         * Type: STRING
         */
        public static final String COLUMN_TITLE = "title";

        /**
         * Summary for this root, which may be shown to a user. This column is
         * optional, and may be {@code null}. For a single storage service
         * surfacing multiple accounts as different roots, this summary should
         * be the name of the account.
         * <p>
         * Type: STRING
         */
        public static final String COLUMN_SUMMARY = "summary";

        /**
         * Document which is a directory that represents the top directory of
         * this root. This column is required.
         * <p>
         * Type: STRING
         *
         * @see Document#COLUMN_DOCUMENT_ID
         */
        public static final String COLUMN_DOCUMENT_ID = "document_id";

        /**
         * Number of bytes available in this root. This column is optional, and
         * may be {@code null} if unknown or unbounded.
         * <p>
         * Type: INTEGER (long)
         */
        public static final String COLUMN_AVAILABLE_BYTES = "available_bytes";

        /**
         * Capacity of a root in bytes. This column is optional, and may be
         * {@code null} if unknown or unbounded.
         * <p>
         * Type: INTEGER (long)
         */
        public static final String COLUMN_CAPACITY_BYTES = "capacity_bytes";

        /**
         * MIME types supported by this root. This column is optional, and if
         * {@code null} the root is assumed to support all MIME types. Multiple
         * MIME types can be separated by a newline. For example, a root
         * supporting audio might return "audio/*\napplication/x-flac".
         * <p>
         * Type: STRING
         */
        public static final String COLUMN_MIME_TYPES = "mime_types";

        /**
         * Query arguments supported by this root. This column is optional
         * and related to {@link #COLUMN_FLAGS} and {@link #FLAG_SUPPORTS_SEARCH}.
         * If the flags include {@link #FLAG_SUPPORTS_SEARCH}, and the column is
         * {@code null}, the root is assumed to support {@link #QUERY_ARG_DISPLAY_NAME}
         * search of {@link Document#COLUMN_DISPLAY_NAME}. Multiple query arguments
         * can be separated by a newline. For example, a root supporting
         * {@link #QUERY_ARG_MIME_TYPES} and {@link #QUERY_ARG_DISPLAY_NAME} might
         * return "android:query-arg-mime-types\nandroid:query-arg-display-name".
         * <p>
         * Type: STRING
         * @see #COLUMN_FLAGS
         * @see #FLAG_SUPPORTS_SEARCH
         * @see #QUERY_ARG_DISPLAY_NAME
         * @see #QUERY_ARG_FILE_SIZE_OVER
         * @see #QUERY_ARG_LAST_MODIFIED_AFTER
         * @see #QUERY_ARG_MIME_TYPES
         * @see DocumentsProvider#querySearchDocuments(String, String[],
         *      Bundle)
         */
        public static final String COLUMN_QUERY_ARGS = "query_args";

        /**
         * MIME type for a root.
         */
        public static final String MIME_TYPE_ITEM = "vnd.android.document/root";

        /**
         * Flag indicating that at least one directory under this root supports
         * creating content. Roots with this flag will be shown when an
         * application interacts with {@link Intent#ACTION_CREATE_DOCUMENT}.
         *
         * @see #COLUMN_FLAGS
         */
        public static final int FLAG_SUPPORTS_CREATE = 1;

        /**
         * Flag indicating that this root offers content that is strictly local
         * on the device. That is, no network requests are made for the content.
         *
         * @see #COLUMN_FLAGS
         * @see Intent#EXTRA_LOCAL_ONLY
         */
        public static final int FLAG_LOCAL_ONLY = 1 << 1;

        /**
         * Flag indicating that this root can be queried to provide recently
         * modified documents.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#buildRecentDocumentsUri(String, String)
         * @see DocumentsProvider#queryRecentDocuments(String, String[])
         */
        public static final int FLAG_SUPPORTS_RECENTS = 1 << 2;

        /**
         * Flag indicating that this root supports search.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#buildSearchDocumentsUri(String, String,
         *      String)
         * @see DocumentsProvider#querySearchDocuments(String, String,
         *      String[])
         * @see DocumentsProvider#querySearchDocuments(String, String[],
         *      Bundle)
         */
        public static final int FLAG_SUPPORTS_SEARCH = 1 << 3;

        /**
         * Flag indicating that this root supports testing parent child
         * relationships.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsProvider#isChildDocument(String, String)
         */
        public static final int FLAG_SUPPORTS_IS_CHILD = 1 << 4;

        /**
         * Flag indicating that this root can be ejected.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#ejectRoot(ContentResolver, Uri)
         * @see DocumentsProvider#ejectRoot(String)
         */
        public static final int FLAG_SUPPORTS_EJECT = 1 << 5;

        /**
         * Flag indicating that this root is currently empty. This may be used
         * to hide the root when opening documents, but the root will still be
         * shown when creating documents and {@link #FLAG_SUPPORTS_CREATE} is
         * also set. If the value of this flag changes, such as when a root
         * becomes non-empty, you must send a content changed notification for
         * {@link DocumentsContract#buildRootsUri(String)}.
         *
         * @see #COLUMN_FLAGS
         * @see ContentResolver#notifyChange(Uri,
         *      android.database.ContentObserver, boolean)
         */
        public static final int FLAG_EMPTY = 1 << 6;

        /**
         * Flag indicating that this root should only be visible to advanced
         * users.
         *
         * @see #COLUMN_FLAGS
         * {@hide}
         */
        @SystemApi
        public static final int FLAG_ADVANCED = 1 << 16;

        /**
         * Flag indicating that this root has settings.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#ACTION_DOCUMENT_ROOT_SETTINGS
         * {@hide}
         */
        @SystemApi
        public static final int FLAG_HAS_SETTINGS = 1 << 17;

        /**
         * Flag indicating that this root is on removable SD card storage.
         *
         * @see #COLUMN_FLAGS
         * {@hide}
         */
        @SystemApi
        public static final int FLAG_REMOVABLE_SD = 1 << 18;

        /**
         * Flag indicating that this root is on removable USB storage.
         *
         * @see #COLUMN_FLAGS
         * {@hide}
         */
        @SystemApi
        public static final int FLAG_REMOVABLE_USB = 1 << 19;
    }

    /**
     * Optional boolean flag included in a directory {@link Cursor#getExtras()}
     * indicating that a document provider is still loading data. For example, a
     * provider has returned some results, but is still waiting on an
     * outstanding network request. The provider must send a content changed
     * notification when loading is finished.
     *
     * @see ContentResolver#notifyChange(Uri, android.database.ContentObserver,
     *      boolean)
     */
    public static final String EXTRA_LOADING = "loading";

    /**
     * Optional string included in a directory {@link Cursor#getExtras()}
     * providing an informational message that should be shown to a user. For
     * example, a provider may wish to indicate that not all documents are
     * available.
     */
    public static final String EXTRA_INFO = "info";

    /**
     * Optional string included in a directory {@link Cursor#getExtras()}
     * providing an error message that should be shown to a user. For example, a
     * provider may wish to indicate that a network error occurred. The user may
     * choose to retry, resulting in a new query.
     */
    public static final String EXTRA_ERROR = "error";

    /**
     * Optional result (I'm thinking boolean) answer to a question.
     * {@hide}
     */
    public static final String EXTRA_RESULT = "result";

    /** {@hide} */
    @UnsupportedAppUsage
    public static final String METHOD_CREATE_DOCUMENT = "android:createDocument";
    /** {@hide} */
    public static final String METHOD_RENAME_DOCUMENT = "android:renameDocument";
    /** {@hide} */
    public static final String METHOD_DELETE_DOCUMENT = "android:deleteDocument";
    /** {@hide} */
    public static final String METHOD_COPY_DOCUMENT = "android:copyDocument";
    /** {@hide} */
    public static final String METHOD_MOVE_DOCUMENT = "android:moveDocument";
    /** {@hide} */
    public static final String METHOD_IS_CHILD_DOCUMENT = "android:isChildDocument";
    /** {@hide} */
    public static final String METHOD_REMOVE_DOCUMENT = "android:removeDocument";
    /** {@hide} */
    public static final String METHOD_EJECT_ROOT = "android:ejectRoot";
    /** {@hide} */
    public static final String METHOD_FIND_DOCUMENT_PATH = "android:findDocumentPath";
    /** {@hide} */
    public static final String METHOD_CREATE_WEB_LINK_INTENT = "android:createWebLinkIntent";
    /** {@hide} */
    public static final String METHOD_GET_DOCUMENT_METADATA = "android:getDocumentMetadata";

    /** {@hide} */
    public static final String EXTRA_PARENT_URI = "parentUri";
    /** {@hide} */
    public static final String EXTRA_URI = "uri";
    /** {@hide} */
    public static final String EXTRA_URI_PERMISSIONS = "uriPermissions";

    /** {@hide} */
    public static final String EXTRA_OPTIONS = "options";

    private static final String PATH_ROOT = "root";
    private static final String PATH_RECENT = "recent";
    @UnsupportedAppUsage
    private static final String PATH_DOCUMENT = "document";
    private static final String PATH_CHILDREN = "children";
    private static final String PATH_SEARCH = "search";
    @UnsupportedAppUsage
    private static final String PATH_TREE = "tree";

    private static final String PARAM_QUERY = "query";
    private static final String PARAM_MANAGE = "manage";

    /**
     * Build URI representing the roots of a document provider. When queried, a
     * provider will return one or more rows with columns defined by
     * {@link Root}.
     *
     * @see DocumentsProvider#queryRoots(String[])
     */
    public static Uri buildRootsUri(String authority) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .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
     * in a document provider. When queried, a provider will return zero or more
     * rows with columns defined by {@link Document}.
     *
     * @see DocumentsProvider#queryRecentDocuments(String, String[])
     * @see #getRootId(Uri)
     */
    public static Uri buildRecentDocumentsUri(String authority, String rootId) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority).appendPath(PATH_ROOT).appendPath(rootId)
                .appendPath(PATH_RECENT).build();
    }

    /**
     * Build URI representing access to descendant documents of the given
     * {@link Document#COLUMN_DOCUMENT_ID}.
     *
     * @see #getTreeDocumentId(Uri)
     */
    public static Uri buildTreeDocumentUri(String authority, String documentId) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
                .appendPath(PATH_TREE).appendPath(documentId).build();
    }

    /**
     * Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in
     * a document provider. When queried, a provider will return a single row
     * with columns defined by {@link Document}.
     *
     * @see DocumentsProvider#queryDocument(String, String[])
     * @see #getDocumentId(Uri)
     */
    public static Uri buildDocumentUri(String authority, String documentId) {
        return getBaseDocumentUriBuilder(authority).appendPath(documentId).build();
    }

    /**
     * Builds URI as described in {@link #buildDocumentUri(String, String)}, but such that it will
     * be associated with the given user.
     *
     * @hide
     */
    @SystemApi
    @NonNull
    public static Uri buildDocumentUriAsUser(
            @NonNull String authority, @NonNull String documentId, @NonNull UserHandle user) {
        return ContentProvider.maybeAddUserId(
                buildDocumentUri(authority, documentId), user.getIdentifier());
    }

    /** {@hide} */
    public static Uri buildBaseDocumentUri(String authority) {
        return getBaseDocumentUriBuilder(authority).build();
    }

    private static Uri.Builder getBaseDocumentUriBuilder(String authority) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
            .authority(authority).appendPath(PATH_DOCUMENT);
    }

    /**
     * Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in
     * a document provider. When queried, a provider will return a single row
     * with columns defined by {@link Document}.
     * <p>
     * However, instead of directly accessing the target document, the returned
     * URI will leverage access granted through a subtree URI, typically
     * returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target document
     * must be a descendant (child, grandchild, etc) of the subtree.
     * <p>
     * This is typically used to access documents under a user-selected
     * directory tree, since it doesn't require the user to separately confirm
     * each new document access.
     *
     * @param treeUri the subtree to leverage to gain access to the target
     *            document. The target directory must be a descendant of this
     *            subtree.
     * @param documentId the target document, which the caller may not have
     *            direct access to.
     * @see Intent#ACTION_OPEN_DOCUMENT_TREE
     * @see DocumentsProvider#isChildDocument(String, String)
     * @see #buildDocumentUri(String, String)
     */
    public static Uri buildDocumentUriUsingTree(Uri treeUri, String documentId) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(treeUri.getAuthority()).appendPath(PATH_TREE)
                .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT)
                .appendPath(documentId).build();
    }

    /** {@hide} */
    public static Uri buildDocumentUriMaybeUsingTree(Uri baseUri, String documentId) {
        if (isTreeUri(baseUri)) {
            return buildDocumentUriUsingTree(baseUri, documentId);
        } else {
            return buildDocumentUri(baseUri.getAuthority(), documentId);
        }
    }

    /**
     * Build URI representing the children of the target directory in a document
     * provider. When queried, a provider will return zero or more rows with
     * columns defined by {@link Document}.
     *
     * @param parentDocumentId the document to return children for, which must
     *            be a directory with MIME type of
     *            {@link Document#MIME_TYPE_DIR}.
     * @see DocumentsProvider#queryChildDocuments(String, String[], String)
     * @see #getDocumentId(Uri)
     */
    public static Uri buildChildDocumentsUri(String authority, String parentDocumentId) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
                .appendPath(PATH_DOCUMENT).appendPath(parentDocumentId).appendPath(PATH_CHILDREN)
                .build();
    }

    /**
     * Build URI representing the children of the target directory in a document
     * provider. When queried, a provider will return zero or more rows with
     * columns defined by {@link Document}.
     * <p>
     * However, instead of directly accessing the target directory, the returned
     * URI will leverage access granted through a subtree URI, typically
     * returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target
     * directory must be a descendant (child, grandchild, etc) of the subtree.
     * <p>
     * This is typically used to access documents under a user-selected
     * directory tree, since it doesn't require the user to separately confirm
     * each new document access.
     *
     * @param treeUri the subtree to leverage to gain access to the target
     *            document. The target directory must be a descendant of this
     *            subtree.
     * @param parentDocumentId the document to return children for, which the
     *            caller may not have direct access to, and which must be a
     *            directory with MIME type of {@link Document#MIME_TYPE_DIR}.
     * @see Intent#ACTION_OPEN_DOCUMENT_TREE
     * @see DocumentsProvider#isChildDocument(String, String)
     * @see #buildChildDocumentsUri(String, String)
     */
    public static Uri buildChildDocumentsUriUsingTree(Uri treeUri, String parentDocumentId) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(treeUri.getAuthority()).appendPath(PATH_TREE)
                .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT)
                .appendPath(parentDocumentId).appendPath(PATH_CHILDREN).build();
    }

    /**
     * Build URI representing a search for matching documents under a specific
     * root in a document provider. When queried, a provider will return zero or
     * more rows with columns defined by {@link Document}.
     *
     * @see DocumentsProvider#querySearchDocuments(String, String, String[])
     * @see #getRootId(Uri)
     * @see #getSearchDocumentsQuery(Uri)
     */
    public static Uri buildSearchDocumentsUri(
            String authority, String rootId, String query) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
                .appendPath(PATH_ROOT).appendPath(rootId).appendPath(PATH_SEARCH)
                .appendQueryParameter(PARAM_QUERY, query).build();
    }

    /**
     * Check if the values match the query arguments.
     *
     * @param queryArgs the query arguments
     * @param displayName the display time to check against
     * @param mimeType the mime type to check against
     * @param lastModified the last modified time to check against
     * @param size the size to check against
     * @hide
     */
    public static boolean matchSearchQueryArguments(Bundle queryArgs, String displayName,
            String mimeType, long lastModified, long size) {
        if (queryArgs == null) {
            return true;
        }

        final String argDisplayName = queryArgs.getString(QUERY_ARG_DISPLAY_NAME, "");
        if (!argDisplayName.isEmpty()) {
            // TODO (118795812) : Enhance the search string handled in DocumentsProvider
            if (!displayName.toLowerCase().contains(argDisplayName.toLowerCase())) {
                return false;
            }
        }

        final long argFileSize = queryArgs.getLong(QUERY_ARG_FILE_SIZE_OVER, -1 /* defaultValue */);
        if (argFileSize != -1 && size < argFileSize) {
            return false;
        }

        final long argLastModified = queryArgs.getLong(QUERY_ARG_LAST_MODIFIED_AFTER,
                -1 /* defaultValue */);
        if (argLastModified != -1 && lastModified < argLastModified) {
            return false;
        }

        final String[] argMimeTypes = queryArgs.getStringArray(QUERY_ARG_MIME_TYPES);
        if (argMimeTypes != null && argMimeTypes.length > 0) {
            mimeType = Intent.normalizeMimeType(mimeType);
            for (String type : argMimeTypes) {
                if (MimeTypeFilter.matches(mimeType, Intent.normalizeMimeType(type))) {
                    return true;
                }
            }
            return false;
        }
        return true;
    }

    /**
     * Get the handled query arguments from the query bundle. The handled arguments are
     * {@link DocumentsContract#QUERY_ARG_EXCLUDE_MEDIA},
     * {@link DocumentsContract#QUERY_ARG_DISPLAY_NAME},
     * {@link DocumentsContract#QUERY_ARG_MIME_TYPES},
     * {@link DocumentsContract#QUERY_ARG_FILE_SIZE_OVER} and
     * {@link DocumentsContract#QUERY_ARG_LAST_MODIFIED_AFTER}.
     *
     * @param queryArgs the query arguments to be parsed.
     * @return the handled query arguments
     * @hide
     */
    public static String[] getHandledQueryArguments(Bundle queryArgs) {
        if (queryArgs == null) {
            return new String[0];
        }

        final ArrayList<String> args = new ArrayList<>();

        if (queryArgs.keySet().contains(QUERY_ARG_EXCLUDE_MEDIA)) {
            args.add(QUERY_ARG_EXCLUDE_MEDIA);
        }

        if (queryArgs.keySet().contains(QUERY_ARG_DISPLAY_NAME)) {
            args.add(QUERY_ARG_DISPLAY_NAME);
        }

        if (queryArgs.keySet().contains(QUERY_ARG_FILE_SIZE_OVER)) {
            args.add(QUERY_ARG_FILE_SIZE_OVER);
        }

        if (queryArgs.keySet().contains(QUERY_ARG_LAST_MODIFIED_AFTER)) {
            args.add(QUERY_ARG_LAST_MODIFIED_AFTER);
        }

        if (queryArgs.keySet().contains(QUERY_ARG_MIME_TYPES)) {
            args.add(QUERY_ARG_MIME_TYPES);
        }
        return args.toArray(new String[0]);
    }

    /**
     * Test if the given URI represents a {@link Document} backed by a
     * {@link DocumentsProvider}.
     *
     * @see #buildDocumentUri(String, String)
     * @see #buildDocumentUriUsingTree(Uri, String)
     */
    public static boolean isDocumentUri(Context context, @Nullable Uri uri) {
        if (isContentUri(uri) && isDocumentsProvider(context, uri.getAuthority())) {
            final List<String> paths = uri.getPathSegments();
            if (paths.size() == 2) {
                return PATH_DOCUMENT.equals(paths.get(0));
            } else if (paths.size() == 4) {
                return PATH_TREE.equals(paths.get(0)) && PATH_DOCUMENT.equals(paths.get(2));
            }
        }
        return false;
    }

    /**
     * Test if the given URI represents all roots of the authority
     * backed by {@link DocumentsProvider}.
     *
     * @see #buildRootsUri(String)
     */
    public static boolean isRootsUri(@NonNull Context context, @Nullable Uri uri) {
        Preconditions.checkNotNull(context, "context can not be null");
        return isRootUri(context, uri, 1 /* pathSize */);
    }

    /**
     * Test if the given URI represents specific root backed by {@link DocumentsProvider}.
     *
     * @see #buildRootUri(String, String)
     */
    public static boolean isRootUri(@NonNull Context context, @Nullable Uri uri) {
        Preconditions.checkNotNull(context, "context can not be null");
        return isRootUri(context, uri, 2 /* pathSize */);
    }

    /** {@hide} */
    public static boolean isContentUri(@Nullable Uri uri) {
        return uri != null && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme());
    }

    /**
     * Test if the given URI represents a {@link Document} tree.
     *
     * @see #buildTreeDocumentUri(String, String)
     * @see #getTreeDocumentId(Uri)
     */
    public static boolean isTreeUri(Uri uri) {
        final List<String> paths = uri.getPathSegments();
        return (paths.size() >= 2 && PATH_TREE.equals(paths.get(0)));
    }

    private static boolean isRootUri(Context context, @Nullable Uri uri, int pathSize) {
        if (isContentUri(uri) && isDocumentsProvider(context, uri.getAuthority())) {
            final List<String> paths = uri.getPathSegments();
            return (paths.size() == pathSize && PATH_ROOT.equals(paths.get(0)));
        }
        return false;
    }

    private static boolean isDocumentsProvider(Context context, String authority) {
        final Intent intent = new Intent(PROVIDER_INTERFACE);
        final List<ResolveInfo> infos = context.getPackageManager()
                .queryIntentContentProviders(intent, 0);
        for (ResolveInfo info : infos) {
            if (authority.equals(info.providerInfo.authority)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Extract the {@link Root#COLUMN_ROOT_ID} from the given URI.
     */
    public static String getRootId(Uri rootUri) {
        final List<String> paths = rootUri.getPathSegments();
        if (paths.size() >= 2 && PATH_ROOT.equals(paths.get(0))) {
            return paths.get(1);
        }
        throw new IllegalArgumentException("Invalid URI: " + rootUri);
    }

    /**
     * Extract the {@link Document#COLUMN_DOCUMENT_ID} from the given URI.
     *
     * @see #isDocumentUri(Context, Uri)
     */
    public static String getDocumentId(Uri documentUri) {
        final List<String> paths = documentUri.getPathSegments();
        if (paths.size() >= 2 && PATH_DOCUMENT.equals(paths.get(0))) {
            return paths.get(1);
        }
        if (paths.size() >= 4 && PATH_TREE.equals(paths.get(0))
                && PATH_DOCUMENT.equals(paths.get(2))) {
            return paths.get(3);
        }
        throw new IllegalArgumentException("Invalid URI: " + documentUri);
    }

    /**
     * Extract the via {@link Document#COLUMN_DOCUMENT_ID} from the given URI.
     */
    public static String getTreeDocumentId(Uri documentUri) {
        final List<String> paths = documentUri.getPathSegments();
        if (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))) {
            return paths.get(1);
        }
        throw new IllegalArgumentException("Invalid URI: " + documentUri);
    }

    /**
     * Extract the search query from a URI built by
     * {@link #buildSearchDocumentsUri(String, String, String)}.
     */
    public static String getSearchDocumentsQuery(Uri searchDocumentsUri) {
        return searchDocumentsUri.getQueryParameter(PARAM_QUERY);
    }

    /**
     * Extract the search query from a Bundle
     * {@link #QUERY_ARG_DISPLAY_NAME}.
     * {@hide}
     */
    public static String getSearchDocumentsQuery(@NonNull Bundle bundle) {
        Preconditions.checkNotNull(bundle, "bundle can not be null");
        return bundle.getString(QUERY_ARG_DISPLAY_NAME, "" /* defaultValue */);
    }

    /**
     * Build URI that append the query parameter {@link PARAM_MANAGE} to
     * enable the manage mode.
     * @see DocumentsProvider#queryChildDocumentsForManage(String parentDocId, String[], String)
     * {@hide}
     */
    @SystemApi
    @TestApi
    public static @NonNull Uri setManageMode(@NonNull Uri uri) {
        Preconditions.checkNotNull(uri, "uri can not be null");
        return uri.buildUpon().appendQueryParameter(PARAM_MANAGE, "true").build();
    }

    /**
     * Extract the manage mode from a URI built by
     * {@link #setManageMode(Uri)}.
     * {@hide}
     */
    @SystemApi
    @TestApi
    public static boolean isManageMode(@NonNull Uri uri) {
        Preconditions.checkNotNull(uri, "uri can not be null");
        return uri.getBooleanQueryParameter(PARAM_MANAGE, false);
    }

    /**
     * Return thumbnail representing the document at the given URI. Callers are
     * responsible for their own in-memory caching.
     *
     * @param documentUri document to return thumbnail for, which must have
     *            {@link Document#FLAG_SUPPORTS_THUMBNAIL} set.
     * @param size optimal thumbnail size desired. A provider may return a
     *            thumbnail of a different size, but never more than double the
     *            requested size.
     * @param signal signal used to indicate if caller is no longer interested
     *            in the thumbnail.
     * @return decoded thumbnail, or {@code null} if problem was encountered.
     * @see DocumentsProvider#openDocumentThumbnail(String, Point,
     *      android.os.CancellationSignal)
     */
    public static @Nullable Bitmap getDocumentThumbnail(@NonNull ContentResolver content,
            @NonNull Uri documentUri, @NonNull Point size, @Nullable CancellationSignal signal)
            throws FileNotFoundException {
        try {
            return ContentResolver.loadThumbnail(content, documentUri, Point.convert(size), signal,
                    ImageDecoder.ALLOCATOR_SOFTWARE);
        } catch (Exception e) {
            if (!(e instanceof OperationCanceledException)) {
                Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e);
            }
            rethrowIfNecessary(e);
            return null;
        }
    }

    /**
     * Create a new document with given MIME type and display name.
     *
     * @param parentDocumentUri directory with {@link Document#FLAG_DIR_SUPPORTS_CREATE}
     * @param mimeType MIME type of new document
     * @param displayName name of new document
     * @return newly created document, or {@code null} if failed
     */
    public static @Nullable Uri createDocument(@NonNull ContentResolver content,
            @NonNull Uri parentDocumentUri, @NonNull String mimeType, @NonNull String displayName)
            throws FileNotFoundException {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, parentDocumentUri);
            in.putString(Document.COLUMN_MIME_TYPE, mimeType);
            in.putString(Document.COLUMN_DISPLAY_NAME, displayName);

            final Bundle out = content.call(parentDocumentUri.getAuthority(),
                    METHOD_CREATE_DOCUMENT, null, in);
            return out.getParcelable(DocumentsContract.EXTRA_URI);
        } catch (Exception e) {
            Log.w(TAG, "Failed to create document", e);
            rethrowIfNecessary(e);
            return null;
        }
    }

    /**
     * Test if a document is descendant (child, grandchild, etc) from the given
     * parent.
     *
     * @param parentDocumentUri parent to verify against.
     * @param childDocumentUri child to verify.
     * @return if given document is a descendant of the given parent.
     * @see Root#FLAG_SUPPORTS_IS_CHILD
     */
    public static boolean isChildDocument(@NonNull ContentResolver content,
            @NonNull Uri parentDocumentUri, @NonNull Uri childDocumentUri)
            throws FileNotFoundException {
        Preconditions.checkNotNull(content, "content can not be null");
        Preconditions.checkNotNull(parentDocumentUri, "parentDocumentUri can not be null");
        Preconditions.checkNotNull(childDocumentUri, "childDocumentUri can not be null");
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, parentDocumentUri);
            in.putParcelable(DocumentsContract.EXTRA_TARGET_URI, childDocumentUri);

            final Bundle out = content.call(parentDocumentUri.getAuthority(),
                    METHOD_IS_CHILD_DOCUMENT, null, in);
            if (out == null) {
                throw new RemoteException("Failed to get a response from isChildDocument query.");
            }
            if (!out.containsKey(DocumentsContract.EXTRA_RESULT)) {
                throw new RemoteException("Response did not include result field..");
            }
            return out.getBoolean(DocumentsContract.EXTRA_RESULT);
        } catch (Exception e) {
            Log.w(TAG, "Failed to create document", e);
            rethrowIfNecessary(e);
            return false;
        }
    }

    /**
     * Change the display name of an existing document.
     * <p>
     * If the underlying provider needs to create a new
     * {@link Document#COLUMN_DOCUMENT_ID} to represent the updated display
     * name, that new document is returned and the original document is no
     * longer valid. Otherwise, the original document is returned.
     *
     * @param documentUri document with {@link Document#FLAG_SUPPORTS_RENAME}
     * @param displayName updated name for document
     * @return the existing or new document after the rename, or {@code null} if
     *         failed.
     */
    public static @Nullable Uri renameDocument(@NonNull ContentResolver content,
            @NonNull Uri documentUri, @NonNull String displayName) throws FileNotFoundException {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, documentUri);
            in.putString(Document.COLUMN_DISPLAY_NAME, displayName);

            final Bundle out = content.call(documentUri.getAuthority(),
                    METHOD_RENAME_DOCUMENT, null, in);
            final Uri outUri = out.getParcelable(DocumentsContract.EXTRA_URI);
            return (outUri != null) ? outUri : documentUri;
        } catch (Exception e) {
            Log.w(TAG, "Failed to rename document", e);
            rethrowIfNecessary(e);
            return null;
        }
    }

    /**
     * Delete the given document.
     *
     * @param documentUri document with {@link Document#FLAG_SUPPORTS_DELETE}
     * @return if the document was deleted successfully.
     */
    public static boolean deleteDocument(@NonNull ContentResolver content, @NonNull Uri documentUri)
            throws FileNotFoundException {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, documentUri);

            content.call(documentUri.getAuthority(),
                    METHOD_DELETE_DOCUMENT, null, in);
            return true;
        } catch (Exception e) {
            Log.w(TAG, "Failed to delete document", e);
            rethrowIfNecessary(e);
            return false;
        }
    }

    /**
     * Copies the given document.
     *
     * @param sourceDocumentUri document with {@link Document#FLAG_SUPPORTS_COPY}
     * @param targetParentDocumentUri document which will become a parent of the source
     *         document's copy.
     * @return the copied document, or {@code null} if failed.
     */
    public static @Nullable Uri copyDocument(@NonNull ContentResolver content,
            @NonNull Uri sourceDocumentUri, @NonNull Uri targetParentDocumentUri)
            throws FileNotFoundException {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, sourceDocumentUri);
            in.putParcelable(DocumentsContract.EXTRA_TARGET_URI, targetParentDocumentUri);

            final Bundle out = content.call(sourceDocumentUri.getAuthority(),
                    METHOD_COPY_DOCUMENT, null, in);
            return out.getParcelable(DocumentsContract.EXTRA_URI);
        } catch (Exception e) {
            Log.w(TAG, "Failed to copy document", e);
            rethrowIfNecessary(e);
            return null;
        }
    }

    /**
     * Moves the given document under a new parent.
     *
     * @param sourceDocumentUri document with {@link Document#FLAG_SUPPORTS_MOVE}
     * @param sourceParentDocumentUri parent document of the document to move.
     * @param targetParentDocumentUri document which will become a new parent of the source
     *         document.
     * @return the moved document, or {@code null} if failed.
     */
    public static @Nullable Uri moveDocument(@NonNull ContentResolver content,
            @NonNull Uri sourceDocumentUri, @NonNull Uri sourceParentDocumentUri,
            @NonNull Uri targetParentDocumentUri) throws FileNotFoundException {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, sourceDocumentUri);
            in.putParcelable(DocumentsContract.EXTRA_PARENT_URI, sourceParentDocumentUri);
            in.putParcelable(DocumentsContract.EXTRA_TARGET_URI, targetParentDocumentUri);

            final Bundle out = content.call(sourceDocumentUri.getAuthority(),
                    METHOD_MOVE_DOCUMENT, null, in);
            return out.getParcelable(DocumentsContract.EXTRA_URI);
        } catch (Exception e) {
            Log.w(TAG, "Failed to move document", e);
            rethrowIfNecessary(e);
            return null;
        }
    }

    /**
     * Removes the given document from a parent directory.
     *
     * <p>In contrast to {@link #deleteDocument} it requires specifying the parent.
     * This method is especially useful if the document can be in multiple parents.
     *
     * @param documentUri document with {@link Document#FLAG_SUPPORTS_REMOVE}
     * @param parentDocumentUri parent document of the document to remove.
     * @return true if the document was removed successfully.
     */
    public static boolean removeDocument(@NonNull ContentResolver content, @NonNull Uri documentUri,
            @NonNull Uri parentDocumentUri) throws FileNotFoundException {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, documentUri);
            in.putParcelable(DocumentsContract.EXTRA_PARENT_URI, parentDocumentUri);

            content.call(documentUri.getAuthority(),
                    METHOD_REMOVE_DOCUMENT, null, in);
            return true;
        } catch (Exception e) {
            Log.w(TAG, "Failed to remove document", e);
            rethrowIfNecessary(e);
            return false;
        }
    }

    /**
     * Ejects the given root. It throws {@link IllegalStateException} when ejection failed.
     *
     * @param rootUri root with {@link Root#FLAG_SUPPORTS_EJECT} to be ejected
     */
    public static void ejectRoot(@NonNull ContentResolver content, @NonNull Uri rootUri) {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, rootUri);

            content.call(rootUri.getAuthority(),
                    METHOD_EJECT_ROOT, null, in);
        } catch (Exception e) {
            Log.w(TAG, "Failed to eject", e);
        }
    }

    /**
     * Returns metadata associated with the document. The type of metadata returned
     * is specific to the document type. For example the data returned for an image
     * file will likely consist primarily or solely of EXIF metadata.
     *
     * <p>The returned {@link Bundle} will contain zero or more entries depending
     * on the type of data supported by the document provider.
     *
     * <ol>
     * <li>A {@link DocumentsContract#METADATA_TYPES} containing a {@code String[]} value.
     *     The string array identifies the type or types of metadata returned. Each
     *     value in the can be used to access a {@link Bundle} of data
     *     containing that type of data.
     * <li>An entry each for each type of returned metadata. Each set of metadata is
     *     itself represented as a bundle and accessible via a string key naming
     *     the type of data.
     * </ol>
     *
     * <p>Example:
     * <p><pre><code>
     *     Bundle metadata = DocumentsContract.getDocumentMetadata(client, imageDocUri, tags);
     *     if (metadata.containsKey(DocumentsContract.METADATA_EXIF)) {
     *         Bundle exif = metadata.getBundle(DocumentsContract.METADATA_EXIF);
     *         int imageLength = exif.getInt(ExifInterface.TAG_IMAGE_LENGTH);
     *     }
     * </code></pre>
     *
     * @param documentUri a Document URI
     * @return a Bundle of Bundles.
     */
    public static @Nullable Bundle getDocumentMetadata(@NonNull ContentResolver content,
            @NonNull Uri documentUri) throws FileNotFoundException {
        Preconditions.checkNotNull(content, "content can not be null");
        Preconditions.checkNotNull(documentUri, "documentUri can not be null");
        try {
            final Bundle in = new Bundle();
            in.putParcelable(EXTRA_URI, documentUri);

            return content.call(documentUri.getAuthority(),
                    METHOD_GET_DOCUMENT_METADATA, null, in);
        } catch (Exception e) {
            Log.w(TAG, "Failed to get document metadata");
            rethrowIfNecessary(e);
            return null;
        }
    }

    /**
     * Finds the canonical path from the top of the document tree.
     *
     * The {@link Path#getPath()} of the return value contains the document ID
     * of all documents along the path from the top the document tree to the
     * requested document, both inclusive.
     *
     * The {@link Path#getRootId()} of the return value returns {@code null}.
     *
     * @param treeUri treeUri of the document which path is requested.
     * @return the path of the document, or {@code null} if failed.
     * @see DocumentsProvider#findDocumentPath(String, String)
     */
    public static @Nullable Path findDocumentPath(@NonNull ContentResolver content,
            @NonNull Uri treeUri) throws FileNotFoundException {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, treeUri);

            final Bundle out = content.call(treeUri.getAuthority(),
                    METHOD_FIND_DOCUMENT_PATH, null, in);
            return out.getParcelable(DocumentsContract.EXTRA_RESULT);
        } catch (Exception e) {
            Log.w(TAG, "Failed to find path", e);
            rethrowIfNecessary(e);
            return null;
        }
    }

    /**
     * Creates an intent for obtaining a web link for the specified document.
     *
     * <p>Note, that due to internal limitations, if there is already a web link
     * intent created for the specified document but with different options,
     * then it may be overridden.
     *
     * <p>Providers are required to show confirmation UI for all new permissions granted
     * for the linked document.
     *
     * <p>If list of recipients is known, then it should be passed in options as
     * {@link Intent#EXTRA_EMAIL} as a list of email addresses. Note, that
     * this is just a hint for the provider, which can ignore the list. In either
     * case the provider is required to show a UI for letting the user confirm
     * any new permission grants.
     *
     * <p>Note, that the entire <code>options</code> bundle will be sent to the provider
     * backing the passed <code>uri</code>. Make sure that you trust the provider
     * before passing any sensitive information.
     *
     * <p>Since this API may show a UI, it cannot be called from background.
     *
     * <p>In order to obtain the Web Link use code like this:
     * <pre><code>
     * void onSomethingHappened() {
     *   IntentSender sender = DocumentsContract.createWebLinkIntent(<i>...</i>);
     *   if (sender != null) {
     *     startIntentSenderForResult(
     *         sender,
     *         WEB_LINK_REQUEST_CODE,
     *         null, 0, 0, 0, null);
     *   }
     * }
     *
     * <i>(...)</i>
     *
     * void onActivityResult(int requestCode, int resultCode, Intent data) {
     *   if (requestCode == WEB_LINK_REQUEST_CODE && resultCode == RESULT_OK) {
     *     Uri weblinkUri = data.getData();
     *     <i>...</i>
     *   }
     * }
     * </code></pre>
     *
     * @param uri uri for the document to create a link to.
     * @param options Extra information for generating the link.
     * @return an intent sender to obtain the web link, or null if the document
     *      is not linkable, or creating the intent sender failed.
     * @see DocumentsProvider#createWebLinkIntent(String, Bundle)
     * @see Intent#EXTRA_EMAIL
     */
    public static @Nullable IntentSender createWebLinkIntent(@NonNull ContentResolver content,
            @NonNull Uri uri, @Nullable Bundle options) throws FileNotFoundException {
        try {
            final Bundle in = new Bundle();
            in.putParcelable(DocumentsContract.EXTRA_URI, uri);

            // Options may be provider specific, so put them in a separate bundle to
            // avoid overriding the Uri.
            if (options != null) {
                in.putBundle(EXTRA_OPTIONS, options);
            }

            final Bundle out = content.call(uri.getAuthority(),
                    METHOD_CREATE_WEB_LINK_INTENT, null, in);
            return out.getParcelable(DocumentsContract.EXTRA_RESULT);
        } catch (Exception e) {
            Log.w(TAG, "Failed to create a web link intent", e);
            rethrowIfNecessary(e);
            return null;
        }
    }

    /**
     * Open the given image for thumbnail purposes, using any embedded EXIF
     * thumbnail if available, and providing orientation hints from the parent
     * image.
     *
     * @hide
     */
    public static AssetFileDescriptor openImageThumbnail(File file) throws FileNotFoundException {
        final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
                file, ParcelFileDescriptor.MODE_READ_ONLY);
        try {
            final ExifInterface exif = new ExifInterface(file.getAbsolutePath());

            final long[] thumb = exif.getThumbnailRange();
            if (thumb != null) {
                // If we use thumb to decode, we need to handle the rotation by ourselves.
                Bundle extras = null;
                switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1)) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        extras = new Bundle(1);
                        extras.putInt(EXTRA_ORIENTATION, 90);
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        extras = new Bundle(1);
                        extras.putInt(EXTRA_ORIENTATION, 180);
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        extras = new Bundle(1);
                        extras.putInt(EXTRA_ORIENTATION, 270);
                        break;
                }

                return new AssetFileDescriptor(pfd, thumb[0], thumb[1], extras);
            }
        } catch (IOException e) {
        }

        // Do full file decoding, we don't need to handle the orientation
        return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH, null);
    }

    private static void rethrowIfNecessary(Exception e) throws FileNotFoundException {
        // We only want to throw applications targetting O and above
        if (VMRuntime.getRuntime().getTargetSdkVersion() >= Build.VERSION_CODES.O) {
            if (e instanceof ParcelableException) {
                ((ParcelableException) e).maybeRethrow(FileNotFoundException.class);
            } else if (e instanceof RemoteException) {
                ((RemoteException) e).rethrowAsRuntimeException();
            } else if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
            }
        }
    }

    /**
     * Holds a path from a document to a particular document under it. It
     * may also contains the root ID where the path resides.
     */
    public static final class Path implements Parcelable {

        private final @Nullable String mRootId;
        private final List<String> mPath;

        /**
         * Creates a Path.
         *
         * @param rootId the ID of the root. May be null.
         * @param path the list of document ID from the parent document at
         *          position 0 to the child document.
         */
        public Path(@Nullable String rootId, List<String> path) {
            checkCollectionNotEmpty(path, "path");
            checkCollectionElementsNotNull(path, "path");

            mRootId = rootId;
            mPath = path;
        }

        /**
         * Returns the root id or null if the calling package doesn't have
         * permission to access root information.
         */
        public @Nullable String getRootId() {
            return mRootId;
        }

        /**
         * Returns the path. The path is trimmed to the top of tree if
         * calling package doesn't have permission to access those
         * documents.
         */
        public List<String> getPath() {
            return mPath;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || !(o instanceof Path)) {
                return false;
            }
            Path path = (Path) o;
            return Objects.equals(mRootId, path.mRootId) &&
                    Objects.equals(mPath, path.mPath);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mRootId, mPath);
        }

        @Override
        public String toString() {
            return new StringBuilder()
                    .append("DocumentsContract.Path{")
                    .append("rootId=")
                    .append(mRootId)
                    .append(", path=")
                    .append(mPath)
                    .append("}")
                    .toString();
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(mRootId);
            dest.writeStringList(mPath);
        }

        @Override
        public int describeContents() {
            return 0;
        }

        public static final @android.annotation.NonNull Creator<Path> CREATOR = new Creator<Path>() {
            @Override
            public Path createFromParcel(Parcel in) {
                final String rootId = in.readString();
                final List<String> path = in.createStringArrayList();
                return new Path(rootId, path);
            }

            @Override
            public Path[] newArray(int size) {
                return new Path[size];
            }
        };
    }
}
