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" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/md5.h" | 13 #include "base/md5.h" |
14 #include "base/memory/ref_counted_memory.h" | 14 #include "base/memory/ref_counted_memory.h" |
15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
17 #include "base/prefs/pref_service.h" | 17 #include "base/prefs/pref_service.h" |
18 #include "base/prefs/scoped_user_pref_update.h" | 18 #include "base/prefs/scoped_user_pref_update.h" |
19 #include "base/single_thread_task_runner.h" | |
19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
20 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
21 #include "base/task_runner.h" | 22 #include "base/task_runner.h" |
22 #include "base/values.h" | 23 #include "base/values.h" |
23 #include "chrome/browser/chrome_notification_types.h" | 24 #include "chrome/browser/chrome_notification_types.h" |
24 #include "chrome/browser/history/history_backend.h" | 25 #include "chrome/browser/history/history_backend.h" |
25 #include "chrome/browser/history/history_notifications.h" | 26 #include "chrome/browser/history/history_notifications.h" |
26 #include "chrome/browser/history/history_service_factory.h" | 27 #include "chrome/browser/history/history_service_factory.h" |
27 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
28 #include "chrome/common/pref_names.h" | 29 #include "chrome/common/pref_names.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 // Time from startup to first HistoryService query. | 89 // Time from startup to first HistoryService query. |
89 static const int64 kUpdateIntervalSecs = 15; | 90 static const int64 kUpdateIntervalSecs = 15; |
90 // Intervals between requests to HistoryService. | 91 // Intervals between requests to HistoryService. |
91 static const int64 kMinUpdateIntervalMinutes = 1; | 92 static const int64 kMinUpdateIntervalMinutes = 1; |
92 static const int64 kMaxUpdateIntervalMinutes = 60; | 93 static const int64 kMaxUpdateIntervalMinutes = 60; |
93 | 94 |
94 // Use 100 quality (highest quality) because we're very sensitive to | 95 // Use 100 quality (highest quality) because we're very sensitive to |
95 // artifacts for these small sized, highly detailed images. | 96 // artifacts for these small sized, highly detailed images. |
96 static const int kTopSitesImageQuality = 100; | 97 static const int kTopSitesImageQuality = 100; |
97 | 98 |
98 TopSitesImpl::TopSitesImpl(Profile* profile) | 99 TopSitesImpl::TopSitesImpl(Profile* profile, |
100 const PrepopulatedPageList& prepopulated_pages) | |
99 : backend_(NULL), | 101 : backend_(NULL), |
100 cache_(new TopSitesCache()), | 102 cache_(new TopSitesCache()), |
101 thread_safe_cache_(new TopSitesCache()), | 103 thread_safe_cache_(new TopSitesCache()), |
102 profile_(profile), | 104 profile_(profile), |
103 last_num_urls_changed_(0), | 105 last_num_urls_changed_(0), |
106 prepopulated_pages_(prepopulated_pages), | |
104 loaded_(false) { | 107 loaded_(false) { |
105 if (!profile_) | 108 if (!profile_) |
106 return; | 109 return; |
107 | 110 |
108 if (content::NotificationService::current()) { | 111 if (content::NotificationService::current()) { |
109 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 112 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
110 content::Source<Profile>(profile_)); | 113 content::Source<Profile>(profile_)); |
111 // Listen for any nav commits. We'll ignore those not related to this | 114 // Listen for any nav commits. We'll ignore those not related to this |
112 // profile when we get the notification. | 115 // profile when we get the notification. |
113 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 116 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
114 content::NotificationService::AllSources()); | 117 content::NotificationService::AllSources()); |
115 } | 118 } |
116 for (int i = 0; i < kPrepopulatedPagesCount; i++) { | |
117 int url_id = kPrepopulatedPages[i].url_id; | |
118 prepopulated_page_urls_.push_back( | |
119 GURL(l10n_util::GetStringUTF8(url_id))); | |
120 } | |
121 } | 119 } |
122 | 120 |
123 void TopSitesImpl::Init(const base::FilePath& db_name) { | 121 void TopSitesImpl::Init( |
122 const base::FilePath& db_name, | |
123 const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner) { | |
124 // Create the backend here, rather than in the constructor, so that | 124 // Create the backend here, rather than in the constructor, so that |
125 // unit tests that do not need the backend can run without a problem. | 125 // unit tests that do not need the backend can run without a problem. |
126 backend_ = new TopSitesBackend; | 126 backend_ = new TopSitesBackend(db_task_runner); |
127 backend_->Init(db_name); | 127 backend_->Init(db_name); |
128 backend_->GetMostVisitedThumbnails( | 128 backend_->GetMostVisitedThumbnails( |
129 base::Bind(&TopSitesImpl::OnGotMostVisitedThumbnails, | 129 base::Bind(&TopSitesImpl::OnGotMostVisitedThumbnails, |
130 base::Unretained(this)), | 130 base::Unretained(this)), |
131 &cancelable_task_tracker_); | 131 &cancelable_task_tracker_); |
132 } | 132 } |
133 | 133 |
134 bool TopSitesImpl::SetPageThumbnail(const GURL& url, | 134 bool TopSitesImpl::SetPageThumbnail(const GURL& url, |
135 const gfx::Image& thumbnail, | 135 const gfx::Image& thumbnail, |
136 const ThumbnailScore& score) { | 136 const ThumbnailScore& score) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 scoped_refptr<base::RefCountedMemory>* bytes) { | 238 scoped_refptr<base::RefCountedMemory>* bytes) { |
239 // WARNING: this may be invoked on any thread. | 239 // WARNING: this may be invoked on any thread. |
240 // Perform exact match. | 240 // Perform exact match. |
241 { | 241 { |
242 base::AutoLock lock(lock_); | 242 base::AutoLock lock(lock_); |
243 if (thread_safe_cache_->GetPageThumbnail(url, bytes)) | 243 if (thread_safe_cache_->GetPageThumbnail(url, bytes)) |
244 return true; | 244 return true; |
245 } | 245 } |
246 | 246 |
247 // Resource bundle is thread safe. | 247 // Resource bundle is thread safe. |
248 for (int i = 0; i < kPrepopulatedPagesCount; i++) { | 248 for (const auto& prepopulated_page : prepopulated_pages_) { |
249 if (url == prepopulated_page_urls_[i]) { | 249 if (url == prepopulated_page.url.url) { |
droger
2015/01/27 10:08:36
should this be something like:
prepopulated_page.m
sdefresne
2015/01/27 13:55:16
Changed to prepopulated.most_visited.url (though t
| |
250 *bytes = ResourceBundle::GetSharedInstance(). | 250 *bytes = |
251 LoadDataResourceBytesForScale( | 251 ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( |
252 kPrepopulatedPages[i].thumbnail_id, | 252 prepopulated_page.thumbnail_id, ui::SCALE_FACTOR_100P); |
253 ui::SCALE_FACTOR_100P); | |
254 return true; | 253 return true; |
255 } | 254 } |
256 } | 255 } |
257 | 256 |
258 if (prefix_match) { | 257 if (prefix_match) { |
259 // If http or https, search with |url| first, then try the other one. | 258 // If http or https, search with |url| first, then try the other one. |
260 std::vector<GURL> url_list; | 259 std::vector<GURL> url_list; |
261 url_list.push_back(url); | 260 url_list.push_back(url); |
262 if (url.SchemeIsHTTPOrHTTPS()) | 261 if (url.SchemeIsHTTPOrHTTPS()) |
263 url_list.push_back(ToggleHTTPAndHTTPS(url)); | 262 url_list.push_back(ToggleHTTPAndHTTPS(url)); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
584 int TopSitesImpl::GetRedirectDistanceForURL(const MostVisitedURL& most_visited, | 583 int TopSitesImpl::GetRedirectDistanceForURL(const MostVisitedURL& most_visited, |
585 const GURL& url) { | 584 const GURL& url) { |
586 for (size_t i = 0; i < most_visited.redirects.size(); i++) { | 585 for (size_t i = 0; i < most_visited.redirects.size(); i++) { |
587 if (most_visited.redirects[i] == url) | 586 if (most_visited.redirects[i] == url) |
588 return static_cast<int>(most_visited.redirects.size() - i - 1); | 587 return static_cast<int>(most_visited.redirects.size() - i - 1); |
589 } | 588 } |
590 NOTREACHED() << "URL should always be found."; | 589 NOTREACHED() << "URL should always be found."; |
591 return 0; | 590 return 0; |
592 } | 591 } |
593 | 592 |
594 MostVisitedURLList TopSitesImpl::GetPrepopulatePages() { | 593 PrepopulatedPageList TopSitesImpl::GetPrepopulatedPages() { |
595 MostVisitedURLList urls; | 594 return prepopulated_pages_; |
596 urls.resize(kPrepopulatedPagesCount); | |
597 for (int i = 0; i < kPrepopulatedPagesCount; ++i) { | |
598 MostVisitedURL& url = urls[i]; | |
599 url.url = GURL(prepopulated_page_urls_[i]); | |
600 url.redirects.push_back(url.url); | |
601 url.title = l10n_util::GetStringUTF16(kPrepopulatedPages[i].title_id); | |
602 } | |
603 return urls; | |
604 } | 595 } |
605 | 596 |
606 bool TopSitesImpl::loaded() const { | 597 bool TopSitesImpl::loaded() const { |
607 return loaded_; | 598 return loaded_; |
608 } | 599 } |
609 | 600 |
610 bool TopSitesImpl::AddForcedURL(const GURL& url, const base::Time& time) { | 601 bool TopSitesImpl::AddForcedURL(const GURL& url, const base::Time& time) { |
611 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
612 size_t num_forced = cache_->GetNumForcedURLs(); | 603 size_t num_forced = cache_->GetNumForcedURLs(); |
613 MostVisitedURLList new_list(cache_->top_sites()); | 604 MostVisitedURLList new_list(cache_->top_sites()); |
(...skipping 22 matching lines...) Expand all Loading... | |
636 new_list.insert(mid, new_url); | 627 new_list.insert(mid, new_url); |
637 mid = new_list.begin() + num_forced; // Mid was invalidated. | 628 mid = new_list.begin() + num_forced; // Mid was invalidated. |
638 std::inplace_merge(new_list.begin(), mid, mid + 1, ForcedURLComparator); | 629 std::inplace_merge(new_list.begin(), mid, mid + 1, ForcedURLComparator); |
639 SetTopSites(new_list); | 630 SetTopSites(new_list); |
640 return true; | 631 return true; |
641 } | 632 } |
642 | 633 |
643 bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls, | 634 bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls, |
644 size_t num_forced_urls) { | 635 size_t num_forced_urls) { |
645 bool added = false; | 636 bool added = false; |
646 MostVisitedURLList prepopulate_urls = GetPrepopulatePages(); | 637 for (const auto& prepopulated_page : prepopulated_pages_) { |
647 for (size_t i = 0; i < prepopulate_urls.size(); ++i) { | |
648 if (urls->size() - num_forced_urls < kNonForcedTopSitesNumber && | 638 if (urls->size() - num_forced_urls < kNonForcedTopSitesNumber && |
649 IndexOf(*urls, prepopulate_urls[i].url) == -1) { | 639 IndexOf(*urls, prepopulated_page.url.url) == -1) { |
650 urls->push_back(prepopulate_urls[i]); | 640 urls->push_back(prepopulated_page.url); |
651 added = true; | 641 added = true; |
652 } | 642 } |
653 } | 643 } |
654 return added; | 644 return added; |
655 } | 645 } |
656 | 646 |
657 size_t TopSitesImpl::MergeCachedForcedURLs(MostVisitedURLList* new_list) { | 647 size_t TopSitesImpl::MergeCachedForcedURLs(MostVisitedURLList* new_list) { |
658 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 648 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
659 // Add all the new URLs for quick lookup. Take that opportunity to count the | 649 // Add all the new URLs for quick lookup. Take that opportunity to count the |
660 // number of forced URLs in |new_list|. | 650 // number of forced URLs in |new_list|. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 } | 713 } |
724 } | 714 } |
725 | 715 |
726 std::string TopSitesImpl::GetURLHash(const GURL& url) { | 716 std::string TopSitesImpl::GetURLHash(const GURL& url) { |
727 // We don't use canonical URLs here to be able to blacklist only one of | 717 // We don't use canonical URLs here to be able to blacklist only one of |
728 // the two 'duplicate' sites, e.g. 'gmail.com' and 'mail.google.com'. | 718 // the two 'duplicate' sites, e.g. 'gmail.com' and 'mail.google.com'. |
729 return base::MD5String(url.spec()); | 719 return base::MD5String(url.spec()); |
730 } | 720 } |
731 | 721 |
732 base::TimeDelta TopSitesImpl::GetUpdateDelay() { | 722 base::TimeDelta TopSitesImpl::GetUpdateDelay() { |
733 if (cache_->top_sites().size() <= kPrepopulatedPagesCount) | 723 if (cache_->top_sites().size() <= prepopulated_pages_.size()) |
734 return base::TimeDelta::FromSeconds(30); | 724 return base::TimeDelta::FromSeconds(30); |
735 | 725 |
736 int64 range = kMaxUpdateIntervalMinutes - kMinUpdateIntervalMinutes; | 726 int64 range = kMaxUpdateIntervalMinutes - kMinUpdateIntervalMinutes; |
737 int64 minutes = kMaxUpdateIntervalMinutes - | 727 int64 minutes = kMaxUpdateIntervalMinutes - |
738 last_num_urls_changed_ * range / cache_->top_sites().size(); | 728 last_num_urls_changed_ * range / cache_->top_sites().size(); |
739 return base::TimeDelta::FromMinutes(minutes); | 729 return base::TimeDelta::FromMinutes(minutes); |
740 } | 730 } |
741 | 731 |
742 void TopSitesImpl::Observe(int type, | 732 void TopSitesImpl::Observe(int type, |
743 const content::NotificationSource& source, | 733 const content::NotificationSource& source, |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
922 base::TimeDelta::FromSeconds(kUpdateIntervalSecs)); | 912 base::TimeDelta::FromSeconds(kUpdateIntervalSecs)); |
923 } | 913 } |
924 | 914 |
925 void TopSitesImpl::OnTopSitesAvailableFromHistory( | 915 void TopSitesImpl::OnTopSitesAvailableFromHistory( |
926 const MostVisitedURLList* pages) { | 916 const MostVisitedURLList* pages) { |
927 DCHECK(pages); | 917 DCHECK(pages); |
928 SetTopSites(*pages); | 918 SetTopSites(*pages); |
929 } | 919 } |
930 | 920 |
931 } // namespace history | 921 } // namespace history |
OLD | NEW |