OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/sync/glue/favicon_cache.h" | 5 #include "chrome/browser/sync/glue/favicon_cache.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "chrome/browser/favicon/favicon_service.h" | 9 #include "chrome/browser/favicon/favicon_service.h" |
10 #include "chrome/browser/favicon/favicon_service_factory.h" | 10 #include "chrome/browser/favicon/favicon_service_factory.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 // Note: Do not modify this directly! It should only be modified via | 45 // Note: Do not modify this directly! It should only be modified via |
46 // UpdateFaviconVisitTime(..). | 46 // UpdateFaviconVisitTime(..). |
47 base::Time last_visit_time; | 47 base::Time last_visit_time; |
48 // Whether we've received a local update for this favicon since starting up. | 48 // Whether we've received a local update for this favicon since starting up. |
49 bool received_local_update; | 49 bool received_local_update; |
50 | 50 |
51 private: | 51 private: |
52 DISALLOW_COPY_AND_ASSIGN(SyncedFaviconInfo); | 52 DISALLOW_COPY_AND_ASSIGN(SyncedFaviconInfo); |
53 }; | 53 }; |
54 | 54 |
55 // Information for handling local favicon updates. Used in | |
56 // OnFaviconDataAvailable. | |
57 struct LocalFaviconUpdateInfo { | |
58 LocalFaviconUpdateInfo() | |
59 : new_image(false), | |
60 new_tracking(false), | |
61 image_needs_rewrite(false), | |
62 favicon_info(NULL) {} | |
63 | |
64 bool new_image; | |
65 bool new_tracking; | |
66 bool image_needs_rewrite; | |
67 SyncedFaviconInfo* favicon_info; | |
68 }; | |
69 | |
55 namespace { | 70 namespace { |
56 | 71 |
57 // Maximum number of favicons to keep in memory (0 means no limit). | 72 // Maximum number of favicons to keep in memory (0 means no limit). |
58 const size_t kMaxFaviconsInMem = 0; | 73 const size_t kMaxFaviconsInMem = 0; |
59 | 74 |
60 // Maximum width/height resolution supported. | 75 // Maximum width/height resolution supported. |
61 const int kMaxFaviconResolution = 16; | 76 const int kMaxFaviconResolution = 16; |
62 | 77 |
63 // Returns a mask of the supported favicon types. | 78 // Returns a mask of the supported favicon types. |
64 // TODO(zea): Supporting other favicons types will involve some work in the | 79 // TODO(zea): Supporting other favicons types will involve some work in the |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 favicon_info->bitmap_data[icon_size] = bitmap_result; | 195 favicon_info->bitmap_data[icon_size] = bitmap_result; |
181 favicon_info->received_local_update = true; | 196 favicon_info->received_local_update = true; |
182 return true; | 197 return true; |
183 } else { | 198 } else { |
184 // We only allow updating the image data once per restart. | 199 // We only allow updating the image data once per restart. |
185 DVLOG(2) << "Ignoring local update for " << bitmap_result.icon_url.spec(); | 200 DVLOG(2) << "Ignoring local update for " << bitmap_result.icon_url.spec(); |
186 return false; | 201 return false; |
187 } | 202 } |
188 } | 203 } |
189 | 204 |
205 bool FaviconInfoHasImages(const SyncedFaviconInfo& favicon_info) { | |
206 return favicon_info.bitmap_data[SIZE_16].bitmap_data.get() || | |
207 favicon_info.bitmap_data[SIZE_32].bitmap_data.get() || | |
208 favicon_info.bitmap_data[SIZE_64].bitmap_data.get(); | |
209 } | |
210 | |
211 bool FaviconInfoHasTracking(const SyncedFaviconInfo& favicon_info) { | |
212 return !favicon_info.last_visit_time.is_null(); | |
213 } | |
214 | |
190 } // namespace | 215 } // namespace |
191 | 216 |
192 FaviconCacheObserver::~FaviconCacheObserver() {} | 217 FaviconCacheObserver::~FaviconCacheObserver() {} |
193 | 218 |
194 FaviconCache::FaviconCache(Profile* profile, int max_sync_favicon_limit) | 219 FaviconCache::FaviconCache(Profile* profile, int max_sync_favicon_limit) |
195 : profile_(profile), | 220 : profile_(profile), |
196 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 221 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
197 legacy_delegate_(NULL), | 222 legacy_delegate_(NULL), |
198 max_sync_favicon_limit_(max_sync_favicon_limit) { | 223 max_sync_favicon_limit_(max_sync_favicon_limit) { |
199 notification_registrar_.Add(this, | 224 notification_registrar_.Add(this, |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 } | 343 } |
319 FaviconMap::iterator favicon_iter = synced_favicons_.find(favicon_url); | 344 FaviconMap::iterator favicon_iter = synced_favicons_.find(favicon_url); |
320 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { | 345 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { |
321 if (favicon_iter == synced_favicons_.end()) { | 346 if (favicon_iter == synced_favicons_.end()) { |
322 // Two clients might wind up deleting different parts of the same | 347 // Two clients might wind up deleting different parts of the same |
323 // favicon, so ignore this. | 348 // favicon, so ignore this. |
324 continue; | 349 continue; |
325 } else { | 350 } else { |
326 DVLOG(1) << "Deleting favicon at " << favicon_url.spec(); | 351 DVLOG(1) << "Deleting favicon at " << favicon_url.spec(); |
327 DropSyncedFavicon(favicon_iter); | 352 DropSyncedFavicon(favicon_iter); |
328 // TODO(zea): it's possible that we'll receive a deletion for an image, | |
329 // but not a tracking data, or vice versa, resulting in an orphan | |
330 // favicon node in one of the types. We should track how often this | |
331 // happens, and if it becomes a problem delete each part individually | |
332 // from the local model. | |
333 } | 353 } |
334 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE || | 354 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE || |
335 iter->change_type() == syncer::SyncChange::ACTION_ADD) { | 355 iter->change_type() == syncer::SyncChange::ACTION_ADD) { |
336 // Adds and updates are treated the same due to the lack of strong | 356 // Adds and updates are treated the same due to the lack of strong |
337 // consistency (it's possible we'll receive an update for a tracking info | 357 // consistency (it's possible we'll receive an update for a tracking info |
338 // before we've received the add for the image, and should handle both | 358 // before we've received the add for the image, and should handle both |
339 // gracefully). | 359 // gracefully). |
340 if (favicon_iter == synced_favicons_.end()) { | 360 if (favicon_iter == synced_favicons_.end()) { |
341 DVLOG(1) << "Adding favicon at " << favicon_url.spec(); | 361 DVLOG(1) << "Adding favicon at " << favicon_url.spec(); |
342 AddLocalFaviconFromSyncedData(iter->sync_data()); | 362 AddLocalFaviconFromSyncedData(iter->sync_data()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 FaviconMap::const_iterator icon_iter = | 400 FaviconMap::const_iterator icon_iter = |
381 synced_favicons_.find(url_iter->second); | 401 synced_favicons_.find(url_iter->second); |
382 // TODO(zea): consider what to do when only a subset of supported | 402 // TODO(zea): consider what to do when only a subset of supported |
383 // resolutions are available. | 403 // resolutions are available. |
384 if (icon_iter != synced_favicons_.end() && | 404 if (icon_iter != synced_favicons_.end() && |
385 icon_iter->second->bitmap_data[SIZE_16].bitmap_data.get()) { | 405 icon_iter->second->bitmap_data[SIZE_16].bitmap_data.get()) { |
386 DVLOG(2) << "Using cached favicon url for " << page_url.spec() | 406 DVLOG(2) << "Using cached favicon url for " << page_url.spec() |
387 << ": " << icon_iter->second->favicon_url.spec(); | 407 << ": " << icon_iter->second->favicon_url.spec(); |
388 UpdateFaviconVisitTime(icon_iter->second->favicon_url, base::Time::Now()); | 408 UpdateFaviconVisitTime(icon_iter->second->favicon_url, base::Time::Now()); |
389 UpdateSyncState(icon_iter->second->favicon_url, | 409 UpdateSyncState(icon_iter->second->favicon_url, |
390 SYNC_TRACKING, | 410 syncer::SyncChange::ACTION_INVALID, |
391 syncer::SyncChange::ACTION_UPDATE); | 411 syncer::SyncChange::ACTION_UPDATE); |
392 return; | 412 return; |
393 } | 413 } |
394 } | 414 } |
395 | 415 |
396 DVLOG(1) << "Triggering favicon load for url " << page_url.spec(); | 416 DVLOG(1) << "Triggering favicon load for url " << page_url.spec(); |
397 | 417 |
398 if (!profile_) { | 418 if (!profile_) { |
399 page_task_map_[page_url] = 0; // For testing only. | 419 page_task_map_[page_url] = 0; // For testing only. |
400 return; | 420 return; |
(...skipping 23 matching lines...) Expand all Loading... | |
424 // all desired resolutions? | 444 // all desired resolutions? |
425 OnPageFaviconUpdated(page_url); | 445 OnPageFaviconUpdated(page_url); |
426 return; | 446 return; |
427 } | 447 } |
428 | 448 |
429 DVLOG(1) << "Associating " << page_url.spec() << " with favicon at " | 449 DVLOG(1) << "Associating " << page_url.spec() << " with favicon at " |
430 << favicon_url.spec() << " and marking visited."; | 450 << favicon_url.spec() << " and marking visited."; |
431 page_favicon_map_[page_url] = favicon_url; | 451 page_favicon_map_[page_url] = favicon_url; |
432 UpdateFaviconVisitTime(favicon_url, base::Time::Now()); | 452 UpdateFaviconVisitTime(favicon_url, base::Time::Now()); |
433 UpdateSyncState(favicon_url, | 453 UpdateSyncState(favicon_url, |
434 SYNC_TRACKING, | 454 syncer::SyncChange::ACTION_INVALID, |
435 syncer::SyncChange::ACTION_UPDATE); | 455 (FaviconInfoHasTracking( |
456 *synced_favicons_.find(favicon_url)->second) ? | |
457 syncer::SyncChange::ACTION_UPDATE : | |
458 syncer::SyncChange::ACTION_ADD)); | |
436 } | 459 } |
437 | 460 |
438 bool FaviconCache::GetSyncedFaviconForFaviconURL( | 461 bool FaviconCache::GetSyncedFaviconForFaviconURL( |
439 const GURL& favicon_url, | 462 const GURL& favicon_url, |
440 scoped_refptr<base::RefCountedMemory>* favicon_png) const { | 463 scoped_refptr<base::RefCountedMemory>* favicon_png) const { |
441 if (!favicon_url.is_valid()) | 464 if (!favicon_url.is_valid()) |
442 return false; | 465 return false; |
443 FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url); | 466 FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url); |
444 | 467 |
445 UMA_HISTOGRAM_BOOLEAN("Sync.FaviconCacheLookupSucceeded", | 468 UMA_HISTOGRAM_BOOLEAN("Sync.FaviconCacheLookupSucceeded", |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 | 533 |
511 SyncedFaviconInfo* favicon_info = GetFaviconInfo(icon_url); | 534 SyncedFaviconInfo* favicon_info = GetFaviconInfo(icon_url); |
512 if (!favicon_info) | 535 if (!favicon_info) |
513 return; // We reached the in-memory limit. | 536 return; // We reached the in-memory limit. |
514 base::RefCountedString* temp_string = new base::RefCountedString(); | 537 base::RefCountedString* temp_string = new base::RefCountedString(); |
515 temp_string->data() = icon_bytes; | 538 temp_string->data() = icon_bytes; |
516 favicon_info->bitmap_data[SIZE_16].bitmap_data = temp_string; | 539 favicon_info->bitmap_data[SIZE_16].bitmap_data = temp_string; |
517 // We assume legacy favicons are 16x16. | 540 // We assume legacy favicons are 16x16. |
518 favicon_info->bitmap_data[SIZE_16].pixel_size.set_width(16); | 541 favicon_info->bitmap_data[SIZE_16].pixel_size.set_width(16); |
519 favicon_info->bitmap_data[SIZE_16].pixel_size.set_height(16); | 542 favicon_info->bitmap_data[SIZE_16].pixel_size.set_height(16); |
520 UpdateFaviconVisitTime(icon_url, syncer::ProtoTimeToTime(visit_time_ms)); | 543 bool added_tracking = !FaviconInfoHasTracking(*favicon_info); |
544 UpdateFaviconVisitTime(icon_url, | |
545 syncer::ProtoTimeToTime(visit_time_ms)); | |
521 | 546 |
522 UpdateSyncState(icon_url, | 547 UpdateSyncState(icon_url, |
523 SYNC_BOTH, | 548 syncer::SyncChange::ACTION_ADD, |
524 syncer::SyncChange::ACTION_ADD); | 549 (added_tracking ? |
550 syncer::SyncChange::ACTION_ADD : | |
551 syncer::SyncChange::ACTION_UPDATE)); | |
525 } | 552 } |
526 | 553 |
527 void FaviconCache::SetLegacyDelegate(FaviconCacheObserver* observer) { | 554 void FaviconCache::SetLegacyDelegate(FaviconCacheObserver* observer) { |
528 legacy_delegate_ = observer; | 555 legacy_delegate_ = observer; |
529 } | 556 } |
530 | 557 |
531 void FaviconCache::RemoveLegacyDelegate() { | 558 void FaviconCache::RemoveLegacyDelegate() { |
532 legacy_delegate_ = NULL; | 559 legacy_delegate_ = NULL; |
533 } | 560 } |
534 | 561 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 page_task_map_.erase(page_iter); | 614 page_task_map_.erase(page_iter); |
588 | 615 |
589 if (bitmap_results.size() == 0) { | 616 if (bitmap_results.size() == 0) { |
590 // Either the favicon isn't loaded yet or there is no valid favicon. | 617 // Either the favicon isn't loaded yet or there is no valid favicon. |
591 // We already cleared the task id, so just return. | 618 // We already cleared the task id, so just return. |
592 DVLOG(1) << "Favicon load failed for page " << page_url.spec(); | 619 DVLOG(1) << "Favicon load failed for page " << page_url.spec(); |
593 return; | 620 return; |
594 } | 621 } |
595 | 622 |
596 base::Time now = base::Time::Now(); | 623 base::Time now = base::Time::Now(); |
597 std::set<SyncedFaviconInfo*> favicon_updates; | 624 std::map<GURL, LocalFaviconUpdateInfo> favicon_updates; |
598 for (size_t i = 0; i < bitmap_results.size(); ++i) { | 625 for (size_t i = 0; i < bitmap_results.size(); ++i) { |
599 const history::FaviconBitmapResult& bitmap_result = bitmap_results[i]; | 626 const history::FaviconBitmapResult& bitmap_result = bitmap_results[i]; |
600 GURL favicon_url = bitmap_result.icon_url; | 627 GURL favicon_url = bitmap_result.icon_url; |
601 if (!favicon_url.is_valid() || favicon_url.SchemeIs("data")) | 628 if (!favicon_url.is_valid() || favicon_url.SchemeIs("data")) |
602 continue; // Can happen if the page is still loading. | 629 continue; // Can happen if the page is still loading. |
603 | 630 |
604 SyncedFaviconInfo* favicon_info = GetFaviconInfo(favicon_url); | 631 SyncedFaviconInfo* favicon_info = GetFaviconInfo(favicon_url); |
605 if (!favicon_info) | 632 if (!favicon_info) |
606 return; // We reached the in-memory limit. | 633 return; // We reached the in-memory limit. |
607 | 634 |
608 if (!UpdateFaviconFromBitmapResult(bitmap_result, favicon_info)) | 635 favicon_updates[favicon_url].new_image |= |
609 continue; // Invalid favicon or no change. | 636 !FaviconInfoHasImages(*favicon_info); |
610 | 637 favicon_updates[favicon_url].new_tracking |= |
611 favicon_updates.insert(favicon_info); | 638 !FaviconInfoHasTracking(*favicon_info); |
639 favicon_updates[favicon_url].image_needs_rewrite |= | |
640 UpdateFaviconFromBitmapResult(bitmap_result, favicon_info); | |
641 favicon_updates[favicon_url].favicon_info = favicon_info; | |
612 } | 642 } |
613 | 643 |
614 for (std::set<SyncedFaviconInfo*>::iterator iter = favicon_updates.begin(); | 644 for (std::map<GURL, LocalFaviconUpdateInfo>::const_iterator |
615 iter != favicon_updates.end(); ++iter) { | 645 iter = favicon_updates.begin(); iter != favicon_updates.end(); |
616 SyncedFaviconInfo* favicon_info = *iter; | 646 ++iter) { |
647 SyncedFaviconInfo* favicon_info = iter->second.favicon_info; | |
617 const GURL& favicon_url = favicon_info->favicon_url; | 648 const GURL& favicon_url = favicon_info->favicon_url; |
618 if (!favicon_info->last_visit_time.is_null()) { | 649 if (!favicon_info->last_visit_time.is_null()) { |
619 UMA_HISTOGRAM_COUNTS_10000( | 650 UMA_HISTOGRAM_COUNTS_10000( |
620 "Sync.FaviconVisitPeriod", | 651 "Sync.FaviconVisitPeriod", |
621 (now - favicon_info->last_visit_time).InHours()); | 652 (now - favicon_info->last_visit_time).InHours()); |
622 } | 653 } |
623 favicon_info->received_local_update = true; | 654 favicon_info->received_local_update = true; |
624 bool added_favicon = favicon_info->last_visit_time.is_null(); | |
625 UpdateFaviconVisitTime(favicon_url, now); | 655 UpdateFaviconVisitTime(favicon_url, now); |
626 UpdateSyncState(favicon_url, | 656 UpdateSyncState(favicon_url, |
rlarocque
2013/04/04 23:29:07
I dislike ternary operators, and wouldn't use them
Nicolas Zea
2013/04/04 23:42:29
Haha, ok, done.
| |
627 SYNC_BOTH, | 657 (iter->second.new_image ? |
628 (added_favicon ? | 658 syncer::SyncChange::ACTION_ADD : |
659 (iter->second.image_needs_rewrite ? | |
660 syncer::SyncChange::ACTION_UPDATE : | |
661 syncer::SyncChange::ACTION_INVALID)), | |
662 (iter->second.new_tracking ? | |
629 syncer::SyncChange::ACTION_ADD : | 663 syncer::SyncChange::ACTION_ADD : |
630 syncer::SyncChange::ACTION_UPDATE)); | 664 syncer::SyncChange::ACTION_UPDATE)); |
631 if (legacy_delegate_) | 665 if (legacy_delegate_) |
632 legacy_delegate_->OnFaviconUpdated(page_url, favicon_url); | 666 legacy_delegate_->OnFaviconUpdated(page_url, favicon_url); |
633 | 667 |
634 // TODO(zea): support multiple favicon urls per page. | 668 // TODO(zea): support multiple favicon urls per page. |
635 page_favicon_map_[page_url] = favicon_url; | 669 page_favicon_map_[page_url] = favicon_url; |
636 } | 670 } |
637 } | 671 } |
638 | 672 |
639 void FaviconCache::UpdateSyncState( | 673 void FaviconCache::UpdateSyncState( |
640 const GURL& icon_url, | 674 const GURL& icon_url, |
641 SyncState state_to_update, | 675 syncer::SyncChange::SyncChangeType image_change_type, |
642 syncer::SyncChange::SyncChangeType change_type) { | 676 syncer::SyncChange::SyncChangeType tracking_change_type) { |
643 DCHECK(icon_url.is_valid()); | 677 DCHECK(icon_url.is_valid()); |
644 // It's possible that we'll receive a favicon update before both types | 678 // It's possible that we'll receive a favicon update before both types |
645 // have finished setting up. In that case ignore the update. | 679 // have finished setting up. In that case ignore the update. |
646 // TODO(zea): consider tracking these skipped updates somehow? | 680 // TODO(zea): consider tracking these skipped updates somehow? |
647 if (!favicon_images_sync_processor_.get() || | 681 if (!favicon_images_sync_processor_.get() || |
648 !favicon_tracking_sync_processor_.get()) | 682 !favicon_tracking_sync_processor_.get()) |
649 return; | 683 return; |
650 | 684 |
651 FaviconMap::const_iterator iter = synced_favicons_.find(icon_url); | 685 FaviconMap::const_iterator iter = synced_favicons_.find(icon_url); |
652 DCHECK(iter != synced_favicons_.end()); | 686 DCHECK(iter != synced_favicons_.end()); |
653 const SyncedFaviconInfo* favicon_info = iter->second.get(); | 687 const SyncedFaviconInfo* favicon_info = iter->second.get(); |
654 | 688 |
655 syncer::SyncChangeList image_changes; | 689 syncer::SyncChangeList image_changes; |
656 syncer::SyncChangeList tracking_changes; | 690 syncer::SyncChangeList tracking_changes; |
657 if (state_to_update == SYNC_IMAGE || state_to_update == SYNC_BOTH) { | 691 if (image_change_type != syncer::SyncChange::ACTION_INVALID) { |
658 sync_pb::EntitySpecifics new_specifics; | 692 sync_pb::EntitySpecifics new_specifics; |
659 sync_pb::FaviconImageSpecifics* image_specifics = | 693 sync_pb::FaviconImageSpecifics* image_specifics = |
660 new_specifics.mutable_favicon_image(); | 694 new_specifics.mutable_favicon_image(); |
661 BuildImageSpecifics(favicon_info, image_specifics); | 695 BuildImageSpecifics(favicon_info, image_specifics); |
662 | 696 |
663 image_changes.push_back( | 697 image_changes.push_back( |
664 syncer::SyncChange(FROM_HERE, | 698 syncer::SyncChange(FROM_HERE, |
665 change_type, | 699 image_change_type, |
666 syncer::SyncData::CreateLocalData( | 700 syncer::SyncData::CreateLocalData( |
667 icon_url.spec(), | 701 icon_url.spec(), |
668 icon_url.spec(), | 702 icon_url.spec(), |
669 new_specifics))); | 703 new_specifics))); |
670 } | 704 } |
671 if (state_to_update == SYNC_TRACKING || state_to_update == SYNC_BOTH) { | 705 if (tracking_change_type != syncer::SyncChange::ACTION_INVALID) { |
672 sync_pb::EntitySpecifics new_specifics; | 706 sync_pb::EntitySpecifics new_specifics; |
673 sync_pb::FaviconTrackingSpecifics* tracking_specifics = | 707 sync_pb::FaviconTrackingSpecifics* tracking_specifics = |
674 new_specifics.mutable_favicon_tracking(); | 708 new_specifics.mutable_favicon_tracking(); |
675 BuildTrackingSpecifics(favicon_info, tracking_specifics); | 709 BuildTrackingSpecifics(favicon_info, tracking_specifics); |
676 | 710 |
677 tracking_changes.push_back( | 711 tracking_changes.push_back( |
678 syncer::SyncChange(FROM_HERE, | 712 syncer::SyncChange(FROM_HERE, |
679 change_type, | 713 tracking_change_type, |
680 syncer::SyncData::CreateLocalData( | 714 syncer::SyncData::CreateLocalData( |
681 icon_url.spec(), | 715 icon_url.spec(), |
682 icon_url.spec(), | 716 icon_url.spec(), |
683 new_specifics))); | 717 new_specifics))); |
684 } | 718 } |
685 ExpireFaviconsIfNecessary(&image_changes, &tracking_changes); | 719 ExpireFaviconsIfNecessary(&image_changes, &tracking_changes); |
686 if (!image_changes.empty()) { | 720 if (!image_changes.empty()) { |
687 favicon_images_sync_processor_->ProcessSyncChanges(FROM_HERE, | 721 favicon_images_sync_processor_->ProcessSyncChanges(FROM_HERE, |
688 image_changes); | 722 image_changes); |
689 } | 723 } |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
950 | 984 |
951 size_t FaviconCache::NumFaviconsForTest() const { | 985 size_t FaviconCache::NumFaviconsForTest() const { |
952 return synced_favicons_.size(); | 986 return synced_favicons_.size(); |
953 } | 987 } |
954 | 988 |
955 size_t FaviconCache::NumTasksForTest() const { | 989 size_t FaviconCache::NumTasksForTest() const { |
956 return page_task_map_.size(); | 990 return page_task_map_.size(); |
957 } | 991 } |
958 | 992 |
959 } // namespace browser_sync | 993 } // namespace browser_sync |
OLD | NEW |