1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_item.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/basictypes.h"
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/file_util.h"
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/format_macros.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/metrics/histogram.h"
12201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/stringprintf.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/timer.h"
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/net_util.h"
1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/download/download_extensions.h"
174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/download/download_file_manager.h"
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/download/download_history.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_manager.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/download/download_prefs.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_util.h"
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/history/download_create_info.h"
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/platform_util.h"
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/extensions/extension.h"
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/pref_names.h"
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// A DownloadItem normally goes through the following states:
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//      * Created (when download starts)
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//      * Made visible to consumers (e.g. Javascript) after the
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//        destination file has been determined.
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//      * Entered into the history database.
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//      * Made visible in the download shelf.
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//      * All data is saved.  Note that the actual data download occurs
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//        in parallel with the above steps, but until those steps are
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//        complete, completion of the data download will be ignored.
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//      * Download file is renamed to its final name, and possibly
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//        auto-opened.
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// TODO(rdsmith): This progress should be reflected in
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// DownloadItem::DownloadState and a state transition table/state diagram.
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// TODO(rdsmith): This description should be updated to reflect the cancel
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// pathways.
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Update frequency (milliseconds).
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kUpdateTimeMs = 1000;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DeleteDownloadedFile(const FilePath& path) {
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Make sure we only delete files.
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!file_util::DirectoryExists(path))
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    file_util::Delete(path, false);
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
61201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char* DebugSafetyStateString(DownloadItem::SafetyState state) {
62201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  switch (state) {
63201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case DownloadItem::SAFE:
64201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "SAFE";
65201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case DownloadItem::DANGEROUS:
66201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "DANGEROUS";
67201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case DownloadItem::DANGEROUS_BUT_VALIDATED:
68201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "DANGEROUS_BUT_VALIDATED";
69201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    default:
70201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      NOTREACHED() << "Unknown safety state " << state;
71201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "unknown";
72201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  };
73201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
74201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
75201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char* DebugDownloadStateString(DownloadItem::DownloadState state) {
76201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  switch (state) {
77201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case DownloadItem::IN_PROGRESS:
78201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "IN_PROGRESS";
79201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case DownloadItem::COMPLETE:
80201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "COMPLETE";
81201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case DownloadItem::CANCELLED:
82201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "CANCELLED";
83201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case DownloadItem::REMOVING:
84201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "REMOVING";
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case DownloadItem::INTERRUPTED:
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return "INTERRUPTED";
87201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    default:
88201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      NOTREACHED() << "Unknown download state " << state;
89201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return "unknown";
90201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  };
91201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
92201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
93dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenDownloadItem::SafetyState GetSafetyState(bool dangerous_file,
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                         bool dangerous_url) {
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return (dangerous_url || dangerous_file) ?
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      DownloadItem::DANGEROUS : DownloadItem::SAFE;
97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Note: When a download has both |dangerous_file| and |dangerous_url| set,
100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// danger type is set to DANGEROUS_URL since the risk of dangerous URL
101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// overweights that of dangerous file type.
102dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenDownloadItem::DangerType GetDangerType(bool dangerous_file,
103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                       bool dangerous_url) {
104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (dangerous_url) {
105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // dangerous URL overweights dangerous file. We check dangerous URL first.
106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return DownloadItem::DANGEROUS_URL;
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else if (dangerous_file) {
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return DownloadItem::DANGEROUS_FILE;
109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return DownloadItem::NOT_DANGEROUS;
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Constructor for reading from the history service.
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDownloadItem::DownloadItem(DownloadManager* download_manager,
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           const DownloadCreateInfo& info)
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : id_(-1),
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      full_path_(info.path),
120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      path_uniquifier_(0),
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url_chain_(info.url_chain),
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      referrer_url_(info.referrer_url),
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      mime_type_(info.mime_type),
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      original_mime_type_(info.original_mime_type),
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      total_bytes_(info.total_bytes),
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      received_bytes_(info.received_bytes),
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      start_tick_(base::TimeTicks()),
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      state_(static_cast<DownloadState>(info.state)),
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      start_time_(info.start_time),
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      db_handle_(info.db_handle),
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      download_manager_(download_manager),
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_paused_(false),
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      open_when_complete_(false),
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      safety_state_(SAFE),
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      danger_type_(NOT_DANGEROUS),
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      auto_opened_(false),
137513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      target_name_(info.original_name),
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      render_process_id_(-1),
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_id_(-1),
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      save_as_(false),
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_otr_(false),
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_extension_install_(info.is_extension_install),
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      name_finalized_(false),
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_temporary_(false),
14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      all_data_saved_(false),
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      opened_(false) {
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (IsInProgress())
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    state_ = CANCELLED;
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (IsComplete())
15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    all_data_saved_ = true;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Init(false /* don't start progress timer */);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Constructing for a regular download:
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDownloadItem::DownloadItem(DownloadManager* download_manager,
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           const DownloadCreateInfo& info,
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           bool is_otr)
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : id_(info.download_id),
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      full_path_(info.path),
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      path_uniquifier_(info.path_uniquifier),
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url_chain_(info.url_chain),
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      referrer_url_(info.referrer_url),
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      mime_type_(info.mime_type),
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      original_mime_type_(info.original_mime_type),
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      total_bytes_(info.total_bytes),
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      received_bytes_(0),
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      last_os_error_(0),
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      start_tick_(base::TimeTicks::Now()),
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      state_(IN_PROGRESS),
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      start_time_(info.start_time),
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      db_handle_(DownloadHistory::kUninitializedHandle),
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      download_manager_(download_manager),
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      is_paused_(false),
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      open_when_complete_(false),
175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      safety_state_(GetSafetyState(info.is_dangerous_file,
176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                   info.is_dangerous_url)),
177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      danger_type_(GetDangerType(info.is_dangerous_file,
178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                 info.is_dangerous_url)),
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      auto_opened_(false),
180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      target_name_(info.original_name),
1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      render_process_id_(info.child_id),
1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      request_id_(info.request_id),
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      save_as_(info.prompt_user_for_save_location),
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      is_otr_(is_otr),
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      is_extension_install_(info.is_extension_install),
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      name_finalized_(false),
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      is_temporary_(!info.save_info.file_path.empty()),
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      all_data_saved_(false),
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      opened_(false) {
1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Init(true /* start progress timer */);
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Constructing for the "Save Page As..." feature:
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDownloadItem::DownloadItem(DownloadManager* download_manager,
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           const FilePath& path,
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           const GURL& url,
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           bool is_otr)
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : id_(1),
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      full_path_(path),
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      path_uniquifier_(0),
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url_chain_(1, url),
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      referrer_url_(GURL()),
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      mime_type_(std::string()),
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      original_mime_type_(std::string()),
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      total_bytes_(0),
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      received_bytes_(0),
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      last_os_error_(0),
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      start_tick_(base::TimeTicks::Now()),
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      state_(IN_PROGRESS),
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      start_time_(base::Time::Now()),
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      db_handle_(DownloadHistory::kUninitializedHandle),
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      download_manager_(download_manager),
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_paused_(false),
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      open_when_complete_(false),
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      safety_state_(SAFE),
216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      danger_type_(NOT_DANGEROUS),
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      auto_opened_(false),
2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      render_process_id_(-1),
2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      request_id_(-1),
2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      save_as_(false),
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_otr_(is_otr),
2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      is_extension_install_(false),
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      name_finalized_(false),
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      is_temporary_(false),
22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      all_data_saved_(false),
2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      opened_(false) {
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Init(true /* start progress timer */);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDownloadItem::~DownloadItem() {
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  state_ = REMOVING;
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateObservers();
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItem::AddObserver(Observer* observer) {
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observers_.AddObserver(observer);
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItem::RemoveObserver(Observer* observer) {
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observers_.RemoveObserver(observer);
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItem::UpdateObservers() {
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this));
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DownloadItem::CanOpenDownload() {
2483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return !Extension::IsExtension(target_name_);
2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DownloadItem::ShouldOpenFileBasedOnExtension() {
252513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return download_manager_->ShouldOpenFileBasedOnExtension(
253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      GetUserVerifiedFilePath());
2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DownloadItem::OpenFilesBasedOnExtension(bool open) {
2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DownloadPrefs* prefs = download_manager_->download_prefs();
2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (open)
259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    prefs->EnableAutoOpenBasedOnExtension(GetUserVerifiedFilePath());
2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
261201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    prefs->DisableAutoOpenBasedOnExtension(GetUserVerifiedFilePath());
2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DownloadItem::OpenDownload() {
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (IsPartialDownload()) {
2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    open_when_complete_ = !open_when_complete_;
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (IsComplete()) {
2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    opened_ = true;
2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FOR_EACH_OBSERVER(Observer, observers_, OnDownloadOpened(this));
2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (is_extension_install()) {
2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      download_util::OpenChromeExtension(download_manager_->profile(),
2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         download_manager_,
2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         *this);
2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return;
2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_MACOSX)
2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Mac OS X requires opening downloads on the UI thread.
2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    platform_util::OpenItem(full_path());
2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#else
280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::FILE, FROM_HERE,
2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        NewRunnableFunction(&platform_util::OpenItem, full_path()));
2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DownloadItem::ShowDownloadInShell() {
2883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_MACOSX)
2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Mac needs to run this operation on the UI thread.
2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  platform_util::ShowItemInFolder(full_path());
2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#else
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::FILE, FROM_HERE,
2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NewRunnableFunction(&platform_util::ShowItemInFolder,
2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                          full_path()));
2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DownloadItem::DangerousDownloadValidated() {
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UMA_HISTOGRAM_ENUMERATION("Download.DangerousDownloadValidated",
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            danger_type_,
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            DANGEROUS_TYPE_MAX);
3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  download_manager_->DangerousDownloadValidated(this);
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItem::UpdateSize(int64 bytes_so_far) {
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  received_bytes_ = bytes_so_far;
3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If we've received more data than we were expecting (bad server info?),
3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // revert to 'unknown size mode'.
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (received_bytes_ > total_bytes_)
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    total_bytes_ = 0;
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DownloadItem::StartProgressTimer() {
3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdateTimeMs), this,
3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                      &DownloadItem::UpdateObservers);
3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DownloadItem::StopProgressTimer() {
3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  update_timer_.Stop();
3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Updates from the download thread may have been posted while this download
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// was being cancelled in the UI thread, so we'll accept them unless we're
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// complete.
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItem::Update(int64 bytes_so_far) {
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!IsInProgress()) {
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateSize(bytes_so_far);
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateObservers();
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Triggered by a user action.
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItem::Cancel(bool update_history) {
338201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  VLOG(20) << __FUNCTION__ << "()" << " download = " << DebugString(true);
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!IsPartialDownload()) {
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Small downloads might be complete before this method has
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // a chance to run.
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_util::RecordDownloadCount(download_util::CANCELLED_COUNT);
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  state_ = CANCELLED;
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateObservers();
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopProgressTimer();
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (update_history)
3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    download_manager_->DownloadCancelled(id_);
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid DownloadItem::MarkAsComplete() {
35572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(all_data_saved_);
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  state_ = COMPLETE;
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateObservers();
35872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
35972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
36072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid DownloadItem::OnAllDataSaved(int64 size) {
36172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(!all_data_saved_);
36272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  all_data_saved_ = true;
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateSize(size);
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopProgressTimer();
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DownloadItem::Completed() {
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VLOG(20) << " " << __FUNCTION__ << "() "
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           << DebugString(false);
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_util::RecordDownloadCount(download_util::COMPLETED_COUNT);
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Handle chrome extensions explicitly and skip the shell execute.
3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (is_extension_install()) {
3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    download_util::OpenChromeExtension(download_manager_->profile(),
3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                       download_manager_,
3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                       *this);
3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    auto_opened_ = true;
3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else if (open_when_complete() ||
380513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch             download_manager_->ShouldOpenFileBasedOnExtension(
381201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                 GetUserVerifiedFilePath()) ||
3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick             is_temporary()) {
3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // If the download is temporary, like in drag-and-drop, do not open it but
3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // we still need to set it auto-opened so that it can be removed from the
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // download shelf.
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!is_temporary())
3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      OpenDownload();
3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    auto_opened_ = true;
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(all_data_saved_);
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state_ = COMPLETE;
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateObservers();
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_manager_->DownloadCompleted(id());
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DownloadItem::Interrupted(int64 size, int os_error) {
398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!IsInProgress())
399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state_ = INTERRUPTED;
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  last_os_error_ = os_error;
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateSize(size);
403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  StopProgressTimer();
4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateObservers();
405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
4063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DownloadItem::Delete(DeleteReason reason) {
408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  switch (reason) {
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case DELETE_DUE_TO_USER_DISCARD:
410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      UMA_HISTOGRAM_ENUMERATION("Download.UserDiscard",
411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                danger_type_,
412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                DANGEROUS_TYPE_MAX);
413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case DELETE_DUE_TO_BROWSER_SHUTDOWN:
415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      UMA_HISTOGRAM_ENUMERATION("Download.Discard",
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                danger_type_,
417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                DANGEROUS_TYPE_MAX);
418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    default:
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NOTREACHED();
42172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::FILE, FROM_HERE,
425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableFunction(&DeleteDownloadedFile, full_path_));
426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Remove();
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We have now been deleted.
4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DownloadItem::Remove() {
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Cancel(true);
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  state_ = REMOVING;
4333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  download_manager_->RemoveDownload(db_handle_);
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We have now been deleted.
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DownloadItem::TimeRemaining(base::TimeDelta* remaining) const {
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (total_bytes_ <= 0)
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;  // We never received the content_length for this download.
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 speed = CurrentSpeed();
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (speed == 0)
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *remaining =
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base::TimeDelta::FromSeconds((total_bytes_ - received_bytes_) / speed);
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint64 DownloadItem::CurrentSpeed() const {
4514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (is_paused_)
4524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return 0;
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeDelta diff = base::TimeTicks::Now() - start_tick_;
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 diff_ms = diff.InMilliseconds();
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return diff_ms == 0 ? 0 : received_bytes_ * 1000 / diff_ms;
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint DownloadItem::PercentComplete() const {
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int percent = -1;
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (total_bytes_ > 0)
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    percent = static_cast<int>(received_bytes_ * 100.0 / total_bytes_);
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return percent;
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItem::Rename(const FilePath& full_path) {
46621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VLOG(20) << " " << __FUNCTION__ << "()"
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           << " full_path = \"" << full_path.value() << "\""
46821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           << DebugString(true);
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!full_path.empty());
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  full_path_ = full_path;
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItem::TogglePause() {
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(IsInProgress());
4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  download_manager_->PauseDownload(id_, !is_paused_);
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_paused_ = !is_paused_;
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateObservers();
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DownloadItem::OnNameFinalized() {
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VLOG(20) << " " << __FUNCTION__ << "() "
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           << DebugString(true);
4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  name_finalized_ = true;
4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We can't reach this point in the code without having received all the
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // data, so it's safe to move to the COMPLETE state.
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(all_data_saved_);
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state_ = COMPLETE;
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateObservers();
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_manager_->DownloadCompleted(id());
4913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DownloadItem::OnDownloadCompleting(DownloadFileManager* file_manager) {
494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VLOG(20) << " " << __FUNCTION__ << "() "
495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           << " needs rename = " << NeedsRename()
496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           << " " << DebugString(true);
497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK_NE(DANGEROUS, safety_state());
4984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK(file_manager);
499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (NeedsRename()) {
5014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    BrowserThread::PostTask(
5024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        BrowserThread::FILE, FROM_HERE,
5034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        NewRunnableMethod(
504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            file_manager, &DownloadFileManager::RenameCompletingDownloadFile,
505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            id(), GetTargetFilePath(), safety_state() == SAFE));
5064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return;
507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    name_finalized_ = true;
5094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
5104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Completed();
512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::FILE, FROM_HERE,
515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableMethod(
516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          file_manager, &DownloadFileManager::CompleteDownload, id()));
5174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
5184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
5194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid DownloadItem::OnDownloadRenamedToFinalName(const FilePath& full_path) {
52021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VLOG(20) << " " << __FUNCTION__ << "()"
521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           << " full_path = " << full_path.value()
522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           << " needed rename = " << NeedsRename()
523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           << " " << DebugString(false);
524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(NeedsRename());
5254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
5264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  Rename(full_path);
5274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  OnNameFinalized();
5284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Completed();
5304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
5314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool DownloadItem::MatchesQuery(const string16& query) const {
5333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (query.empty())
5343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return true;
5353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK_EQ(query, l10n_util::ToLower(query));
5373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  string16 url_raw(l10n_util::ToLower(UTF8ToUTF16(url().spec())));
5393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (url_raw.find(query) != string16::npos)
5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return true;
5413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(phajdan.jr): write a test case for the following code.
5433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // A good test case would be:
5443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   "/\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xbd\xa0\xe5\xa5\xbd",
5453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   L"/\x4f60\x597d\x4f60\x597d",
5463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   "/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD"
5473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  PrefService* prefs = download_manager_->profile()->GetPrefs();
5483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string languages(prefs->GetString(prefs::kAcceptLanguages));
549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  string16 url_formatted(l10n_util::ToLower(net::FormatUrl(url(), languages)));
5503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (url_formatted.find(query) != string16::npos)
5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return true;
5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
55372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  string16 path(l10n_util::ToLower(full_path().LossyDisplayName()));
55472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // This shouldn't just do a substring match; it is wrong for Unicode
55572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // due to normalization and we have a fancier search-query system
55672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // used elsewhere.
55772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // http://code.google.com/p/chromium/issues/detail?id=71982
55872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (path.find(query) != string16::npos)
5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return true;
5603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return false;
5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
56421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid DownloadItem::SetFileCheckResults(const FilePath& path,
565dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                       bool is_dangerous_file,
566dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                       bool is_dangerous_url,
56721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       int path_uniquifier,
56821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       bool prompt,
56921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       bool is_extension_install,
57021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       const FilePath& original_name) {
57121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VLOG(20) << " " << __FUNCTION__ << "()"
57221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           << " path = \"" << path.value() << "\""
573dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen           << " is_dangerous_file = " << is_dangerous_file
574dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen           << " is_dangerous_url = " << is_dangerous_url
57521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           << " path_uniquifier = " << path_uniquifier
57621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           << " prompt = " << prompt
57721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           << " is_extension_install = " << is_extension_install
57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           << " path = \"" << path.value() << "\""
57921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           << " original_name = \"" << original_name.value() << "\""
58021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           << " " << DebugString(true);
58121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Make sure the initial file name is set only once.
58221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(full_path_.empty());
58321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(!path.empty());
58421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
58521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  full_path_ = path;
586dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  safety_state_ = GetSafetyState(is_dangerous_file, is_dangerous_url);
587dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  danger_type_ = GetDangerType(is_dangerous_file, is_dangerous_url);
58821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  path_uniquifier_ = path_uniquifier;
58921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  save_as_ = prompt;
59021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  is_extension_install_ = is_extension_install;
59121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  target_name_ = original_name;
59221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
59321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (target_name_.value().empty())
59421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    target_name_ = full_path_.BaseName();
59521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
59621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
597513209b27ff55e2841eac0e4120199c23acce758Ben MurdochFilePath DownloadItem::GetTargetFilePath() const {
598513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return full_path_.DirName().Append(target_name_);
599513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
600513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
601513209b27ff55e2841eac0e4120199c23acce758Ben MurdochFilePath DownloadItem::GetFileNameToReportUser() const {
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (path_uniquifier_ > 0) {
603513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    FilePath name(target_name_);
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    download_util::AppendNumberToPath(&name, path_uniquifier_);
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return name;
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
607513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return target_name_;
608513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
609513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
610201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochFilePath DownloadItem::GetUserVerifiedFilePath() const {
611513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (safety_state_ == DownloadItem::SAFE)
612201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return GetTargetFilePath();
613201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return full_path_;
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
6153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid DownloadItem::Init(bool start_timer) {
617513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (target_name_.value().empty())
618513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    target_name_ = full_path_.BaseName();
6193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (start_timer)
6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    StartProgressTimer();
62121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VLOG(20) << " " << __FUNCTION__ << "() " << DebugString(true);
6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
623201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(ahendrickson) -- Move |INTERRUPTED| from |IsCancelled()| to
625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// |IsPartialDownload()|, when resuming interrupted downloads is implemented.
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool DownloadItem::IsPartialDownload() const {
627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return (state_ == IN_PROGRESS);
628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool DownloadItem::IsInProgress() const {
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return (state_ == IN_PROGRESS);
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool DownloadItem::IsCancelled() const {
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return (state_ == CANCELLED) || (state_ == INTERRUPTED);
636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool DownloadItem::IsInterrupted() const {
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return (state_ == INTERRUPTED);
640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool DownloadItem::IsComplete() const {
643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return state() == COMPLETE;
644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
646201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstd::string DownloadItem::DebugString(bool verbose) const {
647201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::string description =
64821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      base::StringPrintf("{ id_ = %d"
64921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                         " state = %s",
65021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                         id_,
65121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                         DebugDownloadStateString(state()));
652201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
653201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (verbose) {
654201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    description += base::StringPrintf(
65521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " db_handle = %" PRId64
65621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " total_bytes = %" PRId64
65721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " is_paused = " "%c"
65821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " is_extension_install = " "%c"
65921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " is_otr = " "%c"
66021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " safety_state = " "%s"
66121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " url = " "\"%s\""
66221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " target_name_ = \"%" PRFilePath "\""
66321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        " full_path = \"%" PRFilePath "\"",
66421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        db_handle(),
66521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        total_bytes(),
66621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        is_paused() ? 'T' : 'F',
66721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        is_extension_install() ? 'T' : 'F',
66821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        is_otr() ? 'T' : 'F',
66921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        DebugSafetyStateString(safety_state()),
67021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        url().spec().c_str(),
671201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        target_name_.value().c_str(),
67221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        full_path().value().c_str());
67321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
67421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    description += base::StringPrintf(" url = \"%s\"", url().spec().c_str());
675201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
676201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
67721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  description += " }";
678201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
679201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return description;
680201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
681