| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 | 6 |
| 7 #include "content/browser/download/save_file_manager.h" | 7 #include "content/browser/download/save_file_manager.h" |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 // Called during the browser shutdown process to clean up any state (open files, | 36 // Called during the browser shutdown process to clean up any state (open files, |
| 37 // timers) that live on the saving thread (file thread). | 37 // timers) that live on the saving thread (file thread). |
| 38 void SaveFileManager::Shutdown() { | 38 void SaveFileManager::Shutdown() { |
| 39 BrowserThread::PostTask( | 39 BrowserThread::PostTask( |
| 40 BrowserThread::FILE, FROM_HERE, | 40 BrowserThread::FILE, FROM_HERE, |
| 41 base::Bind(&SaveFileManager::OnShutdown, this)); | 41 base::Bind(&SaveFileManager::OnShutdown, this)); |
| 42 } | 42 } |
| 43 | 43 |
| 44 // Stop file thread operations. | 44 // Stop file thread operations. |
| 45 void SaveFileManager::OnShutdown() { | 45 void SaveFileManager::OnShutdown() { |
| 46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 46 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 47 STLDeleteValues(&save_file_map_); | 47 STLDeleteValues(&save_file_map_); |
| 48 } | 48 } |
| 49 | 49 |
| 50 SaveFile* SaveFileManager::LookupSaveFile(int save_id) { | 50 SaveFile* SaveFileManager::LookupSaveFile(int save_id) { |
| 51 SaveFileMap::iterator it = save_file_map_.find(save_id); | 51 SaveFileMap::iterator it = save_file_map_.find(save_id); |
| 52 return it == save_file_map_.end() ? NULL : it->second; | 52 return it == save_file_map_.end() ? NULL : it->second; |
| 53 } | 53 } |
| 54 | 54 |
| 55 // Called on the IO thread when | 55 // Called on the IO thread when |
| 56 // a) The ResourceDispatcherHostImpl has decided that a request is savable. | 56 // a) The ResourceDispatcherHostImpl has decided that a request is savable. |
| 57 // b) The resource does not come from the network, but we still need a | 57 // b) The resource does not come from the network, but we still need a |
| 58 // save ID for for managing the status of the saving operation. So we | 58 // save ID for for managing the status of the saving operation. So we |
| 59 // file a request from the file thread to the IO thread to generate a | 59 // file a request from the file thread to the IO thread to generate a |
| 60 // unique save ID. | 60 // unique save ID. |
| 61 int SaveFileManager::GetNextId() { | 61 int SaveFileManager::GetNextId() { |
| 62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 62 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 63 return next_id_++; | 63 return next_id_++; |
| 64 } | 64 } |
| 65 | 65 |
| 66 void SaveFileManager::RegisterStartingRequest(const GURL& save_url, | 66 void SaveFileManager::RegisterStartingRequest(const GURL& save_url, |
| 67 SavePackage* save_package) { | 67 SavePackage* save_package) { |
| 68 // Make sure it runs in the UI thread. | 68 // Make sure it runs in the UI thread. |
| 69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 69 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 70 int contents_id = save_package->contents_id(); | 70 int contents_id = save_package->contents_id(); |
| 71 | 71 |
| 72 // Register this starting request. | 72 // Register this starting request. |
| 73 StartingRequestsMap& starting_requests = | 73 StartingRequestsMap& starting_requests = |
| 74 contents_starting_requests_[contents_id]; | 74 contents_starting_requests_[contents_id]; |
| 75 bool never_present = starting_requests.insert( | 75 bool never_present = starting_requests.insert( |
| 76 StartingRequestsMap::value_type(save_url.spec(), save_package)).second; | 76 StartingRequestsMap::value_type(save_url.spec(), save_package)).second; |
| 77 DCHECK(never_present); | 77 DCHECK(never_present); |
| 78 } | 78 } |
| 79 | 79 |
| 80 SavePackage* SaveFileManager::UnregisterStartingRequest( | 80 SavePackage* SaveFileManager::UnregisterStartingRequest( |
| 81 const GURL& save_url, int contents_id) { | 81 const GURL& save_url, int contents_id) { |
| 82 // Make sure it runs in UI thread. | 82 // Make sure it runs in UI thread. |
| 83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 83 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 84 | 84 |
| 85 ContentsToStartingRequestsMap::iterator it = | 85 ContentsToStartingRequestsMap::iterator it = |
| 86 contents_starting_requests_.find(contents_id); | 86 contents_starting_requests_.find(contents_id); |
| 87 if (it != contents_starting_requests_.end()) { | 87 if (it != contents_starting_requests_.end()) { |
| 88 StartingRequestsMap& requests = it->second; | 88 StartingRequestsMap& requests = it->second; |
| 89 StartingRequestsMap::iterator sit = requests.find(save_url.spec()); | 89 StartingRequestsMap::iterator sit = requests.find(save_url.spec()); |
| 90 if (sit == requests.end()) | 90 if (sit == requests.end()) |
| 91 return NULL; | 91 return NULL; |
| 92 | 92 |
| 93 // Found, erase it from starting list and return SavePackage. | 93 // Found, erase it from starting list and return SavePackage. |
| 94 SavePackage* save_package = sit->second; | 94 SavePackage* save_package = sit->second; |
| 95 requests.erase(sit); | 95 requests.erase(sit); |
| 96 // If there is no element in requests, remove it | 96 // If there is no element in requests, remove it |
| 97 if (requests.empty()) | 97 if (requests.empty()) |
| 98 contents_starting_requests_.erase(it); | 98 contents_starting_requests_.erase(it); |
| 99 return save_package; | 99 return save_package; |
| 100 } | 100 } |
| 101 | 101 |
| 102 return NULL; | 102 return NULL; |
| 103 } | 103 } |
| 104 | 104 |
| 105 // Look up a SavePackage according to a save id. | 105 // Look up a SavePackage according to a save id. |
| 106 SavePackage* SaveFileManager::LookupPackage(int save_id) { | 106 SavePackage* SaveFileManager::LookupPackage(int save_id) { |
| 107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 107 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 108 SavePackageMap::iterator it = packages_.find(save_id); | 108 SavePackageMap::iterator it = packages_.find(save_id); |
| 109 if (it != packages_.end()) | 109 if (it != packages_.end()) |
| 110 return it->second; | 110 return it->second; |
| 111 return NULL; | 111 return NULL; |
| 112 } | 112 } |
| 113 | 113 |
| 114 // Call from SavePackage for starting a saving job | 114 // Call from SavePackage for starting a saving job |
| 115 void SaveFileManager::SaveURL( | 115 void SaveFileManager::SaveURL( |
| 116 const GURL& url, | 116 const GURL& url, |
| 117 const Referrer& referrer, | 117 const Referrer& referrer, |
| 118 int render_process_host_id, | 118 int render_process_host_id, |
| 119 int render_view_id, | 119 int render_view_id, |
| 120 SaveFileCreateInfo::SaveFileSource save_source, | 120 SaveFileCreateInfo::SaveFileSource save_source, |
| 121 const base::FilePath& file_full_path, | 121 const base::FilePath& file_full_path, |
| 122 ResourceContext* context, | 122 ResourceContext* context, |
| 123 SavePackage* save_package) { | 123 SavePackage* save_package) { |
| 124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 124 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 125 | 125 |
| 126 // Register a saving job. | 126 // Register a saving job. |
| 127 RegisterStartingRequest(url, save_package); | 127 RegisterStartingRequest(url, save_package); |
| 128 if (save_source == SaveFileCreateInfo::SAVE_FILE_FROM_NET) { | 128 if (save_source == SaveFileCreateInfo::SAVE_FILE_FROM_NET) { |
| 129 DCHECK(url.is_valid()); | 129 DCHECK(url.is_valid()); |
| 130 | 130 |
| 131 BrowserThread::PostTask( | 131 BrowserThread::PostTask( |
| 132 BrowserThread::IO, FROM_HERE, | 132 BrowserThread::IO, FROM_HERE, |
| 133 base::Bind(&SaveFileManager::OnSaveURL, this, url, referrer, | 133 base::Bind(&SaveFileManager::OnSaveURL, this, url, referrer, |
| 134 render_process_host_id, render_view_id, context)); | 134 render_process_host_id, render_view_id, context)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 152 | 152 |
| 153 // Utility function for look up table maintenance, called on the UI thread. | 153 // Utility function for look up table maintenance, called on the UI thread. |
| 154 // A manager may have multiple save page job (SavePackage) in progress, | 154 // A manager may have multiple save page job (SavePackage) in progress, |
| 155 // so we just look up the save id and remove it from the tracking table. | 155 // so we just look up the save id and remove it from the tracking table. |
| 156 // If the save id is -1, it means we just send a request to save, but the | 156 // If the save id is -1, it means we just send a request to save, but the |
| 157 // saving action has still not happened, need to call UnregisterStartingRequest | 157 // saving action has still not happened, need to call UnregisterStartingRequest |
| 158 // to remove it from the tracking map. | 158 // to remove it from the tracking map. |
| 159 void SaveFileManager::RemoveSaveFile(int save_id, const GURL& save_url, | 159 void SaveFileManager::RemoveSaveFile(int save_id, const GURL& save_url, |
| 160 SavePackage* package) { | 160 SavePackage* package) { |
| 161 DCHECK(package); | 161 DCHECK(package); |
| 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 162 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 163 // A save page job (SavePackage) can only have one manager, | 163 // A save page job (SavePackage) can only have one manager, |
| 164 // so remove it if it exists. | 164 // so remove it if it exists. |
| 165 if (save_id == -1) { | 165 if (save_id == -1) { |
| 166 SavePackage* old_package = | 166 SavePackage* old_package = |
| 167 UnregisterStartingRequest(save_url, package->contents_id()); | 167 UnregisterStartingRequest(save_url, package->contents_id()); |
| 168 DCHECK_EQ(old_package, package); | 168 DCHECK_EQ(old_package, package); |
| 169 } else { | 169 } else { |
| 170 SavePackageMap::iterator it = packages_.find(save_id); | 170 SavePackageMap::iterator it = packages_.find(save_id); |
| 171 if (it != packages_.end()) | 171 if (it != packages_.end()) |
| 172 packages_.erase(it); | 172 packages_.erase(it); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 184 WebContentsImpl* contents = static_cast<WebContentsImpl*>( | 184 WebContentsImpl* contents = static_cast<WebContentsImpl*>( |
| 185 render_view_host->GetDelegate()->GetAsWebContents()); | 185 render_view_host->GetDelegate()->GetAsWebContents()); |
| 186 if (!contents) | 186 if (!contents) |
| 187 return NULL; | 187 return NULL; |
| 188 | 188 |
| 189 return contents->save_package(); | 189 return contents->save_package(); |
| 190 } | 190 } |
| 191 | 191 |
| 192 void SaveFileManager::DeleteDirectoryOrFile(const base::FilePath& full_path, | 192 void SaveFileManager::DeleteDirectoryOrFile(const base::FilePath& full_path, |
| 193 bool is_dir) { | 193 bool is_dir) { |
| 194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 194 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 195 BrowserThread::PostTask( | 195 BrowserThread::PostTask( |
| 196 BrowserThread::FILE, FROM_HERE, | 196 BrowserThread::FILE, FROM_HERE, |
| 197 base::Bind(&SaveFileManager::OnDeleteDirectoryOrFile, | 197 base::Bind(&SaveFileManager::OnDeleteDirectoryOrFile, |
| 198 this, full_path, is_dir)); | 198 this, full_path, is_dir)); |
| 199 } | 199 } |
| 200 | 200 |
| 201 void SaveFileManager::SendCancelRequest(int save_id) { | 201 void SaveFileManager::SendCancelRequest(int save_id) { |
| 202 // Cancel the request which has specific save id. | 202 // Cancel the request which has specific save id. |
| 203 DCHECK_GT(save_id, -1); | 203 DCHECK_GT(save_id, -1); |
| 204 BrowserThread::PostTask( | 204 BrowserThread::PostTask( |
| 205 BrowserThread::FILE, FROM_HERE, | 205 BrowserThread::FILE, FROM_HERE, |
| 206 base::Bind(&SaveFileManager::CancelSave, this, save_id)); | 206 base::Bind(&SaveFileManager::CancelSave, this, save_id)); |
| 207 } | 207 } |
| 208 | 208 |
| 209 // Notifications sent from the IO thread and run on the file thread: | 209 // Notifications sent from the IO thread and run on the file thread: |
| 210 | 210 |
| 211 // The IO thread created |info|, but the file thread (this method) uses it | 211 // The IO thread created |info|, but the file thread (this method) uses it |
| 212 // to create a SaveFile which will hold and finally destroy |info|. It will | 212 // to create a SaveFile which will hold and finally destroy |info|. It will |
| 213 // then passes |info| to the UI thread for reporting saving status. | 213 // then passes |info| to the UI thread for reporting saving status. |
| 214 void SaveFileManager::StartSave(SaveFileCreateInfo* info) { | 214 void SaveFileManager::StartSave(SaveFileCreateInfo* info) { |
| 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 215 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 216 DCHECK(info); | 216 DCHECK(info); |
| 217 // No need to calculate hash. | 217 // No need to calculate hash. |
| 218 SaveFile* save_file = new SaveFile(info, false); | 218 SaveFile* save_file = new SaveFile(info, false); |
| 219 | 219 |
| 220 // TODO(phajdan.jr): We should check the return value and handle errors here. | 220 // TODO(phajdan.jr): We should check the return value and handle errors here. |
| 221 save_file->Initialize(); | 221 save_file->Initialize(); |
| 222 | 222 |
| 223 DCHECK(!LookupSaveFile(info->save_id)); | 223 DCHECK(!LookupSaveFile(info->save_id)); |
| 224 save_file_map_[info->save_id] = save_file; | 224 save_file_map_[info->save_id] = save_file; |
| 225 info->path = save_file->FullPath(); | 225 info->path = save_file->FullPath(); |
| 226 | 226 |
| 227 BrowserThread::PostTask( | 227 BrowserThread::PostTask( |
| 228 BrowserThread::UI, FROM_HERE, | 228 BrowserThread::UI, FROM_HERE, |
| 229 base::Bind(&SaveFileManager::OnStartSave, this, info)); | 229 base::Bind(&SaveFileManager::OnStartSave, this, info)); |
| 230 } | 230 } |
| 231 | 231 |
| 232 // We do forward an update to the UI thread here, since we do not use timer to | 232 // We do forward an update to the UI thread here, since we do not use timer to |
| 233 // update the UI. If the user has canceled the saving action (in the UI | 233 // update the UI. If the user has canceled the saving action (in the UI |
| 234 // thread). We may receive a few more updates before the IO thread gets the | 234 // thread). We may receive a few more updates before the IO thread gets the |
| 235 // cancel message. We just delete the data since the SaveFile has been deleted. | 235 // cancel message. We just delete the data since the SaveFile has been deleted. |
| 236 void SaveFileManager::UpdateSaveProgress(int save_id, | 236 void SaveFileManager::UpdateSaveProgress(int save_id, |
| 237 net::IOBuffer* data, | 237 net::IOBuffer* data, |
| 238 int data_len) { | 238 int data_len) { |
| 239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 239 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 240 SaveFile* save_file = LookupSaveFile(save_id); | 240 SaveFile* save_file = LookupSaveFile(save_id); |
| 241 if (save_file) { | 241 if (save_file) { |
| 242 DCHECK(save_file->InProgress()); | 242 DCHECK(save_file->InProgress()); |
| 243 | 243 |
| 244 DownloadInterruptReason reason = | 244 DownloadInterruptReason reason = |
| 245 save_file->AppendDataToFile(data->data(), data_len); | 245 save_file->AppendDataToFile(data->data(), data_len); |
| 246 BrowserThread::PostTask( | 246 BrowserThread::PostTask( |
| 247 BrowserThread::UI, FROM_HERE, | 247 BrowserThread::UI, FROM_HERE, |
| 248 base::Bind(&SaveFileManager::OnUpdateSaveProgress, | 248 base::Bind(&SaveFileManager::OnUpdateSaveProgress, |
| 249 this, | 249 this, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 260 // thread, which will use the save URL to find corresponding request record and | 260 // thread, which will use the save URL to find corresponding request record and |
| 261 // delete it. | 261 // delete it. |
| 262 void SaveFileManager::SaveFinished(int save_id, | 262 void SaveFileManager::SaveFinished(int save_id, |
| 263 const GURL& save_url, | 263 const GURL& save_url, |
| 264 int render_process_id, | 264 int render_process_id, |
| 265 bool is_success) { | 265 bool is_success) { |
| 266 DVLOG(20) << " " << __FUNCTION__ << "()" | 266 DVLOG(20) << " " << __FUNCTION__ << "()" |
| 267 << " save_id = " << save_id | 267 << " save_id = " << save_id |
| 268 << " save_url = \"" << save_url.spec() << "\"" | 268 << " save_url = \"" << save_url.spec() << "\"" |
| 269 << " is_success = " << is_success; | 269 << " is_success = " << is_success; |
| 270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 270 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 271 SaveFileMap::iterator it = save_file_map_.find(save_id); | 271 SaveFileMap::iterator it = save_file_map_.find(save_id); |
| 272 if (it != save_file_map_.end()) { | 272 if (it != save_file_map_.end()) { |
| 273 SaveFile* save_file = it->second; | 273 SaveFile* save_file = it->second; |
| 274 // This routine may be called twice for the same from from | 274 // This routine may be called twice for the same from from |
| 275 // SaveePackage::OnReceivedSerializedHtmlData, once for the file | 275 // SaveePackage::OnReceivedSerializedHtmlData, once for the file |
| 276 // itself, and once when all frames have been serialized. | 276 // itself, and once when all frames have been serialized. |
| 277 // So we can't assert that the file is InProgress() here. | 277 // So we can't assert that the file is InProgress() here. |
| 278 // TODO(rdsmith): Fix this logic and put the DCHECK below back in. | 278 // TODO(rdsmith): Fix this logic and put the DCHECK below back in. |
| 279 // DCHECK(save_file->InProgress()); | 279 // DCHECK(save_file->InProgress()); |
| 280 | 280 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 293 BrowserThread::PostTask( | 293 BrowserThread::PostTask( |
| 294 BrowserThread::UI, FROM_HERE, | 294 BrowserThread::UI, FROM_HERE, |
| 295 base::Bind(&SaveFileManager::OnErrorFinished, this, save_url, | 295 base::Bind(&SaveFileManager::OnErrorFinished, this, save_url, |
| 296 render_process_id)); | 296 render_process_id)); |
| 297 } | 297 } |
| 298 } | 298 } |
| 299 | 299 |
| 300 // Notifications sent from the file thread and run on the UI thread. | 300 // Notifications sent from the file thread and run on the UI thread. |
| 301 | 301 |
| 302 void SaveFileManager::OnStartSave(const SaveFileCreateInfo* info) { | 302 void SaveFileManager::OnStartSave(const SaveFileCreateInfo* info) { |
| 303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 303 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 304 SavePackage* save_package = | 304 SavePackage* save_package = |
| 305 GetSavePackageFromRenderIds(info->render_process_id, | 305 GetSavePackageFromRenderIds(info->render_process_id, |
| 306 info->render_view_id); | 306 info->render_view_id); |
| 307 if (!save_package) { | 307 if (!save_package) { |
| 308 // Cancel this request. | 308 // Cancel this request. |
| 309 SendCancelRequest(info->save_id); | 309 SendCancelRequest(info->save_id); |
| 310 return; | 310 return; |
| 311 } | 311 } |
| 312 | 312 |
| 313 // Insert started saving job to tracking list. | 313 // Insert started saving job to tracking list. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 327 } else { | 327 } else { |
| 328 NOTREACHED(); | 328 NOTREACHED(); |
| 329 } | 329 } |
| 330 | 330 |
| 331 // Forward this message to SavePackage. | 331 // Forward this message to SavePackage. |
| 332 save_package->StartSave(info); | 332 save_package->StartSave(info); |
| 333 } | 333 } |
| 334 | 334 |
| 335 void SaveFileManager::OnUpdateSaveProgress(int save_id, int64 bytes_so_far, | 335 void SaveFileManager::OnUpdateSaveProgress(int save_id, int64 bytes_so_far, |
| 336 bool write_success) { | 336 bool write_success) { |
| 337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 337 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 338 SavePackage* package = LookupPackage(save_id); | 338 SavePackage* package = LookupPackage(save_id); |
| 339 if (package) | 339 if (package) |
| 340 package->UpdateSaveProgress(save_id, bytes_so_far, write_success); | 340 package->UpdateSaveProgress(save_id, bytes_so_far, write_success); |
| 341 else | 341 else |
| 342 SendCancelRequest(save_id); | 342 SendCancelRequest(save_id); |
| 343 } | 343 } |
| 344 | 344 |
| 345 void SaveFileManager::OnSaveFinished(int save_id, | 345 void SaveFileManager::OnSaveFinished(int save_id, |
| 346 int64 bytes_so_far, | 346 int64 bytes_so_far, |
| 347 bool is_success) { | 347 bool is_success) { |
| 348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 348 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 349 SavePackage* package = LookupPackage(save_id); | 349 SavePackage* package = LookupPackage(save_id); |
| 350 if (package) | 350 if (package) |
| 351 package->SaveFinished(save_id, bytes_so_far, is_success); | 351 package->SaveFinished(save_id, bytes_so_far, is_success); |
| 352 } | 352 } |
| 353 | 353 |
| 354 void SaveFileManager::OnErrorFinished(const GURL& save_url, int contents_id) { | 354 void SaveFileManager::OnErrorFinished(const GURL& save_url, int contents_id) { |
| 355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 355 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 356 SavePackage* save_package = UnregisterStartingRequest(save_url, contents_id); | 356 SavePackage* save_package = UnregisterStartingRequest(save_url, contents_id); |
| 357 if (save_package) | 357 if (save_package) |
| 358 save_package->SaveFailed(save_url); | 358 save_package->SaveFailed(save_url); |
| 359 } | 359 } |
| 360 | 360 |
| 361 // Notifications sent from the UI thread and run on the IO thread. | 361 // Notifications sent from the UI thread and run on the IO thread. |
| 362 | 362 |
| 363 void SaveFileManager::OnSaveURL( | 363 void SaveFileManager::OnSaveURL( |
| 364 const GURL& url, | 364 const GURL& url, |
| 365 const Referrer& referrer, | 365 const Referrer& referrer, |
| 366 int render_process_host_id, | 366 int render_process_host_id, |
| 367 int render_view_id, | 367 int render_view_id, |
| 368 ResourceContext* context) { | 368 ResourceContext* context) { |
| 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 369 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 370 ResourceDispatcherHostImpl::Get()->BeginSaveFile(url, | 370 ResourceDispatcherHostImpl::Get()->BeginSaveFile(url, |
| 371 referrer, | 371 referrer, |
| 372 render_process_host_id, | 372 render_process_host_id, |
| 373 render_view_id, | 373 render_view_id, |
| 374 context); | 374 context); |
| 375 } | 375 } |
| 376 | 376 |
| 377 void SaveFileManager::OnRequireSaveJobFromOtherSource( | 377 void SaveFileManager::OnRequireSaveJobFromOtherSource( |
| 378 SaveFileCreateInfo* info) { | 378 SaveFileCreateInfo* info) { |
| 379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 379 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 380 DCHECK_EQ(info->save_id, -1); | 380 DCHECK_EQ(info->save_id, -1); |
| 381 // Generate a unique save id. | 381 // Generate a unique save id. |
| 382 info->save_id = GetNextId(); | 382 info->save_id = GetNextId(); |
| 383 // Start real saving action. | 383 // Start real saving action. |
| 384 BrowserThread::PostTask( | 384 BrowserThread::PostTask( |
| 385 BrowserThread::FILE, FROM_HERE, | 385 BrowserThread::FILE, FROM_HERE, |
| 386 base::Bind(&SaveFileManager::StartSave, this, info)); | 386 base::Bind(&SaveFileManager::StartSave, this, info)); |
| 387 } | 387 } |
| 388 | 388 |
| 389 void SaveFileManager::ExecuteCancelSaveRequest(int render_process_id, | 389 void SaveFileManager::ExecuteCancelSaveRequest(int render_process_id, |
| 390 int request_id) { | 390 int request_id) { |
| 391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 391 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 392 ResourceDispatcherHostImpl::Get()->CancelRequest( | 392 ResourceDispatcherHostImpl::Get()->CancelRequest( |
| 393 render_process_id, request_id); | 393 render_process_id, request_id); |
| 394 } | 394 } |
| 395 | 395 |
| 396 // Notifications sent from the UI thread and run on the file thread. | 396 // Notifications sent from the UI thread and run on the file thread. |
| 397 | 397 |
| 398 // This method will be sent via a user action, or shutdown on the UI thread, | 398 // This method will be sent via a user action, or shutdown on the UI thread, |
| 399 // and run on the file thread. We don't post a message back for cancels, | 399 // and run on the file thread. We don't post a message back for cancels, |
| 400 // but we do forward the cancel to the IO thread. Since this message has been | 400 // but we do forward the cancel to the IO thread. Since this message has been |
| 401 // sent from the UI thread, the saving job may have already completed and | 401 // sent from the UI thread, the saving job may have already completed and |
| 402 // won't exist in our map. | 402 // won't exist in our map. |
| 403 void SaveFileManager::CancelSave(int save_id) { | 403 void SaveFileManager::CancelSave(int save_id) { |
| 404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 404 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 405 SaveFileMap::iterator it = save_file_map_.find(save_id); | 405 SaveFileMap::iterator it = save_file_map_.find(save_id); |
| 406 if (it != save_file_map_.end()) { | 406 if (it != save_file_map_.end()) { |
| 407 SaveFile* save_file = it->second; | 407 SaveFile* save_file = it->second; |
| 408 | 408 |
| 409 if (!save_file->InProgress()) { | 409 if (!save_file->InProgress()) { |
| 410 // We've won a race with the UI thread--we finished the file before | 410 // We've won a race with the UI thread--we finished the file before |
| 411 // the UI thread cancelled it on us. Unfortunately, in this situation | 411 // the UI thread cancelled it on us. Unfortunately, in this situation |
| 412 // the cancel wins, so we need to delete the now detached file. | 412 // the cancel wins, so we need to delete the now detached file. |
| 413 base::DeleteFile(save_file->FullPath(), false); | 413 base::DeleteFile(save_file->FullPath(), false); |
| 414 } else if (save_file->save_source() == | 414 } else if (save_file->save_source() == |
| (...skipping 14 matching lines...) Expand all Loading... |
| 429 delete save_file; | 429 delete save_file; |
| 430 } | 430 } |
| 431 } | 431 } |
| 432 | 432 |
| 433 // It is possible that SaveItem which has specified save_id has been canceled | 433 // It is possible that SaveItem which has specified save_id has been canceled |
| 434 // before this function runs. So if we can not find corresponding SaveFile by | 434 // before this function runs. So if we can not find corresponding SaveFile by |
| 435 // using specified save_id, just return. | 435 // using specified save_id, just return. |
| 436 void SaveFileManager::SaveLocalFile(const GURL& original_file_url, | 436 void SaveFileManager::SaveLocalFile(const GURL& original_file_url, |
| 437 int save_id, | 437 int save_id, |
| 438 int render_process_id) { | 438 int render_process_id) { |
| 439 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 439 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 440 SaveFile* save_file = LookupSaveFile(save_id); | 440 SaveFile* save_file = LookupSaveFile(save_id); |
| 441 if (!save_file) | 441 if (!save_file) |
| 442 return; | 442 return; |
| 443 // If it has finished, just return. | 443 // If it has finished, just return. |
| 444 if (!save_file->InProgress()) | 444 if (!save_file->InProgress()) |
| 445 return; | 445 return; |
| 446 | 446 |
| 447 // Close the save file before the copy operation. | 447 // Close the save file before the copy operation. |
| 448 save_file->Finish(); | 448 save_file->Finish(); |
| 449 save_file->Detach(); | 449 save_file->Detach(); |
| 450 | 450 |
| 451 DCHECK(original_file_url.SchemeIsFile()); | 451 DCHECK(original_file_url.SchemeIsFile()); |
| 452 base::FilePath file_path; | 452 base::FilePath file_path; |
| 453 net::FileURLToFilePath(original_file_url, &file_path); | 453 net::FileURLToFilePath(original_file_url, &file_path); |
| 454 // If we can not get valid file path from original URL, treat it as | 454 // If we can not get valid file path from original URL, treat it as |
| 455 // disk error. | 455 // disk error. |
| 456 if (file_path.empty()) | 456 if (file_path.empty()) |
| 457 SaveFinished(save_id, original_file_url, render_process_id, false); | 457 SaveFinished(save_id, original_file_url, render_process_id, false); |
| 458 | 458 |
| 459 // Copy the local file to the temporary file. It will be renamed to its | 459 // Copy the local file to the temporary file. It will be renamed to its |
| 460 // final name later. | 460 // final name later. |
| 461 bool success = base::CopyFile(file_path, save_file->FullPath()); | 461 bool success = base::CopyFile(file_path, save_file->FullPath()); |
| 462 if (!success) | 462 if (!success) |
| 463 base::DeleteFile(save_file->FullPath(), false); | 463 base::DeleteFile(save_file->FullPath(), false); |
| 464 SaveFinished(save_id, original_file_url, render_process_id, success); | 464 SaveFinished(save_id, original_file_url, render_process_id, success); |
| 465 } | 465 } |
| 466 | 466 |
| 467 void SaveFileManager::OnDeleteDirectoryOrFile(const base::FilePath& full_path, | 467 void SaveFileManager::OnDeleteDirectoryOrFile(const base::FilePath& full_path, |
| 468 bool is_dir) { | 468 bool is_dir) { |
| 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 469 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 470 DCHECK(!full_path.empty()); | 470 DCHECK(!full_path.empty()); |
| 471 | 471 |
| 472 base::DeleteFile(full_path, is_dir); | 472 base::DeleteFile(full_path, is_dir); |
| 473 } | 473 } |
| 474 | 474 |
| 475 void SaveFileManager::RenameAllFiles( | 475 void SaveFileManager::RenameAllFiles( |
| 476 const FinalNameList& final_names, | 476 const FinalNameList& final_names, |
| 477 const base::FilePath& resource_dir, | 477 const base::FilePath& resource_dir, |
| 478 int render_process_id, | 478 int render_process_id, |
| 479 int render_view_id, | 479 int render_view_id, |
| 480 int save_package_id) { | 480 int save_package_id) { |
| 481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 481 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 482 | 482 |
| 483 if (!resource_dir.empty() && !base::PathExists(resource_dir)) | 483 if (!resource_dir.empty() && !base::PathExists(resource_dir)) |
| 484 base::CreateDirectory(resource_dir); | 484 base::CreateDirectory(resource_dir); |
| 485 | 485 |
| 486 for (FinalNameList::const_iterator i = final_names.begin(); | 486 for (FinalNameList::const_iterator i = final_names.begin(); |
| 487 i != final_names.end(); ++i) { | 487 i != final_names.end(); ++i) { |
| 488 SaveFileMap::iterator it = save_file_map_.find(i->first); | 488 SaveFileMap::iterator it = save_file_map_.find(i->first); |
| 489 if (it != save_file_map_.end()) { | 489 if (it != save_file_map_.end()) { |
| 490 SaveFile* save_file = it->second; | 490 SaveFile* save_file = it->second; |
| 491 DCHECK(!save_file->InProgress()); | 491 DCHECK(!save_file->InProgress()); |
| 492 save_file->Rename(i->second); | 492 save_file->Rename(i->second); |
| 493 delete save_file; | 493 delete save_file; |
| 494 save_file_map_.erase(it); | 494 save_file_map_.erase(it); |
| 495 } | 495 } |
| 496 } | 496 } |
| 497 | 497 |
| 498 BrowserThread::PostTask( | 498 BrowserThread::PostTask( |
| 499 BrowserThread::UI, FROM_HERE, | 499 BrowserThread::UI, FROM_HERE, |
| 500 base::Bind(&SaveFileManager::OnFinishSavePageJob, this, | 500 base::Bind(&SaveFileManager::OnFinishSavePageJob, this, |
| 501 render_process_id, render_view_id, save_package_id)); | 501 render_process_id, render_view_id, save_package_id)); |
| 502 } | 502 } |
| 503 | 503 |
| 504 void SaveFileManager::OnFinishSavePageJob(int render_process_id, | 504 void SaveFileManager::OnFinishSavePageJob(int render_process_id, |
| 505 int render_view_id, | 505 int render_view_id, |
| 506 int save_package_id) { | 506 int save_package_id) { |
| 507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 507 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 508 | 508 |
| 509 SavePackage* save_package = | 509 SavePackage* save_package = |
| 510 GetSavePackageFromRenderIds(render_process_id, render_view_id); | 510 GetSavePackageFromRenderIds(render_process_id, render_view_id); |
| 511 | 511 |
| 512 if (save_package && save_package->id() == save_package_id) | 512 if (save_package && save_package->id() == save_package_id) |
| 513 save_package->Finish(); | 513 save_package->Finish(); |
| 514 } | 514 } |
| 515 | 515 |
| 516 void SaveFileManager::RemoveSavedFileFromFileMap( | 516 void SaveFileManager::RemoveSavedFileFromFileMap( |
| 517 const SaveIDList& save_ids) { | 517 const SaveIDList& save_ids) { |
| 518 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 518 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 519 | 519 |
| 520 for (SaveIDList::const_iterator i = save_ids.begin(); | 520 for (SaveIDList::const_iterator i = save_ids.begin(); |
| 521 i != save_ids.end(); ++i) { | 521 i != save_ids.end(); ++i) { |
| 522 SaveFileMap::iterator it = save_file_map_.find(*i); | 522 SaveFileMap::iterator it = save_file_map_.find(*i); |
| 523 if (it != save_file_map_.end()) { | 523 if (it != save_file_map_.end()) { |
| 524 SaveFile* save_file = it->second; | 524 SaveFile* save_file = it->second; |
| 525 DCHECK(!save_file->InProgress()); | 525 DCHECK(!save_file->InProgress()); |
| 526 base::DeleteFile(save_file->FullPath(), false); | 526 base::DeleteFile(save_file->FullPath(), false); |
| 527 delete save_file; | 527 delete save_file; |
| 528 save_file_map_.erase(it); | 528 save_file_map_.erase(it); |
| 529 } | 529 } |
| 530 } | 530 } |
| 531 } | 531 } |
| 532 | 532 |
| 533 } // namespace content | 533 } // namespace content |
| OLD | NEW |