| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 void SaveFileManager::StartSave(SaveFileCreateInfo* info) { | 213 void SaveFileManager::StartSave(SaveFileCreateInfo* info) { |
| 214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 215 DCHECK(info); | 215 DCHECK(info); |
| 216 SaveFile* save_file = new SaveFile(info); | 216 SaveFile* save_file = new SaveFile(info); |
| 217 | 217 |
| 218 // TODO(phajdan.jr): We should check the return value and handle errors here. | 218 // TODO(phajdan.jr): We should check the return value and handle errors here. |
| 219 save_file->Initialize(false); // No need to calculate hash. | 219 save_file->Initialize(false); // No need to calculate hash. |
| 220 | 220 |
| 221 DCHECK(!LookupSaveFile(info->save_id)); | 221 DCHECK(!LookupSaveFile(info->save_id)); |
| 222 save_file_map_[info->save_id] = save_file; | 222 save_file_map_[info->save_id] = save_file; |
| 223 info->path = save_file->full_path(); | 223 info->path = save_file->FullPath(); |
| 224 | 224 |
| 225 BrowserThread::PostTask( | 225 BrowserThread::PostTask( |
| 226 BrowserThread::UI, FROM_HERE, | 226 BrowserThread::UI, FROM_HERE, |
| 227 base::Bind(&SaveFileManager::OnStartSave, this, info)); | 227 base::Bind(&SaveFileManager::OnStartSave, this, info)); |
| 228 } | 228 } |
| 229 | 229 |
| 230 // We do forward an update to the UI thread here, since we do not use timer to | 230 // We do forward an update to the UI thread here, since we do not use timer to |
| 231 // update the UI. If the user has canceled the saving action (in the UI | 231 // update the UI. If the user has canceled the saving action (in the UI |
| 232 // thread). We may receive a few more updates before the IO thread gets the | 232 // thread). We may receive a few more updates before the IO thread gets the |
| 233 // cancel message. We just delete the data since the SaveFile has been deleted. | 233 // cancel message. We just delete the data since the SaveFile has been deleted. |
| 234 void SaveFileManager::UpdateSaveProgress(int save_id, | 234 void SaveFileManager::UpdateSaveProgress(int save_id, |
| 235 net::IOBuffer* data, | 235 net::IOBuffer* data, |
| 236 int data_len) { | 236 int data_len) { |
| 237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 238 SaveFile* save_file = LookupSaveFile(save_id); | 238 SaveFile* save_file = LookupSaveFile(save_id); |
| 239 if (save_file) { | 239 if (save_file) { |
| 240 net::Error write_success = | 240 net::Error write_success = |
| 241 save_file->AppendDataToFile(data->data(), data_len); | 241 save_file->AppendDataToFile(data->data(), data_len); |
| 242 BrowserThread::PostTask( | 242 BrowserThread::PostTask( |
| 243 BrowserThread::UI, FROM_HERE, | 243 BrowserThread::UI, FROM_HERE, |
| 244 base::Bind(&SaveFileManager::OnUpdateSaveProgress, | 244 base::Bind(&SaveFileManager::OnUpdateSaveProgress, |
| 245 this, | 245 this, |
| 246 save_file->save_id(), | 246 save_file->save_id(), |
| 247 save_file->bytes_so_far(), | 247 save_file->BytesSoFar(), |
| 248 write_success == net::OK)); | 248 write_success == net::OK)); |
| 249 } | 249 } |
| 250 } | 250 } |
| 251 | 251 |
| 252 // The IO thread will call this when saving is completed or it got error when | 252 // The IO thread will call this when saving is completed or it got error when |
| 253 // fetching data. In the former case, we forward the message to OnSaveFinished | 253 // fetching data. In the former case, we forward the message to OnSaveFinished |
| 254 // in UI thread. In the latter case, the save ID will be -1, which means the | 254 // in UI thread. In the latter case, the save ID will be -1, which means the |
| 255 // saving action did not even start, so we need to call OnErrorFinished in UI | 255 // saving action did not even start, so we need to call OnErrorFinished in UI |
| 256 // thread, which will use the save URL to find corresponding request record and | 256 // thread, which will use the save URL to find corresponding request record and |
| 257 // delete it. | 257 // delete it. |
| 258 void SaveFileManager::SaveFinished(int save_id, | 258 void SaveFileManager::SaveFinished(int save_id, |
| 259 const GURL& save_url, | 259 const GURL& save_url, |
| 260 int render_process_id, | 260 int render_process_id, |
| 261 bool is_success) { | 261 bool is_success) { |
| 262 VLOG(20) << " " << __FUNCTION__ << "()" | 262 VLOG(20) << " " << __FUNCTION__ << "()" |
| 263 << " save_id = " << save_id | 263 << " save_id = " << save_id |
| 264 << " save_url = \"" << save_url.spec() << "\"" | 264 << " save_url = \"" << save_url.spec() << "\"" |
| 265 << " is_success = " << is_success; | 265 << " is_success = " << is_success; |
| 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 267 SaveFileMap::iterator it = save_file_map_.find(save_id); | 267 SaveFileMap::iterator it = save_file_map_.find(save_id); |
| 268 if (it != save_file_map_.end()) { | 268 if (it != save_file_map_.end()) { |
| 269 SaveFile* save_file = it->second; | 269 SaveFile* save_file = it->second; |
| 270 VLOG(20) << " " << __FUNCTION__ << "()" | 270 VLOG(20) << " " << __FUNCTION__ << "()" |
| 271 << " save_file = " << save_file->DebugString(); | 271 << " save_file = " << save_file->DebugString(); |
| 272 BrowserThread::PostTask( | 272 BrowserThread::PostTask( |
| 273 BrowserThread::UI, FROM_HERE, | 273 BrowserThread::UI, FROM_HERE, |
| 274 base::Bind(&SaveFileManager::OnSaveFinished, this, save_id, | 274 base::Bind(&SaveFileManager::OnSaveFinished, this, save_id, |
| 275 save_file->bytes_so_far(), is_success)); | 275 save_file->BytesSoFar(), is_success)); |
| 276 | 276 |
| 277 save_file->Finish(); | 277 save_file->Finish(); |
| 278 save_file->Detach(); | 278 save_file->Detach(); |
| 279 } else if (save_id == -1) { | 279 } else if (save_id == -1) { |
| 280 // Before saving started, we got error. We still call finish process. | 280 // Before saving started, we got error. We still call finish process. |
| 281 DCHECK(!save_url.is_empty()); | 281 DCHECK(!save_url.is_empty()); |
| 282 BrowserThread::PostTask( | 282 BrowserThread::PostTask( |
| 283 BrowserThread::UI, FROM_HERE, | 283 BrowserThread::UI, FROM_HERE, |
| 284 base::Bind(&SaveFileManager::OnErrorFinished, this, save_url, | 284 base::Bind(&SaveFileManager::OnErrorFinished, this, save_url, |
| 285 render_process_id)); | 285 render_process_id)); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 save_file->render_process_id(), save_file->request_id())); | 406 save_file->render_process_id(), save_file->request_id())); |
| 407 | 407 |
| 408 // UI thread will notify the render process to stop sending data, | 408 // UI thread will notify the render process to stop sending data, |
| 409 // so in here, we need not to do anything, just close the save file. | 409 // so in here, we need not to do anything, just close the save file. |
| 410 save_file->Cancel(); | 410 save_file->Cancel(); |
| 411 } else { | 411 } else { |
| 412 // If we did not find SaveFile in map, the saving job should either get | 412 // If we did not find SaveFile in map, the saving job should either get |
| 413 // data from other sources or have finished. | 413 // data from other sources or have finished. |
| 414 DCHECK(save_file->save_source() != | 414 DCHECK(save_file->save_source() != |
| 415 SaveFileCreateInfo::SAVE_FILE_FROM_NET || | 415 SaveFileCreateInfo::SAVE_FILE_FROM_NET || |
| 416 !save_file->in_progress()); | 416 !save_file->InProgress()); |
| 417 } | 417 } |
| 418 // Whatever the save file is renamed or not, just delete it. | 418 // Whatever the save file is renamed or not, just delete it. |
| 419 save_file_map_.erase(it); | 419 save_file_map_.erase(it); |
| 420 delete save_file; | 420 delete save_file; |
| 421 } | 421 } |
| 422 } | 422 } |
| 423 | 423 |
| 424 // It is possible that SaveItem which has specified save_id has been canceled | 424 // It is possible that SaveItem which has specified save_id has been canceled |
| 425 // before this function runs. So if we can not find corresponding SaveFile by | 425 // before this function runs. So if we can not find corresponding SaveFile by |
| 426 // using specified save_id, just return. | 426 // using specified save_id, just return. |
| 427 void SaveFileManager::SaveLocalFile(const GURL& original_file_url, | 427 void SaveFileManager::SaveLocalFile(const GURL& original_file_url, |
| 428 int save_id, | 428 int save_id, |
| 429 int render_process_id) { | 429 int render_process_id) { |
| 430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 431 SaveFile* save_file = LookupSaveFile(save_id); | 431 SaveFile* save_file = LookupSaveFile(save_id); |
| 432 if (!save_file) | 432 if (!save_file) |
| 433 return; | 433 return; |
| 434 // If it has finished, just return. | 434 // If it has finished, just return. |
| 435 if (!save_file->in_progress()) | 435 if (!save_file->InProgress()) |
| 436 return; | 436 return; |
| 437 | 437 |
| 438 // Close the save file before the copy operation. | 438 // Close the save file before the copy operation. |
| 439 save_file->Finish(); | 439 save_file->Finish(); |
| 440 save_file->Detach(); | 440 save_file->Detach(); |
| 441 | 441 |
| 442 DCHECK(original_file_url.SchemeIsFile()); | 442 DCHECK(original_file_url.SchemeIsFile()); |
| 443 FilePath file_path; | 443 FilePath file_path; |
| 444 net::FileURLToFilePath(original_file_url, &file_path); | 444 net::FileURLToFilePath(original_file_url, &file_path); |
| 445 // If we can not get valid file path from original URL, treat it as | 445 // If we can not get valid file path from original URL, treat it as |
| 446 // disk error. | 446 // disk error. |
| 447 if (file_path.empty()) | 447 if (file_path.empty()) |
| 448 SaveFinished(save_id, original_file_url, render_process_id, false); | 448 SaveFinished(save_id, original_file_url, render_process_id, false); |
| 449 | 449 |
| 450 // Copy the local file to the temporary file. It will be renamed to its | 450 // Copy the local file to the temporary file. It will be renamed to its |
| 451 // final name later. | 451 // final name later. |
| 452 bool success = file_util::CopyFile(file_path, save_file->full_path()); | 452 bool success = file_util::CopyFile(file_path, save_file->FullPath()); |
| 453 if (!success) | 453 if (!success) |
| 454 file_util::Delete(save_file->full_path(), false); | 454 file_util::Delete(save_file->FullPath(), false); |
| 455 SaveFinished(save_id, original_file_url, render_process_id, success); | 455 SaveFinished(save_id, original_file_url, render_process_id, success); |
| 456 } | 456 } |
| 457 | 457 |
| 458 void SaveFileManager::OnDeleteDirectoryOrFile(const FilePath& full_path, | 458 void SaveFileManager::OnDeleteDirectoryOrFile(const FilePath& full_path, |
| 459 bool is_dir) { | 459 bool is_dir) { |
| 460 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 460 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 461 DCHECK(!full_path.empty()); | 461 DCHECK(!full_path.empty()); |
| 462 | 462 |
| 463 file_util::Delete(full_path, is_dir); | 463 file_util::Delete(full_path, is_dir); |
| 464 } | 464 } |
| 465 | 465 |
| 466 void SaveFileManager::RenameAllFiles( | 466 void SaveFileManager::RenameAllFiles( |
| 467 const FinalNameList& final_names, | 467 const FinalNameList& final_names, |
| 468 const FilePath& resource_dir, | 468 const FilePath& resource_dir, |
| 469 int render_process_id, | 469 int render_process_id, |
| 470 int render_view_id, | 470 int render_view_id, |
| 471 int save_package_id) { | 471 int save_package_id) { |
| 472 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 472 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 473 | 473 |
| 474 if (!resource_dir.empty() && !file_util::PathExists(resource_dir)) | 474 if (!resource_dir.empty() && !file_util::PathExists(resource_dir)) |
| 475 file_util::CreateDirectory(resource_dir); | 475 file_util::CreateDirectory(resource_dir); |
| 476 | 476 |
| 477 for (FinalNameList::const_iterator i = final_names.begin(); | 477 for (FinalNameList::const_iterator i = final_names.begin(); |
| 478 i != final_names.end(); ++i) { | 478 i != final_names.end(); ++i) { |
| 479 SaveFileMap::iterator it = save_file_map_.find(i->first); | 479 SaveFileMap::iterator it = save_file_map_.find(i->first); |
| 480 if (it != save_file_map_.end()) { | 480 if (it != save_file_map_.end()) { |
| 481 SaveFile* save_file = it->second; | 481 SaveFile* save_file = it->second; |
| 482 DCHECK(!save_file->in_progress()); | 482 DCHECK(!save_file->InProgress()); |
| 483 save_file->Rename(i->second); | 483 save_file->Rename(i->second); |
| 484 delete save_file; | 484 delete save_file; |
| 485 save_file_map_.erase(it); | 485 save_file_map_.erase(it); |
| 486 } | 486 } |
| 487 } | 487 } |
| 488 | 488 |
| 489 BrowserThread::PostTask( | 489 BrowserThread::PostTask( |
| 490 BrowserThread::UI, FROM_HERE, | 490 BrowserThread::UI, FROM_HERE, |
| 491 base::Bind(&SaveFileManager::OnFinishSavePageJob, this, | 491 base::Bind(&SaveFileManager::OnFinishSavePageJob, this, |
| 492 render_process_id, render_view_id, save_package_id)); | 492 render_process_id, render_view_id, save_package_id)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 506 | 506 |
| 507 void SaveFileManager::RemoveSavedFileFromFileMap( | 507 void SaveFileManager::RemoveSavedFileFromFileMap( |
| 508 const SaveIDList& save_ids) { | 508 const SaveIDList& save_ids) { |
| 509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 510 | 510 |
| 511 for (SaveIDList::const_iterator i = save_ids.begin(); | 511 for (SaveIDList::const_iterator i = save_ids.begin(); |
| 512 i != save_ids.end(); ++i) { | 512 i != save_ids.end(); ++i) { |
| 513 SaveFileMap::iterator it = save_file_map_.find(*i); | 513 SaveFileMap::iterator it = save_file_map_.find(*i); |
| 514 if (it != save_file_map_.end()) { | 514 if (it != save_file_map_.end()) { |
| 515 SaveFile* save_file = it->second; | 515 SaveFile* save_file = it->second; |
| 516 DCHECK(!save_file->in_progress()); | 516 DCHECK(!save_file->InProgress()); |
| 517 file_util::Delete(save_file->full_path(), false); | 517 file_util::Delete(save_file->FullPath(), false); |
| 518 delete save_file; | 518 delete save_file; |
| 519 save_file_map_.erase(it); | 519 save_file_map_.erase(it); |
| 520 } | 520 } |
| 521 } | 521 } |
| 522 } | 522 } |
| OLD | NEW |