Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: chrome/browser/download/save_file_manager.cc

Issue 172074: Show or open downloaded items on the UI thread for Mac (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/download/save_file_manager.h ('k') | chrome/browser/download/save_package.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "chrome/browser/download/save_file_manager.h" 7 #include "chrome/browser/download/save_file_manager.h"
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 } 49 }
50 50
51 SaveFileManager::~SaveFileManager() { 51 SaveFileManager::~SaveFileManager() {
52 // Check for clean shutdown. 52 // Check for clean shutdown.
53 DCHECK(save_file_map_.empty()); 53 DCHECK(save_file_map_.empty());
54 } 54 }
55 55
56 // Called during the browser shutdown process to clean up any state (open files, 56 // Called during the browser shutdown process to clean up any state (open files,
57 // timers) that live on the saving thread (file thread). 57 // timers) that live on the saving thread (file thread).
58 void SaveFileManager::Shutdown() { 58 void SaveFileManager::Shutdown() {
59 MessageLoop* loop = GetSaveLoop(); 59 MessageLoop* loop = file_loop();
60 if (loop) { 60 if (loop) {
61 loop->PostTask(FROM_HERE, 61 loop->PostTask(FROM_HERE,
62 NewRunnableMethod(this, &SaveFileManager::OnShutdown)); 62 NewRunnableMethod(this, &SaveFileManager::OnShutdown));
63 } 63 }
64 } 64 }
65 65
66 // Stop file thread operations. 66 // Stop file thread operations.
67 void SaveFileManager::OnShutdown() { 67 void SaveFileManager::OnShutdown() {
68 DCHECK(MessageLoop::current() == GetSaveLoop()); 68 DCHECK(MessageLoop::current() == file_loop());
69 STLDeleteValues(&save_file_map_); 69 STLDeleteValues(&save_file_map_);
70 } 70 }
71 71
72 SaveFile* SaveFileManager::LookupSaveFile(int save_id) { 72 SaveFile* SaveFileManager::LookupSaveFile(int save_id) {
73 SaveFileMap::iterator it = save_file_map_.find(save_id); 73 SaveFileMap::iterator it = save_file_map_.find(save_id);
74 return it == save_file_map_.end() ? NULL : it->second; 74 return it == save_file_map_.end() ? NULL : it->second;
75 } 75 }
76 76
77 // Called on the IO thread when 77 // Called on the IO thread when
78 // a) The ResourceDispatcherHost has decided that a request is savable. 78 // a) The ResourceDispatcherHost has decided that a request is savable.
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 if (contents) 218 if (contents)
219 return contents->save_package(); 219 return contents->save_package();
220 220
221 return NULL; 221 return NULL;
222 } 222 }
223 223
224 // Utility function for deleting specified file. 224 // Utility function for deleting specified file.
225 void SaveFileManager::DeleteDirectoryOrFile(const FilePath& full_path, 225 void SaveFileManager::DeleteDirectoryOrFile(const FilePath& full_path,
226 bool is_dir) { 226 bool is_dir) {
227 DCHECK(MessageLoop::current() == ui_loop_); 227 DCHECK(MessageLoop::current() == ui_loop_);
228 MessageLoop* loop = GetSaveLoop(); 228 MessageLoop* loop = file_loop();
229 DCHECK(loop); 229 DCHECK(loop);
230 loop->PostTask(FROM_HERE, 230 loop->PostTask(FROM_HERE,
231 NewRunnableMethod(this, 231 NewRunnableMethod(this,
232 &SaveFileManager::OnDeleteDirectoryOrFile, 232 &SaveFileManager::OnDeleteDirectoryOrFile,
233 full_path, 233 full_path,
234 is_dir)); 234 is_dir));
235 } 235 }
236 236
237 void SaveFileManager::SendCancelRequest(int save_id) { 237 void SaveFileManager::SendCancelRequest(int save_id) {
238 // Cancel the request which has specific save id. 238 // Cancel the request which has specific save id.
239 DCHECK(save_id > -1); 239 DCHECK(save_id > -1);
240 MessageLoop* loop = GetSaveLoop(); 240 MessageLoop* loop = file_loop();
241 DCHECK(loop); 241 DCHECK(loop);
242 loop->PostTask(FROM_HERE, 242 loop->PostTask(FROM_HERE,
243 NewRunnableMethod(this, 243 NewRunnableMethod(this,
244 &SaveFileManager::CancelSave, 244 &SaveFileManager::CancelSave,
245 save_id)); 245 save_id));
246 } 246 }
247 247
248 // Notifications sent from the IO thread and run on the file thread: 248 // Notifications sent from the IO thread and run on the file thread:
249 249
250 // The IO thread created |info|, but the file thread (this method) uses it 250 // The IO thread created |info|, but the file thread (this method) uses it
251 // to create a SaveFile which will hold and finally destroy |info|. It will 251 // to create a SaveFile which will hold and finally destroy |info|. It will
252 // then passes |info| to the UI thread for reporting saving status. 252 // then passes |info| to the UI thread for reporting saving status.
253 void SaveFileManager::StartSave(SaveFileCreateInfo* info) { 253 void SaveFileManager::StartSave(SaveFileCreateInfo* info) {
254 DCHECK(MessageLoop::current() == GetSaveLoop()); 254 DCHECK(MessageLoop::current() == file_loop());
255 DCHECK(info); 255 DCHECK(info);
256 SaveFile* save_file = new SaveFile(info); 256 SaveFile* save_file = new SaveFile(info);
257 DCHECK(LookupSaveFile(info->save_id) == NULL); 257 DCHECK(LookupSaveFile(info->save_id) == NULL);
258 save_file_map_[info->save_id] = save_file; 258 save_file_map_[info->save_id] = save_file;
259 info->path = save_file->full_path(); 259 info->path = save_file->full_path();
260 260
261 ui_loop_->PostTask(FROM_HERE, 261 ui_loop_->PostTask(FROM_HERE,
262 NewRunnableMethod(this, 262 NewRunnableMethod(this,
263 &SaveFileManager::OnStartSave, 263 &SaveFileManager::OnStartSave,
264 info)); 264 info));
265 } 265 }
266 266
267 // We do forward an update to the UI thread here, since we do not use timer to 267 // We do forward an update to the UI thread here, since we do not use timer to
268 // update the UI. If the user has canceled the saving action (in the UI 268 // update the UI. If the user has canceled the saving action (in the UI
269 // thread). We may receive a few more updates before the IO thread gets the 269 // thread). We may receive a few more updates before the IO thread gets the
270 // cancel message. We just delete the data since the SaveFile has been deleted. 270 // cancel message. We just delete the data since the SaveFile has been deleted.
271 void SaveFileManager::UpdateSaveProgress(int save_id, 271 void SaveFileManager::UpdateSaveProgress(int save_id,
272 net::IOBuffer* data, 272 net::IOBuffer* data,
273 int data_len) { 273 int data_len) {
274 DCHECK(MessageLoop::current() == GetSaveLoop()); 274 DCHECK(MessageLoop::current() == file_loop());
275 SaveFile* save_file = LookupSaveFile(save_id); 275 SaveFile* save_file = LookupSaveFile(save_id);
276 if (save_file) { 276 if (save_file) {
277 bool write_success = save_file->AppendDataToFile(data->data(), data_len); 277 bool write_success = save_file->AppendDataToFile(data->data(), data_len);
278 ui_loop_->PostTask(FROM_HERE, 278 ui_loop_->PostTask(FROM_HERE,
279 NewRunnableMethod(this, 279 NewRunnableMethod(this,
280 &SaveFileManager::OnUpdateSaveProgress, 280 &SaveFileManager::OnUpdateSaveProgress,
281 save_file->save_id(), 281 save_file->save_id(),
282 save_file->bytes_so_far(), 282 save_file->bytes_so_far(),
283 write_success)); 283 write_success));
284 } 284 }
285 data->Release(); 285 data->Release();
286 } 286 }
287 287
288 // The IO thread will call this when saving is completed or it got error when 288 // The IO thread will call this when saving is completed or it got error when
289 // fetching data. In the former case, we forward the message to OnSaveFinished 289 // fetching data. In the former case, we forward the message to OnSaveFinished
290 // in UI thread. In the latter case, the save ID will be -1, which means the 290 // in UI thread. In the latter case, the save ID will be -1, which means the
291 // saving action did not even start, so we need to call OnErrorFinished in UI 291 // saving action did not even start, so we need to call OnErrorFinished in UI
292 // thread, which will use the save URL to find corresponding request record and 292 // thread, which will use the save URL to find corresponding request record and
293 // delete it. 293 // delete it.
294 void SaveFileManager::SaveFinished(int save_id, 294 void SaveFileManager::SaveFinished(int save_id,
295 GURL save_url, 295 GURL save_url,
296 int render_process_id, 296 int render_process_id,
297 bool is_success) { 297 bool is_success) {
298 DCHECK(MessageLoop::current() == GetSaveLoop()); 298 DCHECK(MessageLoop::current() == file_loop());
299 SaveFileMap::iterator it = save_file_map_.find(save_id); 299 SaveFileMap::iterator it = save_file_map_.find(save_id);
300 if (it != save_file_map_.end()) { 300 if (it != save_file_map_.end()) {
301 SaveFile* save_file = it->second; 301 SaveFile* save_file = it->second;
302 ui_loop_->PostTask(FROM_HERE, 302 ui_loop_->PostTask(FROM_HERE,
303 NewRunnableMethod(this, 303 NewRunnableMethod(this,
304 &SaveFileManager::OnSaveFinished, 304 &SaveFileManager::OnSaveFinished,
305 save_id, 305 save_id,
306 save_file->bytes_so_far(), 306 save_file->bytes_so_far(),
307 is_success)); 307 is_success));
308 308
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 request_context); 405 request_context);
406 } 406 }
407 407
408 void SaveFileManager::OnRequireSaveJobFromOtherSource( 408 void SaveFileManager::OnRequireSaveJobFromOtherSource(
409 SaveFileCreateInfo* info) { 409 SaveFileCreateInfo* info) {
410 DCHECK(MessageLoop::current() == io_loop_); 410 DCHECK(MessageLoop::current() == io_loop_);
411 DCHECK(info->save_id == -1); 411 DCHECK(info->save_id == -1);
412 // Generate a unique save id. 412 // Generate a unique save id.
413 info->save_id = GetNextId(); 413 info->save_id = GetNextId();
414 // Start real saving action. 414 // Start real saving action.
415 MessageLoop* loop = GetSaveLoop(); 415 MessageLoop* loop = file_loop();
416 DCHECK(loop); 416 DCHECK(loop);
417 loop->PostTask(FROM_HERE, 417 loop->PostTask(FROM_HERE,
418 NewRunnableMethod(this, 418 NewRunnableMethod(this,
419 &SaveFileManager::StartSave, 419 &SaveFileManager::StartSave,
420 info)); 420 info));
421 } 421 }
422 422
423 void SaveFileManager::ExecuteCancelSaveRequest(int render_process_id, 423 void SaveFileManager::ExecuteCancelSaveRequest(int render_process_id,
424 int request_id) { 424 int request_id) {
425 DCHECK(MessageLoop::current() == io_loop_); 425 DCHECK(MessageLoop::current() == io_loop_);
426 resource_dispatcher_host_->CancelRequest(render_process_id, 426 resource_dispatcher_host_->CancelRequest(render_process_id,
427 request_id, 427 request_id,
428 false); 428 false);
429 } 429 }
430 430
431 // Notifications sent from the UI thread and run on the file thread. 431 // Notifications sent from the UI thread and run on the file thread.
432 432
433 // This method will be sent via a user action, or shutdown on the UI thread, 433 // This method will be sent via a user action, or shutdown on the UI thread,
434 // and run on the file thread. We don't post a message back for cancels, 434 // and run on the file thread. We don't post a message back for cancels,
435 // but we do forward the cancel to the IO thread. Since this message has been 435 // but we do forward the cancel to the IO thread. Since this message has been
436 // sent from the UI thread, the saving job may have already completed and 436 // sent from the UI thread, the saving job may have already completed and
437 // won't exist in our map. 437 // won't exist in our map.
438 void SaveFileManager::CancelSave(int save_id) { 438 void SaveFileManager::CancelSave(int save_id) {
439 DCHECK(MessageLoop::current() == GetSaveLoop()); 439 DCHECK(MessageLoop::current() == file_loop());
440 SaveFileMap::iterator it = save_file_map_.find(save_id); 440 SaveFileMap::iterator it = save_file_map_.find(save_id);
441 if (it != save_file_map_.end()) { 441 if (it != save_file_map_.end()) {
442 SaveFile* save_file = it->second; 442 SaveFile* save_file = it->second;
443 443
444 // If the data comes from the net IO thread, then forward the cancel 444 // If the data comes from the net IO thread, then forward the cancel
445 // message to IO thread. If the data comes from other sources, just 445 // message to IO thread. If the data comes from other sources, just
446 // ignore the cancel message. 446 // ignore the cancel message.
447 if (save_file->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_NET) { 447 if (save_file->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_NET) {
448 ui_loop_->PostTask(FROM_HERE, 448 ui_loop_->PostTask(FROM_HERE,
449 NewRunnableMethod(this, 449 NewRunnableMethod(this,
(...skipping 16 matching lines...) Expand all
466 delete save_file; 466 delete save_file;
467 } 467 }
468 } 468 }
469 469
470 // It is possible that SaveItem which has specified save_id has been canceled 470 // It is possible that SaveItem which has specified save_id has been canceled
471 // before this function runs. So if we can not find corresponding SaveFile by 471 // before this function runs. So if we can not find corresponding SaveFile by
472 // using specified save_id, just return. 472 // using specified save_id, just return.
473 void SaveFileManager::SaveLocalFile(const GURL& original_file_url, 473 void SaveFileManager::SaveLocalFile(const GURL& original_file_url,
474 int save_id, 474 int save_id,
475 int render_process_id) { 475 int render_process_id) {
476 DCHECK(MessageLoop::current() == GetSaveLoop()); 476 DCHECK(MessageLoop::current() == file_loop());
477 SaveFile* save_file = LookupSaveFile(save_id); 477 SaveFile* save_file = LookupSaveFile(save_id);
478 if (!save_file) 478 if (!save_file)
479 return; 479 return;
480 DCHECK(!save_file->path_renamed()); 480 DCHECK(!save_file->path_renamed());
481 // If it has finished, just return. 481 // If it has finished, just return.
482 if (!save_file->in_progress()) 482 if (!save_file->in_progress())
483 return; 483 return;
484 484
485 // Close the save file before the copy operation. 485 // Close the save file before the copy operation.
486 save_file->Finish(); 486 save_file->Finish();
487 487
488 DCHECK(original_file_url.SchemeIsFile()); 488 DCHECK(original_file_url.SchemeIsFile());
489 FilePath file_path; 489 FilePath file_path;
490 net::FileURLToFilePath(original_file_url, &file_path); 490 net::FileURLToFilePath(original_file_url, &file_path);
491 // If we can not get valid file path from original URL, treat it as 491 // If we can not get valid file path from original URL, treat it as
492 // disk error. 492 // disk error.
493 if (file_path.empty()) 493 if (file_path.empty())
494 SaveFinished(save_id, original_file_url, render_process_id, false); 494 SaveFinished(save_id, original_file_url, render_process_id, false);
495 495
496 // Copy the local file to the temporary file. It will be renamed to its 496 // Copy the local file to the temporary file. It will be renamed to its
497 // final name later. 497 // final name later.
498 bool success = file_util::CopyFile(file_path, save_file->full_path()); 498 bool success = file_util::CopyFile(file_path, save_file->full_path());
499 if (!success) 499 if (!success)
500 file_util::Delete(save_file->full_path(), false); 500 file_util::Delete(save_file->full_path(), false);
501 SaveFinished(save_id, original_file_url, render_process_id, success); 501 SaveFinished(save_id, original_file_url, render_process_id, success);
502 } 502 }
503 503
504 void SaveFileManager::OnDeleteDirectoryOrFile(const FilePath& full_path, 504 void SaveFileManager::OnDeleteDirectoryOrFile(const FilePath& full_path,
505 bool is_dir) { 505 bool is_dir) {
506 DCHECK(MessageLoop::current() == GetSaveLoop()); 506 DCHECK(MessageLoop::current() == file_loop());
507 DCHECK(!full_path.empty()); 507 DCHECK(!full_path.empty());
508 508
509 file_util::Delete(full_path, is_dir); 509 file_util::Delete(full_path, is_dir);
510 } 510 }
511 511
512 // Open a saved page package, show it in a Windows Explorer window. 512 // Open a saved page package, show it in a Windows Explorer window.
513 // We run on this thread to avoid blocking the UI with slow Shell operations. 513 // We run on this thread to avoid blocking the UI with slow Shell operations.
514 #if !defined(OS_MACOSX)
514 void SaveFileManager::OnShowSavedFileInShell(const FilePath full_path) { 515 void SaveFileManager::OnShowSavedFileInShell(const FilePath full_path) {
515 DCHECK(MessageLoop::current() == GetSaveLoop()); 516 DCHECK(MessageLoop::current() == file_loop());
516 platform_util::ShowItemInFolder(full_path); 517 platform_util::ShowItemInFolder(full_path);
517 } 518 }
519 #endif
518 520
519 void SaveFileManager::RenameAllFiles( 521 void SaveFileManager::RenameAllFiles(
520 const FinalNameList& final_names, 522 const FinalNameList& final_names,
521 const FilePath& resource_dir, 523 const FilePath& resource_dir,
522 int render_process_id, 524 int render_process_id,
523 int render_view_id) { 525 int render_view_id) {
524 DCHECK(MessageLoop::current() == GetSaveLoop()); 526 DCHECK(MessageLoop::current() == file_loop());
525 527
526 if (!resource_dir.empty() && !file_util::PathExists(resource_dir)) 528 if (!resource_dir.empty() && !file_util::PathExists(resource_dir))
527 file_util::CreateDirectory(resource_dir); 529 file_util::CreateDirectory(resource_dir);
528 530
529 for (FinalNameList::const_iterator i = final_names.begin(); 531 for (FinalNameList::const_iterator i = final_names.begin();
530 i != final_names.end(); ++i) { 532 i != final_names.end(); ++i) {
531 SaveFileMap::iterator it = save_file_map_.find(i->first); 533 SaveFileMap::iterator it = save_file_map_.find(i->first);
532 if (it != save_file_map_.end()) { 534 if (it != save_file_map_.end()) {
533 SaveFile* save_file = it->second; 535 SaveFile* save_file = it->second;
534 DCHECK(!save_file->in_progress()); 536 DCHECK(!save_file->in_progress());
(...skipping 18 matching lines...) Expand all
553 GetSavePackageFromRenderIds(render_process_id, render_view_id); 555 GetSavePackageFromRenderIds(render_process_id, render_view_id);
554 556
555 if (save_package) { 557 if (save_package) {
556 // save_package is null if save was canceled. 558 // save_package is null if save was canceled.
557 save_package->Finish(); 559 save_package->Finish();
558 } 560 }
559 } 561 }
560 562
561 void SaveFileManager::RemoveSavedFileFromFileMap( 563 void SaveFileManager::RemoveSavedFileFromFileMap(
562 const SaveIDList& save_ids) { 564 const SaveIDList& save_ids) {
563 DCHECK(MessageLoop::current() == GetSaveLoop()); 565 DCHECK(MessageLoop::current() == file_loop());
564 566
565 for (SaveIDList::const_iterator i = save_ids.begin(); 567 for (SaveIDList::const_iterator i = save_ids.begin();
566 i != save_ids.end(); ++i) { 568 i != save_ids.end(); ++i) {
567 SaveFileMap::iterator it = save_file_map_.find(*i); 569 SaveFileMap::iterator it = save_file_map_.find(*i);
568 if (it != save_file_map_.end()) { 570 if (it != save_file_map_.end()) {
569 SaveFile* save_file = it->second; 571 SaveFile* save_file = it->second;
570 DCHECK(!save_file->in_progress()); 572 DCHECK(!save_file->in_progress());
571 file_util::Delete(save_file->full_path(), false); 573 file_util::Delete(save_file->full_path(), false);
572 delete save_file; 574 delete save_file;
573 save_file_map_.erase(it); 575 save_file_map_.erase(it);
574 } 576 }
575 } 577 }
576 } 578 }
OLDNEW
« no previous file with comments | « chrome/browser/download/save_file_manager.h ('k') | chrome/browser/download/save_package.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698