Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: chrome/browser/download_manager.h

Issue 2826: Move the download code to new directories: (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/download_item_model.cc ('k') | chrome/browser/download_manager.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
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
35 #ifndef CHROME_BROWSER_DOWNLOAD_MANAGER_H__
36 #define CHROME_BROWSER_DOWNLOAD_MANAGER_H__
37
38 #include <string>
39 #include <map>
40 #include <set>
41 #include <vector>
42
43 #include "base/basictypes.h"
44 #include "base/hash_tables.h"
45 #include "base/observer_list.h"
46 #include "base/ref_counted.h"
47 #include "chrome/browser/cancelable_request.h"
48 #include "chrome/browser/history/download_types.h"
49 #include "chrome/browser/history/history.h"
50 #include "chrome/browser/shell_dialogs.h"
51 #include "chrome/common/pref_member.h"
52
53 class DownloadFileManager;
54 class DownloadItem;
55 class DownloadItemView;
56 class DownloadManager;
57 class GURL;
58 class MessageLoop;
59 class PrefService;
60 class Profile;
61 class ResourceDispatcherHost;
62 class URLRequestContext;
63 class WebContents;
64
65 namespace base {
66 class Thread;
67 }
68
69 // DownloadItem ----------------------------------------------------------------
70
71 // One DownloadItem per download. This is the model class that stores all the
72 // state for a download. Multiple views, such as a tab's download shelf and the
73 // Destination tab's download view, may refer to a given DownloadItem.
74 class DownloadItem {
75 public:
76 enum DownloadState {
77 IN_PROGRESS,
78 COMPLETE,
79 CANCELLED,
80 REMOVING
81 };
82
83 // Interface that observers of a particular download must implement in order
84 // to receive updates to the download's status.
85 class Observer {
86 public:
87 virtual void OnDownloadUpdated(DownloadItem* download) = 0;
88 };
89
90 // Constructing from persistent store:
91 DownloadItem(const DownloadCreateInfo& info);
92
93 // Constructing from user action:
94 DownloadItem(int32 download_id,
95 const std::wstring& path,
96 const std::wstring& url,
97 const Time start_time,
98 int64 download_size,
99 int render_process_id,
100 int request_id);
101
102 ~DownloadItem();
103
104 void Init(bool start_timer);
105
106 // Public API
107
108 void AddObserver(Observer* observer);
109 void RemoveObserver(Observer* observer);
110
111 // Notify our observers periodically
112 void UpdateObservers();
113
114 // Received a new chunk of data
115 void Update(int64 bytes_so_far);
116
117 // Cancel the download operation. We need to distinguish between cancels at
118 // exit (DownloadManager destructor) from user interface initiated cancels
119 // because at exit, the history system may not exist, and any updates to it
120 // require AddRef'ing the DownloadManager in the destructor which results in
121 // a DCHECK failure. Set 'update_history' to false when canceling from at
122 // exit to prevent this crash. This may result in a difference between the
123 // downloaded file's size on disk, and what the history system's last record
124 // of it is. At worst, we'll end up re-downloading a small portion of the file
125 // when resuming a download (assuming the server supports byte ranges).
126 void Cancel(bool update_history);
127
128 // Download operation completed
129 void Finished(int64 size);
130
131 // The user wants to remove the download from the views and history. This
132 // operation does not delete the file on the disk.
133 void Remove();
134
135 // Start/stop sending periodic updates to our observers
136 void StartProgressTimer();
137 void StopProgressTimer();
138
139 // Simple calculation of the amount of time remaining to completion. Fills
140 // |*remaining| with the amount of time remaining if successful. Fails and
141 // returns false if we do not have the number of bytes or the speed so can
142 // not estimate.
143 bool TimeRemaining(TimeDelta* remaining) const;
144
145 // Simple speed estimate in bytes/s
146 int64 CurrentSpeed() const;
147
148 // Rough percent complete, -1 means we don't know (since we didn't receive a
149 // total size).
150 int PercentComplete() const;
151
152 // Update the download's path, the actual file is renamed on the download
153 // thread.
154 void Rename(const std::wstring& full_path);
155
156 // Allow the user to temporarily pause a download or resume a paused download.
157 void TogglePause();
158
159 // Accessors
160 DownloadState state() const { return state_; }
161 std::wstring full_path() const { return full_path_; }
162 std::wstring file_name() const { return file_name_; }
163 std::wstring url() const { return url_; }
164 int64 total_bytes() const { return total_bytes_; }
165 void set_total_bytes(int64 total_bytes) { total_bytes_ = total_bytes; }
166 int64 received_bytes() const { return received_bytes_; }
167 int32 id() const { return id_; }
168 Time start_time() const { return start_time_; }
169 void set_db_handle(int64 handle) { db_handle_ = handle; }
170 int64 db_handle() const { return db_handle_; }
171 DownloadManager* manager() const { return manager_; }
172 void set_manager(DownloadManager* manager) { manager_ = manager; }
173 bool is_paused() const { return is_paused_; }
174 void set_is_paused(bool pause) { is_paused_ = pause; }
175 bool open_when_complete() const { return open_when_complete_; }
176 void set_open_when_complete(bool open) { open_when_complete_ = open; }
177 int render_process_id() const { return render_process_id_; }
178 int request_id() const { return request_id_; }
179
180 private:
181 // Internal helper for maintaining consistent received and total sizes.
182 void UpdateSize(int64 size);
183
184 // Request ID assigned by the ResourceDispatcherHost.
185 int32 id_;
186
187 // Full path to the downloaded file
188 std::wstring full_path_;
189
190 // Short display version of the file
191 std::wstring file_name_;
192
193 // The URL from whence we came, for display
194 std::wstring url_;
195
196 // Total bytes expected
197 int64 total_bytes_;
198
199 // Current received bytes
200 int64 received_bytes_;
201
202 // Start time for calculating remaining time
203 uintptr_t start_tick_;
204
205 // The current state of this download
206 DownloadState state_;
207
208 // The views of this item in the download shelf and download tab
209 ObserverList<Observer> observers_;
210
211 // Time the download was started
212 Time start_time_;
213
214 // Our persistent store handle
215 int64 db_handle_;
216
217 // Timer for regularly updating our observers
218 base::RepeatingTimer<DownloadItem> update_timer_;
219
220 // Our owning object
221 DownloadManager* manager_;
222
223 // In progress downloads may be paused by the user, we note it here
224 bool is_paused_;
225
226 // A flag for indicating if the download should be opened at completion.
227 bool open_when_complete_;
228
229 // For canceling or pausing requests.
230 int render_process_id_;
231 int request_id_;
232
233 DISALLOW_EVIL_CONSTRUCTORS(DownloadItem);
234 };
235
236
237 // DownloadManager -------------------------------------------------------------
238
239 // Browser's download manager: manages all downloads and destination view.
240 class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>,
241 public SelectFileDialog::Listener {
242 // For testing.
243 friend class DownloadManagerTest;
244
245 public:
246 DownloadManager();
247 ~DownloadManager();
248
249 static void RegisterUserPrefs(PrefService* prefs);
250
251 // Interface to implement for observers that wish to be informed of changes
252 // to the DownloadManager's collection of downloads.
253 class Observer {
254 public:
255 // New or deleted download, observers should query us for the current set
256 // of downloads.
257 virtual void ModelChanged() = 0;
258
259 // A callback once the DownloadManager has retrieved the requested set of
260 // downloads. The DownloadManagerObserver must copy the vector, but does not
261 // own the individual DownloadItems, when this call is made.
262 virtual void SetDownloads(std::vector<DownloadItem*>& downloads) = 0;
263 };
264
265 // Public API
266
267 // Begin a search for all downloads matching 'search_text'. If 'search_text'
268 // is empty, return all known downloads. The results are returned in the
269 // 'SetDownloads' observer callback.
270 void GetDownloads(Observer* observer,
271 const std::wstring& search_text);
272
273 // Returns true if initialized properly.
274 bool Init(Profile* profile);
275
276 // Schedule a query of the history service to retrieve all downloads.
277 void QueryHistoryForDownloads();
278
279 // Notifications sent from the download thread to the UI thread
280 void StartDownload(DownloadCreateInfo* info);
281 void UpdateDownload(int32 download_id, int64 size);
282 void DownloadFinished(int32 download_id, int64 size);
283
284 // Helper method for cancelling the network request associated with a
285 // download.
286 static void CancelDownloadRequest(int render_process_id, int request_id);
287
288 // Called from a view when a user clicks a UI button or link.
289 void DownloadCancelled(int32 download_id);
290 void PauseDownload(int32 download_id, bool pause);
291 void RemoveDownload(int64 download_handle);
292
293 // Remove downloads after remove_begin (inclusive) and before remove_end
294 // (exclusive). You may pass in null Time values to do an unbounded delete
295 // in either direction.
296 int RemoveDownloadsBetween(const Time remove_begin, const Time remove_end);
297
298 // Remove downloads will delete all downloads that have a timestamp that is
299 // the same or more recent than |remove_begin|. The number of downloads
300 // deleted is returned back to the caller.
301 int RemoveDownloads(const Time remove_begin);
302
303 // Download the object at the URL. Used in cases such as "Save Link As..."
304 void DownloadUrl(const GURL& url,
305 const GURL& referrer,
306 WebContents* web_contents);
307
308 // Allow objects to observe the download creation process.
309 void AddObserver(Observer* observer);
310
311 // Remove a download observer from ourself.
312 void RemoveObserver(Observer* observer);
313
314 // Methods called on completion of a query sent to the history system.
315 void OnQueryDownloadEntriesComplete(
316 std::vector<DownloadCreateInfo>* entries);
317 void OnCreateDownloadEntryComplete(DownloadCreateInfo info, int64 db_handle);
318 void OnSearchComplete(HistoryService::Handle handle,
319 std::vector<int64>* results);
320
321 // Show or Open a download via the Windows shell.
322 void ShowDownloadInShell(const DownloadItem* download);
323 void OpenDownloadInShell(const DownloadItem* download, HWND parent_window);
324
325 // The number of in progress (including paused) downloads.
326 int in_progress_count() const {
327 return static_cast<int>(in_progress_.size());
328 }
329
330 std::wstring download_path() { return *download_path_; }
331
332 // Registers this file extension for automatic opening upon download
333 // completion if 'open' is true, or prevents the extension from automatic
334 // opening if 'open' is false.
335 void OpenFilesOfExtension(const std::wstring& extension, bool open);
336
337 // Tests if a file type should be opened automatically.
338 bool ShouldOpenFileExtension(const std::wstring& extension);
339
340 // Tests if we think the server means for this mime_type to be executable.
341 static bool IsExecutableMimeType(const std::string& mime_type);
342
343 // Tests if a file type is considered executable.
344 bool IsExecutable(const std::wstring& extension);
345
346 // Resets the automatic open preference.
347 void ResetAutoOpenFiles();
348
349 // Returns true if there are automatic handlers registered for any file
350 // types.
351 bool HasAutoOpenFileTypesRegistered() const;
352
353 // Overridden from SelectFileDialog::Listener:
354 virtual void FileSelected(const std::wstring& path, void* params);
355 virtual void FileSelectionCanceled(void* params);
356
357 private:
358 // Shutdown the download manager. This call is needed only after Init.
359 void Shutdown();
360
361 // Called on the download thread to check whether the suggested file path
362 // exists. We don't check if the file exists on the UI thread to avoid UI
363 // stalls from interacting with the file system.
364 void CheckIfSuggestedPathExists(DownloadCreateInfo* info);
365
366 // Called on the UI thread once the DownloadManager has determined whether the
367 // suggested file path exists.
368 void OnPathExistenceAvailable(DownloadCreateInfo* info);
369
370 // Called back after a target path for the file to be downloaded to has been
371 // determined, either automatically based on the suggested file name, or by
372 // the user in a Save As dialog box.
373 void ContinueStartDownload(DownloadCreateInfo* info,
374 const std::wstring& target_path);
375
376 // Update the history service for a particular download.
377 void UpdateHistoryForDownload(DownloadItem* download);
378 void RemoveDownloadFromHistory(DownloadItem* download);
379 void RemoveDownloadsFromHistoryBetween(const Time remove_begin,
380 const Time remove_before);
381
382 // Inform the notification service of download starts and stops.
383 void NotifyAboutDownloadStart();
384 void NotifyAboutDownloadStop();
385
386 // Create an extension based on the file name and mime type.
387 void GenerateExtension(const std::wstring& file_name,
388 const std::string& mime_type,
389 std::wstring* generated_extension);
390
391 // Create a file name based on the response from the server.
392 void GenerateFilename(DownloadCreateInfo* info, std::wstring* generated_name);
393
394 // Persist the automatic opening preference.
395 void SaveAutoOpens();
396
397 // Runs the network cancel on the IO thread.
398 static void OnCancelDownloadRequest(ResourceDispatcherHost* rdh,
399 int render_process_id,
400 int request_id);
401
402 // Runs the pause on the IO thread.
403 static void OnPauseDownloadRequest(ResourceDispatcherHost* rdh,
404 int render_process_id,
405 int request_id,
406 bool pause);
407
408 // 'downloads_' is map of all downloads in this profile. The key is the handle
409 // returned by the history system, which is unique across sessions. This map
410 // owns all the DownloadItems once they have been created in the history
411 // system.
412 //
413 // 'in_progress_' is a map of all downloads that are in progress and that have
414 // not yet received a valid history handle. The key is the ID assigned by the
415 // ResourceDispatcherHost, which is unique for the current session. This map
416 // does not own the DownloadItems.
417 //
418 // When a download is created through a user action, the corresponding
419 // DownloadItem* is placed in 'in_progress_' and remains there until it has
420 // received a valid handle from the history system. Once it has a valid
421 // handle, the DownloadItem* is placed in the 'downloads_' map. When the
422 // download is complete, it is removed from 'in_progress_'. Downloads from
423 // past sessions read from a persisted state from the history system are
424 // placed directly into 'downloads_' since they have valid handles in the
425 // history system.
426 typedef base::hash_map<int64, DownloadItem*> DownloadMap;
427 DownloadMap downloads_;
428 DownloadMap in_progress_;
429
430 // True if the download manager has been initialized and requires a shutdown.
431 bool shutdown_needed_;
432
433 // Observers that want to be notified of changes to the set of downloads.
434 ObserverList<Observer> observers_;
435
436 // The current active profile.
437 Profile* profile_;
438 scoped_refptr<URLRequestContext> request_context_;
439
440 // Used for history service request management.
441 CancelableRequestConsumerT<Observer*, 0> cancelable_consumer_;
442
443 // Non-owning pointer for handling file writing on the download_thread_.
444 DownloadFileManager* file_manager_;
445
446 // A pointer to the main UI loop.
447 MessageLoop* ui_loop_;
448
449 // A pointer to the file thread's loop. The file thread lives longer than
450 // the DownloadManager, so this is safe to cache.
451 MessageLoop* file_loop_;
452
453 // User preferences
454 BooleanPrefMember prompt_for_download_;
455 StringPrefMember download_path_;
456
457 // The user's last choice for download directory. This is only used when the
458 // user wants us to prompt for a save location for each download.
459 std::wstring last_download_path_;
460
461 // Set of file extensions to open at download completion.
462 std::set<std::wstring> auto_open_;
463
464 // Set of file extensions that are executables and shouldn't be auto opened.
465 std::set<std::wstring> exe_types_;
466
467 // Keep track of downloads that are completed before the user selects the
468 // destination, so that observers are appropriately notified of completion
469 // after this determination is made.
470 // The map is of download_id->remaining size (bytes), both of which are
471 // required when calling DownloadFinished.
472 typedef std::map<int32, int64> PendingFinishedMap;
473 PendingFinishedMap pending_finished_downloads_;
474
475 // The "Save As" dialog box used to ask the user where a file should be
476 // saved.
477 scoped_refptr<SelectFileDialog> select_file_dialog_;
478
479 DISALLOW_EVIL_CONSTRUCTORS(DownloadManager);
480 };
481
482
483 #endif // CHROME_BROWSER_DOWNLOAD_MANAGER_H__
OLDNEW
« no previous file with comments | « chrome/browser/download_item_model.cc ('k') | chrome/browser/download_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698