diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-01-04 14:17:57 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-01-05 10:05:06 +0000 |
commit | 39d357e3248f80abea0159765ff39554affb40db (patch) | |
tree | aba0e6bfb76de0244bba0f5fdbd64b830dd6e621 /chromium/components/ntp_tiles | |
parent | 87778abf5a1f89266f37d1321b92a21851d8244d (diff) | |
download | qtwebengine-chromium-39d357e3248f80abea0159765ff39554affb40db.tar.gz |
BASELINE: Update Chromium to 55.0.2883.105
And updates ninja to 1.7.2
Change-Id: I20d43c737f82764d857ada9a55586901b18b9243
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components/ntp_tiles')
-rw-r--r-- | chromium/components/ntp_tiles/BUILD.gn | 10 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/DEPS | 2 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/OWNERS | 1 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/android/BUILD.gn | 2 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/most_visited_sites.cc | 432 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/most_visited_sites.h | 159 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/most_visited_sites_unittest.cc | 71 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/ntp_tile.cc | 15 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/ntp_tile.h | 49 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/popular_sites.cc | 42 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/popular_sites.h | 46 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/pref_names.cc | 10 | ||||
-rw-r--r-- | chromium/components/ntp_tiles/pref_names.h | 7 |
13 files changed, 415 insertions, 431 deletions
diff --git a/chromium/components/ntp_tiles/BUILD.gn b/chromium/components/ntp_tiles/BUILD.gn index dc95cd619eb..e51074fe2d0 100644 --- a/chromium/components/ntp_tiles/BUILD.gn +++ b/chromium/components/ntp_tiles/BUILD.gn @@ -2,19 +2,18 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -assert(!is_ios) # TODO(sfiera): support iOS http://crbug.com/617966 - if (is_android) { import("//build/config/android/rules.gni") } -# GYP version: components/ntp_tiles.gypi:ntp_tiles -source_set("ntp_tiles") { +static_library("ntp_tiles") { sources = [ "constants.cc", "constants.h", "most_visited_sites.cc", "most_visited_sites.h", + "ntp_tile.cc", + "ntp_tile.h", "popular_sites.cc", "popular_sites.h", "pref_names.cc", @@ -29,10 +28,10 @@ source_set("ntp_tiles") { "//components/suggestions", ] deps = [ + "//components/data_use_measurement/core", "//components/google/core/browser", "//components/pref_registry", "//components/prefs", - "//components/safe_json", "//components/search_engines", "//components/variations", "//components/variations/service", @@ -59,6 +58,7 @@ if (is_android) { java_cpp_enum("ntp_tiles_enums_java") { sources = [ "most_visited_sites.h", + "ntp_tile.h", ] } } diff --git a/chromium/components/ntp_tiles/DEPS b/chromium/components/ntp_tiles/DEPS index a01a8e32056..fdb9b3d1e59 100644 --- a/chromium/components/ntp_tiles/DEPS +++ b/chromium/components/ntp_tiles/DEPS @@ -1,9 +1,9 @@ include_rules = [ + "+components/data_use_measurement/core", "+components/google/core/browser", "+components/history/core/browser", "+components/pref_registry", "+components/prefs", - "+components/safe_json", "+components/search_engines", "+components/suggestions", "+components/variations", diff --git a/chromium/components/ntp_tiles/OWNERS b/chromium/components/ntp_tiles/OWNERS index f0b684fb2d5..7078b1cafd0 100644 --- a/chromium/components/ntp_tiles/OWNERS +++ b/chromium/components/ntp_tiles/OWNERS @@ -1,2 +1,3 @@ bauerb@chromium.org treib@chromium.org +sfiera@chromium.org diff --git a/chromium/components/ntp_tiles/android/BUILD.gn b/chromium/components/ntp_tiles/android/BUILD.gn index cf6c2cf970f..e125f19af9b 100644 --- a/chromium/components/ntp_tiles/android/BUILD.gn +++ b/chromium/components/ntp_tiles/android/BUILD.gn @@ -7,13 +7,11 @@ import("//build/config/android/rules.gni") _jni_sources = [ "java/src/org/chromium/components/ntptiles/MostVisitedSites.java" ] -# GYP: //components/ntp_tiles.gypi:ntp_tiles_jni_headers generate_jni("ntp_tiles_jni_headers") { sources = _jni_sources jni_package = "ntp_tiles" } -# GYP: //components/ntp_tiles.gypi:ntp_tiles_java android_library("ntp_tiles_java") { deps = [ "//base:base_java", diff --git a/chromium/components/ntp_tiles/most_visited_sites.cc b/chromium/components/ntp_tiles/most_visited_sites.cc index 14468a66a3b..309a0b48d15 100644 --- a/chromium/components/ntp_tiles/most_visited_sites.cc +++ b/chromium/components/ntp_tiles/most_visited_sites.cc @@ -6,6 +6,7 @@ #include <algorithm> #include <set> +#include <string> #include <utility> #if defined(OS_ANDROID) @@ -17,20 +18,18 @@ #include "base/feature_list.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" +#include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" #include "components/history/core/browser/top_sites.h" #include "components/ntp_tiles/constants.h" #include "components/ntp_tiles/pref_names.h" #include "components/ntp_tiles/switches.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" -#include "ui/gfx/codec/jpeg_codec.h" -#include "url/gurl.h" #if defined(OS_ANDROID) #include "base/android/jni_android.h" @@ -49,7 +48,6 @@ namespace { // Identifiers for the various tile sources. const char kHistogramClientName[] = "client"; const char kHistogramServerName[] = "server"; -const char kHistogramServerFormat[] = "server%d"; const char kHistogramPopularName[] = "popular"; const char kHistogramWhitelistName[] = "whitelist"; @@ -79,9 +77,10 @@ bool ShouldShowPopularSites() { base::FieldTrialList::FindFullName(kPopularSitesFieldTrialName); base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); - if (cmd_line->HasSwitch(ntp_tiles::switches::kDisableNTPPopularSites)) + if (cmd_line->HasSwitch(switches::kDisableNTPPopularSites)) return false; - if (cmd_line->HasSwitch(ntp_tiles::switches::kEnableNTPPopularSites)) + + if (cmd_line->HasSwitch(switches::kEnableNTPPopularSites)) return true; #if defined(OS_ANDROID) @@ -95,24 +94,28 @@ bool ShouldShowPopularSites() { base::CompareCase::INSENSITIVE_ASCII); } -// Determine whether we need any popular suggestions to fill up a grid of +// Determine whether we need any tiles from PopularSites to fill up a grid of // |num_tiles| tiles. -bool NeedPopularSites(const PrefService* prefs, size_t num_tiles) { +bool NeedPopularSites(const PrefService* prefs, int num_tiles) { + if (num_tiles <= prefs->GetInteger(prefs::kNumPersonalTiles)) + return false; + + // TODO(treib): Remove after M55. const base::ListValue* source_list = - prefs->GetList(ntp_tiles::prefs::kNTPSuggestionsIsPersonal); - // If there aren't enough previous suggestions to fill the grid, we need - // popular suggestions. - if (source_list->GetSize() < num_tiles) + prefs->GetList(prefs::kDeprecatedNTPTilesIsPersonal); + // If there aren't enough previous tiles to fill the grid, we need tiles from + // PopularSites. + if (static_cast<int>(source_list->GetSize()) < num_tiles) return true; - // Otherwise, if any of the previous suggestions is not personal, then also - // get popular suggestions. - for (size_t i = 0; i < num_tiles; ++i) { + // Otherwise, if any of the previous tiles are not personal, then also + // get tiles from PopularSites. + for (int i = 0; i < num_tiles; ++i) { bool is_personal = false; if (source_list->GetBoolean(i, &is_personal) && !is_personal) return true; } - // The whole grid is already filled with personal suggestions, no point in - // bothering with popular ones. + // The whole grid is already filled with personal tiles, no point in bothering + // with popular ones. return false; } @@ -120,88 +123,53 @@ bool AreURLsEquivalent(const GURL& url1, const GURL& url2) { return url1.host() == url2.host() && url1.path() == url2.path(); } -std::string GetSourceHistogramName(int source, int provider_index) { +std::string GetSourceHistogramName(NTPTileSource source) { switch (source) { - case MostVisitedSites::TOP_SITES: + case NTPTileSource::TOP_SITES: return kHistogramClientName; - case MostVisitedSites::POPULAR: + case NTPTileSource::POPULAR: return kHistogramPopularName; - case MostVisitedSites::WHITELIST: + case NTPTileSource::WHITELIST: return kHistogramWhitelistName; - case MostVisitedSites::SUGGESTIONS_SERVICE: - return provider_index >= 0 - ? base::StringPrintf(kHistogramServerFormat, provider_index) - : kHistogramServerName; + case NTPTileSource::SUGGESTIONS_SERVICE: + return kHistogramServerName; } NOTREACHED(); return std::string(); } -std::string GetSourceHistogramNameFromSuggestion( - const MostVisitedSites::Suggestion& suggestion) { - return GetSourceHistogramName(suggestion.source, suggestion.provider_index); -} - -void AppendSuggestions(MostVisitedSites::SuggestionsVector src, - MostVisitedSites::SuggestionsVector* dst) { - dst->insert(dst->end(), - std::make_move_iterator(src.begin()), - std::make_move_iterator(src.end())); -} - } // namespace -MostVisitedSites::Suggestion::Suggestion() : provider_index(-1) {} - -MostVisitedSites::Suggestion::~Suggestion() {} - -MostVisitedSites::Suggestion::Suggestion(Suggestion&&) = default; -MostVisitedSites::Suggestion& -MostVisitedSites::Suggestion::operator=(Suggestion&&) = default; - -MostVisitedSites::MostVisitedSites( - scoped_refptr<base::SequencedWorkerPool> blocking_pool, - PrefService* prefs, - const TemplateURLService* template_url_service, - variations::VariationsService* variations_service, - net::URLRequestContextGetter* download_context, - const base::FilePath& popular_sites_directory, - scoped_refptr<history::TopSites> top_sites, - SuggestionsService* suggestions, - MostVisitedSitesSupervisor* supervisor) +MostVisitedSites::MostVisitedSites(PrefService* prefs, + scoped_refptr<history::TopSites> top_sites, + SuggestionsService* suggestions, + std::unique_ptr<PopularSites> popular_sites, + MostVisitedSitesSupervisor* supervisor) : prefs_(prefs), - template_url_service_(template_url_service), - variations_service_(variations_service), - download_context_(download_context), - popular_sites_directory_(popular_sites_directory), top_sites_(top_sites), suggestions_service_(suggestions), + popular_sites_(std::move(popular_sites)), supervisor_(supervisor), observer_(nullptr), num_sites_(0), - received_most_visited_sites_(false), - received_popular_sites_(false), + waiting_for_most_visited_sites_(true), + waiting_for_popular_sites_(true), recorded_uma_(false), - scoped_observer_(this), - mv_source_(SUGGESTIONS_SERVICE), - blocking_pool_(std::move(blocking_pool)), - blocking_runner_(blocking_pool_->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)), + top_sites_observer_(this), + mv_source_(NTPTileSource::SUGGESTIONS_SERVICE), weak_ptr_factory_(this) { + DCHECK(prefs_); + // top_sites_ can be null in tests. + // TODO(sfiera): have iOS use a dummy TopSites in its tests. DCHECK(suggestions_service_); - supervisor_->SetObserver(this); + if (supervisor_) + supervisor_->SetObserver(this); } MostVisitedSites::~MostVisitedSites() { - supervisor_->SetObserver(nullptr); -} - -#if defined(OS_ANDROID) -// static -bool MostVisitedSites::Register(JNIEnv* env) { - return RegisterNativesImpl(env); + if (supervisor_) + supervisor_->SetObserver(nullptr); } -#endif void MostVisitedSites::SetMostVisitedURLsObserver(Observer* observer, int num_sites) { @@ -209,15 +177,13 @@ void MostVisitedSites::SetMostVisitedURLsObserver(Observer* observer, observer_ = observer; num_sites_ = num_sites; - if (ShouldShowPopularSites() && + if (popular_sites_ && ShouldShowPopularSites() && NeedPopularSites(prefs_, num_sites_)) { - popular_sites_.reset(new PopularSites( - blocking_pool_, prefs_, template_url_service_, variations_service_, - download_context_, popular_sites_directory_, false, - base::Bind(&MostVisitedSites::OnPopularSitesAvailable, - base::Unretained(this)))); + popular_sites_->StartFetch( + false, base::Bind(&MostVisitedSites::OnPopularSitesAvailable, + base::Unretained(this))); } else { - received_popular_sites_ = true; + waiting_for_popular_sites_ = false; } if (top_sites_) { @@ -227,16 +193,16 @@ void MostVisitedSites::SetMostVisitedURLsObserver(Observer* observer, // Register as TopSitesObserver so that we can update ourselves when the // TopSites changes. - scoped_observer_.Add(top_sites_.get()); + top_sites_observer_.Add(top_sites_.get()); } suggestions_subscription_ = suggestions_service_->AddCallback( base::Bind(&MostVisitedSites::OnSuggestionsProfileAvailable, base::Unretained(this))); - // Immediately build the current suggestions, getting personal suggestions - // from the SuggestionsService's cache or, if that is empty, from TopSites. - BuildCurrentSuggestions(); + // Immediately build the current set of tiles, getting suggestions from the + // SuggestionsService's cache or, if that is empty, sites from TopSites. + BuildCurrentTiles(); // Also start a request for fresh suggestions. suggestions_service_->FetchSuggestionsData(); } @@ -252,7 +218,7 @@ void MostVisitedSites::AddOrRemoveBlacklistedUrl(const GURL& url, } // Only blacklist in the server-side suggestions service if it's active. - if (mv_source_ == SUGGESTIONS_SERVICE) { + if (mv_source_ == NTPTileSource::SUGGESTIONS_SERVICE) { if (add_url) suggestions_service_->BlacklistURL(url); else @@ -261,16 +227,18 @@ void MostVisitedSites::AddOrRemoveBlacklistedUrl(const GURL& url, } void MostVisitedSites::RecordTileTypeMetrics( - const std::vector<int>& tile_types, - const std::vector<int>& sources, - const std::vector<int>& provider_indices) { + const std::vector<MostVisitedTileType>& tile_types, + const std::vector<NTPTileSource>& sources) { int counts_per_type[NUM_TILE_TYPES] = {0}; for (size_t i = 0; i < tile_types.size(); ++i) { - int tile_type = tile_types[i]; + MostVisitedTileType tile_type = tile_types[i]; ++counts_per_type[tile_type]; + + UMA_HISTOGRAM_ENUMERATION("NewTabPage.TileType", tile_type, NUM_TILE_TYPES); + std::string histogram = base::StringPrintf( "NewTabPage.TileType.%s", - GetSourceHistogramName(sources[i], provider_indices[i]).c_str()); + GetSourceHistogramName(sources[i]).c_str()); LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES); } @@ -282,42 +250,38 @@ void MostVisitedSites::RecordTileTypeMetrics( counts_per_type[ICON_DEFAULT]); } -void MostVisitedSites::RecordOpenedMostVisitedItem(int index, int tile_type) { - // TODO(treib): |current_suggestions_| could be updated before this function - // is called, leading to DCHECKs and/or memory corruption. Adjust this - // function to work with asynchronous UI. - DCHECK_GE(index, 0); - DCHECK_LT(index, static_cast<int>(current_suggestions_.size())); +void MostVisitedSites::RecordOpenedMostVisitedItem( + int index, + MostVisitedTileType tile_type, + NTPTileSource source) { + UMA_HISTOGRAM_ENUMERATION("NewTabPage.MostVisited", index, num_sites_); + std::string histogram = base::StringPrintf( - "NewTabPage.MostVisited.%s", - GetSourceHistogramNameFromSuggestion(current_suggestions_[index]) - .c_str()); + "NewTabPage.MostVisited.%s", GetSourceHistogramName(source).c_str()); LogHistogramEvent(histogram, index, num_sites_); - histogram = base::StringPrintf( - "NewTabPage.TileTypeClicked.%s", - GetSourceHistogramNameFromSuggestion(current_suggestions_[index]) - .c_str()); + UMA_HISTOGRAM_ENUMERATION( + "NewTabPage.TileTypeClicked", tile_type, NUM_TILE_TYPES); + + histogram = base::StringPrintf("NewTabPage.TileTypeClicked.%s", + GetSourceHistogramName(source).c_str()); LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES); } void MostVisitedSites::OnBlockedSitesChanged() { - BuildCurrentSuggestions(); + BuildCurrentTiles(); } // static void MostVisitedSites::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { - // TODO(treib): Remove this, it's unused. Do we need migration code to clean - // up existing entries? - registry->RegisterListPref(ntp_tiles::prefs::kNTPSuggestionsURL); - // TODO(treib): Remove this. It's only used to determine if we need - // PopularSites at all. Find a way to do that without prefs, or failing that, - // replace this list pref by a simple bool. - registry->RegisterListPref(ntp_tiles::prefs::kNTPSuggestionsIsPersonal); + registry->RegisterIntegerPref(prefs::kNumPersonalTiles, 0); + // TODO(treib): Remove after M55. + registry->RegisterListPref(prefs::kDeprecatedNTPTilesURL); + registry->RegisterListPref(prefs::kDeprecatedNTPTilesIsPersonal); } -void MostVisitedSites::BuildCurrentSuggestions() { +void MostVisitedSites::BuildCurrentTiles() { // Get the current suggestions from cache. If the cache is empty, this will // fall back to TopSites. OnSuggestionsProfileAvailable( @@ -334,16 +298,18 @@ void MostVisitedSites::InitiateTopSitesQuery() { } base::FilePath MostVisitedSites::GetWhitelistLargeIconPath(const GURL& url) { - for (const auto& whitelist : supervisor_->whitelists()) { - if (AreURLsEquivalent(whitelist.entry_point, url)) - return whitelist.large_icon_path; + if (supervisor_) { + for (const auto& whitelist : supervisor_->whitelists()) { + if (AreURLsEquivalent(whitelist.entry_point, url)) + return whitelist.large_icon_path; + } } return base::FilePath(); } void MostVisitedSites::OnMostVisitedURLsAvailable( const history::MostVisitedURLList& visited_list) { - SuggestionsVector suggestions; + NTPTilesVector tiles; size_t num_tiles = std::min(visited_list.size(), static_cast<size_t>(num_sites_)); for (size_t i = 0; i < num_tiles; ++i) { @@ -352,21 +318,21 @@ void MostVisitedSites::OnMostVisitedURLsAvailable( num_tiles = i; break; // This is the signal that there are no more real visited sites. } - if (supervisor_->IsBlocked(visited.url)) + if (supervisor_ && supervisor_->IsBlocked(visited.url)) continue; - Suggestion suggestion; - suggestion.title = visited.title; - suggestion.url = visited.url; - suggestion.source = TOP_SITES; - suggestion.whitelist_icon_path = GetWhitelistLargeIconPath(visited.url); + NTPTile tile; + tile.title = visited.title; + tile.url = visited.url; + tile.source = NTPTileSource::TOP_SITES; + tile.whitelist_icon_path = GetWhitelistLargeIconPath(visited.url); - suggestions.push_back(std::move(suggestion)); + tiles.push_back(std::move(tile)); } - received_most_visited_sites_ = true; - mv_source_ = TOP_SITES; - SaveNewSuggestions(std::move(suggestions)); + waiting_for_most_visited_sites_ = false; + mv_source_ = NTPTileSource::TOP_SITES; + SaveNewTiles(std::move(tiles)); NotifyMostVisitedURLsObserver(); } @@ -382,49 +348,50 @@ void MostVisitedSites::OnSuggestionsProfileAvailable( if (num_sites_ < num_tiles) num_tiles = num_sites_; - SuggestionsVector suggestions; + NTPTilesVector tiles; for (int i = 0; i < num_tiles; ++i) { - const ChromeSuggestion& suggestion = suggestions_profile.suggestions(i); - if (supervisor_->IsBlocked(GURL(suggestion.url()))) + const ChromeSuggestion& suggestion_pb = suggestions_profile.suggestions(i); + GURL url(suggestion_pb.url()); + if (supervisor_ && supervisor_->IsBlocked(url)) continue; - Suggestion generated_suggestion; - generated_suggestion.title = base::UTF8ToUTF16(suggestion.title()); - generated_suggestion.url = GURL(suggestion.url()); - generated_suggestion.source = SUGGESTIONS_SERVICE; - generated_suggestion.whitelist_icon_path = - GetWhitelistLargeIconPath(GURL(suggestion.url())); - if (suggestion.providers_size() > 0) - generated_suggestion.provider_index = suggestion.providers(0); + NTPTile tile; + tile.title = base::UTF8ToUTF16(suggestion_pb.title()); + tile.url = url; + tile.source = NTPTileSource::SUGGESTIONS_SERVICE; + tile.whitelist_icon_path = GetWhitelistLargeIconPath(url); - suggestions.push_back(std::move(generated_suggestion)); + tiles.push_back(std::move(tile)); } - received_most_visited_sites_ = true; - mv_source_ = SUGGESTIONS_SERVICE; - SaveNewSuggestions(std::move(suggestions)); + waiting_for_most_visited_sites_ = false; + mv_source_ = NTPTileSource::SUGGESTIONS_SERVICE; + SaveNewTiles(std::move(tiles)); NotifyMostVisitedURLsObserver(); } -MostVisitedSites::SuggestionsVector -MostVisitedSites::CreateWhitelistEntryPointSuggestions( - const SuggestionsVector& personal_suggestions) { - size_t num_personal_suggestions = personal_suggestions.size(); - DCHECK_LE(num_personal_suggestions, static_cast<size_t>(num_sites_)); +NTPTilesVector MostVisitedSites::CreateWhitelistEntryPointTiles( + const NTPTilesVector& personal_tiles) { + if (!supervisor_) { + return NTPTilesVector(); + } + + size_t num_personal_tiles = personal_tiles.size(); + DCHECK_LE(num_personal_tiles, static_cast<size_t>(num_sites_)); - size_t num_whitelist_suggestions = num_sites_ - num_personal_suggestions; - SuggestionsVector whitelist_suggestions; + size_t num_whitelist_tiles = num_sites_ - num_personal_tiles; + NTPTilesVector whitelist_tiles; std::set<std::string> personal_hosts; - for (const auto& suggestion : personal_suggestions) - personal_hosts.insert(suggestion.url.host()); + for (const auto& tile : personal_tiles) + personal_hosts.insert(tile.url.host()); for (const auto& whitelist : supervisor_->whitelists()) { // Skip blacklisted sites. if (top_sites_ && top_sites_->IsBlacklisted(whitelist.entry_point)) continue; - // Skip suggestions already present. + // Skip tiles already present. if (personal_hosts.find(whitelist.entry_point.host()) != personal_hosts.end()) continue; @@ -433,127 +400,118 @@ MostVisitedSites::CreateWhitelistEntryPointSuggestions( if (supervisor_->IsBlocked(whitelist.entry_point)) continue; - Suggestion suggestion; - suggestion.title = whitelist.title; - suggestion.url = whitelist.entry_point; - suggestion.source = WHITELIST; - suggestion.whitelist_icon_path = whitelist.large_icon_path; + NTPTile tile; + tile.title = whitelist.title; + tile.url = whitelist.entry_point; + tile.source = NTPTileSource::WHITELIST; + tile.whitelist_icon_path = whitelist.large_icon_path; - whitelist_suggestions.push_back(std::move(suggestion)); - if (whitelist_suggestions.size() >= num_whitelist_suggestions) + whitelist_tiles.push_back(std::move(tile)); + if (whitelist_tiles.size() >= num_whitelist_tiles) break; } - return whitelist_suggestions; + return whitelist_tiles; } -MostVisitedSites::SuggestionsVector -MostVisitedSites::CreatePopularSitesSuggestions( - const SuggestionsVector& personal_suggestions, - const SuggestionsVector& whitelist_suggestions) { - // For child accounts popular sites suggestions will not be added. - if (supervisor_->IsChildProfile()) - return SuggestionsVector(); +NTPTilesVector MostVisitedSites::CreatePopularSitesTiles( + const NTPTilesVector& personal_tiles, + const NTPTilesVector& whitelist_tiles) { + // For child accounts popular sites tiles will not be added. + if (supervisor_ && supervisor_->IsChildProfile()) + return NTPTilesVector(); - size_t num_suggestions = - personal_suggestions.size() + whitelist_suggestions.size(); - DCHECK_LE(num_suggestions, static_cast<size_t>(num_sites_)); + size_t num_tiles = personal_tiles.size() + whitelist_tiles.size(); + DCHECK_LE(num_tiles, static_cast<size_t>(num_sites_)); // Collect non-blacklisted popular suggestions, skipping those already present // in the personal suggestions. - size_t num_popular_sites_suggestions = num_sites_ - num_suggestions; - SuggestionsVector popular_sites_suggestions; + size_t num_popular_sites_tiles = num_sites_ - num_tiles; + NTPTilesVector popular_sites_tiles; - if (num_popular_sites_suggestions > 0 && popular_sites_) { + if (num_popular_sites_tiles > 0 && popular_sites_) { std::set<std::string> hosts; - for (const auto& suggestion : personal_suggestions) - hosts.insert(suggestion.url.host()); - for (const auto& suggestion : whitelist_suggestions) - hosts.insert(suggestion.url.host()); + for (const auto& tile : personal_tiles) + hosts.insert(tile.url.host()); + for (const auto& tile : whitelist_tiles) + hosts.insert(tile.url.host()); for (const PopularSites::Site& popular_site : popular_sites_->sites()) { // Skip blacklisted sites. if (top_sites_ && top_sites_->IsBlacklisted(popular_site.url)) continue; std::string host = popular_site.url.host(); - // Skip suggestions already present in personal or whitelists. + // Skip tiles already present in personal or whitelists. if (hosts.find(host) != hosts.end()) continue; - Suggestion suggestion; - suggestion.title = popular_site.title; - suggestion.url = GURL(popular_site.url); - suggestion.source = POPULAR; + NTPTile tile; + tile.title = popular_site.title; + tile.url = GURL(popular_site.url); + tile.source = NTPTileSource::POPULAR; - popular_sites_suggestions.push_back(std::move(suggestion)); - if (popular_sites_suggestions.size() >= num_popular_sites_suggestions) + popular_sites_tiles.push_back(std::move(tile)); + if (popular_sites_tiles.size() >= num_popular_sites_tiles) break; } } - return popular_sites_suggestions; + return popular_sites_tiles; } -void MostVisitedSites::SaveNewSuggestions( - SuggestionsVector personal_suggestions) { - SuggestionsVector whitelist_suggestions = - CreateWhitelistEntryPointSuggestions(personal_suggestions); - SuggestionsVector popular_sites_suggestions = - CreatePopularSitesSuggestions(personal_suggestions, - whitelist_suggestions); - - size_t num_actual_tiles = personal_suggestions.size() + - whitelist_suggestions.size() + - popular_sites_suggestions.size(); +void MostVisitedSites::SaveNewTiles(NTPTilesVector personal_tiles) { + NTPTilesVector whitelist_tiles = + CreateWhitelistEntryPointTiles(personal_tiles); + NTPTilesVector popular_sites_tiles = + CreatePopularSitesTiles(personal_tiles, whitelist_tiles); + + size_t num_actual_tiles = personal_tiles.size() + whitelist_tiles.size() + + popular_sites_tiles.size(); DCHECK_LE(num_actual_tiles, static_cast<size_t>(num_sites_)); - current_suggestions_ = MergeSuggestions(std::move(personal_suggestions), - std::move(whitelist_suggestions), - std::move(popular_sites_suggestions)); - DCHECK_EQ(num_actual_tiles, current_suggestions_.size()); + current_tiles_ = + MergeTiles(std::move(personal_tiles), std::move(whitelist_tiles), + std::move(popular_sites_tiles)); + DCHECK_EQ(num_actual_tiles, current_tiles_.size()); - if (received_popular_sites_) - SaveCurrentSuggestionsToPrefs(); + int num_personal_tiles = 0; + for (const auto& tile : current_tiles_) { + if (tile.source != NTPTileSource::POPULAR) + num_personal_tiles++; + } + prefs_->SetInteger(prefs::kNumPersonalTiles, num_personal_tiles); + // TODO(treib): Remove after M55. + prefs_->ClearPref(prefs::kDeprecatedNTPTilesIsPersonal); + prefs_->ClearPref(prefs::kDeprecatedNTPTilesURL); } // static -MostVisitedSites::SuggestionsVector MostVisitedSites::MergeSuggestions( - SuggestionsVector personal_suggestions, - SuggestionsVector whitelist_suggestions, - SuggestionsVector popular_suggestions) { - SuggestionsVector merged_suggestions; - AppendSuggestions(std::move(personal_suggestions), &merged_suggestions); - AppendSuggestions(std::move(whitelist_suggestions), &merged_suggestions); - AppendSuggestions(std::move(popular_suggestions), &merged_suggestions); - return merged_suggestions; -} - -void MostVisitedSites::SaveCurrentSuggestionsToPrefs() { - base::ListValue url_list; - base::ListValue source_list; - for (const auto& suggestion : current_suggestions_) { - url_list.AppendString(suggestion.url.spec()); - source_list.AppendBoolean(suggestion.source != POPULAR); - } - prefs_->Set(ntp_tiles::prefs::kNTPSuggestionsIsPersonal, source_list); - prefs_->Set(ntp_tiles::prefs::kNTPSuggestionsURL, url_list); +NTPTilesVector MostVisitedSites::MergeTiles(NTPTilesVector personal_tiles, + NTPTilesVector whitelist_tiles, + NTPTilesVector popular_tiles) { + NTPTilesVector merged_tiles; + std::move(personal_tiles.begin(), personal_tiles.end(), + std::back_inserter(merged_tiles)); + std::move(whitelist_tiles.begin(), whitelist_tiles.end(), + std::back_inserter(merged_tiles)); + std::move(popular_tiles.begin(), popular_tiles.end(), + std::back_inserter(merged_tiles)); + return merged_tiles; } void MostVisitedSites::NotifyMostVisitedURLsObserver() { - if (received_most_visited_sites_ && received_popular_sites_ && + if (!waiting_for_most_visited_sites_ && !waiting_for_popular_sites_ && !recorded_uma_) { RecordImpressionUMAMetrics(); - UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.NumberOfTiles", - current_suggestions_.size()); recorded_uma_ = true; } if (!observer_) return; - observer_->OnMostVisitedURLsAvailable(current_suggestions_); + observer_->OnMostVisitedURLsAvailable(current_tiles_); } void MostVisitedSites::OnPopularSitesAvailable(bool success) { - received_popular_sites_ = true; + waiting_for_popular_sites_ = false; if (!success) { LOG(WARNING) << "Download of popular sites failed"; @@ -564,15 +522,21 @@ void MostVisitedSites::OnPopularSitesAvailable(bool success) { // missing icons, but will *not* cause it to display the popular sites. observer_->OnPopularURLsAvailable(popular_sites_->sites()); - // Re-build the suggestions list. Once done, this will notify the observer. - BuildCurrentSuggestions(); + // Re-build the tile list. Once done, this will notify the observer. + BuildCurrentTiles(); } void MostVisitedSites::RecordImpressionUMAMetrics() { - for (size_t i = 0; i < current_suggestions_.size(); i++) { + UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.NumberOfTiles", + current_tiles_.size()); + + for (size_t i = 0; i < current_tiles_.size(); i++) { + UMA_HISTOGRAM_ENUMERATION( + "NewTabPage.SuggestionsImpression", static_cast<int>(i), num_sites_); + std::string histogram = base::StringPrintf( "NewTabPage.SuggestionsImpression.%s", - GetSourceHistogramNameFromSuggestion(current_suggestions_[i]).c_str()); + GetSourceHistogramName(current_tiles_[i].source).c_str()); LogHistogramEvent(histogram, static_cast<int>(i), num_sites_); } } @@ -581,8 +545,8 @@ void MostVisitedSites::TopSitesLoaded(TopSites* top_sites) {} void MostVisitedSites::TopSitesChanged(TopSites* top_sites, ChangeReason change_reason) { - if (mv_source_ == TOP_SITES) { - // The displayed suggestions are invalidated. + if (mv_source_ == NTPTileSource::TOP_SITES) { + // The displayed tiles are invalidated. InitiateTopSitesQuery(); } } diff --git a/chromium/components/ntp_tiles/most_visited_sites.h b/chromium/components/ntp_tiles/most_visited_sites.h index efbae53ff45..28f9b070df0 100644 --- a/chromium/components/ntp_tiles/most_visited_sites.h +++ b/chromium/components/ntp_tiles/most_visited_sites.h @@ -8,7 +8,6 @@ #include <stddef.h> #include <memory> -#include <string> #include <vector> #include "base/compiler_specific.h" @@ -16,33 +15,23 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" +#include "base/strings/string16.h" #include "components/history/core/browser/history_types.h" #include "components/history/core/browser/top_sites_observer.h" +#include "components/ntp_tiles/ntp_tile.h" #include "components/ntp_tiles/popular_sites.h" #include "components/suggestions/proto/suggestions.pb.h" #include "components/suggestions/suggestions_service.h" #include "url/gurl.h" -namespace gfx { -class Image; -} - namespace history { class TopSites; } -namespace suggestions { -class SuggestionsService; -} - namespace user_prefs { class PrefRegistrySyncable; } -namespace variations { -class VariationsService; -} - namespace ntp_tiles { // Shim interface for SupervisedUserService. @@ -71,7 +60,7 @@ class MostVisitedSitesSupervisor { // If true, |url| should not be shown on the NTP. virtual bool IsBlocked(const GURL& url) = 0; - // Explicit suggestions for sites to show on NTP. + // Explicitly-specified sites to show on NTP. virtual std::vector<Whitelist> whitelists() = 0; // If true, be conservative about suggesting sites from outside sources. @@ -91,8 +80,6 @@ class MostVisitedSitesSupervisor { class MostVisitedSites : public history::TopSitesObserver, public MostVisitedSitesSupervisor::Observer { public: - struct Suggestion; - using SuggestionsVector = std::vector<Suggestion>; using PopularSitesVector = std::vector<PopularSites::Site>; // The visual type of a most visited tile. @@ -114,79 +101,39 @@ class MostVisitedSites : public history::TopSitesObserver, NUM_TILE_TYPES, }; - // The source of the Most Visited sites. - // A Java counterpart will be generated for this enum. - // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.ntp - enum MostVisitedSource { - // Item comes from the personal top sites list. - TOP_SITES, - // Item comes from the suggestions service. - SUGGESTIONS_SERVICE, - // Item is regionally popular. - POPULAR, - // Item is on an custodian-managed whitelist. - WHITELIST - }; - // The observer to be notified when the list of most visited sites changes. class Observer { public: - virtual void OnMostVisitedURLsAvailable( - const SuggestionsVector& suggestions) = 0; - virtual void OnPopularURLsAvailable(const PopularSitesVector& sites) = 0; + virtual void OnMostVisitedURLsAvailable(const NTPTilesVector& tiles) = 0; + virtual void OnPopularURLsAvailable(const PopularSitesVector& sites) {} protected: virtual ~Observer() {} }; - struct Suggestion { - base::string16 title; - GURL url; - MostVisitedSource source; - - // Only valid for source == WHITELIST (empty otherwise). - base::FilePath whitelist_icon_path; - - // Only valid for source == SUGGESTIONS_SERVICE (-1 otherwise). - int provider_index; - - Suggestion(); - ~Suggestion(); - - Suggestion(Suggestion&&); - Suggestion& operator=(Suggestion&&); - - private: - DISALLOW_COPY_AND_ASSIGN(Suggestion); - }; - - MostVisitedSites(scoped_refptr<base::SequencedWorkerPool> blocking_pool, - PrefService* prefs, - const TemplateURLService* template_url_service, - variations::VariationsService* variations_service, - net::URLRequestContextGetter* download_context, - const base::FilePath& popular_sites_directory, + // Construct a MostVisitedSites instance. + // + // |prefs| and |suggestions| are required and may not be null. |top_sites|, + // |popular_sites|, and |supervisor| are optional and if null the associated + // features will be disabled. + MostVisitedSites(PrefService* prefs, scoped_refptr<history::TopSites> top_sites, suggestions::SuggestionsService* suggestions, + std::unique_ptr<PopularSites> popular_sites, MostVisitedSitesSupervisor* supervisor); ~MostVisitedSites() override; -#if defined(OS_ANDROID) - static bool Register(JNIEnv* env); -#endif - // Does not take ownership of |observer|, which must outlive this object and // must not be null. void SetMostVisitedURLsObserver(Observer* observer, int num_sites); - using ThumbnailCallback = base::Callback< - void(bool /* is_local_thumbnail */, const SkBitmap* /* bitmap */)>; void AddOrRemoveBlacklistedUrl(const GURL& url, bool add_url); - void RecordTileTypeMetrics(const std::vector<int>& tile_types, - const std::vector<int>& sources, - const std::vector<int>& provider_indices); - void RecordOpenedMostVisitedItem(int index, int tile_type); + void RecordTileTypeMetrics(const std::vector<MostVisitedTileType>& tile_types, + const std::vector<NTPTileSource>& sources); + void RecordOpenedMostVisitedItem(int index, + MostVisitedTileType tile_type, + NTPTileSource source); // MostVisitedSitesSupervisor::Observer implementation. void OnBlockedSitesChanged() override; @@ -196,7 +143,7 @@ class MostVisitedSites : public history::TopSitesObserver, private: friend class MostVisitedSitesTest; - void BuildCurrentSuggestions(); + void BuildCurrentTiles(); // Initialize the query to Top Sites. Called if the SuggestionsService // returned no data. @@ -215,37 +162,30 @@ class MostVisitedSites : public history::TopSitesObserver, // Takes the personal suggestions and creates whitelist entry point // suggestions if necessary. - SuggestionsVector CreateWhitelistEntryPointSuggestions( - const SuggestionsVector& personal_suggestions); - - // Takes the personal and whitelist suggestions and creates popular - // suggestions if necessary. - SuggestionsVector CreatePopularSitesSuggestions( - const SuggestionsVector& personal_suggestions, - const SuggestionsVector& whitelist_suggestions); + NTPTilesVector CreateWhitelistEntryPointTiles( + const NTPTilesVector& personal_tiles); - // Takes the personal suggestions, creates and merges in whitelist and popular - // suggestions if appropriate, and saves the new suggestions. - void SaveNewSuggestions(SuggestionsVector personal_suggestions); + // Takes the personal and whitelist tiles and creates popular tiles if + // necessary. + NTPTilesVector CreatePopularSitesTiles(const NTPTilesVector& personal_tiles, + const NTPTilesVector& whitelist_tiles); - // Workhorse for SaveNewSuggestions above. Implemented as a separate static - // method for ease of testing. - static SuggestionsVector MergeSuggestions( - SuggestionsVector personal_suggestions, - SuggestionsVector whitelist_suggestions, - SuggestionsVector popular_suggestions); + // Takes the personal tiles, creates and merges in whitelist and popular tiles + // if appropriate, and saves the new tiles. + void SaveNewTiles(NTPTilesVector personal_tiles); - void SaveCurrentSuggestionsToPrefs(); + // Workhorse for SaveNewTiles above. Implemented as a separate static method + // for ease of testing. + static NTPTilesVector MergeTiles(NTPTilesVector personal_tiles, + NTPTilesVector whitelist_tiles, + NTPTilesVector popular_tiles); - // Notifies the observer about the availability of suggestions. + // Notifies the observer about the availability of tiles. // Also records impressions UMA if not done already. void NotifyMostVisitedURLsObserver(); void OnPopularSitesAvailable(bool success); - // Records thumbnail-related UMA histogram metrics. - void RecordThumbnailUMAMetrics(); - // Records UMA histogram metrics related to the number of impressions. void RecordImpressionUMAMetrics(); @@ -255,12 +195,9 @@ class MostVisitedSites : public history::TopSitesObserver, ChangeReason change_reason) override; PrefService* prefs_; - const TemplateURLService* template_url_service_; - variations::VariationsService* variations_service_; - net::URLRequestContextGetter* download_context_; - base::FilePath popular_sites_directory_; scoped_refptr<history::TopSites> top_sites_; suggestions::SuggestionsService* suggestions_service_; + std::unique_ptr<PopularSites> const popular_sites_; MostVisitedSitesSupervisor* supervisor_; Observer* observer_; @@ -268,15 +205,15 @@ class MostVisitedSites : public history::TopSitesObserver, // The maximum number of most visited sites to return. int num_sites_; - // Whether we have received an initial set of most visited sites (from either - // TopSites or the SuggestionsService). - bool received_most_visited_sites_; + // True if we are still waiting for an initial set of most visited sites (from + // either TopSites or the SuggestionsService). + bool waiting_for_most_visited_sites_; - // Whether we have received the set of popular sites. Immediately set to true - // if popular sites are disabled. - bool received_popular_sites_; + // True if we are still waiting for the set of popular sites. Immediately set + // to false if popular sites are disabled, or are not required. + bool waiting_for_popular_sites_; - // Whether we have recorded one-shot UMA metrics such as impressions. They are + // True if we have recorded one-shot UMA metrics such as impressions. They are // recorded once both the previous flags are true. bool recorded_uma_; @@ -284,17 +221,13 @@ class MostVisitedSites : public history::TopSitesObserver, suggestions::SuggestionsService::ResponseCallbackList::Subscription> suggestions_subscription_; - ScopedObserver<history::TopSites, history::TopSitesObserver> scoped_observer_; - - MostVisitedSource mv_source_; - - std::unique_ptr<PopularSites> popular_sites_; + ScopedObserver<history::TopSites, history::TopSitesObserver> + top_sites_observer_; - SuggestionsVector current_suggestions_; + // The main source of personal tiles - either TOP_SITES or SUGGESTIONS_SEVICE. + NTPTileSource mv_source_; - base::ThreadChecker thread_checker_; - scoped_refptr<base::SequencedWorkerPool> blocking_pool_; - scoped_refptr<base::TaskRunner> blocking_runner_; + NTPTilesVector current_tiles_; // For callbacks may be run after destruction. base::WeakPtrFactory<MostVisitedSites> weak_ptr_factory_; diff --git a/chromium/components/ntp_tiles/most_visited_sites_unittest.cc b/chromium/components/ntp_tiles/most_visited_sites_unittest.cc index e88f518f648..6fbc9dcd087 100644 --- a/chromium/components/ntp_tiles/most_visited_sites_unittest.cc +++ b/chromium/components/ntp_tiles/most_visited_sites_unittest.cc @@ -36,13 +36,13 @@ static const size_t kNumSites = 4; } // namespace -// This a test for MostVisitedSites::MergeSuggestions(...) method, and thus has -// the same scope as the method itself. This tests merging popular suggestions -// with personal suggestions. +// This a test for MostVisitedSites::MergeTiles(...) method, and thus has the +// same scope as the method itself. This tests merging popular sites with +// personal tiles. // More important things out of the scope of testing presently: -// - Removing blacklisted suggestions. +// - Removing blacklisted tiles. // - Correct host extraction from the URL. -// - Ensuring personal suggestions are not duplicated in popular suggestions. +// - Ensuring personal tiles are not duplicated in popular tiles. class MostVisitedSitesTest : public testing::Test { protected: void Check(const std::vector<TitleURL>& popular_sites, @@ -50,42 +50,39 @@ class MostVisitedSitesTest : public testing::Test { const std::vector<TitleURL>& personal_sites, const std::vector<bool>& expected_sites_is_personal, const std::vector<TitleURL>& expected_sites) { - MostVisitedSites::SuggestionsVector personal_suggestions; + NTPTilesVector personal_tiles; for (const TitleURL& site : personal_sites) - personal_suggestions.push_back(MakeSuggestionFrom(site, true, false)); - MostVisitedSites::SuggestionsVector whitelist_suggestions; + personal_tiles.push_back(MakeTileFrom(site, true, false)); + NTPTilesVector whitelist_tiles; for (const TitleURL& site : whitelist_entry_points) - whitelist_suggestions.push_back(MakeSuggestionFrom(site, false, true)); - MostVisitedSites::SuggestionsVector popular_suggestions; + whitelist_tiles.push_back(MakeTileFrom(site, false, true)); + NTPTilesVector popular_tiles; for (const TitleURL& site : popular_sites) - popular_suggestions.push_back(MakeSuggestionFrom(site, false, false)); - MostVisitedSites::SuggestionsVector result_suggestions = - MostVisitedSites::MergeSuggestions(std::move(personal_suggestions), - std::move(whitelist_suggestions), - std::move(popular_suggestions)); + popular_tiles.push_back(MakeTileFrom(site, false, false)); + NTPTilesVector result_tiles = MostVisitedSites::MergeTiles( + std::move(personal_tiles), std::move(whitelist_tiles), + std::move(popular_tiles)); std::vector<TitleURL> result_sites; std::vector<bool> result_is_personal; - result_sites.reserve(result_suggestions.size()); - result_is_personal.reserve(result_suggestions.size()); - for (const auto& suggestion : result_suggestions) { - result_sites.push_back(TitleURL(suggestion.title, suggestion.url.spec())); - result_is_personal.push_back(suggestion.source != - MostVisitedSites::POPULAR); + result_sites.reserve(result_tiles.size()); + result_is_personal.reserve(result_tiles.size()); + for (const auto& tile : result_tiles) { + result_sites.push_back(TitleURL(tile.title, tile.url.spec())); + result_is_personal.push_back(tile.source != NTPTileSource::POPULAR); } EXPECT_EQ(expected_sites_is_personal, result_is_personal); EXPECT_EQ(expected_sites, result_sites); } - static MostVisitedSites::Suggestion MakeSuggestionFrom( - const TitleURL& title_url, - bool is_personal, - bool whitelist) { - MostVisitedSites::Suggestion suggestion; - suggestion.title = title_url.title; - suggestion.url = GURL(title_url.url); - suggestion.source = whitelist ? MostVisitedSites::WHITELIST - : (is_personal ? MostVisitedSites::TOP_SITES - : MostVisitedSites::POPULAR); - return suggestion; + static NTPTile MakeTileFrom(const TitleURL& title_url, + bool is_personal, + bool whitelist) { + NTPTile tile; + tile.title = title_url.title; + tile.url = GURL(title_url.url); + tile.source = whitelist ? NTPTileSource::WHITELIST + : (is_personal ? NTPTileSource::TOP_SITES + : NTPTileSource::POPULAR); + return tile; } }; @@ -96,8 +93,8 @@ TEST_F(MostVisitedSitesTest, PersonalSites) { TitleURL("Site 3", "https://www.site3.com/"), TitleURL("Site 4", "https://www.site4.com/"), }; - // Without any popular suggestions, the result after merge should be the - // personal suggestions. + // Without any popular tiles, the result after merge should be the personal + // tiles. std::vector<bool> expected_sites_source(kNumSites, true /*personal source*/); Check(std::vector<TitleURL>(), std::vector<TitleURL>(), personal_sites, expected_sites_source, personal_sites); @@ -110,8 +107,8 @@ TEST_F(MostVisitedSitesTest, PopularSites) { TitleURL("Site 3", "https://www.site3.com/"), TitleURL("Site 4", "https://www.site4.com/"), }; - // Without any personal suggestions, the result after merge should be the - // popular suggestions. + // Without any personal tiles, the result after merge should be the popular + // tiles. std::vector<bool> expected_sites_source(kNumSites, false /*popular source*/); Check(popular_sites, std::vector<TitleURL>(), std::vector<TitleURL>(), expected_sites_source, popular_sites); @@ -126,7 +123,7 @@ TEST_F(MostVisitedSitesTest, PersonalPrecedePopularSites) { TitleURL("Site 3", "https://www.site3.com/"), TitleURL("Site 4", "https://www.site4.com/"), }; - // Personal suggestions should precede popular suggestions. + // Personal tiles should precede popular tiles. std::vector<TitleURL> expected_sites{ TitleURL("Site 3", "https://www.site3.com/"), TitleURL("Site 4", "https://www.site4.com/"), diff --git a/chromium/components/ntp_tiles/ntp_tile.cc b/chromium/components/ntp_tiles/ntp_tile.cc new file mode 100644 index 00000000000..ece28625aa4 --- /dev/null +++ b/chromium/components/ntp_tiles/ntp_tile.cc @@ -0,0 +1,15 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/ntp_tiles/ntp_tile.h" + +namespace ntp_tiles { + +NTPTile::NTPTile() : source(NTPTileSource::TOP_SITES) {} + +NTPTile::NTPTile(const NTPTile&) = default; + +NTPTile::~NTPTile() {} + +} // namespace ntp_tiles diff --git a/chromium/components/ntp_tiles/ntp_tile.h b/chromium/components/ntp_tiles/ntp_tile.h new file mode 100644 index 00000000000..ef228b54b38 --- /dev/null +++ b/chromium/components/ntp_tiles/ntp_tile.h @@ -0,0 +1,49 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_NTP_TILES_NTP_TILE_H_ +#define COMPONENTS_NTP_TILES_NTP_TILE_H_ + +#include <vector> + +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/strings/string16.h" +#include "url/gurl.h" + +namespace ntp_tiles { + +// The source of an NTP tile. +// A Java counterpart will be generated for this enum. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.ntp +enum class NTPTileSource { + // Tile comes from the personal top sites list, based on local history. + TOP_SITES, + // Tile comes from the suggestions service, based on synced history. + SUGGESTIONS_SERVICE, + // Tile is regionally popular. + POPULAR, + // Tile is on an custodian-managed whitelist. + WHITELIST +}; + +// A suggested site shown on the New Tab Page. +struct NTPTile { + base::string16 title; + GURL url; + NTPTileSource source; + + // Only valid for source == WHITELIST (empty otherwise). + base::FilePath whitelist_icon_path; + + NTPTile(); + NTPTile(const NTPTile&); + ~NTPTile(); +}; + +using NTPTilesVector = std::vector<NTPTile>; + +} // namespace ntp_tiles + +#endif // COMPONENTS_NTP_TILES_NTP_TILE_H_ diff --git a/chromium/components/ntp_tiles/popular_sites.cc b/chromium/components/ntp_tiles/popular_sites.cc index 88cccff2876..a24b7aa4eb3 100644 --- a/chromium/components/ntp_tiles/popular_sites.cc +++ b/chromium/components/ntp_tiles/popular_sites.cc @@ -19,13 +19,13 @@ #include "base/task_runner_util.h" #include "base/time/time.h" #include "base/values.h" +#include "components/data_use_measurement/core/data_use_user_data.h" #include "components/google/core/browser/google_util.h" #include "components/ntp_tiles/constants.h" #include "components/ntp_tiles/pref_names.h" #include "components/ntp_tiles/switches.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" -#include "components/safe_json/safe_json_parser.h" #include "components/search_engines/search_engine_type.h" #include "components/search_engines/template_url_service.h" #include "components/variations/service/variations_service.h" @@ -177,18 +177,27 @@ PopularSites::PopularSites( VariationsService* variations_service, net::URLRequestContextGetter* download_context, const base::FilePath& directory, - bool force_download, - const FinishedCallback& callback) - : callback_(callback), - is_fallback_(false), + ParseJSONCallback parse_json) + : blocking_runner_(blocking_pool->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)), + prefs_(prefs), + template_url_service_(template_url_service), + variations_(variations_service), + download_context_(download_context), local_path_(directory.empty() ? base::FilePath() : directory.AppendASCII(kPopularSitesLocalFilename)), - prefs_(prefs), - download_context_(download_context), - blocking_runner_(blocking_pool->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)), - weak_ptr_factory_(this) { + parse_json_(std::move(parse_json)), + is_fallback_(false), + weak_ptr_factory_(this) {} + +PopularSites::~PopularSites() {} + +void PopularSites::StartFetch(bool force_download, + const FinishedCallback& callback) { + DCHECK(!callback_); + callback_ = callback; + const base::Time last_download_time = base::Time::FromInternalValue( prefs_->GetInt64(kPopularSitesLastDownloadPref)); const base::TimeDelta time_since_last_download = @@ -198,11 +207,11 @@ PopularSites::PopularSites( const bool download_time_is_future = base::Time::Now() < last_download_time; const std::string country = - GetCountryToUse(prefs, template_url_service, variations_service); - const std::string version = GetVersionToUse(prefs); + GetCountryToUse(prefs_, template_url_service_, variations_); + const std::string version = GetVersionToUse(prefs_); const GURL override_url = - GURL(prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL)); + GURL(prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL)); pending_url_ = override_url.is_valid() ? override_url : GetPopularSitesURL(country, version); const bool url_changed = @@ -231,8 +240,6 @@ PopularSites::PopularSites( base::Passed(std::move(file_data)))); } -PopularSites::~PopularSites() {} - GURL PopularSites::LastURL() const { return GURL(prefs_->GetString(kPopularSitesURLPref)); } @@ -272,6 +279,9 @@ void PopularSites::OnReadFileDone(std::unique_ptr<std::string> data, void PopularSites::FetchPopularSites() { fetcher_ = URLFetcher::Create(pending_url_, URLFetcher::GET, this); + // TODO(sfiera): Count the downloaded bytes of icons fetched by popular sites. + data_use_measurement::DataUseUserData::AttachToFetcher( + fetcher_.get(), data_use_measurement::DataUseUserData::NTP_TILES); fetcher_->SetRequestContext(download_context_); fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); @@ -291,7 +301,7 @@ void PopularSites::OnURLFetchComplete(const net::URLFetcher* source) { return; } - safe_json::SafeJsonParser::Parse( + parse_json_.Run( json_string, base::Bind(&PopularSites::OnJsonParsed, weak_ptr_factory_.GetWeakPtr()), base::Bind(&PopularSites::OnJsonParseFailed, diff --git a/chromium/components/ntp_tiles/popular_sites.h b/chromium/components/ntp_tiles/popular_sites.h index 36237a391ab..639aedf4046 100644 --- a/chromium/components/ntp_tiles/popular_sites.h +++ b/chromium/components/ntp_tiles/popular_sites.h @@ -38,9 +38,14 @@ class TemplateURLService; namespace ntp_tiles { +using ParseJSONCallback = base::Callback<void( + const std::string& unsafe_json, + const base::Callback<void(std::unique_ptr<base::Value>)>& success_callback, + const base::Callback<void(const std::string&)>& error_callback)>; + // Downloads and provides a list of suggested popular sites, for display on -// the NTP when there are not enough personalized suggestions. Caches the -// downloaded file on disk to avoid re-downloading on every startup. +// the NTP when there are not enough personalized tiles. Caches the downloaded +// file on disk to avoid re-downloading on every startup. class PopularSites : public net::URLFetcherDelegate { public: struct Site { @@ -61,19 +66,24 @@ class PopularSites : public net::URLFetcherDelegate { using FinishedCallback = base::Callback<void(bool /* success */)>; - // When the suggestions have been fetched (from cache or URL) and parsed, - // invokes |callback|, on the same thread as the caller. - // - // Set |force_download| to enforce re-downloading the suggestions file, even - // if it already exists on disk. PopularSites(const scoped_refptr<base::SequencedWorkerPool>& blocking_pool, PrefService* prefs, const TemplateURLService* template_url_service, variations::VariationsService* variations_service, net::URLRequestContextGetter* download_context, const base::FilePath& directory, - bool force_download, - const FinishedCallback& callback); + ParseJSONCallback parse_json); + + // Starts the process of retrieving popular sites. When they are available, + // invokes |callback| with the result, on the same thread as the caller. Never + // invokes |callback| before returning control to the caller, even if the + // result is immediately known. + // + // Set |force_download| to enforce re-downloading the popular sites file, even + // if it already exists on disk. + // + // Must be called at most once on a given PopularSites object. + void StartFetch(bool force_download, const FinishedCallback& callback); ~PopularSites() override; @@ -104,19 +114,23 @@ class PopularSites : public net::URLFetcherDelegate { void ParseSiteList(std::unique_ptr<base::Value> json); void OnDownloadFailed(); + // Parameters set from constructor. + scoped_refptr<base::TaskRunner> const blocking_runner_; + PrefService* const prefs_; + const TemplateURLService* const template_url_service_; + variations::VariationsService* const variations_; + net::URLRequestContextGetter* const download_context_; + base::FilePath const local_path_; + ParseJSONCallback parse_json_; + + // Set by StartFetch() and called after fetch completes. FinishedCallback callback_; + std::unique_ptr<net::URLFetcher> fetcher_; bool is_fallback_; std::vector<Site> sites_; GURL pending_url_; - base::FilePath local_path_; - - PrefService* prefs_; - net::URLRequestContextGetter* download_context_; - - scoped_refptr<base::TaskRunner> blocking_runner_; - base::WeakPtrFactory<PopularSites> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(PopularSites); diff --git a/chromium/components/ntp_tiles/pref_names.cc b/chromium/components/ntp_tiles/pref_names.cc index dd72edbf8f6..1ec52196efa 100644 --- a/chromium/components/ntp_tiles/pref_names.cc +++ b/chromium/components/ntp_tiles/pref_names.cc @@ -7,12 +7,12 @@ namespace ntp_tiles { namespace prefs { -// Ordered list of website suggestions shown on the new tab page that will allow -// retaining the order even if the suggestions change over time. -const char kNTPSuggestionsURL[] = "ntp.suggestions_url"; +const char kDeprecatedNTPTilesURL[] = "ntp.suggestions_url"; +const char kDeprecatedNTPTilesIsPersonal[] = "ntp.suggestions_is_personal"; -// Whether the suggestion was derived from personal data. -const char kNTPSuggestionsIsPersonal[] = "ntp.suggestions_is_personal"; +// The number of personal tiles we had previously. Used to figure out +// whether we need popular sites. +const char kNumPersonalTiles[] = "ntp.num_personal_suggestions"; // If set, overrides the URL for popular sites, including the individual // overrides for country and version below. diff --git a/chromium/components/ntp_tiles/pref_names.h b/chromium/components/ntp_tiles/pref_names.h index d1ca404f734..243a5fa1e4b 100644 --- a/chromium/components/ntp_tiles/pref_names.h +++ b/chromium/components/ntp_tiles/pref_names.h @@ -8,8 +8,11 @@ namespace ntp_tiles { namespace prefs { -extern const char kNTPSuggestionsURL[]; -extern const char kNTPSuggestionsIsPersonal[]; +// TODO(treib): Remove after M55. +extern const char kDeprecatedNTPTilesURL[]; +extern const char kDeprecatedNTPTilesIsPersonal[]; + +extern const char kNumPersonalTiles[]; extern const char kPopularSitesOverrideURL[]; extern const char kPopularSitesOverrideCountry[]; |