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

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

Issue 2825056: Recommit r52848 - Option-click to download should not display "Save As" UI. (Closed)
Patch Set: Created 10 years, 5 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/download/download_manager.h" 5 #include "chrome/browser/download/download_manager.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 // history system of a new download. Since this method can be called while the 397 // history system of a new download. Since this method can be called while the
398 // history service thread is still reading the persistent state, we do not 398 // history service thread is still reading the persistent state, we do not
399 // insert the new DownloadItem into 'downloads_' or inform our observers at this 399 // insert the new DownloadItem into 'downloads_' or inform our observers at this
400 // point. OnCreateDatabaseEntryComplete() handles that finalization of the the 400 // point. OnCreateDatabaseEntryComplete() handles that finalization of the the
401 // download creation as a callback from the history thread. 401 // download creation as a callback from the history thread.
402 void DownloadManager::StartDownload(DownloadCreateInfo* info) { 402 void DownloadManager::StartDownload(DownloadCreateInfo* info) {
403 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 403 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
404 DCHECK(info); 404 DCHECK(info);
405 405
406 // Check whether this download is for an extension install or not. 406 // Check whether this download is for an extension install or not.
407 if (!info->save_as) { // Allow extensions to be explicitly saved. 407 // Allow extensions to be explicitly saved.
408 if (!info->prompt_user_for_save_location) {
408 if (UserScript::HasUserScriptFileExtension(info->url) || 409 if (UserScript::HasUserScriptFileExtension(info->url) ||
409 info->mime_type == Extension::kMimeType) 410 info->mime_type == Extension::kMimeType)
410 info->is_extension_install = true; 411 info->is_extension_install = true;
411 } 412 }
412 413
413 if (info->save_info.file_path.empty()) { 414 if (info->save_info.file_path.empty()) {
414 FilePath generated_name; 415 FilePath generated_name;
415 GenerateFileNameFromInfo(info, &generated_name); 416 GenerateFileNameFromInfo(info, &generated_name);
416 417
417 // Freeze the user's preference for showing a Save As dialog. We're going 418 // Freeze the user's preference for showing a Save As dialog. We're going
418 // to bounce around a bunch of threads and we don't want to worry about race 419 // to bounce around a bunch of threads and we don't want to worry about race
419 // conditions where the user changes this pref out from under us. 420 // conditions where the user changes this pref out from under us.
420 if (*prompt_for_download_) { 421 if (*prompt_for_download_) {
421 // But ignore the user's preference for the following scenarios: 422 // But ignore the user's preference for the following scenarios:
422 // 1) Extension installation. Note that we only care here about the case 423 // 1) Extension installation. Note that we only care here about the case
423 // where an extension is installed, not when one is downloaded with 424 // where an extension is installed, not when one is downloaded with
424 // "save as...". 425 // "save as...".
425 // 2) Filetypes marked "always open." If the user just wants this file 426 // 2) Filetypes marked "always open." If the user just wants this file
426 // opened, don't bother asking where to keep it. 427 // opened, don't bother asking where to keep it.
427 if (!info->is_extension_install && 428 if (!info->is_extension_install &&
428 !ShouldOpenFileBasedOnExtension(generated_name)) 429 !ShouldOpenFileBasedOnExtension(generated_name))
429 info->save_as = true; 430 info->prompt_user_for_save_location = true;
430 } 431 }
431 432
432 // Determine the proper path for a download, by either one of the following: 433 // Determine the proper path for a download, by either one of the following:
433 // 1) using the default download directory. 434 // 1) using the default download directory.
434 // 2) prompting the user. 435 // 2) prompting the user.
435 if (info->save_as && !last_download_path_.empty()) 436 if (info->prompt_user_for_save_location && !last_download_path_.empty())
436 info->suggested_path = last_download_path_; 437 info->suggested_path = last_download_path_;
437 else 438 else
438 info->suggested_path = download_path(); 439 info->suggested_path = download_path();
439 info->suggested_path = info->suggested_path.Append(generated_name); 440 info->suggested_path = info->suggested_path.Append(generated_name);
440 } else { 441 } else {
441 info->suggested_path = info->save_info.file_path; 442 info->suggested_path = info->save_info.file_path;
442 } 443 }
443 444
444 if (!info->save_as && info->save_info.file_path.empty()) { 445 if (!info->prompt_user_for_save_location &&
446 info->save_info.file_path.empty()) {
445 // Downloads can be marked as dangerous for two reasons: 447 // Downloads can be marked as dangerous for two reasons:
446 // a) They have a dangerous-looking filename 448 // a) They have a dangerous-looking filename
447 // b) They are an extension that is not from the gallery 449 // b) They are an extension that is not from the gallery
448 if (IsDangerous(info->suggested_path.BaseName())) 450 if (IsDangerous(info->suggested_path.BaseName()))
449 info->is_dangerous = true; 451 info->is_dangerous = true;
450 else if (info->is_extension_install && 452 else if (info->is_extension_install &&
451 !ExtensionsService::IsDownloadFromGallery(info->url, 453 !ExtensionsService::IsDownloadFromGallery(info->url,
452 info->referrer_url)) { 454 info->referrer_url)) {
453 info->is_dangerous = true; 455 info->is_dangerous = true;
454 } 456 }
455 } 457 }
456 458
457 // We need to move over to the download thread because we don't want to stat 459 // We need to move over to the download thread because we don't want to stat
458 // the suggested path on the UI thread. 460 // the suggested path on the UI thread.
459 ChromeThread::PostTask( 461 ChromeThread::PostTask(
460 ChromeThread::FILE, FROM_HERE, 462 ChromeThread::FILE, FROM_HERE,
461 NewRunnableMethod( 463 NewRunnableMethod(
462 this, &DownloadManager::CheckIfSuggestedPathExists, info)); 464 this, &DownloadManager::CheckIfSuggestedPathExists, info));
463 } 465 }
464 466
465 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) { 467 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
466 DCHECK(info); 468 DCHECK(info);
467 469
468 // Check writability of the suggested path. If we can't write to it, default 470 // Check writability of the suggested path. If we can't write to it, default
469 // to the user's "My Documents" directory. We'll prompt them in this case. 471 // to the user's "My Documents" directory. We'll prompt them in this case.
470 FilePath dir = info->suggested_path.DirName(); 472 FilePath dir = info->suggested_path.DirName();
471 FilePath filename = info->suggested_path.BaseName(); 473 FilePath filename = info->suggested_path.BaseName();
472 if (!file_util::PathIsWritable(dir)) { 474 if (!file_util::PathIsWritable(dir)) {
473 info->save_as = true; 475 info->prompt_user_for_save_location = true;
474 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path); 476 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path);
475 info->suggested_path = info->suggested_path.Append(filename); 477 info->suggested_path = info->suggested_path.Append(filename);
476 } 478 }
477 479
478 // Do not add the path uniquifier if we are saving to a specific path as in 480 // Do not add the path uniquifier if we are saving to a specific path as in
479 // the drag-out case. 481 // the drag-out case.
480 if (info->save_info.file_path.empty()) { 482 if (info->save_info.file_path.empty()) {
481 info->path_uniquifier = download_util::GetUniquePathNumber( 483 info->path_uniquifier = download_util::GetUniquePathNumber(
482 info->suggested_path); 484 info->suggested_path);
483 } 485 }
(...skipping 16 matching lines...) Expand all
500 } else { 502 } else {
501 // We know the final path, build it if necessary. 503 // We know the final path, build it if necessary.
502 if (info->path_uniquifier > 0) { 504 if (info->path_uniquifier > 0) {
503 download_util::AppendNumberToPath(&(info->suggested_path), 505 download_util::AppendNumberToPath(&(info->suggested_path),
504 info->path_uniquifier); 506 info->path_uniquifier);
505 // Setting path_uniquifier to 0 to make sure we don't try to unique it 507 // Setting path_uniquifier to 0 to make sure we don't try to unique it
506 // later on. 508 // later on.
507 info->path_uniquifier = 0; 509 info->path_uniquifier = 0;
508 } else if (info->path_uniquifier == -1) { 510 } else if (info->path_uniquifier == -1) {
509 // We failed to find a unique path. We have to prompt the user. 511 // We failed to find a unique path. We have to prompt the user.
510 info->save_as = true; 512 info->prompt_user_for_save_location = true;
511 } 513 }
512 } 514 }
513 515
514 if (!info->save_as && info->save_info.file_path.empty()) { 516 if (!info->prompt_user_for_save_location &&
517 info->save_info.file_path.empty()) {
515 // Create an empty file at the suggested path so that we don't allocate the 518 // Create an empty file at the suggested path so that we don't allocate the
516 // same "non-existant" path to multiple downloads. 519 // same "non-existant" path to multiple downloads.
517 // See: http://code.google.com/p/chromium/issues/detail?id=3662 520 // See: http://code.google.com/p/chromium/issues/detail?id=3662
518 file_util::WriteFile(info->suggested_path, "", 0); 521 file_util::WriteFile(info->suggested_path, "", 0);
519 } 522 }
520 523
521 // Now we return to the UI thread. 524 // Now we return to the UI thread.
522 ChromeThread::PostTask( 525 ChromeThread::PostTask(
523 ChromeThread::UI, FROM_HERE, 526 ChromeThread::UI, FROM_HERE,
524 NewRunnableMethod(this, 527 NewRunnableMethod(this,
525 &DownloadManager::OnPathExistenceAvailable, 528 &DownloadManager::OnPathExistenceAvailable,
526 info)); 529 info));
527 } 530 }
528 531
529 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { 532 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
530 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 533 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
531 DCHECK(info); 534 DCHECK(info);
532 535
533 if (info->save_as) { 536 if (info->prompt_user_for_save_location) {
534 // We must ask the user for the place to put the download. 537 // We must ask the user for the place to put the download.
535 if (!select_file_dialog_.get()) 538 if (!select_file_dialog_.get())
536 select_file_dialog_ = SelectFileDialog::Create(this); 539 select_file_dialog_ = SelectFileDialog::Create(this);
537 540
538 TabContents* contents = tab_util::GetTabContentsByID(info->child_id, 541 TabContents* contents = tab_util::GetTabContentsByID(info->child_id,
539 info->render_view_id); 542 info->render_view_id);
540 SelectFileDialog::FileTypeInfo file_type_info; 543 SelectFileDialog::FileTypeInfo file_type_info;
541 file_type_info.extensions.resize(1); 544 file_type_info.extensions.resize(1);
542 file_type_info.extensions[0].push_back(info->suggested_path.Extension()); 545 file_type_info.extensions[0].push_back(info->suggested_path.Extension());
543 if (!file_type_info.extensions[0][0].empty()) 546 if (!file_type_info.extensions[0][0].empty())
(...skipping 26 matching lines...) Expand all
570 info->url, 573 info->url,
571 info->referrer_url, 574 info->referrer_url,
572 info->mime_type, 575 info->mime_type,
573 info->original_mime_type, 576 info->original_mime_type,
574 info->original_name, 577 info->original_name,
575 info->start_time, 578 info->start_time,
576 info->total_bytes, 579 info->total_bytes,
577 info->child_id, 580 info->child_id,
578 info->request_id, 581 info->request_id,
579 info->is_dangerous, 582 info->is_dangerous,
580 info->save_as, 583 info->prompt_user_for_save_location,
581 profile_->IsOffTheRecord(), 584 profile_->IsOffTheRecord(),
582 info->is_extension_install, 585 info->is_extension_install,
583 !info->save_info.file_path.empty()); 586 !info->save_info.file_path.empty());
584 download->set_manager(this); 587 download->set_manager(this);
585 in_progress_[info->download_id] = download; 588 in_progress_[info->download_id] = download;
586 } else { 589 } else {
587 NOTREACHED(); // Should not exist! 590 NOTREACHED(); // Should not exist!
588 return; 591 return;
589 } 592 }
590 593
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 if (!extensions.empty()) 1406 if (!extensions.empty())
1404 extensions.erase(extensions.size() - 1); 1407 extensions.erase(extensions.size() - 1);
1405 1408
1406 prefs->SetString(prefs::kDownloadExtensionsToOpen, extensions); 1409 prefs->SetString(prefs::kDownloadExtensionsToOpen, extensions);
1407 } 1410 }
1408 } 1411 }
1409 1412
1410 void DownloadManager::FileSelected(const FilePath& path, 1413 void DownloadManager::FileSelected(const FilePath& path,
1411 int index, void* params) { 1414 int index, void* params) {
1412 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1415 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params);
1413 if (info->save_as) 1416 if (info->prompt_user_for_save_location)
1414 last_download_path_ = path.DirName(); 1417 last_download_path_ = path.DirName();
1415 ContinueStartDownload(info, path); 1418 ContinueStartDownload(info, path);
1416 } 1419 }
1417 1420
1418 void DownloadManager::FileSelectionCanceled(void* params) { 1421 void DownloadManager::FileSelectionCanceled(void* params) {
1419 // The user didn't pick a place to save the file, so need to cancel the 1422 // The user didn't pick a place to save the file, so need to cancel the
1420 // download that's already in progress to the temporary location. 1423 // download that's already in progress to the temporary location.
1421 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1424 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params);
1422 DownloadCancelledInternal(info->download_id, 1425 DownloadCancelledInternal(info->download_id,
1423 info->child_id, 1426 info->child_id,
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 observing_download_manager_->NotifyModelChanged(); 1608 observing_download_manager_->NotifyModelChanged();
1606 } 1609 }
1607 1610
1608 void DownloadManager::OtherDownloadManagerObserver::SetDownloads( 1611 void DownloadManager::OtherDownloadManagerObserver::SetDownloads(
1609 std::vector<DownloadItem*>& downloads) { 1612 std::vector<DownloadItem*>& downloads) {
1610 } 1613 }
1611 1614
1612 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { 1615 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() {
1613 observed_download_manager_ = NULL; 1616 observed_download_manager_ = NULL;
1614 } 1617 }
OLDNEW
« no previous file with comments | « chrome/browser/download/download_file_manager.cc ('k') | chrome/browser/download/download_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698