| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/webui/ntp/most_visited_handler.h" | 5 #include "chrome/browser/ui/webui/ntp/most_visited_handler.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/md5.h" | 12 #include "base/md5.h" |
| 13 #include "base/memory/scoped_vector.h" | 13 #include "base/memory/scoped_vector.h" |
| 14 #include "base/memory/singleton.h" | 14 #include "base/memory/singleton.h" |
| 15 #include "base/metrics/field_trial.h" | |
| 16 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 17 #include "base/prefs/pref_service.h" | 16 #include "base/prefs/pref_service.h" |
| 18 #include "base/strings/string16.h" | 17 #include "base/strings/string16.h" |
| 19 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
| 22 #include "base/values.h" | 21 #include "base/values.h" |
| 23 #include "chrome/browser/history/page_usage_data.h" | 22 #include "chrome/browser/history/page_usage_data.h" |
| 24 #include "chrome/browser/history/top_sites.h" | 23 #include "chrome/browser/history/top_sites.h" |
| 25 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 24 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 45 #include "googleurl/src/gurl.h" | 44 #include "googleurl/src/gurl.h" |
| 46 #include "grit/chromium_strings.h" | 45 #include "grit/chromium_strings.h" |
| 47 #include "grit/generated_resources.h" | 46 #include "grit/generated_resources.h" |
| 48 #include "grit/locale_settings.h" | 47 #include "grit/locale_settings.h" |
| 49 #include "ui/base/l10n/l10n_util.h" | 48 #include "ui/base/l10n/l10n_util.h" |
| 50 | 49 |
| 51 using content::UserMetricsAction; | 50 using content::UserMetricsAction; |
| 52 | 51 |
| 53 namespace { | 52 namespace { |
| 54 | 53 |
| 55 // Constants for the most visited tile placement field trial. | |
| 56 const char kMostVisitedFieldTrialName[] = "MostVisitedTilePlacement"; | |
| 57 const char kTabsGroupName[] = "DontShowOpenTabs"; | |
| 58 | |
| 59 // Minimum number of suggestions that |pages_value_| must hold for the Most | |
| 60 // Visited Field Trial to remove a URL if already open in the browser. | |
| 61 const size_t kMinUrlSuggestions = 8; | |
| 62 | |
| 63 // Creates a set containing the canonical URLs of the currently open tabs. | 54 // Creates a set containing the canonical URLs of the currently open tabs. |
| 64 void GetOpenUrls(const TabStripModel& tabs, | 55 void GetOpenUrls(const TabStripModel& tabs, |
| 65 const history::TopSites& ts, | 56 const history::TopSites& ts, |
| 66 std::set<std::string>* urls) { | 57 std::set<std::string>* urls) { |
| 67 for (int i = 0; i < tabs.count(); ++i) { | 58 for (int i = 0; i < tabs.count(); ++i) { |
| 68 content::WebContents* web_contents = tabs.GetWebContentsAt(i); | 59 content::WebContents* web_contents = tabs.GetWebContentsAt(i); |
| 69 if (web_contents) | 60 if (web_contents) |
| 70 urls->insert(ts.GetCanonicalURLString(web_contents->GetURL())); | 61 urls->insert(ts.GetCanonicalURLString(web_contents->GetURL())); |
| 71 } | 62 } |
| 72 } | 63 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 void MostVisitedHandler::SendPagesValue() { | 154 void MostVisitedHandler::SendPagesValue() { |
| 164 if (pages_value_) { | 155 if (pages_value_) { |
| 165 Profile* profile = Profile::FromWebUI(web_ui()); | 156 Profile* profile = Profile::FromWebUI(web_ui()); |
| 166 const DictionaryValue* url_blacklist = | 157 const DictionaryValue* url_blacklist = |
| 167 profile->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist); | 158 profile->GetPrefs()->GetDictionary(prefs::kNtpMostVisitedURLsBlacklist); |
| 168 bool has_blacklisted_urls = !url_blacklist->empty(); | 159 bool has_blacklisted_urls = !url_blacklist->empty(); |
| 169 history::TopSites* ts = profile->GetTopSites(); | 160 history::TopSites* ts = profile->GetTopSites(); |
| 170 if (ts) { | 161 if (ts) { |
| 171 has_blacklisted_urls = ts->HasBlacklistedItems(); | 162 has_blacklisted_urls = ts->HasBlacklistedItems(); |
| 172 | 163 |
| 173 // The following experiment removes recommended URLs if a matching URL is | 164 MaybeRemovePageValues(); |
| 174 // already open in the Browser. Note: this targets only the | |
| 175 // top-level of sites i.e. if www.foo.com/bar is open in browser, and | |
| 176 // www.foo.com is a recommended URL, www.foo.com will still appear on the | |
| 177 // next NTP open. | |
| 178 if (base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName) == | |
| 179 kTabsGroupName) { | |
| 180 RemovePageValuesMatchingOpenTabs(); | |
| 181 } | |
| 182 } | 165 } |
| 183 | 166 |
| 184 base::FundamentalValue has_blacklisted_urls_value(has_blacklisted_urls); | 167 base::FundamentalValue has_blacklisted_urls_value(has_blacklisted_urls); |
| 185 web_ui()->CallJavascriptFunction("ntp.setMostVisitedPages", | 168 web_ui()->CallJavascriptFunction("ntp.setMostVisitedPages", |
| 186 *pages_value_, | 169 *pages_value_, |
| 187 has_blacklisted_urls_value); | 170 has_blacklisted_urls_value); |
| 188 pages_value_.reset(); | 171 pages_value_.reset(); |
| 189 } | 172 } |
| 190 } | 173 } |
| 191 | 174 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 history::TopSites* ts = Profile::FromWebUI(web_ui())->GetTopSites(); | 275 history::TopSites* ts = Profile::FromWebUI(web_ui())->GetTopSites(); |
| 293 if (ts) | 276 if (ts) |
| 294 ts->AddBlacklistedURL(url); | 277 ts->AddBlacklistedURL(url); |
| 295 content::RecordAction(UserMetricsAction("MostVisited_UrlBlacklisted")); | 278 content::RecordAction(UserMetricsAction("MostVisited_UrlBlacklisted")); |
| 296 } | 279 } |
| 297 | 280 |
| 298 std::string MostVisitedHandler::GetDictionaryKeyForUrl(const std::string& url) { | 281 std::string MostVisitedHandler::GetDictionaryKeyForUrl(const std::string& url) { |
| 299 return base::MD5String(url); | 282 return base::MD5String(url); |
| 300 } | 283 } |
| 301 | 284 |
| 302 void MostVisitedHandler::RemovePageValuesMatchingOpenTabs() { | 285 void MostVisitedHandler::MaybeRemovePageValues() { |
| 303 #if !defined(OS_ANDROID) | 286 #if !defined(OS_ANDROID) |
| 287 if (!history::TopSites::IsClientInTabsGroup()) |
| 288 return; |
| 289 |
| 304 TabStripModel* tab_strip_model = chrome::FindBrowserWithWebContents( | 290 TabStripModel* tab_strip_model = chrome::FindBrowserWithWebContents( |
| 305 web_ui()->GetWebContents())->tab_strip_model(); | 291 web_ui()->GetWebContents())->tab_strip_model(); |
| 306 history::TopSites* ts = Profile::FromWebUI(web_ui())->GetTopSites(); | 292 history::TopSites* ts = Profile::FromWebUI(web_ui())->GetTopSites(); |
| 307 if (!tab_strip_model || !ts) { | 293 if (!tab_strip_model || !ts) { |
| 308 NOTREACHED(); | 294 NOTREACHED(); |
| 309 return; | 295 return; |
| 310 } | 296 } |
| 311 | 297 |
| 312 // Iterate through most visited suggestions and remove pages already open in | |
| 313 // current browser, making sure to not drop below 8 suggestions. | |
| 314 std::set<std::string> open_urls; | 298 std::set<std::string> open_urls; |
| 315 GetOpenUrls(*tab_strip_model, *ts, &open_urls); | 299 GetOpenUrls(*tab_strip_model, *ts, &open_urls); |
| 316 size_t i = 0; | 300 history::TopSites::RemovePageValuesMatchingOpenTabs( |
| 317 while (i < pages_value_->GetSize() && | 301 open_urls, |
| 318 pages_value_->GetSize() > kMinUrlSuggestions) { | 302 pages_value_.get()); |
| 319 base::DictionaryValue* page_value; | |
| 320 std::string url; | |
| 321 if (pages_value_->GetDictionary(i, &page_value) && | |
| 322 page_value->GetString("url", &url) && | |
| 323 open_urls.count(url) != 0) { | |
| 324 pages_value_->Remove(*page_value, &i); | |
| 325 } else { | |
| 326 ++i; | |
| 327 } | |
| 328 } | |
| 329 #endif | 303 #endif |
| 330 } | 304 } |
| 331 | 305 |
| 332 // static | 306 // static |
| 333 void MostVisitedHandler::RegisterUserPrefs( | 307 void MostVisitedHandler::RegisterUserPrefs( |
| 334 user_prefs::PrefRegistrySyncable* registry) { | 308 user_prefs::PrefRegistrySyncable* registry) { |
| 335 registry->RegisterDictionaryPref( | 309 registry->RegisterDictionaryPref( |
| 336 prefs::kNtpMostVisitedURLsBlacklist, | 310 prefs::kNtpMostVisitedURLsBlacklist, |
| 337 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 311 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 338 } | 312 } |
| OLD | NEW |