1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.provider;
18
19import android.app.DownloadManager;
20import android.content.Context;
21import android.net.NetworkPolicyManager;
22import android.net.Uri;
23
24/**
25 * The Download Manager
26 *
27 * @pending
28 */
29public final class Downloads {
30    private Downloads() {}
31
32    /**
33     * Implementation details
34     *
35     * Exposes constants used to interact with the download manager's
36     * content provider.
37     * The constants URI ... STATUS are the names of columns in the downloads table.
38     *
39     * @hide
40     */
41    public static final class Impl implements BaseColumns {
42        private Impl() {}
43
44        public static final String AUTHORITY = "downloads";
45
46        /**
47         * The permission to access the download manager
48         */
49        public static final String PERMISSION_ACCESS = "android.permission.ACCESS_DOWNLOAD_MANAGER";
50
51        /**
52         * The permission to access the download manager's advanced functions
53         */
54        public static final String PERMISSION_ACCESS_ADVANCED =
55                "android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED";
56
57        /**
58         * The permission to access the all the downloads in the manager.
59         */
60        public static final String PERMISSION_ACCESS_ALL =
61                "android.permission.ACCESS_ALL_DOWNLOADS";
62
63        /**
64         * The permission to directly access the download manager's cache
65         * directory
66         */
67        public static final String PERMISSION_CACHE = "android.permission.ACCESS_CACHE_FILESYSTEM";
68
69        /**
70         * The permission to send broadcasts on download completion
71         */
72        public static final String PERMISSION_SEND_INTENTS =
73                "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS";
74
75        /**
76         * The permission to download files to the cache partition that won't be automatically
77         * purged when space is needed.
78         */
79        public static final String PERMISSION_CACHE_NON_PURGEABLE =
80                "android.permission.DOWNLOAD_CACHE_NON_PURGEABLE";
81
82        /**
83         * The permission to download files without any system notification being shown.
84         */
85        public static final String PERMISSION_NO_NOTIFICATION =
86                "android.permission.DOWNLOAD_WITHOUT_NOTIFICATION";
87
88        /**
89         * The content:// URI to access downloads owned by the caller's UID.
90         */
91        public static final Uri CONTENT_URI =
92                Uri.parse("content://downloads/my_downloads");
93
94        /**
95         * The content URI for accessing all downloads across all UIDs (requires the
96         * ACCESS_ALL_DOWNLOADS permission).
97         */
98        public static final Uri ALL_DOWNLOADS_CONTENT_URI =
99                Uri.parse("content://downloads/all_downloads");
100
101        /** URI segment to access a publicly accessible downloaded file */
102        public static final String PUBLICLY_ACCESSIBLE_DOWNLOADS_URI_SEGMENT = "public_downloads";
103
104        /**
105         * The content URI for accessing publicly accessible downloads (i.e., it requires no
106         * permissions to access this downloaded file)
107         */
108        public static final Uri PUBLICLY_ACCESSIBLE_DOWNLOADS_URI =
109                Uri.parse("content://downloads/" + PUBLICLY_ACCESSIBLE_DOWNLOADS_URI_SEGMENT);
110
111        /**
112         * Broadcast Action: this is sent by the download manager to the app
113         * that had initiated a download when that download completes. The
114         * download's content: uri is specified in the intent's data.
115         */
116        public static final String ACTION_DOWNLOAD_COMPLETED =
117                DownloadManager.ACTION_DOWNLOAD_COMPLETED;
118
119        /**
120         * Broadcast Action: this is sent by the download manager to the app
121         * that had initiated a download when the user selects the notification
122         * associated with that download. The download's content: uri is specified
123         * in the intent's data if the click is associated with a single download,
124         * or Downloads.CONTENT_URI if the notification is associated with
125         * multiple downloads.
126         * Note: this is not currently sent for downloads that have completed
127         * successfully.
128         */
129        public static final String ACTION_NOTIFICATION_CLICKED =
130                DownloadManager.ACTION_NOTIFICATION_CLICKED;
131
132        /**
133         * The name of the column containing the URI of the data being downloaded.
134         * <P>Type: TEXT</P>
135         * <P>Owner can Init/Read</P>
136         */
137        public static final String COLUMN_URI = "uri";
138
139        /**
140         * The name of the column containing application-specific data.
141         * <P>Type: TEXT</P>
142         * <P>Owner can Init/Read/Write</P>
143         */
144        public static final String COLUMN_APP_DATA = "entity";
145
146        /**
147         * The name of the column containing the flags that indicates whether
148         * the initiating application is capable of verifying the integrity of
149         * the downloaded file. When this flag is set, the download manager
150         * performs downloads and reports success even in some situations where
151         * it can't guarantee that the download has completed (e.g. when doing
152         * a byte-range request without an ETag, or when it can't determine
153         * whether a download fully completed).
154         * <P>Type: BOOLEAN</P>
155         * <P>Owner can Init</P>
156         */
157        public static final String COLUMN_NO_INTEGRITY = "no_integrity";
158
159        /**
160         * The name of the column containing the filename that the initiating
161         * application recommends. When possible, the download manager will attempt
162         * to use this filename, or a variation, as the actual name for the file.
163         * <P>Type: TEXT</P>
164         * <P>Owner can Init</P>
165         */
166        public static final String COLUMN_FILE_NAME_HINT = "hint";
167
168        /**
169         * The name of the column containing the filename where the downloaded data
170         * was actually stored.
171         * <P>Type: TEXT</P>
172         * <P>Owner can Read</P>
173         */
174        public static final String _DATA = "_data";
175
176        /**
177         * The name of the column containing the MIME type of the downloaded data.
178         * <P>Type: TEXT</P>
179         * <P>Owner can Init/Read</P>
180         */
181        public static final String COLUMN_MIME_TYPE = "mimetype";
182
183        /**
184         * The name of the column containing the flag that controls the destination
185         * of the download. See the DESTINATION_* constants for a list of legal values.
186         * <P>Type: INTEGER</P>
187         * <P>Owner can Init</P>
188         */
189        public static final String COLUMN_DESTINATION = "destination";
190
191        /**
192         * The name of the column containing the flags that controls whether the
193         * download is displayed by the UI. See the VISIBILITY_* constants for
194         * a list of legal values.
195         * <P>Type: INTEGER</P>
196         * <P>Owner can Init/Read/Write</P>
197         */
198        public static final String COLUMN_VISIBILITY = "visibility";
199
200        /**
201         * The name of the column containing the current control state  of the download.
202         * Applications can write to this to control (pause/resume) the download.
203         * the CONTROL_* constants for a list of legal values.
204         * <P>Type: INTEGER</P>
205         * <P>Owner can Read</P>
206         */
207        public static final String COLUMN_CONTROL = "control";
208
209        /**
210         * The name of the column containing the current status of the download.
211         * Applications can read this to follow the progress of each download. See
212         * the STATUS_* constants for a list of legal values.
213         * <P>Type: INTEGER</P>
214         * <P>Owner can Read</P>
215         */
216        public static final String COLUMN_STATUS = "status";
217
218        /**
219         * The name of the column containing the date at which some interesting
220         * status changed in the download. Stored as a System.currentTimeMillis()
221         * value.
222         * <P>Type: BIGINT</P>
223         * <P>Owner can Read</P>
224         */
225        public static final String COLUMN_LAST_MODIFICATION = "lastmod";
226
227        /**
228         * The name of the column containing the package name of the application
229         * that initiating the download. The download manager will send
230         * notifications to a component in this package when the download completes.
231         * <P>Type: TEXT</P>
232         * <P>Owner can Init/Read</P>
233         */
234        public static final String COLUMN_NOTIFICATION_PACKAGE = "notificationpackage";
235
236        /**
237         * The name of the column containing the component name of the class that
238         * will receive notifications associated with the download. The
239         * package/class combination is passed to
240         * Intent.setClassName(String,String).
241         * <P>Type: TEXT</P>
242         * <P>Owner can Init/Read</P>
243         */
244        public static final String COLUMN_NOTIFICATION_CLASS = "notificationclass";
245
246        /**
247         * If extras are specified when requesting a download they will be provided in the intent that
248         * is sent to the specified class and package when a download has finished.
249         * <P>Type: TEXT</P>
250         * <P>Owner can Init</P>
251         */
252        public static final String COLUMN_NOTIFICATION_EXTRAS = "notificationextras";
253
254        /**
255         * The name of the column contain the values of the cookie to be used for
256         * the download. This is used directly as the value for the Cookie: HTTP
257         * header that gets sent with the request.
258         * <P>Type: TEXT</P>
259         * <P>Owner can Init</P>
260         */
261        public static final String COLUMN_COOKIE_DATA = "cookiedata";
262
263        /**
264         * The name of the column containing the user agent that the initiating
265         * application wants the download manager to use for this download.
266         * <P>Type: TEXT</P>
267         * <P>Owner can Init</P>
268         */
269        public static final String COLUMN_USER_AGENT = "useragent";
270
271        /**
272         * The name of the column containing the referer (sic) that the initiating
273         * application wants the download manager to use for this download.
274         * <P>Type: TEXT</P>
275         * <P>Owner can Init</P>
276         */
277        public static final String COLUMN_REFERER = "referer";
278
279        /**
280         * The name of the column containing the total size of the file being
281         * downloaded.
282         * <P>Type: INTEGER</P>
283         * <P>Owner can Read</P>
284         */
285        public static final String COLUMN_TOTAL_BYTES = "total_bytes";
286
287        /**
288         * The name of the column containing the size of the part of the file that
289         * has been downloaded so far.
290         * <P>Type: INTEGER</P>
291         * <P>Owner can Read</P>
292         */
293        public static final String COLUMN_CURRENT_BYTES = "current_bytes";
294
295        /**
296         * The name of the column where the initiating application can provide the
297         * UID of another application that is allowed to access this download. If
298         * multiple applications share the same UID, all those applications will be
299         * allowed to access this download. This column can be updated after the
300         * download is initiated. This requires the permission
301         * android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED.
302         * <P>Type: INTEGER</P>
303         * <P>Owner can Init</P>
304         */
305        public static final String COLUMN_OTHER_UID = "otheruid";
306
307        /**
308         * The name of the column where the initiating application can provided the
309         * title of this download. The title will be displayed ito the user in the
310         * list of downloads.
311         * <P>Type: TEXT</P>
312         * <P>Owner can Init/Read/Write</P>
313         */
314        public static final String COLUMN_TITLE = "title";
315
316        /**
317         * The name of the column where the initiating application can provide the
318         * description of this download. The description will be displayed to the
319         * user in the list of downloads.
320         * <P>Type: TEXT</P>
321         * <P>Owner can Init/Read/Write</P>
322         */
323        public static final String COLUMN_DESCRIPTION = "description";
324
325        /**
326         * The name of the column indicating whether the download was requesting through the public
327         * API.  This controls some differences in behavior.
328         * <P>Type: BOOLEAN</P>
329         * <P>Owner can Init/Read</P>
330         */
331        public static final String COLUMN_IS_PUBLIC_API = "is_public_api";
332
333        /**
334         * The name of the column holding a bitmask of allowed network types.  This is only used for
335         * public API downloads.
336         * <P>Type: INTEGER</P>
337         * <P>Owner can Init/Read</P>
338         */
339        public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types";
340
341        /**
342         * The name of the column indicating whether roaming connections can be used.  This is only
343         * used for public API downloads.
344         * <P>Type: BOOLEAN</P>
345         * <P>Owner can Init/Read</P>
346         */
347        public static final String COLUMN_ALLOW_ROAMING = "allow_roaming";
348
349        /**
350         * The name of the column indicating whether metered connections can be used.  This is only
351         * used for public API downloads.
352         * <P>Type: BOOLEAN</P>
353         * <P>Owner can Init/Read</P>
354         */
355        public static final String COLUMN_ALLOW_METERED = "allow_metered";
356
357        /**
358         * Whether or not this download should be displayed in the system's Downloads UI.  Defaults
359         * to true.
360         * <P>Type: INTEGER</P>
361         * <P>Owner can Init/Read</P>
362         */
363        public static final String COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI = "is_visible_in_downloads_ui";
364
365        /**
366         * If true, the user has confirmed that this download can proceed over the mobile network
367         * even though it exceeds the recommended maximum size.
368         * <P>Type: BOOLEAN</P>
369         */
370        public static final String COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT =
371            "bypass_recommended_size_limit";
372
373        /**
374         * Set to true if this download is deleted. It is completely removed from the database
375         * when MediaProvider database also deletes the metadata asociated with this downloaded file.
376         * <P>Type: BOOLEAN</P>
377         * <P>Owner can Read</P>
378         */
379        public static final String COLUMN_DELETED = "deleted";
380
381        /**
382         * The URI to the corresponding entry in MediaProvider for this downloaded entry. It is
383         * used to delete the entries from MediaProvider database when it is deleted from the
384         * downloaded list.
385         * <P>Type: TEXT</P>
386         * <P>Owner can Read</P>
387         */
388        public static final String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
389
390        /**
391         * The column that is used to remember whether the media scanner was invoked.
392         * It can take the values: null or 0(not scanned), 1(scanned), 2 (not scannable).
393         * <P>Type: TEXT</P>
394         */
395        public static final String COLUMN_MEDIA_SCANNED = "scanned";
396
397        /**
398         * The column with errorMsg for a failed downloaded.
399         * Used only for debugging purposes.
400         * <P>Type: TEXT</P>
401         */
402        public static final String COLUMN_ERROR_MSG = "errorMsg";
403
404        /**
405         *  This column stores the source of the last update to this row.
406         *  This column is only for internal use.
407         *  Valid values are indicated by LAST_UPDATESRC_* constants.
408         * <P>Type: INT</P>
409         */
410        public static final String COLUMN_LAST_UPDATESRC = "lastUpdateSrc";
411
412        /** The column that is used to count retries */
413        public static final String COLUMN_FAILED_CONNECTIONS = "numfailed";
414
415        public static final String COLUMN_ALLOW_WRITE = "allow_write";
416
417        public static final int FLAG_REQUIRES_CHARGING = 1 << 0;
418        public static final int FLAG_REQUIRES_DEVICE_IDLE = 1 << 1;
419
420        public static final String COLUMN_FLAGS = "flags";
421
422        /**
423         * default value for {@link #COLUMN_LAST_UPDATESRC}.
424         * This value is used when this column's value is not relevant.
425         */
426        public static final int LAST_UPDATESRC_NOT_RELEVANT = 0;
427
428        /**
429         * One of the values taken by {@link #COLUMN_LAST_UPDATESRC}.
430         * This value is used when the update is NOT to be relayed to the DownloadService
431         * (and thus spare DownloadService from scanning the database when this change occurs)
432         */
433        public static final int LAST_UPDATESRC_DONT_NOTIFY_DOWNLOADSVC = 1;
434
435        /*
436         * Lists the destinations that an application can specify for a download.
437         */
438
439        /**
440         * This download will be saved to the external storage. This is the
441         * default behavior, and should be used for any file that the user
442         * can freely access, copy, delete. Even with that destination,
443         * unencrypted DRM files are saved in secure internal storage.
444         * Downloads to the external destination only write files for which
445         * there is a registered handler. The resulting files are accessible
446         * by filename to all applications.
447         */
448        public static final int DESTINATION_EXTERNAL = 0;
449
450        /**
451         * This download will be saved to the download manager's private
452         * partition. This is the behavior used by applications that want to
453         * download private files that are used and deleted soon after they
454         * get downloaded. All file types are allowed, and only the initiating
455         * application can access the file (indirectly through a content
456         * provider). This requires the
457         * android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED permission.
458         */
459        public static final int DESTINATION_CACHE_PARTITION = 1;
460
461        /**
462         * This download will be saved to the download manager's private
463         * partition and will be purged as necessary to make space. This is
464         * for private files (similar to CACHE_PARTITION) that aren't deleted
465         * immediately after they are used, and are kept around by the download
466         * manager as long as space is available.
467         */
468        public static final int DESTINATION_CACHE_PARTITION_PURGEABLE = 2;
469
470        /**
471         * This download will be saved to the download manager's private
472         * partition, as with DESTINATION_CACHE_PARTITION, but the download
473         * will not proceed if the user is on a roaming data connection.
474         */
475        public static final int DESTINATION_CACHE_PARTITION_NOROAMING = 3;
476
477        /**
478         * This download will be saved to the location given by the file URI in
479         * {@link #COLUMN_FILE_NAME_HINT}.
480         */
481        public static final int DESTINATION_FILE_URI = 4;
482
483        /**
484         * This download will be saved to the system cache ("/cache")
485         * partition. This option is only used by system apps and so it requires
486         * android.permission.ACCESS_CACHE_FILESYSTEM permission.
487         */
488        public static final int DESTINATION_SYSTEMCACHE_PARTITION = 5;
489
490        /**
491         * This download was completed by the caller (i.e., NOT downloadmanager)
492         * and caller wants to have this download displayed in Downloads App.
493         */
494        public static final int DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD = 6;
495
496        /**
497         * This download is allowed to run.
498         */
499        public static final int CONTROL_RUN = 0;
500
501        /**
502         * This download must pause at the first opportunity.
503         */
504        public static final int CONTROL_PAUSED = 1;
505
506        /*
507         * Lists the states that the download manager can set on a download
508         * to notify applications of the download progress.
509         * The codes follow the HTTP families:<br>
510         * 1xx: informational<br>
511         * 2xx: success<br>
512         * 3xx: redirects (not used by the download manager)<br>
513         * 4xx: client errors<br>
514         * 5xx: server errors
515         */
516
517        /**
518         * Returns whether the status is informational (i.e. 1xx).
519         */
520        public static boolean isStatusInformational(int status) {
521            return (status >= 100 && status < 200);
522        }
523
524        /**
525         * Returns whether the status is a success (i.e. 2xx).
526         */
527        public static boolean isStatusSuccess(int status) {
528            return (status >= 200 && status < 300);
529        }
530
531        /**
532         * Returns whether the status is an error (i.e. 4xx or 5xx).
533         */
534        public static boolean isStatusError(int status) {
535            return (status >= 400 && status < 600);
536        }
537
538        /**
539         * Returns whether the status is a client error (i.e. 4xx).
540         */
541        public static boolean isStatusClientError(int status) {
542            return (status >= 400 && status < 500);
543        }
544
545        /**
546         * Returns whether the status is a server error (i.e. 5xx).
547         */
548        public static boolean isStatusServerError(int status) {
549            return (status >= 500 && status < 600);
550        }
551
552        /**
553         * this method determines if a notification should be displayed for a
554         * given {@link #COLUMN_VISIBILITY} value
555         * @param visibility the value of {@link #COLUMN_VISIBILITY}.
556         * @return true if the notification should be displayed. false otherwise.
557         */
558        public static boolean isNotificationToBeDisplayed(int visibility) {
559            return visibility == DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED ||
560                    visibility == DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION;
561        }
562
563        /**
564         * Returns whether the download has completed (either with success or
565         * error).
566         */
567        public static boolean isStatusCompleted(int status) {
568            return (status >= 200 && status < 300) || (status >= 400 && status < 600);
569        }
570
571        /**
572         * This download hasn't stated yet
573         */
574        public static final int STATUS_PENDING = 190;
575
576        /**
577         * This download has started
578         */
579        public static final int STATUS_RUNNING = 192;
580
581        /**
582         * This download has been paused by the owning app.
583         */
584        public static final int STATUS_PAUSED_BY_APP = 193;
585
586        /**
587         * This download encountered some network error and is waiting before retrying the request.
588         */
589        public static final int STATUS_WAITING_TO_RETRY = 194;
590
591        /**
592         * This download is waiting for network connectivity to proceed.
593         */
594        public static final int STATUS_WAITING_FOR_NETWORK = 195;
595
596        /**
597         * This download exceeded a size limit for mobile networks and is waiting for a Wi-Fi
598         * connection to proceed.
599         */
600        public static final int STATUS_QUEUED_FOR_WIFI = 196;
601
602        /**
603         * This download couldn't be completed due to insufficient storage
604         * space.  Typically, this is because the SD card is full.
605         */
606        public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 198;
607
608        /**
609         * This download couldn't be completed because no external storage
610         * device was found.  Typically, this is because the SD card is not
611         * mounted.
612         */
613        public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 199;
614
615        /**
616         * This download has successfully completed.
617         * Warning: there might be other status values that indicate success
618         * in the future.
619         * Use isStatusSuccess() to capture the entire category.
620         */
621        public static final int STATUS_SUCCESS = 200;
622
623        /**
624         * This request couldn't be parsed. This is also used when processing
625         * requests with unknown/unsupported URI schemes.
626         */
627        public static final int STATUS_BAD_REQUEST = 400;
628
629        /**
630         * This download can't be performed because the content type cannot be
631         * handled.
632         */
633        public static final int STATUS_NOT_ACCEPTABLE = 406;
634
635        /**
636         * This download cannot be performed because the length cannot be
637         * determined accurately. This is the code for the HTTP error "Length
638         * Required", which is typically used when making requests that require
639         * a content length but don't have one, and it is also used in the
640         * client when a response is received whose length cannot be determined
641         * accurately (therefore making it impossible to know when a download
642         * completes).
643         */
644        public static final int STATUS_LENGTH_REQUIRED = 411;
645
646        /**
647         * This download was interrupted and cannot be resumed.
648         * This is the code for the HTTP error "Precondition Failed", and it is
649         * also used in situations where the client doesn't have an ETag at all.
650         */
651        public static final int STATUS_PRECONDITION_FAILED = 412;
652
653        /**
654         * The lowest-valued error status that is not an actual HTTP status code.
655         */
656        public static final int MIN_ARTIFICIAL_ERROR_STATUS = 488;
657
658        /**
659         * The requested destination file already exists.
660         */
661        public static final int STATUS_FILE_ALREADY_EXISTS_ERROR = 488;
662
663        /**
664         * Some possibly transient error occurred, but we can't resume the download.
665         */
666        public static final int STATUS_CANNOT_RESUME = 489;
667
668        /**
669         * This download was canceled
670         */
671        public static final int STATUS_CANCELED = 490;
672
673        /**
674         * This download has completed with an error.
675         * Warning: there will be other status values that indicate errors in
676         * the future. Use isStatusError() to capture the entire category.
677         */
678        public static final int STATUS_UNKNOWN_ERROR = 491;
679
680        /**
681         * This download couldn't be completed because of a storage issue.
682         * Typically, that's because the filesystem is missing or full.
683         * Use the more specific {@link #STATUS_INSUFFICIENT_SPACE_ERROR}
684         * and {@link #STATUS_DEVICE_NOT_FOUND_ERROR} when appropriate.
685         */
686        public static final int STATUS_FILE_ERROR = 492;
687
688        /**
689         * This download couldn't be completed because of an HTTP
690         * redirect response that the download manager couldn't
691         * handle.
692         */
693        public static final int STATUS_UNHANDLED_REDIRECT = 493;
694
695        /**
696         * This download couldn't be completed because of an
697         * unspecified unhandled HTTP code.
698         */
699        public static final int STATUS_UNHANDLED_HTTP_CODE = 494;
700
701        /**
702         * This download couldn't be completed because of an
703         * error receiving or processing data at the HTTP level.
704         */
705        public static final int STATUS_HTTP_DATA_ERROR = 495;
706
707        /**
708         * This download couldn't be completed because of an
709         * HttpException while setting up the request.
710         */
711        public static final int STATUS_HTTP_EXCEPTION = 496;
712
713        /**
714         * This download couldn't be completed because there were
715         * too many redirects.
716         */
717        public static final int STATUS_TOO_MANY_REDIRECTS = 497;
718
719        /**
720         * This download has failed because requesting application has been
721         * blocked by {@link NetworkPolicyManager}.
722         *
723         * @hide
724         * @deprecated since behavior now uses
725         *             {@link #STATUS_WAITING_FOR_NETWORK}
726         */
727        @Deprecated
728        public static final int STATUS_BLOCKED = 498;
729
730        /** {@hide} */
731        public static String statusToString(int status) {
732            switch (status) {
733                case STATUS_PENDING: return "PENDING";
734                case STATUS_RUNNING: return "RUNNING";
735                case STATUS_PAUSED_BY_APP: return "PAUSED_BY_APP";
736                case STATUS_WAITING_TO_RETRY: return "WAITING_TO_RETRY";
737                case STATUS_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK";
738                case STATUS_QUEUED_FOR_WIFI: return "QUEUED_FOR_WIFI";
739                case STATUS_INSUFFICIENT_SPACE_ERROR: return "INSUFFICIENT_SPACE_ERROR";
740                case STATUS_DEVICE_NOT_FOUND_ERROR: return "DEVICE_NOT_FOUND_ERROR";
741                case STATUS_SUCCESS: return "SUCCESS";
742                case STATUS_BAD_REQUEST: return "BAD_REQUEST";
743                case STATUS_NOT_ACCEPTABLE: return "NOT_ACCEPTABLE";
744                case STATUS_LENGTH_REQUIRED: return "LENGTH_REQUIRED";
745                case STATUS_PRECONDITION_FAILED: return "PRECONDITION_FAILED";
746                case STATUS_FILE_ALREADY_EXISTS_ERROR: return "FILE_ALREADY_EXISTS_ERROR";
747                case STATUS_CANNOT_RESUME: return "CANNOT_RESUME";
748                case STATUS_CANCELED: return "CANCELED";
749                case STATUS_UNKNOWN_ERROR: return "UNKNOWN_ERROR";
750                case STATUS_FILE_ERROR: return "FILE_ERROR";
751                case STATUS_UNHANDLED_REDIRECT: return "UNHANDLED_REDIRECT";
752                case STATUS_UNHANDLED_HTTP_CODE: return "UNHANDLED_HTTP_CODE";
753                case STATUS_HTTP_DATA_ERROR: return "HTTP_DATA_ERROR";
754                case STATUS_HTTP_EXCEPTION: return "HTTP_EXCEPTION";
755                case STATUS_TOO_MANY_REDIRECTS: return "TOO_MANY_REDIRECTS";
756                case STATUS_BLOCKED: return "BLOCKED";
757                default: return Integer.toString(status);
758            }
759        }
760
761        /**
762         * This download is visible but only shows in the notifications
763         * while it's in progress.
764         */
765        public static final int VISIBILITY_VISIBLE = DownloadManager.Request.VISIBILITY_VISIBLE;
766
767        /**
768         * This download is visible and shows in the notifications while
769         * in progress and after completion.
770         */
771        public static final int VISIBILITY_VISIBLE_NOTIFY_COMPLETED =
772                DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED;
773
774        /**
775         * This download doesn't show in the UI or in the notifications.
776         */
777        public static final int VISIBILITY_HIDDEN = DownloadManager.Request.VISIBILITY_HIDDEN;
778
779        /**
780         * Constants related to HTTP request headers associated with each download.
781         */
782        public static class RequestHeaders {
783            public static final String HEADERS_DB_TABLE = "request_headers";
784            public static final String COLUMN_DOWNLOAD_ID = "download_id";
785            public static final String COLUMN_HEADER = "header";
786            public static final String COLUMN_VALUE = "value";
787
788            /**
789             * Path segment to add to a download URI to retrieve request headers
790             */
791            public static final String URI_SEGMENT = "headers";
792
793            /**
794             * Prefix for ContentValues keys that contain HTTP header lines, to be passed to
795             * DownloadProvider.insert().
796             */
797            public static final String INSERT_KEY_PREFIX = "http_header_";
798        }
799    }
800
801    /**
802     * Query where clause for general querying.
803     */
804    private static final String QUERY_WHERE_CLAUSE = Impl.COLUMN_NOTIFICATION_PACKAGE + "=? AND "
805            + Impl.COLUMN_NOTIFICATION_CLASS + "=?";
806
807    /**
808     * Delete all the downloads for a package/class pair.
809     */
810    public static final void removeAllDownloadsByPackage(
811            Context context, String notification_package, String notification_class) {
812        context.getContentResolver().delete(Impl.CONTENT_URI, QUERY_WHERE_CLAUSE,
813                new String[] { notification_package, notification_class });
814    }
815}
816