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
27namespace content {
28class DownloadFile;
29class DownloadItemImplDelegate;
30
31// See download_item.h for usage.
32class 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