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 "components/history/core/browser/top_sites_impl.h" | 5 #include "components/history/core/browser/top_sites_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 165 // Always remove the existing entry and then add it back. That way if we end | 165 // Always remove the existing entry and then add it back. That way if we end |
| 166 // up with too many temp thumbnails we'll prune the oldest first. | 166 // up with too many temp thumbnails we'll prune the oldest first. |
| 167 RemoveTemporaryThumbnailByURL(url); | 167 RemoveTemporaryThumbnailByURL(url); |
| 168 AddTemporaryThumbnail(url, thumbnail_data.get(), score); | 168 AddTemporaryThumbnail(url, thumbnail_data.get(), score); |
| 169 return true; | 169 return true; |
| 170 } | 170 } |
| 171 | 171 |
| 172 return SetPageThumbnailEncoded(url, thumbnail_data.get(), score); | 172 return SetPageThumbnailEncoded(url, thumbnail_data.get(), score); |
| 173 } | 173 } |
| 174 | 174 |
| 175 bool TopSitesImpl::SetPageThumbnailToJPEGBytes( | |
| 176 const GURL& url, | |
| 177 const base::RefCountedMemory* memory, | |
| 178 const ThumbnailScore& score) { | |
| 179 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 180 | |
| 181 if (!loaded_) { | |
| 182 // TODO(sky): I need to cache these and apply them after the load | |
| 183 // completes. | |
| 184 return false; | |
| 185 } | |
| 186 | |
| 187 bool add_temp_thumbnail = false; | |
| 188 if (!IsKnownURL(url)) { | |
| 189 if (!IsNonForcedFull()) { | |
| 190 add_temp_thumbnail = true; | |
| 191 } else { | |
| 192 return false; // This URL is not known to us. | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 if (!can_add_url_to_history_.Run(url)) | |
| 197 return false; // It's not a real webpage. | |
| 198 | |
| 199 if (add_temp_thumbnail) { | |
| 200 // Always remove the existing entry and then add it back. That way if we end | |
| 201 // up with too many temp thumbnails we'll prune the oldest first. | |
| 202 RemoveTemporaryThumbnailByURL(url); | |
| 203 AddTemporaryThumbnail(url, memory, score); | |
| 204 return true; | |
| 205 } | |
| 206 | |
| 207 return SetPageThumbnailEncoded(url, memory, score); | |
| 208 } | |
| 209 | |
| 210 // WARNING: this function may be invoked on any thread. | 175 // WARNING: this function may be invoked on any thread. |
| 211 void TopSitesImpl::GetMostVisitedURLs( | 176 void TopSitesImpl::GetMostVisitedURLs( |
| 212 const GetMostVisitedURLsCallback& callback, | 177 const GetMostVisitedURLsCallback& callback, |
| 213 bool include_forced_urls) { | 178 bool include_forced_urls) { |
| 214 MostVisitedURLList filtered_urls; | 179 MostVisitedURLList filtered_urls; |
| 215 { | 180 { |
| 216 base::AutoLock lock(lock_); | 181 base::AutoLock lock(lock_); |
| 217 if (!loaded_) { | 182 if (!loaded_) { |
| 218 // A request came in before we finished loading. Store the callback and | 183 // A request came in before we finished loading. Store the callback and |
| 219 // we'll run it on current thread when we finish loading. | 184 // we'll run it on current thread when we finish loading. |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 DCHECK(thread_checker_.CalledOnValidThread()); | 324 DCHECK(thread_checker_.CalledOnValidThread()); |
| 360 { | 325 { |
| 361 DictionaryPrefUpdate update(pref_service_, kMostVisitedURLsBlacklist); | 326 DictionaryPrefUpdate update(pref_service_, kMostVisitedURLsBlacklist); |
| 362 base::DictionaryValue* blacklist = update.Get(); | 327 base::DictionaryValue* blacklist = update.Get(); |
| 363 blacklist->Clear(); | 328 blacklist->Clear(); |
| 364 } | 329 } |
| 365 ResetThreadSafeCache(); | 330 ResetThreadSafeCache(); |
| 366 NotifyTopSitesChanged(TopSitesObserver::ChangeReason::BLACKLIST); | 331 NotifyTopSitesChanged(TopSitesObserver::ChangeReason::BLACKLIST); |
| 367 } | 332 } |
| 368 | 333 |
| 334 bool TopSitesImpl::IsKnownURL(const GURL& url) { | |
|
sdefresne
2016/12/21 12:57:09
I assume you are just reordering function to match
Marc Treib
2016/12/26 19:56:51
Yup, exactly. The only change apart from the reord
| |
| 335 return loaded_ && cache_->IsKnownURL(url); | |
| 336 } | |
| 337 | |
| 338 bool TopSitesImpl::IsNonForcedFull() { | |
| 339 return loaded_ && cache_->GetNumNonForcedURLs() >= kNonForcedTopSitesNumber; | |
| 340 } | |
| 341 | |
| 342 bool TopSitesImpl::IsForcedFull() { | |
| 343 return loaded_ && cache_->GetNumForcedURLs() >= kForcedTopSitesNumber; | |
| 344 } | |
| 345 | |
| 346 PrepopulatedPageList TopSitesImpl::GetPrepopulatedPages() { | |
| 347 return prepopulated_pages_; | |
| 348 } | |
| 349 | |
| 350 bool TopSitesImpl::loaded() const { | |
| 351 return loaded_; | |
| 352 } | |
| 353 | |
| 354 bool TopSitesImpl::AddForcedURL(const GURL& url, const base::Time& time) { | |
| 355 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 356 | |
| 357 if (!loaded_) { | |
| 358 // Optimally we could cache this and apply it after the load completes, but | |
| 359 // in practice it's not an issue since AddForcedURL will be called again | |
| 360 // next time the user hits the NTP. | |
| 361 return false; | |
| 362 } | |
| 363 | |
| 364 size_t num_forced = cache_->GetNumForcedURLs(); | |
| 365 MostVisitedURLList new_list(cache_->top_sites()); | |
| 366 MostVisitedURL new_url; | |
| 367 | |
| 368 if (cache_->IsKnownURL(url)) { | |
| 369 size_t index = cache_->GetURLIndex(url); | |
| 370 // Do nothing if we currently have that URL as non-forced. | |
| 371 if (new_list[index].last_forced_time.is_null()) | |
| 372 return false; | |
| 373 | |
| 374 // Update the |last_forced_time| of the already existing URL. Delete it and | |
| 375 // reinsert it at the right location. | |
| 376 new_url = new_list[index]; | |
| 377 new_list.erase(new_list.begin() + index); | |
| 378 num_forced--; | |
| 379 } else { | |
| 380 new_url.url = url; | |
| 381 new_url.redirects.push_back(url); | |
| 382 } | |
| 383 new_url.last_forced_time = time; | |
| 384 // Add forced URLs and sort. Added to the end of the list of forced URLs | |
| 385 // since this is almost always where it needs to go, unless the user's local | |
| 386 // clock is fiddled with. | |
| 387 MostVisitedURLList::iterator mid = new_list.begin() + num_forced; | |
| 388 new_list.insert(mid, new_url); | |
| 389 mid = new_list.begin() + num_forced; // Mid was invalidated. | |
| 390 std::inplace_merge(new_list.begin(), mid, mid + 1, ForcedURLComparator); | |
| 391 SetTopSites(new_list, CALL_LOCATION_FROM_FORCED_URLS); | |
| 392 return true; | |
| 393 } | |
| 394 | |
| 395 void TopSitesImpl::OnNavigationCommitted(const GURL& url) { | |
| 396 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 397 if (!loaded_ || IsNonForcedFull()) | |
| 398 return; | |
| 399 | |
| 400 if (!cache_->IsKnownURL(url) && can_add_url_to_history_.Run(url)) { | |
| 401 // To avoid slamming history we throttle requests when the url updates. To | |
| 402 // do otherwise negatively impacts perf tests. | |
| 403 RestartQueryForTopSitesTimer(GetUpdateDelay()); | |
| 404 } | |
| 405 } | |
| 406 | |
| 369 void TopSitesImpl::ShutdownOnUIThread() { | 407 void TopSitesImpl::ShutdownOnUIThread() { |
| 370 history_service_ = nullptr; | 408 history_service_ = nullptr; |
| 371 history_service_observer_.RemoveAll(); | 409 history_service_observer_.RemoveAll(); |
| 372 // Cancel all requests so that the service doesn't callback to us after we've | 410 // Cancel all requests so that the service doesn't callback to us after we've |
| 373 // invoked Shutdown (this could happen if we have a pending request and | 411 // invoked Shutdown (this could happen if we have a pending request and |
| 374 // Shutdown is invoked). | 412 // Shutdown is invoked). |
| 375 cancelable_task_tracker_.TryCancelAll(); | 413 cancelable_task_tracker_.TryCancelAll(); |
| 376 if (backend_) | 414 if (backend_) |
| 377 backend_->Shutdown(); | 415 backend_->Shutdown(); |
| 378 } | 416 } |
| 379 | 417 |
| 380 // static | 418 // static |
| 381 void TopSitesImpl::RegisterPrefs(PrefRegistrySimple* registry) { | 419 void TopSitesImpl::RegisterPrefs(PrefRegistrySimple* registry) { |
| 382 registry->RegisterDictionaryPref(kMostVisitedURLsBlacklist); | 420 registry->RegisterDictionaryPref(kMostVisitedURLsBlacklist); |
| 383 } | 421 } |
| 384 | 422 |
| 423 TopSitesImpl::~TopSitesImpl() = default; | |
| 424 | |
| 425 void TopSitesImpl::StartQueryForMostVisited() { | |
| 426 DCHECK(loaded_); | |
| 427 if (!history_service_) | |
| 428 return; | |
| 429 | |
| 430 history_service_->QueryMostVisitedURLs( | |
| 431 num_results_to_request_from_history(), kDaysOfHistory, | |
| 432 base::Bind(&TopSitesImpl::OnTopSitesAvailableFromHistory, | |
| 433 base::Unretained(this)), | |
| 434 &cancelable_task_tracker_); | |
| 435 } | |
| 436 | |
| 385 // static | 437 // static |
| 386 void TopSitesImpl::DiffMostVisited(const MostVisitedURLList& old_list, | 438 void TopSitesImpl::DiffMostVisited(const MostVisitedURLList& old_list, |
| 387 const MostVisitedURLList& new_list, | 439 const MostVisitedURLList& new_list, |
| 388 TopSitesDelta* delta) { | 440 TopSitesDelta* delta) { |
| 389 | 441 |
| 390 // Add all the old URLs for quick lookup. This maps URLs to the corresponding | 442 // Add all the old URLs for quick lookup. This maps URLs to the corresponding |
| 391 // index in the input. | 443 // index in the input. |
| 392 std::map<GURL, size_t> all_old_urls; | 444 std::map<GURL, size_t> all_old_urls; |
| 393 size_t num_old_forced = 0; | 445 size_t num_old_forced = 0; |
| 394 for (size_t i = 0; i < old_list.size(); i++) { | 446 for (size_t i = 0; i < old_list.size(); i++) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 | 489 |
| 438 // Any member without the special marker in the all_old_urls list means that | 490 // Any member without the special marker in the all_old_urls list means that |
| 439 // there wasn't a "new" URL that mapped to it, so it was deleted. | 491 // there wasn't a "new" URL that mapped to it, so it was deleted. |
| 440 for (std::map<GURL, size_t>::const_iterator i = all_old_urls.begin(); | 492 for (std::map<GURL, size_t>::const_iterator i = all_old_urls.begin(); |
| 441 i != all_old_urls.end(); ++i) { | 493 i != all_old_urls.end(); ++i) { |
| 442 if (i->second != kAlreadyFoundMarker) | 494 if (i->second != kAlreadyFoundMarker) |
| 443 delta->deleted.push_back(old_list[i->second]); | 495 delta->deleted.push_back(old_list[i->second]); |
| 444 } | 496 } |
| 445 } | 497 } |
| 446 | 498 |
| 447 base::CancelableTaskTracker::TaskId TopSitesImpl::StartQueryForMostVisited() { | |
| 448 DCHECK(loaded_); | |
| 449 if (!history_service_) | |
| 450 return base::CancelableTaskTracker::kBadTaskId; | |
| 451 | |
| 452 return history_service_->QueryMostVisitedURLs( | |
| 453 num_results_to_request_from_history(), kDaysOfHistory, | |
| 454 base::Bind(&TopSitesImpl::OnTopSitesAvailableFromHistory, | |
| 455 base::Unretained(this)), | |
| 456 &cancelable_task_tracker_); | |
| 457 } | |
| 458 | |
| 459 bool TopSitesImpl::IsKnownURL(const GURL& url) { | |
| 460 return loaded_ && cache_->IsKnownURL(url); | |
| 461 } | |
| 462 | |
| 463 const std::string& TopSitesImpl::GetCanonicalURLString(const GURL& url) const { | |
| 464 return cache_->GetCanonicalURL(url).spec(); | |
| 465 } | |
| 466 | |
| 467 bool TopSitesImpl::IsNonForcedFull() { | |
| 468 return loaded_ && cache_->GetNumNonForcedURLs() >= kNonForcedTopSitesNumber; | |
| 469 } | |
| 470 | |
| 471 bool TopSitesImpl::IsForcedFull() { | |
| 472 return loaded_ && cache_->GetNumForcedURLs() >= kForcedTopSitesNumber; | |
| 473 } | |
| 474 | |
| 475 TopSitesImpl::~TopSitesImpl() { | |
| 476 } | |
| 477 | |
| 478 bool TopSitesImpl::SetPageThumbnailNoDB( | 499 bool TopSitesImpl::SetPageThumbnailNoDB( |
| 479 const GURL& url, | 500 const GURL& url, |
| 480 const base::RefCountedMemory* thumbnail_data, | 501 const base::RefCountedMemory* thumbnail_data, |
| 481 const ThumbnailScore& score) { | 502 const ThumbnailScore& score) { |
| 482 // This should only be invoked when we know about the url. | 503 // This should only be invoked when we know about the url. |
| 483 DCHECK(cache_->IsKnownURL(url)); | 504 DCHECK(cache_->IsKnownURL(url)); |
| 484 | 505 |
| 485 const MostVisitedURL& most_visited = | 506 const MostVisitedURL& most_visited = |
| 486 cache_->top_sites()[cache_->GetURLIndex(url)]; | 507 cache_->top_sites()[cache_->GetURLIndex(url)]; |
| 487 Images* image = cache_->GetImage(url); | 508 Images* image = cache_->GetImage(url); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 574 int TopSitesImpl::GetRedirectDistanceForURL(const MostVisitedURL& most_visited, | 595 int TopSitesImpl::GetRedirectDistanceForURL(const MostVisitedURL& most_visited, |
| 575 const GURL& url) { | 596 const GURL& url) { |
| 576 for (size_t i = 0; i < most_visited.redirects.size(); i++) { | 597 for (size_t i = 0; i < most_visited.redirects.size(); i++) { |
| 577 if (most_visited.redirects[i] == url) | 598 if (most_visited.redirects[i] == url) |
| 578 return static_cast<int>(most_visited.redirects.size() - i - 1); | 599 return static_cast<int>(most_visited.redirects.size() - i - 1); |
| 579 } | 600 } |
| 580 NOTREACHED() << "URL should always be found."; | 601 NOTREACHED() << "URL should always be found."; |
| 581 return 0; | 602 return 0; |
| 582 } | 603 } |
| 583 | 604 |
| 584 PrepopulatedPageList TopSitesImpl::GetPrepopulatedPages() { | |
| 585 return prepopulated_pages_; | |
| 586 } | |
| 587 | |
| 588 bool TopSitesImpl::loaded() const { | |
| 589 return loaded_; | |
| 590 } | |
| 591 | |
| 592 bool TopSitesImpl::AddForcedURL(const GURL& url, const base::Time& time) { | |
| 593 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 594 | |
| 595 if (!loaded_) { | |
| 596 // Optimally we could cache this and apply it after the load completes, but | |
| 597 // in practice it's not an issue since AddForcedURL will be called again | |
| 598 // next time the user hits the NTP. | |
| 599 return false; | |
| 600 } | |
| 601 | |
| 602 size_t num_forced = cache_->GetNumForcedURLs(); | |
| 603 MostVisitedURLList new_list(cache_->top_sites()); | |
| 604 MostVisitedURL new_url; | |
| 605 | |
| 606 if (cache_->IsKnownURL(url)) { | |
| 607 size_t index = cache_->GetURLIndex(url); | |
| 608 // Do nothing if we currently have that URL as non-forced. | |
| 609 if (new_list[index].last_forced_time.is_null()) | |
| 610 return false; | |
| 611 | |
| 612 // Update the |last_forced_time| of the already existing URL. Delete it and | |
| 613 // reinsert it at the right location. | |
| 614 new_url = new_list[index]; | |
| 615 new_list.erase(new_list.begin() + index); | |
| 616 num_forced--; | |
| 617 } else { | |
| 618 new_url.url = url; | |
| 619 new_url.redirects.push_back(url); | |
| 620 } | |
| 621 new_url.last_forced_time = time; | |
| 622 // Add forced URLs and sort. Added to the end of the list of forced URLs | |
| 623 // since this is almost always where it needs to go, unless the user's local | |
| 624 // clock is fiddled with. | |
| 625 MostVisitedURLList::iterator mid = new_list.begin() + num_forced; | |
| 626 new_list.insert(mid, new_url); | |
| 627 mid = new_list.begin() + num_forced; // Mid was invalidated. | |
| 628 std::inplace_merge(new_list.begin(), mid, mid + 1, ForcedURLComparator); | |
| 629 SetTopSites(new_list, CALL_LOCATION_FROM_FORCED_URLS); | |
| 630 return true; | |
| 631 } | |
| 632 | |
| 633 void TopSitesImpl::OnNavigationCommitted(const GURL& url) { | |
| 634 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 635 if (!loaded_ || IsNonForcedFull()) | |
| 636 return; | |
| 637 | |
| 638 if (!cache_->IsKnownURL(url) && can_add_url_to_history_.Run(url)) { | |
| 639 // To avoid slamming history we throttle requests when the url updates. To | |
| 640 // do otherwise negatively impacts perf tests. | |
| 641 RestartQueryForTopSitesTimer(GetUpdateDelay()); | |
| 642 } | |
| 643 } | |
| 644 | |
| 645 bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls, | 605 bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls, |
| 646 size_t num_forced_urls) { | 606 size_t num_forced_urls) { |
| 647 bool added = false; | 607 bool added = false; |
| 648 for (const auto& prepopulated_page : prepopulated_pages_) { | 608 for (const auto& prepopulated_page : prepopulated_pages_) { |
| 649 if (urls->size() - num_forced_urls < kNonForcedTopSitesNumber && | 609 if (urls->size() - num_forced_urls < kNonForcedTopSitesNumber && |
| 650 IndexOf(*urls, prepopulated_page.most_visited.url) == -1) { | 610 IndexOf(*urls, prepopulated_page.most_visited.url) == -1) { |
| 651 urls->push_back(prepopulated_page.most_visited); | 611 urls->push_back(prepopulated_page.most_visited); |
| 652 added = true; | 612 added = true; |
| 653 } | 613 } |
| 654 } | 614 } |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 930 for (std::set<size_t>::reverse_iterator i = indices_to_delete.rbegin(); | 890 for (std::set<size_t>::reverse_iterator i = indices_to_delete.rbegin(); |
| 931 i != indices_to_delete.rend(); i++) { | 891 i != indices_to_delete.rend(); i++) { |
| 932 new_top_sites.erase(new_top_sites.begin() + *i); | 892 new_top_sites.erase(new_top_sites.begin() + *i); |
| 933 } | 893 } |
| 934 SetTopSites(new_top_sites, CALL_LOCATION_FROM_OTHER_PLACES); | 894 SetTopSites(new_top_sites, CALL_LOCATION_FROM_OTHER_PLACES); |
| 935 } | 895 } |
| 936 StartQueryForMostVisited(); | 896 StartQueryForMostVisited(); |
| 937 } | 897 } |
| 938 | 898 |
| 939 } // namespace history | 899 } // namespace history |
| OLD | NEW |