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