/*
 * 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.UnsupportedAppUsage;
import android.content.ContentInterface;
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.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(ContentInterface, Uri)
     */
    public static final String METADATA_TYPES = "android:documentMetadataTypes";

    /**
     * Get Exif information using DocumentsContract#getDocumentMetadata.
     *
     * @see #getDocumentMetadata(ContentInterface, 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(ContentInterface, 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(ContentInterface, 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_SUPPORTS_WRITE
         * @see #FLAG_SUPPORTS_DELETE
         * @see #FLAG_SUPPORTS_THUMBNAIL
         * @see #FLAG_DIR_PREFERS_GRID
         * @see #FLAG_DIR_PREFERS_LAST_MODIFIED
         * @see #FLAG_VIRTUAL_DOCUMENT
         * @see #FLAG_SUPPORTS_COPY
         * @see #FLAG_SUPPORTS_MOVE
         * @see #FLAG_SUPPORTS_REMOVE
         */
        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(ContentInterface, 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(ContentInterface, 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(ContentInterface, 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(ContentInterface, 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(ContentInterface, 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(ContentInterface, 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(ContentInterface, Uri)
         */
        public static final int FLAG_SUPPORTS_METADATA = 1 << 14;
    }

    /**
     * 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(ContentInterface, 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();
    }

    /** {@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
    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
    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];
            }
        };
    }
}
