• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 #ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_IMPL_H_
6 #define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_IMPL_H_
7 
8 #include <string>
9 
10 #include "base/basictypes.h"
11 #include "base/callback_forward.h"
12 #include "base/files/file_path.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/observer_list.h"
16 #include "base/time/time.h"
17 #include "base/timer/timer.h"
18 #include "content/browser/download/download_net_log_parameters.h"
19 #include "content/browser/download/download_request_handle.h"
20 #include "content/common/content_export.h"
21 #include "content/public/browser/download_destination_observer.h"
22 #include "content/public/browser/download_item.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/net_log.h"
25 #include "url/gurl.h"
26 
27 namespace content {
28 class DownloadFile;
29 class DownloadItemImplDelegate;
30 
31 // See download_item.h for usage.
32 class CONTENT_EXPORT DownloadItemImpl
33     : public DownloadItem,
34       public DownloadDestinationObserver {
35  public:
36   enum ResumeMode {
37     RESUME_MODE_INVALID = 0,
38     RESUME_MODE_IMMEDIATE_CONTINUE,
39     RESUME_MODE_IMMEDIATE_RESTART,
40     RESUME_MODE_USER_CONTINUE,
41     RESUME_MODE_USER_RESTART
42   };
43 
44   // The maximum number of attempts we will make to resume automatically.
45   static const int kMaxAutoResumeAttempts;
46 
47   // Note that it is the responsibility of the caller to ensure that a
48   // DownloadItemImplDelegate passed to a DownloadItemImpl constructor
49   // outlives the DownloadItemImpl.
50 
51   // Constructing from persistent store:
52   // |bound_net_log| is constructed externally for our use.
53   DownloadItemImpl(DownloadItemImplDelegate* delegate,
54                    uint32 id,
55                    const base::FilePath& current_path,
56                    const base::FilePath& target_path,
57                    const std::vector<GURL>& url_chain,
58                    const GURL& referrer_url,
59                    const base::Time& start_time,
60                    const base::Time& end_time,
61                    const std::string& etag,
62                    const std::string& last_modified,
63                    int64 received_bytes,
64                    int64 total_bytes,
65                    DownloadItem::DownloadState state,
66                    DownloadDangerType danger_type,
67                    DownloadInterruptReason interrupt_reason,
68                    bool opened,
69                    const net::BoundNetLog& bound_net_log);
70 
71   // Constructing for a regular download.
72   // |bound_net_log| is constructed externally for our use.
73   DownloadItemImpl(DownloadItemImplDelegate* delegate,
74                    uint32 id,
75                    const DownloadCreateInfo& info,
76                    const net::BoundNetLog& bound_net_log);
77 
78   // Constructing for the "Save Page As..." feature:
79   // |bound_net_log| is constructed externally for our use.
80   DownloadItemImpl(DownloadItemImplDelegate* delegate,
81                    uint32 id,
82                    const base::FilePath& path,
83                    const GURL& url,
84                    const std::string& mime_type,
85                    scoped_ptr<DownloadRequestHandleInterface> request_handle,
86                    const net::BoundNetLog& bound_net_log);
87 
88   virtual ~DownloadItemImpl();
89 
90   // DownloadItem
91   virtual void AddObserver(DownloadItem::Observer* observer) OVERRIDE;
92   virtual void RemoveObserver(DownloadItem::Observer* observer) OVERRIDE;
93   virtual void UpdateObservers() OVERRIDE;
94   virtual void ValidateDangerousDownload() OVERRIDE;
95   virtual void StealDangerousDownload(const AcquireFileCallback& callback)
96       OVERRIDE;
97   virtual void Pause() OVERRIDE;
98   virtual void Resume() OVERRIDE;
99   virtual void Cancel(bool user_cancel) OVERRIDE;
100   virtual void Remove() OVERRIDE;
101   virtual void OpenDownload() OVERRIDE;
102   virtual void ShowDownloadInShell() OVERRIDE;
103   virtual uint32 GetId() const OVERRIDE;
104   virtual DownloadState GetState() const OVERRIDE;
105   virtual DownloadInterruptReason GetLastReason() const OVERRIDE;
106   virtual bool IsPaused() const OVERRIDE;
107   virtual bool IsTemporary() const OVERRIDE;
108   virtual bool CanResume() const OVERRIDE;
109   virtual bool IsDone() const OVERRIDE;
110   virtual const GURL& GetURL() const OVERRIDE;
111   virtual const std::vector<GURL>& GetUrlChain() const OVERRIDE;
112   virtual const GURL& GetOriginalUrl() const OVERRIDE;
113   virtual const GURL& GetReferrerUrl() const OVERRIDE;
114   virtual std::string GetSuggestedFilename() const OVERRIDE;
115   virtual std::string GetContentDisposition() const OVERRIDE;
116   virtual std::string GetMimeType() const OVERRIDE;
117   virtual std::string GetOriginalMimeType() const OVERRIDE;
118   virtual std::string GetRemoteAddress() const OVERRIDE;
119   virtual bool HasUserGesture() const OVERRIDE;
120   virtual PageTransition GetTransitionType() const OVERRIDE;
121   virtual const std::string& GetLastModifiedTime() const OVERRIDE;
122   virtual const std::string& GetETag() const OVERRIDE;
123   virtual bool IsSavePackageDownload() const OVERRIDE;
124   virtual const base::FilePath& GetFullPath() const OVERRIDE;
125   virtual const base::FilePath& GetTargetFilePath() const OVERRIDE;
126   virtual const base::FilePath& GetForcedFilePath() const OVERRIDE;
127   virtual base::FilePath GetFileNameToReportUser() const OVERRIDE;
128   virtual TargetDisposition GetTargetDisposition() const OVERRIDE;
129   virtual const std::string& GetHash() const OVERRIDE;
130   virtual const std::string& GetHashState() const OVERRIDE;
131   virtual bool GetFileExternallyRemoved() const OVERRIDE;
132   virtual void DeleteFile() OVERRIDE;
133   virtual bool IsDangerous() const OVERRIDE;
134   virtual DownloadDangerType GetDangerType() const OVERRIDE;
135   virtual bool TimeRemaining(base::TimeDelta* remaining) const OVERRIDE;
136   virtual int64 CurrentSpeed() const OVERRIDE;
137   virtual int PercentComplete() const OVERRIDE;
138   virtual bool AllDataSaved() const OVERRIDE;
139   virtual int64 GetTotalBytes() const OVERRIDE;
140   virtual int64 GetReceivedBytes() const OVERRIDE;
141   virtual base::Time GetStartTime() const OVERRIDE;
142   virtual base::Time GetEndTime() const OVERRIDE;
143   virtual bool CanShowInFolder() OVERRIDE;
144   virtual bool CanOpenDownload() OVERRIDE;
145   virtual bool ShouldOpenFileBasedOnExtension() OVERRIDE;
146   virtual bool GetOpenWhenComplete() const OVERRIDE;
147   virtual bool GetAutoOpened() OVERRIDE;
148   virtual bool GetOpened() const OVERRIDE;
149   virtual BrowserContext* GetBrowserContext() const OVERRIDE;
150   virtual WebContents* GetWebContents() const OVERRIDE;
151   virtual void OnContentCheckCompleted(DownloadDangerType danger_type) OVERRIDE;
152   virtual void SetOpenWhenComplete(bool open) OVERRIDE;
153   virtual void SetIsTemporary(bool temporary) OVERRIDE;
154   virtual void SetOpened(bool opened) OVERRIDE;
155   virtual void SetDisplayName(const base::FilePath& name) OVERRIDE;
156   virtual std::string DebugString(bool verbose) const OVERRIDE;
157 
158   // All remaining public interfaces virtual to allow for DownloadItemImpl
159   // mocks.
160 
161   // Determines the resume mode for an interrupted download. Requires
162   // last_reason_ to be set, but doesn't require the download to be in
163   // INTERRUPTED state.
164   virtual ResumeMode GetResumeMode() const;
165 
166   // Notify the download item that new origin information is available due to a
167   // resumption request receiving a response.
168   virtual void MergeOriginInfoOnResume(
169       const DownloadCreateInfo& new_create_info);
170 
171   // State transition operations on regular downloads --------------------------
172 
173   // Start the download.
174   // |download_file| is the associated file on the storage medium.
175   // |req_handle| is the new request handle associated with the download.
176   virtual void Start(scoped_ptr<DownloadFile> download_file,
177                      scoped_ptr<DownloadRequestHandleInterface> req_handle);
178 
179   // Needed because of intertwining with DownloadManagerImpl -------------------
180 
181   // TODO(rdsmith): Unwind DownloadManagerImpl and DownloadItemImpl,
182   // removing these from the public interface.
183 
184   // Notify observers that this item is being removed by the user.
185   virtual void NotifyRemoved();
186 
187   virtual void OnDownloadedFileRemoved();
188 
189   // Provide a weak pointer reference to a DownloadDestinationObserver
190   // for use by download destinations.
191   virtual base::WeakPtr<DownloadDestinationObserver>
192       DestinationObserverAsWeakPtr();
193 
194   // Get the download's BoundNetLog.
195   virtual const net::BoundNetLog& GetBoundNetLog() const;
196 
197   // DownloadItemImpl routines only needed by SavePackage ----------------------
198 
199   // Called by SavePackage to set the total number of bytes on the item.
200   virtual void SetTotalBytes(int64 total_bytes);
201 
202   virtual void OnAllDataSaved(const std::string& final_hash);
203 
204   // Called by SavePackage to display progress when the DownloadItem
205   // should be considered complete.
206   virtual void MarkAsComplete();
207 
208   // DownloadDestinationObserver
209   virtual void DestinationUpdate(int64 bytes_so_far,
210                                  int64 bytes_per_sec,
211                                  const std::string& hash_state) OVERRIDE;
212   virtual void DestinationError(DownloadInterruptReason reason) OVERRIDE;
213   virtual void DestinationCompleted(const std::string& final_hash) OVERRIDE;
214 
215  private:
216   // Fine grained states of a download. Note that active downloads are created
217   // in IN_PROGRESS_INTERNAL state. However, downloads creates via history can
218   // be created in COMPLETE_INTERNAL, CANCELLED_INTERNAL and
219   // INTERRUPTED_INTERNAL.
220 
221   enum DownloadInternalState {
222     // Includes both before and after file name determination, and paused
223     // downloads.
224     // TODO(rdsmith): Put in state variable for file name determination.
225     // Transitions from:
226     //   <Initial creation>    Active downloads are created in this state.
227     //   RESUMING_INTERNAL
228     // Transitions to:
229     //   COMPLETING_INTERNAL   On final rename completion.
230     //   CANCELLED_INTERNAL    On cancel.
231     //   INTERRUPTED_INTERNAL  On interrupt.
232     //   COMPLETE_INTERNAL     On SavePackage download completion.
233     IN_PROGRESS_INTERNAL,
234 
235     // Between commit point (dispatch of download file release) and completed.
236     // Embedder may be opening the file in this state.
237     // Transitions from:
238     //   IN_PROGRESS_INTERNAL
239     // Transitions to:
240     //   COMPLETE_INTERNAL     On successful completion.
241     COMPLETING_INTERNAL,
242 
243     // After embedder has had a chance to auto-open.  User may now open
244     // or auto-open based on extension.
245     // Transitions from:
246     //   COMPLETING_INTERNAL
247     //   IN_PROGRESS_INTERNAL  SavePackage only.
248     //   <Initial creation>    Completed persisted downloads.
249     // Transitions to:
250     //   <none>                Terminal state.
251     COMPLETE_INTERNAL,
252 
253     // User has cancelled the download.
254     // Transitions from:
255     //   IN_PROGRESS_INTERNAL
256     //   INTERRUPTED_INTERNAL
257     //   RESUMING_INTERNAL
258     //   <Initial creation>    Canceleld persisted downloads.
259     // Transitions to:
260     //   <none>                Terminal state.
261     CANCELLED_INTERNAL,
262 
263     // An error has interrupted the download.
264     // Transitions from:
265     //   IN_PROGRESS_INTERNAL
266     //   RESUMING_INTERNAL
267     //   <Initial creation>    Interrupted persisted downloads.
268     // Transitions to:
269     //   RESUMING_INTERNAL     On resumption.
270     INTERRUPTED_INTERNAL,
271 
272     // A request to resume this interrupted download is in progress.
273     // Transitions from:
274     //   INTERRUPTED_INTERNAL
275     // Transitions to:
276     //   IN_PROGRESS_INTERNAL  Once a server response is received from a
277     //                         resumption.
278     //   INTERRUPTED_INTERNAL  If the resumption request fails.
279     //   CANCELLED_INTERNAL    On cancel.
280     RESUMING_INTERNAL,
281 
282     MAX_DOWNLOAD_INTERNAL_STATE,
283   };
284 
285   // Used with TransitionTo() to indicate whether or not to call
286   // UpdateObservers() after the state transition.
287   enum ShouldUpdateObservers {
288     UPDATE_OBSERVERS,
289     DONT_UPDATE_OBSERVERS
290   };
291 
292   // Normal progression of a download ------------------------------------------
293 
294   // These are listed in approximately chronological order.  There are also
295   // public methods involved in normal download progression; see
296   // the implementation ordering in download_item_impl.cc.
297 
298   // Construction common to all constructors. |active| should be true for new
299   // downloads and false for downloads from the history.
300   // |download_type| indicates to the net log system what kind of download
301   // this is.
302   void Init(bool active, DownloadType download_type);
303 
304   // Called when the target path has been determined. |target_path| is the
305   // suggested target path. |disposition| indicates how the target path should
306   // be used (see TargetDisposition). |danger_type| is the danger level of
307   // |target_path| as determined by the caller. |intermediate_path| is the path
308   // to use to store the download until OnDownloadCompleting() is called.
309   virtual void OnDownloadTargetDetermined(
310       const base::FilePath& target_path,
311       TargetDisposition disposition,
312       DownloadDangerType danger_type,
313       const base::FilePath& intermediate_path);
314 
315   // Callback from file thread when we initialize the DownloadFile.
316   void OnDownloadFileInitialized(DownloadInterruptReason result);
317 
318   void OnDownloadRenamedToIntermediateName(
319       DownloadInterruptReason reason, const base::FilePath& full_path);
320 
321   // If all pre-requisites have been met, complete download processing, i.e. do
322   // internal cleanup, file rename, and potentially auto-open.  (Dangerous
323   // downloads still may block on user acceptance after this point.)
324   void MaybeCompleteDownload();
325 
326   // Called when the download is ready to complete.
327   // This may perform final rename if necessary and will eventually call
328   // DownloadItem::Completed().
329   void OnDownloadCompleting();
330 
331   void OnDownloadRenamedToFinalName(DownloadInterruptReason reason,
332                                     const base::FilePath& full_path);
333 
334   // Called if the embedder took over opening a download, to indicate that
335   // the download has been opened.
336   void DelayedDownloadOpened(bool auto_opened);
337 
338   // Called when the entire download operation (including renaming etc)
339   // is completed.
340   void Completed();
341 
342   // Callback invoked when the URLRequest for a download resumption has started.
343   void OnResumeRequestStarted(DownloadItem* item, net::Error error);
344 
345   // Helper routines -----------------------------------------------------------
346 
347   // Indicate that an error has occurred on the download.
348   void Interrupt(DownloadInterruptReason reason);
349 
350   // Destroy the DownloadFile object.  If |destroy_file| is true, the file is
351   // destroyed with it.  Otherwise, DownloadFile::Detach() is called before
352   // object destruction to prevent file destruction. Destroying the file also
353   // resets |current_path_|.
354   void ReleaseDownloadFile(bool destroy_file);
355 
356   // Check if a download is ready for completion.  The callback provided
357   // may be called at some point in the future if an external entity
358   // state has change s.t. this routine should be checked again.
359   bool IsDownloadReadyForCompletion(const base::Closure& state_change_notify);
360 
361   // Call to transition state; all state transitions should go through this.
362   // |notify_action| specifies whether or not to call UpdateObservers() after
363   // the state transition.
364   void TransitionTo(DownloadInternalState new_state,
365                     ShouldUpdateObservers notify_action);
366 
367   // Set the |danger_type_| and invoke obserers if necessary.
368   void SetDangerType(DownloadDangerType danger_type);
369 
370   void SetFullPath(const base::FilePath& new_path);
371 
372   void AutoResumeIfValid();
373 
374   void ResumeInterruptedDownload();
375 
376   static DownloadState InternalToExternalState(
377       DownloadInternalState internal_state);
378   static DownloadInternalState ExternalToInternalState(
379       DownloadState external_state);
380 
381   // Debugging routines --------------------------------------------------------
382   static const char* DebugDownloadStateString(DownloadInternalState state);
383   static const char* DebugResumeModeString(ResumeMode mode);
384 
385   // Will be false for save package downloads retrieved from the history.
386   // TODO(rdsmith): Replace with a generalized enum for "download source".
387   const bool is_save_package_download_;
388 
389   // The handle to the request information.  Used for operations outside the
390   // download system.
391   scoped_ptr<DownloadRequestHandleInterface> request_handle_;
392 
393   uint32 download_id_;
394 
395   // Display name for the download. If this is empty, then the display name is
396   // considered to be |target_path_.BaseName()|.
397   base::FilePath display_name_;
398 
399   // Full path to the downloaded or downloading file. This is the path to the
400   // physical file, if one exists. The final target path is specified by
401   // |target_path_|. |current_path_| can be empty if the in-progress path hasn't
402   // been determined.
403   base::FilePath current_path_;
404 
405   // Target path of an in-progress download. We may be downloading to a
406   // temporary or intermediate file (specified by |current_path_|.  Once the
407   // download completes, we will rename the file to |target_path_|.
408   base::FilePath target_path_;
409 
410   // Whether the target should be overwritten, uniquified or prompted for.
411   TargetDisposition target_disposition_;
412 
413   // The chain of redirects that leading up to and including the final URL.
414   std::vector<GURL> url_chain_;
415 
416   // The URL of the page that initiated the download.
417   GURL referrer_url_;
418 
419   // Filename suggestion from DownloadSaveInfo. It could, among others, be the
420   // suggested filename in 'download' attribute of an anchor. Details:
421   // http://www.whatwg.org/specs/web-apps/current-work/#downloading-hyperlinks
422   std::string suggested_filename_;
423 
424   // If non-empty, contains an externally supplied path that should be used as
425   // the target path.
426   base::FilePath forced_file_path_;
427 
428   // Page transition that triggerred the download.
429   PageTransition transition_type_;
430 
431   // Whether the download was triggered with a user gesture.
432   bool has_user_gesture_;
433 
434   // Information from the request.
435   // Content-disposition field from the header.
436   std::string content_disposition_;
437 
438   // Mime-type from the header.  Subject to change.
439   std::string mime_type_;
440 
441   // The value of the content type header sent with the downloaded item.  It
442   // may be different from |mime_type_|, which may be set based on heuristics
443   // which may look at the file extension and first few bytes of the file.
444   std::string original_mime_type_;
445 
446   // The remote IP address where the download was fetched from.  Copied from
447   // DownloadCreateInfo::remote_address.
448   std::string remote_address_;
449 
450   // Total bytes expected.
451   int64 total_bytes_;
452 
453   // Current received bytes.
454   int64 received_bytes_;
455 
456   // Current speed. Calculated by the DownloadFile.
457   int64 bytes_per_sec_;
458 
459   // Sha256 hash of the content.  This might be empty either because
460   // the download isn't done yet or because the hash isn't needed
461   // (ChromeDownloadManagerDelegate::GenerateFileHash() returned false).
462   std::string hash_;
463 
464   // A blob containing the state of the hash algorithm.  Only valid while the
465   // download is in progress.
466   std::string hash_state_;
467 
468   // Server's time stamp for the file.
469   std::string last_modified_time_;
470 
471   // Server's ETAG for the file.
472   std::string etag_;
473 
474   // Last reason.
475   DownloadInterruptReason last_reason_;
476 
477   // Start time for recording statistics.
478   base::TimeTicks start_tick_;
479 
480   // The current state of this download.
481   DownloadInternalState state_;
482 
483   // Current danger type for the download.
484   DownloadDangerType danger_type_;
485 
486   // The views of this item in the download shelf and download contents.
487   ObserverList<Observer> observers_;
488 
489   // Time the download was started.
490   base::Time start_time_;
491 
492   // Time the download completed.
493   base::Time end_time_;
494 
495   // Our delegate.
496   DownloadItemImplDelegate* delegate_;
497 
498   // In progress downloads may be paused by the user, we note it here.
499   bool is_paused_;
500 
501   // The number of times this download has been resumed automatically.
502   int auto_resume_count_;
503 
504   // A flag for indicating if the download should be opened at completion.
505   bool open_when_complete_;
506 
507   // A flag for indicating if the downloaded file is externally removed.
508   bool file_externally_removed_;
509 
510   // True if the download was auto-opened. We set this rather than using
511   // an observer as it's frequently possible for the download to be auto opened
512   // before the observer is added.
513   bool auto_opened_;
514 
515   // True if the item was downloaded temporarily.
516   bool is_temporary_;
517 
518   // True if we've saved all the data for the download.
519   bool all_data_saved_;
520 
521   // Error return from DestinationError.  Stored separately from
522   // last_reason_ so that we can avoid handling destination errors until
523   // after file name determination has occurred.
524   DownloadInterruptReason destination_error_;
525 
526   // Did the user open the item either directly or indirectly (such as by
527   // setting always open files of this type)? The shelf also sets this field
528   // when the user closes the shelf before the item has been opened but should
529   // be treated as though the user opened it.
530   bool opened_;
531 
532   // Did the delegate delay calling Complete on this download?
533   bool delegate_delayed_complete_;
534 
535   // DownloadFile associated with this download.  Note that this
536   // pointer may only be used or destroyed on the FILE thread.
537   // This pointer will be non-null only while the DownloadItem is in
538   // the IN_PROGRESS state.
539   scoped_ptr<DownloadFile> download_file_;
540 
541   // Net log to use for this download.
542   const net::BoundNetLog bound_net_log_;
543 
544   base::WeakPtrFactory<DownloadItemImpl> weak_ptr_factory_;
545 
546   DISALLOW_COPY_AND_ASSIGN(DownloadItemImpl);
547 };
548 
549 }  // namespace content
550 
551 #endif  // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_IMPL_H_
552