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

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

Issue 1902593006: [Offline pages] Removing undoing of deleting offline pages (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bookmarks-out
Patch Set: Created 4 years, 8 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 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 25 matching lines...) Expand all
36 STORE_RELOAD_FAILED, 36 STORE_RELOAD_FAILED,
37 37
38 // NOTE: always keep this entry at the end. 38 // NOTE: always keep this entry at the end.
39 CLEAR_ALL_STATUS_COUNT 39 CLEAR_ALL_STATUS_COUNT
40 }; 40 };
41 41
42 // Threshold for how old offline copy of a page should be before we offer to 42 // Threshold for how old offline copy of a page should be before we offer to
43 // delete it to free up space. 43 // delete it to free up space.
44 const base::TimeDelta kPageCleanUpThreshold = base::TimeDelta::FromDays(30); 44 const base::TimeDelta kPageCleanUpThreshold = base::TimeDelta::FromDays(30);
45 45
46 // The delay for the final deletion to kick in after the page is marked for
47 // deletion. The value set here is a bit longer that the duration of the
48 // snackbar that offers undo.
49 const base::TimeDelta kFinalDeletionDelay = base::TimeDelta::FromSeconds(6);
50
51 // The maximum histogram size for the metrics that measure time between views of 46 // The maximum histogram size for the metrics that measure time between views of
52 // a given page. 47 // a given page.
53 const base::TimeDelta kMaxOpenedPageHistogramBucket = 48 const base::TimeDelta kMaxOpenedPageHistogramBucket =
54 base::TimeDelta::FromDays(90); 49 base::TimeDelta::FromDays(90);
55 50
56 SavePageResult ToSavePageResult(ArchiverResult archiver_result) { 51 SavePageResult ToSavePageResult(ArchiverResult archiver_result) {
57 SavePageResult result; 52 SavePageResult result;
58 switch (archiver_result) { 53 switch (archiver_result) {
59 case ArchiverResult::SUCCESSFULLY_CREATED: 54 case ArchiverResult::SUCCESSFULLY_CREATED:
60 result = SavePageResult::SUCCESS; 55 result = SavePageResult::SUCCESS;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 CHECK(base::CreateDirectory(archives_dir)); 99 CHECK(base::CreateDirectory(archives_dir));
105 } 100 }
106 101
107 } // namespace 102 } // namespace
108 103
109 // static 104 // static
110 bool OfflinePageModel::CanSavePage(const GURL& url) { 105 bool OfflinePageModel::CanSavePage(const GURL& url) {
111 return url.SchemeIsHTTPOrHTTPS(); 106 return url.SchemeIsHTTPOrHTTPS();
112 } 107 }
113 108
114 // static
115 base::TimeDelta OfflinePageModel::GetFinalDeletionDelayForTesting() {
116 return kFinalDeletionDelay;
117 }
118
119 OfflinePageModel::OfflinePageModel( 109 OfflinePageModel::OfflinePageModel(
120 scoped_ptr<OfflinePageMetadataStore> store, 110 scoped_ptr<OfflinePageMetadataStore> store,
121 const base::FilePath& archives_dir, 111 const base::FilePath& archives_dir,
122 const scoped_refptr<base::SequencedTaskRunner>& task_runner) 112 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
123 : store_(std::move(store)), 113 : store_(std::move(store)),
124 archives_dir_(archives_dir), 114 archives_dir_(archives_dir),
125 is_loaded_(false), 115 is_loaded_(false),
126 task_runner_(task_runner), 116 task_runner_(task_runner),
127 weak_ptr_factory_(this) { 117 weak_ptr_factory_(this) {
128 task_runner_->PostTaskAndReply( 118 task_runner_->PostTaskAndReply(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 client_id, base::Time::Now(), callback)); 157 client_id, base::Time::Now(), callback));
168 pending_archivers_.push_back(std::move(archiver)); 158 pending_archivers_.push_back(std::move(archiver));
169 } 159 }
170 160
171 void OfflinePageModel::MarkPageAccessed(int64_t offline_id) { 161 void OfflinePageModel::MarkPageAccessed(int64_t offline_id) {
172 DCHECK(is_loaded_); 162 DCHECK(is_loaded_);
173 auto iter = offline_pages_.find(offline_id); 163 auto iter = offline_pages_.find(offline_id);
174 if (iter == offline_pages_.end()) 164 if (iter == offline_pages_.end())
175 return; 165 return;
176 166
177 // MarkPageAccessed should not be called for a page that is being marked for
178 // deletion.
179 DCHECK(!iter->second.IsMarkedForDeletion());
180
181 // Make a copy of the cached item and update it. The cached item should only 167 // Make a copy of the cached item and update it. The cached item should only
182 // be updated upon the successful store operation. 168 // be updated upon the successful store operation.
183 OfflinePageItem offline_page_item = iter->second; 169 OfflinePageItem offline_page_item = iter->second;
184 170
185 base::Time now = base::Time::Now(); 171 base::Time now = base::Time::Now();
186 base::TimeDelta time_since_last_accessed = 172 base::TimeDelta time_since_last_accessed =
187 now - offline_page_item.last_access_time; 173 now - offline_page_item.last_access_time;
188 174
189 // The last access time was set to same as creation time when the page was 175 // The last access time was set to same as creation time when the page was
190 // created. 176 // created.
191 if (offline_page_item.creation_time == offline_page_item.last_access_time) { 177 if (offline_page_item.creation_time == offline_page_item.last_access_time) {
192 UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.FirstOpenSinceCreated", 178 UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.FirstOpenSinceCreated",
193 time_since_last_accessed.InMinutes(), 1, 179 time_since_last_accessed.InMinutes(), 1,
194 kMaxOpenedPageHistogramBucket.InMinutes(), 50); 180 kMaxOpenedPageHistogramBucket.InMinutes(), 50);
195 } else { 181 } else {
196 UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.OpenSinceLastOpen", 182 UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.OpenSinceLastOpen",
197 time_since_last_accessed.InMinutes(), 1, 183 time_since_last_accessed.InMinutes(), 1,
198 kMaxOpenedPageHistogramBucket.InMinutes(), 50); 184 kMaxOpenedPageHistogramBucket.InMinutes(), 50);
199 } 185 }
200 186
201 offline_page_item.last_access_time = now; 187 offline_page_item.last_access_time = now;
202 offline_page_item.access_count++; 188 offline_page_item.access_count++;
203 189
204 store_->AddOrUpdateOfflinePage( 190 store_->AddOrUpdateOfflinePage(
205 offline_page_item, 191 offline_page_item,
206 base::Bind(&OfflinePageModel::OnMarkPageAccesseDone, 192 base::Bind(&OfflinePageModel::OnMarkPageAccesseDone,
207 weak_ptr_factory_.GetWeakPtr(), offline_page_item)); 193 weak_ptr_factory_.GetWeakPtr(), offline_page_item));
208 } 194 }
209 195
210 void OfflinePageModel::MarkPageForDeletion(int64_t offline_id,
211 const DeletePageCallback& callback) {
212 DCHECK(is_loaded_);
213 auto iter = offline_pages_.find(offline_id);
214 if (iter == offline_pages_.end()) {
215 InformDeletePageDone(callback, DeletePageResult::NOT_FOUND);
216 return;
217 }
218
219 // Make a copy of the cached item and update it. The cached item should only
220 // be updated upon the successful store operation.
221 OfflinePageItem offline_page_item = iter->second;
222 offline_page_item.MarkForDeletion();
223 store_->AddOrUpdateOfflinePage(
224 offline_page_item,
225 base::Bind(&OfflinePageModel::OnMarkPageForDeletionDone,
226 weak_ptr_factory_.GetWeakPtr(), offline_page_item, callback));
227 }
228
229 void OfflinePageModel::DeletePagesByOfflineId( 196 void OfflinePageModel::DeletePagesByOfflineId(
230 const std::vector<int64_t>& offline_ids, 197 const std::vector<int64_t>& offline_ids,
231 const DeletePageCallback& callback) { 198 const DeletePageCallback& callback) {
232 if (!is_loaded_) { 199 if (!is_loaded_) {
233 delayed_tasks_.push_back( 200 delayed_tasks_.push_back(
234 base::Bind(&OfflinePageModel::DoDeletePagesByOfflineId, 201 base::Bind(&OfflinePageModel::DoDeletePagesByOfflineId,
235 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback)); 202 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback));
236 203
237 return; 204 return;
238 } 205 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 DoDeletePagesByURLPredicate(predicate, callback); 257 DoDeletePagesByURLPredicate(predicate, callback);
291 } 258 }
292 259
293 void OfflinePageModel::DoDeletePagesByURLPredicate( 260 void OfflinePageModel::DoDeletePagesByURLPredicate(
294 const base::Callback<bool(const GURL&)>& predicate, 261 const base::Callback<bool(const GURL&)>& predicate,
295 const DeletePageCallback& callback) { 262 const DeletePageCallback& callback) {
296 DCHECK(is_loaded_); 263 DCHECK(is_loaded_);
297 264
298 std::vector<int64_t> offline_ids; 265 std::vector<int64_t> offline_ids;
299 for (const auto& id_page_pair : offline_pages_) { 266 for (const auto& id_page_pair : offline_pages_) {
300 if (!id_page_pair.second.IsMarkedForDeletion() && 267 if (predicate.Run(id_page_pair.second.url))
301 predicate.Run(id_page_pair.second.url)) {
302 offline_ids.push_back(id_page_pair.first); 268 offline_ids.push_back(id_page_pair.first);
303 }
304 } 269 }
305 DoDeletePagesByOfflineId(offline_ids, callback); 270 DoDeletePagesByOfflineId(offline_ids, callback);
306 } 271 }
307 272
308 void OfflinePageModel::HasPages(const std::string& name_space, 273 void OfflinePageModel::HasPages(const std::string& name_space,
309 const HasPagesCallback& callback) { 274 const HasPagesCallback& callback) {
310 RunWhenLoaded(base::Bind(&OfflinePageModel::HasPagesAfterLoadDone, 275 RunWhenLoaded(base::Bind(&OfflinePageModel::HasPagesAfterLoadDone,
311 weak_ptr_factory_.GetWeakPtr(), name_space, 276 weak_ptr_factory_.GetWeakPtr(), name_space,
312 callback)); 277 callback));
313 } 278 }
314 279
315 void OfflinePageModel::HasPagesAfterLoadDone( 280 void OfflinePageModel::HasPagesAfterLoadDone(
316 const std::string& name_space, 281 const std::string& name_space,
317 const HasPagesCallback& callback) const { 282 const HasPagesCallback& callback) const {
318 callback.Run(MaybeHasPages(name_space)); 283 callback.Run(MaybeHasPages(name_space));
319 } 284 }
320 285
321 bool OfflinePageModel::MaybeHasPages(const std::string& name_space) const { 286 bool OfflinePageModel::MaybeHasPages(const std::string& name_space) const {
322 if (!is_loaded_) 287 if (!is_loaded_)
323 return false; 288 return false;
324 289
325 for (const auto& id_page_pair : offline_pages_) { 290 for (const auto& id_page_pair : offline_pages_) {
326 if (!id_page_pair.second.IsMarkedForDeletion() && 291 if (id_page_pair.second.client_id.name_space == name_space)
327 id_page_pair.second.client_id.name_space == name_space) {
328 return true; 292 return true;
329 }
330 } 293 }
331 294
332 return false; 295 return false;
333 } 296 }
334 297
335 void OfflinePageModel::GetAllPages(const GetAllPagesCallback& callback) { 298 void OfflinePageModel::GetAllPages(const GetAllPagesCallback& callback) {
336 if (!is_loaded_) { 299 if (!is_loaded_) {
337 delayed_tasks_.push_back( 300 delayed_tasks_.push_back(
338 base::Bind(&OfflinePageModel::GetAllPagesAfterLoadDone, 301 base::Bind(&OfflinePageModel::GetAllPagesAfterLoadDone,
339 weak_ptr_factory_.GetWeakPtr(), callback)); 302 weak_ptr_factory_.GetWeakPtr(), callback));
340 return; 303 return;
341 } 304 }
342 305
343 GetAllPagesAfterLoadDone(callback); 306 GetAllPagesAfterLoadDone(callback);
344 } 307 }
345 308
346 void OfflinePageModel::GetAllPagesAfterLoadDone( 309 void OfflinePageModel::GetAllPagesAfterLoadDone(
347 const GetAllPagesCallback& callback) { 310 const GetAllPagesCallback& callback) {
348 DCHECK(is_loaded_); 311 DCHECK(is_loaded_);
349 312
350 std::vector<OfflinePageItem> offline_pages; 313 std::vector<OfflinePageItem> offline_pages;
351 for (const auto& id_page_pair : offline_pages_) { 314 for (const auto& id_page_pair : offline_pages_)
352 if (id_page_pair.second.IsMarkedForDeletion())
353 continue;
354 offline_pages.push_back(id_page_pair.second); 315 offline_pages.push_back(id_page_pair.second);
355 }
356 316
357 callback.Run(offline_pages); 317 callback.Run(offline_pages);
358 } 318 }
359 319
360 const std::vector<OfflinePageItem> OfflinePageModel::GetPagesToCleanUp() const { 320 const std::vector<OfflinePageItem> OfflinePageModel::GetPagesToCleanUp() const {
361 DCHECK(is_loaded_); 321 DCHECK(is_loaded_);
362 std::vector<OfflinePageItem> offline_pages; 322 std::vector<OfflinePageItem> offline_pages;
363 base::Time now = base::Time::Now(); 323 base::Time now = base::Time::Now();
364 for (const auto& id_page_pair : offline_pages_) { 324 for (const auto& id_page_pair : offline_pages_) {
365 if (!id_page_pair.second.IsMarkedForDeletion() && 325 if (now - id_page_pair.second.last_access_time > kPageCleanUpThreshold)
366 now - id_page_pair.second.last_access_time > kPageCleanUpThreshold) {
367 offline_pages.push_back(id_page_pair.second); 326 offline_pages.push_back(id_page_pair.second);
368 }
369 } 327 }
370 return offline_pages; 328 return offline_pages;
371 } 329 }
372 330
331 // TODO(fgorski): Remove include_deleted, as it no longer makes sense.
373 const std::vector<int64_t> OfflinePageModel::GetOfflineIdsForClientId( 332 const std::vector<int64_t> OfflinePageModel::GetOfflineIdsForClientId(
374 const ClientId& client_id, 333 const ClientId& client_id,
375 bool include_deleted) const { 334 bool include_deleted) const {
376 DCHECK(is_loaded_); 335 DCHECK(is_loaded_);
377 std::vector<int64_t> results; 336 std::vector<int64_t> results;
378 337
379 // We want only all pages, including those marked for deletion. 338 // We want only all pages, including those marked for deletion.
380 // TODO(bburns): actually use an index rather than linear scan. 339 // TODO(bburns): actually use an index rather than linear scan.
381 for (const auto& id_page_pair : offline_pages_) { 340 for (const auto& id_page_pair : offline_pages_) {
382 if (id_page_pair.second.client_id == client_id) { 341 if (id_page_pair.second.client_id == client_id)
383 if (include_deleted || !id_page_pair.second.IsMarkedForDeletion()) { 342 results.push_back(id_page_pair.second.offline_id);
384 results.push_back(id_page_pair.second.offline_id);
385 }
386 }
387 } 343 }
388 return results; 344 return results;
389 } 345 }
390 346
391 const OfflinePageItem* OfflinePageModel::GetPageByOfflineId( 347 const OfflinePageItem* OfflinePageModel::GetPageByOfflineId(
392 int64_t offline_id) const { 348 int64_t offline_id) const {
393 const auto iter = offline_pages_.find(offline_id); 349 const auto iter = offline_pages_.find(offline_id);
394 return iter != offline_pages_.end() && !iter->second.IsMarkedForDeletion() 350 return iter != offline_pages_.end() ? &(iter->second) : nullptr;
395 ? &(iter->second)
396 : nullptr;
397 } 351 }
398 352
399 const OfflinePageItem* OfflinePageModel::GetPageByOfflineURL( 353 const OfflinePageItem* OfflinePageModel::GetPageByOfflineURL(
400 const GURL& offline_url) const { 354 const GURL& offline_url) const {
401 for (auto iter = offline_pages_.begin(); 355 for (const auto& id_page_pair : offline_pages_) {
402 iter != offline_pages_.end(); 356 if (id_page_pair.second.GetOfflineURL() == offline_url)
403 ++iter) { 357 return &(id_page_pair.second);
404 if (iter->second.GetOfflineURL() == offline_url &&
405 !iter->second.IsMarkedForDeletion()) {
406 return &(iter->second);
407 }
408 } 358 }
409 return nullptr; 359 return nullptr;
410 } 360 }
411 361
412 const OfflinePageItem* OfflinePageModel::GetPageByOnlineURL( 362 const OfflinePageItem* OfflinePageModel::GetPageByOnlineURL(
413 const GURL& online_url) const { 363 const GURL& online_url) const {
414 for (auto iter = offline_pages_.begin(); iter != offline_pages_.end(); 364 for (const auto& id_page_pair : offline_pages_) {
415 ++iter) { 365 if (id_page_pair.second.url == online_url)
416 if (iter->second.url == online_url && !iter->second.IsMarkedForDeletion()) 366 return &(id_page_pair.second);
417 return &(iter->second);
418 } 367 }
419 return nullptr; 368 return nullptr;
420 } 369 }
421 370
422 void OfflinePageModel::CheckForExternalFileDeletion() { 371 void OfflinePageModel::CheckForExternalFileDeletion() {
423 DCHECK(is_loaded_); 372 DCHECK(is_loaded_);
424 373
425 std::vector<std::pair<int64_t, base::FilePath>> id_path_pairs; 374 std::vector<std::pair<int64_t, base::FilePath>> id_path_pairs;
426 for (const auto& id_page_pair : offline_pages_) { 375 for (const auto& id_page_pair : offline_pages_) {
427 id_path_pairs.push_back( 376 id_path_pairs.push_back(
428 std::make_pair(id_page_pair.first, id_page_pair.second.file_path)); 377 std::make_pair(id_page_pair.first, id_page_pair.second.file_path));
429 } 378 }
430 379
431 std::vector<int64_t>* ids_of_pages_missing_archive_file = 380 std::vector<int64_t>* ids_of_pages_missing_archive_file =
432 new std::vector<int64_t>(); 381 new std::vector<int64_t>();
433 task_runner_->PostTaskAndReply( 382 task_runner_->PostTaskAndReply(
434 FROM_HERE, base::Bind(&FindPagesMissingArchiveFile, id_path_pairs, 383 FROM_HERE, base::Bind(&FindPagesMissingArchiveFile, id_path_pairs,
435 ids_of_pages_missing_archive_file), 384 ids_of_pages_missing_archive_file),
436 base::Bind(&OfflinePageModel::OnFindPagesMissingArchiveFile, 385 base::Bind(&OfflinePageModel::OnFindPagesMissingArchiveFile,
437 weak_ptr_factory_.GetWeakPtr(), 386 weak_ptr_factory_.GetWeakPtr(),
438 base::Owned(ids_of_pages_missing_archive_file))); 387 base::Owned(ids_of_pages_missing_archive_file)));
439 } 388 }
440 389
441 void OfflinePageModel::RecordStorageHistograms(int64_t total_space_bytes, 390 void OfflinePageModel::RecordStorageHistograms(int64_t total_space_bytes,
442 int64_t free_space_bytes, 391 int64_t free_space_bytes,
443 bool reporting_after_delete) { 392 bool reporting_after_delete) {
444 // Total space taken by offline pages. 393 // Total space taken by offline pages.
445 int64_t total_page_size = 0; 394 int64_t total_page_size = 0;
446 for (const auto& id_page_pair : offline_pages_) { 395 for (const auto& id_page_pair : offline_pages_) {
447 if (!id_page_pair.second.IsMarkedForDeletion())
448 continue;
449 total_page_size += id_page_pair.second.file_size; 396 total_page_size += id_page_pair.second.file_size;
450 } 397 }
451 398
452 int total_page_size_mb = static_cast<int>(total_page_size / (1024 * 1024)); 399 int total_page_size_mb = static_cast<int>(total_page_size / (1024 * 1024));
453 UMA_HISTOGRAM_COUNTS_10000("OfflinePages.TotalPageSize", total_page_size_mb); 400 UMA_HISTOGRAM_COUNTS_10000("OfflinePages.TotalPageSize", total_page_size_mb);
454 401
455 // How much of the total space the offline pages take. 402 // How much of the total space the offline pages take.
456 int total_page_size_percentage = 403 int total_page_size_percentage =
457 static_cast<int>(1.0 * total_page_size / total_space_bytes * 100); 404 static_cast<int>(1.0 * total_page_size / total_space_bytes * 100);
458 UMA_HISTOGRAM_PERCENTAGE("OfflinePages.TotalPageSizePercentage", 405 UMA_HISTOGRAM_PERCENTAGE("OfflinePages.TotalPageSizePercentage",
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 void OfflinePageModel::OnMarkPageAccesseDone( 481 void OfflinePageModel::OnMarkPageAccesseDone(
535 const OfflinePageItem& offline_page_item, bool success) { 482 const OfflinePageItem& offline_page_item, bool success) {
536 // Update the item in the cache only upon success. 483 // Update the item in the cache only upon success.
537 if (success) 484 if (success)
538 offline_pages_[offline_page_item.offline_id] = offline_page_item; 485 offline_pages_[offline_page_item.offline_id] = offline_page_item;
539 486
540 // No need to fire OfflinePageModelChanged event since updating access info 487 // No need to fire OfflinePageModelChanged event since updating access info
541 // should not have any impact to the UI. 488 // should not have any impact to the UI.
542 } 489 }
543 490
544 void OfflinePageModel::OnMarkPageForDeletionDone(
545 const OfflinePageItem& offline_page_item,
546 const DeletePageCallback& callback,
547 bool success) {
548 // Update the item in the cache only upon success.
549 if (success)
550 offline_pages_[offline_page_item.offline_id] = offline_page_item;
551
552 InformDeletePageDone(callback, success ? DeletePageResult::SUCCESS
553 : DeletePageResult::STORE_FAILURE);
554
555 if (!success)
556 return;
557
558 // Schedule to do the final deletion.
559 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
560 FROM_HERE,
561 base::Bind(&OfflinePageModel::FinalizePageDeletion,
562 weak_ptr_factory_.GetWeakPtr()),
563 kFinalDeletionDelay);
564
565 FOR_EACH_OBSERVER(Observer, observers_,
566 OfflinePageDeleted(offline_page_item.offline_id,
567 offline_page_item.client_id));
568 }
569
570 void OfflinePageModel::OnUndoOfflinePageDone(
571 const OfflinePageItem& offline_page, bool success) {
572 if (!success)
573 return;
574 offline_pages_[offline_page.offline_id] = offline_page;
575
576 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this));
577 }
578
579 void OfflinePageModel::FinalizePageDeletion() {
580 std::vector<int64_t> offline_ids_pending_deletion;
581 for (const auto& id_page_pair : offline_pages_) {
582 if (!id_page_pair.second.IsMarkedForDeletion())
583 continue;
584 offline_ids_pending_deletion.push_back(id_page_pair.second.offline_id);
585 }
586 DeletePagesByOfflineId(offline_ids_pending_deletion, DeletePageCallback());
587 }
588
589 void OfflinePageModel::UndoPageDeletion(int64_t offline_id) {
590 auto iter = offline_pages_.find(offline_id);
591 if (iter == offline_pages_.end())
592 return;
593
594 // Make a copy of the cached item and update it. The cached item should only
595 // be updated upon the successful store operation.
596 OfflinePageItem offline_page_item = iter->second;
597 if (!offline_page_item.IsMarkedForDeletion())
598 return;
599
600 // Clear the flag to bring it back.
601 offline_page_item.ClearMarkForDeletion();
602 store_->AddOrUpdateOfflinePage(
603 offline_page_item,
604 base::Bind(&OfflinePageModel::OnUndoOfflinePageDone,
605 weak_ptr_factory_.GetWeakPtr(), offline_page_item));
606 }
607
608 void OfflinePageModel::OnEnsureArchivesDirCreatedDone() { 491 void OfflinePageModel::OnEnsureArchivesDirCreatedDone() {
609 store_->Load(base::Bind(&OfflinePageModel::OnLoadDone, 492 store_->Load(base::Bind(&OfflinePageModel::OnLoadDone,
610 weak_ptr_factory_.GetWeakPtr())); 493 weak_ptr_factory_.GetWeakPtr()));
611 } 494 }
612 495
613 void OfflinePageModel::OnLoadDone( 496 void OfflinePageModel::OnLoadDone(
614 OfflinePageMetadataStore::LoadStatus load_status, 497 OfflinePageMetadataStore::LoadStatus load_status,
615 const std::vector<OfflinePageItem>& offline_pages) { 498 const std::vector<OfflinePageItem>& offline_pages) {
616 DCHECK(!is_loaded_); 499 DCHECK(!is_loaded_);
617 is_loaded_ = true; 500 is_loaded_ = true;
618 501
619 // TODO(jianli): rebuild the store upon failure. 502 // TODO(jianli): rebuild the store upon failure.
620 503
621 if (load_status == OfflinePageMetadataStore::LOAD_SUCCEEDED) 504 if (load_status == OfflinePageMetadataStore::LOAD_SUCCEEDED)
622 CacheLoadedData(offline_pages); 505 CacheLoadedData(offline_pages);
623 506
624 // Run all the delayed tasks. 507 // Run all the delayed tasks.
625 for (const auto& delayed_task : delayed_tasks_) 508 for (const auto& delayed_task : delayed_tasks_)
626 delayed_task.Run(); 509 delayed_task.Run();
627 delayed_tasks_.clear(); 510 delayed_tasks_.clear();
628 511
629 // If there are pages that are marked for deletion, but not yet deleted and
630 // OfflinePageModel gets reloaded. Delete the pages now.
631 FinalizePageDeletion();
632
633 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelLoaded(this)); 512 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelLoaded(this));
634 513
635 CheckForExternalFileDeletion(); 514 CheckForExternalFileDeletion();
636 } 515 }
637 516
638 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback, 517 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback,
639 SavePageResult result, 518 SavePageResult result,
640 int64_t offline_id) { 519 int64_t offline_id) {
641 UMA_HISTOGRAM_ENUMERATION( 520 UMA_HISTOGRAM_ENUMERATION(
642 "OfflinePages.SavePageResult", 521 "OfflinePages.SavePageResult",
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 "OfflinePages.DeletePage.LastOpenToCreated", 575 "OfflinePages.DeletePage.LastOpenToCreated",
697 (iter->second.last_access_time - iter->second.creation_time). 576 (iter->second.last_access_time - iter->second.creation_time).
698 InMinutes(), 577 InMinutes(),
699 1, 578 1,
700 base::TimeDelta::FromDays(365).InMinutes(), 579 base::TimeDelta::FromDays(365).InMinutes(),
701 100); 580 100);
702 UMA_HISTOGRAM_MEMORY_KB( 581 UMA_HISTOGRAM_MEMORY_KB(
703 "OfflinePages.DeletePage.PageSize", iter->second.file_size / 1024); 582 "OfflinePages.DeletePage.PageSize", iter->second.file_size / 1024);
704 UMA_HISTOGRAM_COUNTS( 583 UMA_HISTOGRAM_COUNTS(
705 "OfflinePages.DeletePage.AccessCount", iter->second.access_count); 584 "OfflinePages.DeletePage.AccessCount", iter->second.access_count);
706 // If the page is not marked for deletion at this point, the model has not 585 FOR_EACH_OBSERVER(
707 // yet informed the observer that the offline page is deleted. 586 Observer, observers_,
708 if (!iter->second.IsMarkedForDeletion()) { 587 OfflinePageDeleted(iter->second.offline_id, iter->second.client_id));
709 FOR_EACH_OBSERVER(
710 Observer, observers_,
711 OfflinePageDeleted(iter->second.offline_id, iter->second.client_id));
712 }
713 offline_pages_.erase(iter); 588 offline_pages_.erase(iter);
714 } 589 }
715 if (offline_ids.size() > 1) { 590 if (offline_ids.size() > 1) {
716 UMA_HISTOGRAM_COUNTS("OfflinePages.BatchDelete.Count", offline_ids.size()); 591 UMA_HISTOGRAM_COUNTS("OfflinePages.BatchDelete.Count", offline_ids.size());
717 UMA_HISTOGRAM_MEMORY_KB( 592 UMA_HISTOGRAM_MEMORY_KB(
718 "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024); 593 "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024);
719 } 594 }
720 // Deleting multiple pages always succeeds when it gets to this point. 595 // Deleting multiple pages always succeeds when it gets to this point.
721 InformDeletePageDone(callback, (success || offline_ids.size() > 1) 596 InformDeletePageDone(callback, (success || offline_ids.size() > 1)
722 ? DeletePageResult::SUCCESS 597 ? DeletePageResult::SUCCESS
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 const std::vector<OfflinePageItem>& offline_pages) { 688 const std::vector<OfflinePageItem>& offline_pages) {
814 offline_pages_.clear(); 689 offline_pages_.clear();
815 for (const auto& offline_page : offline_pages) 690 for (const auto& offline_page : offline_pages)
816 offline_pages_[offline_page.offline_id] = offline_page; 691 offline_pages_[offline_page.offline_id] = offline_page;
817 } 692 }
818 693
819 int64_t OfflinePageModel::GenerateOfflineId() { 694 int64_t OfflinePageModel::GenerateOfflineId() {
820 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1; 695 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1;
821 } 696 }
822 697
823 void OfflinePageModel::MarkPagesForDeletion(
824 const std::vector<int64_t>& offline_ids,
825 const DeletePageCallback& callback) {
826 if (!is_loaded_) {
827 for (size_t i = 0; i < offline_ids.size(); i++) {
828 delayed_tasks_.push_back(
829 base::Bind(&OfflinePageModel::MarkPageForDeletion,
830 weak_ptr_factory_.GetWeakPtr(), offline_ids[i], callback));
831 }
832 return;
833 }
834 for (const auto& id : offline_ids) {
835 MarkPageForDeletion(id, callback);
836 }
837 }
838
839 void OfflinePageModel::RunWhenLoaded(const base::Closure& task) { 698 void OfflinePageModel::RunWhenLoaded(const base::Closure& task) {
840 if (!is_loaded_) { 699 if (!is_loaded_) {
841 delayed_tasks_.push_back(task); 700 delayed_tasks_.push_back(task);
842 return; 701 return;
843 } 702 }
844 703
845 task_runner_->PostTask(FROM_HERE, task); 704 task_runner_->PostTask(FROM_HERE, task);
846 } 705 }
847 706
848 } // namespace offline_pages 707 } // namespace offline_pages
OLDNEW
« no previous file with comments | « components/offline_pages/offline_page_model.h ('k') | components/offline_pages/offline_page_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698