Add a NavigationThrottle to the public content/ interface
[chromium-blink-merge.git] / content / browser / download / save_file_manager.h
blob4302846be218af8dc69dc9c06d334ce1528f2871
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 // Objects that handle file operations for saving files, on the file thread.
6 //
7 // The SaveFileManager owns a set of SaveFile objects, each of which connects
8 // with a SaveItem object which belongs to one SavePackage and runs on the file
9 // thread for saving data in order to avoid disk activity on either network IO
10 // thread or the UI thread. It coordinates the notifications from the network
11 // and UI.
13 // The SaveFileManager itself is a singleton object owned by the
14 // ResourceDispatcherHostImpl.
16 // The data sent to SaveFileManager have 2 sources, one is from
17 // ResourceDispatcherHostImpl, run in network IO thread, the all sub-resources
18 // and save-only-HTML pages will be got from network IO. The second is from
19 // render process, those html pages which are serialized from DOM will be
20 // composed in render process and encoded to its original encoding, then sent
21 // to UI loop in browser process, then UI loop will dispatch the data to
22 // SaveFileManager on the file thread. SaveFileManager will directly
23 // call SaveFile's method to persist data.
25 // A typical saving job operation involves multiple threads:
27 // Updating an in progress save file
28 // io_thread
29 // |----> data from net ---->|
30 // |
31 // |
32 // |----> data from ---->| |
33 // | render process | |
34 // ui_thread | |
35 // file_thread (writes to disk)
36 // |----> stats ---->|
37 // ui_thread (feedback for user)
40 // Cancel operations perform the inverse order when triggered by a user action:
41 // ui_thread (user click)
42 // |----> cancel command ---->|
43 // | | file_thread (close file)
44 // | |---------------------> cancel command ---->|
45 // | io_thread (stops net IO
46 // ui_thread (user close contents) for saving)
47 // |----> cancel command ---->|
48 // Render process(stop serializing DOM and sending
49 // data)
52 // The SaveFileManager tracks saving requests, mapping from a save ID (unique
53 // integer created in the IO thread) to the SavePackage for the contents where
54 // the saving job was initiated. In the event of a contents closure during
55 // saving, the SavePackage will notify the SaveFileManage to cancel all SaveFile
56 // jobs.
58 #ifndef CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_MANAGER_H_
59 #define CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_MANAGER_H_
61 #include <string>
63 #include "base/basictypes.h"
64 #include "base/containers/hash_tables.h"
65 #include "base/memory/ref_counted.h"
66 #include "content/browser/download/save_types.h"
67 #include "content/common/content_export.h"
69 class GURL;
71 namespace base {
72 class FilePath;
75 namespace net {
76 class IOBuffer;
79 namespace content {
80 class ResourceContext;
81 class SaveFile;
82 class SavePackage;
83 struct Referrer;
85 class SaveFileManager : public base::RefCountedThreadSafe<SaveFileManager> {
86 public:
87 SaveFileManager();
89 // Lifetime management.
90 CONTENT_EXPORT void Shutdown();
92 // Called on the IO thread. This generates unique IDs for
93 // SaveFileResourceHandler objects (there's one per file in a SavePackage).
94 // Note that this is different from the SavePackage's id.
95 int GetNextId();
97 // Save the specified URL. Called on the UI thread and forwarded to the
98 // ResourceDispatcherHostImpl on the IO thread.
99 void SaveURL(const GURL& url,
100 const Referrer& referrer,
101 int render_process_host_id,
102 int render_view_id,
103 int render_frame_id,
104 SaveFileCreateInfo::SaveFileSource save_source,
105 const base::FilePath& file_full_path,
106 ResourceContext* context,
107 SavePackage* save_package);
109 // Notifications sent from the IO thread and run on the file thread:
110 void StartSave(SaveFileCreateInfo* info);
111 void UpdateSaveProgress(int save_id, net::IOBuffer* data, int size);
112 void SaveFinished(int save_id,
113 const GURL& save_url,
114 int render_process_id,
115 bool is_success);
117 // Notifications sent from the UI thread and run on the file thread.
118 // Cancel a SaveFile instance which has specified save id.
119 void CancelSave(int save_id);
121 // Called on the UI thread to remove a save package from SaveFileManager's
122 // tracking map.
123 void RemoveSaveFile(int save_id, const GURL& save_url,
124 SavePackage* package);
126 // Helper function for deleting specified file.
127 void DeleteDirectoryOrFile(const base::FilePath& full_path, bool is_dir);
129 // Runs on file thread to save a file by copying from file system when
130 // original url is using file scheme.
131 void SaveLocalFile(const GURL& original_file_url,
132 int save_id,
133 int render_process_id);
135 // Renames all the successfully saved files.
136 // |final_names| points to a vector which contains pairs of save ids and
137 // final names of successfully saved files.
138 void RenameAllFiles(
139 const FinalNameList& final_names,
140 const base::FilePath& resource_dir,
141 int render_process_id,
142 int render_frame_id,
143 int save_package_id);
145 // When the user cancels the saving, we need to remove all remaining saved
146 // files of this page saving job from save_file_map_.
147 void RemoveSavedFileFromFileMap(const SaveIDList & save_ids);
149 private:
150 friend class base::RefCountedThreadSafe<SaveFileManager>;
152 ~SaveFileManager();
154 // A cleanup helper that runs on the file thread.
155 void OnShutdown();
157 // Called only on UI thread to get the SavePackage for a contents's browser
158 // context.
159 static SavePackage* GetSavePackageFromRenderIds(int render_process_id,
160 int render_Frame_id);
162 // Register a starting request. Associate the save URL with a
163 // SavePackage for further matching.
164 void RegisterStartingRequest(const GURL& save_url,
165 SavePackage* save_package);
166 // Unregister a start request according save URL, disassociate
167 // the save URL and SavePackage.
168 SavePackage* UnregisterStartingRequest(const GURL& save_url,
169 int contents_id);
171 // Look up the SavePackage according to save id.
172 SavePackage* LookupPackage(int save_id);
174 // Called only on the file thread.
175 // Look up one in-progress saving item according to save id.
176 SaveFile* LookupSaveFile(int save_id);
178 // Help function for sending notification of canceling specific request.
179 void SendCancelRequest(int save_id);
181 // Notifications sent from the file thread and run on the UI thread.
183 // Lookup the SaveManager for this WebContents' saving browser context and
184 // inform it the saving job has been started.
185 void OnStartSave(const SaveFileCreateInfo* info);
186 // Update the SavePackage with the current state of a started saving job.
187 // If the SavePackage for this saving job is gone, cancel the request.
188 void OnUpdateSaveProgress(int save_id,
189 int64 bytes_so_far,
190 bool write_success);
191 // Update the SavePackage with the finish state, and remove the request
192 // tracking entries.
193 void OnSaveFinished(int save_id, int64 bytes_so_far, bool is_success);
194 // For those requests that do not have valid save id, use
195 // map:(url, SavePackage) to find the request and remove it.
196 void OnErrorFinished(const GURL& save_url, int contents_id);
197 // Notifies SavePackage that the whole page saving job is finished.
198 void OnFinishSavePageJob(int render_process_id,
199 int render_frame_id,
200 int save_package_id);
202 // Notifications sent from the UI thread and run on the file thread.
204 // Deletes a specified file on the file thread.
205 void OnDeleteDirectoryOrFile(const base::FilePath& full_path, bool is_dir);
207 // Notifications sent from the UI thread and run on the IO thread
209 // Initiates a request for URL to be saved.
210 void OnSaveURL(const GURL& url,
211 const Referrer& referrer,
212 int render_process_host_id,
213 int render_view_id,
214 int render_frame_id,
215 ResourceContext* context);
216 // Handler for a notification sent to the IO thread for generating save id.
217 void OnRequireSaveJobFromOtherSource(SaveFileCreateInfo* info);
218 // Call ResourceDispatcherHostImpl's CancelRequest method to execute cancel
219 // action in the IO thread.
220 void ExecuteCancelSaveRequest(int render_process_id, int request_id);
222 // Unique ID for the next SaveFile object.
223 int next_id_;
225 // A map of all saving jobs by using save id.
226 typedef base::hash_map<int, SaveFile*> SaveFileMap;
227 SaveFileMap save_file_map_;
229 // Tracks which SavePackage to send data to, called only on UI thread.
230 // SavePackageMap maps save IDs to their SavePackage.
231 typedef base::hash_map<int, SavePackage*> SavePackageMap;
232 SavePackageMap packages_;
234 // There is a gap between after calling SaveURL() and before calling
235 // StartSave(). In this gap, each request does not have save id for tracking.
236 // But sometimes users might want to stop saving job or ResourceDispatcherHost
237 // calls SaveFinished with save id -1 for network error. We name the requests
238 // as starting requests. For tracking those starting requests, we need to
239 // have some data structure.
240 // First we use a hashmap to map the request URL to SavePackage, then we use a
241 // hashmap to map the contents id (we actually use render_process_id) to the
242 // hashmap since it is possible to save the same URL in different contents at
243 // same time.
244 typedef base::hash_map<std::string, SavePackage*> StartingRequestsMap;
245 typedef base::hash_map<int, StartingRequestsMap>
246 ContentsToStartingRequestsMap;
247 ContentsToStartingRequestsMap contents_starting_requests_;
249 DISALLOW_COPY_AND_ASSIGN(SaveFileManager);
252 } // namespace content
254 #endif // CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_MANAGER_H_