/*
 * Copyright (C) 2007 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 com.android.providers.downloads;

import static android.provider.BaseColumns._ID;
import static android.provider.Downloads.Impl.COLUMN_DESTINATION;
import static android.provider.Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI;
import static android.provider.Downloads.Impl.COLUMN_MEDIASTORE_URI;
import static android.provider.Downloads.Impl.COLUMN_MEDIA_SCANNED;
import static android.provider.Downloads.Impl.COLUMN_OTHER_UID;
import static android.provider.Downloads.Impl.DESTINATION_FILE_URI;
import static android.provider.Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD;
import static android.provider.Downloads.Impl.MEDIA_NOT_SCANNABLE;
import static android.provider.Downloads.Impl.MEDIA_NOT_SCANNED;
import static android.provider.Downloads.Impl.MEDIA_SCANNED;
import static android.provider.Downloads.Impl.PERMISSION_ACCESS_ALL;

import static com.android.providers.downloads.Helpers.convertToMediaStoreDownloadsUri;
import static com.android.providers.downloads.Helpers.triggerMediaScan;

import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.app.job.JobScheduler;
import android.content.ContentProvider;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.UriMatcher;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.OnCloseListener;
import android.os.Process;
import android.os.RemoteException;
import android.os.storage.StorageManager;
import android.provider.BaseColumns;
import android.provider.Downloads;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;

import libcore.io.IoUtils;

import com.google.common.annotations.VisibleForTesting;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;

/**
 * Allows application to interact with the download manager.
 */
public final class DownloadProvider extends ContentProvider {
    /** Database filename */
    private static final String DB_NAME = "downloads.db";
    /** Current database version */
    private static final int DB_VERSION = 114;
    /** Name of table in the database */
    private static final String DB_TABLE = "downloads";
    /** Memory optimization - close idle connections after 30s of inactivity */
    private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;

    /** MIME type for the entire download list */
    private static final String DOWNLOAD_LIST_TYPE = "vnd.android.cursor.dir/download";
    /** MIME type for an individual download */
    private static final String DOWNLOAD_TYPE = "vnd.android.cursor.item/download";

    /** URI matcher used to recognize URIs sent by applications */
    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    /** URI matcher constant for the URI of all downloads belonging to the calling UID */
    private static final int MY_DOWNLOADS = 1;
    /** URI matcher constant for the URI of an individual download belonging to the calling UID */
    private static final int MY_DOWNLOADS_ID = 2;
    /** URI matcher constant for the URI of a download's request headers */
    private static final int MY_DOWNLOADS_ID_HEADERS = 3;
    /** URI matcher constant for the URI of all downloads in the system */
    private static final int ALL_DOWNLOADS = 4;
    /** URI matcher constant for the URI of an individual download */
    private static final int ALL_DOWNLOADS_ID = 5;
    /** URI matcher constant for the URI of a download's request headers */
    private static final int ALL_DOWNLOADS_ID_HEADERS = 6;
    static {
        sURIMatcher.addURI("downloads", "my_downloads", MY_DOWNLOADS);
        sURIMatcher.addURI("downloads", "my_downloads/#", MY_DOWNLOADS_ID);
        sURIMatcher.addURI("downloads", "all_downloads", ALL_DOWNLOADS);
        sURIMatcher.addURI("downloads", "all_downloads/#", ALL_DOWNLOADS_ID);
        sURIMatcher.addURI("downloads",
                "my_downloads/#/" + Downloads.Impl.RequestHeaders.URI_SEGMENT,
                MY_DOWNLOADS_ID_HEADERS);
        sURIMatcher.addURI("downloads",
                "all_downloads/#/" + Downloads.Impl.RequestHeaders.URI_SEGMENT,
                ALL_DOWNLOADS_ID_HEADERS);
        // temporary, for backwards compatibility
        sURIMatcher.addURI("downloads", "download", MY_DOWNLOADS);
        sURIMatcher.addURI("downloads", "download/#", MY_DOWNLOADS_ID);
        sURIMatcher.addURI("downloads",
                "download/#/" + Downloads.Impl.RequestHeaders.URI_SEGMENT,
                MY_DOWNLOADS_ID_HEADERS);
    }

    /** Different base URIs that could be used to access an individual download */
    private static final Uri[] BASE_URIS = new Uri[] {
            Downloads.Impl.CONTENT_URI,
            Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
    };

    private static void addMapping(Map<String, String> map, String column) {
        if (!map.containsKey(column)) {
            map.put(column, column);
        }
    }

    private static void addMapping(Map<String, String> map, String column, String rawColumn) {
        if (!map.containsKey(column)) {
            map.put(column, rawColumn + " AS " + column);
        }
    }

    private static final Map<String, String> sDownloadsMap = new ArrayMap<>();
    static {
        final Map<String, String> map = sDownloadsMap;

        // Columns defined by public API
        addMapping(map, DownloadManager.COLUMN_ID,
                Downloads.Impl._ID);
        addMapping(map, DownloadManager.COLUMN_LOCAL_FILENAME,
                Downloads.Impl._DATA);
        addMapping(map, DownloadManager.COLUMN_MEDIAPROVIDER_URI);
        addMapping(map, DownloadManager.COLUMN_DESTINATION);
        addMapping(map, DownloadManager.COLUMN_TITLE);
        addMapping(map, DownloadManager.COLUMN_DESCRIPTION);
        addMapping(map, DownloadManager.COLUMN_URI);
        addMapping(map, DownloadManager.COLUMN_STATUS);
        addMapping(map, DownloadManager.COLUMN_FILE_NAME_HINT);
        addMapping(map, DownloadManager.COLUMN_MEDIA_TYPE,
                Downloads.Impl.COLUMN_MIME_TYPE);
        addMapping(map, DownloadManager.COLUMN_TOTAL_SIZE_BYTES,
                Downloads.Impl.COLUMN_TOTAL_BYTES);
        addMapping(map, DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP,
                Downloads.Impl.COLUMN_LAST_MODIFICATION);
        addMapping(map, DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR,
                Downloads.Impl.COLUMN_CURRENT_BYTES);
        addMapping(map, DownloadManager.COLUMN_ALLOW_WRITE);
        addMapping(map, DownloadManager.COLUMN_LOCAL_URI,
                "'placeholder'");
        addMapping(map, DownloadManager.COLUMN_REASON,
                "'placeholder'");

        // Columns defined by OpenableColumns
        addMapping(map, OpenableColumns.DISPLAY_NAME,
                Downloads.Impl.COLUMN_TITLE);
        addMapping(map, OpenableColumns.SIZE,
                Downloads.Impl.COLUMN_TOTAL_BYTES);

        // Allow references to all other columns to support DownloadInfo.Reader;
        // we're already using SQLiteQueryBuilder to block access to other rows
        // that don't belong to the calling UID.
        addMapping(map, Downloads.Impl._ID);
        addMapping(map, Downloads.Impl._DATA);
        addMapping(map, Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES);
        addMapping(map, Downloads.Impl.COLUMN_ALLOW_METERED);
        addMapping(map, Downloads.Impl.COLUMN_ALLOW_ROAMING);
        addMapping(map, Downloads.Impl.COLUMN_ALLOW_WRITE);
        addMapping(map, Downloads.Impl.COLUMN_APP_DATA);
        addMapping(map, Downloads.Impl.COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT);
        addMapping(map, Downloads.Impl.COLUMN_CONTROL);
        addMapping(map, Downloads.Impl.COLUMN_COOKIE_DATA);
        addMapping(map, Downloads.Impl.COLUMN_CURRENT_BYTES);
        addMapping(map, Downloads.Impl.COLUMN_DELETED);
        addMapping(map, Downloads.Impl.COLUMN_DESCRIPTION);
        addMapping(map, Downloads.Impl.COLUMN_DESTINATION);
        addMapping(map, Downloads.Impl.COLUMN_ERROR_MSG);
        addMapping(map, Downloads.Impl.COLUMN_FAILED_CONNECTIONS);
        addMapping(map, Downloads.Impl.COLUMN_FILE_NAME_HINT);
        addMapping(map, Downloads.Impl.COLUMN_FLAGS);
        addMapping(map, Downloads.Impl.COLUMN_IS_PUBLIC_API);
        addMapping(map, Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI);
        addMapping(map, Downloads.Impl.COLUMN_LAST_MODIFICATION);
        addMapping(map, Downloads.Impl.COLUMN_MEDIAPROVIDER_URI);
        addMapping(map, Downloads.Impl.COLUMN_MEDIA_SCANNED);
        addMapping(map, Downloads.Impl.COLUMN_MEDIASTORE_URI);
        addMapping(map, Downloads.Impl.COLUMN_MIME_TYPE);
        addMapping(map, Downloads.Impl.COLUMN_NO_INTEGRITY);
        addMapping(map, Downloads.Impl.COLUMN_NOTIFICATION_CLASS);
        addMapping(map, Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS);
        addMapping(map, Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
        addMapping(map, Downloads.Impl.COLUMN_OTHER_UID);
        addMapping(map, Downloads.Impl.COLUMN_REFERER);
        addMapping(map, Downloads.Impl.COLUMN_STATUS);
        addMapping(map, Downloads.Impl.COLUMN_TITLE);
        addMapping(map, Downloads.Impl.COLUMN_TOTAL_BYTES);
        addMapping(map, Downloads.Impl.COLUMN_URI);
        addMapping(map, Downloads.Impl.COLUMN_USER_AGENT);
        addMapping(map, Downloads.Impl.COLUMN_VISIBILITY);

        addMapping(map, Constants.ETAG);
        addMapping(map, Constants.RETRY_AFTER_X_REDIRECT_COUNT);
        addMapping(map, Constants.UID);
    }

    private static final Map<String, String> sHeadersMap = new ArrayMap<>();
    static {
        final Map<String, String> map = sHeadersMap;
        addMapping(map, "id");
        addMapping(map, Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID);
        addMapping(map, Downloads.Impl.RequestHeaders.COLUMN_HEADER);
        addMapping(map, Downloads.Impl.RequestHeaders.COLUMN_VALUE);
    }

    @VisibleForTesting
    SystemFacade mSystemFacade;

    /** The database that lies underneath this content provider */
    private SQLiteOpenHelper mOpenHelper = null;

    /** List of uids that can access the downloads */
    private int mSystemUid = -1;

    private StorageManager mStorageManager;

    /**
     * Creates and updated database on demand when opening it.
     * Helper class to create database the first time the provider is
     * initialized and upgrade it when a new version of the provider needs
     * an updated version of the database.
     */
    private final class DatabaseHelper extends SQLiteOpenHelper {
        public DatabaseHelper(final Context context) {
            super(context, DB_NAME, null, DB_VERSION);
            setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
        }

        /**
         * Creates database the first time we try to open it.
         */
        @Override
        public void onCreate(final SQLiteDatabase db) {
            if (Constants.LOGVV) {
                Log.v(Constants.TAG, "populating new database");
            }
            onUpgrade(db, 0, DB_VERSION);
        }

        /**
         * Updates the database format when a content provider is used
         * with a database that was created with a different format.
         *
         * Note: to support downgrades, creating a table should always drop it first if it already
         * exists.
         */
        @Override
        public void onUpgrade(final SQLiteDatabase db, int oldV, final int newV) {
            if (oldV == 31) {
                // 31 and 100 are identical, just in different codelines. Upgrading from 31 is the
                // same as upgrading from 100.
                oldV = 100;
            } else if (oldV < 100) {
                // no logic to upgrade from these older version, just recreate the DB
                Log.i(Constants.TAG, "Upgrading downloads database from version " + oldV
                      + " to version " + newV + ", which will destroy all old data");
                oldV = 99;
            } else if (oldV > newV) {
                // user must have downgraded software; we have no way to know how to downgrade the
                // DB, so just recreate it
                Log.i(Constants.TAG, "Downgrading downloads database from version " + oldV
                      + " (current version is " + newV + "), destroying all old data");
                oldV = 99;
            }

            for (int version = oldV + 1; version <= newV; version++) {
                upgradeTo(db, version);
            }
        }

        /**
         * Upgrade database from (version - 1) to version.
         */
        private void upgradeTo(SQLiteDatabase db, int version) {
            boolean scheduleMediaScanTriggerJob = false;
            switch (version) {
                case 100:
                    createDownloadsTable(db);
                    break;

                case 101:
                    createHeadersTable(db);
                    break;

                case 102:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_IS_PUBLIC_API,
                              "INTEGER NOT NULL DEFAULT 0");
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_ALLOW_ROAMING,
                              "INTEGER NOT NULL DEFAULT 0");
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES,
                              "INTEGER NOT NULL DEFAULT 0");
                    break;

                case 103:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI,
                              "INTEGER NOT NULL DEFAULT 1");
                    makeCacheDownloadsInvisible(db);
                    break;

                case 104:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT,
                            "INTEGER NOT NULL DEFAULT 0");
                    break;

                case 105:
                    fillNullValues(db);
                    break;

                case 106:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_MEDIAPROVIDER_URI, "TEXT");
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_DELETED,
                            "BOOLEAN NOT NULL DEFAULT 0");
                    break;

                case 107:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_ERROR_MSG, "TEXT");
                    break;

                case 108:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_ALLOW_METERED,
                            "INTEGER NOT NULL DEFAULT 1");
                    break;

                case 109:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_ALLOW_WRITE,
                            "BOOLEAN NOT NULL DEFAULT 0");
                    break;

                case 110:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_FLAGS,
                            "INTEGER NOT NULL DEFAULT 0");
                    break;

                case 111:
                    addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_MEDIASTORE_URI,
                            "TEXT DEFAULT NULL");
                    scheduleMediaScanTriggerJob = true;
                    break;

                case 112:
                    updateMediaStoreUrisFromFilesToDownloads(db);
                    break;

                case 113:
                    canonicalizeDataPaths(db);
                    break;

                case 114:
                    nullifyMediaStoreUris(db);
                    scheduleMediaScanTriggerJob = true;
                    break;

                default:
                    throw new IllegalStateException("Don't know how to upgrade to " + version);
            }
            if (scheduleMediaScanTriggerJob) {
                MediaScanTriggerJob.schedule(getContext());
            }
        }

        /**
         * insert() now ensures these four columns are never null for new downloads, so this method
         * makes that true for existing columns, so that code can rely on this assumption.
         */
        private void fillNullValues(SQLiteDatabase db) {
            ContentValues values = new ContentValues();
            values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0);
            fillNullValuesForColumn(db, values);
            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1);
            fillNullValuesForColumn(db, values);
            values.put(Downloads.Impl.COLUMN_TITLE, "");
            fillNullValuesForColumn(db, values);
            values.put(Downloads.Impl.COLUMN_DESCRIPTION, "");
            fillNullValuesForColumn(db, values);
        }

        private void fillNullValuesForColumn(SQLiteDatabase db, ContentValues values) {
            String column = values.valueSet().iterator().next().getKey();
            db.update(DB_TABLE, values, column + " is null", null);
            values.clear();
        }

        /**
         * Set all existing downloads to the cache partition to be invisible in the downloads UI.
         */
        private void makeCacheDownloadsInvisible(SQLiteDatabase db) {
            ContentValues values = new ContentValues();
            values.put(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, false);
            String cacheSelection = Downloads.Impl.COLUMN_DESTINATION
                    + " != " + Downloads.Impl.DESTINATION_EXTERNAL;
            db.update(DB_TABLE, values, cacheSelection, null);
        }

        /**
         * DownloadProvider has been updated to use MediaStore.Downloads based uris
         * for COLUMN_MEDIASTORE_URI but the existing entries would still have MediaStore.Files
         * based uris. It's possible that in the future we might incorrectly assume that all the
         * uris are MediaStore.DownloadColumns based and end up querying some
         * MediaStore.Downloads specific columns. To avoid this, update the existing entries to
         * use MediaStore.Downloads based uris only.
         */
        private void updateMediaStoreUrisFromFilesToDownloads(SQLiteDatabase db) {
            try (Cursor cursor = db.query(DB_TABLE,
                    new String[] { Downloads.Impl._ID, COLUMN_MEDIASTORE_URI },
                    COLUMN_MEDIASTORE_URI + " IS NOT NULL", null, null, null, null)) {
                final ContentValues updateValues = new ContentValues();
                while (cursor.moveToNext()) {
                    final long id = cursor.getLong(0);
                    final Uri mediaStoreFilesUri = Uri.parse(cursor.getString(1));

                    final long mediaStoreId = ContentUris.parseId(mediaStoreFilesUri);
                    final String volumeName = MediaStore.getVolumeName(mediaStoreFilesUri);
                    final Uri mediaStoreDownloadsUri
                            = MediaStore.Downloads.getContentUri(volumeName, mediaStoreId);

                    updateValues.clear();
                    updateValues.put(COLUMN_MEDIASTORE_URI, mediaStoreDownloadsUri.toString());
                    db.update(DB_TABLE, updateValues, Downloads.Impl._ID + "=?",
                            new String[] { Long.toString(id) });
                }
            }
        }

        private void canonicalizeDataPaths(SQLiteDatabase db) {
            try (Cursor cursor = db.query(DB_TABLE,
                    new String[] { Downloads.Impl._ID, Downloads.Impl._DATA},
                    Downloads.Impl._DATA + " IS NOT NULL", null, null, null, null)) {
                final ContentValues updateValues = new ContentValues();
                while (cursor.moveToNext()) {
                    final long id = cursor.getLong(0);
                    final String filePath = cursor.getString(1);
                    final String canonicalPath;
                    try {
                        canonicalPath = new File(filePath).getCanonicalPath();
                    } catch (IOException e) {
                        Log.e(Constants.TAG, "Found invalid path='" + filePath + "' for id=" + id);
                        continue;
                    }

                    updateValues.clear();
                    updateValues.put(Downloads.Impl._DATA, canonicalPath);
                    db.update(DB_TABLE, updateValues, Downloads.Impl._ID + "=?",
                            new String[] { Long.toString(id) });
                }
            }
        }

        /**
         * Set mediastore uri column to null before the clean-up job and fill it again while
         * running the job so that if the clean-up job gets preempted, we could use it
         * as a way to know the entries which are already handled when the job gets restarted.
         */
        private void nullifyMediaStoreUris(SQLiteDatabase db) {
            final String whereClause = Downloads.Impl._DATA + " IS NOT NULL"
                    + " AND (" + COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI + "=1"
                    + " OR " + COLUMN_MEDIA_SCANNED + "=" + MEDIA_SCANNED + ")"
                    + " AND (" + COLUMN_DESTINATION + "=" + Downloads.Impl.DESTINATION_EXTERNAL
                    + " OR " + COLUMN_DESTINATION + "=" + DESTINATION_FILE_URI
                    + " OR " + COLUMN_DESTINATION + "=" + DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD
                    + ")";
            final ContentValues values = new ContentValues();
            values.putNull(COLUMN_MEDIASTORE_URI);
            db.update(DB_TABLE, values, whereClause, null);
        }

        /**
         * Add a column to a table using ALTER TABLE.
         * @param dbTable name of the table
         * @param columnName name of the column to add
         * @param columnDefinition SQL for the column definition
         */
        private void addColumn(SQLiteDatabase db, String dbTable, String columnName,
                               String columnDefinition) {
            db.execSQL("ALTER TABLE " + dbTable + " ADD COLUMN " + columnName + " "
                       + columnDefinition);
        }

        /**
         * Creates the table that'll hold the download information.
         */
        private void createDownloadsTable(SQLiteDatabase db) {
            try {
                db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
                db.execSQL("CREATE TABLE " + DB_TABLE + "(" +
                        Downloads.Impl._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                        Downloads.Impl.COLUMN_URI + " TEXT, " +
                        Constants.RETRY_AFTER_X_REDIRECT_COUNT + " INTEGER, " +
                        Downloads.Impl.COLUMN_APP_DATA + " TEXT, " +
                        Downloads.Impl.COLUMN_NO_INTEGRITY + " BOOLEAN, " +
                        Downloads.Impl.COLUMN_FILE_NAME_HINT + " TEXT, " +
                        Constants.OTA_UPDATE + " BOOLEAN, " +
                        Downloads.Impl._DATA + " TEXT, " +
                        Downloads.Impl.COLUMN_MIME_TYPE + " TEXT, " +
                        Downloads.Impl.COLUMN_DESTINATION + " INTEGER, " +
                        Constants.NO_SYSTEM_FILES + " BOOLEAN, " +
                        Downloads.Impl.COLUMN_VISIBILITY + " INTEGER, " +
                        Downloads.Impl.COLUMN_CONTROL + " INTEGER, " +
                        Downloads.Impl.COLUMN_STATUS + " INTEGER, " +
                        Downloads.Impl.COLUMN_FAILED_CONNECTIONS + " INTEGER, " +
                        Downloads.Impl.COLUMN_LAST_MODIFICATION + " BIGINT, " +
                        Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE + " TEXT, " +
                        Downloads.Impl.COLUMN_NOTIFICATION_CLASS + " TEXT, " +
                        Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS + " TEXT, " +
                        Downloads.Impl.COLUMN_COOKIE_DATA + " TEXT, " +
                        Downloads.Impl.COLUMN_USER_AGENT + " TEXT, " +
                        Downloads.Impl.COLUMN_REFERER + " TEXT, " +
                        Downloads.Impl.COLUMN_TOTAL_BYTES + " INTEGER, " +
                        Downloads.Impl.COLUMN_CURRENT_BYTES + " INTEGER, " +
                        Constants.ETAG + " TEXT, " +
                        Constants.UID + " INTEGER, " +
                        Downloads.Impl.COLUMN_OTHER_UID + " INTEGER, " +
                        Downloads.Impl.COLUMN_TITLE + " TEXT, " +
                        Downloads.Impl.COLUMN_DESCRIPTION + " TEXT, " +
                        Downloads.Impl.COLUMN_MEDIA_SCANNED + " BOOLEAN);");
            } catch (SQLException ex) {
                Log.e(Constants.TAG, "couldn't create table in downloads database");
                throw ex;
            }
        }

        private void createHeadersTable(SQLiteDatabase db) {
            db.execSQL("DROP TABLE IF EXISTS " + Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE);
            db.execSQL("CREATE TABLE " + Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE + "(" +
                       "id INTEGER PRIMARY KEY AUTOINCREMENT," +
                       Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID + " INTEGER NOT NULL," +
                       Downloads.Impl.RequestHeaders.COLUMN_HEADER + " TEXT NOT NULL," +
                       Downloads.Impl.RequestHeaders.COLUMN_VALUE + " TEXT NOT NULL" +
                       ");");
        }
    }

    /**
     * Initializes the content provider when it is created.
     */
    @Override
    public boolean onCreate() {
        if (mSystemFacade == null) {
            mSystemFacade = new RealSystemFacade(getContext());
        }

        mOpenHelper = new DatabaseHelper(getContext());
        // Initialize the system uid
        mSystemUid = Process.SYSTEM_UID;

        mStorageManager = getContext().getSystemService(StorageManager.class);

        // Grant access permissions for all known downloads to the owning apps.
        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        try (Cursor cursor = db.query(DB_TABLE,
                new String[] { _ID, Constants.UID }, null, null, null, null, null)) {
            while (cursor.moveToNext()) {
                final long id = cursor.getLong(0);
                final int uid = cursor.getInt(1);
                final String[] packageNames = getContext().getPackageManager()
                        .getPackagesForUid(uid);
                // Potentially stale download, will be deleted after MEDIA_MOUNTED broadcast
                // is received.
                if (ArrayUtils.isEmpty(packageNames)) {
                    continue;
                }
                // We only need to grant to the first package, since the
                // platform internally tracks based on UIDs.
                grantAllDownloadsPermission(packageNames[0], id);
            }
        }
        return true;
    }

    /**
     * Returns the content-provider-style MIME types of the various
     * types accessible through this content provider.
     */
    @Override
    public String getType(final Uri uri) {
        int match = sURIMatcher.match(uri);
        switch (match) {
            case MY_DOWNLOADS:
            case ALL_DOWNLOADS: {
                return DOWNLOAD_LIST_TYPE;
            }
            case MY_DOWNLOADS_ID:
            case ALL_DOWNLOADS_ID: {
                // return the mimetype of this id from the database
                final String id = getDownloadIdFromUri(uri);
                final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
                final String mimeType = DatabaseUtils.stringForQuery(db,
                        "SELECT " + Downloads.Impl.COLUMN_MIME_TYPE + " FROM " + DB_TABLE +
                        " WHERE " + Downloads.Impl._ID + " = ?",
                        new String[]{id});
                if (TextUtils.isEmpty(mimeType)) {
                    return DOWNLOAD_TYPE;
                } else {
                    return mimeType;
                }
            }
            default: {
                if (Constants.LOGV) {
                    Log.v(Constants.TAG, "calling getType on an unknown URI: " + uri);
                }
                throw new IllegalArgumentException("Unknown URI: " + uri);
            }
        }
    }

    @Override
    public Bundle call(String method, String arg, Bundle extras) {
        switch (method) {
            case Downloads.CALL_MEDIASTORE_DOWNLOADS_DELETED: {
                getContext().enforceCallingOrSelfPermission(
                        android.Manifest.permission.WRITE_MEDIA_STORAGE, Constants.TAG);
                final long[] deletedDownloadIds = extras.getLongArray(Downloads.EXTRA_IDS);
                final String[] mimeTypes = extras.getStringArray(Downloads.EXTRA_MIME_TYPES);
                DownloadStorageProvider.onMediaProviderDownloadsDelete(getContext(),
                        deletedDownloadIds, mimeTypes);
                return null;
            }
            case Downloads.CALL_CREATE_EXTERNAL_PUBLIC_DIR: {
                final String dirType = extras.getString(Downloads.DIR_TYPE);
                if (!ArrayUtils.contains(Environment.STANDARD_DIRECTORIES, dirType)) {
                    throw new IllegalStateException("Not one of standard directories: " + dirType);
                }
                final File file = Environment.getExternalStoragePublicDirectory(dirType);
                if (file.exists()) {
                    if (!file.isDirectory()) {
                        throw new IllegalStateException(file.getAbsolutePath() +
                                " already exists and is not a directory");
                    }
                } else if (!file.mkdirs()) {
                    throw new IllegalStateException("Unable to create directory: " +
                            file.getAbsolutePath());
                }
                return null;
            }
            case Downloads.CALL_REVOKE_MEDIASTORE_URI_PERMS : {
                getContext().enforceCallingOrSelfPermission(
                        android.Manifest.permission.WRITE_MEDIA_STORAGE, Constants.TAG);
                DownloadStorageProvider.revokeAllMediaStoreUriPermissions(getContext());
                return null;
            }
            default:
                throw new UnsupportedOperationException("Unsupported call: " + method);
        }
    }

    /**
     * Inserts a row in the database
     */
    @Override
    public Uri insert(final Uri uri, final ContentValues values) {
        checkInsertPermissions(values);
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        // note we disallow inserting into ALL_DOWNLOADS
        int match = sURIMatcher.match(uri);
        if (match != MY_DOWNLOADS) {
            Log.d(Constants.TAG, "calling insert on an unknown/invalid URI: " + uri);
            throw new IllegalArgumentException("Unknown/Invalid URI " + uri);
        }

        ContentValues filteredValues = new ContentValues();

        boolean isPublicApi =
                values.getAsBoolean(Downloads.Impl.COLUMN_IS_PUBLIC_API) == Boolean.TRUE;

        // validate the destination column
        Integer dest = values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION);
        if (dest != null) {
            if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
                    != PackageManager.PERMISSION_GRANTED
                    && (dest == Downloads.Impl.DESTINATION_CACHE_PARTITION
                            || dest == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING)) {
                throw new SecurityException("setting destination to : " + dest +
                        " not allowed, unless PERMISSION_ACCESS_ADVANCED is granted");
            }
            // for public API behavior, if an app has CACHE_NON_PURGEABLE permission, automatically
            // switch to non-purgeable download
            boolean hasNonPurgeablePermission =
                    getContext().checkCallingOrSelfPermission(
                            Downloads.Impl.PERMISSION_CACHE_NON_PURGEABLE)
                            == PackageManager.PERMISSION_GRANTED;
            if (isPublicApi && dest == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE
                    && hasNonPurgeablePermission) {
                dest = Downloads.Impl.DESTINATION_CACHE_PARTITION;
            }
            if (dest == Downloads.Impl.DESTINATION_FILE_URI) {
                checkFileUriDestination(values);
            } else if (dest == DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) {
                checkDownloadedFilePath(values);
            } else if (dest == Downloads.Impl.DESTINATION_EXTERNAL) {
                getContext().enforceCallingOrSelfPermission(
                        android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        "No permission to write");

                final AppOpsManager appOps = getContext().getSystemService(AppOpsManager.class);
                if (appOps.noteProxyOp(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, getCallingPackage(),
                        Binder.getCallingUid(), getCallingAttributionTag(), null)
                        != AppOpsManager.MODE_ALLOWED) {
                    throw new SecurityException("No permission to write");
                }
            }

            filteredValues.put(Downloads.Impl.COLUMN_DESTINATION, dest);
        }

        ensureDefaultColumns(values);

        // copy some of the input values as is
        copyString(Downloads.Impl.COLUMN_URI, values, filteredValues);
        copyString(Downloads.Impl.COLUMN_APP_DATA, values, filteredValues);
        copyBoolean(Downloads.Impl.COLUMN_NO_INTEGRITY, values, filteredValues);
        copyString(Downloads.Impl.COLUMN_FILE_NAME_HINT, values, filteredValues);
        copyString(Downloads.Impl.COLUMN_MIME_TYPE, values, filteredValues);
        copyBoolean(Downloads.Impl.COLUMN_IS_PUBLIC_API, values, filteredValues);

        // validate the visibility column
        Integer vis = values.getAsInteger(Downloads.Impl.COLUMN_VISIBILITY);
        if (vis == null) {
            if (dest == Downloads.Impl.DESTINATION_EXTERNAL) {
                filteredValues.put(Downloads.Impl.COLUMN_VISIBILITY,
                        Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            } else {
                filteredValues.put(Downloads.Impl.COLUMN_VISIBILITY,
                        Downloads.Impl.VISIBILITY_HIDDEN);
            }
        } else {
            filteredValues.put(Downloads.Impl.COLUMN_VISIBILITY, vis);
        }
        // copy the control column as is
        copyInteger(Downloads.Impl.COLUMN_CONTROL, values, filteredValues);

        /*
         * requests coming from
         * DownloadManager.addCompletedDownload(String, String, String,
         * boolean, String, String, long) need special treatment
         */
        if (values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION) ==
                Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) {
            // these requests always are marked as 'completed'
            filteredValues.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_SUCCESS);
            filteredValues.put(Downloads.Impl.COLUMN_TOTAL_BYTES,
                    values.getAsLong(Downloads.Impl.COLUMN_TOTAL_BYTES));
            filteredValues.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0);
            copyString(Downloads.Impl._DATA, values, filteredValues);
            copyBoolean(Downloads.Impl.COLUMN_ALLOW_WRITE, values, filteredValues);
        } else {
            filteredValues.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING);
            filteredValues.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1);
            filteredValues.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0);
        }

        // set lastupdate to current time
        long lastMod = mSystemFacade.currentTimeMillis();
        filteredValues.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, lastMod);

        // use packagename of the caller to set the notification columns
        String pckg = values.getAsString(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
        String clazz = values.getAsString(Downloads.Impl.COLUMN_NOTIFICATION_CLASS);
        if (pckg != null && (clazz != null || isPublicApi)) {
            int uid = Binder.getCallingUid();
            try {
                if (uid == 0 || mSystemFacade.userOwnsPackage(uid, pckg)) {
                    filteredValues.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE, pckg);
                    if (clazz != null) {
                        filteredValues.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS, clazz);
                    }
                }
            } catch (PackageManager.NameNotFoundException ex) {
                /* ignored for now */
            }
        }

        // copy some more columns as is
        copyString(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS, values, filteredValues);
        copyString(Downloads.Impl.COLUMN_COOKIE_DATA, values, filteredValues);
        copyString(Downloads.Impl.COLUMN_USER_AGENT, values, filteredValues);
        copyString(Downloads.Impl.COLUMN_REFERER, values, filteredValues);

        // UID, PID columns
        if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
                == PackageManager.PERMISSION_GRANTED) {
            copyInteger(Downloads.Impl.COLUMN_OTHER_UID, values, filteredValues);
        }
        filteredValues.put(Constants.UID, Binder.getCallingUid());
        if (Binder.getCallingUid() == 0) {
            copyInteger(Constants.UID, values, filteredValues);
        }

        // copy some more columns as is
        copyStringWithDefault(Downloads.Impl.COLUMN_TITLE, values, filteredValues, "");
        copyStringWithDefault(Downloads.Impl.COLUMN_DESCRIPTION, values, filteredValues, "");

        // is_visible_in_downloads_ui column
        copyBoolean(COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, values, filteredValues);

        // public api requests and networktypes/roaming columns
        if (isPublicApi) {
            copyInteger(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES, values, filteredValues);
            copyBoolean(Downloads.Impl.COLUMN_ALLOW_ROAMING, values, filteredValues);
            copyBoolean(Downloads.Impl.COLUMN_ALLOW_METERED, values, filteredValues);
            copyInteger(Downloads.Impl.COLUMN_FLAGS, values, filteredValues);
        }

        final Integer mediaScanned = values.getAsInteger(Downloads.Impl.COLUMN_MEDIA_SCANNED);
        filteredValues.put(COLUMN_MEDIA_SCANNED,
                mediaScanned == null ? MEDIA_NOT_SCANNED : mediaScanned);

        final boolean shouldBeVisibleToUser
                = filteredValues.getAsBoolean(COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI)
                        || filteredValues.getAsInteger(COLUMN_MEDIA_SCANNED) == MEDIA_NOT_SCANNED;
        if (shouldBeVisibleToUser && filteredValues.getAsInteger(COLUMN_DESTINATION)
                == DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) {
            final CallingIdentity token = clearCallingIdentity();
            try {
                final Uri mediaStoreUri = MediaStore.scanFile(getContext().getContentResolver(),
                        new File(filteredValues.getAsString(Downloads.Impl._DATA)));
                if (mediaStoreUri != null) {
                    final ContentValues mediaValues = new ContentValues();
                    mediaValues.put(MediaStore.Downloads.DOWNLOAD_URI,
                            filteredValues.getAsString(Downloads.Impl.COLUMN_URI));
                    mediaValues.put(MediaStore.Downloads.REFERER_URI,
                            filteredValues.getAsString(Downloads.Impl.COLUMN_REFERER));
                    mediaValues.put(MediaStore.Downloads.OWNER_PACKAGE_NAME,
                            Helpers.getPackageForUid(getContext(),
                                    filteredValues.getAsInteger(Constants.UID)));
                    getContext().getContentResolver().update(
                            convertToMediaStoreDownloadsUri(mediaStoreUri),
                            mediaValues, null, null);

                    filteredValues.put(Downloads.Impl.COLUMN_MEDIASTORE_URI,
                            mediaStoreUri.toString());
                    filteredValues.put(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
                            mediaStoreUri.toString());
                    filteredValues.put(COLUMN_MEDIA_SCANNED, MEDIA_SCANNED);
                }
            } finally {
                restoreCallingIdentity(token);
            }
        }

        if (Constants.LOGVV) {
            Log.v(Constants.TAG, "initiating download with UID "
                    + filteredValues.getAsInteger(Constants.UID));
            if (filteredValues.containsKey(Downloads.Impl.COLUMN_OTHER_UID)) {
                Log.v(Constants.TAG, "other UID " +
                        filteredValues.getAsInteger(Downloads.Impl.COLUMN_OTHER_UID));
            }
        }

        long rowID = db.insert(DB_TABLE, null, filteredValues);
        if (rowID == -1) {
            Log.d(Constants.TAG, "couldn't insert into downloads database");
            return null;
        }

        insertRequestHeaders(db, rowID, values);

        final String callingPackage = Helpers.getPackageForUid(getContext(),
                Binder.getCallingUid());
        if (callingPackage == null) {
            Log.e(Constants.TAG, "Package does not exist for calling uid");
            return null;
        }
        grantAllDownloadsPermission(callingPackage, rowID);
        notifyContentChanged(uri, match);

        final long token = Binder.clearCallingIdentity();
        try {
            Helpers.scheduleJob(getContext(), rowID);
        } finally {
            Binder.restoreCallingIdentity(token);
        }

        return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, rowID);
    }

    /**
     * If an entry corresponding to given mediaValues doesn't already exist in MediaProvider,
     * add it, otherwise update that entry with the given values.
     */
    Uri updateMediaProvider(@NonNull ContentProviderClient mediaProvider,
            @NonNull ContentValues mediaValues) {
        final String filePath = mediaValues.getAsString(MediaStore.DownloadColumns.DATA);
        Uri mediaStoreUri = getMediaStoreUri(mediaProvider, filePath);

        try {
            if (mediaStoreUri == null) {
                mediaStoreUri = mediaProvider.insert(
                        Helpers.getContentUriForPath(getContext(), filePath),
                        mediaValues);
                if (mediaStoreUri == null) {
                    Log.e(Constants.TAG, "Error inserting into mediaProvider: " + mediaValues);
                }
                return mediaStoreUri;
            } else {
                if (mediaProvider.update(mediaStoreUri, mediaValues, null, null) != 1) {
                    Log.e(Constants.TAG, "Error updating MediaProvider, uri: " + mediaStoreUri
                            + ", values: " + mediaValues);
                }
                return mediaStoreUri;
            }
        } catch (IllegalArgumentException ignored) {
            // Insert or update MediaStore failed. At this point we can't do
            // much here. If the file belongs to MediaStore collection, it will
            // get added to MediaStore collection during next scan, and we will
            // obtain the uri to the file in the next MediaStore#scanFile
            // initiated by us
            Log.w(Constants.TAG, "Couldn't update MediaStore for " + filePath, ignored);
        } catch (RemoteException e) {
            // Should not happen
        }
        return null;
    }

    private Uri getMediaStoreUri(@NonNull ContentProviderClient mediaProvider,
            @NonNull String filePath) {
        final Uri filesUri = MediaStore.setIncludePending(
                Helpers.getContentUriForPath(getContext(), filePath));
        try (Cursor cursor = mediaProvider.query(filesUri,
                new String[] { MediaStore.Files.FileColumns._ID },
                MediaStore.Files.FileColumns.DATA + "=?", new String[] { filePath }, null, null)) {
            if (cursor.moveToNext()) {
                return ContentUris.withAppendedId(filesUri, cursor.getLong(0));
            }
        } catch (RemoteException e) {
            // Should not happen
        }
        return null;
    }

    ContentValues convertToMediaProviderValues(DownloadInfo info) {
        final String filePath;
        try {
            filePath = new File(info.mFileName).getCanonicalPath();
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
        final boolean downloadCompleted = Downloads.Impl.isStatusCompleted(info.mStatus);
        final ContentValues mediaValues = new ContentValues();
        mediaValues.put(MediaStore.Downloads.DATA, filePath);
        mediaValues.put(MediaStore.Downloads.VOLUME_NAME, Helpers.extractVolumeName(filePath));
        mediaValues.put(MediaStore.Downloads.RELATIVE_PATH, Helpers.extractRelativePath(filePath));
        mediaValues.put(MediaStore.Downloads.DISPLAY_NAME, Helpers.extractDisplayName(filePath));
        mediaValues.put(MediaStore.Downloads.SIZE,
                downloadCompleted ? info.mTotalBytes : info.mCurrentBytes);
        mediaValues.put(MediaStore.Downloads.DOWNLOAD_URI, info.mUri);
        mediaValues.put(MediaStore.Downloads.REFERER_URI, info.mReferer);
        mediaValues.put(MediaStore.Downloads.MIME_TYPE, info.mMimeType);
        mediaValues.put(MediaStore.Downloads.IS_PENDING, downloadCompleted ? 0 : 1);
        mediaValues.put(MediaStore.Downloads.OWNER_PACKAGE_NAME,
                Helpers.getPackageForUid(getContext(), info.mUid));
        return mediaValues;
    }

    private static Uri getFileUri(String uriString) {
        final Uri uri = Uri.parse(uriString);
        return TextUtils.equals(uri.getScheme(), ContentResolver.SCHEME_FILE) ? uri : null;
    }

    private void ensureDefaultColumns(ContentValues values) {
        final Integer dest = values.getAsInteger(COLUMN_DESTINATION);
        if (dest != null) {
            final int mediaScannable;
            final boolean visibleInDownloadsUi;
            if (dest == Downloads.Impl.DESTINATION_EXTERNAL) {
                mediaScannable = MEDIA_NOT_SCANNED;
                visibleInDownloadsUi = true;
            } else if (dest != DESTINATION_FILE_URI
                    && dest != DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) {
                mediaScannable = MEDIA_NOT_SCANNABLE;
                visibleInDownloadsUi = false;
            } else {
                final File file;
                if (dest == Downloads.Impl.DESTINATION_FILE_URI) {
                    final String fileUri = values.getAsString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
                    file = new File(getFileUri(fileUri).getPath());
                } else {
                    file = new File(values.getAsString(Downloads.Impl._DATA));
                }

                if (Helpers.isFileInExternalAndroidDirs(file.getAbsolutePath())) {
                    mediaScannable = MEDIA_NOT_SCANNABLE;
                    visibleInDownloadsUi = false;
                } else if (Helpers.isFilenameValidInPublicDownloadsDir(file)) {
                    mediaScannable = MEDIA_NOT_SCANNED;
                    visibleInDownloadsUi = true;
                } else {
                    mediaScannable = MEDIA_NOT_SCANNED;
                    visibleInDownloadsUi = false;
                }
            }
            values.put(COLUMN_MEDIA_SCANNED, mediaScannable);
            values.put(COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, visibleInDownloadsUi);
        } else {
            if (!values.containsKey(COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI)) {
                values.put(COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, true);
            }
        }
    }

    /**
     * Check that the file URI provided for DESTINATION_FILE_URI is valid.
     */
    private void checkFileUriDestination(ContentValues values) {
        String fileUri = values.getAsString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
        if (fileUri == null) {
            throw new IllegalArgumentException(
                    "DESTINATION_FILE_URI must include a file URI under COLUMN_FILE_NAME_HINT");
        }
        final Uri uri = getFileUri(fileUri);
        if (uri == null) {
            throw new IllegalArgumentException("Not a file URI: " + uri);
        }
        final String path = uri.getPath();
        if (path == null || ("/" + path + "/").contains("/../")) {
            throw new IllegalArgumentException("Invalid file URI: " + uri);
        }

        final File file;
        try {
            file = new File(path).getCanonicalFile();
            values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, Uri.fromFile(file).toString());
        } catch (IOException e) {
            throw new SecurityException(e);
        }

        final int targetSdkVersion = getCallingPackageTargetSdkVersion();
        final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
        final boolean runningLegacyMode = appOpsManager.checkOp(AppOpsManager.OP_LEGACY_STORAGE,
                Binder.getCallingUid(), getCallingPackage()) == AppOpsManager.MODE_ALLOWED;

        if (Helpers.isFilenameValidInExternalPackage(getContext(), file, getCallingPackage())
                || Helpers.isFilenameValidInKnownPublicDir(file.getAbsolutePath())) {
            // No permissions required for paths belonging to calling package or
            // public downloads dir.
            return;
        } else if (runningLegacyMode && Helpers.isFilenameValidInExternal(getContext(), file)) {
            // Otherwise we require write permission
            getContext().enforceCallingOrSelfPermission(
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    "No permission to write to " + file);

            final AppOpsManager appOps = getContext().getSystemService(AppOpsManager.class);
            if (appOps.noteProxyOp(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, getCallingPackage(),
                    Binder.getCallingUid(), getCallingAttributionTag(), null)
                    != AppOpsManager.MODE_ALLOWED) {
                throw new SecurityException("No permission to write to " + file);
            }
        } else if (Helpers.isFilenameValidInExternalObbDir(file) &&
                ((appOpsManager.noteOp(
                    AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
                    Binder.getCallingUid(), getCallingPackage(), null, "obb_download")
                        == AppOpsManager.MODE_ALLOWED)
                || (getContext().checkCallingOrSelfPermission(
                    android.Manifest.permission.REQUEST_INSTALL_PACKAGES)
                    == PackageManager.PERMISSION_GRANTED))) {
            // Installers are allowed to download in OBB dirs, even outside their own package
            return;
        } else {
            throw new SecurityException("Unsupported path " + file);
        }
    }

    private void checkDownloadedFilePath(ContentValues values) {
        final String path = values.getAsString(Downloads.Impl._DATA);
        if (path == null || ("/" + path + "/").contains("/../")) {
            throw new IllegalArgumentException("Invalid file path: "
                    + (path == null ? "null" : path));
        }

        final File file;
        try {
            file = new File(path).getCanonicalFile();
            values.put(Downloads.Impl._DATA, file.getPath());
        } catch (IOException e) {
            throw new SecurityException(e);
        }

        if (!file.exists()) {
            throw new IllegalArgumentException("File doesn't exist: " + file);
        }

        final int targetSdkVersion = getCallingPackageTargetSdkVersion();
        final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
        final boolean runningLegacyMode = appOpsManager.checkOp(AppOpsManager.OP_LEGACY_STORAGE,
                Binder.getCallingUid(), getCallingPackage()) == AppOpsManager.MODE_ALLOWED;

        if (Binder.getCallingPid() == Process.myPid()) {
            return;
        } else if (Helpers.isFilenameValidInExternalPackage(getContext(), file, getCallingPackage())
                || Helpers.isFilenameValidInPublicDownloadsDir(file)) {
            // No permissions required for paths belonging to calling package or
            // public downloads dir.
            return;
        } else if (runningLegacyMode && Helpers.isFilenameValidInExternal(getContext(), file)) {
            // Otherwise we require write permission
            getContext().enforceCallingOrSelfPermission(
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    "No permission to write to " + file);

            final AppOpsManager appOps = getContext().getSystemService(AppOpsManager.class);
            if (appOps.noteProxyOp(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, getCallingPackage(),
                    Binder.getCallingUid(), getCallingAttributionTag(), null)
                    != AppOpsManager.MODE_ALLOWED) {
                throw new SecurityException("No permission to write to " + file);
            }
        } else {
            throw new SecurityException("Unsupported path " + file);
        }
    }

    private int getCallingPackageTargetSdkVersion() {
        final String callingPackage = getCallingPackage();
        if (callingPackage != null) {
            ApplicationInfo ai = null;
            try {
                ai = getContext().getPackageManager()
                        .getApplicationInfo(callingPackage, 0);
            } catch (PackageManager.NameNotFoundException ignored) {
            }
            if (ai != null) {
                return ai.targetSdkVersion;
            }
        }
        return Build.VERSION_CODES.CUR_DEVELOPMENT;
    }

    /**
     * Apps with the ACCESS_DOWNLOAD_MANAGER permission can access this provider freely, subject to
     * constraints in the rest of the code. Apps without that may still access this provider through
     * the public API, but additional restrictions are imposed. We check those restrictions here.
     *
     * @param values ContentValues provided to insert()
     * @throws SecurityException if the caller has insufficient permissions
     */
    private void checkInsertPermissions(ContentValues values) {
        if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_ACCESS)
                == PackageManager.PERMISSION_GRANTED) {
            return;
        }

        getContext().enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
                "INTERNET permission is required to use the download manager");

        // ensure the request fits within the bounds of a public API request
        // first copy so we can remove values
        values = new ContentValues(values);

        // check columns whose values are restricted
        enforceAllowedValues(values, Downloads.Impl.COLUMN_IS_PUBLIC_API, Boolean.TRUE);

        // validate the destination column
        if (values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION) ==
                Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) {
            /* this row is inserted by
             * DownloadManager.addCompletedDownload(String, String, String,
             * boolean, String, String, long)
             */
            values.remove(Downloads.Impl.COLUMN_TOTAL_BYTES);
            values.remove(Downloads.Impl._DATA);
            values.remove(Downloads.Impl.COLUMN_STATUS);
        }
        enforceAllowedValues(values, Downloads.Impl.COLUMN_DESTINATION,
                Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE,
                Downloads.Impl.DESTINATION_FILE_URI,
                Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD);

        if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_NO_NOTIFICATION)
                == PackageManager.PERMISSION_GRANTED) {
            enforceAllowedValues(values, Downloads.Impl.COLUMN_VISIBILITY,
                    Request.VISIBILITY_HIDDEN,
                    Request.VISIBILITY_VISIBLE,
                    Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED,
                    Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION);
        } else {
            enforceAllowedValues(values, Downloads.Impl.COLUMN_VISIBILITY,
                    Request.VISIBILITY_VISIBLE,
                    Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED,
                    Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION);
        }

        // remove the rest of the columns that are allowed (with any value)
        values.remove(Downloads.Impl.COLUMN_URI);
        values.remove(Downloads.Impl.COLUMN_TITLE);
        values.remove(Downloads.Impl.COLUMN_DESCRIPTION);
        values.remove(Downloads.Impl.COLUMN_MIME_TYPE);
        values.remove(Downloads.Impl.COLUMN_FILE_NAME_HINT); // checked later in insert()
        values.remove(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE); // checked later in insert()
        values.remove(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES);
        values.remove(Downloads.Impl.COLUMN_ALLOW_ROAMING);
        values.remove(Downloads.Impl.COLUMN_ALLOW_METERED);
        values.remove(Downloads.Impl.COLUMN_FLAGS);
        values.remove(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI);
        values.remove(Downloads.Impl.COLUMN_MEDIA_SCANNED);
        values.remove(Downloads.Impl.COLUMN_ALLOW_WRITE);
        Iterator<Map.Entry<String, Object>> iterator = values.valueSet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next().getKey();
            if (key.startsWith(Downloads.Impl.RequestHeaders.INSERT_KEY_PREFIX)) {
                iterator.remove();
            }
        }

        // any extra columns are extraneous and disallowed
        if (values.size() > 0) {
            StringBuilder error = new StringBuilder("Invalid columns in request: ");
            boolean first = true;
            for (Map.Entry<String, Object> entry : values.valueSet()) {
                if (!first) {
                    error.append(", ");
                }
                error.append(entry.getKey());
                first = false;
            }
            throw new SecurityException(error.toString());
        }
    }

    /**
     * Remove column from values, and throw a SecurityException if the value isn't within the
     * specified allowedValues.
     */
    private void enforceAllowedValues(ContentValues values, String column,
            Object... allowedValues) {
        Object value = values.get(column);
        values.remove(column);
        for (Object allowedValue : allowedValues) {
            if (value == null && allowedValue == null) {
                return;
            }
            if (value != null && value.equals(allowedValue)) {
                return;
            }
        }
        throw new SecurityException("Invalid value for " + column + ": " + value);
    }

    private Cursor queryCleared(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sort) {
        final long token = Binder.clearCallingIdentity();
        try {
            return query(uri, projection, selection, selectionArgs, sort);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    /**
     * Starts a database query
     */
    @Override
    public Cursor query(final Uri uri, String[] projection,
             final String selection, final String[] selectionArgs,
             final String sort) {

        SQLiteDatabase db = mOpenHelper.getReadableDatabase();

        int match = sURIMatcher.match(uri);
        if (match == -1) {
            if (Constants.LOGV) {
                Log.v(Constants.TAG, "querying unknown URI: " + uri);
            }
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }

        if (match == MY_DOWNLOADS_ID_HEADERS || match == ALL_DOWNLOADS_ID_HEADERS) {
            if (projection != null || selection != null || sort != null) {
                throw new UnsupportedOperationException("Request header queries do not support "
                                                        + "projections, selections or sorting");
            }

            // Headers are only available to callers with full access.
            getContext().enforceCallingOrSelfPermission(
                    Downloads.Impl.PERMISSION_ACCESS_ALL, Constants.TAG);

            final SQLiteQueryBuilder qb = getQueryBuilder(uri, match);
            projection = new String[] {
                    Downloads.Impl.RequestHeaders.COLUMN_HEADER,
                    Downloads.Impl.RequestHeaders.COLUMN_VALUE
            };
            return qb.query(db, projection, null, null, null, null, null);
        }

        if (Constants.LOGVV) {
            logVerboseQueryInfo(projection, selection, selectionArgs, sort, db);
        }

        final SQLiteQueryBuilder qb = getQueryBuilder(uri, match);

        final Cursor ret = qb.query(db, projection, selection, selectionArgs, null, null, sort);

        if (ret != null) {
            ret.setNotificationUri(getContext().getContentResolver(), uri);
            if (Constants.LOGVV) {
                Log.v(Constants.TAG,
                        "created cursor " + ret + " on behalf of " + Binder.getCallingPid());
            }
        } else {
            if (Constants.LOGV) {
                Log.v(Constants.TAG, "query failed in downloads database");
            }
        }

        return ret;
    }

    private void logVerboseQueryInfo(String[] projection, final String selection,
            final String[] selectionArgs, final String sort, SQLiteDatabase db) {
        java.lang.StringBuilder sb = new java.lang.StringBuilder();
        sb.append("starting query, database is ");
        if (db != null) {
            sb.append("not ");
        }
        sb.append("null; ");
        if (projection == null) {
            sb.append("projection is null; ");
        } else if (projection.length == 0) {
            sb.append("projection is empty; ");
        } else {
            for (int i = 0; i < projection.length; ++i) {
                sb.append("projection[");
                sb.append(i);
                sb.append("] is ");
                sb.append(projection[i]);
                sb.append("; ");
            }
        }
        sb.append("selection is ");
        sb.append(selection);
        sb.append("; ");
        if (selectionArgs == null) {
            sb.append("selectionArgs is null; ");
        } else if (selectionArgs.length == 0) {
            sb.append("selectionArgs is empty; ");
        } else {
            for (int i = 0; i < selectionArgs.length; ++i) {
                sb.append("selectionArgs[");
                sb.append(i);
                sb.append("] is ");
                sb.append(selectionArgs[i]);
                sb.append("; ");
            }
        }
        sb.append("sort is ");
        sb.append(sort);
        sb.append(".");
        Log.v(Constants.TAG, sb.toString());
    }

    private String getDownloadIdFromUri(final Uri uri) {
        return uri.getPathSegments().get(1);
    }

    /**
     * Insert request headers for a download into the DB.
     */
    private void insertRequestHeaders(SQLiteDatabase db, long downloadId, ContentValues values) {
        ContentValues rowValues = new ContentValues();
        rowValues.put(Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID, downloadId);
        for (Map.Entry<String, Object> entry : values.valueSet()) {
            String key = entry.getKey();
            if (key.startsWith(Downloads.Impl.RequestHeaders.INSERT_KEY_PREFIX)) {
                String headerLine = entry.getValue().toString();
                if (!headerLine.contains(":")) {
                    throw new IllegalArgumentException("Invalid HTTP header line: " + headerLine);
                }
                String[] parts = headerLine.split(":", 2);
                rowValues.put(Downloads.Impl.RequestHeaders.COLUMN_HEADER, parts[0].trim());
                rowValues.put(Downloads.Impl.RequestHeaders.COLUMN_VALUE, parts[1].trim());
                db.insert(Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE, null, rowValues);
            }
        }
    }

    /**
     * Updates a row in the database
     */
    @Override
    public int update(final Uri uri, final ContentValues values,
            final String where, final String[] whereArgs) {
        final Context context = getContext();
        final ContentResolver resolver = context.getContentResolver();

        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        int count;
        boolean updateSchedule = false;
        boolean isCompleting = false;

        ContentValues filteredValues;
        if (Binder.getCallingPid() != Process.myPid()) {
            filteredValues = new ContentValues();
            copyString(Downloads.Impl.COLUMN_APP_DATA, values, filteredValues);
            copyInteger(Downloads.Impl.COLUMN_VISIBILITY, values, filteredValues);
            Integer i = values.getAsInteger(Downloads.Impl.COLUMN_CONTROL);
            if (i != null) {
                filteredValues.put(Downloads.Impl.COLUMN_CONTROL, i);
                updateSchedule = true;
            }

            copyInteger(Downloads.Impl.COLUMN_CONTROL, values, filteredValues);
            copyString(Downloads.Impl.COLUMN_TITLE, values, filteredValues);
            copyString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI, values, filteredValues);
            copyString(Downloads.Impl.COLUMN_DESCRIPTION, values, filteredValues);
            copyInteger(Downloads.Impl.COLUMN_DELETED, values, filteredValues);
        } else {
            filteredValues = values;
            String filename = values.getAsString(Downloads.Impl._DATA);
            if (filename != null) {
                try {
                    filteredValues.put(Downloads.Impl._DATA, new File(filename).getCanonicalPath());
                } catch (IOException e) {
                    throw new IllegalStateException("Invalid path: " + filename);
                }

                Cursor c = null;
                try {
                    c = query(uri, new String[]
                            { Downloads.Impl.COLUMN_TITLE }, null, null, null);
                    if (!c.moveToFirst() || c.getString(0).isEmpty()) {
                        values.put(Downloads.Impl.COLUMN_TITLE, new File(filename).getName());
                    }
                } finally {
                    IoUtils.closeQuietly(c);
                }
            }

            Integer status = values.getAsInteger(Downloads.Impl.COLUMN_STATUS);
            boolean isRestart = status != null && status == Downloads.Impl.STATUS_PENDING;
            boolean isUserBypassingSizeLimit =
                values.containsKey(Downloads.Impl.COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT);
            if (isRestart || isUserBypassingSizeLimit) {
                updateSchedule = true;
            }
            isCompleting = status != null && Downloads.Impl.isStatusCompleted(status);
        }

        int match = sURIMatcher.match(uri);
        switch (match) {
            case MY_DOWNLOADS:
            case MY_DOWNLOADS_ID:
            case ALL_DOWNLOADS:
            case ALL_DOWNLOADS_ID:
                if (filteredValues.size() == 0) {
                    count = 0;
                    break;
                }

                final SQLiteQueryBuilder qb = getQueryBuilder(uri, match);
                count = qb.update(db, filteredValues, where, whereArgs);
                final CallingIdentity token = clearCallingIdentity();
                try (Cursor cursor = qb.query(db, null, where, whereArgs, null, null, null);
                        ContentProviderClient client = getContext().getContentResolver()
                                .acquireContentProviderClient(MediaStore.AUTHORITY)) {
                    final DownloadInfo.Reader reader = new DownloadInfo.Reader(resolver,
                            cursor);
                    final DownloadInfo info = new DownloadInfo(context);
                    final ContentValues updateValues = new ContentValues();
                    while (cursor.moveToNext()) {
                        reader.updateFromDatabase(info);
                        final boolean visibleToUser = info.mIsVisibleInDownloadsUi
                                || (info.mMediaScanned != MEDIA_NOT_SCANNABLE);
                        if (info.mFileName == null) {
                            if (info.mMediaStoreUri != null) {
                                // If there was a mediastore entry, it would be deleted in it's
                                // next idle pass.
                                updateValues.clear();
                                updateValues.putNull(Downloads.Impl.COLUMN_MEDIASTORE_URI);
                                qb.update(db, updateValues, Downloads.Impl._ID + "=?",
                                        new String[] { Long.toString(info.mId) });
                            }
                        } else if ((info.mDestination == Downloads.Impl.DESTINATION_EXTERNAL
                                || info.mDestination == Downloads.Impl.DESTINATION_FILE_URI
                                || info.mDestination == Downloads.Impl
                                        .DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD)
                                && visibleToUser) {
                            final ContentValues mediaValues = convertToMediaProviderValues(info);
                            final Uri mediaStoreUri;
                            if (Downloads.Impl.isStatusCompleted(info.mStatus)) {
                                // Set size to 0 to ensure MediaScanner will scan this file.
                                mediaValues.put(MediaStore.Downloads.SIZE, 0);
                                updateMediaProvider(client, mediaValues);
                                mediaStoreUri = triggerMediaScan(client, new File(info.mFileName));
                            } else {
                                // Don't insert/update MediaStore db until the download is complete.
                                // Incomplete files can only be inserted to MediaStore by setting
                                // IS_PENDING=1 and using RELATIVE_PATH and DISPLAY_NAME in
                                // MediaProvider#insert operation. We use DATA column, IS_PENDING
                                // with DATA column will not be respected by MediaProvider.
                                mediaStoreUri = null;
                            }
                            if (!TextUtils.equals(info.mMediaStoreUri,
                                    mediaStoreUri == null ? null : mediaStoreUri.toString())) {
                                updateValues.clear();
                                if (mediaStoreUri == null) {
                                    updateValues.putNull(Downloads.Impl.COLUMN_MEDIASTORE_URI);
                                    updateValues.putNull(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI);
                                    updateValues.put(COLUMN_MEDIA_SCANNED, MEDIA_NOT_SCANNED);
                                } else {
                                    updateValues.put(Downloads.Impl.COLUMN_MEDIASTORE_URI,
                                            mediaStoreUri.toString());
                                    updateValues.put(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
                                            mediaStoreUri.toString());
                                    updateValues.put(COLUMN_MEDIA_SCANNED, MEDIA_SCANNED);
                                }
                                qb.update(db, updateValues, Downloads.Impl._ID + "=?",
                                        new String[] { Long.toString(info.mId) });
                            }
                        }
                        if (updateSchedule) {
                            Helpers.scheduleJob(context, info);
                        }
                        if (isCompleting) {
                            info.sendIntentIfRequested();
                        }
                    }
                } finally {
                    restoreCallingIdentity(token);
                }
                break;

            default:
                Log.d(Constants.TAG, "updating unknown/invalid URI: " + uri);
                throw new UnsupportedOperationException("Cannot update URI: " + uri);
        }

        notifyContentChanged(uri, match);
        return count;
    }

    /**
     * Notify of a change through both URIs (/my_downloads and /all_downloads)
     * @param uri either URI for the changed download(s)
     * @param uriMatch the match ID from {@link #sURIMatcher}
     */
    private void notifyContentChanged(final Uri uri, int uriMatch) {
        Long downloadId = null;
        if (uriMatch == MY_DOWNLOADS_ID || uriMatch == ALL_DOWNLOADS_ID) {
            downloadId = Long.parseLong(getDownloadIdFromUri(uri));
        }
        for (Uri uriToNotify : BASE_URIS) {
            if (downloadId != null) {
                uriToNotify = ContentUris.withAppendedId(uriToNotify, downloadId);
            }
            getContext().getContentResolver().notifyChange(uriToNotify, null);
        }
    }

    /**
     * Create a query builder that filters access to the underlying database
     * based on both the requested {@link Uri} and permissions of the caller.
     */
    private SQLiteQueryBuilder getQueryBuilder(final Uri uri, int match) {
        final String table;
        final Map<String, String> projectionMap;

        final StringBuilder where = new StringBuilder();
        switch (match) {
            // The "my_downloads" view normally limits the caller to operating
            // on downloads that they either directly own, or have been given
            // indirect ownership of via OTHER_UID.
            case MY_DOWNLOADS_ID:
                appendWhereExpression(where, _ID + "=" + getDownloadIdFromUri(uri));
                // fall-through
            case MY_DOWNLOADS:
                table = DB_TABLE;
                projectionMap = sDownloadsMap;
                if (getContext().checkCallingOrSelfPermission(
                        PERMISSION_ACCESS_ALL) != PackageManager.PERMISSION_GRANTED) {
                    appendWhereExpression(where, Constants.UID + "=" + Binder.getCallingUid()
                            + " OR " + COLUMN_OTHER_UID + "=" + Binder.getCallingUid());
                }
                break;

            // The "all_downloads" view is already limited via <path-permission>
            // to only callers holding the ACCESS_ALL_DOWNLOADS permission, but
            // access may also be delegated via Uri permission grants.
            case ALL_DOWNLOADS_ID:
                appendWhereExpression(where, _ID + "=" + getDownloadIdFromUri(uri));
                // fall-through
            case ALL_DOWNLOADS:
                table = DB_TABLE;
                projectionMap = sDownloadsMap;
                break;

            // Headers are limited to callers holding the ACCESS_ALL_DOWNLOADS
            // permission, since they're only needed for executing downloads.
            case MY_DOWNLOADS_ID_HEADERS:
            case ALL_DOWNLOADS_ID_HEADERS:
                table = Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE;
                projectionMap = sHeadersMap;
                appendWhereExpression(where, Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID + "="
                        + getDownloadIdFromUri(uri));
                break;

            default:
                throw new UnsupportedOperationException("Unknown URI: " + uri);
        }

        final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(table);
        qb.setProjectionMap(projectionMap);
        qb.setStrict(true);
        qb.setStrictColumns(true);
        qb.setStrictGrammar(true);
        qb.appendWhere(where);
        return qb;
    }

    private static void appendWhereExpression(StringBuilder sb, String expression) {
        if (sb.length() > 0) {
            sb.append(" AND ");
        }
        sb.append('(').append(expression).append(')');
    }

    /**
     * Deletes a row in the database
     */
    @Override
    public int delete(final Uri uri, final String where, final String[] whereArgs) {
        final Context context = getContext();
        final ContentResolver resolver = context.getContentResolver();
        final JobScheduler scheduler = context.getSystemService(JobScheduler.class);

        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        int match = sURIMatcher.match(uri);
        switch (match) {
            case MY_DOWNLOADS:
            case MY_DOWNLOADS_ID:
            case ALL_DOWNLOADS:
            case ALL_DOWNLOADS_ID:
                final SQLiteQueryBuilder qb = getQueryBuilder(uri, match);
                try (Cursor cursor = qb.query(db, null, where, whereArgs, null, null, null)) {
                    final DownloadInfo.Reader reader = new DownloadInfo.Reader(resolver, cursor);
                    final DownloadInfo info = new DownloadInfo(context);
                    while (cursor.moveToNext()) {
                        reader.updateFromDatabase(info);
                        scheduler.cancel((int) info.mId);

                        revokeAllDownloadsPermission(info.mId);
                        DownloadStorageProvider.onDownloadProviderDelete(getContext(), info.mId);

                        final String path = info.mFileName;
                        if (!TextUtils.isEmpty(path)) {
                            try {
                                final File file = new File(path).getCanonicalFile();
                                if (Helpers.isFilenameValid(getContext(), file)) {
                                    Log.v(Constants.TAG,
                                            "Deleting " + file + " via provider delete");
                                    file.delete();
                                    MediaStore.scanFile(getContext().getContentResolver(), file);
                                } else {
                                    Log.d(Constants.TAG, "Ignoring invalid file: " + file);
                                }
                            } catch (IOException e) {
                                Log.e(Constants.TAG, "Couldn't delete file: " + path, e);
                            }
                        }

                        // If the download wasn't completed yet, we're
                        // effectively completing it now, and we need to send
                        // any requested broadcasts
                        if (!Downloads.Impl.isStatusCompleted(info.mStatus)) {
                            info.sendIntentIfRequested();
                        }

                        // Delete any headers for this download
                        db.delete(Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE,
                                Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID + "=?",
                                new String[] { Long.toString(info.mId) });
                    }
                }

                count = qb.delete(db, where, whereArgs);
                break;

            default:
                Log.d(Constants.TAG, "deleting unknown/invalid URI: " + uri);
                throw new UnsupportedOperationException("Cannot delete URI: " + uri);
        }
        notifyContentChanged(uri, match);
        final long token = Binder.clearCallingIdentity();
        try {
            Helpers.getDownloadNotifier(getContext()).update();
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        return count;
    }

    /**
     * Remotely opens a file
     */
    @Override
    public ParcelFileDescriptor openFile(final Uri uri, String mode) throws FileNotFoundException {
        if (Constants.LOGVV) {
            logVerboseOpenFileInfo(uri, mode);
        }

        // Perform normal query to enforce caller identity access before
        // clearing it to reach internal-only columns
        final Cursor probeCursor = query(uri, new String[] {
                Downloads.Impl._DATA }, null, null, null);
        try {
            if ((probeCursor == null) || (probeCursor.getCount() == 0)) {
                throw new FileNotFoundException(
                        "No file found for " + uri + " as UID " + Binder.getCallingUid());
            }
        } finally {
            IoUtils.closeQuietly(probeCursor);
        }

        final Cursor cursor = queryCleared(uri, new String[] {
                Downloads.Impl._DATA, Downloads.Impl.COLUMN_STATUS,
                Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.COLUMN_MEDIA_SCANNED }, null,
                null, null);
        final String path;
        final boolean shouldScan;
        try {
            int count = (cursor != null) ? cursor.getCount() : 0;
            if (count != 1) {
                // If there is not exactly one result, throw an appropriate exception.
                if (count == 0) {
                    throw new FileNotFoundException("No entry for " + uri);
                }
                throw new FileNotFoundException("Multiple items at " + uri);
            }

            if (cursor.moveToFirst()) {
                final int status = cursor.getInt(1);
                final int destination = cursor.getInt(2);
                final int mediaScanned = cursor.getInt(3);

                path = cursor.getString(0);
                shouldScan = Downloads.Impl.isStatusSuccess(status) && (
                        destination == Downloads.Impl.DESTINATION_EXTERNAL
                        || destination == Downloads.Impl.DESTINATION_FILE_URI
                        || destination == Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD)
                        && mediaScanned != Downloads.Impl.MEDIA_NOT_SCANNABLE;
            } else {
                throw new FileNotFoundException("Failed moveToFirst");
            }
        } finally {
            IoUtils.closeQuietly(cursor);
        }

        if (path == null) {
            throw new FileNotFoundException("No filename found.");
        }

        final File file;
        try {
            file = new File(path).getCanonicalFile();
        } catch (IOException e) {
            throw new FileNotFoundException(e.getMessage());
        }

        if (!Helpers.isFilenameValid(getContext(), file)) {
            throw new FileNotFoundException("Invalid file: " + file);
        }

        final int pfdMode = ParcelFileDescriptor.parseMode(mode);
        if (pfdMode == ParcelFileDescriptor.MODE_READ_ONLY) {
            return ParcelFileDescriptor.open(file, pfdMode);
        } else {
            try {
                // When finished writing, update size and timestamp
                return ParcelFileDescriptor.open(file, pfdMode, Helpers.getAsyncHandler(),
                        new OnCloseListener() {
                    @Override
                    public void onClose(IOException e) {
                        final ContentValues values = new ContentValues();
                        values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, file.length());
                        values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION,
                                mSystemFacade.currentTimeMillis());
                        update(uri, values, null, null);

                        if (shouldScan) {
                            final Intent intent = new Intent(
                                    Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                            intent.setData(Uri.fromFile(file));
                            getContext().sendBroadcast(intent);
                        }
                    }
                });
            } catch (IOException e) {
                throw new FileNotFoundException("Failed to open for writing: " + e);
            }
        }
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ", 120);

        pw.println("Downloads updated in last hour:");
        pw.increaseIndent();

        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        final long modifiedAfter = mSystemFacade.currentTimeMillis() - DateUtils.HOUR_IN_MILLIS;
        final Cursor cursor = db.query(DB_TABLE, null,
                Downloads.Impl.COLUMN_LAST_MODIFICATION + ">" + modifiedAfter, null, null, null,
                Downloads.Impl._ID + " ASC");
        try {
            final String[] cols = cursor.getColumnNames();
            final int idCol = cursor.getColumnIndex(BaseColumns._ID);
            while (cursor.moveToNext()) {
                pw.println("Download #" + cursor.getInt(idCol) + ":");
                pw.increaseIndent();
                for (int i = 0; i < cols.length; i++) {
                    // Omit sensitive data when dumping
                    if (Downloads.Impl.COLUMN_COOKIE_DATA.equals(cols[i])) {
                        continue;
                    }
                    pw.printPair(cols[i], cursor.getString(i));
                }
                pw.println();
                pw.decreaseIndent();
            }
        } finally {
            cursor.close();
        }

        pw.decreaseIndent();
    }

    private void logVerboseOpenFileInfo(Uri uri, String mode) {
        Log.v(Constants.TAG, "openFile uri: " + uri + ", mode: " + mode
                + ", uid: " + Binder.getCallingUid());
        Cursor cursor = query(Downloads.Impl.CONTENT_URI,
                new String[] { "_id" }, null, null, "_id");
        if (cursor == null) {
            Log.v(Constants.TAG, "null cursor in openFile");
        } else {
            try {
                if (!cursor.moveToFirst()) {
                    Log.v(Constants.TAG, "empty cursor in openFile");
                } else {
                    do {
                        Log.v(Constants.TAG, "row " + cursor.getInt(0) + " available");
                    } while(cursor.moveToNext());
                }
            } finally {
                cursor.close();
            }
        }
        cursor = query(uri, new String[] { "_data" }, null, null, null);
        if (cursor == null) {
            Log.v(Constants.TAG, "null cursor in openFile");
        } else {
            try {
                if (!cursor.moveToFirst()) {
                    Log.v(Constants.TAG, "empty cursor in openFile");
                } else {
                    String filename = cursor.getString(0);
                    Log.v(Constants.TAG, "filename in openFile: " + filename);
                    if (new java.io.File(filename).isFile()) {
                        Log.v(Constants.TAG, "file exists in openFile");
                    }
                }
            } finally {
                cursor.close();
            }
        }
    }

    private static final void copyInteger(String key, ContentValues from, ContentValues to) {
        Integer i = from.getAsInteger(key);
        if (i != null) {
            to.put(key, i);
        }
    }

    private static final void copyBoolean(String key, ContentValues from, ContentValues to) {
        Boolean b = from.getAsBoolean(key);
        if (b != null) {
            to.put(key, b);
        }
    }

    private static final void copyString(String key, ContentValues from, ContentValues to) {
        String s = from.getAsString(key);
        if (s != null) {
            to.put(key, s);
        }
    }

    private static final void copyStringWithDefault(String key, ContentValues from,
            ContentValues to, String defaultValue) {
        copyString(key, from, to);
        if (!to.containsKey(key)) {
            to.put(key, defaultValue);
        }
    }

    private void grantAllDownloadsPermission(String toPackage, long id) {
        final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id);
        getContext().grantUriPermission(toPackage, uri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    }

    private void revokeAllDownloadsPermission(long id) {
        final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id);
        getContext().revokeUriPermission(uri, ~0);
    }
}
