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

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: Removed GetAllMostVisited. 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;
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 bool include_forced_urls) {
198 MostVisitedURLList filtered_urls; 214 MostVisitedURLList filtered_urls;
199 { 215 {
200 base::AutoLock lock(lock_); 216 base::AutoLock lock(lock_);
201 if (!loaded_) { 217 if (!loaded_) {
202 // A request came in before we finished loading. Store the callback and 218 // A request came in before we finished loading. Store the callback and
203 // we'll run it on current thread when we finish loading. 219 // we'll run it on current thread when we finish loading.
204 pending_callbacks_.push_back( 220 pending_callbacks_.push_back(
205 base::Bind(&RunOrPostGetMostVisitedURLsCallback, 221 base::Bind(&RunOrPostGetMostVisitedURLsCallback,
206 base::MessageLoopProxy::current(), 222 base::MessageLoopProxy::current(),
223 include_forced_urls,
207 callback)); 224 callback));
208 return; 225 return;
209 } 226 }
210 filtered_urls = thread_safe_cache_->top_sites(); 227 if (include_forced_urls) {
228 filtered_urls = thread_safe_cache_->top_sites();
229 } else {
230 filtered_urls.assign(thread_safe_cache_->top_sites().begin() +
231 thread_safe_cache_->GetNumForcedURLs(),
232 thread_safe_cache_->top_sites().end());
233 }
211 } 234 }
212 callback.Run(filtered_urls); 235 callback.Run(filtered_urls);
213 } 236 }
214 237
215 bool TopSitesImpl::GetPageThumbnail( 238 bool TopSitesImpl::GetPageThumbnail(
216 const GURL& url, 239 const GURL& url,
217 bool prefix_match, 240 bool prefix_match,
218 scoped_refptr<base::RefCountedMemory>* bytes) { 241 scoped_refptr<base::RefCountedMemory>* bytes) {
219 // WARNING: this may be invoked on any thread. 242 // WARNING: this may be invoked on any thread.
220 // Perform exact match. 243 // Perform exact match.
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 // invoked Shutdown (this could happen if we have a pending request and 382 // invoked Shutdown (this could happen if we have a pending request and
360 // Shutdown is invoked). 383 // Shutdown is invoked).
361 history_consumer_.CancelAllRequests(); 384 history_consumer_.CancelAllRequests();
362 backend_->Shutdown(); 385 backend_->Shutdown();
363 } 386 }
364 387
365 // static 388 // static
366 void TopSitesImpl::DiffMostVisited(const MostVisitedURLList& old_list, 389 void TopSitesImpl::DiffMostVisited(const MostVisitedURLList& old_list,
367 const MostVisitedURLList& new_list, 390 const MostVisitedURLList& new_list,
368 TopSitesDelta* delta) { 391 TopSitesDelta* delta) {
392
369 // Add all the old URLs for quick lookup. This maps URLs to the corresponding 393 // Add all the old URLs for quick lookup. This maps URLs to the corresponding
370 // index in the input. 394 // index in the input.
371 std::map<GURL, size_t> all_old_urls; 395 std::map<GURL, size_t> all_old_urls;
372 for (size_t i = 0; i < old_list.size(); i++) 396 size_t num_old_forced = 0;
397 for (size_t i = 0; i < old_list.size(); i++) {
398 if (!old_list[i].last_forced_time.is_null())
399 num_old_forced++;
400 DCHECK(old_list[i].last_forced_time.is_null() || i < num_old_forced)
401 << "Forced URLs must all appear before non-forced URLs.";
373 all_old_urls[old_list[i].url] = i; 402 all_old_urls[old_list[i].url] = i;
403 }
374 404
375 // Check all the URLs in the new set to see which ones are new or just moved. 405 // Check all the URLs in the new set to see which ones are new or just moved.
376 // When we find a match in the old set, we'll reset its index to our special 406 // When we find a match in the old set, we'll reset its index to our special
377 // marker. This allows us to quickly identify the deleted ones in a later 407 // marker. This allows us to quickly identify the deleted ones in a later
378 // pass. 408 // pass.
379 const size_t kAlreadyFoundMarker = static_cast<size_t>(-1); 409 const size_t kAlreadyFoundMarker = static_cast<size_t>(-1);
410 int rank = -1; // Forced URLs have a rank of -1.
380 for (size_t i = 0; i < new_list.size(); i++) { 411 for (size_t i = 0; i < new_list.size(); i++) {
412 // Increase the rank if we're going through forced URLs. This works because
413 // non-forced URLs all come after forced URLs.
414 if (new_list[i].last_forced_time.is_null())
415 rank++;
416 DCHECK(new_list[i].last_forced_time.is_null() == (rank != -1))
417 << "Forced URLs must all appear before non-forced URLs.";
381 std::map<GURL, size_t>::iterator found = all_old_urls.find(new_list[i].url); 418 std::map<GURL, size_t>::iterator found = all_old_urls.find(new_list[i].url);
382 if (found == all_old_urls.end()) { 419 if (found == all_old_urls.end()) {
383 MostVisitedURLWithRank added; 420 MostVisitedURLWithRank added;
384 added.url = new_list[i]; 421 added.url = new_list[i];
385 added.rank = i; 422 added.rank = rank;
386 delta->added.push_back(added); 423 delta->added.push_back(added);
387 } else { 424 } else {
388 if (found->second != i) { 425 DCHECK(found->second != kAlreadyFoundMarker)
426 << "Same URL appears twice in the new list.";
427 int old_rank = found->second >= num_old_forced ?
428 found->second - num_old_forced : -1;
429 if (old_rank != rank ||
430 old_list[found->second].last_forced_time !=
431 new_list[i].last_forced_time) {
389 MostVisitedURLWithRank moved; 432 MostVisitedURLWithRank moved;
390 moved.url = new_list[i]; 433 moved.url = new_list[i];
391 moved.rank = i; 434 moved.rank = rank;
392 delta->moved.push_back(moved); 435 delta->moved.push_back(moved);
393 } 436 }
394 found->second = kAlreadyFoundMarker; 437 found->second = kAlreadyFoundMarker;
395 } 438 }
396 } 439 }
397 440
398 // Any member without the special marker in the all_old_urls list means that 441 // Any member without the special marker in the all_old_urls list means that
399 // there wasn't a "new" URL that mapped to it, so it was deleted. 442 // there wasn't a "new" URL that mapped to it, so it was deleted.
400 for (std::map<GURL, size_t>::const_iterator i = all_old_urls.begin(); 443 for (std::map<GURL, size_t>::const_iterator i = all_old_urls.begin();
401 i != all_old_urls.end(); ++i) { 444 i != all_old_urls.end(); ++i) {
(...skipping 22 matching lines...) Expand all
424 } 467 }
425 468
426 bool TopSitesImpl::IsKnownURL(const GURL& url) { 469 bool TopSitesImpl::IsKnownURL(const GURL& url) {
427 return loaded_ && cache_->IsKnownURL(url); 470 return loaded_ && cache_->IsKnownURL(url);
428 } 471 }
429 472
430 const std::string& TopSitesImpl::GetCanonicalURLString(const GURL& url) const { 473 const std::string& TopSitesImpl::GetCanonicalURLString(const GURL& url) const {
431 return cache_->GetCanonicalURL(url).spec(); 474 return cache_->GetCanonicalURL(url).spec();
432 } 475 }
433 476
434 bool TopSitesImpl::IsFull() { 477 bool TopSitesImpl::IsNonForcedFull() {
435 return loaded_ && cache_->top_sites().size() >= kTopSitesNumber; 478 return loaded_ && cache_->GetNumNonForcedURLs() >= kNonForcedTopSitesNumber;
479 }
480
481 bool TopSitesImpl::IsForcedFull() {
482 return loaded_ && cache_->GetNumForcedURLs() >= kForcedTopSitesNumber;
436 } 483 }
437 484
438 TopSitesImpl::~TopSitesImpl() { 485 TopSitesImpl::~TopSitesImpl() {
439 } 486 }
440 487
441 bool TopSitesImpl::SetPageThumbnailNoDB( 488 bool TopSitesImpl::SetPageThumbnailNoDB(
442 const GURL& url, 489 const GURL& url,
443 const base::RefCountedMemory* thumbnail_data, 490 const base::RefCountedMemory* thumbnail_data,
444 const ThumbnailScore& score) { 491 const ThumbnailScore& score) {
445 // This should only be invoked when we know about the url. 492 // This should only be invoked when we know about the url.
(...skipping 27 matching lines...) Expand all
473 const base::RefCountedMemory* thumbnail, 520 const base::RefCountedMemory* thumbnail,
474 const ThumbnailScore& score) { 521 const ThumbnailScore& score) {
475 if (!SetPageThumbnailNoDB(url, thumbnail, score)) 522 if (!SetPageThumbnailNoDB(url, thumbnail, score))
476 return false; 523 return false;
477 524
478 // Update the database. 525 // Update the database.
479 if (!cache_->IsKnownURL(url)) 526 if (!cache_->IsKnownURL(url))
480 return false; 527 return false;
481 528
482 size_t index = cache_->GetURLIndex(url); 529 size_t index = cache_->GetURLIndex(url);
530 int url_rank = index - cache_->GetNumForcedURLs();
483 const MostVisitedURL& most_visited = cache_->top_sites()[index]; 531 const MostVisitedURL& most_visited = cache_->top_sites()[index];
484 backend_->SetPageThumbnail(most_visited, 532 backend_->SetPageThumbnail(most_visited,
485 index, 533 url_rank < 0 ? -1 : url_rank,
486 *(cache_->GetImage(most_visited.url))); 534 *(cache_->GetImage(most_visited.url)));
487 return true; 535 return true;
488 } 536 }
489 537
490 // static 538 // static
491 bool TopSitesImpl::EncodeBitmap(const gfx::Image& bitmap, 539 bool TopSitesImpl::EncodeBitmap(const gfx::Image& bitmap,
492 scoped_refptr<base::RefCountedBytes>* bytes) { 540 scoped_refptr<base::RefCountedBytes>* bytes) {
493 if (bitmap.IsEmpty()) 541 if (bitmap.IsEmpty())
494 return false; 542 return false;
495 *bytes = new base::RefCountedBytes(); 543 *bytes = new base::RefCountedBytes();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 url.redirects.push_back(url.url); 600 url.redirects.push_back(url.url);
553 url.title = l10n_util::GetStringUTF16(kPrepopulatedPages[i].title_id); 601 url.title = l10n_util::GetStringUTF16(kPrepopulatedPages[i].title_id);
554 } 602 }
555 return urls; 603 return urls;
556 } 604 }
557 605
558 bool TopSitesImpl::loaded() const { 606 bool TopSitesImpl::loaded() const {
559 return loaded_; 607 return loaded_;
560 } 608 }
561 609
562 bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls) { 610 bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls,
611 size_t num_forced_urls) {
563 bool added = false; 612 bool added = false;
564 MostVisitedURLList prepopulate_urls = GetPrepopulatePages(); 613 MostVisitedURLList prepopulate_urls = GetPrepopulatePages();
565 for (size_t i = 0; i < prepopulate_urls.size(); ++i) { 614 for (size_t i = 0; i < prepopulate_urls.size(); ++i) {
566 if (urls->size() < kTopSitesNumber && 615 if (urls->size() - num_forced_urls < kNonForcedTopSitesNumber &&
567 IndexOf(*urls, prepopulate_urls[i].url) == -1) { 616 IndexOf(*urls, prepopulate_urls[i].url) == -1) {
568 urls->push_back(prepopulate_urls[i]); 617 urls->push_back(prepopulate_urls[i]);
569 added = true; 618 added = true;
570 } 619 }
571 } 620 }
572 return added; 621 return added;
573 } 622 }
574 623
624 size_t TopSitesImpl::MergeCachedForcedURLs(MostVisitedURLList* new_list) {
625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
626 // Add all the new URLs for quick lookup. Take that opportunity to count the
627 // number of forced URLs in |new_list|.
628 std::set<GURL> all_new_urls;
629 size_t num_forced = 0;
630 for (size_t i = 0; i < new_list->size(); ++i) {
631 all_new_urls.insert((*new_list)[i].url);
632 if (!(*new_list)[i].last_forced_time.is_null())
633 ++num_forced;
634 }
635
636 // Keep the forced URLs from |cache_| that are not found in |new_list|.
637 MostVisitedURLList filtered_forced_urls;
638 for (size_t i = 0; i < cache_->GetNumForcedURLs(); ++i) {
639 if (all_new_urls.find(cache_->top_sites()[i].url) == all_new_urls.end())
640 filtered_forced_urls.push_back(cache_->top_sites()[i]);
641 }
642 num_forced += filtered_forced_urls.size();
643
644 // Prepend forced URLs and sort in order of ascending |last_forced_time|.
645 new_list->insert(new_list->begin(), filtered_forced_urls.begin(),
646 filtered_forced_urls.end());
647 std::inplace_merge(
648 new_list->begin(), new_list->begin() + filtered_forced_urls.size(),
649 new_list->begin() + num_forced, ForcedURLComparator);
650
651 // Drop older forced URLs if the list overflows. Since forced URLs are always
652 // sort in increasing order of |last_forced_time|, drop the first ones.
653 if (num_forced > kForcedTopSitesNumber) {
654 new_list->erase(new_list->begin(),
655 new_list->begin() + (num_forced - kForcedTopSitesNumber));
656 num_forced = kForcedTopSitesNumber;
657 }
658
659 return num_forced;
660 }
661
575 void TopSitesImpl::ApplyBlacklist(const MostVisitedURLList& urls, 662 void TopSitesImpl::ApplyBlacklist(const MostVisitedURLList& urls,
576 MostVisitedURLList* out) { 663 MostVisitedURLList* out) {
577 // Log the number of times ApplyBlacklist is called so we can compute the 664 // Log the number of times ApplyBlacklist is called so we can compute the
578 // average number of blacklisted items per user. 665 // average number of blacklisted items per user.
579 const DictionaryValue* blacklist = 666 const DictionaryValue* blacklist =
580 profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist); 667 profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist);
581 UMA_HISTOGRAM_BOOLEAN("TopSites.NumberOfApplyBlacklist", true); 668 UMA_HISTOGRAM_BOOLEAN("TopSites.NumberOfApplyBlacklist", true);
582 UMA_HISTOGRAM_COUNTS_100("TopSites.NumberOfBlacklistedItems", 669 UMA_HISTOGRAM_COUNTS_100("TopSites.NumberOfBlacklistedItems",
583 (blacklist ? blacklist->size() : 0)); 670 (blacklist ? blacklist->size() : 0));
584 for (size_t i = 0; i < urls.size() && i < kTopSitesNumber; ++i) { 671 size_t num_non_forced_urls = 0;
585 if (!IsBlacklisted(urls[i].url)) 672 size_t num_forced_urls = 0;
673 for (size_t i = 0; i < urls.size(); ++i) {
674 if (!IsBlacklisted(urls[i].url)) {
675 if (urls[i].last_forced_time.is_null()) {
676 // Non-forced URL.
677 if (num_non_forced_urls >= kNonForcedTopSitesNumber)
678 continue;
679 num_non_forced_urls++;
680 } else {
681 // Forced URL.
682 if (num_forced_urls >= kForcedTopSitesNumber)
683 continue;
684 num_forced_urls++;
685 }
586 out->push_back(urls[i]); 686 out->push_back(urls[i]);
687 }
587 } 688 }
588 } 689 }
589 690
590 std::string TopSitesImpl::GetURLHash(const GURL& url) { 691 std::string TopSitesImpl::GetURLHash(const GURL& url) {
591 // We don't use canonical URLs here to be able to blacklist only one of 692 // We don't use canonical URLs here to be able to blacklist only one of
592 // the two 'duplicate' sites, e.g. 'gmail.com' and 'mail.google.com'. 693 // the two 'duplicate' sites, e.g. 'gmail.com' and 'mail.google.com'.
593 return base::MD5String(url.spec()); 694 return base::MD5String(url.spec());
594 } 695 }
595 696
596 base::TimeDelta TopSitesImpl::GetUpdateDelay() { 697 base::TimeDelta TopSitesImpl::GetUpdateDelay() {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 new_top_sites.erase(new_top_sites.begin() + *i); 732 new_top_sites.erase(new_top_sites.begin() + *i);
632 } 733 }
633 SetTopSites(new_top_sites); 734 SetTopSites(new_top_sites);
634 } 735 }
635 StartQueryForMostVisited(); 736 StartQueryForMostVisited();
636 } else if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { 737 } else if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
637 NavigationController* controller = 738 NavigationController* controller =
638 content::Source<NavigationController>(source).ptr(); 739 content::Source<NavigationController>(source).ptr();
639 Profile* profile = Profile::FromBrowserContext( 740 Profile* profile = Profile::FromBrowserContext(
640 controller->GetWebContents()->GetBrowserContext()); 741 controller->GetWebContents()->GetBrowserContext());
641 if (profile == profile_ && !IsFull()) { 742 if (profile == profile_ && !IsNonForcedFull()) {
642 content::LoadCommittedDetails* load_details = 743 content::LoadCommittedDetails* load_details =
643 content::Details<content::LoadCommittedDetails>(details).ptr(); 744 content::Details<content::LoadCommittedDetails>(details).ptr();
644 if (!load_details) 745 if (!load_details)
645 return; 746 return;
646 const GURL& url = load_details->entry->GetURL(); 747 const GURL& url = load_details->entry->GetURL();
647 if (!cache_->IsKnownURL(url) && HistoryService::CanAddURL(url)) { 748 if (!cache_->IsKnownURL(url) && HistoryService::CanAddURL(url)) {
648 // To avoid slamming history we throttle requests when the url updates. 749 // To avoid slamming history we throttle requests when the url updates.
649 // To do otherwise negatively impacts perf tests. 750 // To do otherwise negatively impacts perf tests.
650 RestartQueryForTopSitesTimer(GetUpdateDelay()); 751 RestartQueryForTopSitesTimer(GetUpdateDelay());
651 } 752 }
652 } 753 }
653 } 754 }
654 } 755 }
655 756
656 void TopSitesImpl::SetTopSites(const MostVisitedURLList& new_top_sites) { 757 void TopSitesImpl::SetTopSites(const MostVisitedURLList& new_top_sites) {
657 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 758 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
658 759
659 MostVisitedURLList top_sites(new_top_sites); 760 MostVisitedURLList top_sites(new_top_sites);
660 AddPrepopulatedPages(&top_sites); 761 size_t num_forced_urls = MergeCachedForcedURLs(&top_sites);
762 AddPrepopulatedPages(&top_sites, num_forced_urls);
661 763
662 TopSitesDelta delta; 764 TopSitesDelta delta;
663 DiffMostVisited(cache_->top_sites(), top_sites, &delta); 765 DiffMostVisited(cache_->top_sites(), top_sites, &delta);
664 if (!delta.deleted.empty() || !delta.added.empty() || !delta.moved.empty()) { 766 if (!delta.deleted.empty() || !delta.added.empty() || !delta.moved.empty()) {
665 backend_->UpdateTopSites(delta); 767 backend_->UpdateTopSites(delta);
666 } 768 }
667 769
668 last_num_urls_changed_ = delta.added.size() + delta.moved.size(); 770 last_num_urls_changed_ = delta.added.size() + delta.moved.size();
669 771
670 // We always do the following steps (setting top sites in cache, and resetting 772 // We always do the following steps (setting top sites in cache, and resetting
(...skipping 13 matching lines...) Expand all
684 if (canonical_url == cache_->GetCanonicalURL(it->first)) { 786 if (canonical_url == cache_->GetCanonicalURL(it->first)) {
685 SetPageThumbnailEncoded( 787 SetPageThumbnailEncoded(
686 mv.url, it->second.thumbnail.get(), it->second.thumbnail_score); 788 mv.url, it->second.thumbnail.get(), it->second.thumbnail_score);
687 temp_images_.erase(it); 789 temp_images_.erase(it);
688 break; 790 break;
689 } 791 }
690 } 792 }
691 } 793 }
692 } 794 }
693 795
694 if (top_sites.size() >= kTopSitesNumber) 796 if (top_sites.size() - num_forced_urls >= kNonForcedTopSitesNumber)
695 temp_images_.clear(); 797 temp_images_.clear();
696 798
697 ResetThreadSafeCache(); 799 ResetThreadSafeCache();
698 ResetThreadSafeImageCache(); 800 ResetThreadSafeImageCache();
699 NotifyTopSitesChanged(); 801 NotifyTopSitesChanged();
700 802
701 // Restart the timer that queries history for top sites. This is done to 803 // Restart the timer that queries history for top sites. This is done to
702 // ensure we stay in sync with history. 804 // ensure we stay in sync with history.
703 RestartQueryForTopSitesTimer(GetUpdateDelay()); 805 RestartQueryForTopSitesTimer(GetUpdateDelay());
704 } 806 }
705 807
706 int TopSitesImpl::num_results_to_request_from_history() const { 808 int TopSitesImpl::num_results_to_request_from_history() const {
707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 809 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
708 810
709 const DictionaryValue* blacklist = 811 const DictionaryValue* blacklist =
710 profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist); 812 profile_->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist);
711 return kTopSitesNumber + (blacklist ? blacklist->size() : 0); 813 return kNonForcedTopSitesNumber + (blacklist ? blacklist->size() : 0);
712 } 814 }
713 815
714 void TopSitesImpl::MoveStateToLoaded() { 816 void TopSitesImpl::MoveStateToLoaded() {
715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
716 818
717 MostVisitedURLList filtered_urls; 819 MostVisitedURLList filtered_urls_all;
820 MostVisitedURLList filtered_urls_nonforced;
718 PendingCallbacks pending_callbacks; 821 PendingCallbacks pending_callbacks;
719 { 822 {
720 base::AutoLock lock(lock_); 823 base::AutoLock lock(lock_);
721 824
722 if (loaded_) 825 if (loaded_)
723 return; // Don't do anything if we're already loaded. 826 return; // Don't do anything if we're already loaded.
724 loaded_ = true; 827 loaded_ = true;
725 828
726 // Now that we're loaded we can service the queued up callbacks. Copy them 829 // Now that we're loaded we can service the queued up callbacks. Copy them
727 // here and service them outside the lock. 830 // here and service them outside the lock.
728 if (!pending_callbacks_.empty()) { 831 if (!pending_callbacks_.empty()) {
729 filtered_urls = thread_safe_cache_->top_sites(); 832 // We always filter out forced URLs because callers of GetMostVisitedURLs
833 // are not interested in them.
834 filtered_urls_all = thread_safe_cache_->top_sites();
835 filtered_urls_nonforced.assign(thread_safe_cache_->top_sites().begin() +
836 thread_safe_cache_->GetNumForcedURLs(),
837 thread_safe_cache_->top_sites().end());
730 pending_callbacks.swap(pending_callbacks_); 838 pending_callbacks.swap(pending_callbacks_);
731 } 839 }
732 } 840 }
733 841
734 for (size_t i = 0; i < pending_callbacks.size(); i++) 842 for (size_t i = 0; i < pending_callbacks.size(); i++)
735 pending_callbacks[i].Run(filtered_urls); 843 pending_callbacks[i].Run(filtered_urls_all, filtered_urls_nonforced);
736 844
737 content::NotificationService::current()->Notify( 845 content::NotificationService::current()->Notify(
738 chrome::NOTIFICATION_TOP_SITES_LOADED, 846 chrome::NOTIFICATION_TOP_SITES_LOADED,
739 content::Source<Profile>(profile_), 847 content::Source<Profile>(profile_),
740 content::Details<TopSites>(this)); 848 content::Details<TopSites>(this));
741 } 849 }
742 850
743 void TopSitesImpl::ResetThreadSafeCache() { 851 void TopSitesImpl::ResetThreadSafeCache() {
744 base::AutoLock lock(lock_); 852 base::AutoLock lock(lock_);
745 MostVisitedURLList cached; 853 MostVisitedURLList cached;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 SetTopSites(pages); 903 SetTopSites(pages);
796 904
797 // Used only in testing. 905 // Used only in testing.
798 content::NotificationService::current()->Notify( 906 content::NotificationService::current()->Notify(
799 chrome::NOTIFICATION_TOP_SITES_UPDATED, 907 chrome::NOTIFICATION_TOP_SITES_UPDATED,
800 content::Source<TopSitesImpl>(this), 908 content::Source<TopSitesImpl>(this),
801 content::Details<CancelableRequestProvider::Handle>(&handle)); 909 content::Details<CancelableRequestProvider::Handle>(&handle));
802 } 910 }
803 911
804 } // namespace history 912 } // namespace history
OLDNEW
« no previous file with comments | « chrome/browser/history/top_sites_impl.h ('k') | chrome/browser/history/top_sites_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698