| 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 "content/browser/download/save_package.h" | 5 #include "content/browser/download/save_package.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/i18n/file_util_icu.h" | 12 #include "base/i18n/file_util_icu.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/macros.h" |
| 14 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 15 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 16 #include "base/strings/string_piece.h" | 17 #include "base/strings/string_piece.h" |
| 17 #include "base/strings/string_split.h" | 18 #include "base/strings/string_split.h" |
| 18 #include "base/strings/sys_string_conversions.h" | 19 #include "base/strings/sys_string_conversions.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
| 22 #include "build/build_config.h" |
| 21 #include "components/url_formatter/url_formatter.h" | 23 #include "components/url_formatter/url_formatter.h" |
| 22 #include "content/browser/download/download_item_impl.h" | 24 #include "content/browser/download/download_item_impl.h" |
| 23 #include "content/browser/download/download_manager_impl.h" | 25 #include "content/browser/download/download_manager_impl.h" |
| 24 #include "content/browser/download/download_stats.h" | 26 #include "content/browser/download/download_stats.h" |
| 25 #include "content/browser/download/save_file.h" | 27 #include "content/browser/download/save_file.h" |
| 26 #include "content/browser/download/save_file_manager.h" | 28 #include "content/browser/download/save_file_manager.h" |
| 27 #include "content/browser/download/save_item.h" | 29 #include "content/browser/download/save_item.h" |
| 28 #include "content/browser/frame_host/frame_tree.h" | 30 #include "content/browser/frame_host/frame_tree.h" |
| 29 #include "content/browser/frame_host/frame_tree_node.h" | 31 #include "content/browser/frame_host/frame_tree_node.h" |
| 30 #include "content/browser/frame_host/render_frame_host_impl.h" | 32 #include "content/browser/frame_host/render_frame_host_impl.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 57 | 59 |
| 58 // A counter for uniquely identifying each save package. | 60 // A counter for uniquely identifying each save package. |
| 59 int g_save_package_id = 0; | 61 int g_save_package_id = 0; |
| 60 | 62 |
| 61 // Default name which will be used when we can not get proper name from | 63 // Default name which will be used when we can not get proper name from |
| 62 // resource URL. | 64 // resource URL. |
| 63 const char kDefaultSaveName[] = "saved_resource"; | 65 const char kDefaultSaveName[] = "saved_resource"; |
| 64 | 66 |
| 65 // Maximum number of file ordinal number. I think it's big enough for resolving | 67 // Maximum number of file ordinal number. I think it's big enough for resolving |
| 66 // name-conflict files which has same base file name. | 68 // name-conflict files which has same base file name. |
| 67 const int32 kMaxFileOrdinalNumber = 9999; | 69 const int32_t kMaxFileOrdinalNumber = 9999; |
| 68 | 70 |
| 69 // Maximum length for file path. Since Windows have MAX_PATH limitation for | 71 // Maximum length for file path. Since Windows have MAX_PATH limitation for |
| 70 // file path, we need to make sure length of file path of every saved file | 72 // file path, we need to make sure length of file path of every saved file |
| 71 // is less than MAX_PATH | 73 // is less than MAX_PATH |
| 72 #if defined(OS_WIN) | 74 #if defined(OS_WIN) |
| 73 const uint32 kMaxFilePathLength = MAX_PATH - 1; | 75 const uint32_t kMaxFilePathLength = MAX_PATH - 1; |
| 74 #elif defined(OS_POSIX) | 76 #elif defined(OS_POSIX) |
| 75 const uint32 kMaxFilePathLength = PATH_MAX - 1; | 77 const uint32_t kMaxFilePathLength = PATH_MAX - 1; |
| 76 #endif | 78 #endif |
| 77 | 79 |
| 78 // Maximum length for file ordinal number part. Since we only support the | 80 // Maximum length for file ordinal number part. Since we only support the |
| 79 // maximum 9999 for ordinal number, which means maximum file ordinal number part | 81 // maximum 9999 for ordinal number, which means maximum file ordinal number part |
| 80 // should be "(9998)", so the value is 6. | 82 // should be "(9998)", so the value is 6. |
| 81 const uint32 kMaxFileOrdinalNumberPartLength = 6; | 83 const uint32_t kMaxFileOrdinalNumberPartLength = 6; |
| 82 | 84 |
| 83 // Strip current ordinal number, if any. Should only be used on pure | 85 // Strip current ordinal number, if any. Should only be used on pure |
| 84 // file names, i.e. those stripped of their extensions. | 86 // file names, i.e. those stripped of their extensions. |
| 85 // TODO(estade): improve this to not choke on alternate encodings. | 87 // TODO(estade): improve this to not choke on alternate encodings. |
| 86 base::FilePath::StringType StripOrdinalNumber( | 88 base::FilePath::StringType StripOrdinalNumber( |
| 87 const base::FilePath::StringType& pure_file_name) { | 89 const base::FilePath::StringType& pure_file_name) { |
| 88 base::FilePath::StringType::size_type r_paren_index = | 90 base::FilePath::StringType::size_type r_paren_index = |
| 89 pure_file_name.rfind(FILE_PATH_LITERAL(')')); | 91 pure_file_name.rfind(FILE_PATH_LITERAL(')')); |
| 90 base::FilePath::StringType::size_type l_paren_index = | 92 base::FilePath::StringType::size_type l_paren_index = |
| 91 pure_file_name.rfind(FILE_PATH_LITERAL('(')); | 93 pure_file_name.rfind(FILE_PATH_LITERAL('(')); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 save_source); | 356 save_source); |
| 355 // Add this item to waiting list. | 357 // Add this item to waiting list. |
| 356 waiting_item_queue_.push_back(save_item); | 358 waiting_item_queue_.push_back(save_item); |
| 357 all_save_items_count_ = 1; | 359 all_save_items_count_ = 1; |
| 358 download_->SetTotalBytes(1); | 360 download_->SetTotalBytes(1); |
| 359 | 361 |
| 360 DoSavingProcess(); | 362 DoSavingProcess(); |
| 361 } | 363 } |
| 362 } | 364 } |
| 363 | 365 |
| 364 void SavePackage::OnMHTMLGenerated(int64 size) { | 366 void SavePackage::OnMHTMLGenerated(int64_t size) { |
| 365 if (size <= 0) { | 367 if (size <= 0) { |
| 366 Cancel(false); | 368 Cancel(false); |
| 367 return; | 369 return; |
| 368 } | 370 } |
| 369 wrote_to_completed_file_ = true; | 371 wrote_to_completed_file_ = true; |
| 370 | 372 |
| 371 // Hack to avoid touching download_ after user cancel. | 373 // Hack to avoid touching download_ after user cancel. |
| 372 // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem | 374 // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem |
| 373 // with SavePackage flow. | 375 // with SavePackage flow. |
| 374 if (download_->GetState() == DownloadItem::IN_PROGRESS) { | 376 if (download_->GetState() == DownloadItem::IN_PROGRESS) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 387 | 389 |
| 388 if (download_manager_->GetDelegate()->ShouldCompleteDownload( | 390 if (download_manager_->GetDelegate()->ShouldCompleteDownload( |
| 389 download_, base::Bind(&SavePackage::Finish, this))) { | 391 download_, base::Bind(&SavePackage::Finish, this))) { |
| 390 Finish(); | 392 Finish(); |
| 391 } | 393 } |
| 392 } | 394 } |
| 393 | 395 |
| 394 // On POSIX, the length of |pure_file_name| + |file_name_ext| is further | 396 // On POSIX, the length of |pure_file_name| + |file_name_ext| is further |
| 395 // restricted by NAME_MAX. The maximum allowed path looks like: | 397 // restricted by NAME_MAX. The maximum allowed path looks like: |
| 396 // '/path/to/save_dir' + '/' + NAME_MAX. | 398 // '/path/to/save_dir' + '/' + NAME_MAX. |
| 397 uint32 SavePackage::GetMaxPathLengthForDirectory( | 399 uint32_t SavePackage::GetMaxPathLengthForDirectory( |
| 398 const base::FilePath& base_dir) { | 400 const base::FilePath& base_dir) { |
| 399 #if defined(OS_POSIX) | 401 #if defined(OS_POSIX) |
| 400 return std::min(kMaxFilePathLength, | 402 return std::min( |
| 401 static_cast<uint32>(base_dir.value().length()) + | 403 kMaxFilePathLength, |
| 402 NAME_MAX + 1); | 404 static_cast<uint32_t>(base_dir.value().length()) + NAME_MAX + 1); |
| 403 #else | 405 #else |
| 404 return kMaxFilePathLength; | 406 return kMaxFilePathLength; |
| 405 #endif | 407 #endif |
| 406 } | 408 } |
| 407 | 409 |
| 408 // File name is considered being consist of pure file name, dot and file | 410 // File name is considered being consist of pure file name, dot and file |
| 409 // extension name. File name might has no dot and file extension, or has | 411 // extension name. File name might has no dot and file extension, or has |
| 410 // multiple dot inside file name. The dot, which separates the pure file | 412 // multiple dot inside file name. The dot, which separates the pure file |
| 411 // name and file extension name, is last dot in the whole file name. | 413 // name and file extension name, is last dot in the whole file name. |
| 412 // This function is for making sure the length of specified file path is not | 414 // This function is for making sure the length of specified file path is not |
| 413 // great than the specified maximum length of file path and getting safe pure | 415 // great than the specified maximum length of file path and getting safe pure |
| 414 // file name part if the input pure file name is too long. | 416 // file name part if the input pure file name is too long. |
| 415 // The parameter |dir_path| specifies directory part of the specified | 417 // The parameter |dir_path| specifies directory part of the specified |
| 416 // file path. The parameter |file_name_ext| specifies file extension | 418 // file path. The parameter |file_name_ext| specifies file extension |
| 417 // name part of the specified file path (including start dot). The parameter | 419 // name part of the specified file path (including start dot). The parameter |
| 418 // |max_file_path_len| specifies maximum length of the specified file path. | 420 // |max_file_path_len| specifies maximum length of the specified file path. |
| 419 // The parameter |pure_file_name| input pure file name part of the specified | 421 // The parameter |pure_file_name| input pure file name part of the specified |
| 420 // file path. If the length of specified file path is great than | 422 // file path. If the length of specified file path is great than |
| 421 // |max_file_path_len|, the |pure_file_name| will output new pure file name | 423 // |max_file_path_len|, the |pure_file_name| will output new pure file name |
| 422 // part for making sure the length of specified file path is less than | 424 // part for making sure the length of specified file path is less than |
| 423 // specified maximum length of file path. Return false if the function can | 425 // specified maximum length of file path. Return false if the function can |
| 424 // not get a safe pure file name, otherwise it returns true. | 426 // not get a safe pure file name, otherwise it returns true. |
| 425 bool SavePackage::GetSafePureFileName( | 427 bool SavePackage::GetSafePureFileName( |
| 426 const base::FilePath& dir_path, | 428 const base::FilePath& dir_path, |
| 427 const base::FilePath::StringType& file_name_ext, | 429 const base::FilePath::StringType& file_name_ext, |
| 428 uint32 max_file_path_len, | 430 uint32_t max_file_path_len, |
| 429 base::FilePath::StringType* pure_file_name) { | 431 base::FilePath::StringType* pure_file_name) { |
| 430 DCHECK(!pure_file_name->empty()); | 432 DCHECK(!pure_file_name->empty()); |
| 431 int available_length = static_cast<int>(max_file_path_len - | 433 int available_length = static_cast<int>(max_file_path_len - |
| 432 dir_path.value().length() - | 434 dir_path.value().length() - |
| 433 file_name_ext.length()); | 435 file_name_ext.length()); |
| 434 // Need an extra space for the separator. | 436 // Need an extra space for the separator. |
| 435 if (!dir_path.EndsWithSeparator()) | 437 if (!dir_path.EndsWithSeparator()) |
| 436 --available_length; | 438 --available_length; |
| 437 | 439 |
| 438 // Plenty of room. | 440 // Plenty of room. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 469 file_path.RemoveExtension().BaseName().value(); | 471 file_path.RemoveExtension().BaseName().value(); |
| 470 base::FilePath::StringType file_name_ext = file_path.Extension(); | 472 base::FilePath::StringType file_name_ext = file_path.Extension(); |
| 471 | 473 |
| 472 // If it is HTML resource, use ".html" as its extension. | 474 // If it is HTML resource, use ".html" as its extension. |
| 473 if (need_html_ext) { | 475 if (need_html_ext) { |
| 474 file_name_ext = FILE_PATH_LITERAL("."); | 476 file_name_ext = FILE_PATH_LITERAL("."); |
| 475 file_name_ext.append(kDefaultHtmlExtension); | 477 file_name_ext.append(kDefaultHtmlExtension); |
| 476 } | 478 } |
| 477 | 479 |
| 478 // Need to make sure the suggested file name is not too long. | 480 // Need to make sure the suggested file name is not too long. |
| 479 uint32 max_path = GetMaxPathLengthForDirectory(saved_main_directory_path_); | 481 uint32_t max_path = GetMaxPathLengthForDirectory(saved_main_directory_path_); |
| 480 | 482 |
| 481 // Get safe pure file name. | 483 // Get safe pure file name. |
| 482 if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext, | 484 if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext, |
| 483 max_path, &pure_file_name)) | 485 max_path, &pure_file_name)) |
| 484 return false; | 486 return false; |
| 485 | 487 |
| 486 base::FilePath::StringType file_name = pure_file_name + file_name_ext; | 488 base::FilePath::StringType file_name = pure_file_name + file_name_ext; |
| 487 | 489 |
| 488 // Check whether we already have same name in a case insensitive manner. | 490 // Check whether we already have same name in a case insensitive manner. |
| 489 FileNameSet::const_iterator iter = file_name_set_.find(file_name); | 491 FileNameSet::const_iterator iter = file_name_set_.find(file_name); |
| 490 if (iter == file_name_set_.end()) { | 492 if (iter == file_name_set_.end()) { |
| 491 file_name_set_.insert(file_name); | 493 file_name_set_.insert(file_name); |
| 492 } else { | 494 } else { |
| 493 // Found same name, increase the ordinal number for the file name. | 495 // Found same name, increase the ordinal number for the file name. |
| 494 pure_file_name = | 496 pure_file_name = |
| 495 base::FilePath(*iter).RemoveExtension().BaseName().value(); | 497 base::FilePath(*iter).RemoveExtension().BaseName().value(); |
| 496 base::FilePath::StringType base_file_name = | 498 base::FilePath::StringType base_file_name = |
| 497 StripOrdinalNumber(pure_file_name); | 499 StripOrdinalNumber(pure_file_name); |
| 498 | 500 |
| 499 // We need to make sure the length of base file name plus maximum ordinal | 501 // We need to make sure the length of base file name plus maximum ordinal |
| 500 // number path will be less than or equal to kMaxFilePathLength. | 502 // number path will be less than or equal to kMaxFilePathLength. |
| 501 if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext, | 503 if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext, |
| 502 max_path - kMaxFileOrdinalNumberPartLength, &base_file_name)) | 504 max_path - kMaxFileOrdinalNumberPartLength, &base_file_name)) |
| 503 return false; | 505 return false; |
| 504 | 506 |
| 505 // Prepare the new ordinal number. | 507 // Prepare the new ordinal number. |
| 506 uint32 ordinal_number; | 508 uint32_t ordinal_number; |
| 507 FileNameCountMap::iterator it = file_name_count_map_.find(base_file_name); | 509 FileNameCountMap::iterator it = file_name_count_map_.find(base_file_name); |
| 508 if (it == file_name_count_map_.end()) { | 510 if (it == file_name_count_map_.end()) { |
| 509 // First base-name-conflict resolving, use 1 as initial ordinal number. | 511 // First base-name-conflict resolving, use 1 as initial ordinal number. |
| 510 file_name_count_map_[base_file_name] = 1; | 512 file_name_count_map_[base_file_name] = 1; |
| 511 ordinal_number = 1; | 513 ordinal_number = 1; |
| 512 } else { | 514 } else { |
| 513 // We have met same base-name conflict, use latest ordinal number. | 515 // We have met same base-name conflict, use latest ordinal number. |
| 514 ordinal_number = it->second; | 516 ordinal_number = it->second; |
| 515 } | 517 } |
| 516 | 518 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 | 620 |
| 619 // Check whether we begin to require serialized HTML data. | 621 // Check whether we begin to require serialized HTML data. |
| 620 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML && | 622 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML && |
| 621 wait_state_ == HTML_DATA) { | 623 wait_state_ == HTML_DATA) { |
| 622 // Inform backend to serialize the all frames' DOM and send serialized | 624 // Inform backend to serialize the all frames' DOM and send serialized |
| 623 // HTML data back. | 625 // HTML data back. |
| 624 GetSerializedHtmlWithLocalLinks(); | 626 GetSerializedHtmlWithLocalLinks(); |
| 625 } | 627 } |
| 626 } | 628 } |
| 627 | 629 |
| 628 SaveItem* SavePackage::LookupSaveItemInProcess(int32 save_item_id) { | 630 SaveItem* SavePackage::LookupSaveItemInProcess(int32_t save_item_id) { |
| 629 auto it = in_progress_items_.find(save_item_id); | 631 auto it = in_progress_items_.find(save_item_id); |
| 630 if (it != in_progress_items_.end()) { | 632 if (it != in_progress_items_.end()) { |
| 631 SaveItem* save_item = it->second; | 633 SaveItem* save_item = it->second; |
| 632 DCHECK_EQ(SaveItem::IN_PROGRESS, save_item->state()); | 634 DCHECK_EQ(SaveItem::IN_PROGRESS, save_item->state()); |
| 633 return save_item; | 635 return save_item; |
| 634 } | 636 } |
| 635 return nullptr; | 637 return nullptr; |
| 636 } | 638 } |
| 637 | 639 |
| 638 void SavePackage::PutInProgressItemToSavedMap(SaveItem* save_item) { | 640 void SavePackage::PutInProgressItemToSavedMap(SaveItem* save_item) { |
| 639 SaveItemIdMap::iterator it = in_progress_items_.find(save_item->id()); | 641 SaveItemIdMap::iterator it = in_progress_items_.find(save_item->id()); |
| 640 DCHECK(it != in_progress_items_.end()); | 642 DCHECK(it != in_progress_items_.end()); |
| 641 DCHECK(save_item == it->second); | 643 DCHECK(save_item == it->second); |
| 642 in_progress_items_.erase(it); | 644 in_progress_items_.erase(it); |
| 643 | 645 |
| 644 if (save_item->success()) { | 646 if (save_item->success()) { |
| 645 // Add it to saved_success_items_. | 647 // Add it to saved_success_items_. |
| 646 DCHECK(saved_success_items_.find(save_item->id()) == | 648 DCHECK(saved_success_items_.find(save_item->id()) == |
| 647 saved_success_items_.end()); | 649 saved_success_items_.end()); |
| 648 saved_success_items_[save_item->id()] = save_item; | 650 saved_success_items_[save_item->id()] = save_item; |
| 649 } else { | 651 } else { |
| 650 // Add it to saved_failed_items_. | 652 // Add it to saved_failed_items_. |
| 651 DCHECK(saved_failed_items_.find(save_item->id()) == | 653 DCHECK(saved_failed_items_.find(save_item->id()) == |
| 652 saved_failed_items_.end()); | 654 saved_failed_items_.end()); |
| 653 saved_failed_items_[save_item->id()] = save_item; | 655 saved_failed_items_[save_item->id()] = save_item; |
| 654 } | 656 } |
| 655 } | 657 } |
| 656 | 658 |
| 657 // Called for updating saving state. | 659 // Called for updating saving state. |
| 658 bool SavePackage::UpdateSaveProgress(int32 save_item_id, | 660 bool SavePackage::UpdateSaveProgress(int32_t save_item_id, |
| 659 int64 size, | 661 int64_t size, |
| 660 bool write_success) { | 662 bool write_success) { |
| 661 // Because we might have canceled this saving job before, | 663 // Because we might have canceled this saving job before, |
| 662 // so we might not find corresponding SaveItem. | 664 // so we might not find corresponding SaveItem. |
| 663 SaveItem* save_item = LookupSaveItemInProcess(save_item_id); | 665 SaveItem* save_item = LookupSaveItemInProcess(save_item_id); |
| 664 if (!save_item) | 666 if (!save_item) |
| 665 return false; | 667 return false; |
| 666 | 668 |
| 667 save_item->Update(size); | 669 save_item->Update(size); |
| 668 | 670 |
| 669 // If we got disk error, cancel whole save page job. | 671 // If we got disk error, cancel whole save page job. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 all_save_items_count_, CurrentSpeed(), std::string()); | 789 all_save_items_count_, CurrentSpeed(), std::string()); |
| 788 download_->OnAllDataSaved(DownloadItem::kEmptyFileHash); | 790 download_->OnAllDataSaved(DownloadItem::kEmptyFileHash); |
| 789 } | 791 } |
| 790 download_->MarkAsComplete(); | 792 download_->MarkAsComplete(); |
| 791 } | 793 } |
| 792 FinalizeDownloadEntry(); | 794 FinalizeDownloadEntry(); |
| 793 } | 795 } |
| 794 } | 796 } |
| 795 | 797 |
| 796 // Called for updating end state. | 798 // Called for updating end state. |
| 797 void SavePackage::SaveFinished(int32 save_item_id, | 799 void SavePackage::SaveFinished(int32_t save_item_id, |
| 798 int64 size, | 800 int64_t size, |
| 799 bool is_success) { | 801 bool is_success) { |
| 800 // Because we might have canceled this saving job before, | 802 // Because we might have canceled this saving job before, |
| 801 // so we might not find corresponding SaveItem. Just ignore it. | 803 // so we might not find corresponding SaveItem. Just ignore it. |
| 802 SaveItem* save_item = LookupSaveItemInProcess(save_item_id); | 804 SaveItem* save_item = LookupSaveItemInProcess(save_item_id); |
| 803 if (!save_item) | 805 if (!save_item) |
| 804 return; | 806 return; |
| 805 | 807 |
| 806 // Let SaveItem set end state. | 808 // Let SaveItem set end state. |
| 807 save_item->Finish(size, is_success); | 809 save_item->Finish(size, is_success); |
| 808 // Remove the associated save id and SavePackage. | 810 // Remove the associated save id and SavePackage. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 // Calculate the percentage of whole save page job. | 879 // Calculate the percentage of whole save page job. |
| 878 int SavePackage::PercentComplete() { | 880 int SavePackage::PercentComplete() { |
| 879 if (!all_save_items_count_) | 881 if (!all_save_items_count_) |
| 880 return 0; | 882 return 0; |
| 881 else if (!in_process_count()) | 883 else if (!in_process_count()) |
| 882 return 100; | 884 return 100; |
| 883 else | 885 else |
| 884 return completed_count() / all_save_items_count_; | 886 return completed_count() / all_save_items_count_; |
| 885 } | 887 } |
| 886 | 888 |
| 887 int64 SavePackage::CurrentSpeed() const { | 889 int64_t SavePackage::CurrentSpeed() const { |
| 888 base::TimeDelta diff = base::TimeTicks::Now() - start_tick_; | 890 base::TimeDelta diff = base::TimeTicks::Now() - start_tick_; |
| 889 int64 diff_ms = diff.InMilliseconds(); | 891 int64_t diff_ms = diff.InMilliseconds(); |
| 890 return diff_ms == 0 ? 0 : completed_count() * 1000 / diff_ms; | 892 return diff_ms == 0 ? 0 : completed_count() * 1000 / diff_ms; |
| 891 } | 893 } |
| 892 | 894 |
| 893 // Continue processing the save page job after one SaveItem has been | 895 // Continue processing the save page job after one SaveItem has been |
| 894 // finished. | 896 // finished. |
| 895 void SavePackage::DoSavingProcess() { | 897 void SavePackage::DoSavingProcess() { |
| 896 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { | 898 if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { |
| 897 // We guarantee that images and JavaScripts must be downloaded first. | 899 // We guarantee that images and JavaScripts must be downloaded first. |
| 898 // So when finishing all those sub-resources, we will know which | 900 // So when finishing all those sub-resources, we will know which |
| 899 // sub-resource's link can be replaced with local file path, which | 901 // sub-resource's link can be replaced with local file path, which |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1346 { FILE_PATH_LITERAL("text/xml"), FILE_PATH_LITERAL("xml") }, | 1348 { FILE_PATH_LITERAL("text/xml"), FILE_PATH_LITERAL("xml") }, |
| 1347 { FILE_PATH_LITERAL("application/xhtml+xml"), FILE_PATH_LITERAL("xhtml") }, | 1349 { FILE_PATH_LITERAL("application/xhtml+xml"), FILE_PATH_LITERAL("xhtml") }, |
| 1348 { FILE_PATH_LITERAL("text/plain"), FILE_PATH_LITERAL("txt") }, | 1350 { FILE_PATH_LITERAL("text/plain"), FILE_PATH_LITERAL("txt") }, |
| 1349 { FILE_PATH_LITERAL("text/css"), FILE_PATH_LITERAL("css") }, | 1351 { FILE_PATH_LITERAL("text/css"), FILE_PATH_LITERAL("css") }, |
| 1350 }; | 1352 }; |
| 1351 #if defined(OS_POSIX) | 1353 #if defined(OS_POSIX) |
| 1352 base::FilePath::StringType mime_type(contents_mime_type); | 1354 base::FilePath::StringType mime_type(contents_mime_type); |
| 1353 #elif defined(OS_WIN) | 1355 #elif defined(OS_WIN) |
| 1354 base::FilePath::StringType mime_type(base::UTF8ToWide(contents_mime_type)); | 1356 base::FilePath::StringType mime_type(base::UTF8ToWide(contents_mime_type)); |
| 1355 #endif // OS_WIN | 1357 #endif // OS_WIN |
| 1356 for (uint32 i = 0; i < arraysize(extensions); ++i) { | 1358 for (uint32_t i = 0; i < arraysize(extensions); ++i) { |
| 1357 if (mime_type == extensions[i].mime_type) | 1359 if (mime_type == extensions[i].mime_type) |
| 1358 return extensions[i].suggested_extension; | 1360 return extensions[i].suggested_extension; |
| 1359 } | 1361 } |
| 1360 return FILE_PATH_LITERAL(""); | 1362 return FILE_PATH_LITERAL(""); |
| 1361 } | 1363 } |
| 1362 | 1364 |
| 1363 void SavePackage::GetSaveInfo() { | 1365 void SavePackage::GetSaveInfo() { |
| 1364 // Can't use web_contents_ in the file thread, so get the data that we need | 1366 // Can't use web_contents_ in the file thread, so get the data that we need |
| 1365 // before calling to it. | 1367 // before calling to it. |
| 1366 base::FilePath website_save_dir, download_save_dir; | 1368 base::FilePath website_save_dir, download_save_dir; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 } | 1407 } |
| 1406 | 1408 |
| 1407 bool can_save_as_complete = CanSaveAsComplete(mime_type); | 1409 bool can_save_as_complete = CanSaveAsComplete(mime_type); |
| 1408 base::FilePath suggested_filename = GetSuggestedNameForSaveAs( | 1410 base::FilePath suggested_filename = GetSuggestedNameForSaveAs( |
| 1409 can_save_as_complete, mime_type, accept_langs); | 1411 can_save_as_complete, mime_type, accept_langs); |
| 1410 base::FilePath::StringType pure_file_name = | 1412 base::FilePath::StringType pure_file_name = |
| 1411 suggested_filename.RemoveExtension().BaseName().value(); | 1413 suggested_filename.RemoveExtension().BaseName().value(); |
| 1412 base::FilePath::StringType file_name_ext = suggested_filename.Extension(); | 1414 base::FilePath::StringType file_name_ext = suggested_filename.Extension(); |
| 1413 | 1415 |
| 1414 // Need to make sure the suggested file name is not too long. | 1416 // Need to make sure the suggested file name is not too long. |
| 1415 uint32 max_path = GetMaxPathLengthForDirectory(save_dir); | 1417 uint32_t max_path = GetMaxPathLengthForDirectory(save_dir); |
| 1416 | 1418 |
| 1417 if (GetSafePureFileName(save_dir, file_name_ext, max_path, &pure_file_name)) { | 1419 if (GetSafePureFileName(save_dir, file_name_ext, max_path, &pure_file_name)) { |
| 1418 save_dir = save_dir.Append(pure_file_name + file_name_ext); | 1420 save_dir = save_dir.Append(pure_file_name + file_name_ext); |
| 1419 } else { | 1421 } else { |
| 1420 // Cannot create a shorter filename. This will cause the save as operation | 1422 // Cannot create a shorter filename. This will cause the save as operation |
| 1421 // to fail unless the user pick a shorter name. Continuing even though it | 1423 // to fail unless the user pick a shorter name. Continuing even though it |
| 1422 // will fail because returning means no save as popup for the user, which | 1424 // will fail because returning means no save as popup for the user, which |
| 1423 // is even more confusing. This case should be rare though. | 1425 // is even more confusing. This case should be rare though. |
| 1424 save_dir = save_dir.Append(suggested_filename); | 1426 save_dir = save_dir.Append(suggested_filename); |
| 1425 } | 1427 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 | 1494 |
| 1493 void SavePackage::FinalizeDownloadEntry() { | 1495 void SavePackage::FinalizeDownloadEntry() { |
| 1494 DCHECK(download_); | 1496 DCHECK(download_); |
| 1495 DCHECK(download_manager_); | 1497 DCHECK(download_manager_); |
| 1496 | 1498 |
| 1497 download_manager_->OnSavePackageSuccessfullyFinished(download_); | 1499 download_manager_->OnSavePackageSuccessfullyFinished(download_); |
| 1498 StopObservation(); | 1500 StopObservation(); |
| 1499 } | 1501 } |
| 1500 | 1502 |
| 1501 } // namespace content | 1503 } // namespace content |
| OLD | NEW |