OLD | NEW |
| (Empty) |
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 // 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 // Download observers: | |
11 // Objects that are interested in notifications about new downloads, or progress | |
12 // updates for a given download must implement one of the download observer | |
13 // interfaces: | |
14 // DownloadManager::Observer: | |
15 // - allows observers, primarily views, to be notified when changes to the | |
16 // set of all downloads (such as new downloads, or deletes) occur | |
17 // Use AddObserver() / RemoveObserver() on the appropriate download object to | |
18 // receive state updates. | |
19 // | |
20 // Download state persistence: | |
21 // The DownloadManager uses the history service for storing persistent | |
22 // information about the state of all downloads. The history system maintains a | |
23 // separate table for this called 'downloads'. At the point that the | |
24 // DownloadManager is constructed, we query the history service for the state of | |
25 // all persisted downloads. | |
26 | |
27 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ | |
28 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ | |
29 #pragma once | |
30 | |
31 #include <map> | |
32 #include <set> | |
33 #include <string> | |
34 #include <vector> | |
35 | |
36 #include "base/basictypes.h" | |
37 #include "base/file_path.h" | |
38 #include "base/gtest_prod_util.h" | |
39 #include "base/hash_tables.h" | |
40 #include "base/memory/ref_counted.h" | |
41 #include "base/memory/scoped_ptr.h" | |
42 #include "base/memory/weak_ptr.h" | |
43 #include "base/observer_list.h" | |
44 #include "base/time.h" | |
45 #include "chrome/browser/download/download_item.h" | |
46 #include "chrome/browser/download/download_request_handle.h" | |
47 #include "chrome/browser/download/download_status_updater_delegate.h" | |
48 #include "content/browser/browser_thread.h" | |
49 | |
50 class DownloadFileManager; | |
51 class DownloadHistory; | |
52 class DownloadManagerDelegate; | |
53 class DownloadPrefs; | |
54 class DownloadStatusUpdater; | |
55 class GURL; | |
56 class Profile; | |
57 class ResourceDispatcherHost; | |
58 class TabContents; | |
59 struct DownloadCreateInfo; | |
60 struct DownloadHistoryInfo; | |
61 struct DownloadSaveInfo; | |
62 | |
63 // Browser's download manager: manages all downloads and destination view. | |
64 class DownloadManager | |
65 : public base::RefCountedThreadSafe<DownloadManager, | |
66 BrowserThread::DeleteOnUIThread>, | |
67 public DownloadStatusUpdaterDelegate { | |
68 public: | |
69 DownloadManager(DownloadManagerDelegate* delegate, | |
70 DownloadStatusUpdater* status_updater); | |
71 | |
72 // Shutdown the download manager. Must be called before destruction. | |
73 void Shutdown(); | |
74 | |
75 // Interface to implement for observers that wish to be informed of changes | |
76 // to the DownloadManager's collection of downloads. | |
77 class Observer { | |
78 public: | |
79 // New or deleted download, observers should query us for the current set | |
80 // of downloads. | |
81 virtual void ModelChanged() = 0; | |
82 | |
83 // Called when the DownloadManager is being destroyed to prevent Observers | |
84 // from calling back to a stale pointer. | |
85 virtual void ManagerGoingDown() {} | |
86 | |
87 // Called immediately after the DownloadManager puts up a select file | |
88 // dialog. | |
89 // |id| indicates which download opened the dialog. | |
90 virtual void SelectFileDialogDisplayed(int32 id) {} | |
91 | |
92 protected: | |
93 virtual ~Observer() {} | |
94 }; | |
95 | |
96 typedef std::vector<DownloadItem*> DownloadVector; | |
97 | |
98 // Return all temporary downloads that reside in the specified directory. | |
99 void GetTemporaryDownloads(const FilePath& dir_path, DownloadVector* result); | |
100 | |
101 // Return all non-temporary downloads in the specified directory that are | |
102 // are in progress or have completed. | |
103 void GetAllDownloads(const FilePath& dir_path, DownloadVector* result); | |
104 | |
105 // Return all non-temporary downloads in the specified directory that are | |
106 // in-progress (including dangerous downloads waiting for user confirmation). | |
107 void GetCurrentDownloads(const FilePath& dir_path, DownloadVector* result); | |
108 | |
109 // Returns all non-temporary downloads matching |query|. Empty query matches | |
110 // everything. | |
111 void SearchDownloads(const string16& query, DownloadVector* result); | |
112 | |
113 // Returns true if initialized properly. | |
114 bool Init(Profile* profile); | |
115 | |
116 // Notifications sent from the download thread to the UI thread | |
117 void StartDownload(int32 id); | |
118 void UpdateDownload(int32 download_id, int64 size); | |
119 // |hash| is sha256 hash for the downloaded file. It is empty when the hash | |
120 // is not available. | |
121 void OnResponseCompleted(int32 download_id, int64 size, int os_error, | |
122 const std::string& hash); | |
123 | |
124 // Called from a view when a user clicks a UI button or link. | |
125 void DownloadCancelled(int32 download_id); | |
126 void RemoveDownload(int64 download_handle); | |
127 | |
128 // Determine if the download is ready for completion, i.e. has had | |
129 // all data saved, and completed the filename determination and | |
130 // history insertion. | |
131 bool IsDownloadReadyForCompletion(DownloadItem* download); | |
132 | |
133 // If all pre-requisites have been met, complete download processing, i.e. | |
134 // do internal cleanup, file rename, and potentially auto-open. | |
135 // (Dangerous downloads still may block on user acceptance after this | |
136 // point.) | |
137 void MaybeCompleteDownload(DownloadItem* download); | |
138 | |
139 // Called when the download is renamed to its final name. | |
140 // |uniquifier| is a number used to make unique names for the file. It is | |
141 // only valid for the DANGEROUS_BUT_VALIDATED state of the download item. | |
142 void OnDownloadRenamedToFinalName(int download_id, | |
143 const FilePath& full_path, | |
144 int uniquifier); | |
145 | |
146 // Remove downloads after remove_begin (inclusive) and before remove_end | |
147 // (exclusive). You may pass in null Time values to do an unbounded delete | |
148 // in either direction. | |
149 int RemoveDownloadsBetween(const base::Time remove_begin, | |
150 const base::Time remove_end); | |
151 | |
152 // Remove downloads will delete all downloads that have a timestamp that is | |
153 // the same or more recent than |remove_begin|. The number of downloads | |
154 // deleted is returned back to the caller. | |
155 int RemoveDownloads(const base::Time remove_begin); | |
156 | |
157 // Remove all downloads will delete all downloads. The number of downloads | |
158 // deleted is returned back to the caller. | |
159 int RemoveAllDownloads(); | |
160 | |
161 // Final download manager transition for download: Update the download | |
162 // history and remove the download from |active_downloads_|. | |
163 void DownloadCompleted(int32 download_id); | |
164 | |
165 // Download the object at the URL. Used in cases such as "Save Link As..." | |
166 void DownloadUrl(const GURL& url, | |
167 const GURL& referrer, | |
168 const std::string& referrer_encoding, | |
169 TabContents* tab_contents); | |
170 | |
171 // Download the object at the URL and save it to the specified path. The | |
172 // download is treated as the temporary download and thus will not appear | |
173 // in the download history. Used in cases such as drag and drop. | |
174 void DownloadUrlToFile(const GURL& url, | |
175 const GURL& referrer, | |
176 const std::string& referrer_encoding, | |
177 const DownloadSaveInfo& save_info, | |
178 TabContents* tab_contents); | |
179 | |
180 // Allow objects to observe the download creation process. | |
181 void AddObserver(Observer* observer); | |
182 | |
183 // Remove a download observer from ourself. | |
184 void RemoveObserver(Observer* observer); | |
185 | |
186 // Methods called on completion of a query sent to the history system. | |
187 void OnQueryDownloadEntriesComplete( | |
188 std::vector<DownloadHistoryInfo>* entries); | |
189 void OnCreateDownloadEntryComplete(int32 download_id, int64 db_handle); | |
190 | |
191 // Display a new download in the appropriate browser UI. | |
192 void ShowDownloadInBrowser(DownloadItem* download); | |
193 | |
194 // The number of in progress (including paused) downloads. | |
195 int in_progress_count() const { | |
196 return static_cast<int>(in_progress_.size()); | |
197 } | |
198 | |
199 Profile* profile() { return profile_; } | |
200 | |
201 DownloadHistory* download_history() { return download_history_.get(); } | |
202 | |
203 DownloadPrefs* download_prefs() { return download_prefs_.get(); } | |
204 | |
205 FilePath last_download_path() { return last_download_path_; } | |
206 | |
207 // Creates the download item. Must be called on the UI thread. | |
208 void CreateDownloadItem(DownloadCreateInfo* info); | |
209 | |
210 // Clears the last download path, used to initialize "save as" dialogs. | |
211 void ClearLastDownloadPath(); | |
212 | |
213 // Overridden from DownloadStatusUpdaterDelegate: | |
214 virtual bool IsDownloadProgressKnown(); | |
215 virtual int64 GetInProgressDownloadCount(); | |
216 virtual int64 GetReceivedDownloadBytes(); | |
217 virtual int64 GetTotalDownloadBytes(); | |
218 | |
219 // Called by the delegate after the save as dialog is closed. | |
220 void FileSelected(const FilePath& path, void* params); | |
221 void FileSelectionCanceled(void* params); | |
222 | |
223 // Called by the delegate if it delayed the download in | |
224 // DownloadManagerDelegate::ShouldStartDownload and now is ready. | |
225 void RestartDownload(int32 download_id); | |
226 | |
227 // Checks whether downloaded files still exist. Updates state of downloads | |
228 // that refer to removed files. The check runs in the background and may | |
229 // finish asynchronously after this method returns. | |
230 void CheckForHistoryFilesRemoval(); | |
231 | |
232 // Checks whether a downloaded file still exists and updates the file's state | |
233 // if the file is already removed. The check runs in the background and may | |
234 // finish asynchronously after this method returns. | |
235 void CheckForFileRemoval(DownloadItem* download_item); | |
236 | |
237 // Assert the named download item is on the correct queues | |
238 // in the DownloadManager. For debugging. | |
239 void AssertQueueStateConsistent(DownloadItem* download); | |
240 | |
241 // Get the download item from the history map. Useful after the item has | |
242 // been removed from the active map, or was retrieved from the history DB. | |
243 DownloadItem* GetDownloadItem(int id); | |
244 | |
245 // Called when Save Page download starts. Transfers ownership of |download| | |
246 // to the DownloadManager. | |
247 void SavePageDownloadStarted(DownloadItem* download); | |
248 | |
249 // Callback when Save Page As entry is commited to the history system. | |
250 void OnSavePageDownloadEntryAdded(int32 download_id, int64 db_handle); | |
251 | |
252 // Called when Save Page download is done. | |
253 void SavePageDownloadFinished(DownloadItem* download); | |
254 | |
255 // Download Id for next Save Page. | |
256 int32 GetNextSavePageId(); | |
257 | |
258 // Get the download item from the active map. Useful when the item is not | |
259 // yet in the history map. | |
260 DownloadItem* GetActiveDownloadItem(int id); | |
261 | |
262 DownloadManagerDelegate* delegate() const { return delegate_; } | |
263 | |
264 private: | |
265 typedef std::set<DownloadItem*> DownloadSet; | |
266 typedef base::hash_map<int64, DownloadItem*> DownloadMap; | |
267 | |
268 // For testing. | |
269 friend class DownloadManagerTest; | |
270 friend class MockDownloadManager; | |
271 | |
272 // This class is used to let an incognito DownloadManager observe changes to | |
273 // a normal DownloadManager, to propagate ModelChanged() calls from the parent | |
274 // DownloadManager to the observers of the incognito DownloadManager. | |
275 class OtherDownloadManagerObserver : public Observer { | |
276 public: | |
277 explicit OtherDownloadManagerObserver( | |
278 DownloadManager* observing_download_manager); | |
279 virtual ~OtherDownloadManagerObserver(); | |
280 | |
281 // Observer interface. | |
282 virtual void ModelChanged(); | |
283 virtual void ManagerGoingDown(); | |
284 | |
285 private: | |
286 // The incognito download manager. | |
287 DownloadManager* observing_download_manager_; | |
288 | |
289 // The original profile's download manager. | |
290 DownloadManager* observed_download_manager_; | |
291 }; | |
292 | |
293 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; | |
294 friend class DeleteTask<DownloadManager>; | |
295 friend class OtherDownloadManagerObserver; | |
296 | |
297 virtual ~DownloadManager(); | |
298 | |
299 // Called on the FILE thread to check the existence of a downloaded file. | |
300 void CheckForFileRemovalOnFileThread(int64 db_handle, const FilePath& path); | |
301 | |
302 // Called on the UI thread if the FILE thread detects the removal of | |
303 // the downloaded file. The UI thread updates the state of the file | |
304 // and then notifies this update to the file's observer. | |
305 void OnFileRemovalDetected(int64 db_handle); | |
306 | |
307 // Called back after a target path for the file to be downloaded to has been | |
308 // determined, either automatically based on the suggested file name, or by | |
309 // the user in a Save As dialog box. | |
310 void ContinueDownloadWithPath(DownloadItem* download, | |
311 const FilePath& chosen_file); | |
312 | |
313 // Download cancel helper function. | |
314 void DownloadCancelledInternal(int download_id, | |
315 const DownloadRequestHandle& request_handle); | |
316 | |
317 // All data has been downloaded. | |
318 // |hash| is sha256 hash for the downloaded file. It is empty when the hash | |
319 // is not available. | |
320 void OnAllDataSaved(int32 download_id, int64 size, const std::string& hash); | |
321 | |
322 // An error occurred in the download. | |
323 void OnDownloadError(int32 download_id, int64 size, int os_error); | |
324 | |
325 // Updates the app icon about the overall download progress. | |
326 void UpdateAppIcon(); | |
327 | |
328 // Inform observers that the model has changed. | |
329 void NotifyModelChanged(); | |
330 | |
331 // Debugging routine to confirm relationship between below | |
332 // containers; no-op if NDEBUG. | |
333 void AssertContainersConsistent() const; | |
334 | |
335 // Add a DownloadItem to history_downloads_. | |
336 void AddDownloadItemToHistory(DownloadItem* item, int64 db_handle); | |
337 | |
338 // Remove from internal maps. | |
339 int RemoveDownloadItems(const DownloadVector& pending_deletes); | |
340 | |
341 // |downloads_| is the owning set for all downloads known to the | |
342 // DownloadManager. This includes downloads started by the user in | |
343 // this session, downloads initialized from the history system, and | |
344 // "save page as" downloads. All other DownloadItem containers in | |
345 // the DownloadManager are maps; they do not own the DownloadItems. | |
346 // Note that this is the only place (with any functional implications; | |
347 // see save_page_as_downloads_ below) that "save page as" downloads are | |
348 // kept, as the DownloadManager's only job is to hold onto those | |
349 // until destruction. | |
350 // | |
351 // |history_downloads_| is map of all downloads in this profile. The key | |
352 // is the handle returned by the history system, which is unique | |
353 // across sessions. | |
354 // | |
355 // |active_downloads_| is a map of all downloads that are currently being | |
356 // processed. The key is the ID assigned by the ResourceDispatcherHost, | |
357 // which is unique for the current session. | |
358 // | |
359 // |in_progress_| is a map of all downloads that are in progress and that have | |
360 // not yet received a valid history handle. The key is the ID assigned by the | |
361 // ResourceDispatcherHost, which is unique for the current session. | |
362 // | |
363 // |save_page_as_downloads_| (if defined) is a collection of all the | |
364 // downloads the "save page as" system has given to us to hold onto | |
365 // until we are destroyed. It is only used for debugging. | |
366 // | |
367 // When a download is created through a user action, the corresponding | |
368 // DownloadItem* is placed in |active_downloads_| and remains there until the | |
369 // download is in a terminal state (COMPLETE or CANCELLED). It is also | |
370 // placed in |in_progress_| and remains there until it has received a | |
371 // valid handle from the history system. Once it has a valid handle, the | |
372 // DownloadItem* is placed in the |history_downloads_| map. When the | |
373 // download reaches a terminal state, it is removed from |in_progress_|. | |
374 // Downloads from past sessions read from a persisted state from the | |
375 // history system are placed directly into |history_downloads_| since | |
376 // they have valid handles in the history system. | |
377 | |
378 DownloadSet downloads_; | |
379 DownloadMap history_downloads_; | |
380 DownloadMap in_progress_; | |
381 DownloadMap active_downloads_; | |
382 DownloadMap save_page_downloads_; | |
383 | |
384 // True if the download manager has been initialized and requires a shutdown. | |
385 bool shutdown_needed_; | |
386 | |
387 // Observers that want to be notified of changes to the set of downloads. | |
388 ObserverList<Observer> observers_; | |
389 | |
390 // The current active profile. | |
391 Profile* profile_; | |
392 | |
393 scoped_ptr<DownloadHistory> download_history_; | |
394 | |
395 scoped_ptr<DownloadPrefs> download_prefs_; | |
396 | |
397 // Non-owning pointer for handling file writing on the download_thread_. | |
398 DownloadFileManager* file_manager_; | |
399 | |
400 // Non-owning pointer for updating the download status. | |
401 base::WeakPtr<DownloadStatusUpdater> status_updater_; | |
402 | |
403 // The user's last choice for download directory. This is only used when the | |
404 // user wants us to prompt for a save location for each download. | |
405 FilePath last_download_path_; | |
406 | |
407 // Download Id for next Save Page. | |
408 int32 next_save_page_id_; | |
409 | |
410 scoped_ptr<OtherDownloadManagerObserver> other_download_manager_observer_; | |
411 | |
412 // Allows an embedder to control behavior. Guaranteed to outlive this object. | |
413 DownloadManagerDelegate* delegate_; | |
414 | |
415 DISALLOW_COPY_AND_ASSIGN(DownloadManager); | |
416 }; | |
417 | |
418 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ | |
OLD | NEW |