blob: 397b9e417e57e19ef82cba73c832ca1ae7f70b0d [file] [log] [blame]
[email protected]c764b2822013-07-03 04:16:481// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
sfiera3ff01c0d2016-06-13 15:33:385#include "components/ntp_tiles/most_visited_sites.h"
[email protected]c764b2822013-07-03 04:16:486
sfiera3ff01c0d2016-06-13 15:33:387#include <algorithm>
8#include <set>
treibd2698222016-07-14 11:32:449#include <string>
dchengbc6125d2015-12-30 01:54:0710#include <utility>
11
[email protected]d33adb40d2014-06-03 21:38:4612#include "base/callback.h"
mastizf3468a82016-06-15 11:05:4113#include "base/feature_list.h"
[email protected]bc093e82014-03-04 21:49:1114#include "base/strings/utf_string_conversions.h"
sdefresne0da3bc02015-01-29 18:26:3515#include "components/history/core/browser/top_sites.h"
treibdb416392016-06-29 17:20:5016#include "components/ntp_tiles/constants.h"
Eric Noyau4793d932016-11-16 16:19:2317#include "components/ntp_tiles/field_trial.h"
sfieraae1ae692016-10-24 18:19:1518#include "components/ntp_tiles/icon_cacher.h"
sfiera0dc4da52016-04-29 09:23:0519#include "components/ntp_tiles/pref_names.h"
20#include "components/ntp_tiles/switches.h"
knncbbd754d2015-09-09 15:43:4021#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0822#include "components/prefs/pref_service.h"
[email protected]c764b2822013-07-03 04:16:4823
[email protected]c764b2822013-07-03 04:16:4824using history::TopSites;
[email protected]bc093e82014-03-04 21:49:1125using suggestions::ChromeSuggestion;
26using suggestions::SuggestionsProfile;
sfiera7e952d42016-05-04 17:56:3327using suggestions::SuggestionsService;
[email protected]c764b2822013-07-03 04:16:4828
sfiera08009fe2016-06-15 17:07:2629namespace ntp_tiles {
30
[email protected]c764b2822013-07-03 04:16:4831namespace {
32
mastizf3468a82016-06-15 11:05:4133const base::Feature kDisplaySuggestionsServiceTiles{
34 "DisplaySuggestionsServiceTiles", base::FEATURE_ENABLED_BY_DEFAULT};
35
sfiera635d21d2016-08-04 07:56:0936// Determine whether we need any tiles from PopularSites to fill up a grid of
treibf79ed40d2015-09-22 12:38:0637// |num_tiles| tiles.
treibcd3d2ef2016-07-13 16:53:3138bool NeedPopularSites(const PrefService* prefs, int num_tiles) {
treib41b5968d2016-10-13 08:14:2239 return prefs->GetInteger(prefs::kNumPersonalTiles) < num_tiles;
treibf79ed40d2015-09-22 12:38:0640}
41
atanasova9c0dda602016-03-22 17:41:1342bool AreURLsEquivalent(const GURL& url1, const GURL& url2) {
csharrison88b3b712016-11-14 23:12:3543 return url1.host_piece() == url2.host_piece() &&
44 url1.path_piece() == url2.path_piece();
atanasova9c0dda602016-03-22 17:41:1345}
46
sfiera8df7b382016-04-26 14:06:3347} // namespace
48
sfiera635d21d2016-08-04 07:56:0949MostVisitedSites::MostVisitedSites(PrefService* prefs,
50 scoped_refptr<history::TopSites> top_sites,
51 SuggestionsService* suggestions,
sfiera96c03252016-09-14 18:58:1652 std::unique_ptr<PopularSites> popular_sites,
sfieraae1ae692016-10-24 18:19:1553 std::unique_ptr<IconCacher> icon_cacher,
sfiera635d21d2016-08-04 07:56:0954 MostVisitedSitesSupervisor* supervisor)
sfiera79e643b2016-05-13 16:52:4955 : prefs_(prefs),
sfiera685a987e2016-05-12 17:08:4756 top_sites_(top_sites),
57 suggestions_service_(suggestions),
sfiera96c03252016-09-14 18:58:1658 popular_sites_(std::move(popular_sites)),
sfieraae1ae692016-10-24 18:19:1559 icon_cacher_(std::move(icon_cacher)),
sfiera79e643b2016-05-13 16:52:4960 supervisor_(supervisor),
sfiera685a987e2016-05-12 17:08:4761 observer_(nullptr),
62 num_sites_(0),
treibbaada0f2016-08-01 11:30:3363 top_sites_observer_(this),
sfiera635d21d2016-08-04 07:56:0964 mv_source_(NTPTileSource::SUGGESTIONS_SERVICE),
sfiera7e952d42016-05-04 17:56:3365 weak_ptr_factory_(this) {
sfiera87db8582016-08-05 10:46:4266 DCHECK(prefs_);
sfieraaa1b8862016-10-04 16:09:2367 // top_sites_ can be null in tests.
68 // TODO(sfiera): have iOS use a dummy TopSites in its tests.
mastizc60d74e2016-06-14 14:02:4969 DCHECK(suggestions_service_);
sfiera87db8582016-08-05 10:46:4270 if (supervisor_)
71 supervisor_->SetObserver(this);
[email protected]7ceb4e32013-12-06 04:13:0472}
[email protected]c764b2822013-07-03 04:16:4873
[email protected]7ceb4e32013-12-06 04:13:0474MostVisitedSites::~MostVisitedSites() {
sfiera87db8582016-08-05 10:46:4275 if (supervisor_)
76 supervisor_->SetObserver(nullptr);
[email protected]7ceb4e32013-12-06 04:13:0477}
[email protected]c764b2822013-07-03 04:16:4878
treib5a59f542016-05-18 12:17:2979void MostVisitedSites::SetMostVisitedURLsObserver(Observer* observer,
80 int num_sites) {
treibc1bd1f12016-04-29 15:06:0581 DCHECK(observer);
sfiera929502f32016-04-21 12:52:4882 observer_ = observer;
[email protected]7ceb4e32013-12-06 04:13:0483 num_sites_ = num_sites;
[email protected]852fc792013-10-04 04:15:1284
treib99f6b992016-11-23 13:59:5085 // The order for this condition is important, ShouldShowPopularSites() should
Eric Noyau4793d932016-11-16 16:19:2386 // always be called last to keep metrics as relevant as possible.
87 if (popular_sites_ && NeedPopularSites(prefs_, num_sites_) &&
88 ShouldShowPopularSites()) {
sfiera00a58ab2016-07-28 10:20:4989 popular_sites_->StartFetch(
90 false, base::Bind(&MostVisitedSites::OnPopularSitesAvailable,
91 base::Unretained(this)));
treibf79ed40d2015-09-22 12:38:0692 }
93
treibf7d11512016-06-29 09:06:1594 if (top_sites_) {
95 // TopSites updates itself after a delay. To ensure up-to-date results,
96 // force an update now.
97 top_sites_->SyncWithHistory();
[email protected]7ceb4e32013-12-06 04:13:0498
treibf7d11512016-06-29 09:06:1599 // Register as TopSitesObserver so that we can update ourselves when the
100 // TopSites changes.
treibbaada0f2016-08-01 11:30:33101 top_sites_observer_.Add(top_sites_.get());
treibf7d11512016-06-29 09:06:15102 }
treibcb9c93b2016-04-01 13:22:52103
sfiera728962f2016-04-29 11:04:02104 suggestions_subscription_ = suggestions_service_->AddCallback(
treibcb9c93b2016-04-01 13:22:52105 base::Bind(&MostVisitedSites::OnSuggestionsProfileAvailable,
106 base::Unretained(this)));
107
sfiera635d21d2016-08-04 07:56:09108 // Immediately build the current set of tiles, getting suggestions from the
109 // SuggestionsService's cache or, if that is empty, sites from TopSites.
110 BuildCurrentTiles();
treibcb9c93b2016-04-01 13:22:52111 // Also start a request for fresh suggestions.
treibbb0c5af52016-12-09 17:34:15112 Refresh();
113}
114
115void MostVisitedSites::Refresh() {
sfiera728962f2016-04-29 11:04:02116 suggestions_service_->FetchSuggestionsData();
[email protected]c764b2822013-07-03 04:16:48117}
118
treib5a59f542016-05-18 12:17:29119void MostVisitedSites::AddOrRemoveBlacklistedUrl(const GURL& url,
120 bool add_url) {
treibf7d11512016-06-29 09:06:15121 if (top_sites_) {
122 // Always blacklist in the local TopSites.
123 if (add_url)
124 top_sites_->AddBlacklistedURL(url);
125 else
126 top_sites_->RemoveBlacklistedURL(url);
127 }
[email protected]d4975242014-06-02 18:16:20128
treibfac75192015-08-17 13:21:24129 // Only blacklist in the server-side suggestions service if it's active.
sfiera635d21d2016-08-04 07:56:09130 if (mv_source_ == NTPTileSource::SUGGESTIONS_SERVICE) {
treib16070ce2016-03-11 11:57:40131 if (add_url)
sfiera728962f2016-04-29 11:04:02132 suggestions_service_->BlacklistURL(url);
treib16070ce2016-03-11 11:57:40133 else
sfiera728962f2016-04-29 11:04:02134 suggestions_service_->UndoBlacklistURL(url);
[email protected]d4975242014-06-02 18:16:20135 }
[email protected]a4c2f282013-07-20 05:26:05136}
[email protected]7ceb4e32013-12-06 04:13:04137
treibbb0c5af52016-12-09 17:34:15138void MostVisitedSites::ClearBlacklistedUrls() {
139 if (top_sites_) {
140 // Always update the blacklist in the local TopSites.
141 top_sites_->ClearBlacklistedURLs();
142 }
143
144 // Only update the server-side blacklist if it's active.
145 if (mv_source_ == NTPTileSource::SUGGESTIONS_SERVICE) {
146 suggestions_service_->ClearBlacklist();
147 }
148}
149
sfiera79e643b2016-05-13 16:52:49150void MostVisitedSites::OnBlockedSitesChanged() {
sfiera635d21d2016-08-04 07:56:09151 BuildCurrentTiles();
atanasova9572aaf2016-02-26 18:08:26152}
153
[email protected]7ceb4e32013-12-06 04:13:04154// static
knncbbd754d2015-09-09 15:43:40155void MostVisitedSites::RegisterProfilePrefs(
156 user_prefs::PrefRegistrySyncable* registry) {
sfiera635d21d2016-08-04 07:56:09157 registry->RegisterIntegerPref(prefs::kNumPersonalTiles, 0);
knncbbd754d2015-09-09 15:43:40158}
159
sfiera635d21d2016-08-04 07:56:09160void MostVisitedSites::BuildCurrentTiles() {
treibc1bd1f12016-04-29 15:06:05161 // Get the current suggestions from cache. If the cache is empty, this will
162 // fall back to TopSites.
treibba0dee72016-03-31 13:25:59163 OnSuggestionsProfileAvailable(
sfiera728962f2016-04-29 11:04:02164 suggestions_service_->GetSuggestionsDataFromCache());
[email protected]bc093e82014-03-04 21:49:11165}
166
167void MostVisitedSites::InitiateTopSitesQuery() {
treibf7d11512016-06-29 09:06:15168 if (!top_sites_)
169 return;
sfiera728962f2016-04-29 11:04:02170 top_sites_->GetMostVisitedURLs(
knn6cf777fc2015-05-06 13:21:48171 base::Bind(&MostVisitedSites::OnMostVisitedURLsAvailable,
172 weak_ptr_factory_.GetWeakPtr()),
[email protected]7ceb4e32013-12-06 04:13:04173 false);
174}
175
atanasova9c0dda602016-03-22 17:41:13176base::FilePath MostVisitedSites::GetWhitelistLargeIconPath(const GURL& url) {
sfiera87db8582016-08-05 10:46:42177 if (supervisor_) {
178 for (const auto& whitelist : supervisor_->whitelists()) {
179 if (AreURLsEquivalent(whitelist.entry_point, url))
180 return whitelist.large_icon_path;
181 }
atanasova9c0dda602016-03-22 17:41:13182 }
183 return base::FilePath();
184}
185
[email protected]d4975242014-06-02 18:16:20186void MostVisitedSites::OnMostVisitedURLsAvailable(
[email protected]d4975242014-06-02 18:16:20187 const history::MostVisitedURLList& visited_list) {
sfiera635d21d2016-08-04 07:56:09188 NTPTilesVector tiles;
knncbbd754d2015-09-09 15:43:40189 size_t num_tiles =
190 std::min(visited_list.size(), static_cast<size_t>(num_sites_));
191 for (size_t i = 0; i < num_tiles; ++i) {
knn6cf777fc2015-05-06 13:21:48192 const history::MostVisitedURL& visited = visited_list[i];
193 if (visited.url.is_empty()) {
194 num_tiles = i;
195 break; // This is the signal that there are no more real visited sites.
196 }
sfiera87db8582016-08-05 10:46:42197 if (supervisor_ && supervisor_->IsBlocked(visited.url))
atanasova9514b302016-02-26 23:09:28198 continue;
atanasova9514b302016-02-26 23:09:28199
sfiera635d21d2016-08-04 07:56:09200 NTPTile tile;
201 tile.title = visited.title;
202 tile.url = visited.url;
203 tile.source = NTPTileSource::TOP_SITES;
204 tile.whitelist_icon_path = GetWhitelistLargeIconPath(visited.url);
atanasovac3c25d12016-03-17 18:33:57205
sfiera635d21d2016-08-04 07:56:09206 tiles.push_back(std::move(tile));
knn6cf777fc2015-05-06 13:21:48207 }
[email protected]d4975242014-06-02 18:16:20208
sfiera635d21d2016-08-04 07:56:09209 mv_source_ = NTPTileSource::TOP_SITES;
210 SaveNewTiles(std::move(tiles));
knncbbd754d2015-09-09 15:43:40211 NotifyMostVisitedURLsObserver();
[email protected]d4975242014-06-02 18:16:20212}
213
[email protected]bc093e82014-03-04 21:49:11214void MostVisitedSites::OnSuggestionsProfileAvailable(
[email protected]bc093e82014-03-04 21:49:11215 const SuggestionsProfile& suggestions_profile) {
knn6cf777fc2015-05-06 13:21:48216 int num_tiles = suggestions_profile.suggestions_size();
treibc1bd1f12016-04-29 15:06:05217 // With no server suggestions, fall back to local TopSites.
mastizf3468a82016-06-15 11:05:41218 if (num_tiles == 0 ||
219 !base::FeatureList::IsEnabled(kDisplaySuggestionsServiceTiles)) {
[email protected]bc093e82014-03-04 21:49:11220 InitiateTopSitesQuery();
221 return;
222 }
knn6cf777fc2015-05-06 13:21:48223 if (num_sites_ < num_tiles)
224 num_tiles = num_sites_;
[email protected]bc093e82014-03-04 21:49:11225
sfiera635d21d2016-08-04 07:56:09226 NTPTilesVector tiles;
knn6cf777fc2015-05-06 13:21:48227 for (int i = 0; i < num_tiles; ++i) {
treibd2698222016-07-14 11:32:44228 const ChromeSuggestion& suggestion_pb = suggestions_profile.suggestions(i);
229 GURL url(suggestion_pb.url());
sfiera87db8582016-08-05 10:46:42230 if (supervisor_ && supervisor_->IsBlocked(url))
atanasova9514b302016-02-26 23:09:28231 continue;
atanasova9514b302016-02-26 23:09:28232
sfiera635d21d2016-08-04 07:56:09233 NTPTile tile;
234 tile.title = base::UTF8ToUTF16(suggestion_pb.title());
235 tile.url = url;
236 tile.source = NTPTileSource::SUGGESTIONS_SERVICE;
237 tile.whitelist_icon_path = GetWhitelistLargeIconPath(url);
treibbb0c5af52016-12-09 17:34:15238 tile.thumbnail_url = GURL(suggestion_pb.thumbnail());
239 tile.favicon_url = GURL(suggestion_pb.favicon_url());
atanasovac3c25d12016-03-17 18:33:57240
sfiera635d21d2016-08-04 07:56:09241 tiles.push_back(std::move(tile));
[email protected]bc093e82014-03-04 21:49:11242 }
treib783a3372015-08-25 16:24:39243
sfiera635d21d2016-08-04 07:56:09244 mv_source_ = NTPTileSource::SUGGESTIONS_SERVICE;
245 SaveNewTiles(std::move(tiles));
knncbbd754d2015-09-09 15:43:40246 NotifyMostVisitedURLsObserver();
knn6cf777fc2015-05-06 13:21:48247}
[email protected]d4975242014-06-02 18:16:20248
sfiera635d21d2016-08-04 07:56:09249NTPTilesVector MostVisitedSites::CreateWhitelistEntryPointTiles(
250 const NTPTilesVector& personal_tiles) {
sfiera87db8582016-08-05 10:46:42251 if (!supervisor_) {
252 return NTPTilesVector();
253 }
254
sfiera635d21d2016-08-04 07:56:09255 size_t num_personal_tiles = personal_tiles.size();
256 DCHECK_LE(num_personal_tiles, static_cast<size_t>(num_sites_));
treibcffa6502015-08-06 09:12:27257
sfiera635d21d2016-08-04 07:56:09258 size_t num_whitelist_tiles = num_sites_ - num_personal_tiles;
259 NTPTilesVector whitelist_tiles;
atanasova9572aaf2016-02-26 18:08:26260
atanasova9514b302016-02-26 23:09:28261 std::set<std::string> personal_hosts;
sfiera635d21d2016-08-04 07:56:09262 for (const auto& tile : personal_tiles)
263 personal_hosts.insert(tile.url.host());
atanasova9572aaf2016-02-26 18:08:26264
sfiera79e643b2016-05-13 16:52:49265 for (const auto& whitelist : supervisor_->whitelists()) {
atanasova9514b302016-02-26 23:09:28266 // Skip blacklisted sites.
treibf7d11512016-06-29 09:06:15267 if (top_sites_ && top_sites_->IsBlacklisted(whitelist.entry_point))
atanasova9514b302016-02-26 23:09:28268 continue;
269
sfiera635d21d2016-08-04 07:56:09270 // Skip tiles already present.
sfiera79e643b2016-05-13 16:52:49271 if (personal_hosts.find(whitelist.entry_point.host()) !=
atanasova9514b302016-02-26 23:09:28272 personal_hosts.end())
273 continue;
274
275 // Skip whitelist entry points that are manually blocked.
sfiera79e643b2016-05-13 16:52:49276 if (supervisor_->IsBlocked(whitelist.entry_point))
atanasova9514b302016-02-26 23:09:28277 continue;
atanasova9514b302016-02-26 23:09:28278
sfiera635d21d2016-08-04 07:56:09279 NTPTile tile;
280 tile.title = whitelist.title;
281 tile.url = whitelist.entry_point;
282 tile.source = NTPTileSource::WHITELIST;
283 tile.whitelist_icon_path = whitelist.large_icon_path;
atanasovac3c25d12016-03-17 18:33:57284
sfiera635d21d2016-08-04 07:56:09285 whitelist_tiles.push_back(std::move(tile));
286 if (whitelist_tiles.size() >= num_whitelist_tiles)
atanasova9572aaf2016-02-26 18:08:26287 break;
288 }
289
sfiera635d21d2016-08-04 07:56:09290 return whitelist_tiles;
atanasova9572aaf2016-02-26 18:08:26291}
292
sfiera635d21d2016-08-04 07:56:09293NTPTilesVector MostVisitedSites::CreatePopularSitesTiles(
294 const NTPTilesVector& personal_tiles,
295 const NTPTilesVector& whitelist_tiles) {
296 // For child accounts popular sites tiles will not be added.
sfiera87db8582016-08-05 10:46:42297 if (supervisor_ && supervisor_->IsChildProfile())
sfiera635d21d2016-08-04 07:56:09298 return NTPTilesVector();
atanasova9514b302016-02-26 23:09:28299
sfiera635d21d2016-08-04 07:56:09300 size_t num_tiles = personal_tiles.size() + whitelist_tiles.size();
301 DCHECK_LE(num_tiles, static_cast<size_t>(num_sites_));
atanasova9572aaf2016-02-26 18:08:26302
knncbbd754d2015-09-09 15:43:40303 // Collect non-blacklisted popular suggestions, skipping those already present
304 // in the personal suggestions.
sfiera635d21d2016-08-04 07:56:09305 size_t num_popular_sites_tiles = num_sites_ - num_tiles;
306 NTPTilesVector popular_sites_tiles;
treibcffa6502015-08-06 09:12:27307
sfiera635d21d2016-08-04 07:56:09308 if (num_popular_sites_tiles > 0 && popular_sites_) {
atanasova9514b302016-02-26 23:09:28309 std::set<std::string> hosts;
sfiera635d21d2016-08-04 07:56:09310 for (const auto& tile : personal_tiles)
311 hosts.insert(tile.url.host());
312 for (const auto& tile : whitelist_tiles)
313 hosts.insert(tile.url.host());
knncbbd754d2015-09-09 15:43:40314 for (const PopularSites::Site& popular_site : popular_sites_->sites()) {
315 // Skip blacklisted sites.
treibf7d11512016-06-29 09:06:15316 if (top_sites_ && top_sites_->IsBlacklisted(popular_site.url))
knncbbd754d2015-09-09 15:43:40317 continue;
318 std::string host = popular_site.url.host();
sfiera635d21d2016-08-04 07:56:09319 // Skip tiles already present in personal or whitelists.
atanasova9514b302016-02-26 23:09:28320 if (hosts.find(host) != hosts.end())
knncbbd754d2015-09-09 15:43:40321 continue;
treibcffa6502015-08-06 09:12:27322
sfiera635d21d2016-08-04 07:56:09323 NTPTile tile;
324 tile.title = popular_site.title;
325 tile.url = GURL(popular_site.url);
326 tile.source = NTPTileSource::POPULAR;
atanasovac3c25d12016-03-17 18:33:57327
sfiera635d21d2016-08-04 07:56:09328 popular_sites_tiles.push_back(std::move(tile));
sfieraae1ae692016-10-24 18:19:15329 icon_cacher_->StartFetch(
330 popular_site, base::Bind(&MostVisitedSites::OnIconMadeAvailable,
331 base::Unretained(this), popular_site.url));
sfiera635d21d2016-08-04 07:56:09332 if (popular_sites_tiles.size() >= num_popular_sites_tiles)
knncbbd754d2015-09-09 15:43:40333 break;
334 }
treibcffa6502015-08-06 09:12:27335 }
sfiera635d21d2016-08-04 07:56:09336 return popular_sites_tiles;
atanasova9572aaf2016-02-26 18:08:26337}
338
sfiera635d21d2016-08-04 07:56:09339void MostVisitedSites::SaveNewTiles(NTPTilesVector personal_tiles) {
340 NTPTilesVector whitelist_tiles =
341 CreateWhitelistEntryPointTiles(personal_tiles);
342 NTPTilesVector popular_sites_tiles =
343 CreatePopularSitesTiles(personal_tiles, whitelist_tiles);
treib5a59f542016-05-18 12:17:29344
sfiera635d21d2016-08-04 07:56:09345 size_t num_actual_tiles = personal_tiles.size() + whitelist_tiles.size() +
346 popular_sites_tiles.size();
treib5a59f542016-05-18 12:17:29347 DCHECK_LE(num_actual_tiles, static_cast<size_t>(num_sites_));
348
sfiera635d21d2016-08-04 07:56:09349 current_tiles_ =
350 MergeTiles(std::move(personal_tiles), std::move(whitelist_tiles),
351 std::move(popular_sites_tiles));
352 DCHECK_EQ(num_actual_tiles, current_tiles_.size());
treib5a59f542016-05-18 12:17:29353
sfiera635d21d2016-08-04 07:56:09354 int num_personal_tiles = 0;
355 for (const auto& tile : current_tiles_) {
356 if (tile.source != NTPTileSource::POPULAR)
357 num_personal_tiles++;
treibcd3d2ef2016-07-13 16:53:31358 }
sfiera635d21d2016-08-04 07:56:09359 prefs_->SetInteger(prefs::kNumPersonalTiles, num_personal_tiles);
treibcf674e62015-08-17 15:43:01360}
361
362// static
sfiera635d21d2016-08-04 07:56:09363NTPTilesVector MostVisitedSites::MergeTiles(NTPTilesVector personal_tiles,
364 NTPTilesVector whitelist_tiles,
365 NTPTilesVector popular_tiles) {
366 NTPTilesVector merged_tiles;
367 std::move(personal_tiles.begin(), personal_tiles.end(),
368 std::back_inserter(merged_tiles));
369 std::move(whitelist_tiles.begin(), whitelist_tiles.end(),
370 std::back_inserter(merged_tiles));
371 std::move(popular_tiles.begin(), popular_tiles.end(),
372 std::back_inserter(merged_tiles));
373 return merged_tiles;
treibcffa6502015-08-06 09:12:27374}
375
knncbbd754d2015-09-09 15:43:40376void MostVisitedSites::NotifyMostVisitedURLsObserver() {
sfiera1e7993c62016-04-18 09:43:26377 if (!observer_)
treib16070ce2016-03-11 11:57:40378 return;
379
sfiera635d21d2016-08-04 07:56:09380 observer_->OnMostVisitedURLsAvailable(current_tiles_);
[email protected]bc093e82014-03-04 21:49:11381}
382
treibcffa6502015-08-06 09:12:27383void MostVisitedSites::OnPopularSitesAvailable(bool success) {
384 if (!success) {
385 LOG(WARNING) << "Download of popular sites failed";
386 return;
387 }
388
sfiera635d21d2016-08-04 07:56:09389 // Re-build the tile list. Once done, this will notify the observer.
390 BuildCurrentTiles();
treibcffa6502015-08-06 09:12:27391}
392
sfieraae1ae692016-10-24 18:19:15393void MostVisitedSites::OnIconMadeAvailable(const GURL& site_url,
394 bool newly_available) {
395 if (newly_available)
396 observer_->OnIconMadeAvailable(site_url);
397}
398
treib16070ce2016-03-11 11:57:40399void MostVisitedSites::TopSitesLoaded(TopSites* top_sites) {}
sdefresneedf9e01f2015-01-13 19:45:41400
treib16070ce2016-03-11 11:57:40401void MostVisitedSites::TopSitesChanged(TopSites* top_sites,
fserbdb575112015-06-29 21:31:59402 ChangeReason change_reason) {
sfiera635d21d2016-08-04 07:56:09403 if (mv_source_ == NTPTileSource::TOP_SITES) {
404 // The displayed tiles are invalidated.
newt2a47ce72015-10-01 20:09:49405 InitiateTopSitesQuery();
sdefresneedf9e01f2015-01-13 19:45:41406 }
407}
sfiera08009fe2016-06-15 17:07:26408
409} // namespace ntp_tiles