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

Side by Side Diff: chrome/browser/history/top_sites_impl.cc

Issue 53283004: Adding support for forced URLs to TopSites. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Corrected minor spacing problem. Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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/history/top_sites_impl.h" 5 #include "chrome/browser/history/top_sites_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 using base::DictionaryValue; 48 using base::DictionaryValue;
49 using content::BrowserThread; 49 using content::BrowserThread;
50 using content::NavigationController; 50 using content::NavigationController;
51 51
52 namespace history { 52 namespace history {
53 53
54 namespace { 54 namespace {
55 55
56 void RunOrPostGetMostVisitedURLsCallback( 56 void RunOrPostGetMostVisitedURLsCallback(
57 base::TaskRunner* task_runner, 57 base::TaskRunner* task_runner,
58 bool include_forced_urls,
58 const TopSitesImpl::GetMostVisitedURLsCallback& callback, 59 const TopSitesImpl::GetMostVisitedURLsCallback& callback,
59 const MostVisitedURLList& urls) { 60 const MostVisitedURLList& all_urls,
61 const MostVisitedURLList& nonforced_urls) {
62 const MostVisitedURLList* urls =
63 include_forced_urls ? &all_urls : &nonforced_urls;
brettw 2013/11/08 22:56:07 Indent 2 more spaces.
beaudoin 2013/11/11 21:58:09 Done.
60 if (task_runner->RunsTasksOnCurrentThread()) 64 if (task_runner->RunsTasksOnCurrentThread())
61 callback.Run(urls); 65 callback.Run(*urls);
62 else 66 else
63 task_runner->PostTask(FROM_HERE, base::Bind(callback, urls)); 67 task_runner->PostTask(FROM_HERE, base::Bind(callback, *urls));
68 }
69
70 // Compares two MostVisitedURL having a non-null |last_forced_time|.
71 bool ForcedURLComparator(const MostVisitedURL& first,
72 const MostVisitedURL& second) {
73 DCHECK(!first.last_forced_time.is_null() &&
74 !second.last_forced_time.is_null());
75 return first.last_forced_time < second.last_forced_time;
64 } 76 }
65 77
66 } // namespace 78 } // namespace
67 79
68 // How many top sites to store in the cache. 80 // How many non-forced top sites to store in the cache.
69 static const size_t kTopSitesNumber = 20; 81 static const size_t kNonForcedTopSitesNumber = 20;
82
83 // How many forced top sites to store in the cache.
84 static const size_t kForcedTopSitesNumber = 20;
70 85
71 // Max number of temporary images we'll cache. See comment above 86 // Max number of temporary images we'll cache. See comment above
72 // temp_images_ for details. 87 // temp_images_ for details.
73 static const size_t kMaxTempTopImages = 8; 88 static const size_t kMaxTempTopImages = 8;
74 89
75 static const int kDaysOfHistory = 90; 90 static const int kDaysOfHistory = 90;
76 // Time from startup to first HistoryService query. 91 // Time from startup to first HistoryService query.
77 static const int64 kUpdateIntervalSecs = 15; 92 static const int64 kUpdateIntervalSecs = 15;
78 // Intervals between requests to HistoryService. 93 // Intervals between requests to HistoryService.
79 static const int64 kMinUpdateIntervalMinutes = 1; 94 static const int64 kMinUpdateIntervalMinutes = 1;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
126 141
127 if (!loaded_) { 142 if (!loaded_) {
128 // TODO(sky): I need to cache these and apply them after the load 143 // TODO(sky): I need to cache these and apply them after the load
129 // completes. 144 // completes.
130 return false; 145 return false;
131 } 146 }
132 147
133 bool add_temp_thumbnail = false; 148 bool add_temp_thumbnail = false;
134 if (!IsKnownURL(url)) { 149 if (!IsKnownURL(url)) {
135 if (!IsFull()) { 150 if (!IsNonForcedFull()) {
136 add_temp_thumbnail = true; 151 add_temp_thumbnail = true;
137 } else { 152 } else {
138 return false; // This URL is not known to us. 153 return false; // This URL is not known to us.
139 } 154 }
140 } 155 }
141 156
142 if (!HistoryService::CanAddURL(url)) 157 if (!HistoryService::CanAddURL(url))
143 return false; // It's not a real webpage. 158 return false; // It's not a real webpage.
144 159
145 scoped_refptr<base::RefCountedBytes> thumbnail_data; 160 scoped_refptr<base::RefCountedBytes> thumbnail_data;
(...skipping 18 matching lines...) Expand all
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
165 180
166 if (!loaded_) { 181 if (!loaded_) {
167 // TODO(sky): I need to cache these and apply them after the load 182 // TODO(sky): I need to cache these and apply them after the load
168 // completes. 183 // completes.
169 return false; 184 return false;
170 } 185 }
171 186
172 bool add_temp_thumbnail = false; 187 bool add_temp_thumbnail = false;
173 if (!IsKnownURL(url)) { 188 if (!IsKnownURL(url)) {
174 if (!IsFull()) { 189 if (!IsNonForcedFull()) {
175 add_temp_thumbnail = true; 190 add_temp_thumbnail = true;
176 } else { 191 } else {
177 return false; // This URL is not known to us. 192 return false; // This URL is not known to us.
178 } 193 }
179 } 194 }
180 195
181 if (!HistoryService::CanAddURL(url)) 196 if (!HistoryService::CanAddURL(url))
182 return false; // It's not a real webpage. 197 return false; // It's not a real webpage.
183 198
184 if (add_temp_thumbnail) { 199 if (add_temp_thumbnail) {
185 // Always remove the existing entry and then add it back. That way if we end 200 // Always remove the existing entry and then add it back. That way if we end
186 // up with too many temp thumbnails we'll prune the oldest first. 201 // up with too many temp thumbnails we'll prune the oldest first.
187 RemoveTemporaryThumbnailByURL(url); 202 RemoveTemporaryThumbnailByURL(url);
188 AddTemporaryThumbnail(url, memory, score); 203 AddTemporaryThumbnail(url, memory, score);
189 return true; 204 return true;
190 } 205 }
191 206
192 return SetPageThumbnailEncoded(url, memory, score); 207 return SetPageThumbnailEncoded(url, memory, score);
193 } 208 }
194 209
195 // WARNING: this function may be invoked on any thread. 210 // WARNING: this function may be invoked on any thread.
196 void TopSitesImpl::GetMostVisitedURLs( 211 void TopSitesImpl::GetMostVisitedURLs(
197 const GetMostVisitedURLsCallback& callback) { 212 const GetMostVisitedURLsCallback& callback) {
213 GetAllMostVisitedURLs(callback, false);
214 }
215
216 // WARNING: this function may be invoked on any thread.
217 void TopSitesImpl::GetAllMostVisitedURLs(
218 const GetMostVisitedURLsCallback& callback,
219 bool include_forced_urls) {
198 MostVisitedURLList filtered_urls; 220 MostVisitedURLList filtered_urls;
199 { 221 {
200 base::AutoLock lock(lock_); 222 base::AutoLock lock(lock_);
201 if (!loaded_) { 223 if (!loaded_) {
202 // A request came in before we finished loading. Store the callback and 224 // A request came in before we finished loading. Store the callback and
203 // we'll run it on current thread when we finish loading. 225 // we'll run it on current thread when we finish loading.
204 pending_callbacks_.push_back( 226 pending_callbacks_.push_back(
205 base::Bind(&RunOrPostGetMostVisitedURLsCallback, 227 base::Bind(&RunOrPostGetMostVisitedURLsCallback,
206 base::MessageLoopProxy::current(), 228 base::MessageLoopProxy::current(),
229 include_forced_urls,
207 callback)); 230 callback));
208 return; 231 return;
209 } 232 }
210 filtered_urls = thread_safe_cache_->top_sites(); 233 if (include_forced_urls) {
234 filtered_urls = thread_safe_cache_->top_sites();
235 } else {
236 filtered_urls.assign(thread_safe_cache_->top_sites().begin() +
237 thread_safe_cache_->GetNbForcedURLs(),
238 thread_safe_cache_->top_sites().end());
239 }
211 } 240 }
212 callback.Run(filtered_urls); 241 callback.Run(filtered_urls);
213 } 242 }
214 243
215 bool TopSitesImpl::GetPageThumbnail( 244 bool TopSitesImpl::GetPageThumbnail(
216 const GURL& url, 245 const GURL& url,
217 bool prefix_match, 246 bool prefix_match,
218 scoped_refptr<base::RefCountedMemory>* bytes) { 247 scoped_refptr<base::RefCountedMemory>* bytes) {
219 // WARNING: this may be invoked on any thread. 248 // WARNING: this may be invoked on any thread.
220 // Perform exact match. 249 // Perform exact match.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 // invoked Shutdown (this could happen if we have a pending request and 395 // invoked Shutdown (this could happen if we have a pending request and
367 // Shutdown is invoked). 396 // Shutdown is invoked).
368 history_consumer_.CancelAllRequests(); 397 history_consumer_.CancelAllRequests();
369 backend_->Shutdown(); 398 backend_->Shutdown();
370 } 399 }
371 400
372 // static 401 // static
373 void TopSitesImpl::DiffMostVisited(const MostVisitedURLList& old_list, 402 void TopSitesImpl::DiffMostVisited(const MostVisitedURLList& old_list,
374 const MostVisitedURLList& new_list, 403 const MostVisitedURLList& new_list,
375 TopSitesDelta* delta) { 404 TopSitesDelta* delta) {
405
376 // Add all the old URLs for quick lookup. This maps URLs to the corresponding 406 // Add all the old URLs for quick lookup. This maps URLs to the corresponding
377 // index in the input. 407 // index in the input.
378 std::map<GURL, size_t> all_old_urls; 408 std::map<GURL, size_t> all_old_urls;
379 for (size_t i = 0; i < old_list.size(); i++) 409 size_t nb_old_forced = 0;
410 for (size_t i = 0; i < old_list.size(); i++) {
411 if (!old_list[i].last_forced_time.is_null())
412 nb_old_forced++;
413 DCHECK(old_list[i].last_forced_time.is_null() || i < nb_old_forced)
414 << "Forced URLs must all appear before non-forced URLs.";
380 all_old_urls[old_list[i].url] = i; 415 all_old_urls[old_list[i].url] = i;
416 }
381 417
382 // Check all the URLs in the new set to see which ones are new or just moved. 418 // Check all the URLs in the new set to see which ones are new or just moved.
383 // When we find a match in the old set, we'll reset its index to our special 419 // When we find a match in the old set, we'll reset its index to our special
384 // marker. This allows us to quickly identify the deleted ones in a later 420 // marker. This allows us to quickly identify the deleted ones in a later
385 // pass. 421 // pass.
386 const size_t kAlreadyFoundMarker = static_cast<size_t>(-1); 422 const size_t kAlreadyFoundMarker = static_cast<size_t>(-1);
423 int rank = -1; // Forced URLs have a rank of -1.
387 for (size_t i = 0; i < new_list.size(); i++) { 424 for (size_t i = 0; i < new_list.size(); i++) {
425 // Increase the rank if we're going through forced URLs. This works because
426 // non-forced URLs all come after forced URLs.
427 if (new_list[i].last_forced_time.is_null())
428 rank++;
429 DCHECK(new_list[i].last_forced_time.is_null() == (rank != -1))
430 << "Forced URLs must all appear before non-forced URLs.";
388 std::map<GURL, size_t>::iterator found = all_old_urls.find(new_list[i].url); 431 std::map<GURL, size_t>::iterator found = all_old_urls.find(new_list[i].url);
389 if (found == all_old_urls.end()) { 432 if (found == all_old_urls.end()) {
390 MostVisitedURLWithRank added; 433 MostVisitedURLWithRank added;
391 added.url = new_list[i]; 434 added.url = new_list[i];
392 added.rank = i; 435 added.rank = rank;
393 delta->added.push_back(added); 436 delta->added.push_back(added);
394 } else { 437 } else {
395 if (found->second != i) { 438 DCHECK(found->second != kAlreadyFoundMarker)
439 << "Same URL appears twice in the new list.";
440 int oldRank = found->second >= nb_old_forced ?
brettw 2013/11/08 23:14:58 Style: oldRank -> old_rank
beaudoin 2013/11/11 21:58:09 Sorry! :| Done.
441 found->second - nb_old_forced : -1;
442 if (oldRank != rank ||
443 old_list[found->second].last_forced_time !=
444 new_list[i].last_forced_time) {
396 MostVisitedURLWithRank moved; 445 MostVisitedURLWithRank moved;
397 moved.url = new_list[i]; 446 moved.url = new_list[i];
398 moved.rank = i; 447 moved.rank = rank;
399 delta->moved.push_back(moved); 448 delta->moved.push_back(moved);
400 } 449 }
401 found->second = kAlreadyFoundMarker; 450 found->second = kAlreadyFoundMarker;
402 } 451 }
403 } 452 }
404 453
405 // Any member without the special marker in the all_old_urls list means that 454 // Any member without the special marker in the all_old_urls list means that
406 // there wasn't a "new" URL that mapped to it, so it was deleted. 455 // there wasn't a "new" URL that mapped to it, so it was deleted.
407 for (std::map<GURL, size_t>::const_iterator i = all_old_urls.begin(); 456 for (std::map<GURL, size_t>::const_iterator i = all_old_urls.begin();
408 i != all_old_urls.end(); ++i) { 457 i != all_old_urls.end(); ++i) {
(...skipping 22 matching lines...) Expand all
431 } 480 }
432 481
433 bool TopSitesImpl::IsKnownURL(const GURL& url) { 482 bool TopSitesImpl::IsKnownURL(const GURL& url) {
434 return loaded_ && cache_->IsKnownURL(url); 483 return loaded_ && cache_->IsKnownURL(url);
435 } 484 }
436 485
437 const std::string& TopSitesImpl::GetCanonicalURLString(const GURL& url) const { 486 const std::string& TopSitesImpl::GetCanonicalURLString(const GURL& url) const {
438 return cache_->GetCanonicalURL(url).spec(); 487 return cache_->GetCanonicalURL(url).spec();
439 } 488 }
440 489
441 bool TopSitesImpl::IsFull() { 490 bool TopSitesImpl::IsNonForcedFull() {
442 return loaded_ && cache_->top_sites().size() >= kTopSitesNumber; 491 return loaded_ && cache_->GetNbNonForcedURLs() >= kNonForcedTopSitesNumber;
492 }
493
494 bool TopSitesImpl::IsForcedFull() {
495 return loaded_ && cache_->GetNbForcedURLs() >= kForcedTopSitesNumber;
443 } 496 }
444 497
445 TopSitesImpl::~TopSitesImpl() { 498 TopSitesImpl::~TopSitesImpl() {
446 } 499 }
447 500
448 bool TopSitesImpl::SetPageThumbnailNoDB( 501 bool TopSitesImpl::SetPageThumbnailNoDB(
449 const GURL& url, 502 const GURL& url,
450 const base::RefCountedMemory* thumbnail_data, 503 const base::RefCountedMemory* thumbnail_data,
451 const ThumbnailScore& score) { 504 const ThumbnailScore& score) {
452 // This should only be invoked when we know about the url. 505 // This should only be invoked when we know about the url.
(...skipping 27 matching lines...) Expand all
480 const base::RefCountedMemory* thumbnail, 533 const base::RefCountedMemory* thumbnail,
481 const ThumbnailScore& score) { 534 const ThumbnailScore& score) {
482 if (!SetPageThumbnailNoDB(url, thumbnail, score)) 535 if (!SetPageThumbnailNoDB(url, thumbnail, score))
483 return false; 536 return false;
484 537
485 // Update the database. 538 // Update the database.
486 if (!cache_->IsKnownURL(url)) 539 if (!cache_->IsKnownURL(url))
487 return false; 540 return false;
488 541
489 size_t index = cache_->GetURLIndex(url); 542 size_t index = cache_->GetURLIndex(url);
543 int url_rank = index - cache_->GetNbForcedURLs();
490 const MostVisitedURL& most_visited = cache_->top_sites()[index]; 544 const MostVisitedURL& most_visited = cache_->top_sites()[index];
491 backend_->SetPageThumbnail(most_visited, 545 backend_->SetPageThumbnail(most_visited,
492 index, 546 url_rank < 0 ? -1 : url_rank,
493 *(cache_->GetImage(most_visited.url))); 547 *(cache_->GetImage(most_visited.url)));
494 return true; 548 return true;
495 } 549 }
496 550
497 // static 551 // static
498 bool TopSitesImpl::EncodeBitmap(const gfx::Image& bitmap, 552 bool TopSitesImpl::EncodeBitmap(const gfx::Image& bitmap,
499 scoped_refptr<base::RefCountedBytes>* bytes) { 553 scoped_refptr<base::RefCountedBytes>* bytes) {
500 if (bitmap.IsEmpty()) 554 if (bitmap.IsEmpty())
501 return false; 555 return false;
502 *bytes = new base::RefCountedBytes(); 556 *bytes = new base::RefCountedBytes();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 url.redirects.push_back(url.url); 613 url.redirects.push_back(url.url);
560 url.title = l10n_util::GetStringUTF16(kPrepopulatedPages[i].title_id); 614 url.title = l10n_util::GetStringUTF16(kPrepopulatedPages[i].title_id);
561 } 615 }
562 return urls; 616 return urls;
563 } 617 }
564 618
565 bool TopSitesImpl::loaded() const { 619 bool TopSitesImpl::loaded() const {
566 return loaded_; 620 return loaded_;
567 } 621 }
568 622
569 bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls) { 623 bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls,
624 size_t nb_forced_urls) {
570 bool added = false; 625 bool added = false;
571 MostVisitedURLList prepopulate_urls = GetPrepopulatePages(); 626 MostVisitedURLList prepopulate_urls = GetPrepopulatePages();
572 for (size_t i = 0; i < prepopulate_urls.size(); ++i) { 627 for (size_t i = 0; i < prepopulate_urls.size(); ++i) {
573 if (urls->size() < kTopSitesNumber && 628 if (urls->size() - nb_forced_urls < kNonForcedTopSitesNumber &&
574 IndexOf(*urls, prepopulate_urls[i].url) == -1) { 629 IndexOf(*urls, prepopulate_urls[i].url) == -1) {
575 urls->push_back(prepopulate_urls[i]); 630 urls->push_back(prepopulate_urls[i]);
576 added = true; 631 added = true;
577 } 632 }
578 } 633 }
579 return added; 634 return added;
580 } 635 }
581 636
637 size_t TopSitesImpl::MergeCachedForcedURLs(MostVisitedURLList* new_list) {
638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
639 // Add all the new URLs for quick lookup. Take that opportunity to count the
640 // number of forced URLs in |new_list|.
641 std::set<GURL> all_new_urls;
642 size_t nb_forced = 0;
643 for (size_t i = 0; i < new_list->size(); ++i) {
644 all_new_urls.insert((*new_list)[i].url);
645 if (!(*new_list)[i].last_forced_time.is_null())
646 ++nb_forced;
647 }
648
649 // Keep the forced URLs from |cache_| that are not found in |new_list|.
650 MostVisitedURLList filtered_forced_urls;
651 for (size_t i = 0; i < cache_->GetNbForcedURLs(); ++i) {
652 if (all_new_urls.find(cache_->top_sites()[i].url) == all_new_urls.end())
653 filtered_forced_urls.push_back(cache_->top_sites()[i]);
654 }
655 nb_forced += filtered_forced_urls.size();
656
657 // Prepend forced URLs and sort.
658 new_list->insert(new_list->begin(), filtered_forced_urls.begin(),
659 filtered_forced_urls.end());
660 std::inplace_merge(
661 new_list->begin(), new_list->begin() + filtered_forced_urls.size(),
662 new_list->begin() + nb_forced, ForcedURLComparator);
663
664 // Drop older forced URLs if the list overflows.
brettw 2013/11/08 23:14:58 It might be worth mentioning somewhere (either her
beaudoin 2013/11/11 21:58:09 Done.
665 if (nb_forced > kForcedTopSitesNumber) {
666 new_list->erase(new_list->begin(),
667 new_list->begin() + (nb_forced - kForcedTopSitesNumber));
668 nb_forced = kForcedTopSitesNumber;
669 }
670
671 return nb_forced;
672 }
673
brettw 2013/11/08 23:14:58 Style nit: only one blank line here
beaudoin 2013/11/11 21:58:09 Done.
674
582 void TopSitesImpl::ApplyBlacklist(const MostVisitedURLList& urls, 675 void TopSitesImpl::ApplyBlacklist(const MostVisitedURLList& urls,
583 MostVisitedURLList* out) { 676 MostVisitedURLList* out) {
584 // Log the number of times ApplyBlacklist is called so we can compute the 677 // Log the number of times ApplyBlacklist is called so we can compute the
585 // average number of blacklisted items per user. 678 // average number of blacklisted items per user.
586 const DictionaryValue* blacklist = 679 const DictionaryValue* blacklist =
587 profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist); 680 profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist);
588 UMA_HISTOGRAM_BOOLEAN("TopSites.NumberOfApplyBlacklist", true); 681 UMA_HISTOGRAM_BOOLEAN("TopSites.NumberOfApplyBlacklist", true);
589 UMA_HISTOGRAM_COUNTS_100("TopSites.NumberOfBlacklistedItems", 682 UMA_HISTOGRAM_COUNTS_100("TopSites.NumberOfBlacklistedItems",
590 (blacklist ? blacklist->size() : 0)); 683 (blacklist ? blacklist->size() : 0));
591 for (size_t i = 0; i < urls.size() && i < kTopSitesNumber; ++i) { 684 size_t nb_non_forced_urls = 0;
592 if (!IsBlacklisted(urls[i].url)) 685 size_t nb_forced_urls = 0;
686 for (size_t i = 0; i < urls.size(); ++i) {
687 if (!IsBlacklisted(urls[i].url)) {
688 if (urls[i].last_forced_time.is_null()) {
689 // Non-forced URL.
690 if (nb_non_forced_urls >= kNonForcedTopSitesNumber)
691 continue;
692 nb_non_forced_urls++;
693 } else {
694 // Forced URL.
695 if (nb_forced_urls >= kForcedTopSitesNumber)
696 continue;
697 nb_forced_urls++;
698 }
593 out->push_back(urls[i]); 699 out->push_back(urls[i]);
700 }
594 } 701 }
595 } 702 }
596 703
597 std::string TopSitesImpl::GetURLHash(const GURL& url) { 704 std::string TopSitesImpl::GetURLHash(const GURL& url) {
598 // We don't use canonical URLs here to be able to blacklist only one of 705 // We don't use canonical URLs here to be able to blacklist only one of
599 // the two 'duplicate' sites, e.g. 'gmail.com' and 'mail.google.com'. 706 // the two 'duplicate' sites, e.g. 'gmail.com' and 'mail.google.com'.
600 return base::MD5String(url.spec()); 707 return base::MD5String(url.spec());
601 } 708 }
602 709
603 base::TimeDelta TopSitesImpl::GetUpdateDelay() { 710 base::TimeDelta TopSitesImpl::GetUpdateDelay() {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 new_top_sites.erase(new_top_sites.begin() + *i); 745 new_top_sites.erase(new_top_sites.begin() + *i);
639 } 746 }
640 SetTopSites(new_top_sites); 747 SetTopSites(new_top_sites);
641 } 748 }
642 StartQueryForMostVisited(); 749 StartQueryForMostVisited();
643 } else if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { 750 } else if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
644 NavigationController* controller = 751 NavigationController* controller =
645 content::Source<NavigationController>(source).ptr(); 752 content::Source<NavigationController>(source).ptr();
646 Profile* profile = Profile::FromBrowserContext( 753 Profile* profile = Profile::FromBrowserContext(
647 controller->GetWebContents()->GetBrowserContext()); 754 controller->GetWebContents()->GetBrowserContext());
648 if (profile == profile_ && !IsFull()) { 755 if (profile == profile_ && !IsNonForcedFull()) {
649 content::LoadCommittedDetails* load_details = 756 content::LoadCommittedDetails* load_details =
650 content::Details<content::LoadCommittedDetails>(details).ptr(); 757 content::Details<content::LoadCommittedDetails>(details).ptr();
651 if (!load_details) 758 if (!load_details)
652 return; 759 return;
653 const GURL& url = load_details->entry->GetURL(); 760 const GURL& url = load_details->entry->GetURL();
654 if (!cache_->IsKnownURL(url) && HistoryService::CanAddURL(url)) { 761 if (!cache_->IsKnownURL(url) && HistoryService::CanAddURL(url)) {
655 // To avoid slamming history we throttle requests when the url updates. 762 // To avoid slamming history we throttle requests when the url updates.
656 // To do otherwise negatively impacts perf tests. 763 // To do otherwise negatively impacts perf tests.
657 RestartQueryForTopSitesTimer(GetUpdateDelay()); 764 RestartQueryForTopSitesTimer(GetUpdateDelay());
658 } 765 }
659 } 766 }
660 } 767 }
661 } 768 }
662 769
663 void TopSitesImpl::SetTopSites(const MostVisitedURLList& new_top_sites) { 770 void TopSitesImpl::SetTopSites(const MostVisitedURLList& new_top_sites) {
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 771 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
665 772
666 MostVisitedURLList top_sites(new_top_sites); 773 MostVisitedURLList top_sites(new_top_sites);
667 AddPrepopulatedPages(&top_sites); 774 size_t nb_forced_urls = MergeCachedForcedURLs(&top_sites);
775 AddPrepopulatedPages(&top_sites, nb_forced_urls);
668 776
669 TopSitesDelta delta; 777 TopSitesDelta delta;
670 DiffMostVisited(cache_->top_sites(), top_sites, &delta); 778 DiffMostVisited(cache_->top_sites(), top_sites, &delta);
671 if (!delta.deleted.empty() || !delta.added.empty() || !delta.moved.empty()) { 779 if (!delta.deleted.empty() || !delta.added.empty() || !delta.moved.empty()) {
672 backend_->UpdateTopSites(delta); 780 backend_->UpdateTopSites(delta);
673 } 781 }
674 782
675 last_num_urls_changed_ = delta.added.size() + delta.moved.size(); 783 last_num_urls_changed_ = delta.added.size() + delta.moved.size();
676 784
677 // We always do the following steps (setting top sites in cache, and resetting 785 // We always do the following steps (setting top sites in cache, and resetting
(...skipping 13 matching lines...) Expand all
691 if (canonical_url == cache_->GetCanonicalURL(it->first)) { 799 if (canonical_url == cache_->GetCanonicalURL(it->first)) {
692 SetPageThumbnailEncoded( 800 SetPageThumbnailEncoded(
693 mv.url, it->second.thumbnail.get(), it->second.thumbnail_score); 801 mv.url, it->second.thumbnail.get(), it->second.thumbnail_score);
694 temp_images_.erase(it); 802 temp_images_.erase(it);
695 break; 803 break;
696 } 804 }
697 } 805 }
698 } 806 }
699 } 807 }
700 808
701 if (top_sites.size() >= kTopSitesNumber) 809 if (top_sites.size() - nb_forced_urls >= kNonForcedTopSitesNumber)
702 temp_images_.clear(); 810 temp_images_.clear();
703 811
704 ResetThreadSafeCache(); 812 ResetThreadSafeCache();
705 ResetThreadSafeImageCache(); 813 ResetThreadSafeImageCache();
706 NotifyTopSitesChanged(); 814 NotifyTopSitesChanged();
707 815
708 // Restart the timer that queries history for top sites. This is done to 816 // Restart the timer that queries history for top sites. This is done to
709 // ensure we stay in sync with history. 817 // ensure we stay in sync with history.
710 RestartQueryForTopSitesTimer(GetUpdateDelay()); 818 RestartQueryForTopSitesTimer(GetUpdateDelay());
711 } 819 }
712 820
713 int TopSitesImpl::num_results_to_request_from_history() const { 821 int TopSitesImpl::num_results_to_request_from_history() const {
714 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
715 823
716 const DictionaryValue* blacklist = 824 const DictionaryValue* blacklist =
717 profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist); 825 profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist);
718 return kTopSitesNumber + (blacklist ? blacklist->size() : 0); 826 return kNonForcedTopSitesNumber + (blacklist ? blacklist->size() : 0);
719 } 827 }
720 828
721 void TopSitesImpl::MoveStateToLoaded() { 829 void TopSitesImpl::MoveStateToLoaded() {
722 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 830 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
723 831
724 MostVisitedURLList filtered_urls; 832 MostVisitedURLList filtered_urls_all;
833 MostVisitedURLList filtered_urls_nonforced;
725 PendingCallbacks pending_callbacks; 834 PendingCallbacks pending_callbacks;
726 { 835 {
727 base::AutoLock lock(lock_); 836 base::AutoLock lock(lock_);
728 837
729 if (loaded_) 838 if (loaded_)
730 return; // Don't do anything if we're already loaded. 839 return; // Don't do anything if we're already loaded.
731 loaded_ = true; 840 loaded_ = true;
732 841
733 // Now that we're loaded we can service the queued up callbacks. Copy them 842 // Now that we're loaded we can service the queued up callbacks. Copy them
734 // here and service them outside the lock. 843 // here and service them outside the lock.
735 if (!pending_callbacks_.empty()) { 844 if (!pending_callbacks_.empty()) {
736 filtered_urls = thread_safe_cache_->top_sites(); 845 // We always filter out forced URLs because callers of GetMostVisitedURLs
846 // are not interested in them.
847 filtered_urls_all = thread_safe_cache_->top_sites();
848 filtered_urls_nonforced.assign(thread_safe_cache_->top_sites().begin() +
849 thread_safe_cache_->GetNbForcedURLs(),
850 thread_safe_cache_->top_sites().end());
737 pending_callbacks.swap(pending_callbacks_); 851 pending_callbacks.swap(pending_callbacks_);
738 } 852 }
739 } 853 }
740 854
741 for (size_t i = 0; i < pending_callbacks.size(); i++) 855 for (size_t i = 0; i < pending_callbacks.size(); i++)
742 pending_callbacks[i].Run(filtered_urls); 856 pending_callbacks[i].Run(filtered_urls_all, filtered_urls_nonforced);
743 857
744 content::NotificationService::current()->Notify( 858 content::NotificationService::current()->Notify(
745 chrome::NOTIFICATION_TOP_SITES_LOADED, 859 chrome::NOTIFICATION_TOP_SITES_LOADED,
746 content::Source<Profile>(profile_), 860 content::Source<Profile>(profile_),
747 content::Details<TopSites>(this)); 861 content::Details<TopSites>(this));
748 } 862 }
749 863
750 void TopSitesImpl::ResetThreadSafeCache() { 864 void TopSitesImpl::ResetThreadSafeCache() {
751 base::AutoLock lock(lock_); 865 base::AutoLock lock(lock_);
752 MostVisitedURLList cached; 866 MostVisitedURLList cached;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 SetTopSites(pages); 916 SetTopSites(pages);
803 917
804 // Used only in testing. 918 // Used only in testing.
805 content::NotificationService::current()->Notify( 919 content::NotificationService::current()->Notify(
806 chrome::NOTIFICATION_TOP_SITES_UPDATED, 920 chrome::NOTIFICATION_TOP_SITES_UPDATED,
807 content::Source<TopSitesImpl>(this), 921 content::Source<TopSitesImpl>(this),
808 content::Details<CancelableRequestProvider::Handle>(&handle)); 922 content::Details<CancelableRequestProvider::Handle>(&handle));
809 } 923 }
810 924
811 } // namespace history 925 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698