1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // Each download is represented by a DownloadItem, and all DownloadItems
6 // are owned by the DownloadManager which maintains a global list of all
7 // downloads. DownloadItems are created when a user initiates a download,
8 // and exist for the duration of the browser life time.
9 //
10 // Download observers:
11 //   DownloadItem::Observer:
12 //     - allows observers to receive notifications about one download from start
13 //       to completion
14 // Use AddObserver() / RemoveObserver() on the appropriate download object to
15 // receive state updates.
16 
17 #ifndef COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_ITEM_H_
18 #define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_ITEM_H_
19 
20 #include <stdint.h>
21 
22 #include <map>
23 #include <string>
24 #include <vector>
25 
26 #include "base/callback_forward.h"
27 #include "base/files/file_path.h"
28 #include "base/memory/ref_counted.h"
29 #include "base/optional.h"
30 #include "base/strings/string16.h"
31 #include "base/supports_user_data.h"
32 #include "components/download/public/common/download_danger_type.h"
33 #include "components/download/public/common/download_export.h"
34 #include "components/download/public/common/download_interrupt_reasons.h"
35 #include "components/download/public/common/download_source.h"
36 #include "ui/base/page_transition_types.h"
37 #include "url/origin.h"
38 
39 class GURL;
40 
41 namespace base {
42 class FilePath;
43 class Time;
44 class TimeDelta;
45 }  // namespace base
46 
47 namespace net {
48 class HttpResponseHeaders;
49 }
50 
51 namespace download {
52 class DownloadFile;
53 
54 // One DownloadItem per download. This is the model class that stores all the
55 // state for a download.
56 class COMPONENTS_DOWNLOAD_EXPORT DownloadItem : public base::SupportsUserData {
57  public:
58   // A Java counterpart will be generated for this enum.
59   // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.download
60   enum DownloadState {
61     // Download is actively progressing.
62     IN_PROGRESS = 0,
63 
64     // Download is completely finished.
65     COMPLETE,
66 
67     // Download has been cancelled.
68     CANCELLED,
69 
70     // This state indicates that the download has been interrupted.
71     INTERRUPTED,
72 
73     // Maximum value.
74     MAX_DOWNLOAD_STATE
75   };
76 
77   // How the final target path should be used.
78   enum TargetDisposition {
79     TARGET_DISPOSITION_OVERWRITE,  // Overwrite if the target already exists.
80     TARGET_DISPOSITION_PROMPT      // Prompt the user for the actual
81                                    // target. Implies
82                                    // TARGET_DISPOSITION_OVERWRITE.
83   };
84 
85   // How download item is created. Used for trace event.
86   enum DownloadCreationType {
87     TYPE_ACTIVE_DOWNLOAD,
88     TYPE_HISTORY_IMPORT,
89     TYPE_SAVE_PAGE_AS
90   };
91 
92   // Result of a rename attempt for a download item.
93   enum DownloadRenameResult {
94     SUCCESS = 0,
95     FAILURE_NAME_CONFLICT = 1,
96     FAILURE_NAME_TOO_LONG = 2,
97     FAILURE_NAME_INVALID = 3,
98     FAILURE_UNAVAILABLE = 4,
99     FAILURE_UNKNOWN = 5,
100     RESULT_MAX = FAILURE_UNKNOWN
101   };
102 
103   // The mixed content status for a download item.
104   enum MixedContentStatus {
105     // Target not yet determined, so status not yet available.
106     UNKNOWN = 0,
107     // Download is not mixed content.
108     SAFE = 1,
109     // Download has been explicitly OK'd by the user.
110     VALIDATED = 2,
111     // Download is mixed content, and the user should be warned.
112     WARN = 3,
113     // Download is mixed content, and the user should see an error.
114     BLOCK = 4,
115     // Download is mixed content, and it should be silently dropped.
116     SILENT_BLOCK = 5,
117   };
118 
119   // Callback used with AcquireFileAndDeleteDownload().
120   using AcquireFileCallback = base::OnceCallback<void(const base::FilePath&)>;
121   using RenameDownloadCallback = base::OnceCallback<void(DownloadRenameResult)>;
122   // Used to represent an invalid download ID.
123   static const uint32_t kInvalidId;
124 
125   // Interface that observers of a particular download must implement in order
126   // to receive updates to the download's status.
127   class COMPONENTS_DOWNLOAD_EXPORT Observer {
128    public:
OnDownloadUpdated(DownloadItem * download)129     virtual void OnDownloadUpdated(DownloadItem* download) {}
OnDownloadOpened(DownloadItem * download)130     virtual void OnDownloadOpened(DownloadItem* download) {}
OnDownloadRemoved(DownloadItem * download)131     virtual void OnDownloadRemoved(DownloadItem* download) {}
132 
133     // Called when the download is being destroyed. This happens after
134     // every OnDownloadRemoved() as well as when the DownloadManager is going
135     // down.
OnDownloadDestroyed(DownloadItem * download)136     virtual void OnDownloadDestroyed(DownloadItem* download) {}
137 
~Observer()138     virtual ~Observer() {}
139   };
140 
141   // A slice of the target file that has been received so far, used when
142   // parallel downloading is enabled. Slices should have different offsets
143   // so that they don't overlap. |finished| will be marked as true when the
144   // download stream is successfully completed.
145   struct ReceivedSlice {
ReceivedSliceReceivedSlice146     ReceivedSlice(int64_t offset, int64_t received_bytes)
147         : offset(offset), received_bytes(received_bytes), finished(false) {}
148 
ReceivedSliceReceivedSlice149     ReceivedSlice(int64_t offset, int64_t received_bytes, bool finished)
150         : offset(offset), received_bytes(received_bytes), finished(finished) {}
151 
152     bool operator==(const ReceivedSlice& rhs) const {
153       return offset == rhs.offset && received_bytes == rhs.received_bytes &&
154              finished == rhs.finished;
155     }
156 
157     int64_t offset;
158     int64_t received_bytes;
159     bool finished;
160   };
161 
162   using ReceivedSlices = std::vector<DownloadItem::ReceivedSlice>;
163 
~DownloadItem()164   ~DownloadItem() override {}
165 
166   // Observation ---------------------------------------------------------------
167 
168   virtual void AddObserver(DownloadItem::Observer* observer) = 0;
169   virtual void RemoveObserver(DownloadItem::Observer* observer) = 0;
170   virtual void UpdateObservers() = 0;
171 
172   // User Actions --------------------------------------------------------------
173 
174   // Called when the user has validated the download of a dangerous file.
175   virtual void ValidateDangerousDownload() = 0;
176 
177   // Called when the user has validated the download of a mixed content file.
178   virtual void ValidateMixedContentDownload() = 0;
179 
180   // Called to acquire a dangerous download. If |delete_file_afterward| is true,
181   // invokes |callback| on the UI thread with the path to the downloaded file,
182   // and removes the DownloadItem from views and history if appropriate.
183   // Otherwise, makes a temp copy of the download file, and invokes |callback|
184   // with the path to the temp copy. The caller is responsible for cleanup.
185   // Note: It is important for |callback| to be valid since the downloaded file
186   // will not be cleaned up if the callback fails.
187   virtual void StealDangerousDownload(bool delete_file_afterward,
188                                       AcquireFileCallback callback) = 0;
189 
190   // Pause a download.  Will have no effect if the download is already
191   // paused.
192   virtual void Pause() = 0;
193 
194   // Resume a download that has been paused or interrupted. Will have no effect
195   // if the download is neither. Only does something if CanResume() returns
196   // true.
197   virtual void Resume(bool user_resume) = 0;
198 
199   // Cancel the download operation.
200   //
201   // Set |user_cancel| to true if the cancellation was triggered by an explicit
202   // user action. Non-user-initiated cancels typically happen when the browser
203   // is being closed with in-progress downloads.
204   virtual void Cancel(bool user_cancel) = 0;
205 
206   // Removes the download from the views and history. If the download was
207   // in-progress or interrupted, then the intermediate file will also be
208   // deleted.
209   virtual void Remove() = 0;
210 
211   // Open the file associated with this download.  If the download is
212   // still in progress, marks the download to be opened when it is complete.
213   virtual void OpenDownload() = 0;
214 
215   // Show the download via the OS shell.
216   virtual void ShowDownloadInShell() = 0;
217 
218   // Rename a downloaded item to |new_name|, implementer should post and reply
219   // the result. Do not pass the full file path, just pass the file name portion
220   // instead.
221   virtual void Rename(const base::FilePath& new_name,
222                       RenameDownloadCallback callback) = 0;
223 
224   // State accessors -----------------------------------------------------------
225 
226   // Retrieve the ID for this download. The ID is provided by the owner of the
227   // DownloadItem and is expected to uniquely identify the download within the
228   // context of its container during the lifetime of the download. A valid
229   // download will never return |kInvalidId|.
230   virtual uint32_t GetId() const = 0;
231 
232   // Retrieve the GUID for this download. The returned string is never empty and
233   // will satisfy base::IsValidGUID() and uniquely identifies the download
234   // during its lifetime.
235   virtual const std::string& GetGuid() const = 0;
236 
237   // Get the current state of the download. See DownloadState for descriptions
238   // of each download state.
239   virtual DownloadState GetState() const = 0;
240 
241   // Returns the most recent interrupt reason for this download. Returns
242   // |DOWNLOAD_INTERRUPT_REASON_NONE| if there is no previous interrupt reason.
243   // Interrupted downloads and resumed downloads return the last known interrupt
244   // reason.
245   virtual DownloadInterruptReason GetLastReason() const = 0;
246 
247   // Returns whether download is currently paused explicitly by the user. The
248   // download state should be checked in conjunction with this method to
249   // determine whether the download was truly paused. Calling Resume() will
250   // transition out of this paused state.
251   virtual bool IsPaused() const = 0;
252 
253   // Whether the download should be allowed to proceed in a metered network.
254   virtual bool AllowMetered() const = 0;
255 
256   // DEPRECATED. True if this is a temporary download and should not be
257   // persisted.
258   virtual bool IsTemporary() const = 0;
259 
260   // Returns true if the download can be resumed. A download can be resumed if
261   // an in-progress download was paused or if an interrupted download requires
262   // user-interaction to resume.
263   virtual bool CanResume() const = 0;
264 
265   // Returns true if the download is in a terminal state. This includes
266   // completed downloads, cancelled downloads, and interrupted downloads that
267   // can't be resumed.
268   virtual bool IsDone() const = 0;
269 
270   // Returns the calculated number of bytes wasted (if any).
271   virtual int64_t GetBytesWasted() const = 0;
272 
273   // Returns the number of times the download has been auto-resumed since last
274   // user triggered resumption.
275   virtual int32_t GetAutoResumeCount() const = 0;
276 
277   //    Origin State accessors -------------------------------------------------
278 
279   // Final URL. The primary resource being downloaded is from this URL. This is
280   // the tail of GetUrlChain(). May return an empty GURL if there is no valid
281   // download URL.
282   virtual const GURL& GetURL() const = 0;
283 
284   // The complete URL chain including redirects. URL at index i redirected to
285   // URL at index i+1.
286   virtual const std::vector<GURL>& GetUrlChain() const = 0;
287 
288   // The URL that the download request originally attempted to fetch. This may
289   // differ from GetURL() if there were redirects. The return value from this
290   // accessor is the same as the head of GetUrlChain().
291   virtual const GURL& GetOriginalUrl() const = 0;
292 
293   // URL of document that is considered the referrer for the original URL.
294   virtual const GURL& GetReferrerUrl() const = 0;
295 
296   // Site instance URL. Used to locate the correct storage partition during
297   // subsequent browser sessions. This may be different from all of
298   // GetOriginalUrl(), GetURL() and GetReferrerUrl().
299   virtual const GURL& GetSiteUrl() const = 0;
300 
301   // URL of the top level frame at the time the download was initiated.
302   virtual const GURL& GetTabUrl() const = 0;
303 
304   // Referrer URL for top level frame.
305   virtual const GURL& GetTabReferrerUrl() const = 0;
306 
307   // Origin of the original originator of this download, before redirects, etc.
308   virtual const base::Optional<url::Origin>& GetRequestInitiator() const = 0;
309 
310   // For downloads initiated via <a download>, this is the suggested download
311   // filename from the download attribute.
312   virtual std::string GetSuggestedFilename() const = 0;
313 
314   // Returns the HTTP response headers. This contains a nullptr when the
315   // response has not yet been received, and, because the headers are not being
316   // persisted, only capture responses received during the lifetime of the
317   // current process and profile. Only for consuming headers.
318   virtual const scoped_refptr<const net::HttpResponseHeaders>&
319   GetResponseHeaders() const = 0;
320 
321   // Content-Disposition header value from HTTP response.
322   virtual std::string GetContentDisposition() const = 0;
323 
324   // Effective MIME type of downloaded content.
325   virtual std::string GetMimeType() const = 0;
326 
327   // Content-Type header value from HTTP response. May be different from
328   // GetMimeType() if a different effective MIME type was chosen after MIME
329   // sniffing.
330   virtual std::string GetOriginalMimeType() const = 0;
331 
332   // Remote address of server serving download contents.
333   virtual std::string GetRemoteAddress() const = 0;
334 
335   // Whether the download request was initiated in response to a user gesture.
336   virtual bool HasUserGesture() const = 0;
337 
338   // The page transition type associated with the download request.
339   virtual ui::PageTransition GetTransitionType() const = 0;
340 
341   // Last-Modified header value.
342   virtual const std::string& GetLastModifiedTime() const = 0;
343 
344   // ETag header value.
345   virtual const std::string& GetETag() const = 0;
346 
347   // Whether this download is a SavePackage download.
348   virtual bool IsSavePackageDownload() const = 0;
349 
350   // DownloadSource prompting this download.
351   virtual DownloadSource GetDownloadSource() const = 0;
352 
353   //    Destination State accessors --------------------------------------------
354 
355   // Full path to the downloaded or downloading file. This is the path to the
356   // physical file, if one exists. It should be considered a hint; changes to
357   // this value and renames of the file on disk are not atomic with each other.
358   // May be empty if the in-progress path hasn't been determined yet or if the
359   // download was interrupted.
360   //
361   // DO NOT USE THIS METHOD to access the target path of the DownloadItem. Use
362   // GetTargetFilePath() instead. While the download is in progress, the
363   // intermediate file named by GetFullPath() may be renamed or disappear
364   // completely on the download sequence. The path may also be reset to empty
365   // when the download is interrupted.
366   virtual const base::FilePath& GetFullPath() const = 0;
367 
368   // Target path of an in-progress download. We may be downloading to a
369   // temporary or intermediate file (specified by GetFullPath()); this is the
370   // name we will use once the download completes.
371   // May be empty if the target path hasn't yet been determined.
372   virtual const base::FilePath& GetTargetFilePath() const = 0;
373 
374   // If the download forced a path rather than requesting name determination,
375   // return the path requested.
376   virtual const base::FilePath& GetForcedFilePath() const = 0;
377 
378   // Path to the temporary file. This could be empty if full path is already
379   // determined.
380   // TODO(qinmin): merge this with GetFullPath().
381   virtual base::FilePath GetTemporaryFilePath() const = 0;
382 
383   // Returns the file-name that should be reported to the user. If a display
384   // name has been explicitly set using SetDisplayName(), this function returns
385   // that display name. Otherwise returns the final target filename.
386   virtual base::FilePath GetFileNameToReportUser() const = 0;
387 
388   // See TargetDisposition.
389   virtual TargetDisposition GetTargetDisposition() const = 0;
390 
391   // Final hash of completely downloaded file, or partial hash of an interrupted
392   // download; only valid if GetState() == COMPLETED or INTERRUPTED. If
393   // non-empty the returned string contains a raw SHA-256 hash (i.e. not hex
394   // encoded).
395   virtual const std::string& GetHash() const = 0;
396 
397   // True if the file associated with the download has been removed by
398   // external action.
399   virtual bool GetFileExternallyRemoved() const = 0;
400 
401   // If the file is successfully deleted, then GetFileExternallyRemoved() will
402   // become true, GetFullPath() will become empty, and
403   // DownloadItem::OnDownloadUpdated() will be called. Does nothing if
404   // GetState() != COMPLETE or GetFileExternallyRemoved() is already true or
405   // GetFullPath() is already empty. The callback is always run, and it is
406   // always run asynchronously. It will be passed true if the file is
407   // successfully deleted or if GetFilePath() was already empty or if
408   // GetFileExternallyRemoved() was already true. The callback will be passed
409   // false if the DownloadItem was not yet complete or if the file could not be
410   // deleted for any reason.
411   virtual void DeleteFile(base::OnceCallback<void(bool)> callback) = 0;
412 
413   // True if the file that will be written by the download is dangerous
414   // and we will require a call to ValidateDangerousDownload() to complete.
415   // False if the download is safe or that function has been called.
416   virtual bool IsDangerous() const = 0;
417 
418   // True if the file that will be written by the download is mixed content
419   // and we will require a call to ValidateMixedContentDownload() to complete.
420   // False if not mixed content or that function has been called.
421   virtual bool IsMixedContent() const = 0;
422 
423   // Why |safety_state_| is not SAFE.
424   virtual DownloadDangerType GetDangerType() const = 0;
425 
426   // Returns the mixed content status of the download, indicating whether the
427   // download should be blocked or the user warned. This may be UNKNOWN if the
428   // download target hasn't been determined.
429   virtual MixedContentStatus GetMixedContentStatus() const = 0;
430 
431   // Gets the pointer to the DownloadFile owned by this object.
432   virtual DownloadFile* GetDownloadFile() = 0;
433 
434   //    Progress State accessors -----------------------------------------------
435 
436   // Simple calculation of the amount of time remaining to completion. Fills
437   // |*remaining| with the amount of time remaining if successful. Fails and
438   // returns false if we do not have the number of bytes or the speed so can
439   // not estimate.
440   virtual bool TimeRemaining(base::TimeDelta* remaining) const = 0;
441 
442   // Simple speed estimate in bytes/s
443   virtual int64_t CurrentSpeed() const = 0;
444 
445   // Rough percent complete. Returns -1 if progress is unknown. 100 if the
446   // download is already complete.
447   virtual int PercentComplete() const = 0;
448 
449   // Returns true if this download has saved all of its data. A download may
450   // have saved all its data but still be waiting for some other process to
451   // complete before the download is considered complete. E.g. A dangerous
452   // download needs to be accepted by the user before the file is renamed to its
453   // final name.
454   virtual bool AllDataSaved() const = 0;
455 
456   // Total number of expected bytes. Returns -1 if the total size is unknown.
457   virtual int64_t GetTotalBytes() const = 0;
458 
459   // Total number of bytes that have been received and written to the download
460   // file.
461   virtual int64_t GetReceivedBytes() const = 0;
462 
463   // Return the slices that have been received so far, ordered by their offset.
464   // This is only used when parallel downloading is enabled.
465   virtual const std::vector<ReceivedSlice>& GetReceivedSlices() const = 0;
466 
467   // Time the download was first started. This timestamp is always valid and
468   // doesn't change.
469   virtual base::Time GetStartTime() const = 0;
470 
471   // Time the download was marked as complete. Returns base::Time() if the
472   // download hasn't reached a completion state yet.
473   virtual base::Time GetEndTime() const = 0;
474 
475   //    Open/Show State accessors ----------------------------------------------
476 
477   // Returns true if it is OK to open a folder which this file is inside.
478   virtual bool CanShowInFolder() = 0;
479 
480   // Returns true if it is OK to open the download.
481   virtual bool CanOpenDownload() = 0;
482 
483   // Tests if a file type should be opened automatically.
484   virtual bool ShouldOpenFileBasedOnExtension() = 0;
485 
486   // Returns true if the download will be auto-opened when complete.
487   virtual bool GetOpenWhenComplete() const = 0;
488 
489   // Returns true if the download has been auto-opened by the system.
490   virtual bool GetAutoOpened() = 0;
491 
492   // Returns true if the download has been opened.
493   virtual bool GetOpened() const = 0;
494 
495   // Time the download was last accessed. Returns NULL if the download has never
496   // been opened.
497   virtual base::Time GetLastAccessTime() const = 0;
498 
499   // Returns whether the download item is transient. Transient items are cleaned
500   // up after completion and not shown in the UI, and will not prompt to user
501   // for target file path determination.
502   virtual bool IsTransient() const = 0;
503 
504   // Returns whether the download item corresponds to a parallel download. This
505   // usually means parallel download has been enabled and the download job is
506   // parallelizable.
507   virtual bool IsParallelDownload() const = 0;
508 
509   // Gets the DownloadCreationType of this item.
510   virtual DownloadCreationType GetDownloadCreationType() const = 0;
511 
512   // External state transitions/setters ----------------------------------------
513 
514   // TODO(rdsmith): These should all be removed; the download item should
515   // control its own state transitions.
516 
517   // Called if a check of the download contents was performed and the results of
518   // the test are available. This should only be called after AllDataSaved() is
519   // true. If |reason| is not DOWNLOAD_INTERRUPT_REASON_NONE, then the download
520   // file should be blocked.
521   // TODO(crbug.com/733291): Move DownloadInterruptReason out of here and add a
522   // new  Interrupt method instead. Same for other methods supporting
523   // interruptions.
524   virtual void OnContentCheckCompleted(DownloadDangerType danger_type,
525                                        DownloadInterruptReason reason) = 0;
526 
527   // Called when async scanning completes with the given |danger_type|.
528   virtual void OnAsyncScanningCompleted(DownloadDangerType danger_type) = 0;
529 
530   // Mark the download to be auto-opened when completed.
531   virtual void SetOpenWhenComplete(bool open) = 0;
532 
533   // Mark the download as having been opened (without actually opening it).
534   virtual void SetOpened(bool opened) = 0;
535 
536   // Updates the last access time of the download.
537   virtual void SetLastAccessTime(base::Time last_access_time) = 0;
538 
539   // Set a display name for the download that will be independent of the target
540   // filename. If |name| is not empty, then GetFileNameToReportUser() will
541   // return |name|. Has no effect on the final target filename.
542   virtual void SetDisplayName(const base::FilePath& name) = 0;
543 
544   // Debug/testing -------------------------------------------------------------
545   virtual std::string DebugString(bool verbose) const = 0;
546   virtual void SimulateErrorForTesting(DownloadInterruptReason reason) = 0;
547 };
548 
549 }  // namespace download
550 
551 #endif  // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_ITEM_H_
552