1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // Each download is represented by a DownloadItem, and all DownloadItems 6 // are owned by the DownloadManager which maintains a global list of all 7 // downloads. DownloadItems are created when a user initiates a download, 8 // and exist for the duration of the browser life time. 9 // 10 // Download observers: 11 // DownloadItem::Observer: 12 // - allows observers to receive notifications about one download from start 13 // to completion 14 // Use AddObserver() / RemoveObserver() on the appropriate download object to 15 // receive state updates. 16 17 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_H_ 18 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_H_ 19 #pragma once 20 21 #include <string> 22 23 #include "base/basictypes.h" 24 #include "base/file_path.h" 25 #include "base/observer_list.h" 26 #include "base/time.h" 27 #include "base/timer.h" 28 #include "googleurl/src/gurl.h" 29 30 class DownloadFileManager; 31 class DownloadManager; 32 struct DownloadCreateInfo; 33 34 // One DownloadItem per download. This is the model class that stores all the 35 // state for a download. Multiple views, such as a tab's download shelf and the 36 // Destination tab's download view, may refer to a given DownloadItem. 37 // 38 // This is intended to be used only on the UI thread. 39 class DownloadItem { 40 public: 41 enum DownloadState { 42 // Download is actively progressing. 43 IN_PROGRESS, 44 45 // Download is completely finished. 46 COMPLETE, 47 48 // Download has been cancelled. 49 CANCELLED, 50 51 // This state indicates that the download item is about to be destroyed, 52 // and observers seeing this state should release all references. 53 REMOVING, 54 55 // This state indicates that the download has been interrupted. 56 INTERRUPTED 57 }; 58 59 enum SafetyState { 60 SAFE = 0, 61 DANGEROUS, 62 DANGEROUS_BUT_VALIDATED // Dangerous but the user confirmed the download. 63 }; 64 65 // This enum is used by histograms. Do not change the ordering or remove 66 // items. 67 enum DangerType { 68 NOT_DANGEROUS = 0, 69 70 // A dangerous file to the system (e.g.: an executable or extension from 71 // places other than gallery). 72 DANGEROUS_FILE, 73 74 // Safebrowsing service shows this URL leads to malicious file download. 75 DANGEROUS_URL, 76 77 // Memory space for histograms is determined by the max. 78 // ALWAYS ADD NEW VALUES BEFORE THIS ONE. 79 DANGEROUS_TYPE_MAX 80 }; 81 82 // Reason for deleting the download. Passed to Delete(). 83 enum DeleteReason { 84 DELETE_DUE_TO_BROWSER_SHUTDOWN = 0, 85 DELETE_DUE_TO_USER_DISCARD 86 }; 87 88 // Interface that observers of a particular download must implement in order 89 // to receive updates to the download's status. 90 class Observer { 91 public: 92 virtual void OnDownloadUpdated(DownloadItem* download) = 0; 93 94 // Called when a downloaded file has been opened. 95 virtual void OnDownloadOpened(DownloadItem* download) = 0; 96 97 protected: 98 virtual ~Observer() {} 99 }; 100 101 // Constructing from persistent store: 102 DownloadItem(DownloadManager* download_manager, 103 const DownloadCreateInfo& info); 104 105 // Constructing for a regular download: 106 DownloadItem(DownloadManager* download_manager, 107 const DownloadCreateInfo& info, 108 bool is_otr); 109 110 // Constructing for the "Save Page As..." feature: 111 DownloadItem(DownloadManager* download_manager, 112 const FilePath& path, 113 const GURL& url, 114 bool is_otr); 115 116 ~DownloadItem(); 117 118 void AddObserver(Observer* observer); 119 void RemoveObserver(Observer* observer); 120 121 // Notifies our observers periodically. 122 void UpdateObservers(); 123 124 // Whether it is OK to open this download. 125 bool CanOpenDownload(); 126 127 // Tests if a file type should be opened automatically. 128 bool ShouldOpenFileBasedOnExtension(); 129 130 // Registers this file extension for automatic opening upon download 131 // completion if 'open' is true, or prevents the extension from automatic 132 // opening if 'open' is false. 133 void OpenFilesBasedOnExtension(bool open); 134 135 // Open the file associated with this download (wait for the download to 136 // complete if it is in progress). 137 void OpenDownload(); 138 139 // Show the download via the OS shell. 140 void ShowDownloadInShell(); 141 142 // Called when the user has validated the download of a dangerous file. 143 void DangerousDownloadValidated(); 144 145 // Received a new chunk of data 146 void Update(int64 bytes_so_far); 147 148 // Cancel the download operation. We need to distinguish between cancels at 149 // exit (DownloadManager destructor) from user interface initiated cancels 150 // because at exit, the history system may not exist, and any updates to it 151 // require AddRef'ing the DownloadManager in the destructor which results in 152 // a DCHECK failure. Set 'update_history' to false when canceling from at 153 // exit to prevent this crash. This may result in a difference between the 154 // downloaded file's size on disk, and what the history system's last record 155 // of it is. At worst, we'll end up re-downloading a small portion of the file 156 // when resuming a download (assuming the server supports byte ranges). 157 void Cancel(bool update_history); 158 159 // Called when all data has been saved. Only has display effects. 160 void OnAllDataSaved(int64 size); 161 162 // Called by external code (SavePackage) using the DownloadItem interface 163 // to display progress when the DownloadItem should be considered complete. 164 void MarkAsComplete(); 165 166 // Download operation had an error. 167 // |size| is the amount of data received so far, and |os_error| is the error 168 // code that the operation received. 169 void Interrupted(int64 size, int os_error); 170 171 // Deletes the file from disk and removes the download from the views and 172 // history. |user| should be true if this is the result of the user clicking 173 // the discard button, and false if it is being deleted for other reasons like 174 // browser shutdown. 175 void Delete(DeleteReason reason); 176 177 // Removes the download from the views and history. 178 void Remove(); 179 180 // Simple calculation of the amount of time remaining to completion. Fills 181 // |*remaining| with the amount of time remaining if successful. Fails and 182 // returns false if we do not have the number of bytes or the speed so can 183 // not estimate. 184 bool TimeRemaining(base::TimeDelta* remaining) const; 185 186 // Simple speed estimate in bytes/s 187 int64 CurrentSpeed() const; 188 189 // Rough percent complete, -1 means we don't know (since we didn't receive a 190 // total size). 191 int PercentComplete() const; 192 193 // Whether or not this download has saved all of its data. 194 bool all_data_saved() const { return all_data_saved_; } 195 196 // Update the fields that may have changed in DownloadCreateInfo as a 197 // result of analyzing the file and figuring out its type, location, etc. 198 // May only be called once. 199 void SetFileCheckResults(const FilePath& path, 200 bool is_dangerous_file, 201 bool is_dangerous_url, 202 int path_uniquifier, 203 bool prompt, 204 bool is_extension_install, 205 const FilePath& original_name); 206 207 // Update the download's path, the actual file is renamed on the download 208 // thread. 209 void Rename(const FilePath& full_path); 210 211 // Allow the user to temporarily pause a download or resume a paused download. 212 void TogglePause(); 213 214 // Called when the name of the download is finalized. 215 void OnNameFinalized(); 216 217 // Called when the download is ready to complete. 218 // This may perform final rename if necessary and will eventually call 219 // DownloadItem::Completed(). 220 void OnDownloadCompleting(DownloadFileManager* file_manager); 221 222 // Called when the file name for the download is renamed to its final name. 223 void OnDownloadRenamedToFinalName(const FilePath& full_path); 224 225 // Returns true if this item matches |query|. |query| must be lower-cased. 226 bool MatchesQuery(const string16& query) const; 227 228 // Returns true if the download needs more data. 229 bool IsPartialDownload() const; 230 231 // Returns true if the download is still receiving data. 232 bool IsInProgress() const; 233 234 // Returns true if the download has been cancelled or was interrupted. 235 bool IsCancelled() const; 236 237 // Returns true if the download was interrupted. 238 bool IsInterrupted() const; 239 240 // Returns true if we have all the data and know the final file name. 241 bool IsComplete() const; 242 243 // Accessors 244 DownloadState state() const { return state_; } 245 FilePath full_path() const { return full_path_; } 246 void set_path_uniquifier(int uniquifier) { path_uniquifier_ = uniquifier; } 247 const GURL& url() const { return url_chain_.back(); } 248 const std::vector<GURL>& url_chain() const { return url_chain_; } 249 const GURL& original_url() const { return url_chain_.front(); } 250 const GURL& referrer_url() const { return referrer_url_; } 251 std::string mime_type() const { return mime_type_; } 252 std::string original_mime_type() const { return original_mime_type_; } 253 int64 total_bytes() const { return total_bytes_; } 254 void set_total_bytes(int64 total_bytes) { total_bytes_ = total_bytes; } 255 int64 received_bytes() const { return received_bytes_; } 256 int32 id() const { return id_; } 257 base::Time start_time() const { return start_time_; } 258 void set_db_handle(int64 handle) { db_handle_ = handle; } 259 int64 db_handle() const { return db_handle_; } 260 bool is_paused() const { return is_paused_; } 261 bool open_when_complete() const { return open_when_complete_; } 262 void set_open_when_complete(bool open) { open_when_complete_ = open; } 263 int render_process_id() const { return render_process_id_; } 264 int request_id() const { return request_id_; } 265 SafetyState safety_state() const { return safety_state_; } 266 void set_safety_state(SafetyState safety_state) { 267 safety_state_ = safety_state; 268 } 269 DangerType danger_type() { return danger_type_;} 270 bool auto_opened() { return auto_opened_; } 271 FilePath target_name() const { return target_name_; } 272 bool save_as() const { return save_as_; } 273 bool is_otr() const { return is_otr_; } 274 bool is_extension_install() const { return is_extension_install_; } 275 bool name_finalized() const { return name_finalized_; } 276 bool is_temporary() const { return is_temporary_; } 277 void set_opened(bool opened) { opened_ = opened; } 278 bool opened() const { return opened_; } 279 280 // Returns the final target file path for the download. 281 FilePath GetTargetFilePath() const; 282 283 // Returns the file-name that should be reported to the user, which is 284 // target_name_ possibly with the uniquifier number. 285 FilePath GetFileNameToReportUser() const; 286 287 // Returns the user-verified target file path for the download. 288 // This returns the same path as GetTargetFilePath() for safe downloads 289 // but does not for dangerous downloads until the name is verified. 290 FilePath GetUserVerifiedFilePath() const; 291 292 // Returns true if the current file name is not the final target name yet. 293 bool NeedsRename() const { 294 return target_name_ != full_path_.BaseName(); 295 } 296 297 std::string DebugString(bool verbose) const; 298 299 private: 300 void Init(bool start_timer); 301 302 // Internal helper for maintaining consistent received and total sizes. 303 void UpdateSize(int64 size); 304 305 // Called when the entire download operation (including renaming etc) 306 // is completed. 307 void Completed(); 308 309 // Start/stop sending periodic updates to our observers 310 void StartProgressTimer(); 311 void StopProgressTimer(); 312 313 // Request ID assigned by the ResourceDispatcherHost. 314 int32 id_; 315 316 // Full path to the downloaded or downloading file. 317 FilePath full_path_; 318 319 // A number that should be appended to the path to make it unique, or 0 if the 320 // path should be used as is. 321 int path_uniquifier_; 322 323 // The chain of redirects that leading up to and including the final URL. 324 std::vector<GURL> url_chain_; 325 326 // The URL of the page that initiated the download. 327 GURL referrer_url_; 328 329 // The mimetype of the download 330 std::string mime_type_; 331 332 // The value of the content type header received when downloading 333 // this item. |mime_type_| may be different because of type sniffing. 334 std::string original_mime_type_; 335 336 // Total bytes expected 337 int64 total_bytes_; 338 339 // Current received bytes 340 int64 received_bytes_; 341 342 // Last error. 343 int last_os_error_; 344 345 // Start time for calculating remaining time 346 base::TimeTicks start_tick_; 347 348 // The current state of this download 349 DownloadState state_; 350 351 // The views of this item in the download shelf and download tab 352 ObserverList<Observer> observers_; 353 354 // Time the download was started 355 base::Time start_time_; 356 357 // Our persistent store handle 358 int64 db_handle_; 359 360 // Timer for regularly updating our observers 361 base::RepeatingTimer<DownloadItem> update_timer_; 362 363 // Our owning object 364 DownloadManager* download_manager_; 365 366 // In progress downloads may be paused by the user, we note it here 367 bool is_paused_; 368 369 // A flag for indicating if the download should be opened at completion. 370 bool open_when_complete_; 371 372 // Whether the download is considered potentially safe or dangerous 373 // (executable files are typically considered dangerous). 374 SafetyState safety_state_; 375 376 // Why |safety_state_| is not SAFE. 377 DangerType danger_type_; 378 379 // Whether the download was auto-opened. We set this rather than using 380 // an observer as it's frequently possible for the download to be auto opened 381 // before the observer is added. 382 bool auto_opened_; 383 384 // Dangerous downloads or ongoing downloads are given temporary names until 385 // the user approves them or the downloads finish. 386 // This stores their final target name. 387 FilePath target_name_; 388 389 // For canceling or pausing requests. 390 int render_process_id_; 391 int request_id_; 392 393 // True if the item was downloaded as a result of 'save as...' 394 bool save_as_; 395 396 // True if the download was initiated in an incognito window. 397 bool is_otr_; 398 399 // True if the item was downloaded for an extension installation. 400 bool is_extension_install_; 401 402 // True if the filename is finalized. 403 bool name_finalized_; 404 405 // True if the item was downloaded temporarily. 406 bool is_temporary_; 407 408 // True if we've saved all the data for the download. 409 bool all_data_saved_; 410 411 // Did the user open the item either directly or indirectly (such as by 412 // setting always open files of this type)? The shelf also sets this field 413 // when the user closes the shelf before the item has been opened but should 414 // be treated as though the user opened it. 415 bool opened_; 416 417 DISALLOW_COPY_AND_ASSIGN(DownloadItem); 418 }; 419 420 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_H_ 421