diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-07-31 15:50:41 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 12:35:23 +0000 |
commit | 7b2ffa587235a47d4094787d72f38102089f402a (patch) | |
tree | 30e82af9cbab08a7fa028bb18f4f2987a3f74dfa /chromium/components/ntp_tiles | |
parent | d94af01c90575348c4e81a418257f254b6f8d225 (diff) | |
download | qtwebengine-chromium-7b2ffa587235a47d4094787d72f38102089f402a.tar.gz |
BASELINE: Update Chromium to 76.0.3809.94
Change-Id: I321c3f5f929c105aec0f98c5091ef6108822e647
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components/ntp_tiles')
20 files changed, 360 insertions, 301 deletions
diff --git a/chromium/components/ntp_tiles/BUILD.gn b/chromium/components/ntp_tiles/BUILD.gn index 33d2c608dba..244ad33d493 100644 --- a/chromium/components/ntp_tiles/BUILD.gn +++ b/chromium/components/ntp_tiles/BUILD.gn @@ -53,7 +53,6 @@ static_library("ntp_tiles") { "//components/suggestions", ] deps = [ - "//components/data_use_measurement/core", "//components/favicon/core", "//components/favicon_base", "//components/google/core/browser", @@ -72,22 +71,6 @@ static_library("ntp_tiles") { ] } -# If you want to use this, let us (ntp-dev@chromium.org) know. In that case, it -# should be moved to a more common location as it has 2+ callers already. -# Note that you probably shouldn't be using it outside of ios or tests. -source_set("json_unsafe_parser") { - testonly = !is_ios - - sources = [ - "json_unsafe_parser.cc", - "json_unsafe_parser.h", - ] - - public_deps = [ - "//base", - ] -} - source_set("unit_tests") { testonly = true sources = [ @@ -100,7 +83,6 @@ source_set("unit_tests") { ] deps = [ - ":json_unsafe_parser", ":ntp_tiles", "//base/test:test_support", "//components/favicon/core", @@ -112,6 +94,7 @@ source_set("unit_tests") { "//components/rappor:test_support", "//components/sync_preferences:test_support", "//net:test_support", + "//services/data_decoder/public/cpp:test_support", "//services/network:test_support", "//services/network/public/cpp", "//testing/gmock", diff --git a/chromium/components/ntp_tiles/DEPS b/chromium/components/ntp_tiles/DEPS index 18f2f118b9b..985869d766a 100644 --- a/chromium/components/ntp_tiles/DEPS +++ b/chromium/components/ntp_tiles/DEPS @@ -1,5 +1,4 @@ include_rules = [ - "+components/data_use_measurement/core", "+components/favicon", "+components/favicon_base", "+components/google/core", @@ -18,9 +17,9 @@ include_rules = [ "+components/variations", "+jni", "+net", + "+services/data_decoder/public/cpp/testing_json_parser.h", "+services/network/public/cpp", "+services/network/test", "+ui/gfx", "+ui/base", ] - diff --git a/chromium/components/ntp_tiles/OWNERS b/chromium/components/ntp_tiles/OWNERS index e5dfa00fed9..91a328f7120 100644 --- a/chromium/components/ntp_tiles/OWNERS +++ b/chromium/components/ntp_tiles/OWNERS @@ -1,4 +1,5 @@ fhorschig@chromium.org jkrcal@chromium.org +kristipark@chromium.org mastiz@chromium.org treib@chromium.org diff --git a/chromium/components/ntp_tiles/constants.cc b/chromium/components/ntp_tiles/constants.cc index b40488bcd09..ed849b2bf3c 100644 --- a/chromium/components/ntp_tiles/constants.cc +++ b/chromium/components/ntp_tiles/constants.cc @@ -4,23 +4,12 @@ #include "components/ntp_tiles/constants.h" -#include "base/feature_list.h" -#include "ui/base/ui_base_features.h" - namespace ntp_tiles { -const char kPopularSitesFieldTrialName[] = "NTPPopularSites"; - -const base::Feature kPopularSitesBakedInContentFeature{ - "NTPPopularSitesBakedInContent", base::FEATURE_ENABLED_BY_DEFAULT}; - -const base::Feature kNtpMostLikelyFaviconsFromServerFeature{ - "NTPMostLikelyFaviconsFromServer", base::FEATURE_ENABLED_BY_DEFAULT}; - -const base::Feature kSiteExplorationUiFeature{ - "SiteExplorationUi", base::FEATURE_DISABLED_BY_DEFAULT}; +const size_t kMaxNumCustomLinks = 10; -const base::Feature kUsePopularSitesSuggestions{ - "UsePopularSitesSuggestions", base::FEATURE_ENABLED_BY_DEFAULT}; +// Because the custom links feature has an additional "Add shortcut" button, 9 +// tiles are required to balance the Most Visited rows on the NTP. +const int kMaxNumMostVisited = 9; } // namespace ntp_tiles diff --git a/chromium/components/ntp_tiles/constants.h b/chromium/components/ntp_tiles/constants.h index 7395995f975..eb7a95f0b1a 100644 --- a/chromium/components/ntp_tiles/constants.h +++ b/chromium/components/ntp_tiles/constants.h @@ -5,29 +5,20 @@ #ifndef COMPONENTS_NTP_TILES_CONSTANTS_H_ #define COMPONENTS_NTP_TILES_CONSTANTS_H_ -namespace base { -struct Feature; -} // namespace base +#include <stddef.h> -namespace ntp_tiles { - -// Name of the field trial to configure PopularSites. -extern const char kPopularSitesFieldTrialName[]; +#include <utility> -// This feature is enabled by default. Otherwise, users who need it would not -// get the right configuration timely enough. The configuration affects only -// Android or iOS users. -extern const base::Feature kPopularSitesBakedInContentFeature; +namespace ntp_tiles { -// Feature to allow the new Google favicon server for fetching favicons for Most -// Likely tiles on the New Tab Page. -extern const base::Feature kNtpMostLikelyFaviconsFromServerFeature; +// Maximum number of custom links that can be set by the user. Used on desktop. +extern const size_t kMaxNumCustomLinks; -// Feature to provide site exploration tiles in addition to personal tiles. -extern const base::Feature kSiteExplorationUiFeature; +// Maximum number of Most Visited sites that will be generated. Used on desktop. +extern const int kMaxNumMostVisited; -// If this feature is enabled, we enable popular sites in the suggestions UI. -extern const base::Feature kUsePopularSitesSuggestions; +// Maximum number of tiles that can be shown on the NTP. +const int kMaxNumTiles = 10; } // namespace ntp_tiles diff --git a/chromium/components/ntp_tiles/custom_links_manager_impl.cc b/chromium/components/ntp_tiles/custom_links_manager_impl.cc index 75bca9b0393..32b562a39d1 100644 --- a/chromium/components/ntp_tiles/custom_links_manager_impl.cc +++ b/chromium/components/ntp_tiles/custom_links_manager_impl.cc @@ -10,18 +10,13 @@ #include "base/auto_reset.h" #include "base/bind.h" +#include "components/ntp_tiles/constants.h" #include "components/ntp_tiles/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" namespace ntp_tiles { -namespace { - -const int kMaxNumLinks = 10; - -} // namespace - CustomLinksManagerImpl::CustomLinksManagerImpl( PrefService* prefs, history::HistoryService* history_service) @@ -80,7 +75,7 @@ const std::vector<CustomLinksManager::Link>& CustomLinksManagerImpl::GetLinks() bool CustomLinksManagerImpl::AddLink(const GURL& url, const base::string16& title) { if (!IsInitialized() || !url.is_valid() || - current_links_.size() == kMaxNumLinks) { + current_links_.size() == ntp_tiles::kMaxNumCustomLinks) { return false; } diff --git a/chromium/components/ntp_tiles/features.cc b/chromium/components/ntp_tiles/features.cc index d1f3c33814c..0ea51f0746e 100644 --- a/chromium/components/ntp_tiles/features.cc +++ b/chromium/components/ntp_tiles/features.cc @@ -9,6 +9,17 @@ namespace ntp_tiles { +const char kPopularSitesFieldTrialName[] = "NTPPopularSites"; + +const base::Feature kPopularSitesBakedInContentFeature{ + "NTPPopularSitesBakedInContent", base::FEATURE_ENABLED_BY_DEFAULT}; + +const base::Feature kNtpMostLikelyFaviconsFromServerFeature{ + "NTPMostLikelyFaviconsFromServer", base::FEATURE_ENABLED_BY_DEFAULT}; + +const base::Feature kUsePopularSitesSuggestions{ + "UsePopularSitesSuggestions", base::FEATURE_ENABLED_BY_DEFAULT}; + const base::Feature kDefaultSearchShortcut{"DefaultSearchShortcut", base::FEATURE_DISABLED_BY_DEFAULT}; diff --git a/chromium/components/ntp_tiles/features.h b/chromium/components/ntp_tiles/features.h index 0c60cfc0d7b..39dc61dcdb2 100644 --- a/chromium/components/ntp_tiles/features.h +++ b/chromium/components/ntp_tiles/features.h @@ -11,6 +11,21 @@ struct Feature; namespace ntp_tiles { +// Name of the field trial to configure PopularSites. +extern const char kPopularSitesFieldTrialName[]; + +// This feature is enabled by default. Otherwise, users who need it would not +// get the right configuration timely enough. The configuration affects only +// Android or iOS users. +extern const base::Feature kPopularSitesBakedInContentFeature; + +// Feature to allow the new Google favicon server for fetching favicons for Most +// Likely tiles on the New Tab Page. +extern const base::Feature kNtpMostLikelyFaviconsFromServerFeature; + +// If this feature is enabled, we enable popular sites in the suggestions UI. +extern const base::Feature kUsePopularSitesSuggestions; + // If enabled, show a Google search shortcut on the NTP by default. extern const base::Feature kDefaultSearchShortcut; diff --git a/chromium/components/ntp_tiles/icon_cacher_impl.cc b/chromium/components/ntp_tiles/icon_cacher_impl.cc index a4a62030462..aadc7ddc205 100644 --- a/chromium/components/ntp_tiles/icon_cacher_impl.cc +++ b/chromium/components/ntp_tiles/icon_cacher_impl.cc @@ -18,7 +18,7 @@ #include "components/favicon_base/favicon_util.h" #include "components/image_fetcher/core/image_decoder.h" #include "components/image_fetcher/core/image_fetcher.h" -#include "components/ntp_tiles/constants.h" +#include "components/ntp_tiles/features.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/geometry/size.h" @@ -270,7 +270,8 @@ void IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished( page_url, GetMinimumFetchingSizeForChromeSuggestionsFaviconsFromServer(), GetDesiredFetchingSizeForChromeSuggestionsFaviconsFromServer()), - /*may_page_url_be_private=*/true, traffic_annotation, + /*may_page_url_be_private=*/true, /*should_trim_page_url_path=*/false, + traffic_annotation, base::Bind(&IconCacherImpl::OnMostLikelyFaviconDownloaded, weak_ptr_factory_.GetWeakPtr(), page_url)); } diff --git a/chromium/components/ntp_tiles/json_unsafe_parser.cc b/chromium/components/ntp_tiles/json_unsafe_parser.cc deleted file mode 100644 index e1281f00050..00000000000 --- a/chromium/components/ntp_tiles/json_unsafe_parser.cc +++ /dev/null @@ -1,41 +0,0 @@ -// 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/json_unsafe_parser.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "base/json/json_parser.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/values.h" - -namespace ntp_tiles { - -void JsonUnsafeParser::Parse(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce( - [](const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) { - std::string error_msg; - int error_line, error_column; - std::unique_ptr<base::Value> value = - base::JSONReader::ReadAndReturnErrorDeprecated( - unsafe_json, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, - &error_msg, &error_line, &error_column); - if (value) { - success_callback.Run(std::move(value)); - } else { - error_callback.Run(base::StringPrintf( - "%s (%d:%d)", error_msg.c_str(), error_line, error_column)); - } - }, - unsafe_json, success_callback, error_callback)); -} - -} // namespace ntp_tiles diff --git a/chromium/components/ntp_tiles/json_unsafe_parser.h b/chromium/components/ntp_tiles/json_unsafe_parser.h deleted file mode 100644 index 4a5a1f47dcd..00000000000 --- a/chromium/components/ntp_tiles/json_unsafe_parser.h +++ /dev/null @@ -1,40 +0,0 @@ -// 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_JSON_UNSAFE_PARSER_H_ -#define COMPONENTS_NTP_TILES_JSON_UNSAFE_PARSER_H_ - -#include <memory> -#include <string> - -#include "base/callback_forward.h" - -namespace base { -class Value; -} - -namespace ntp_tiles { - -// Mimics SafeJsonParser, but parses unsafely. -// -// Do not use this class, unless you can't help it. On most platforms, -// SafeJsonParser is available and is safer. If it is not available (e.g. on -// iOS), then this class mimics its API without its safety. -class JsonUnsafeParser { - public: - using SuccessCallback = base::Callback<void(std::unique_ptr<base::Value>)>; - using ErrorCallback = base::Callback<void(const std::string&)>; - - // As with SafeJsonParser, runs either success_callback or error_callback on - // the calling thread, but not before the call returns. - static void Parse(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback); - - JsonUnsafeParser() = delete; -}; - -} // namespace ntp_tiles - -#endif // COMPONENTS_NTP_TILES_POPULAR_SITES_H_ diff --git a/chromium/components/ntp_tiles/metrics.cc b/chromium/components/ntp_tiles/metrics.cc index 9cc76163918..8b97fa2fe9d 100644 --- a/chromium/components/ntp_tiles/metrics.cc +++ b/chromium/components/ntp_tiles/metrics.cc @@ -9,6 +9,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" +#include "components/ntp_tiles/constants.h" #include "components/rappor/public/rappor_utils.h" namespace ntp_tiles { @@ -16,9 +17,6 @@ namespace metrics { namespace { -// Maximum number of tiles to record in histograms. -const int kMaxNumTiles = 12; - const int kLastTitleSource = static_cast<int>(TileTitleSource::LAST); // Identifiers for the various tile sources. @@ -29,6 +27,7 @@ const char kHistogramBakedInName[] = "popular_baked_in"; const char kHistogramWhitelistName[] = "whitelist"; const char kHistogramHomepageName[] = "homepage"; const char kHistogramCustomLinksName[] = "custom_links"; +const char kHistogramExploreName[] = "explore"; const char kHistogramSearchName[] = "search_page"; // Suffixes for the various icon types. @@ -60,6 +59,8 @@ std::string GetSourceHistogramName(TileSource source) { return kHistogramHomepageName; case TileSource::CUSTOM_LINKS: return kHistogramCustomLinksName; + case TileSource::EXPLORE: + return kHistogramExploreName; case TileSource::SEARCH_PAGE: return kHistogramSearchName; } diff --git a/chromium/components/ntp_tiles/most_visited_sites.cc b/chromium/components/ntp_tiles/most_visited_sites.cc index e643df1701a..e4744670b75 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 <iterator> +#include <memory> #include <utility> #include "base/bind.h" @@ -37,10 +38,6 @@ namespace ntp_tiles { namespace { -// The maximum number of custom links that can be shown. This is independent of -// the maximum number of Most Visited sites that can be shown. -const size_t kMaxNumCustomLinks = 10; - const base::Feature kDisplaySuggestionsServiceTiles{ "DisplaySuggestionsServiceTiles", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -60,11 +57,9 @@ const char* kKnownGenericPagePrefixes[] = { ""}; // The no-www domain matches domains on same level . // Determine whether we need any tiles from PopularSites to fill up a grid of -// |num_tiles| tiles. If exploration sections are used, we need popular sites -// regardless of how many tiles we already have. +// |num_tiles| tiles. bool NeedPopularSites(const PrefService* prefs, int num_tiles) { - return base::FeatureList::IsEnabled(kSiteExplorationUiFeature) || - prefs->GetInteger(prefs::kNumPersonalTiles) < num_tiles; + return prefs->GetInteger(prefs::kNumPersonalTiles) < num_tiles; } bool AreURLsEquivalent(const GURL& url1, const GURL& url2) { @@ -189,6 +184,8 @@ bool MostVisitedSites::DoesSourceExist(TileSource source) const { return supervisor_ != nullptr; case TileSource::CUSTOM_LINKS: return custom_links_ != nullptr; + case TileSource::EXPLORE: + return explore_sites_client_ != nullptr; case TileSource::SEARCH_PAGE: #if !defined(OS_ANDROID) && !defined(OS_IOS) return true; @@ -206,6 +203,11 @@ void MostVisitedSites::SetHomepageClient( homepage_client_ = std::move(client); } +void MostVisitedSites::SetExploreSitesClient( + std::unique_ptr<ExploreSitesClient> client) { + explore_sites_client_ = std::move(client); +} + void MostVisitedSites::SetMostVisitedURLsObserver(Observer* observer, size_t num_sites) { DCHECK(observer); @@ -295,6 +297,7 @@ bool MostVisitedSites::AddCustomLink(const GURL& url, if (!custom_links_ || !custom_links_enabled_) return false; + bool is_first_action = !custom_links_->IsInitialized(); // Initialize custom links if they have not been initialized yet. InitializeCustomLinks(); @@ -303,6 +306,10 @@ bool MostVisitedSites::AddCustomLink(const GURL& url, if (custom_links_action_count_ != -1) custom_links_action_count_++; BuildCurrentTiles(); + } else if (is_first_action) { + // We don't want to keep custom links initialized if the first action after + // initialization failed. + UninitializeCustomLinks(); } return success; } @@ -313,6 +320,7 @@ bool MostVisitedSites::UpdateCustomLink(const GURL& url, if (!custom_links_ || !custom_links_enabled_) return false; + bool is_first_action = !custom_links_->IsInitialized(); // Initialize custom links if they have not been initialized yet. InitializeCustomLinks(); @@ -321,6 +329,10 @@ bool MostVisitedSites::UpdateCustomLink(const GURL& url, if (custom_links_action_count_ != -1) custom_links_action_count_++; BuildCurrentTiles(); + } else if (is_first_action) { + // We don't want to keep custom links initialized if the first action after + // initialization failed. + UninitializeCustomLinks(); } return success; } @@ -329,6 +341,7 @@ bool MostVisitedSites::ReorderCustomLink(const GURL& url, size_t new_pos) { if (!custom_links_ || !custom_links_enabled_) return false; + bool is_first_action = !custom_links_->IsInitialized(); // Initialize custom links if they have not been initialized yet. InitializeCustomLinks(); @@ -337,6 +350,10 @@ bool MostVisitedSites::ReorderCustomLink(const GURL& url, size_t new_pos) { if (custom_links_action_count_ != -1) custom_links_action_count_++; BuildCurrentTiles(); + } else if (is_first_action) { + // We don't want to keep custom links initialized if the first action after + // initialization failed. + UninitializeCustomLinks(); } return success; } @@ -345,6 +362,7 @@ bool MostVisitedSites::DeleteCustomLink(const GURL& url) { if (!custom_links_ || !custom_links_enabled_) return false; + bool is_first_action = !custom_links_->IsInitialized(); // Initialize custom links if they have not been initialized yet. InitializeCustomLinks(); @@ -353,6 +371,10 @@ bool MostVisitedSites::DeleteCustomLink(const GURL& url) { if (custom_links_action_count_ != -1) custom_links_action_count_++; BuildCurrentTiles(); + } else if (is_first_action) { + // We don't want to keep custom links initialized if the first action after + // initialization failed. + UninitializeCustomLinks(); } return success; } @@ -707,6 +729,19 @@ NTPTilesVector MostVisitedSites::InsertHomeTile( return new_tiles; } +base::Optional<NTPTile> MostVisitedSites::CreateExploreSitesTile() { + if (!explore_sites_client_) + return base::nullopt; + + NTPTile explore_sites_tile; + explore_sites_tile.url = explore_sites_client_->GetExploreSitesUrl(); + explore_sites_tile.title = explore_sites_client_->GetExploreSitesTitle(); + explore_sites_tile.source = TileSource::EXPLORE; + explore_sites_tile.title_source = TileTitleSource::UNKNOWN; + + return explore_sites_tile; +} + NTPTilesVector MostVisitedSites::InsertSearchTile(NTPTilesVector tiles) const { DCHECK_GT(max_num_sites_, 0u); @@ -771,6 +806,8 @@ void MostVisitedSites::BuildCustomLinks( DCHECK(custom_links_); NTPTilesVector tiles; + // The maximum number of custom links that can be shown is independent of the + // maximum number of Most Visited sites that can be shown. size_t num_tiles = std::min(links.size(), kMaxNumCustomLinks); for (size_t i = 0; i < num_tiles; ++i) { const CustomLinksManager::Link& link = links.at(i); @@ -813,7 +850,15 @@ void MostVisitedSites::InitiateNotificationForNewTiles( void MostVisitedSites::MergeMostVisitedTiles(NTPTilesVector personal_tiles) { std::set<std::string> used_hosts; - size_t num_actual_tiles = 0u; + + base::Optional<NTPTile> explore_tile = CreateExploreSitesTile(); + size_t num_actual_tiles = explore_tile ? 1 : 0; + + // The explore sites tile may have taken a space that was utilized by the + // personal tiles. + if (personal_tiles.size() + num_actual_tiles > max_num_sites_) { + personal_tiles.pop_back(); + } AddToHostsAndTotalCount(personal_tiles, &used_hosts, &num_actual_tiles); NTPTilesVector whitelist_tiles = @@ -827,7 +872,7 @@ void MostVisitedSites::MergeMostVisitedTiles(NTPTilesVector personal_tiles) { NTPTilesVector new_tiles = MergeTiles(std::move(personal_tiles), std::move(whitelist_tiles), - std::move(sections[SectionType::PERSONALIZED])); + std::move(sections[SectionType::PERSONALIZED]), explore_tile); SaveTilesAndNotify(std::move(new_tiles), std::move(sections)); } @@ -854,9 +899,11 @@ void MostVisitedSites::SaveTilesAndNotify( } // static -NTPTilesVector MostVisitedSites::MergeTiles(NTPTilesVector personal_tiles, - NTPTilesVector whitelist_tiles, - NTPTilesVector popular_tiles) { +NTPTilesVector MostVisitedSites::MergeTiles( + NTPTilesVector personal_tiles, + NTPTilesVector whitelist_tiles, + NTPTilesVector popular_tiles, + base::Optional<NTPTile> explore_tile) { NTPTilesVector merged_tiles; std::move(personal_tiles.begin(), personal_tiles.end(), std::back_inserter(merged_tiles)); @@ -864,6 +911,9 @@ NTPTilesVector MostVisitedSites::MergeTiles(NTPTilesVector personal_tiles, std::back_inserter(merged_tiles)); std::move(popular_tiles.begin(), popular_tiles.end(), std::back_inserter(merged_tiles)); + if (explore_tile) + merged_tiles.push_back(*explore_tile); + return merged_tiles; } diff --git a/chromium/components/ntp_tiles/most_visited_sites.h b/chromium/components/ntp_tiles/most_visited_sites.h index edcb280a039..e2e349e2a0f 100644 --- a/chromium/components/ntp_tiles/most_visited_sites.h +++ b/chromium/components/ntp_tiles/most_visited_sites.h @@ -113,6 +113,13 @@ class MostVisitedSites : public history::TopSitesObserver, virtual void QueryHomepageTitle(TitleCallback title_callback) = 0; }; + class ExploreSitesClient { + public: + virtual ~ExploreSitesClient() = default; + virtual GURL GetExploreSitesUrl() const = 0; + virtual base::string16 GetExploreSitesTitle() const = 0; + }; + // Construct a MostVisitedSites instance. // // |prefs| and |suggestions| are required and may not be null. |top_sites|, @@ -152,6 +159,10 @@ class MostVisitedSites : public history::TopSitesObserver, // |client| must not be null and outlive this object. void SetHomepageClient(std::unique_ptr<HomepageClient> client); + // Sets the client that provides the Explore Sites tile. Can be null if no + // such tile is desirable. + void SetExploreSitesClient(std::unique_ptr<ExploreSitesClient> client); + // Requests an asynchronous refresh of the suggestions. Notifies the observer // if the request resulted in the set of tiles changing. void Refresh(); @@ -176,24 +187,25 @@ class MostVisitedSites : public history::TopSitesObserver, void EnableCustomLinks(bool enable); // Adds a custom link. If the number of current links is maxed, returns false // and does nothing. Will initialize custom links if they have not been - // initialized yet. Custom links must be enabled. + // initialized yet, unless the action fails. Custom links must be enabled. bool AddCustomLink(const GURL& url, const base::string16& title); // Updates the URL and/or title of the custom link specified by |url|. If // |url| does not exist or |new_url| already exists in the custom link list, // returns false and does nothing. Will initialize custom links if they have - // not been initialized yet. Custom links must be enabled. + // not been initialized yet, unless the action fails. Custom links must be + // enabled. bool UpdateCustomLink(const GURL& url, const GURL& new_url, const base::string16& new_title); // Moves the custom link specified by |url| to the index |new_pos|. If |url| // does not exist, or |new_pos| is invalid, returns false and does nothing. - // Will initialize custom links if they have not been initialized yet. Custom - // links must be enabled. + // Will initialize custom links if they have not been initialized yet, unless + // the action fails. Custom links must be enabled. bool ReorderCustomLink(const GURL& url, size_t new_pos); // Deletes the custom link with the specified |url|. If |url| does not exist // in the custom link list, returns false and does nothing. Will initialize - // custom links if they have not been initialized yet. Custom links must be - // enabled. + // custom links if they have not been initialized yet, unless the action + // fails. Custom links must be enabled. bool DeleteCustomLink(const GURL& url); // Restores the previous state of custom links before the last action that // modified them. If there was no action, does nothing. If this is undoing the @@ -213,7 +225,8 @@ class MostVisitedSites : public history::TopSitesObserver, // public method for ease of testing. static NTPTilesVector MergeTiles(NTPTilesVector personal_tiles, NTPTilesVector whitelist_tiles, - NTPTilesVector popular_tiles); + NTPTilesVector popular_tiles, + base::Optional<NTPTile> explore_tile); private: FRIEND_TEST_ALL_PREFIXES(MostVisitedSitesTest, @@ -309,6 +322,10 @@ class MostVisitedSites : public history::TopSitesObserver, NTPTilesVector InsertHomeTile(NTPTilesVector tiles, const base::string16& title) const; + // Creates a tile for the Explore Sites page, if enabled. The tile is added to + // the front of the list. + base::Optional<NTPTile> CreateExploreSitesTile(); + // Adds the Google Search page as first tile to |tiles| and returns them as // new vector. Drops existing tiles with the same host as the Google Search // page and tiles that would exceed the maximum. @@ -333,6 +350,7 @@ class MostVisitedSites : public history::TopSitesObserver, std::unique_ptr<IconCacher> const icon_cacher_; std::unique_ptr<MostVisitedSitesSupervisor> supervisor_; std::unique_ptr<HomepageClient> homepage_client_; + std::unique_ptr<ExploreSitesClient> explore_sites_client_; Observer* observer_; diff --git a/chromium/components/ntp_tiles/most_visited_sites_unittest.cc b/chromium/components/ntp_tiles/most_visited_sites_unittest.cc index fe08f7a1442..129a07c789f 100644 --- a/chromium/components/ntp_tiles/most_visited_sites_unittest.cc +++ b/chromium/components/ntp_tiles/most_visited_sites_unittest.cc @@ -27,16 +27,15 @@ #include "build/build_config.h" #include "components/history/core/browser/top_sites.h" #include "components/history/core/browser/top_sites_observer.h" -#include "components/ntp_tiles/constants.h" #include "components/ntp_tiles/custom_links_manager.h" #include "components/ntp_tiles/features.h" #include "components/ntp_tiles/icon_cacher.h" -#include "components/ntp_tiles/json_unsafe_parser.h" #include "components/ntp_tiles/popular_sites_impl.h" #include "components/ntp_tiles/pref_names.h" #include "components/ntp_tiles/section_type.h" #include "components/ntp_tiles/switches.h" #include "components/sync_preferences/testing_pref_service_syncable.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" @@ -83,6 +82,8 @@ using testing::_; const char kHomepageUrl[] = "http://ho.me/"; const char kHomepageTitle[] = "Home"; +const char kTestExploreUrl[] = "https://example.com/"; +const char kTestExploreTitle[] = "Example"; std::string PrintTile(const std::string& title, const std::string& url, @@ -102,6 +103,29 @@ MATCHER_P3(MatchesTile, title, url, source, PrintTile(title, url, source)) { arg.source == source; } +std::string PrintTileSource(TileSource source) { + return std::string("has source ") + + testing::PrintToString(static_cast<int>(source)); +} + +MATCHER_P(TileWithSource, source, PrintTileSource(source)) { + return arg.source == source; +} + +MATCHER_P3(LastTileIs, + title, + url, + source, + std::string("last tile ") + PrintTile(title, url, source)) { + const NTPTilesVector& tiles = arg.at(SectionType::PERSONALIZED); + if (tiles.empty()) + return false; + + const NTPTile& last = tiles.back(); + return last.title == base::ASCIIToUTF16(title) && last.url == GURL(url) && + last.source == source; +} + MATCHER_P3(FirstPersonalizedTileIs, title, url, @@ -243,6 +267,17 @@ class FakeHomepageClient : public MostVisitedSites::HomepageClient { base::Optional<base::string16> homepage_title_; }; +class FakeExploreSitesClient : public MostVisitedSites::ExploreSitesClient { + public: + ~FakeExploreSitesClient() override = default; + + GURL GetExploreSitesUrl() const override { return GURL(kTestExploreUrl); } + + base::string16 GetExploreSitesTitle() const override { + return base::ASCIIToUTF16(kTestExploreTitle); + } +}; + class MockIconCacher : public IconCacher { public: MOCK_METHOD3(StartFetchPopularSites, @@ -299,7 +334,7 @@ class PopularSitesFactoryForTest { "title": "PopularSite2", "url": "http://popularsite2/", "favicon_url": "http://popularsite2/favicon.ico" - }, + } ])"); test_url_loader_factory_.AddResponse( @@ -316,7 +351,7 @@ class PopularSitesFactoryForTest { "title": "Google News", "url": "http://news.google.com", "favicon_url": "http://news.google.com/favicon.ico" - }, + } ])"); test_url_loader_factory_.AddResponse( @@ -370,7 +405,7 @@ class PopularSitesFactoryForTest { prefs_, /*template_url_service=*/nullptr, /*variations_service=*/nullptr, test_shared_loader_factory_, - base::Bind(JsonUnsafeParser::Parse)); + base::Bind(&data_decoder::SafeJsonParser::Parse, nullptr)); } private: @@ -502,6 +537,13 @@ class MostVisitedSitesTest : public ::testing::TestWithParam<bool> { return raw_client_ptr; } + FakeExploreSitesClient* RegisterNewExploreSitesClient() { + auto explore_sites_client = std::make_unique<FakeExploreSitesClient>(); + FakeExploreSitesClient* raw_client_ptr = explore_sites_client.get(); + most_visited_sites_->SetExploreSitesClient(std::move(explore_sites_client)); + return raw_client_ptr; + } + void DisableRemoteSuggestions() { EXPECT_CALL(mock_suggestions_service_, AddCallback(_)) .Times(AnyNumber()) @@ -523,6 +565,7 @@ class MostVisitedSitesTest : public ::testing::TestWithParam<bool> { TopSitesCallbackList top_sites_callbacks_; base::test::ScopedTaskEnvironment task_environment_; + data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_; sync_preferences::TestingPrefServiceSyncable pref_service_; PopularSitesFactoryForTest popular_sites_factory_; scoped_refptr<StrictMock<MockTopSites>> mock_top_sites_; @@ -867,6 +910,71 @@ TEST_P(MostVisitedSitesTest, ShouldPinHomepageAgainIfBlacklistingUndone) { base::RunLoop().RunUntilIdle(); } +TEST_P(MostVisitedSitesTest, ShouldNotIncludeTileForExploreSitesIfNoClient) { + // Does not register an explore sites client. + + DisableRemoteSuggestions(); + EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) + .WillRepeatedly(InvokeCallbackArgument<0>(MostVisitedURLList{ + MakeMostVisitedURL("ESPN", "http://espn.com/"), + MakeMostVisitedURL("Mobile", "http://m.mobile.de/"), + MakeMostVisitedURL("Google", "http://www.google.com/")})); + EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); + EXPECT_CALL(mock_observer_, + OnURLsAvailable(Not(Contains( + Pair(SectionType::PERSONALIZED, + Contains(TileWithSource(TileSource::EXPLORE))))))); + // Note that 5 sites are requested, this means that there should be the 3 from + // top sites and two from popular sites. + most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_, + /*num_sites=*/5); + base::RunLoop().RunUntilIdle(); +} + +// Tests that the explore sites tile appears when there is a mix of top sites +// and popular sites. +TEST_P(MostVisitedSitesTest, ShouldIncludeTileForExploreSites) { + RegisterNewExploreSitesClient(); + DisableRemoteSuggestions(); + EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) + .WillRepeatedly(InvokeCallbackArgument<0>(MostVisitedURLList{ + MakeMostVisitedURL("ESPN", "http://espn.com/"), + MakeMostVisitedURL("Mobile", "http://m.mobile.de/"), + MakeMostVisitedURL("Google", "http://www.google.com/")})); + EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); + EXPECT_CALL(mock_observer_, + OnURLsAvailable(LastTileIs(kTestExploreTitle, kTestExploreUrl, + TileSource::EXPLORE))); + // Note that 5 sites are requested, this means that there should be the 3 from + // top sites, one from popular sites, and one explore tile. + most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_, + /*num_sites=*/5); + base::RunLoop().RunUntilIdle(); +} + +TEST_P(MostVisitedSitesTest, RemovesPersonalSiteIfExploreSitesTilePresent) { + RegisterNewExploreSitesClient(); + DisableRemoteSuggestions(); + EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) + .WillRepeatedly(InvokeCallbackArgument<0>(MostVisitedURLList{ + MakeMostVisitedURL("ESPN", "http://espn.com/"), + MakeMostVisitedURL("Mobile", "http://m.mobile.de/"), + MakeMostVisitedURL("Google", "http://www.google.com/")})); + EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); + EXPECT_CALL(mock_observer_, + OnURLsAvailable(Contains(Pair( + SectionType::PERSONALIZED, + ElementsAre(MatchesTile("ESPN", "http://espn.com/", + TileSource::TOP_SITES), + MatchesTile("Mobile", "http://m.mobile.de/", + TileSource::TOP_SITES), + MatchesTile(kTestExploreTitle, kTestExploreUrl, + TileSource::EXPLORE)))))); + most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_, + /*num_sites=*/3); + base::RunLoop().RunUntilIdle(); +} + TEST_P(MostVisitedSitesTest, ShouldInformSuggestionSourcesWhenBlacklisting) { EXPECT_CALL(*mock_top_sites_, AddBlacklistedURL(Eq(GURL(kHomepageUrl)))) .Times(1); @@ -883,51 +991,6 @@ TEST_P(MostVisitedSitesTest, ShouldInformSuggestionSourcesWhenBlacklisting) { /*add_url=*/false); } -TEST_P(MostVisitedSitesTest, ShouldContainSiteExplorationsWhenFeatureEnabled) { - base::test::ScopedFeatureList feature_list; - std::map<SectionType, NTPTilesVector> sections; - feature_list.InitAndEnableFeature(kSiteExplorationUiFeature); - pref_service_.SetString(prefs::kPopularSitesOverrideVersion, "6"); - RecreateMostVisitedSites(); // Refills cache with version 6 popular sites. - DisableRemoteSuggestions(); - EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) - .WillRepeatedly(InvokeCallbackArgument<0>( - MostVisitedURLList{MakeMostVisitedURL("Site 1", "http://site1/")})); - EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); - EXPECT_CALL(mock_observer_, OnURLsAvailable(_)) - .WillOnce(SaveArg<0>(§ions)); - - most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_, - /*num_sites=*/3); - base::RunLoop().RunUntilIdle(); - - if (!IsPopularSitesFeatureEnabled()) { - EXPECT_THAT( - sections, - Contains(Pair(SectionType::PERSONALIZED, - ElementsAre(MatchesTile("Site 1", "http://site1/", - TileSource::TOP_SITES))))); - return; - } - const auto& expected_sections = - most_visited_sites_->popular_sites()->sections(); - ASSERT_THAT(expected_sections.size(), Ge(2ul)); - EXPECT_THAT(sections.size(), Eq(expected_sections.size())); - EXPECT_THAT( - sections, - AllOf(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile("Site 1", "http://site1/", - TileSource::TOP_SITES), - MatchesTile("PopularSite1", "http://popularsite1/", - TileSource::POPULAR), - MatchesTile("PopularSite2", "http://popularsite2/", - TileSource::POPULAR)))), - Contains(Pair(SectionType::NEWS, SizeIs(2ul))), - Contains(Pair(SectionType::SOCIAL, SizeIs(1ul))), - Contains(Pair(_, IsEmpty())))); -} - TEST_P(MostVisitedSitesTest, ShouldDeduplicatePopularSitesWithMostVisitedIffHostAndTitleMatches) { pref_service_.SetString(prefs::kPopularSitesOverrideCountry, "US"); @@ -1515,7 +1578,8 @@ TEST_P(MostVisitedSitesWithCustomLinksTest, // Complete a second custom link action. EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(false)); EXPECT_CALL(*mock_custom_links_, DeleteLink(_)).WillOnce(Return(true)); - EXPECT_CALL(*mock_custom_links_, IsInitialized()).WillOnce(Return(true)); + EXPECT_CALL(*mock_custom_links_, IsInitialized()) + .WillRepeatedly(Return(true)); EXPECT_CALL(*mock_custom_links_, GetLinks()) .WillOnce(ReturnRef(expected_links)); most_visited_sites_->DeleteCustomLink(GURL("test.com")); @@ -1531,6 +1595,73 @@ TEST_P(MostVisitedSitesWithCustomLinksTest, base::RunLoop().RunUntilIdle(); } +TEST_P(MostVisitedSitesWithCustomLinksTest, + UninitializeCustomLinksIfFirstActionFails) { + const char kTestUrl[] = "http://site1/"; + const char kTestTitle[] = "Site 1"; + std::vector<CustomLinksManager::Link> expected_links( + {CustomLinksManager::Link{GURL(kTestUrl), + base::UTF8ToUTF16(kTestTitle)}}); + std::map<SectionType, NTPTilesVector> sections; + DisableRemoteSuggestions(); + + // Build initial tiles with Top Sites. + EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); + ExpectBuildWithTopSites( + MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}, §ions); + most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_, + /*num_sites=*/1); + base::RunLoop().RunUntilIdle(); + ASSERT_THAT( + sections.at(SectionType::PERSONALIZED), + ElementsAre(MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES))); + + // Fail to add a custom link. This should not initialize custom links nor + // notify. + EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true)); + EXPECT_CALL(*mock_custom_links_, AddLink(_, _)).WillOnce(Return(false)); + EXPECT_CALL(*mock_custom_links_, IsInitialized()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_custom_links_, Uninitialize()); + EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(0); + most_visited_sites_->AddCustomLink(GURL(kTestUrl), base::UTF8ToUTF16("test")); + base::RunLoop().RunUntilIdle(); + + // Fail to edit a custom link. This should not initialize custom links nor + // notify. + EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true)); + EXPECT_CALL(*mock_custom_links_, UpdateLink(_, _, _)).WillOnce(Return(false)); + EXPECT_CALL(*mock_custom_links_, IsInitialized()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_custom_links_, Uninitialize()); + EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(0); + most_visited_sites_->UpdateCustomLink(GURL("test.com"), GURL("test2.com"), + base::UTF8ToUTF16("test")); + base::RunLoop().RunUntilIdle(); + + // Fail to reorder a custom link. This should not initialize custom links nor + // notify. + EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true)); + EXPECT_CALL(*mock_custom_links_, ReorderLink(_, _)).WillOnce(Return(false)); + EXPECT_CALL(*mock_custom_links_, IsInitialized()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_custom_links_, Uninitialize()); + EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(0); + most_visited_sites_->ReorderCustomLink(GURL("test.com"), 1); + base::RunLoop().RunUntilIdle(); + + // Fail to delete a custom link. This should not initialize custom links nor + // notify. + EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true)); + EXPECT_CALL(*mock_custom_links_, DeleteLink(_)).WillOnce(Return(false)); + EXPECT_CALL(*mock_custom_links_, IsInitialized()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_custom_links_, Uninitialize()); + EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(0); + most_visited_sites_->DeleteCustomLink(GURL("test.com")); + base::RunLoop().RunUntilIdle(); +} + TEST_P(MostVisitedSitesWithCustomLinksTest, RebuildTilesOnCustomLinksChanged) { const char kTestUrl1[] = "http://site1/"; const char kTestUrl2[] = "http://site2/"; @@ -2062,7 +2193,8 @@ TEST(MostVisitedSitesMergeTest, ShouldMergeTilesWithPersonalOnly) { // tiles. EXPECT_THAT(MostVisitedSites::MergeTiles(std::move(personal_tiles), /*whitelist_tiles=*/NTPTilesVector(), - /*popular_tiles=*/NTPTilesVector()), + /*popular_tiles=*/NTPTilesVector(), + /*explore_tile=*/base::nullopt), ElementsAre(MatchesTile("Site 1", "https://www.site1.com/", TileSource::TOP_SITES), MatchesTile("Site 2", "https://www.site2.com/", @@ -2085,7 +2217,8 @@ TEST(MostVisitedSitesMergeTest, ShouldMergeTilesWithPopularOnly) { EXPECT_THAT( MostVisitedSites::MergeTiles(/*personal_tiles=*/NTPTilesVector(), /*whitelist_tiles=*/NTPTilesVector(), - /*popular_tiles=*/std::move(popular_tiles)), + /*popular_tiles=*/std::move(popular_tiles), + /*explore_tile=*/base::nullopt), ElementsAre( MatchesTile("Site 1", "https://www.site1.com/", TileSource::POPULAR), MatchesTile("Site 2", "https://www.site2.com/", TileSource::POPULAR), @@ -2103,18 +2236,23 @@ TEST(MostVisitedSitesMergeTest, ShouldMergeTilesFavoringPersonalOverPopular) { MakeTile("Site 3", "https://www.site3.com/", TileSource::TOP_SITES), MakeTile("Site 4", "https://www.site4.com/", TileSource::TOP_SITES), }; + base::Optional<NTPTile> explore_tile{ + MakeTile("Explore", "https://explore.example.com/", TileSource::EXPLORE), + }; EXPECT_THAT( MostVisitedSites::MergeTiles(std::move(personal_tiles), /*whitelist_tiles=*/NTPTilesVector(), - /*popular_tiles=*/std::move(popular_tiles)), + /*popular_tiles=*/std::move(popular_tiles), + /*explore_tiles=*/explore_tile), ElementsAre( MatchesTile("Site 3", "https://www.site3.com/", TileSource::TOP_SITES), MatchesTile("Site 4", "https://www.site4.com/", TileSource::TOP_SITES), MatchesTile("Site 1", "https://www.site1.com/", TileSource::POPULAR), - MatchesTile("Site 2", "https://www.site2.com/", - TileSource::POPULAR))); + MatchesTile("Site 2", "https://www.site2.com/", TileSource::POPULAR), + MatchesTile("Explore", "https://explore.example.com/", + TileSource::EXPLORE))); } #if !defined(OS_ANDROID) && !defined(OS_IOS) diff --git a/chromium/components/ntp_tiles/popular_sites_impl.cc b/chromium/components/ntp_tiles/popular_sites_impl.cc index 02380d5d43a..34eef87fd84 100644 --- a/chromium/components/ntp_tiles/popular_sites_impl.cc +++ b/chromium/components/ntp_tiles/popular_sites_impl.cc @@ -19,9 +19,8 @@ #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" -#include "components/data_use_measurement/core/data_use_user_data.h" #include "components/google/core/common/google_util.h" -#include "components/ntp_tiles/constants.h" +#include "components/ntp_tiles/features.h" #include "components/ntp_tiles/pref_names.h" #include "components/ntp_tiles/switches.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -172,9 +171,10 @@ std::map<SectionType, PopularSites::SitesVector> ParseVersion6OrAbove( << "invalid ID (" << section << ")"; continue; } + // Non-personalized site exploration tiles are no longer supported, so + // ignore all other section types. SectionType section_type = static_cast<SectionType>(section); - if (section_type == SectionType::UNKNOWN) { - LOG(WARNING) << "Dropped an unknown section in SitesExploration list."; + if (section_type != SectionType::PERSONALIZED) { continue; } const base::ListValue* sites_list; @@ -183,12 +183,6 @@ std::map<SectionType, PopularSites::SitesVector> ParseVersion6OrAbove( } sections[section_type] = ParseSiteList(*sites_list); } - if (!base::FeatureList::IsEnabled(kSiteExplorationUiFeature)) { - // New versions of popular sites that should act like old versions will - // mimic having only the personalized list. - return {std::make_pair(SectionType::PERSONALIZED, - std::move(sections[SectionType::PERSONALIZED]))}; - } return sections; } @@ -268,12 +262,12 @@ PopularSitesImpl::PopularSitesImpl( const TemplateURLService* template_url_service, VariationsService* variations_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - ParseJSONCallback parse_json) + const ParseJSONCallback& parse_json) : prefs_(prefs), template_url_service_(template_url_service), variations_(variations_service), url_loader_factory_(std::move(url_loader_factory)), - parse_json_(std::move(parse_json)), + parse_json_(parse_json), is_fallback_(false), sections_( ParseSites(*prefs->GetList(prefs::kPopularSitesJsonPref), @@ -450,11 +444,7 @@ void PopularSitesImpl::FetchPopularSites() { })"); auto resource_request = std::make_unique<network::ResourceRequest>(); resource_request->url = pending_url_; - resource_request->load_flags = - net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES; - // TODO(https://crbug.com/808498): Re-add data use measurement once - // SimpleURLLoader supports it. - // ID=data_use_measurement::DataUseUserData::NTP_TILES + resource_request->allow_credentials = false; simple_url_loader_ = network::SimpleURLLoader::Create( std::move(resource_request), traffic_annotation); simple_url_loader_->SetRetryOptions( @@ -475,15 +465,15 @@ void PopularSitesImpl::OnSimpleLoaderComplete( } parse_json_.Run(*response_body, - base::Bind(&PopularSitesImpl::OnJsonParsed, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&PopularSitesImpl::OnJsonParseFailed, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&PopularSitesImpl::OnJsonParsed, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&PopularSitesImpl::OnJsonParseFailed, + weak_ptr_factory_.GetWeakPtr())); } -void PopularSitesImpl::OnJsonParsed(std::unique_ptr<base::Value> json) { +void PopularSitesImpl::OnJsonParsed(base::Value json) { std::unique_ptr<base::ListValue> list = - base::ListValue::From(std::move(json)); + base::ListValue::From(base::Value::ToUniquePtrValue(std::move(json))); if (!list) { DLOG(WARNING) << "JSON is not a list"; OnDownloadFailed(); diff --git a/chromium/components/ntp_tiles/popular_sites_impl.h b/chromium/components/ntp_tiles/popular_sites_impl.h index 43588d01250..5b51e289ccb 100644 --- a/chromium/components/ntp_tiles/popular_sites_impl.h +++ b/chromium/components/ntp_tiles/popular_sites_impl.h @@ -39,10 +39,10 @@ class TemplateURLService; namespace ntp_tiles { -using ParseJSONCallback = base::Callback<void( +using ParseJSONCallback = base::RepeatingCallback<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)>; + base::OnceCallback<void(base::Value)> success_callback, + base::OnceCallback<void(const std::string&)> error_callback)>; // Actual (non-test) implementation of the PopularSites interface. Caches the // downloaded file on disk to avoid re-downloading on every startup. @@ -53,7 +53,7 @@ class PopularSitesImpl : public PopularSites { const TemplateURLService* template_url_service, variations::VariationsService* variations_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - ParseJSONCallback parse_json); + const ParseJSONCallback& parse_json); ~PopularSitesImpl() override; @@ -80,7 +80,7 @@ class PopularSitesImpl : public PopularSites { // Called once SimpleURLLoader completes the network request. void OnSimpleLoaderComplete(std::unique_ptr<std::string> response_body); - void OnJsonParsed(std::unique_ptr<base::Value> json); + void OnJsonParsed(base::Value json); void OnJsonParseFailed(const std::string& error_message); void OnDownloadFailed(); diff --git a/chromium/components/ntp_tiles/popular_sites_impl_unittest.cc b/chromium/components/ntp_tiles/popular_sites_impl_unittest.cc index b3b88f61882..b965d6b611d 100644 --- a/chromium/components/ntp_tiles/popular_sites_impl_unittest.cc +++ b/chromium/components/ntp_tiles/popular_sites_impl_unittest.cc @@ -22,13 +22,13 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "build/build_config.h" -#include "components/ntp_tiles/constants.h" -#include "components/ntp_tiles/json_unsafe_parser.h" +#include "components/ntp_tiles/features.h" #include "components/ntp_tiles/pref_names.h" #include "components/ntp_tiles/tile_source.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "net/http/http_status_code.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" @@ -204,7 +204,7 @@ class PopularSitesTest : public ::testing::Test { prefs_.get(), /*template_url_service=*/nullptr, /*variations_service=*/nullptr, test_shared_loader_factory_, - base::Bind(JsonUnsafeParser::Parse)); + base::Bind(&data_decoder::SafeJsonParser::Parse, nullptr)); } const TestPopularSite kWikipedia; @@ -213,6 +213,7 @@ class PopularSitesTest : public ::testing::Test { base::test::ScopedTaskEnvironment task_environment_{ base::test::ScopedTaskEnvironment::MainThreadType::UI}; + data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_; std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> prefs_; network::TestURLLoaderFactory test_url_loader_factory_; scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; @@ -531,10 +532,7 @@ TEST_F(PopularSitesTest, ShouldOverrideDirectory) { EXPECT_THAT(sites.size(), Eq(1u)); } -TEST_F(PopularSitesTest, DoesNotFetchExplorationSitesWithoutFeature) { - base::test::ScopedFeatureList override_features; - override_features.InitAndDisableFeature(kSiteExplorationUiFeature); - +TEST_F(PopularSitesTest, DoesNotFetchExplorationSites) { SetCountryAndVersion("ZZ", "6"); RespondWithV6JSON( "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_6.json", @@ -549,46 +547,5 @@ TEST_F(PopularSitesTest, DoesNotFetchExplorationSitesWithoutFeature) { EXPECT_THAT(sections, Not(Contains(Pair(SectionType::NEWS, _)))); } -TEST_F(PopularSitesTest, FetchesExplorationSitesWithFeature) { - base::test::ScopedFeatureList override_features; - override_features.InitAndEnableFeature(kSiteExplorationUiFeature); - SetCountryAndVersion("ZZ", "6"); - RespondWithV6JSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_6.json", - {{SectionType::PERSONALIZED, {kChromium}}, - {SectionType::ENTERTAINMENT, {kWikipedia, kYouTube}}, - {SectionType::NEWS, {kYouTube}}, - {SectionType::TOOLS, TestPopularSiteVector{}}}); - - std::map<SectionType, PopularSites::SitesVector> sections; - EXPECT_THAT(FetchAllSections(/*force_download=*/false, §ions), - Eq(base::Optional<bool>(true))); - - EXPECT_THAT(sections, ElementsAre(Pair(SectionType::PERSONALIZED, SizeIs(1)), - Pair(SectionType::ENTERTAINMENT, SizeIs(2)), - Pair(SectionType::NEWS, SizeIs(1)), - Pair(SectionType::TOOLS, IsEmpty()))); -} - -TEST_F(PopularSitesTest, FetchesExplorationSitesIgnoreUnknownSections) { - base::test::ScopedFeatureList override_features; - override_features.InitAndEnableFeature(kSiteExplorationUiFeature); - - SetCountryAndVersion("ZZ", "6"); - RespondWithV6JSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_6.json", - {{SectionType::UNKNOWN, {kChromium}}, - {SectionType::NEWS, {kYouTube}}, - {SectionType::UNKNOWN, {kWikipedia, kYouTube}}}); - - std::map<SectionType, PopularSites::SitesVector> sections; - EXPECT_THAT(FetchAllSections(/*force_download=*/false, §ions), - Eq(base::Optional<bool>(true))); - - // Expect that there are four sections, none of which is empty. - EXPECT_THAT(sections, ElementsAre(Pair(SectionType::PERSONALIZED, SizeIs(0)), - Pair(SectionType::NEWS, SizeIs(1)))); -} - } // namespace } // namespace ntp_tiles diff --git a/chromium/components/ntp_tiles/tile_source.h b/chromium/components/ntp_tiles/tile_source.h index 689411b4302..899e94c9f8c 100644 --- a/chromium/components/ntp_tiles/tile_source.h +++ b/chromium/components/ntp_tiles/tile_source.h @@ -26,6 +26,8 @@ enum class TileSource { WHITELIST, // Tile containing the user-set home page is replacing the home page button. HOMEPAGE, + // Tile comes from explore sites list. + EXPLORE, // Tile containing the Google Search page. SEARCH_PAGE, diff --git a/chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc b/chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc index fdbadcbc115..0ba8febaa8a 100644 --- a/chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc +++ b/chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc @@ -18,6 +18,7 @@ #include "base/task_runner_util.h" #include "base/values.h" #include "components/favicon/core/favicon_service.h" +#include "components/ntp_tiles/constants.h" #include "components/ntp_tiles/most_visited_sites.h" #include "components/ntp_tiles/pref_names.h" #include "components/ntp_tiles/webui/ntp_tiles_internals_message_handler_client.h" @@ -58,9 +59,7 @@ NTPTilesInternalsMessageHandler::NTPTilesInternalsMessageHandler( favicon::FaviconService* favicon_service) : favicon_service_(favicon_service), client_(nullptr), - // 9 tiles are required for the custom links feature in order to balance - // the Most Visited rows (this is due to an additional "Add" button). - site_count_(9), + site_count_(ntp_tiles::kMaxNumMostVisited), weak_ptr_factory_(this) {} NTPTilesInternalsMessageHandler::~NTPTilesInternalsMessageHandler() = default; |