OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 DownloadFileManager owns a set of DownloadFile objects, each of which | |
6 // represent one in progress download and performs the disk IO for that | |
7 // download. The DownloadFileManager itself is a singleton object owned by the | |
8 // ResourceDispatcherHostImpl. | |
9 // | |
10 // The DownloadFileManager uses the file_thread for performing file write | |
11 // operations, in order to avoid disk activity on either the IO (network) thread | |
12 // and the UI thread. It coordinates the notifications from the network and UI. | |
13 // | |
14 // A typical download operation involves multiple threads: | |
15 // | |
16 // Updating an in progress download | |
17 // io_thread | |
18 // |----> data ---->| | |
19 // file_thread (writes to disk) | |
20 // |----> stats ---->| | |
21 // ui_thread (feedback for user and | |
22 // updates to history) | |
23 // | |
24 // Cancel operations perform the inverse order when triggered by a user action: | |
25 // ui_thread (user click) | |
26 // |----> cancel command ---->| | |
27 // file_thread (close file) | |
28 // |----> cancel command ---->| | |
29 // io_thread (stops net IO | |
30 // for download) | |
31 // | |
32 // The DownloadFileManager tracks download requests, mapping from a download | |
33 // ID (unique integer created in the IO thread) to the DownloadManager for the | |
34 // contents (profile) where the download was initiated. In the event of a | |
35 // contents closure during a download, the DownloadFileManager will continue to | |
36 // route data to the appropriate DownloadManager. In progress downloads are | |
37 // cancelled for a DownloadManager that exits (such as when closing a profile). | |
38 | |
39 #ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_FILE_MANAGER_H_ | |
40 #define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_FILE_MANAGER_H_ | |
41 | |
42 #include <map> | |
43 | |
44 #include "base/atomic_sequence_num.h" | |
45 #include "base/basictypes.h" | |
46 #include "base/callback_forward.h" | |
47 #include "base/gtest_prod_util.h" | |
48 #include "base/hash_tables.h" | |
49 #include "base/memory/ref_counted.h" | |
50 #include "base/memory/scoped_ptr.h" | |
51 #include "base/timer.h" | |
52 #include "content/browser/download/download_file.h" | |
53 #include "content/browser/download/download_file_factory.h" | |
54 #include "content/common/content_export.h" | |
55 #include "content/public/browser/download_id.h" | |
56 #include "content/public/browser/download_interrupt_reasons.h" | |
57 #include "net/base/net_errors.h" | |
58 #include "ui/gfx/native_widget_types.h" | |
59 | |
60 struct DownloadCreateInfo; | |
61 class DownloadRequestHandle; | |
62 class FilePath; | |
63 | |
64 namespace content { | |
65 class ByteStreamReader; | |
66 class DownloadId; | |
67 class DownloadManager; | |
68 } | |
69 | |
70 namespace net { | |
71 class BoundNetLog; | |
72 } | |
73 | |
74 // Manages all in progress downloads. | |
75 // Methods are virtual to allow mocks--this class is not intended | |
76 // to be a base class. | |
77 class CONTENT_EXPORT DownloadFileManager | |
78 : public base::RefCountedThreadSafe<DownloadFileManager> { | |
79 public: | |
80 // Callback used with CreateDownloadFile(). |reason| will be | |
81 // DOWNLOAD_INTERRUPT_REASON_NONE on a successful creation. | |
82 typedef base::Callback<void(content::DownloadInterruptReason reason)> | |
83 CreateDownloadFileCallback; | |
84 | |
85 // Callback used with RenameDownloadFile(). | |
86 typedef content::DownloadFile::RenameCompletionCallback | |
87 RenameCompletionCallback; | |
88 | |
89 // Takes ownership of the factory. | |
90 // Passing in a NULL for |factory| will cause a default | |
91 // |DownloadFileFactory| to be used. | |
92 explicit DownloadFileManager(content::DownloadFileFactory* factory); | |
93 | |
94 // Create a download file and record it in the download file manager. | |
95 virtual void CreateDownloadFile( | |
96 scoped_ptr<DownloadCreateInfo> info, | |
97 scoped_ptr<content::ByteStreamReader> stream, | |
98 scoped_refptr<content::DownloadManager> download_manager, | |
99 bool hash_needed, | |
100 const net::BoundNetLog& bound_net_log, | |
101 const CreateDownloadFileCallback& callback); | |
102 | |
103 // Called on shutdown on the UI thread. | |
104 virtual void Shutdown(); | |
105 | |
106 // Handlers for notifications sent from the UI thread and run on the | |
107 // FILE thread. These are both terminal actions with respect to the | |
108 // download file, as far as the DownloadFileManager is concerned -- if | |
109 // anything happens to the download file after they are called, it will | |
110 // be ignored. | |
111 // We call back to the UI thread in the case of CompleteDownload so that | |
112 // we know when we can hand the file off to other consumers. | |
113 virtual void CancelDownload(content::DownloadId id); | |
114 virtual void CompleteDownload(content::DownloadId id, | |
115 const base::Closure& callback); | |
116 | |
117 // Called on FILE thread by DownloadManager at the beginning of its shutdown. | |
118 virtual void OnDownloadManagerShutdown(content::DownloadManager* manager); | |
119 | |
120 // Rename the download file, uniquifying if overwrite was not requested. | |
121 virtual void RenameDownloadFile( | |
122 content::DownloadId id, | |
123 const FilePath& full_path, | |
124 bool overwrite_existing_file, | |
125 const RenameCompletionCallback& callback); | |
126 | |
127 // The number of downloads currently active on the DownloadFileManager. | |
128 // Primarily for testing. | |
129 virtual int NumberOfActiveDownloads() const; | |
130 | |
131 void SetFileFactoryForTesting( | |
132 scoped_ptr<content::DownloadFileFactory> file_factory) { | |
133 download_file_factory_.reset(file_factory.release()); | |
134 } | |
135 | |
136 content::DownloadFileFactory* GetFileFactoryForTesting() const { | |
137 return download_file_factory_.get(); // Explicitly NOT a scoped_ptr. | |
138 } | |
139 | |
140 protected: | |
141 virtual ~DownloadFileManager(); | |
142 | |
143 private: | |
144 friend class base::RefCountedThreadSafe<DownloadFileManager>; | |
145 friend class DownloadFileManagerTest; | |
146 friend class DownloadManagerTest; | |
147 FRIEND_TEST_ALL_PREFIXES(DownloadManagerTest, StartDownload); | |
148 | |
149 // Clean up helper that runs on the download thread. | |
150 void OnShutdown(); | |
151 | |
152 // Called only on the download thread. | |
153 content::DownloadFile* GetDownloadFile(content::DownloadId global_id); | |
154 | |
155 // Erases the download file with the given the download |id| and removes | |
156 // it from the maps. | |
157 void EraseDownload(content::DownloadId global_id); | |
158 | |
159 typedef base::hash_map<content::DownloadId, content::DownloadFile*> | |
160 DownloadFileMap; | |
161 | |
162 // A map of all in progress downloads. It owns the download files. | |
163 DownloadFileMap downloads_; | |
164 | |
165 scoped_ptr<content::DownloadFileFactory> download_file_factory_; | |
166 | |
167 DISALLOW_COPY_AND_ASSIGN(DownloadFileManager); | |
168 }; | |
169 | |
170 #endif // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_FILE_MANAGER_H_ | |
OLD | NEW |