| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/offline_pages/offline_page_model.h" | 5 #include "components/offline_pages/offline_page_model.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 base::DirectoryExists(id_path.second)) { | 96 base::DirectoryExists(id_path.second)) { |
| 97 ids_of_pages_missing_archive_file->push_back(id_path.first); | 97 ids_of_pages_missing_archive_file->push_back(id_path.first); |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 } | 100 } |
| 101 | 101 |
| 102 void EnsureArchivesDirCreated(const base::FilePath& archives_dir) { | 102 void EnsureArchivesDirCreated(const base::FilePath& archives_dir) { |
| 103 CHECK(base::CreateDirectory(archives_dir)); | 103 CHECK(base::CreateDirectory(archives_dir)); |
| 104 } | 104 } |
| 105 | 105 |
| 106 std::string AddHistogramSuffix(const ClientId& client_id, |
| 107 const char* histogram_name) { |
| 108 if (client_id.name_space.empty()) { |
| 109 NOTREACHED(); |
| 110 return histogram_name; |
| 111 } |
| 112 std::string adjusted_histogram_name(histogram_name); |
| 113 adjusted_histogram_name += "."; |
| 114 adjusted_histogram_name += client_id.name_space; |
| 115 return adjusted_histogram_name; |
| 116 } |
| 117 |
| 106 } // namespace | 118 } // namespace |
| 107 | 119 |
| 108 // static | 120 // static |
| 109 bool OfflinePageModel::CanSavePage(const GURL& url) { | 121 bool OfflinePageModel::CanSavePage(const GURL& url) { |
| 110 return url.SchemeIsHTTPOrHTTPS(); | 122 return url.SchemeIsHTTPOrHTTPS(); |
| 111 } | 123 } |
| 112 | 124 |
| 113 OfflinePageModel::OfflinePageModel( | 125 OfflinePageModel::OfflinePageModel( |
| 114 std::unique_ptr<OfflinePageMetadataStore> store, | 126 std::unique_ptr<OfflinePageMetadataStore> store, |
| 115 const base::FilePath& archives_dir, | 127 const base::FilePath& archives_dir, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 137 } | 149 } |
| 138 | 150 |
| 139 void OfflinePageModel::SavePage(const GURL& url, | 151 void OfflinePageModel::SavePage(const GURL& url, |
| 140 const ClientId& client_id, | 152 const ClientId& client_id, |
| 141 std::unique_ptr<OfflinePageArchiver> archiver, | 153 std::unique_ptr<OfflinePageArchiver> archiver, |
| 142 const SavePageCallback& callback) { | 154 const SavePageCallback& callback) { |
| 143 DCHECK(is_loaded_); | 155 DCHECK(is_loaded_); |
| 144 | 156 |
| 145 // Skip saving the page that is not intended to be saved, like local file | 157 // Skip saving the page that is not intended to be saved, like local file |
| 146 // page. | 158 // page. |
| 147 if (!CanSavePage(url)) { | 159 if (url.is_valid() && !CanSavePage(url)) { |
| 148 InformSavePageDone(callback, SavePageResult::SKIPPED, kInvalidOfflineId); | 160 InformSavePageDone(callback, SavePageResult::SKIPPED, client_id, |
| 161 kInvalidOfflineId); |
| 149 return; | 162 return; |
| 150 } | 163 } |
| 151 | 164 |
| 152 DCHECK(archiver.get()); | 165 // The web contents is not available if archiver is not created and passed. |
| 166 if (!archiver.get()) { |
| 167 InformSavePageDone(callback, SavePageResult::CONTENT_UNAVAILABLE, client_id, |
| 168 kInvalidOfflineId); |
| 169 return; |
| 170 } |
| 153 | 171 |
| 154 int64_t offline_id = GenerateOfflineId(); | 172 int64_t offline_id = GenerateOfflineId(); |
| 155 | 173 |
| 156 archiver->CreateArchive( | 174 archiver->CreateArchive( |
| 157 archives_dir_, | 175 archives_dir_, |
| 158 offline_id, | 176 offline_id, |
| 159 base::Bind(&OfflinePageModel::OnCreateArchiveDone, | 177 base::Bind(&OfflinePageModel::OnCreateArchiveDone, |
| 160 weak_ptr_factory_.GetWeakPtr(), url, offline_id, | 178 weak_ptr_factory_.GetWeakPtr(), url, offline_id, |
| 161 client_id, base::Time::Now(), callback)); | 179 client_id, base::Time::Now(), callback)); |
| 162 pending_archivers_.push_back(std::move(archiver)); | 180 pending_archivers_.push_back(std::move(archiver)); |
| 163 } | 181 } |
| 164 | 182 |
| 165 void OfflinePageModel::MarkPageAccessed(int64_t offline_id) { | 183 void OfflinePageModel::MarkPageAccessed(int64_t offline_id) { |
| 166 DCHECK(is_loaded_); | 184 DCHECK(is_loaded_); |
| 167 auto iter = offline_pages_.find(offline_id); | 185 auto iter = offline_pages_.find(offline_id); |
| 168 if (iter == offline_pages_.end()) | 186 if (iter == offline_pages_.end()) |
| 169 return; | 187 return; |
| 170 | 188 |
| 171 // Make a copy of the cached item and update it. The cached item should only | 189 // Make a copy of the cached item and update it. The cached item should only |
| 172 // be updated upon the successful store operation. | 190 // be updated upon the successful store operation. |
| 173 OfflinePageItem offline_page_item = iter->second; | 191 OfflinePageItem offline_page_item = iter->second; |
| 174 | 192 |
| 175 base::Time now = base::Time::Now(); | 193 base::Time now = base::Time::Now(); |
| 176 base::TimeDelta time_since_last_accessed = | 194 base::TimeDelta time_since_last_accessed = |
| 177 now - offline_page_item.last_access_time; | 195 now - offline_page_item.last_access_time; |
| 178 | 196 |
| 179 // The last access time was set to same as creation time when the page was | 197 // When the access account is still zero, the page is opened for the first |
| 180 // created. | 198 // time since its creation. |
| 181 if (offline_page_item.creation_time == offline_page_item.last_access_time) { | 199 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 182 UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.FirstOpenSinceCreated", | 200 AddHistogramSuffix( |
| 183 time_since_last_accessed.InMinutes(), 1, | 201 offline_page_item.client_id, |
| 184 kMaxOpenedPageHistogramBucket.InMinutes(), 50); | 202 (offline_page_item.access_count == 0) ? |
| 185 } else { | 203 "OfflinePages.FirstOpenSinceCreated" : |
| 186 UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.OpenSinceLastOpen", | 204 "OfflinePages.OpenSinceLastOpen").c_str(), |
| 187 time_since_last_accessed.InMinutes(), 1, | 205 time_since_last_accessed.InMinutes(), 1, |
| 188 kMaxOpenedPageHistogramBucket.InMinutes(), 50); | 206 kMaxOpenedPageHistogramBucket.InMinutes(), 50); |
| 189 } | |
| 190 | 207 |
| 191 offline_page_item.last_access_time = now; | 208 offline_page_item.last_access_time = now; |
| 192 offline_page_item.access_count++; | 209 offline_page_item.access_count++; |
| 193 | 210 |
| 194 store_->AddOrUpdateOfflinePage( | 211 store_->AddOrUpdateOfflinePage( |
| 195 offline_page_item, | 212 offline_page_item, |
| 196 base::Bind(&OfflinePageModel::OnMarkPageAccesseDone, | 213 base::Bind(&OfflinePageModel::OnMarkPageAccesseDone, |
| 197 weak_ptr_factory_.GetWeakPtr(), offline_page_item)); | 214 weak_ptr_factory_.GetWeakPtr(), offline_page_item)); |
| 198 } | 215 } |
| 199 | 216 |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 OfflinePageArchiver* archiver, | 529 OfflinePageArchiver* archiver, |
| 513 ArchiverResult archiver_result, | 530 ArchiverResult archiver_result, |
| 514 const GURL& url, | 531 const GURL& url, |
| 515 const base::FilePath& file_path, | 532 const base::FilePath& file_path, |
| 516 int64_t file_size) { | 533 int64_t file_size) { |
| 517 if (requested_url != url) { | 534 if (requested_url != url) { |
| 518 DVLOG(1) << "Saved URL does not match requested URL."; | 535 DVLOG(1) << "Saved URL does not match requested URL."; |
| 519 // TODO(fgorski): We have created an archive for a wrong URL. It should be | 536 // TODO(fgorski): We have created an archive for a wrong URL. It should be |
| 520 // deleted from here, once archiver has the right functionality. | 537 // deleted from here, once archiver has the right functionality. |
| 521 InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED, | 538 InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED, |
| 522 offline_id); | 539 client_id, offline_id); |
| 523 DeletePendingArchiver(archiver); | 540 DeletePendingArchiver(archiver); |
| 524 return; | 541 return; |
| 525 } | 542 } |
| 526 | 543 |
| 527 if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) { | 544 if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) { |
| 528 SavePageResult result = ToSavePageResult(archiver_result); | 545 SavePageResult result = ToSavePageResult(archiver_result); |
| 529 InformSavePageDone(callback, result, offline_id); | 546 InformSavePageDone(callback, result, client_id, offline_id); |
| 530 DeletePendingArchiver(archiver); | 547 DeletePendingArchiver(archiver); |
| 531 return; | 548 return; |
| 532 } | 549 } |
| 533 OfflinePageItem offline_page_item(url, offline_id, client_id, file_path, | 550 OfflinePageItem offline_page_item(url, offline_id, client_id, file_path, |
| 534 file_size, start_time); | 551 file_size, start_time); |
| 535 store_->AddOrUpdateOfflinePage( | 552 store_->AddOrUpdateOfflinePage( |
| 536 offline_page_item, | 553 offline_page_item, |
| 537 base::Bind(&OfflinePageModel::OnAddOfflinePageDone, | 554 base::Bind(&OfflinePageModel::OnAddOfflinePageDone, |
| 538 weak_ptr_factory_.GetWeakPtr(), archiver, callback, | 555 weak_ptr_factory_.GetWeakPtr(), archiver, callback, |
| 539 offline_page_item)); | 556 offline_page_item)); |
| 540 } | 557 } |
| 541 | 558 |
| 542 void OfflinePageModel::OnAddOfflinePageDone(OfflinePageArchiver* archiver, | 559 void OfflinePageModel::OnAddOfflinePageDone(OfflinePageArchiver* archiver, |
| 543 const SavePageCallback& callback, | 560 const SavePageCallback& callback, |
| 544 const OfflinePageItem& offline_page, | 561 const OfflinePageItem& offline_page, |
| 545 bool success) { | 562 bool success) { |
| 546 SavePageResult result; | 563 SavePageResult result; |
| 547 if (success) { | 564 if (success) { |
| 548 offline_pages_[offline_page.offline_id] = offline_page; | 565 offline_pages_[offline_page.offline_id] = offline_page; |
| 549 result = SavePageResult::SUCCESS; | 566 result = SavePageResult::SUCCESS; |
| 550 UMA_HISTOGRAM_TIMES( | 567 UMA_HISTOGRAM_TIMES( |
| 551 "OfflinePages.SavePageTime", | 568 AddHistogramSuffix( |
| 569 offline_page.client_id, "OfflinePages.SavePageTime").c_str(), |
| 552 base::Time::Now() - offline_page.creation_time); | 570 base::Time::Now() - offline_page.creation_time); |
| 553 UMA_HISTOGRAM_MEMORY_KB( | 571 UMA_HISTOGRAM_MEMORY_KB( |
| 554 "OfflinePages.PageSize", offline_page.file_size / 1024); | 572 AddHistogramSuffix( |
| 573 offline_page.client_id, "OfflinePages.PageSize").c_str(), |
| 574 offline_page.file_size / 1024); |
| 555 } else { | 575 } else { |
| 556 result = SavePageResult::STORE_FAILURE; | 576 result = SavePageResult::STORE_FAILURE; |
| 557 } | 577 } |
| 558 InformSavePageDone(callback, result, offline_page.offline_id); | 578 InformSavePageDone(callback, result, offline_page.client_id, |
| 579 offline_page.offline_id); |
| 559 DeletePendingArchiver(archiver); | 580 DeletePendingArchiver(archiver); |
| 560 | 581 |
| 561 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this)); | 582 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this)); |
| 562 } | 583 } |
| 563 | 584 |
| 564 void OfflinePageModel::OnMarkPageAccesseDone( | 585 void OfflinePageModel::OnMarkPageAccesseDone( |
| 565 const OfflinePageItem& offline_page_item, bool success) { | 586 const OfflinePageItem& offline_page_item, bool success) { |
| 566 // Update the item in the cache only upon success. | 587 // Update the item in the cache only upon success. |
| 567 if (success) | 588 if (success) |
| 568 offline_pages_[offline_page_item.offline_id] = offline_page_item; | 589 offline_pages_[offline_page_item.offline_id] = offline_page_item; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 delayed_task.Run(); | 621 delayed_task.Run(); |
| 601 delayed_tasks_.clear(); | 622 delayed_tasks_.clear(); |
| 602 | 623 |
| 603 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelLoaded(this)); | 624 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelLoaded(this)); |
| 604 | 625 |
| 605 CheckForExternalFileDeletion(); | 626 CheckForExternalFileDeletion(); |
| 606 } | 627 } |
| 607 | 628 |
| 608 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback, | 629 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback, |
| 609 SavePageResult result, | 630 SavePageResult result, |
| 631 const ClientId& client_id, |
| 610 int64_t offline_id) { | 632 int64_t offline_id) { |
| 611 UMA_HISTOGRAM_ENUMERATION( | 633 UMA_HISTOGRAM_ENUMERATION( |
| 612 "OfflinePages.SavePageResult", | 634 AddHistogramSuffix(client_id, "OfflinePages.SavePageResult").c_str(), |
| 613 static_cast<int>(result), | 635 static_cast<int>(result), |
| 614 static_cast<int>(SavePageResult::RESULT_COUNT)); | 636 static_cast<int>(SavePageResult::RESULT_COUNT)); |
| 615 callback.Run(result, offline_id); | 637 callback.Run(result, offline_id); |
| 616 } | 638 } |
| 617 | 639 |
| 618 void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) { | 640 void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) { |
| 619 pending_archivers_.erase(std::find( | 641 pending_archivers_.erase(std::find( |
| 620 pending_archivers_.begin(), pending_archivers_.end(), archiver)); | 642 pending_archivers_.begin(), pending_archivers_.end(), archiver)); |
| 621 } | 643 } |
| 622 | 644 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 643 bool success) { | 665 bool success) { |
| 644 // Delete the offline page from the in memory cache regardless of success in | 666 // Delete the offline page from the in memory cache regardless of success in |
| 645 // store. | 667 // store. |
| 646 base::Time now = base::Time::Now(); | 668 base::Time now = base::Time::Now(); |
| 647 int64_t total_size = 0; | 669 int64_t total_size = 0; |
| 648 for (int64_t offline_id : offline_ids) { | 670 for (int64_t offline_id : offline_ids) { |
| 649 auto iter = offline_pages_.find(offline_id); | 671 auto iter = offline_pages_.find(offline_id); |
| 650 if (iter == offline_pages_.end()) | 672 if (iter == offline_pages_.end()) |
| 651 continue; | 673 continue; |
| 652 total_size += iter->second.file_size; | 674 total_size += iter->second.file_size; |
| 675 ClientId client_id = iter->second.client_id; |
| 653 UMA_HISTOGRAM_CUSTOM_COUNTS( | 676 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 654 "OfflinePages.PageLifetime", | 677 AddHistogramSuffix(client_id, "OfflinePages.PageLifetime").c_str(), |
| 655 (now - iter->second.creation_time).InMinutes(), | 678 (now - iter->second.creation_time).InMinutes(), |
| 656 1, | 679 1, |
| 657 base::TimeDelta::FromDays(365).InMinutes(), | 680 base::TimeDelta::FromDays(365).InMinutes(), |
| 658 100); | 681 100); |
| 659 UMA_HISTOGRAM_CUSTOM_COUNTS( | 682 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 660 "OfflinePages.DeletePage.TimeSinceLastOpen", | 683 AddHistogramSuffix( |
| 684 client_id, "OfflinePages.DeletePage.TimeSinceLastOpen").c_str(), |
| 661 (now - iter->second.last_access_time).InMinutes(), | 685 (now - iter->second.last_access_time).InMinutes(), |
| 662 1, | 686 1, |
| 663 base::TimeDelta::FromDays(365).InMinutes(), | 687 base::TimeDelta::FromDays(365).InMinutes(), |
| 664 100); | 688 100); |
| 665 UMA_HISTOGRAM_CUSTOM_COUNTS( | 689 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 666 "OfflinePages.DeletePage.LastOpenToCreated", | 690 AddHistogramSuffix( |
| 691 client_id, "OfflinePages.DeletePage.LastOpenToCreated").c_str(), |
| 667 (iter->second.last_access_time - iter->second.creation_time). | 692 (iter->second.last_access_time - iter->second.creation_time). |
| 668 InMinutes(), | 693 InMinutes(), |
| 669 1, | 694 1, |
| 670 base::TimeDelta::FromDays(365).InMinutes(), | 695 base::TimeDelta::FromDays(365).InMinutes(), |
| 671 100); | 696 100); |
| 672 UMA_HISTOGRAM_MEMORY_KB( | 697 UMA_HISTOGRAM_MEMORY_KB( |
| 673 "OfflinePages.DeletePage.PageSize", iter->second.file_size / 1024); | 698 AddHistogramSuffix( |
| 699 client_id, "OfflinePages.DeletePage.PageSize").c_str(), |
| 700 iter->second.file_size / 1024); |
| 674 UMA_HISTOGRAM_COUNTS( | 701 UMA_HISTOGRAM_COUNTS( |
| 675 "OfflinePages.DeletePage.AccessCount", iter->second.access_count); | 702 AddHistogramSuffix( |
| 703 client_id, "OfflinePages.DeletePage.AccessCount").c_str(), |
| 704 iter->second.access_count); |
| 676 FOR_EACH_OBSERVER( | 705 FOR_EACH_OBSERVER( |
| 677 Observer, observers_, | 706 Observer, observers_, |
| 678 OfflinePageDeleted(iter->second.offline_id, iter->second.client_id)); | 707 OfflinePageDeleted(iter->second.offline_id, iter->second.client_id)); |
| 679 offline_pages_.erase(iter); | 708 offline_pages_.erase(iter); |
| 680 } | 709 } |
| 681 if (offline_ids.size() > 1) { | 710 if (offline_ids.size() > 1) { |
| 682 UMA_HISTOGRAM_COUNTS("OfflinePages.BatchDelete.Count", offline_ids.size()); | 711 UMA_HISTOGRAM_COUNTS("OfflinePages.BatchDelete.Count", offline_ids.size()); |
| 683 UMA_HISTOGRAM_MEMORY_KB( | 712 UMA_HISTOGRAM_MEMORY_KB( |
| 684 "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024); | 713 "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024); |
| 685 } | 714 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 void OfflinePageModel::RunWhenLoaded(const base::Closure& task) { | 818 void OfflinePageModel::RunWhenLoaded(const base::Closure& task) { |
| 790 if (!is_loaded_) { | 819 if (!is_loaded_) { |
| 791 delayed_tasks_.push_back(task); | 820 delayed_tasks_.push_back(task); |
| 792 return; | 821 return; |
| 793 } | 822 } |
| 794 | 823 |
| 795 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); | 824 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); |
| 796 } | 825 } |
| 797 | 826 |
| 798 } // namespace offline_pages | 827 } // namespace offline_pages |
| OLD | NEW |