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

Side by Side Diff: components/offline_pages/offline_page_model_impl.cc

Issue 2322833002: Support serving offline page by offline ID (Closed)
Patch Set: Created 4 years, 3 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_impl.h" 5 #include "components/offline_pages/offline_page_model_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/rand_util.h" 15 #include "base/rand_util.h"
16 #include "base/sequenced_task_runner.h" 16 #include "base/sequenced_task_runner.h"
17 #include "base/strings/string16.h" 17 #include "base/strings/string16.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
20 #include "base/time/default_clock.h"
20 #include "base/time/time.h" 21 #include "base/time/time.h"
21 #include "components/offline_pages/archive_manager.h" 22 #include "components/offline_pages/archive_manager.h"
22 #include "components/offline_pages/client_namespace_constants.h" 23 #include "components/offline_pages/client_namespace_constants.h"
23 #include "components/offline_pages/client_policy_controller.h" 24 #include "components/offline_pages/client_policy_controller.h"
24 #include "components/offline_pages/offline_page_item.h" 25 #include "components/offline_pages/offline_page_item.h"
25 #include "components/offline_pages/offline_page_storage_manager.h" 26 #include "components/offline_pages/offline_page_storage_manager.h"
26 #include "url/gurl.h" 27 #include "url/gurl.h"
27 28
28 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult; 29 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult;
29 using ClearStorageCallback = 30 using ClearStorageCallback =
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // Note: The factory creates and owns the histogram. 144 // Note: The factory creates and owns the histogram.
144 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( 145 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet(
145 AddHistogramSuffix(client_id, "OfflinePages.SavePageResult"), 146 AddHistogramSuffix(client_id, "OfflinePages.SavePageResult"),
146 1, 147 1,
147 static_cast<int>(SavePageResult::RESULT_COUNT), 148 static_cast<int>(SavePageResult::RESULT_COUNT),
148 static_cast<int>(SavePageResult::RESULT_COUNT) + 1, 149 static_cast<int>(SavePageResult::RESULT_COUNT) + 1,
149 base::HistogramBase::kUmaTargetedHistogramFlag); 150 base::HistogramBase::kUmaTargetedHistogramFlag);
150 histogram->Add(static_cast<int>(result)); 151 histogram->Add(static_cast<int>(result));
151 } 152 }
152 153
153 void ReportPageHistogramAfterSave(const OfflinePageItem& offline_page) { 154 void ReportPageHistogramAfterSave(const OfflinePageItem& offline_page,
155 base::Clock* clock) {
154 // The histogram below is an expansion of the UMA_HISTOGRAM_TIMES 156 // The histogram below is an expansion of the UMA_HISTOGRAM_TIMES
155 // macro adapted to allow for a dynamically suffixed histogram name. 157 // macro adapted to allow for a dynamically suffixed histogram name.
156 // Note: The factory creates and owns the histogram. 158 // Note: The factory creates and owns the histogram.
157 base::HistogramBase* histogram = base::Histogram::FactoryTimeGet( 159 base::HistogramBase* histogram = base::Histogram::FactoryTimeGet(
158 AddHistogramSuffix(offline_page.client_id, "OfflinePages.SavePageTime"), 160 AddHistogramSuffix(offline_page.client_id, "OfflinePages.SavePageTime"),
159 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(10), 161 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(10),
160 50, base::HistogramBase::kUmaTargetedHistogramFlag); 162 50, base::HistogramBase::kUmaTargetedHistogramFlag);
161 histogram->AddTime(base::Time::Now() - offline_page.creation_time); 163 histogram->AddTime(clock->Now() - offline_page.creation_time);
162 164
163 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS 165 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS
164 // macro adapted to allow for a dynamically suffixed histogram name. 166 // macro adapted to allow for a dynamically suffixed histogram name.
165 // Note: The factory creates and owns the histogram. 167 // Note: The factory creates and owns the histogram.
166 // Reported as Kb between 1Kb and 10Mb. 168 // Reported as Kb between 1Kb and 10Mb.
167 histogram = base::Histogram::FactoryGet( 169 histogram = base::Histogram::FactoryGet(
168 AddHistogramSuffix(offline_page.client_id, "OfflinePages.PageSize"), 170 AddHistogramSuffix(offline_page.client_id, "OfflinePages.PageSize"),
169 1, 10000, 50, base::HistogramBase::kUmaTargetedHistogramFlag); 171 1, 10000, 50, base::HistogramBase::kUmaTargetedHistogramFlag);
170 histogram->Add(offline_page.file_size / 1024); 172 histogram->Add(offline_page.file_size / 1024);
171 } 173 }
172 174
173 void ReportPageHistogramsAfterDelete( 175 void ReportPageHistogramsAfterDelete(
174 const std::map<int64_t, OfflinePageItem>& offline_pages, 176 const std::map<int64_t, OfflinePageItem>& offline_pages,
175 const std::vector<int64_t>& deleted_offline_ids) { 177 const std::vector<int64_t>& deleted_offline_ids,
178 base::Clock* clock) {
176 const int max_minutes = base::TimeDelta::FromDays(365).InMinutes(); 179 const int max_minutes = base::TimeDelta::FromDays(365).InMinutes();
177 base::Time now = base::Time::Now(); 180 base::Time now = clock->Now();
178 int64_t total_size = 0; 181 int64_t total_size = 0;
179 for (int64_t offline_id : deleted_offline_ids) { 182 for (int64_t offline_id : deleted_offline_ids) {
180 auto iter = offline_pages.find(offline_id); 183 auto iter = offline_pages.find(offline_id);
181 if (iter == offline_pages.end()) 184 if (iter == offline_pages.end())
182 continue; 185 continue;
183 total_size += iter->second.file_size; 186 total_size += iter->second.file_size;
184 ClientId client_id = iter->second.client_id; 187 ClientId client_id = iter->second.client_id;
185 188
186 // The histograms below are an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS 189 // The histograms below are an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS
187 // macro adapted to allow for a dynamically suffixed histogram name. 190 // macro adapted to allow for a dynamically suffixed histogram name.
(...skipping 30 matching lines...) Expand all
218 } 221 }
219 222
220 if (deleted_offline_ids.size() > 1) { 223 if (deleted_offline_ids.size() > 1) {
221 UMA_HISTOGRAM_COUNTS("OfflinePages.BatchDelete.Count", 224 UMA_HISTOGRAM_COUNTS("OfflinePages.BatchDelete.Count",
222 static_cast<int32_t>(deleted_offline_ids.size())); 225 static_cast<int32_t>(deleted_offline_ids.size()));
223 UMA_HISTOGRAM_MEMORY_KB( 226 UMA_HISTOGRAM_MEMORY_KB(
224 "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024); 227 "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024);
225 } 228 }
226 } 229 }
227 230
228 void ReportPageHistogramsAfterAccess(const OfflinePageItem& offline_page_item) { 231 void ReportPageHistogramsAfterAccess(const OfflinePageItem& offline_page_item,
232 base::Clock* clock) {
229 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS 233 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS
230 // macro adapted to allow for a dynamically suffixed histogram name. 234 // macro adapted to allow for a dynamically suffixed histogram name.
231 // Note: The factory creates and owns the histogram. 235 // Note: The factory creates and owns the histogram.
232 base::HistogramBase* histogram = base::Histogram::FactoryGet( 236 base::HistogramBase* histogram = base::Histogram::FactoryGet(
233 AddHistogramSuffix( 237 AddHistogramSuffix(
234 offline_page_item.client_id, 238 offline_page_item.client_id,
235 offline_page_item.access_count == 0 ? 239 offline_page_item.access_count == 0 ?
236 "OfflinePages.FirstOpenSinceCreated" : 240 "OfflinePages.FirstOpenSinceCreated" :
237 "OfflinePages.OpenSinceLastOpen"), 241 "OfflinePages.OpenSinceLastOpen"),
238 1, kMaxOpenedPageHistogramBucket.InMinutes(), 50, 242 1, kMaxOpenedPageHistogramBucket.InMinutes(), 50,
239 base::HistogramBase::kUmaTargetedHistogramFlag); 243 base::HistogramBase::kUmaTargetedHistogramFlag);
240 histogram->Add( 244 histogram->Add(
241 (base::Time::Now() - offline_page_item.last_access_time).InMinutes()); 245 (clock->Now() - offline_page_item.last_access_time).InMinutes());
242 } 246 }
243 247
244 } // namespace 248 } // namespace
245 249
246 // protected 250 // protected
247 OfflinePageModelImpl::OfflinePageModelImpl() 251 OfflinePageModelImpl::OfflinePageModelImpl()
248 : OfflinePageModel(), is_loaded_(false), weak_ptr_factory_(this) {} 252 : OfflinePageModel(), is_loaded_(false), weak_ptr_factory_(this) {}
249 253
250 OfflinePageModelImpl::OfflinePageModelImpl( 254 OfflinePageModelImpl::OfflinePageModelImpl(
251 std::unique_ptr<OfflinePageMetadataStore> store, 255 std::unique_ptr<OfflinePageMetadataStore> store,
252 const base::FilePath& archives_dir, 256 const base::FilePath& archives_dir,
253 const scoped_refptr<base::SequencedTaskRunner>& task_runner) 257 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
254 : store_(std::move(store)), 258 : store_(std::move(store)),
255 archives_dir_(archives_dir), 259 archives_dir_(archives_dir),
256 is_loaded_(false), 260 is_loaded_(false),
257 policy_controller_(new ClientPolicyController()), 261 policy_controller_(new ClientPolicyController()),
258 archive_manager_(new ArchiveManager(archives_dir, task_runner)), 262 archive_manager_(new ArchiveManager(archives_dir, task_runner)),
263 clock_(new base::DefaultClock()),
259 weak_ptr_factory_(this) { 264 weak_ptr_factory_(this) {
260 archive_manager_->EnsureArchivesDirCreated( 265 archive_manager_->EnsureArchivesDirCreated(
261 base::Bind(&OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone, 266 base::Bind(&OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone,
262 weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now())); 267 weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()));
263 } 268 }
264 269
265 OfflinePageModelImpl::~OfflinePageModelImpl() {} 270 OfflinePageModelImpl::~OfflinePageModelImpl() {}
266 271
267 void OfflinePageModelImpl::AddObserver(Observer* observer) { 272 void OfflinePageModelImpl::AddObserver(Observer* observer) {
268 observers_.AddObserver(observer); 273 observers_.AddObserver(observer);
(...skipping 27 matching lines...) Expand all
296 } 301 }
297 302
298 // If we already have an offline id, use it. If not, generate one. 303 // If we already have an offline id, use it. If not, generate one.
299 if (proposed_offline_id == 0l) 304 if (proposed_offline_id == 0l)
300 proposed_offline_id = GenerateOfflineId(); 305 proposed_offline_id = GenerateOfflineId();
301 306
302 archiver->CreateArchive( 307 archiver->CreateArchive(
303 archives_dir_, proposed_offline_id, 308 archives_dir_, proposed_offline_id,
304 base::Bind(&OfflinePageModelImpl::OnCreateArchiveDone, 309 base::Bind(&OfflinePageModelImpl::OnCreateArchiveDone,
305 weak_ptr_factory_.GetWeakPtr(), url, proposed_offline_id, 310 weak_ptr_factory_.GetWeakPtr(), url, proposed_offline_id,
306 client_id, base::Time::Now(), callback)); 311 client_id, clock_->Now(), callback));
307 pending_archivers_.push_back(std::move(archiver)); 312 pending_archivers_.push_back(std::move(archiver));
308 } 313 }
309 314
310 void OfflinePageModelImpl::MarkPageAccessed(int64_t offline_id) { 315 void OfflinePageModelImpl::MarkPageAccessed(int64_t offline_id) {
311 RunWhenLoaded(base::Bind(&OfflinePageModelImpl::MarkPageAccessedWhenLoadDone, 316 RunWhenLoaded(base::Bind(&OfflinePageModelImpl::MarkPageAccessedWhenLoadDone,
312 weak_ptr_factory_.GetWeakPtr(), offline_id)); 317 weak_ptr_factory_.GetWeakPtr(), offline_id));
313 } 318 }
314 319
315 void OfflinePageModelImpl::MarkPageAccessedWhenLoadDone(int64_t offline_id) { 320 void OfflinePageModelImpl::MarkPageAccessedWhenLoadDone(int64_t offline_id) {
316 DCHECK(is_loaded_); 321 DCHECK(is_loaded_);
317 322
318 auto iter = offline_pages_.find(offline_id); 323 auto iter = offline_pages_.find(offline_id);
319 if (iter == offline_pages_.end() || iter->second.IsExpired()) 324 if (iter == offline_pages_.end() || iter->second.IsExpired())
320 return; 325 return;
321 326
322 // Make a copy of the cached item and update it. The cached item should only 327 // Make a copy of the cached item and update it. The cached item should only
323 // be updated upon the successful store operation. 328 // be updated upon the successful store operation.
324 OfflinePageItem offline_page_item = iter->second; 329 OfflinePageItem offline_page_item = iter->second;
325 330
326 ReportPageHistogramsAfterAccess(offline_page_item); 331 ReportPageHistogramsAfterAccess(offline_page_item, clock_.get());
327 332
328 offline_page_item.last_access_time = base::Time::Now(); 333 offline_page_item.last_access_time = clock_->Now();
329 offline_page_item.access_count++; 334 offline_page_item.access_count++;
330 335
331 store_->AddOrUpdateOfflinePage( 336 store_->AddOrUpdateOfflinePage(
332 offline_page_item, 337 offline_page_item,
333 base::Bind(&OfflinePageModelImpl::OnMarkPageAccesseDone, 338 base::Bind(&OfflinePageModelImpl::OnMarkPageAccesseDone,
334 weak_ptr_factory_.GetWeakPtr(), offline_page_item)); 339 weak_ptr_factory_.GetWeakPtr(), offline_page_item));
335 } 340 }
336 341
337 void OfflinePageModelImpl::DeletePagesByOfflineId( 342 void OfflinePageModelImpl::DeletePagesByOfflineId(
338 const std::vector<int64_t>& offline_ids, 343 const std::vector<int64_t>& offline_ids,
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 } 677 }
673 678
674 ClientPolicyController* OfflinePageModelImpl::GetPolicyController() { 679 ClientPolicyController* OfflinePageModelImpl::GetPolicyController() {
675 return policy_controller_.get(); 680 return policy_controller_.get();
676 } 681 }
677 682
678 OfflinePageMetadataStore* OfflinePageModelImpl::GetStoreForTesting() { 683 OfflinePageMetadataStore* OfflinePageModelImpl::GetStoreForTesting() {
679 return store_.get(); 684 return store_.get();
680 } 685 }
681 686
687 void OfflinePageModelImpl::SetClockForTesting(
688 std::unique_ptr<base::Clock> clock) {
689 clock_ = std::move(clock);
690 }
691
682 OfflinePageStorageManager* OfflinePageModelImpl::GetStorageManager() { 692 OfflinePageStorageManager* OfflinePageModelImpl::GetStorageManager() {
683 return storage_manager_.get(); 693 return storage_manager_.get();
684 } 694 }
685 695
686 bool OfflinePageModelImpl::is_loaded() const { 696 bool OfflinePageModelImpl::is_loaded() const {
687 return is_loaded_; 697 return is_loaded_;
688 } 698 }
689 699
690 OfflineEventLogger* OfflinePageModelImpl::GetLogger() { 700 OfflineEventLogger* OfflinePageModelImpl::GetLogger() {
691 return &offline_event_logger_; 701 return &offline_event_logger_;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 739
730 void OfflinePageModelImpl::OnAddOfflinePageDone( 740 void OfflinePageModelImpl::OnAddOfflinePageDone(
731 OfflinePageArchiver* archiver, 741 OfflinePageArchiver* archiver,
732 const SavePageCallback& callback, 742 const SavePageCallback& callback,
733 const OfflinePageItem& offline_page, 743 const OfflinePageItem& offline_page,
734 bool success) { 744 bool success) {
735 SavePageResult result; 745 SavePageResult result;
736 if (success) { 746 if (success) {
737 offline_pages_[offline_page.offline_id] = offline_page; 747 offline_pages_[offline_page.offline_id] = offline_page;
738 result = SavePageResult::SUCCESS; 748 result = SavePageResult::SUCCESS;
739 ReportPageHistogramAfterSave(offline_page); 749 ReportPageHistogramAfterSave(offline_page, clock_.get());
740 offline_event_logger_.RecordPageSaved( 750 offline_event_logger_.RecordPageSaved(
741 offline_page.client_id.name_space, offline_page.url.spec(), 751 offline_page.client_id.name_space, offline_page.url.spec(),
742 std::to_string(offline_page.offline_id)); 752 std::to_string(offline_page.offline_id));
743 } else { 753 } else {
744 result = SavePageResult::STORE_FAILURE; 754 result = SavePageResult::STORE_FAILURE;
745 } 755 }
746 InformSavePageDone(callback, result, offline_page.client_id, 756 InformSavePageDone(callback, result, offline_page.client_id,
747 offline_page.offline_id); 757 offline_page.offline_id);
748 if (result == SavePageResult::SUCCESS) { 758 if (result == SavePageResult::SUCCESS) {
749 DeleteExistingPagesWithSameURL(offline_page); 759 DeleteExistingPagesWithSameURL(offline_page);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 store_->RemoveOfflinePages( 898 store_->RemoveOfflinePages(
889 offline_ids, 899 offline_ids,
890 base::Bind(&OfflinePageModelImpl::OnRemoveOfflinePagesDone, 900 base::Bind(&OfflinePageModelImpl::OnRemoveOfflinePagesDone,
891 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback)); 901 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback));
892 } 902 }
893 903
894 void OfflinePageModelImpl::OnRemoveOfflinePagesDone( 904 void OfflinePageModelImpl::OnRemoveOfflinePagesDone(
895 const std::vector<int64_t>& offline_ids, 905 const std::vector<int64_t>& offline_ids,
896 const DeletePageCallback& callback, 906 const DeletePageCallback& callback,
897 bool success) { 907 bool success) {
898 ReportPageHistogramsAfterDelete(offline_pages_, offline_ids); 908 ReportPageHistogramsAfterDelete(offline_pages_, offline_ids, clock_.get());
899 909
900 for (int64_t offline_id : offline_ids) { 910 for (int64_t offline_id : offline_ids) {
901 offline_event_logger_.RecordPageDeleted(std::to_string(offline_id)); 911 offline_event_logger_.RecordPageDeleted(std::to_string(offline_id));
902 auto iter = offline_pages_.find(offline_id); 912 auto iter = offline_pages_.find(offline_id);
903 if (iter == offline_pages_.end()) 913 if (iter == offline_pages_.end())
904 continue; 914 continue;
905 FOR_EACH_OBSERVER( 915 FOR_EACH_OBSERVER(
906 Observer, observers_, 916 Observer, observers_,
907 OfflinePageDeleted(iter->second.offline_id, iter->second.client_id)); 917 OfflinePageDeleted(iter->second.offline_id, iter->second.client_id));
908 offline_pages_.erase(iter); 918 offline_pages_.erase(iter);
(...skipping 28 matching lines...) Expand all
937 std::vector<int64_t> ids_of_pages_missing_archive_file; 947 std::vector<int64_t> ids_of_pages_missing_archive_file;
938 for (const auto& id_page_pair : offline_pages_) { 948 for (const auto& id_page_pair : offline_pages_) {
939 if (archive_paths.count(id_page_pair.second.file_path) == 0UL) 949 if (archive_paths.count(id_page_pair.second.file_path) == 0UL)
940 ids_of_pages_missing_archive_file.push_back(id_page_pair.first); 950 ids_of_pages_missing_archive_file.push_back(id_page_pair.first);
941 } 951 }
942 952
943 if (ids_of_pages_missing_archive_file.empty()) 953 if (ids_of_pages_missing_archive_file.empty())
944 return; 954 return;
945 955
946 ExpirePages( 956 ExpirePages(
947 ids_of_pages_missing_archive_file, base::Time::Now(), 957 ids_of_pages_missing_archive_file, clock_->Now(),
948 base::Bind(&OfflinePageModelImpl::OnExpirePagesMissingArchiveFileDone, 958 base::Bind(&OfflinePageModelImpl::OnExpirePagesMissingArchiveFileDone,
949 weak_ptr_factory_.GetWeakPtr(), 959 weak_ptr_factory_.GetWeakPtr(),
950 ids_of_pages_missing_archive_file)); 960 ids_of_pages_missing_archive_file));
951 } 961 }
952 962
953 void OfflinePageModelImpl::OnExpirePagesMissingArchiveFileDone( 963 void OfflinePageModelImpl::OnExpirePagesMissingArchiveFileDone(
954 const std::vector<int64_t>& offline_ids, 964 const std::vector<int64_t>& offline_ids,
955 bool success) { 965 bool success) {
956 UMA_HISTOGRAM_COUNTS("OfflinePages.Consistency.PagesMissingArchiveFileCount", 966 UMA_HISTOGRAM_COUNTS("OfflinePages.Consistency.PagesMissingArchiveFileCount",
957 static_cast<int32_t>(offline_ids.size())); 967 static_cast<int32_t>(offline_ids.size()));
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 void OfflinePageModelImpl::RunWhenLoaded(const base::Closure& task) { 1080 void OfflinePageModelImpl::RunWhenLoaded(const base::Closure& task) {
1071 if (!is_loaded_) { 1081 if (!is_loaded_) {
1072 delayed_tasks_.push_back(task); 1082 delayed_tasks_.push_back(task);
1073 return; 1083 return;
1074 } 1084 }
1075 1085
1076 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); 1086 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
1077 } 1087 }
1078 1088
1079 } // namespace offline_pages 1089 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698