Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |