license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 1 | // Copyright (c) 2006-2008 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. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | // |
| 5 | // The DownloadManager object manages the process of downloading, including |
| 6 | // updates to the history system and providing the information for displaying |
| 7 | // the downloads view in the Destinations tab. There is one DownloadManager per |
| 8 | // active profile in Chrome. |
| 9 | // |
| 10 | // Each download is represented by a DownloadItem, and all DownloadItems |
| 11 | // are owned by the DownloadManager which maintains a global list of all |
| 12 | // downloads. DownloadItems are created when a user initiates a download, |
| 13 | // and exist for the duration of the browser life time. |
| 14 | // |
| 15 | // Download observers: |
| 16 | // Objects that are interested in notifications about new downloads, or progress |
| 17 | // updates for a given download must implement one of the download observer |
| 18 | // interfaces: |
| 19 | // DownloadItem::Observer: |
| 20 | // - allows observers to receive notifications about one download from start |
| 21 | // to completion |
| 22 | // DownloadManager::Observer: |
| 23 | // - allows observers, primarily views, to be notified when changes to the |
| 24 | // set of all downloads (such as new downloads, or deletes) occur |
| 25 | // Use AddObserver() / RemoveObserver() on the appropriate download object to |
| 26 | // receive state updates. |
| 27 | // |
| 28 | // Download state persistence: |
| 29 | // The DownloadManager uses the history service for storing persistent |
| 30 | // information about the state of all downloads. The history system maintains a |
| 31 | // separate table for this called 'downloads'. At the point that the |
| 32 | // DownloadManager is constructed, we query the history service for the state of |
| 33 | // all persisted downloads. |
| 34 | |
[email protected] | e93d2823 | 2009-01-30 05:59:59 | [diff] [blame] | 35 | #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ |
| 36 | #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 37 | |
[email protected] | 42eb6b0 | 2008-11-25 23:14:46 | [diff] [blame] | 38 | #include "build/build_config.h" |
| 39 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 40 | #include <string> |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 41 | #include <map> |
| 42 | #include <set> |
| 43 | #include <vector> |
| 44 | |
| 45 | #include "base/basictypes.h" |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 46 | #include "base/file_path.h" |
[email protected] | 2314403 | 2008-09-08 20:51:30 | [diff] [blame] | 47 | #include "base/hash_tables.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 48 | #include "base/observer_list.h" |
| 49 | #include "base/ref_counted.h" |
[email protected] | e93d2823 | 2009-01-30 05:59:59 | [diff] [blame] | 50 | #include "base/time.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 51 | #include "chrome/browser/cancelable_request.h" |
| 52 | #include "chrome/browser/history/download_types.h" |
| 53 | #include "chrome/browser/history/history.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 54 | #include "chrome/browser/shell_dialogs.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 55 | #include "chrome/common/pref_member.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 56 | |
| 57 | class DownloadFileManager; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 58 | class DownloadItemView; |
| 59 | class DownloadManager; |
[email protected] | 46072d4 | 2008-07-28 14:49:35 | [diff] [blame] | 60 | class GURL; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 61 | class MessageLoop; |
| 62 | class PrefService; |
| 63 | class Profile; |
| 64 | class ResourceDispatcherHost; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 65 | class URLRequestContext; |
| 66 | class WebContents; |
| 67 | |
[email protected] | ab820df | 2008-08-26 05:55:10 | [diff] [blame] | 68 | namespace base { |
| 69 | class Thread; |
| 70 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 71 | |
| 72 | // DownloadItem ---------------------------------------------------------------- |
| 73 | |
| 74 | // One DownloadItem per download. This is the model class that stores all the |
| 75 | // state for a download. Multiple views, such as a tab's download shelf and the |
| 76 | // Destination tab's download view, may refer to a given DownloadItem. |
| 77 | class DownloadItem { |
| 78 | public: |
| 79 | enum DownloadState { |
| 80 | IN_PROGRESS, |
| 81 | COMPLETE, |
| 82 | CANCELLED, |
| 83 | REMOVING |
| 84 | }; |
| 85 | |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 86 | enum SafetyState { |
| 87 | SAFE = 0, |
| 88 | DANGEROUS, |
| 89 | DANGEROUS_BUT_VALIDATED // Dangerous but the user confirmed the download. |
| 90 | }; |
| 91 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 92 | // Interface that observers of a particular download must implement in order |
| 93 | // to receive updates to the download's status. |
| 94 | class Observer { |
| 95 | public: |
| 96 | virtual void OnDownloadUpdated(DownloadItem* download) = 0; |
| 97 | }; |
| 98 | |
| 99 | // Constructing from persistent store: |
| 100 | DownloadItem(const DownloadCreateInfo& info); |
| 101 | |
| 102 | // Constructing from user action: |
| 103 | DownloadItem(int32 download_id, |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 104 | const FilePath& path, |
[email protected] | 7a256ea | 2008-10-17 17:34:16 | [diff] [blame] | 105 | int path_uniquifier, |
[email protected] | f6b4853 | 2009-02-12 01:56:32 | [diff] [blame] | 106 | const GURL& url, |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 107 | const FilePath& original_name, |
[email protected] | e1acf6f | 2008-10-27 20:43:33 | [diff] [blame] | 108 | const base::Time start_time, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 109 | int64 download_size, |
| 110 | int render_process_id, |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 111 | int request_id, |
| 112 | bool is_dangerous); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 113 | |
| 114 | ~DownloadItem(); |
| 115 | |
| 116 | void Init(bool start_timer); |
| 117 | |
| 118 | // Public API |
| 119 | |
| 120 | void AddObserver(Observer* observer); |
| 121 | void RemoveObserver(Observer* observer); |
| 122 | |
| 123 | // Notify our observers periodically |
| 124 | void UpdateObservers(); |
| 125 | |
| 126 | // Received a new chunk of data |
| 127 | void Update(int64 bytes_so_far); |
| 128 | |
| 129 | // Cancel the download operation. We need to distinguish between cancels at |
| 130 | // exit (DownloadManager destructor) from user interface initiated cancels |
| 131 | // because at exit, the history system may not exist, and any updates to it |
| 132 | // require AddRef'ing the DownloadManager in the destructor which results in |
| 133 | // a DCHECK failure. Set 'update_history' to false when canceling from at |
| 134 | // exit to prevent this crash. This may result in a difference between the |
| 135 | // downloaded file's size on disk, and what the history system's last record |
| 136 | // of it is. At worst, we'll end up re-downloading a small portion of the file |
| 137 | // when resuming a download (assuming the server supports byte ranges). |
| 138 | void Cancel(bool update_history); |
| 139 | |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 140 | // Download operation completed. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 141 | void Finished(int64 size); |
| 142 | |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 143 | // The user wants to remove the download from the views and history. If |
| 144 | // |delete_file| is true, the file is deleted on the disk. |
| 145 | void Remove(bool delete_file); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 146 | |
| 147 | // Start/stop sending periodic updates to our observers |
| 148 | void StartProgressTimer(); |
| 149 | void StopProgressTimer(); |
| 150 | |
| 151 | // Simple calculation of the amount of time remaining to completion. Fills |
| 152 | // |*remaining| with the amount of time remaining if successful. Fails and |
| 153 | // returns false if we do not have the number of bytes or the speed so can |
| 154 | // not estimate. |
[email protected] | e1acf6f | 2008-10-27 20:43:33 | [diff] [blame] | 155 | bool TimeRemaining(base::TimeDelta* remaining) const; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 156 | |
| 157 | // Simple speed estimate in bytes/s |
| 158 | int64 CurrentSpeed() const; |
| 159 | |
| 160 | // Rough percent complete, -1 means we don't know (since we didn't receive a |
| 161 | // total size). |
| 162 | int PercentComplete() const; |
| 163 | |
| 164 | // Update the download's path, the actual file is renamed on the download |
| 165 | // thread. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 166 | void Rename(const FilePath& full_path); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 167 | |
| 168 | // Allow the user to temporarily pause a download or resume a paused download. |
| 169 | void TogglePause(); |
| 170 | |
| 171 | // Accessors |
| 172 | DownloadState state() const { return state_; } |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 173 | FilePath file_name() const { return file_name_; } |
| 174 | void set_file_name(const FilePath& name) { file_name_ = name; } |
| 175 | FilePath full_path() const { return full_path_; } |
| 176 | void set_full_path(const FilePath& path) { full_path_ = path; } |
[email protected] | 7a256ea | 2008-10-17 17:34:16 | [diff] [blame] | 177 | int path_uniquifier() const { return path_uniquifier_; } |
| 178 | void set_path_uniquifier(int uniquifier) { path_uniquifier_ = uniquifier; } |
[email protected] | f6b4853 | 2009-02-12 01:56:32 | [diff] [blame] | 179 | GURL url() const { return url_; } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 180 | int64 total_bytes() const { return total_bytes_; } |
| 181 | void set_total_bytes(int64 total_bytes) { total_bytes_ = total_bytes; } |
| 182 | int64 received_bytes() const { return received_bytes_; } |
| 183 | int32 id() const { return id_; } |
[email protected] | e1acf6f | 2008-10-27 20:43:33 | [diff] [blame] | 184 | base::Time start_time() const { return start_time_; } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 185 | void set_db_handle(int64 handle) { db_handle_ = handle; } |
| 186 | int64 db_handle() const { return db_handle_; } |
| 187 | DownloadManager* manager() const { return manager_; } |
| 188 | void set_manager(DownloadManager* manager) { manager_ = manager; } |
| 189 | bool is_paused() const { return is_paused_; } |
| 190 | void set_is_paused(bool pause) { is_paused_ = pause; } |
| 191 | bool open_when_complete() const { return open_when_complete_; } |
| 192 | void set_open_when_complete(bool open) { open_when_complete_ = open; } |
| 193 | int render_process_id() const { return render_process_id_; } |
| 194 | int request_id() const { return request_id_; } |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 195 | SafetyState safety_state() const { return safety_state_; } |
| 196 | void set_safety_state(SafetyState safety_state) { |
| 197 | safety_state_ = safety_state; |
| 198 | } |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 199 | FilePath original_name() const { return original_name_; } |
| 200 | void set_original_name(const FilePath& name) { original_name_ = name; } |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 201 | |
| 202 | // Returns the file-name that should be reported to the user, which is |
[email protected] | 7a256ea | 2008-10-17 17:34:16 | [diff] [blame] | 203 | // file_name_ for safe downloads and original_name_ for dangerous ones with |
| 204 | // the uniquifier number. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 205 | FilePath GetFileName() const; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 206 | |
| 207 | private: |
| 208 | // Internal helper for maintaining consistent received and total sizes. |
| 209 | void UpdateSize(int64 size); |
| 210 | |
| 211 | // Request ID assigned by the ResourceDispatcherHost. |
| 212 | int32 id_; |
| 213 | |
| 214 | // Full path to the downloaded file |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 215 | FilePath full_path_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 216 | |
[email protected] | 7a256ea | 2008-10-17 17:34:16 | [diff] [blame] | 217 | // A number that should be appended to the path to make it unique, or 0 if the |
| 218 | // path should be used as is. |
| 219 | int path_uniquifier_; |
| 220 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 221 | // Short display version of the file |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 222 | FilePath file_name_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 223 | |
[email protected] | f6b4853 | 2009-02-12 01:56:32 | [diff] [blame] | 224 | // The URL from whence we came. |
| 225 | GURL url_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 226 | |
| 227 | // Total bytes expected |
| 228 | int64 total_bytes_; |
| 229 | |
| 230 | // Current received bytes |
| 231 | int64 received_bytes_; |
| 232 | |
| 233 | // Start time for calculating remaining time |
| 234 | uintptr_t start_tick_; |
| 235 | |
| 236 | // The current state of this download |
| 237 | DownloadState state_; |
| 238 | |
| 239 | // The views of this item in the download shelf and download tab |
| 240 | ObserverList<Observer> observers_; |
| 241 | |
| 242 | // Time the download was started |
[email protected] | e1acf6f | 2008-10-27 20:43:33 | [diff] [blame] | 243 | base::Time start_time_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 244 | |
| 245 | // Our persistent store handle |
| 246 | int64 db_handle_; |
| 247 | |
[email protected] | 2d31666 | 2008-09-03 18:18:14 | [diff] [blame] | 248 | // Timer for regularly updating our observers |
| 249 | base::RepeatingTimer<DownloadItem> update_timer_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 250 | |
| 251 | // Our owning object |
| 252 | DownloadManager* manager_; |
| 253 | |
| 254 | // In progress downloads may be paused by the user, we note it here |
| 255 | bool is_paused_; |
| 256 | |
| 257 | // A flag for indicating if the download should be opened at completion. |
| 258 | bool open_when_complete_; |
| 259 | |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 260 | // Whether the download is considered potentially safe or dangerous |
| 261 | // (executable files are typically considered dangerous). |
| 262 | SafetyState safety_state_; |
| 263 | |
| 264 | // Dangerous download are given temporary names until the user approves them. |
| 265 | // This stores their original name. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 266 | FilePath original_name_; |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 267 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 268 | // For canceling or pausing requests. |
| 269 | int render_process_id_; |
| 270 | int request_id_; |
| 271 | |
| 272 | DISALLOW_EVIL_CONSTRUCTORS(DownloadItem); |
| 273 | }; |
| 274 | |
| 275 | |
| 276 | // DownloadManager ------------------------------------------------------------- |
| 277 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 278 | // Browser's download manager: manages all downloads and destination view. |
| 279 | class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, |
| 280 | public SelectFileDialog::Listener { |
| 281 | // For testing. |
| 282 | friend class DownloadManagerTest; |
| 283 | |
| 284 | public: |
| 285 | DownloadManager(); |
| 286 | ~DownloadManager(); |
| 287 | |
| 288 | static void RegisterUserPrefs(PrefService* prefs); |
| 289 | |
| 290 | // Interface to implement for observers that wish to be informed of changes |
| 291 | // to the DownloadManager's collection of downloads. |
| 292 | class Observer { |
| 293 | public: |
| 294 | // New or deleted download, observers should query us for the current set |
| 295 | // of downloads. |
| 296 | virtual void ModelChanged() = 0; |
| 297 | |
| 298 | // A callback once the DownloadManager has retrieved the requested set of |
| 299 | // downloads. The DownloadManagerObserver must copy the vector, but does not |
| 300 | // own the individual DownloadItems, when this call is made. |
| 301 | virtual void SetDownloads(std::vector<DownloadItem*>& downloads) = 0; |
| 302 | }; |
| 303 | |
| 304 | // Public API |
| 305 | |
| 306 | // Begin a search for all downloads matching 'search_text'. If 'search_text' |
| 307 | // is empty, return all known downloads. The results are returned in the |
| 308 | // 'SetDownloads' observer callback. |
| 309 | void GetDownloads(Observer* observer, |
| 310 | const std::wstring& search_text); |
| 311 | |
| 312 | // Returns true if initialized properly. |
| 313 | bool Init(Profile* profile); |
| 314 | |
| 315 | // Schedule a query of the history service to retrieve all downloads. |
| 316 | void QueryHistoryForDownloads(); |
| 317 | |
| 318 | // Notifications sent from the download thread to the UI thread |
| 319 | void StartDownload(DownloadCreateInfo* info); |
| 320 | void UpdateDownload(int32 download_id, int64 size); |
| 321 | void DownloadFinished(int32 download_id, int64 size); |
| 322 | |
| 323 | // Helper method for cancelling the network request associated with a |
| 324 | // download. |
| 325 | static void CancelDownloadRequest(int render_process_id, int request_id); |
| 326 | |
| 327 | // Called from a view when a user clicks a UI button or link. |
| 328 | void DownloadCancelled(int32 download_id); |
| 329 | void PauseDownload(int32 download_id, bool pause); |
| 330 | void RemoveDownload(int64 download_handle); |
| 331 | |
| 332 | // Remove downloads after remove_begin (inclusive) and before remove_end |
| 333 | // (exclusive). You may pass in null Time values to do an unbounded delete |
| 334 | // in either direction. |
[email protected] | e1acf6f | 2008-10-27 20:43:33 | [diff] [blame] | 335 | int RemoveDownloadsBetween(const base::Time remove_begin, |
| 336 | const base::Time remove_end); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 337 | |
| 338 | // Remove downloads will delete all downloads that have a timestamp that is |
| 339 | // the same or more recent than |remove_begin|. The number of downloads |
| 340 | // deleted is returned back to the caller. |
[email protected] | e1acf6f | 2008-10-27 20:43:33 | [diff] [blame] | 341 | int RemoveDownloads(const base::Time remove_begin); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 342 | |
| 343 | // Download the object at the URL. Used in cases such as "Save Link As..." |
| 344 | void DownloadUrl(const GURL& url, |
| 345 | const GURL& referrer, |
| 346 | WebContents* web_contents); |
| 347 | |
| 348 | // Allow objects to observe the download creation process. |
| 349 | void AddObserver(Observer* observer); |
| 350 | |
| 351 | // Remove a download observer from ourself. |
| 352 | void RemoveObserver(Observer* observer); |
| 353 | |
| 354 | // Methods called on completion of a query sent to the history system. |
| 355 | void OnQueryDownloadEntriesComplete( |
| 356 | std::vector<DownloadCreateInfo>* entries); |
| 357 | void OnCreateDownloadEntryComplete(DownloadCreateInfo info, int64 db_handle); |
| 358 | void OnSearchComplete(HistoryService::Handle handle, |
| 359 | std::vector<int64>* results); |
| 360 | |
| 361 | // Show or Open a download via the Windows shell. |
| 362 | void ShowDownloadInShell(const DownloadItem* download); |
[email protected] | e93d2823 | 2009-01-30 05:59:59 | [diff] [blame] | 363 | void OpenDownloadInShell(const DownloadItem* download, |
| 364 | gfx::NativeView parent_window); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 365 | |
| 366 | // The number of in progress (including paused) downloads. |
| 367 | int in_progress_count() const { |
| 368 | return static_cast<int>(in_progress_.size()); |
| 369 | } |
| 370 | |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 371 | FilePath download_path() { |
| 372 | return FilePath::FromWStringHack(*download_path_); |
| 373 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 374 | |
[email protected] | 905a08d | 2008-11-19 07:24:12 | [diff] [blame] | 375 | // Clears the last download path, used to initialize "save as" dialogs. |
| 376 | void ClearLastDownloadPath(); |
| 377 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 378 | // Registers this file extension for automatic opening upon download |
| 379 | // completion if 'open' is true, or prevents the extension from automatic |
| 380 | // opening if 'open' is false. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 381 | void OpenFilesOfExtension(const FilePath::StringType& extension, bool open); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 382 | |
| 383 | // Tests if a file type should be opened automatically. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 384 | bool ShouldOpenFileExtension(const FilePath::StringType& extension); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 385 | |
| 386 | // Tests if we think the server means for this mime_type to be executable. |
| 387 | static bool IsExecutableMimeType(const std::string& mime_type); |
| 388 | |
| 389 | // Tests if a file type is considered executable. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 390 | bool IsExecutable(const FilePath::StringType& extension); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 391 | |
| 392 | // Resets the automatic open preference. |
| 393 | void ResetAutoOpenFiles(); |
| 394 | |
| 395 | // Returns true if there are automatic handlers registered for any file |
| 396 | // types. |
| 397 | bool HasAutoOpenFileTypesRegistered() const; |
| 398 | |
| 399 | // Overridden from SelectFileDialog::Listener: |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 400 | // TODO(port): convert this to FilePath when SelectFileDialog gets converted. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 401 | virtual void FileSelected(const std::wstring& path, void* params); |
| 402 | virtual void FileSelectionCanceled(void* params); |
| 403 | |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 404 | // Deletes the specified path on the file thread. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 405 | void DeleteDownload(const FilePath& path); |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 406 | |
| 407 | // Called when the user has validated the donwload of a dangerous file. |
| 408 | void DangerousDownloadValidated(DownloadItem* download); |
| 409 | |
[email protected] | 763f946a | 2009-01-06 19:04:39 | [diff] [blame] | 410 | // Used to make sure we have a safe file extension and filename for a |
| 411 | // download. |file_name| can either be just the file name or it can be a |
| 412 | // full path to a file. |
| 413 | void GenerateSafeFilename(const std::string& mime_type, |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 414 | FilePath* file_name); |
[email protected] | 763f946a | 2009-01-06 19:04:39 | [diff] [blame] | 415 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 416 | private: |
| 417 | // Shutdown the download manager. This call is needed only after Init. |
| 418 | void Shutdown(); |
| 419 | |
| 420 | // Called on the download thread to check whether the suggested file path |
| 421 | // exists. We don't check if the file exists on the UI thread to avoid UI |
| 422 | // stalls from interacting with the file system. |
| 423 | void CheckIfSuggestedPathExists(DownloadCreateInfo* info); |
| 424 | |
| 425 | // Called on the UI thread once the DownloadManager has determined whether the |
| 426 | // suggested file path exists. |
| 427 | void OnPathExistenceAvailable(DownloadCreateInfo* info); |
| 428 | |
| 429 | // Called back after a target path for the file to be downloaded to has been |
| 430 | // determined, either automatically based on the suggested file name, or by |
| 431 | // the user in a Save As dialog box. |
| 432 | void ContinueStartDownload(DownloadCreateInfo* info, |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 433 | const FilePath& target_path); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 434 | |
| 435 | // Update the history service for a particular download. |
| 436 | void UpdateHistoryForDownload(DownloadItem* download); |
| 437 | void RemoveDownloadFromHistory(DownloadItem* download); |
[email protected] | e1acf6f | 2008-10-27 20:43:33 | [diff] [blame] | 438 | void RemoveDownloadsFromHistoryBetween(const base::Time remove_begin, |
| 439 | const base::Time remove_before); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 440 | |
| 441 | // Inform the notification service of download starts and stops. |
| 442 | void NotifyAboutDownloadStart(); |
| 443 | void NotifyAboutDownloadStop(); |
| 444 | |
| 445 | // Create an extension based on the file name and mime type. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 446 | void GenerateExtension(const FilePath& file_name, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 447 | const std::string& mime_type, |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 448 | FilePath::StringType* generated_extension); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 449 | |
| 450 | // Create a file name based on the response from the server. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 451 | void GenerateFilename(DownloadCreateInfo* info, FilePath* generated_name); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 452 | |
| 453 | // Persist the automatic opening preference. |
| 454 | void SaveAutoOpens(); |
| 455 | |
| 456 | // Runs the network cancel on the IO thread. |
| 457 | static void OnCancelDownloadRequest(ResourceDispatcherHost* rdh, |
| 458 | int render_process_id, |
| 459 | int request_id); |
| 460 | |
| 461 | // Runs the pause on the IO thread. |
| 462 | static void OnPauseDownloadRequest(ResourceDispatcherHost* rdh, |
| 463 | int render_process_id, |
| 464 | int request_id, |
| 465 | bool pause); |
| 466 | |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 467 | // Performs the last steps required when a download has been completed. |
| 468 | // It is necessary to break down the flow when a download is finished as |
| 469 | // dangerous downloads are downloaded to temporary files that need to be |
| 470 | // renamed on the file thread first. |
| 471 | // Invoked on the UI thread. |
| 472 | void ContinueDownloadFinished(DownloadItem* download); |
| 473 | |
| 474 | // Renames a finished dangerous download from its temporary file name to its |
| 475 | // real file name. |
| 476 | // Invoked on the file thread. |
| 477 | void ProceedWithFinishedDangerousDownload(int64 download_handle, |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 478 | const FilePath& path, |
| 479 | const FilePath& original_name); |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 480 | |
| 481 | // Invoked on the UI thread when a dangerous downloaded file has been renamed. |
| 482 | void DangerousDownloadRenamed(int64 download_handle, |
| 483 | bool success, |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 484 | const FilePath& new_path, |
[email protected] | 7a256ea | 2008-10-17 17:34:16 | [diff] [blame] | 485 | int new_path_uniquifier); |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 486 | |
| 487 | // Checks whether a file represents a risk if downloaded. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 488 | bool IsDangerous(const FilePath& file_name); |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 489 | |
| 490 | // Changes the paths and file name of the specified |download|, propagating |
| 491 | // the change to the history system. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 492 | void RenameDownload(DownloadItem* download, const FilePath& new_path); |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 493 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 494 | // 'downloads_' is map of all downloads in this profile. The key is the handle |
| 495 | // returned by the history system, which is unique across sessions. This map |
| 496 | // owns all the DownloadItems once they have been created in the history |
| 497 | // system. |
| 498 | // |
| 499 | // 'in_progress_' is a map of all downloads that are in progress and that have |
| 500 | // not yet received a valid history handle. The key is the ID assigned by the |
| 501 | // ResourceDispatcherHost, which is unique for the current session. This map |
| 502 | // does not own the DownloadItems. |
| 503 | // |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 504 | // 'dangerous_finished_' is a map of dangerous download that have finished |
| 505 | // but were not yet approved by the user. Similarly to in_progress_, the key |
| 506 | // is the ID assigned by the ResourceDispatcherHost and the map does not own |
| 507 | // the DownloadItems. It is used on shutdown to delete completed downloads |
| 508 | // that have not been approved. |
| 509 | // |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 510 | // When a download is created through a user action, the corresponding |
| 511 | // DownloadItem* is placed in 'in_progress_' and remains there until it has |
| 512 | // received a valid handle from the history system. Once it has a valid |
| 513 | // handle, the DownloadItem* is placed in the 'downloads_' map. When the |
| 514 | // download is complete, it is removed from 'in_progress_'. Downloads from |
| 515 | // past sessions read from a persisted state from the history system are |
| 516 | // placed directly into 'downloads_' since they have valid handles in the |
| 517 | // history system. |
[email protected] | 2314403 | 2008-09-08 20:51:30 | [diff] [blame] | 518 | typedef base::hash_map<int64, DownloadItem*> DownloadMap; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 519 | DownloadMap downloads_; |
| 520 | DownloadMap in_progress_; |
[email protected] | 9ccbb37 | 2008-10-10 18:50:32 | [diff] [blame] | 521 | DownloadMap dangerous_finished_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 522 | |
| 523 | // True if the download manager has been initialized and requires a shutdown. |
| 524 | bool shutdown_needed_; |
| 525 | |
| 526 | // Observers that want to be notified of changes to the set of downloads. |
| 527 | ObserverList<Observer> observers_; |
| 528 | |
| 529 | // The current active profile. |
| 530 | Profile* profile_; |
| 531 | scoped_refptr<URLRequestContext> request_context_; |
| 532 | |
| 533 | // Used for history service request management. |
[email protected] | c5a46eeb | 2009-01-30 18:46:24 | [diff] [blame] | 534 | CancelableRequestConsumerTSimple<Observer*> cancelable_consumer_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 535 | |
| 536 | // Non-owning pointer for handling file writing on the download_thread_. |
| 537 | DownloadFileManager* file_manager_; |
| 538 | |
| 539 | // A pointer to the main UI loop. |
| 540 | MessageLoop* ui_loop_; |
| 541 | |
| 542 | // A pointer to the file thread's loop. The file thread lives longer than |
| 543 | // the DownloadManager, so this is safe to cache. |
| 544 | MessageLoop* file_loop_; |
| 545 | |
| 546 | // User preferences |
| 547 | BooleanPrefMember prompt_for_download_; |
| 548 | StringPrefMember download_path_; |
| 549 | |
| 550 | // The user's last choice for download directory. This is only used when the |
| 551 | // user wants us to prompt for a save location for each download. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 552 | FilePath last_download_path_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 553 | |
| 554 | // Set of file extensions to open at download completion. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 555 | std::set<FilePath::StringType> auto_open_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 556 | |
| 557 | // Set of file extensions that are executables and shouldn't be auto opened. |
[email protected] | 7ae7c2cb | 2009-01-06 23:31:41 | [diff] [blame] | 558 | std::set<FilePath::StringType> exe_types_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 559 | |
| 560 | // Keep track of downloads that are completed before the user selects the |
| 561 | // destination, so that observers are appropriately notified of completion |
| 562 | // after this determination is made. |
| 563 | // The map is of download_id->remaining size (bytes), both of which are |
| 564 | // required when calling DownloadFinished. |
| 565 | typedef std::map<int32, int64> PendingFinishedMap; |
| 566 | PendingFinishedMap pending_finished_downloads_; |
| 567 | |
| 568 | // The "Save As" dialog box used to ask the user where a file should be |
| 569 | // saved. |
| 570 | scoped_refptr<SelectFileDialog> select_file_dialog_; |
| 571 | |
[email protected] | e93d2823 | 2009-01-30 05:59:59 | [diff] [blame] | 572 | DISALLOW_COPY_AND_ASSIGN(DownloadManager); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 573 | }; |
| 574 | |
[email protected] | e93d2823 | 2009-01-30 05:59:59 | [diff] [blame] | 575 | #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ |