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

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

Powered by Google App Engine
This is Rietveld 408576698