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

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

Issue 1694863003: Refactor the offline page storage to include client namespace and id. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address changes Created 4 years, 9 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"
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/sequenced_task_runner.h" 16 #include "base/sequenced_task_runner.h"
17 #include "base/strings/string_number_conversions.h"
16 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
17 #include "base/time/time.h" 19 #include "base/time/time.h"
18 #include "components/bookmarks/browser/bookmark_model.h" 20 #include "components/bookmarks/browser/bookmark_model.h"
19 #include "components/bookmarks/browser/bookmark_node.h" 21 #include "components/bookmarks/browser/bookmark_node.h"
20 #include "components/offline_pages/offline_page_item.h" 22 #include "components/offline_pages/offline_page_item.h"
23 #include "components/offline_pages/proto/offline_pages.pb.h"
21 #include "url/gurl.h" 24 #include "url/gurl.h"
22 25
23 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult; 26 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult;
24 using SavePageResult = offline_pages::OfflinePageModel::SavePageResult; 27 using SavePageResult = offline_pages::OfflinePageModel::SavePageResult;
25 28
26 namespace offline_pages { 29 namespace offline_pages {
27 30
28 namespace { 31 namespace {
29 32
30 // This enum is used in an UMA histogram. Hence the entries here shouldn't 33 // This enum is used in an UMA histogram. Hence the entries here shouldn't
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 150
148 void OfflinePageModel::AddObserver(Observer* observer) { 151 void OfflinePageModel::AddObserver(Observer* observer) {
149 observers_.AddObserver(observer); 152 observers_.AddObserver(observer);
150 } 153 }
151 154
152 void OfflinePageModel::RemoveObserver(Observer* observer) { 155 void OfflinePageModel::RemoveObserver(Observer* observer) {
153 observers_.RemoveObserver(observer); 156 observers_.RemoveObserver(observer);
154 } 157 }
155 158
156 void OfflinePageModel::SavePage(const GURL& url, 159 void OfflinePageModel::SavePage(const GURL& url,
157 int64_t bookmark_id, 160 const ClientId& client_id,
158 scoped_ptr<OfflinePageArchiver> archiver, 161 scoped_ptr<OfflinePageArchiver> archiver,
159 const SavePageCallback& callback) { 162 const SavePageCallback& callback) {
160 DCHECK(is_loaded_); 163 DCHECK(is_loaded_);
161 164
162 // Skip saving the page that is not intended to be saved, like local file 165 // Skip saving the page that is not intended to be saved, like local file
163 // page. 166 // page.
164 if (!CanSavePage(url)) { 167 if (!CanSavePage(url)) {
165 InformSavePageDone(callback, SavePageResult::SKIPPED); 168 InformSavePageDone(callback, SavePageResult::SKIPPED, INVALID_OFFLINE_ID);
166 return; 169 return;
167 } 170 }
168 171
169 DCHECK(archiver.get()); 172 DCHECK(archiver.get());
170 archiver->CreateArchive(archives_dir_, 173
171 base::Bind(&OfflinePageModel::OnCreateArchiveDone, 174 int64_t offline_id = GenerateOfflineId();
172 weak_ptr_factory_.GetWeakPtr(), url, 175
173 bookmark_id, base::Time::Now(), callback)); 176 archiver->CreateArchive(
177 archives_dir_, base::Bind(&OfflinePageModel::OnCreateArchiveDone,
178 weak_ptr_factory_.GetWeakPtr(), url, offline_id,
179 client_id, base::Time::Now(), callback));
174 pending_archivers_.push_back(std::move(archiver)); 180 pending_archivers_.push_back(std::move(archiver));
175 } 181 }
176 182
177 void OfflinePageModel::MarkPageAccessed(int64_t bookmark_id) { 183 void OfflinePageModel::MarkPageAccessed(int64_t offline_id) {
178 DCHECK(is_loaded_); 184 DCHECK(is_loaded_);
179 auto iter = offline_pages_.find(bookmark_id); 185 auto iter = offline_pages_.find(offline_id);
180 if (iter == offline_pages_.end()) 186 if (iter == offline_pages_.end())
181 return; 187 return;
182 188
183 // MarkPageAccessed should not be called for a page that is being marked for 189 // MarkPageAccessed should not be called for a page that is being marked for
184 // deletion. 190 // deletion.
185 DCHECK(!iter->second.IsMarkedForDeletion()); 191 DCHECK(!iter->second.IsMarkedForDeletion());
186 192
187 // Make a copy of the cached item and update it. The cached item should only 193 // Make a copy of the cached item and update it. The cached item should only
188 // be updated upon the successful store operation. 194 // be updated upon the successful store operation.
189 OfflinePageItem offline_page_item = iter->second; 195 OfflinePageItem offline_page_item = iter->second;
(...skipping 16 matching lines...) Expand all
206 212
207 offline_page_item.last_access_time = now; 213 offline_page_item.last_access_time = now;
208 offline_page_item.access_count++; 214 offline_page_item.access_count++;
209 215
210 store_->AddOrUpdateOfflinePage( 216 store_->AddOrUpdateOfflinePage(
211 offline_page_item, 217 offline_page_item,
212 base::Bind(&OfflinePageModel::OnMarkPageAccesseDone, 218 base::Bind(&OfflinePageModel::OnMarkPageAccesseDone,
213 weak_ptr_factory_.GetWeakPtr(), offline_page_item)); 219 weak_ptr_factory_.GetWeakPtr(), offline_page_item));
214 } 220 }
215 221
216 void OfflinePageModel::MarkPageForDeletion(int64_t bookmark_id, 222 void OfflinePageModel::MarkPageForDeletion(int64_t offline_id,
217 const DeletePageCallback& callback) { 223 const DeletePageCallback& callback) {
218 DCHECK(is_loaded_); 224 DCHECK(is_loaded_);
219 auto iter = offline_pages_.find(bookmark_id); 225 auto iter = offline_pages_.find(offline_id);
220 if (iter == offline_pages_.end()) { 226 if (iter == offline_pages_.end()) {
221 InformDeletePageDone(callback, DeletePageResult::NOT_FOUND); 227 InformDeletePageDone(callback, DeletePageResult::NOT_FOUND);
222 return; 228 return;
223 } 229 }
224 230
225 // Make a copy of the cached item and update it. The cached item should only 231 // Make a copy of the cached item and update it. The cached item should only
226 // be updated upon the successful store operation. 232 // be updated upon the successful store operation.
227 OfflinePageItem offline_page_item = iter->second; 233 OfflinePageItem offline_page_item = iter->second;
228 offline_page_item.MarkForDeletion(); 234 offline_page_item.MarkForDeletion();
229 store_->AddOrUpdateOfflinePage( 235 store_->AddOrUpdateOfflinePage(
230 offline_page_item, 236 offline_page_item,
231 base::Bind(&OfflinePageModel::OnMarkPageForDeletionDone, 237 base::Bind(&OfflinePageModel::OnMarkPageForDeletionDone,
232 weak_ptr_factory_.GetWeakPtr(), offline_page_item, callback)); 238 weak_ptr_factory_.GetWeakPtr(), offline_page_item, callback));
233 } 239 }
234 240
235 void OfflinePageModel::DeletePageByBookmarkId( 241 void OfflinePageModel::DeletePageByOfflineId(
236 int64_t bookmark_id, 242 int64_t offline_id,
237 const DeletePageCallback& callback) { 243 const DeletePageCallback& callback) {
238 DCHECK(is_loaded_); 244 DCHECK(is_loaded_);
239 std::vector<int64_t> bookmark_ids_to_delete; 245 std::vector<int64_t> offline_ids_to_delete;
240 bookmark_ids_to_delete.push_back(bookmark_id); 246 offline_ids_to_delete.push_back(offline_id);
241 DeletePagesByBookmarkId(bookmark_ids_to_delete, callback); 247 DeletePagesByOfflineId(offline_ids_to_delete, callback);
242 } 248 }
243 249
244 void OfflinePageModel::DeletePagesByBookmarkId( 250 void OfflinePageModel::DeletePagesByOfflineId(
245 const std::vector<int64_t>& bookmark_ids, 251 const std::vector<int64_t>& offline_ids,
246 const DeletePageCallback& callback) { 252 const DeletePageCallback& callback) {
247 DCHECK(is_loaded_); 253 DCHECK(is_loaded_);
248 254
249 std::vector<base::FilePath> paths_to_delete; 255 std::vector<base::FilePath> paths_to_delete;
250 for (const auto& bookmark_id : bookmark_ids) { 256 for (const auto& offline_id : offline_ids) {
251 auto iter = offline_pages_.find(bookmark_id); 257 auto iter = offline_pages_.find(offline_id);
252 if (iter != offline_pages_.end()) { 258 if (iter != offline_pages_.end()) {
253 paths_to_delete.push_back(iter->second.file_path); 259 paths_to_delete.push_back(iter->second.file_path);
254 } 260 }
255 } 261 }
256 262
257 if (paths_to_delete.empty()) { 263 if (paths_to_delete.empty()) {
258 InformDeletePageDone(callback, DeletePageResult::NOT_FOUND); 264 InformDeletePageDone(callback, DeletePageResult::NOT_FOUND);
259 return; 265 return;
260 } 266 }
261 267
262 bool* success = new bool(false); 268 bool* success = new bool(false);
263 task_runner_->PostTaskAndReply( 269 task_runner_->PostTaskAndReply(
264 FROM_HERE, 270 FROM_HERE, base::Bind(&DeleteArchiveFiles, paths_to_delete, success),
265 base::Bind(&DeleteArchiveFiles, paths_to_delete, success),
266 base::Bind(&OfflinePageModel::OnDeleteArchiveFilesDone, 271 base::Bind(&OfflinePageModel::OnDeleteArchiveFilesDone,
267 weak_ptr_factory_.GetWeakPtr(), 272 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback,
268 bookmark_ids,
269 callback,
270 base::Owned(success))); 273 base::Owned(success)));
271 } 274 }
272 275
273 void OfflinePageModel::ClearAll(const base::Closure& callback) { 276 void OfflinePageModel::ClearAll(const base::Closure& callback) {
274 DCHECK(is_loaded_); 277 DCHECK(is_loaded_);
275 278
276 std::vector<int64_t> bookmark_ids; 279 std::vector<int64_t> offline_ids;
277 for (const auto& id_page_pair : offline_pages_) 280 for (const auto& id_page_pair : offline_pages_)
278 bookmark_ids.push_back(id_page_pair.first); 281 offline_ids.push_back(id_page_pair.first);
279 DeletePagesByBookmarkId( 282 DeletePagesByOfflineId(
280 bookmark_ids, 283 offline_ids,
281 base::Bind(&OfflinePageModel::OnRemoveAllFilesDoneForClearAll, 284 base::Bind(&OfflinePageModel::OnRemoveAllFilesDoneForClearAll,
282 weak_ptr_factory_.GetWeakPtr(), 285 weak_ptr_factory_.GetWeakPtr(), callback));
283 callback));
284 } 286 }
285 287
286 bool OfflinePageModel::HasOfflinePages() const { 288 bool OfflinePageModel::HasOfflinePages() const {
287 DCHECK(is_loaded_); 289 DCHECK(is_loaded_);
288 // Check that at least one page is not marked for deletion. Because we have 290 // Check that at least one page is not marked for deletion. Because we have
289 // pages marked for deletion, we cannot simply invert result of |empty()|. 291 // pages marked for deletion, we cannot simply invert result of |empty()|.
290 for (const auto& id_page_pair : offline_pages_) { 292 for (const auto& id_page_pair : offline_pages_) {
291 if (!id_page_pair.second.IsMarkedForDeletion()) 293 if (!id_page_pair.second.IsMarkedForDeletion())
292 return true; 294 return true;
293 } 295 }
(...skipping 17 matching lines...) Expand all
311 base::Time now = base::Time::Now(); 313 base::Time now = base::Time::Now();
312 for (const auto& id_page_pair : offline_pages_) { 314 for (const auto& id_page_pair : offline_pages_) {
313 if (!id_page_pair.second.IsMarkedForDeletion() && 315 if (!id_page_pair.second.IsMarkedForDeletion() &&
314 now - id_page_pair.second.last_access_time > kPageCleanUpThreshold) { 316 now - id_page_pair.second.last_access_time > kPageCleanUpThreshold) {
315 offline_pages.push_back(id_page_pair.second); 317 offline_pages.push_back(id_page_pair.second);
316 } 318 }
317 } 319 }
318 return offline_pages; 320 return offline_pages;
319 } 321 }
320 322
321 const OfflinePageItem* OfflinePageModel::GetPageByBookmarkId( 323 const std::vector<int64_t> OfflinePageModel::GetOfflineIdsForClientId(
322 int64_t bookmark_id) const { 324 const ClientId& cid) const {
323 const auto iter = offline_pages_.find(bookmark_id); 325 std::vector<int64_t> results;
326
327 // TODO(bburns): actually use an index rather than linear scan.
328 const std::vector<OfflinePageItem> offline_pages = GetAllPages();
329
330 for (size_t i = 0; i < offline_pages.size(); i++) {
331 if (offline_pages[i].client_id.name_space == cid.name_space &&
332 offline_pages[i].client_id.id == cid.id) {
333 results.push_back(offline_pages[i].offline_id);
334 }
335 }
336 return results;
337 }
338
339 const OfflinePageItem* OfflinePageModel::GetPageByOfflineId(
340 int64_t offline_id) const {
341 const auto iter = offline_pages_.find(offline_id);
324 return iter != offline_pages_.end() && !iter->second.IsMarkedForDeletion() 342 return iter != offline_pages_.end() && !iter->second.IsMarkedForDeletion()
325 ? &(iter->second) 343 ? &(iter->second)
326 : nullptr; 344 : nullptr;
327 } 345 }
328 346
329 const OfflinePageItem* OfflinePageModel::GetPageByOfflineURL( 347 const OfflinePageItem* OfflinePageModel::GetPageByOfflineURL(
330 const GURL& offline_url) const { 348 const GURL& offline_url) const {
331 for (auto iter = offline_pages_.begin(); 349 for (auto iter = offline_pages_.begin();
332 iter != offline_pages_.end(); 350 iter != offline_pages_.end();
333 ++iter) { 351 ++iter) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 base::Bind(&OfflinePageModel::OnFindPagesMissingArchiveFile, 384 base::Bind(&OfflinePageModel::OnFindPagesMissingArchiveFile,
367 weak_ptr_factory_.GetWeakPtr(), 385 weak_ptr_factory_.GetWeakPtr(),
368 base::Owned(ids_of_pages_missing_archive_file))); 386 base::Owned(ids_of_pages_missing_archive_file)));
369 } 387 }
370 388
371 OfflinePageMetadataStore* OfflinePageModel::GetStoreForTesting() { 389 OfflinePageMetadataStore* OfflinePageModel::GetStoreForTesting() {
372 return store_.get(); 390 return store_.get();
373 } 391 }
374 392
375 void OfflinePageModel::OnCreateArchiveDone(const GURL& requested_url, 393 void OfflinePageModel::OnCreateArchiveDone(const GURL& requested_url,
376 int64_t bookmark_id, 394 int64_t offline_id,
395 const ClientId& client_id,
377 const base::Time& start_time, 396 const base::Time& start_time,
378 const SavePageCallback& callback, 397 const SavePageCallback& callback,
379 OfflinePageArchiver* archiver, 398 OfflinePageArchiver* archiver,
380 ArchiverResult archiver_result, 399 ArchiverResult archiver_result,
381 const GURL& url, 400 const GURL& url,
382 const base::FilePath& file_path, 401 const base::FilePath& file_path,
383 int64_t file_size) { 402 int64_t file_size) {
384 if (requested_url != url) { 403 if (requested_url != url) {
385 DVLOG(1) << "Saved URL does not match requested URL."; 404 DVLOG(1) << "Saved URL does not match requested URL.";
386 // TODO(fgorski): We have created an archive for a wrong URL. It should be 405 // TODO(fgorski): We have created an archive for a wrong URL. It should be
387 // deleted from here, once archiver has the right functionality. 406 // deleted from here, once archiver has the right functionality.
388 InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED); 407 InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED,
408 offline_id);
389 DeletePendingArchiver(archiver); 409 DeletePendingArchiver(archiver);
390 return; 410 return;
391 } 411 }
392 412
393 if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) { 413 if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) {
394 SavePageResult result = ToSavePageResult(archiver_result); 414 SavePageResult result = ToSavePageResult(archiver_result);
395 InformSavePageDone(callback, result); 415 InformSavePageDone(callback, result, offline_id);
396 DeletePendingArchiver(archiver); 416 DeletePendingArchiver(archiver);
397 return; 417 return;
398 } 418 }
399 419 OfflinePageItem offline_page_item(url, offline_id, client_id, file_path,
400 OfflinePageItem offline_page_item(url, bookmark_id, file_path, file_size, 420 file_size, start_time);
401 start_time);
402 store_->AddOrUpdateOfflinePage( 421 store_->AddOrUpdateOfflinePage(
403 offline_page_item, 422 offline_page_item,
404 base::Bind(&OfflinePageModel::OnAddOfflinePageDone, 423 base::Bind(&OfflinePageModel::OnAddOfflinePageDone,
405 weak_ptr_factory_.GetWeakPtr(), archiver, callback, 424 weak_ptr_factory_.GetWeakPtr(), archiver, callback,
406 offline_page_item)); 425 offline_page_item));
407 } 426 }
408 427
409 void OfflinePageModel::OnAddOfflinePageDone(OfflinePageArchiver* archiver, 428 void OfflinePageModel::OnAddOfflinePageDone(OfflinePageArchiver* archiver,
410 const SavePageCallback& callback, 429 const SavePageCallback& callback,
411 const OfflinePageItem& offline_page, 430 const OfflinePageItem& offline_page,
412 bool success) { 431 bool success) {
413 SavePageResult result; 432 SavePageResult result;
414 if (success) { 433 if (success) {
415 offline_pages_[offline_page.bookmark_id] = offline_page; 434 offline_pages_[offline_page.offline_id] = offline_page;
416 result = SavePageResult::SUCCESS; 435 result = SavePageResult::SUCCESS;
417 UMA_HISTOGRAM_TIMES( 436 UMA_HISTOGRAM_TIMES(
418 "OfflinePages.SavePageTime", 437 "OfflinePages.SavePageTime",
419 base::Time::Now() - offline_page.creation_time); 438 base::Time::Now() - offline_page.creation_time);
420 UMA_HISTOGRAM_MEMORY_KB( 439 UMA_HISTOGRAM_MEMORY_KB(
421 "OfflinePages.PageSize", offline_page.file_size / 1024); 440 "OfflinePages.PageSize", offline_page.file_size / 1024);
422 } else { 441 } else {
423 result = SavePageResult::STORE_FAILURE; 442 result = SavePageResult::STORE_FAILURE;
424 } 443 }
425 InformSavePageDone(callback, result); 444 InformSavePageDone(callback, result, offline_page.offline_id);
426 DeletePendingArchiver(archiver); 445 DeletePendingArchiver(archiver);
427 446
428 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this)); 447 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this));
429 } 448 }
430 449
431 void OfflinePageModel::OnMarkPageAccesseDone( 450 void OfflinePageModel::OnMarkPageAccesseDone(
432 const OfflinePageItem& offline_page_item, bool success) { 451 const OfflinePageItem& offline_page_item, bool success) {
433 // Update the item in the cache only upon success. 452 // Update the item in the cache only upon success.
434 if (success) 453 if (success)
435 offline_pages_[offline_page_item.bookmark_id] = offline_page_item; 454 offline_pages_[offline_page_item.offline_id] = offline_page_item;
436 455
437 // No need to fire OfflinePageModelChanged event since updating access info 456 // No need to fire OfflinePageModelChanged event since updating access info
438 // should not have any impact to the UI. 457 // should not have any impact to the UI.
439 } 458 }
440 459
441 void OfflinePageModel::OnMarkPageForDeletionDone( 460 void OfflinePageModel::OnMarkPageForDeletionDone(
442 const OfflinePageItem& offline_page_item, 461 const OfflinePageItem& offline_page_item,
443 const DeletePageCallback& callback, 462 const DeletePageCallback& callback,
444 bool success) { 463 bool success) {
445 // Update the item in the cache only upon success. 464 // Update the item in the cache only upon success.
446 if (success) 465 if (success)
447 offline_pages_[offline_page_item.bookmark_id] = offline_page_item; 466 offline_pages_[offline_page_item.offline_id] = offline_page_item;
448 467
449 InformDeletePageDone(callback, success ? DeletePageResult::SUCCESS 468 InformDeletePageDone(callback, success ? DeletePageResult::SUCCESS
450 : DeletePageResult::STORE_FAILURE); 469 : DeletePageResult::STORE_FAILURE);
451 470
452 if (!success) 471 if (!success)
453 return; 472 return;
454 473
455 // Schedule to do the final deletion. 474 // Schedule to do the final deletion.
456 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 475 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
457 FROM_HERE, 476 FROM_HERE,
458 base::Bind(&OfflinePageModel::FinalizePageDeletion, 477 base::Bind(&OfflinePageModel::FinalizePageDeletion,
459 weak_ptr_factory_.GetWeakPtr()), 478 weak_ptr_factory_.GetWeakPtr()),
460 kFinalDeletionDelay); 479 kFinalDeletionDelay);
461 480
462 FOR_EACH_OBSERVER( 481 FOR_EACH_OBSERVER(Observer, observers_,
463 Observer, observers_, OfflinePageDeleted(offline_page_item.bookmark_id)); 482 OfflinePageDeleted(offline_page_item.offline_id));
464 } 483 }
465 484
466 void OfflinePageModel::OnUndoOfflinePageDone( 485 void OfflinePageModel::OnUndoOfflinePageDone(
467 const OfflinePageItem& offline_page, bool success) { 486 const OfflinePageItem& offline_page, bool success) {
468 if (!success) 487 if (!success)
469 return; 488 return;
470 offline_pages_[offline_page.bookmark_id] = offline_page; 489 offline_pages_[offline_page.offline_id] = offline_page;
471 490
472 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this)); 491 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this));
473 } 492 }
474 493
475 void OfflinePageModel::FinalizePageDeletion() { 494 void OfflinePageModel::FinalizePageDeletion() {
476 std::vector<int64_t> bookmark_ids_pending_deletion; 495 std::vector<int64_t> offline_ids_pending_deletion;
477 for (const auto& id_page_pair : offline_pages_) { 496 for (const auto& id_page_pair : offline_pages_) {
478 if (!id_page_pair.second.IsMarkedForDeletion()) 497 if (!id_page_pair.second.IsMarkedForDeletion())
479 continue; 498 continue;
480 bookmark_ids_pending_deletion.push_back(id_page_pair.second.bookmark_id); 499 offline_ids_pending_deletion.push_back(id_page_pair.second.offline_id);
481 } 500 }
482 DeletePagesByBookmarkId(bookmark_ids_pending_deletion, DeletePageCallback()); 501 DeletePagesByOfflineId(offline_ids_pending_deletion, DeletePageCallback());
483 } 502 }
484 503
485 void OfflinePageModel::UndoPageDeletion(int64_t bookmark_id) { 504 void OfflinePageModel::UndoPageDeletion(int64_t offline_id) {
486 auto iter = offline_pages_.find(bookmark_id); 505 auto iter = offline_pages_.find(offline_id);
487 if (iter == offline_pages_.end()) 506 if (iter == offline_pages_.end())
488 return; 507 return;
489 508
490 // Make a copy of the cached item and update it. The cached item should only 509 // Make a copy of the cached item and update it. The cached item should only
491 // be updated upon the successful store operation. 510 // be updated upon the successful store operation.
492 OfflinePageItem offline_page_item = iter->second; 511 OfflinePageItem offline_page_item = iter->second;
493 if (!offline_page_item.IsMarkedForDeletion()) 512 if (!offline_page_item.IsMarkedForDeletion())
494 return; 513 return;
495 514
496 // Clear the flag to bring it back. 515 // Clear the flag to bring it back.
497 offline_page_item.ClearMarkForDeletion(); 516 offline_page_item.ClearMarkForDeletion();
498 store_->AddOrUpdateOfflinePage( 517 store_->AddOrUpdateOfflinePage(
499 offline_page_item, 518 offline_page_item,
500 base::Bind(&OfflinePageModel::OnUndoOfflinePageDone, 519 base::Bind(&OfflinePageModel::OnUndoOfflinePageDone,
501 weak_ptr_factory_.GetWeakPtr(), offline_page_item)); 520 weak_ptr_factory_.GetWeakPtr(), offline_page_item));
502 } 521 }
503 522
504 void OfflinePageModel::BookmarkModelChanged() { 523 void OfflinePageModel::BookmarkModelChanged() {
505 } 524 }
506 525
507 void OfflinePageModel::BookmarkNodeAdded(bookmarks::BookmarkModel* model, 526 void OfflinePageModel::BookmarkNodeAdded(bookmarks::BookmarkModel* model,
508 const bookmarks::BookmarkNode* parent, 527 const bookmarks::BookmarkNode* parent,
509 int index) { 528 int index) {
510 const bookmarks::BookmarkNode* node = parent->GetChild(index); 529 const bookmarks::BookmarkNode* node = parent->GetChild(index);
511 DCHECK(node); 530 DCHECK(node);
512 UndoPageDeletion(node->id()); 531 ClientId client_id(BOOKMARK_NAMESPACE, base::Int64ToString(node->id()));
532 std::vector<int64_t> ids;
533 // In this case we want only all pages, including those marked for deletion.
534 for (const auto& id_page_pair : offline_pages_) {
535 if (id_page_pair.second.client_id == client_id) {
536 ids.push_back(id_page_pair.second.offline_id);
537 }
538 }
539
540 for (size_t i = 0; i < ids.size(); i++) {
541 UndoPageDeletion(ids[i]);
542 }
513 } 543 }
514 544
515 void OfflinePageModel::BookmarkNodeRemoved( 545 void OfflinePageModel::BookmarkNodeRemoved(
516 bookmarks::BookmarkModel* model, 546 bookmarks::BookmarkModel* model,
517 const bookmarks::BookmarkNode* parent, 547 const bookmarks::BookmarkNode* parent,
518 int old_index, 548 int old_index,
519 const bookmarks::BookmarkNode* node, 549 const bookmarks::BookmarkNode* node,
520 const std::set<GURL>& removed_urls) { 550 const std::set<GURL>& removed_urls) {
551 ClientId cid;
552 cid.name_space = BOOKMARK_NAMESPACE;
553 cid.id = base::Int64ToString(node->id());
554 std::vector<int64_t> ids = GetOfflineIdsForClientId(cid);
521 if (!is_loaded_) { 555 if (!is_loaded_) {
522 delayed_tasks_.push_back( 556 for (size_t i = 0; i < ids.size(); i++) {
523 base::Bind(&OfflinePageModel::MarkPageForDeletion, 557 delayed_tasks_.push_back(
524 weak_ptr_factory_.GetWeakPtr(), 558 base::Bind(&OfflinePageModel::MarkPageForDeletion,
525 node->id(), 559 weak_ptr_factory_.GetWeakPtr(), ids[i],
526 base::Bind(&EmptyDeleteCallback))); 560 base::Bind(&EmptyDeleteCallback)));
561 }
527 return; 562 return;
528 } 563 }
529 MarkPageForDeletion(node->id(), base::Bind(&EmptyDeleteCallback)); 564 for (size_t i = 0; i < ids.size(); i++) {
565 MarkPageForDeletion(ids[i], base::Bind(&EmptyDeleteCallback));
566 }
530 } 567 }
531 568
532 void OfflinePageModel::BookmarkNodeChanged( 569 void OfflinePageModel::BookmarkNodeChanged(
533 bookmarks::BookmarkModel* model, 570 bookmarks::BookmarkModel* model,
534 const bookmarks::BookmarkNode* node) { 571 const bookmarks::BookmarkNode* node) {
535 // BookmarkNodeChanged could be triggered if title or URL gets changed. If 572 // BookmarkNodeChanged could be triggered if title or URL gets changed. If
536 // the latter, we need to invalidate the offline copy. 573 // the latter, we need to invalidate the offline copy.
537 auto iter = offline_pages_.find(node->id()); 574 ClientId cid;
538 if (iter != offline_pages_.end() && iter->second.url != node->url()) 575 cid.name_space = BOOKMARK_NAMESPACE;
539 DeletePageByBookmarkId(node->id(), DeletePageCallback()); 576 cid.id = base::Int64ToString(node->id());
577 std::vector<int64_t> ids = GetOfflineIdsForClientId(cid);
578 for (size_t i = 0; i < ids.size(); i++) {
579 auto iter = offline_pages_.find(ids[i]);
580 if (iter != offline_pages_.end() && iter->second.url != node->url())
581 DeletePageByOfflineId(ids[i], DeletePageCallback());
582 }
540 } 583 }
541 584
542 void OfflinePageModel::OnEnsureArchivesDirCreatedDone() { 585 void OfflinePageModel::OnEnsureArchivesDirCreatedDone() {
543 store_->Load(base::Bind(&OfflinePageModel::OnLoadDone, 586 store_->Load(base::Bind(&OfflinePageModel::OnLoadDone,
544 weak_ptr_factory_.GetWeakPtr())); 587 weak_ptr_factory_.GetWeakPtr()));
545 } 588 }
546 589
547 void OfflinePageModel::OnLoadDone( 590 void OfflinePageModel::OnLoadDone(
548 OfflinePageMetadataStore::LoadStatus load_status, 591 OfflinePageMetadataStore::LoadStatus load_status,
549 const std::vector<OfflinePageItem>& offline_pages) { 592 const std::vector<OfflinePageItem>& offline_pages) {
(...skipping 13 matching lines...) Expand all
563 // If there are pages that are marked for deletion, but not yet deleted and 606 // If there are pages that are marked for deletion, but not yet deleted and
564 // OfflinePageModel gets reloaded. Delete the pages now. 607 // OfflinePageModel gets reloaded. Delete the pages now.
565 FinalizePageDeletion(); 608 FinalizePageDeletion();
566 609
567 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelLoaded(this)); 610 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelLoaded(this));
568 611
569 CheckForExternalFileDeletion(); 612 CheckForExternalFileDeletion();
570 } 613 }
571 614
572 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback, 615 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback,
573 SavePageResult result) { 616 SavePageResult result,
617 int64_t offline_id) {
574 UMA_HISTOGRAM_ENUMERATION( 618 UMA_HISTOGRAM_ENUMERATION(
575 "OfflinePages.SavePageResult", 619 "OfflinePages.SavePageResult",
576 static_cast<int>(result), 620 static_cast<int>(result),
577 static_cast<int>(SavePageResult::RESULT_COUNT)); 621 static_cast<int>(SavePageResult::RESULT_COUNT));
578 callback.Run(result); 622 callback.Run(result, offline_id);
579 } 623 }
580 624
581 void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) { 625 void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) {
582 pending_archivers_.erase(std::find( 626 pending_archivers_.erase(std::find(
583 pending_archivers_.begin(), pending_archivers_.end(), archiver)); 627 pending_archivers_.begin(), pending_archivers_.end(), archiver));
584 } 628 }
585 629
586 void OfflinePageModel::OnDeleteArchiveFilesDone( 630 void OfflinePageModel::OnDeleteArchiveFilesDone(
587 const std::vector<int64_t>& bookmark_ids, 631 const std::vector<int64_t>& offline_ids,
588 const DeletePageCallback& callback, 632 const DeletePageCallback& callback,
589 const bool* success) { 633 const bool* success) {
590 DCHECK(success); 634 DCHECK(success);
591 635
592 if (!*success) { 636 if (!*success) {
593 InformDeletePageDone(callback, DeletePageResult::DEVICE_FAILURE); 637 InformDeletePageDone(callback, DeletePageResult::DEVICE_FAILURE);
594 return; 638 return;
595 } 639 }
596 640
597 store_->RemoveOfflinePages( 641 store_->RemoveOfflinePages(
598 bookmark_ids, 642 offline_ids,
599 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone, 643 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone,
600 weak_ptr_factory_.GetWeakPtr(), bookmark_ids, callback)); 644 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback));
601 } 645 }
602 646
603 void OfflinePageModel::OnRemoveOfflinePagesDone( 647 void OfflinePageModel::OnRemoveOfflinePagesDone(
604 const std::vector<int64_t>& bookmark_ids, 648 const std::vector<int64_t>& offline_ids,
605 const DeletePageCallback& callback, 649 const DeletePageCallback& callback,
606 bool success) { 650 bool success) {
607 // Delete the offline page from the in memory cache regardless of success in 651 // Delete the offline page from the in memory cache regardless of success in
608 // store. 652 // store.
609 base::Time now = base::Time::Now(); 653 base::Time now = base::Time::Now();
610 int64_t total_size = 0; 654 int64_t total_size = 0;
611 for (int64_t bookmark_id : bookmark_ids) { 655 for (int64_t offline_id : offline_ids) {
612 auto iter = offline_pages_.find(bookmark_id); 656 auto iter = offline_pages_.find(offline_id);
613 if (iter == offline_pages_.end()) 657 if (iter == offline_pages_.end())
614 continue; 658 continue;
615 total_size += iter->second.file_size; 659 total_size += iter->second.file_size;
616 UMA_HISTOGRAM_CUSTOM_COUNTS( 660 UMA_HISTOGRAM_CUSTOM_COUNTS(
617 "OfflinePages.PageLifetime", 661 "OfflinePages.PageLifetime",
618 (now - iter->second.creation_time).InMinutes(), 662 (now - iter->second.creation_time).InMinutes(),
619 1, 663 1,
620 base::TimeDelta::FromDays(365).InMinutes(), 664 base::TimeDelta::FromDays(365).InMinutes(),
621 100); 665 100);
622 UMA_HISTOGRAM_CUSTOM_COUNTS( 666 UMA_HISTOGRAM_CUSTOM_COUNTS(
(...skipping 10 matching lines...) Expand all
633 base::TimeDelta::FromDays(365).InMinutes(), 677 base::TimeDelta::FromDays(365).InMinutes(),
634 100); 678 100);
635 UMA_HISTOGRAM_MEMORY_KB( 679 UMA_HISTOGRAM_MEMORY_KB(
636 "OfflinePages.DeletePage.PageSize", iter->second.file_size / 1024); 680 "OfflinePages.DeletePage.PageSize", iter->second.file_size / 1024);
637 UMA_HISTOGRAM_COUNTS( 681 UMA_HISTOGRAM_COUNTS(
638 "OfflinePages.DeletePage.AccessCount", iter->second.access_count); 682 "OfflinePages.DeletePage.AccessCount", iter->second.access_count);
639 // If the page is not marked for deletion at this point, the model has not 683 // If the page is not marked for deletion at this point, the model has not
640 // yet informed the observer that the offline page is deleted. 684 // yet informed the observer that the offline page is deleted.
641 if (!iter->second.IsMarkedForDeletion()) { 685 if (!iter->second.IsMarkedForDeletion()) {
642 FOR_EACH_OBSERVER(Observer, observers_, 686 FOR_EACH_OBSERVER(Observer, observers_,
643 OfflinePageDeleted(iter->second.bookmark_id)); 687 OfflinePageDeleted(iter->second.offline_id));
644 } 688 }
645 offline_pages_.erase(iter); 689 offline_pages_.erase(iter);
646 } 690 }
647 if (bookmark_ids.size() > 1) { 691 if (offline_ids.size() > 1) {
648 UMA_HISTOGRAM_COUNTS( 692 UMA_HISTOGRAM_COUNTS("OfflinePages.BatchDelete.Count", offline_ids.size());
649 "OfflinePages.BatchDelete.Count", bookmark_ids.size());
650 UMA_HISTOGRAM_MEMORY_KB( 693 UMA_HISTOGRAM_MEMORY_KB(
651 "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024); 694 "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024);
652 } 695 }
653 // Deleting multiple pages always succeeds when it gets to this point. 696 // Deleting multiple pages always succeeds when it gets to this point.
654 InformDeletePageDone( 697 InformDeletePageDone(callback, (success || offline_ids.size() > 1)
655 callback, 698 ? DeletePageResult::SUCCESS
656 (success || bookmark_ids.size() > 1) ? DeletePageResult::SUCCESS 699 : DeletePageResult::STORE_FAILURE);
657 : DeletePageResult::STORE_FAILURE);
658 } 700 }
659 701
660 void OfflinePageModel::InformDeletePageDone(const DeletePageCallback& callback, 702 void OfflinePageModel::InformDeletePageDone(const DeletePageCallback& callback,
661 DeletePageResult result) { 703 DeletePageResult result) {
662 UMA_HISTOGRAM_ENUMERATION( 704 UMA_HISTOGRAM_ENUMERATION(
663 "OfflinePages.DeletePageResult", 705 "OfflinePages.DeletePageResult",
664 static_cast<int>(result), 706 static_cast<int>(result),
665 static_cast<int>(DeletePageResult::RESULT_COUNT)); 707 static_cast<int>(DeletePageResult::RESULT_COUNT));
666 if (!callback.is_null()) 708 if (!callback.is_null())
667 callback.Run(result); 709 callback.Run(result);
(...skipping 12 matching lines...) Expand all
680 722
681 store_->RemoveOfflinePages( 723 store_->RemoveOfflinePages(
682 *ids_of_pages_missing_archive_file, 724 *ids_of_pages_missing_archive_file,
683 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone, 725 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone,
684 weak_ptr_factory_.GetWeakPtr(), 726 weak_ptr_factory_.GetWeakPtr(),
685 *ids_of_pages_missing_archive_file, 727 *ids_of_pages_missing_archive_file,
686 done_callback)); 728 done_callback));
687 } 729 }
688 730
689 void OfflinePageModel::OnRemoveOfflinePagesMissingArchiveFileDone( 731 void OfflinePageModel::OnRemoveOfflinePagesMissingArchiveFileDone(
690 const std::vector<int64_t>& bookmark_ids, 732 const std::vector<int64_t>& offline_ids,
691 OfflinePageModel::DeletePageResult /* result */) { 733 OfflinePageModel::DeletePageResult /* result */) {
692 for (int64_t bookmark_id : bookmark_ids) { 734 for (int64_t offline_id : offline_ids) {
693 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageDeleted(bookmark_id)); 735 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageDeleted(offline_id));
694 } 736 }
695 } 737 }
696 738
697 void OfflinePageModel::OnRemoveAllFilesDoneForClearAll( 739 void OfflinePageModel::OnRemoveAllFilesDoneForClearAll(
698 const base::Closure& callback, 740 const base::Closure& callback,
699 DeletePageResult result) { 741 DeletePageResult result) {
700 store_->Reset(base::Bind(&OfflinePageModel::OnResetStoreDoneForClearAll, 742 store_->Reset(base::Bind(&OfflinePageModel::OnResetStoreDoneForClearAll,
701 weak_ptr_factory_.GetWeakPtr(), 743 weak_ptr_factory_.GetWeakPtr(),
702 callback)); 744 callback));
703 } 745 }
(...skipping 23 matching lines...) Expand all
727 CLEAR_ALL_STATUS_COUNT); 769 CLEAR_ALL_STATUS_COUNT);
728 770
729 CacheLoadedData(offline_pages); 771 CacheLoadedData(offline_pages);
730 callback.Run(); 772 callback.Run();
731 } 773 }
732 774
733 void OfflinePageModel::CacheLoadedData( 775 void OfflinePageModel::CacheLoadedData(
734 const std::vector<OfflinePageItem>& offline_pages) { 776 const std::vector<OfflinePageItem>& offline_pages) {
735 offline_pages_.clear(); 777 offline_pages_.clear();
736 for (const auto& offline_page : offline_pages) 778 for (const auto& offline_page : offline_pages)
737 offline_pages_[offline_page.bookmark_id] = offline_page; 779 offline_pages_[offline_page.offline_id] = offline_page;
780 }
781
782 int64_t OfflinePageModel::GenerateOfflineId() {
783 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1;
738 } 784 }
739 785
740 } // namespace offline_pages 786 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698