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

Commit 64c48b88 authored by Steve Howard's avatar Steve Howard
Browse files

Update DownloadManager API to support bulk actions.

This includes querying by ID, removing and restarting downloads (the
latter is not a public API).  The methods all use varargs to support
this without undue syntactic pain.

Change-Id: I768005c539d2395cf26587d3a8c425cd01ad9cd2
parent 9934fa77
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -24549,7 +24549,7 @@
</parameter>
</method>
<method name="remove"
 return="void"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
@@ -24558,7 +24558,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="id" type="long">
<parameter name="ids" type="long...">
</parameter>
</method>
<field name="ACTION_DOWNLOAD_COMPLETE"
@@ -24951,7 +24951,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="id" type="long">
<parameter name="ids" type="long...">
</parameter>
</method>
<method name="setFilterByStatus"
+65 −25
Original line number Diff line number Diff line
@@ -567,18 +567,18 @@ public class DownloadManager {
         */
        public static final int ORDER_DESCENDING = 2;

        private Long mId = null;
        private long[] mIds = null;
        private Integer mStatusFlags = null;
        private String mOrderByColumn = Downloads.COLUMN_LAST_MODIFICATION;
        private int mOrderDirection = ORDER_DESCENDING;
        private boolean mOnlyIncludeVisibleInDownloadsUi = false;

        /**
         * Include only the download with the given ID.
         * Include only the downloads with the given IDs.
         * @return this object
         */
        public Query setFilterById(long id) {
            mId = id;
        public Query setFilterById(long... ids) {
            mIds = ids;
            return this;
        }

@@ -639,9 +639,11 @@ public class DownloadManager {
        Cursor runQuery(ContentResolver resolver, String[] projection, Uri baseUri) {
            Uri uri = baseUri;
            List<String> selectionParts = new ArrayList<String>();
            String[] selectionArgs = null;

            if (mId != null) {
                uri = ContentUris.withAppendedId(uri, mId);
            if (mIds != null) {
                selectionParts.add(getWhereClauseForIds(mIds));
                selectionArgs = getWhereArgsForIds(mIds);
            }

            if (mStatusFlags != null) {
@@ -676,7 +678,7 @@ public class DownloadManager {
            String orderDirection = (mOrderDirection == ORDER_ASCENDING ? "ASC" : "DESC");
            String orderBy = mOrderByColumn + " " + orderDirection;

            return resolver.query(uri, projection, selection, null, orderBy);
            return resolver.query(uri, projection, selection, selectionArgs, orderBy);
        }

        private String joinStrings(String joiner, Iterable<String> parts) {
@@ -738,17 +740,28 @@ public class DownloadManager {
    }

    /**
     * Cancel a download and remove it from the download manager.  The download will be stopped if
     * Cancel downloads and remove them from the download manager.  Each download will be stopped if
     * it was running, and it will no longer be accessible through the download manager.  If a file
     * was already downloaded, it will not be deleted.
     * was already downloaded to external storage, it will not be deleted.
     *
     * @param id the ID of the download
     * @param ids the IDs of the downloads to remove
     * @return the number of downloads actually removed
     */
    public void remove(long id) {
        int numDeleted = mResolver.delete(getDownloadUri(id), null, null);
        if (numDeleted == 0) {
            throw new IllegalArgumentException("Download " + id + " does not exist");
    public int remove(long... ids) {
        StringBuilder whereClause = new StringBuilder();
        String[] whereArgs = new String[ids.length];

        whereClause.append(Downloads.Impl._ID + " IN (");
        for (int i = 0; i < ids.length; i++) {
            if (i > 0) {
                whereClause.append(",");
            }
            whereClause.append("?");
            whereArgs[i] = Long.toString(ids[i]);
        }
        whereClause.append(")");

        return mResolver.delete(mBaseUri, whereClause.toString(), whereArgs);
    }

    /**
@@ -776,20 +789,20 @@ public class DownloadManager {
    }

    /**
     * Restart the given download, which must have already completed (successfully or not).  This
     * Restart the given downloads, which must have already completed (successfully or not).  This
     * method will only work when called from within the download manager's process.
     * @param id the ID of the download
     * @param ids the IDs of the downloads
     * @hide
     */
    public void restartDownload(long id) {
        Cursor cursor = query(new Query().setFilterById(id));
    public void restartDownload(long... ids) {
        Cursor cursor = query(new Query().setFilterById(ids));
        try {
            if (!cursor.moveToFirst()) {
                throw new IllegalArgumentException("No download with id " + id);
            }
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                int status = cursor.getInt(cursor.getColumnIndex(COLUMN_STATUS));
                if (status != STATUS_SUCCESSFUL && status != STATUS_FAILED) {
                throw new IllegalArgumentException("Cannot restart incomplete download: " + id);
                    throw new IllegalArgumentException("Cannot restart incomplete download: "
                            + cursor.getLong(cursor.getColumnIndex(COLUMN_ID)));
                }
            }
        } finally {
            cursor.close();
@@ -800,7 +813,7 @@ public class DownloadManager {
        values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1);
        values.putNull(Downloads.Impl._DATA);
        values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING);
        mResolver.update(getDownloadUri(id), values, null, null);
        mResolver.update(mBaseUri, values, getWhereClauseForIds(ids), getWhereArgsForIds(ids));
    }

    /**
@@ -810,6 +823,33 @@ public class DownloadManager {
        return ContentUris.withAppendedId(mBaseUri, id);
    }

    /**
     * Get a parameterized SQL WHERE clause to select a bunch of IDs.
     */
    static String getWhereClauseForIds(long[] ids) {
        StringBuilder whereClause = new StringBuilder();
        whereClause.append(Downloads.Impl._ID + " IN (");
        for (int i = 0; i < ids.length; i++) {
            if (i > 0) {
                whereClause.append(",");
            }
            whereClause.append("?");
        }
        whereClause.append(")");
        return whereClause.toString();
    }

    /**
     * Get the selection args for a clause returned by {@link #getWhereClauseForIds(long[])}.
     */
    static String[] getWhereArgsForIds(long[] ids) {
        String[] whereArgs = new String[ids.length];
        for (int i = 0; i < ids.length; i++) {
            whereArgs[i] = Long.toString(ids[i]);
        }
        return whereArgs;
    }

    /**
     * This class wraps a cursor returned by DownloadProvider -- the "underlying cursor" -- and
     * presents a different set of columns, those defined in the DownloadManager.COLUMN_* constants.