blob: f7a90a89b9e6437bcdf979561b522143f1fb8736 [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
mastiz73693f12017-01-27 15:52:5712#include "base/bind.h"
[email protected]d33adb40d2014-06-03 21:38:4613#include "base/callback.h"
mastizf3468a82016-06-15 11:05:4114#include "base/feature_list.h"
[email protected]bc093e82014-03-04 21:49:1115#include "base/strings/utf_string_conversions.h"
sdefresne0da3bc02015-01-29 18:26:3516#include "components/history/core/browser/top_sites.h"
treibdb416392016-06-29 17:20:5017#include "components/ntp_tiles/constants.h"
Eric Noyau4793d932016-11-16 16:19:2318#include "components/ntp_tiles/field_trial.h"
sfieraae1ae692016-10-24 18:19:1519#include "components/ntp_tiles/icon_cacher.h"
sfiera0dc4da52016-04-29 09:23:0520#include "components/ntp_tiles/pref_names.h"
21#include "components/ntp_tiles/switches.h"
knncbbd754d2015-09-09 15:43:4022#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0823#include "components/prefs/pref_service.h"
[email protected]c764b2822013-07-03 04:16:4824
[email protected]c764b2822013-07-03 04:16:4825using history::TopSites;
[email protected]bc093e82014-03-04 21:49:1126using suggestions::ChromeSuggestion;
27using suggestions::SuggestionsProfile;
sfiera7e952d42016-05-04 17:56:3328using suggestions::SuggestionsService;
[email protected]c764b2822013-07-03 04:16:4829
sfiera08009fe2016-06-15 17:07:2630namespace ntp_tiles {
31
[email protected]c764b2822013-07-03 04:16:4832namespace {
33
mastizf3468a82016-06-15 11:05:4134const base::Feature kDisplaySuggestionsServiceTiles{
35 "DisplaySuggestionsServiceTiles", base::FEATURE_ENABLED_BY_DEFAULT};
36
sfiera635d21d2016-08-04 07:56:0937// Determine whether we need any tiles from PopularSites to fill up a grid of
treibf79ed40d2015-09-22 12:38:0638// |num_tiles| tiles.
treibcd3d2ef2016-07-13 16:53:3139bool NeedPopularSites(const PrefService* prefs, int num_tiles) {
treib41b5968d2016-10-13 08:14:2240 return prefs->GetInteger(prefs::kNumPersonalTiles) < num_tiles;
treibf79ed40d2015-09-22 12:38:0641}
42
atanasova9c0dda602016-03-22 17:41:1343bool AreURLsEquivalent(const GURL& url1, const GURL& url2) {
csharrison88b3b712016-11-14 23:12:3544 return url1.host_piece() == url2.host_piece() &&
45 url1.path_piece() == url2.path_piece();
atanasova9c0dda602016-03-22 17:41:1346}
47
sfiera8df7b382016-04-26 14:06:3348} // namespace
49
sfierac35d2722016-12-14 09:41:4550MostVisitedSites::MostVisitedSites(
51 PrefService* prefs,
52 scoped_refptr<history::TopSites> top_sites,
53 SuggestionsService* suggestions,
54 std::unique_ptr<PopularSites> popular_sites,
55 std::unique_ptr<IconCacher> icon_cacher,
56 std::unique_ptr<MostVisitedSitesSupervisor> supervisor)
sfiera79e643b2016-05-13 16:52:4957 : prefs_(prefs),
sfiera685a987e2016-05-12 17:08:4758 top_sites_(top_sites),
59 suggestions_service_(suggestions),
sfiera96c03252016-09-14 18:58:1660 popular_sites_(std::move(popular_sites)),
sfieraae1ae692016-10-24 18:19:1561 icon_cacher_(std::move(icon_cacher)),
sfierac35d2722016-12-14 09:41:4562 supervisor_(std::move(supervisor)),
sfiera685a987e2016-05-12 17:08:4763 observer_(nullptr),
64 num_sites_(0),
treibbaada0f2016-08-01 11:30:3365 top_sites_observer_(this),
mastiz64840862017-01-05 12:42:3166 mv_source_(NTPTileSource::TOP_SITES),
mastizd0da75e2017-01-09 11:36:4867 top_sites_weak_ptr_factory_(this) {
sfiera87db8582016-08-05 10:46:4268 DCHECK(prefs_);
sfieraaa1b8862016-10-04 16:09:2369 // top_sites_ can be null in tests.
70 // TODO(sfiera): have iOS use a dummy TopSites in its tests.
mastizc60d74e2016-06-14 14:02:4971 DCHECK(suggestions_service_);
sfiera87db8582016-08-05 10:46:4272 if (supervisor_)
73 supervisor_->SetObserver(this);
[email protected]7ceb4e32013-12-06 04:13:0474}
[email protected]c764b2822013-07-03 04:16:4875
[email protected]7ceb4e32013-12-06 04:13:0476MostVisitedSites::~MostVisitedSites() {
sfiera87db8582016-08-05 10:46:4277 if (supervisor_)
78 supervisor_->SetObserver(nullptr);
[email protected]7ceb4e32013-12-06 04:13:0479}
[email protected]c764b2822013-07-03 04:16:4880
treib5a59f542016-05-18 12:17:2981void MostVisitedSites::SetMostVisitedURLsObserver(Observer* observer,
82 int num_sites) {
treibc1bd1f12016-04-29 15:06:0583 DCHECK(observer);
sfiera929502f32016-04-21 12:52:4884 observer_ = observer;
[email protected]7ceb4e32013-12-06 04:13:0485 num_sites_ = num_sites;
[email protected]852fc792013-10-04 04:15:1286
treib99f6b992016-11-23 13:59:5087 // The order for this condition is important, ShouldShowPopularSites() should
Eric Noyau4793d932016-11-16 16:19:2388 // always be called last to keep metrics as relevant as possible.
89 if (popular_sites_ && NeedPopularSites(prefs_, num_sites_) &&
90 ShouldShowPopularSites()) {
mastizfd2c7ab2017-01-27 19:35:0091 popular_sites_->MaybeStartFetch(
92 false, base::Bind(&MostVisitedSites::OnPopularSitesDownloaded,
sfiera00a58ab2016-07-28 10:20:4993 base::Unretained(this)));
treibf79ed40d2015-09-22 12:38:0694 }
95
treibf7d11512016-06-29 09:06:1596 if (top_sites_) {
97 // TopSites updates itself after a delay. To ensure up-to-date results,
98 // force an update now.
99 top_sites_->SyncWithHistory();
[email protected]7ceb4e32013-12-06 04:13:04100
treibf7d11512016-06-29 09:06:15101 // Register as TopSitesObserver so that we can update ourselves when the
102 // TopSites changes.
treibbaada0f2016-08-01 11:30:33103 top_sites_observer_.Add(top_sites_.get());
treibf7d11512016-06-29 09:06:15104 }
treibcb9c93b2016-04-01 13:22:52105
mastizbad28af2017-01-30 16:04:37106 suggestions_subscription_ = suggestions_service_->AddCallback(base::Bind(
107 &MostVisitedSites::OnSuggestionsProfileChanged, base::Unretained(this)));
treibcb9c93b2016-04-01 13:22:52108
sfiera635d21d2016-08-04 07:56:09109 // Immediately build the current set of tiles, getting suggestions from the
110 // SuggestionsService's cache or, if that is empty, sites from TopSites.
111 BuildCurrentTiles();
treibcb9c93b2016-04-01 13:22:52112 // Also start a request for fresh suggestions.
treibbb0c5af52016-12-09 17:34:15113 Refresh();
114}
115
116void MostVisitedSites::Refresh() {
sfiera728962f2016-04-29 11:04:02117 suggestions_service_->FetchSuggestionsData();
[email protected]c764b2822013-07-03 04:16:48118}
119
treib5a59f542016-05-18 12:17:29120void MostVisitedSites::AddOrRemoveBlacklistedUrl(const GURL& url,
121 bool add_url) {
treibf7d11512016-06-29 09:06:15122 if (top_sites_) {
123 // Always blacklist in the local TopSites.
124 if (add_url)
125 top_sites_->AddBlacklistedURL(url);
126 else
127 top_sites_->RemoveBlacklistedURL(url);
128 }
[email protected]d4975242014-06-02 18:16:20129
treibfac75192015-08-17 13:21:24130 // Only blacklist in the server-side suggestions service if it's active.
sfiera635d21d2016-08-04 07:56:09131 if (mv_source_ == NTPTileSource::SUGGESTIONS_SERVICE) {
treib16070ce2016-03-11 11:57:40132 if (add_url)
sfiera728962f2016-04-29 11:04:02133 suggestions_service_->BlacklistURL(url);
treib16070ce2016-03-11 11:57:40134 else
sfiera728962f2016-04-29 11:04:02135 suggestions_service_->UndoBlacklistURL(url);
[email protected]d4975242014-06-02 18:16:20136 }
[email protected]a4c2f282013-07-20 05:26:05137}
[email protected]7ceb4e32013-12-06 04:13:04138
treibbb0c5af52016-12-09 17:34:15139void MostVisitedSites::ClearBlacklistedUrls() {
140 if (top_sites_) {
141 // Always update the blacklist in the local TopSites.
142 top_sites_->ClearBlacklistedURLs();
143 }
144
145 // Only update the server-side blacklist if it's active.
146 if (mv_source_ == NTPTileSource::SUGGESTIONS_SERVICE) {
147 suggestions_service_->ClearBlacklist();
148 }
149}
150
sfiera79e643b2016-05-13 16:52:49151void MostVisitedSites::OnBlockedSitesChanged() {
sfiera635d21d2016-08-04 07:56:09152 BuildCurrentTiles();
atanasova9572aaf2016-02-26 18:08:26153}
154
[email protected]7ceb4e32013-12-06 04:13:04155// static
knncbbd754d2015-09-09 15:43:40156void MostVisitedSites::RegisterProfilePrefs(
157 user_prefs::PrefRegistrySyncable* registry) {
sfiera635d21d2016-08-04 07:56:09158 registry->RegisterIntegerPref(prefs::kNumPersonalTiles, 0);
knncbbd754d2015-09-09 15:43:40159}
160
[email protected]bc093e82014-03-04 21:49:11161void MostVisitedSites::InitiateTopSitesQuery() {
treibf7d11512016-06-29 09:06:15162 if (!top_sites_)
163 return;
mastizd0da75e2017-01-09 11:36:48164 if (top_sites_weak_ptr_factory_.HasWeakPtrs())
165 return; // Ongoing query.
sfiera728962f2016-04-29 11:04:02166 top_sites_->GetMostVisitedURLs(
knn6cf777fc2015-05-06 13:21:48167 base::Bind(&MostVisitedSites::OnMostVisitedURLsAvailable,
mastizd0da75e2017-01-09 11:36:48168 top_sites_weak_ptr_factory_.GetWeakPtr()),
[email protected]7ceb4e32013-12-06 04:13:04169 false);
170}
171
atanasova9c0dda602016-03-22 17:41:13172base::FilePath MostVisitedSites::GetWhitelistLargeIconPath(const GURL& url) {
sfiera87db8582016-08-05 10:46:42173 if (supervisor_) {
174 for (const auto& whitelist : supervisor_->whitelists()) {
175 if (AreURLsEquivalent(whitelist.entry_point, url))
176 return whitelist.large_icon_path;
177 }
atanasova9c0dda602016-03-22 17:41:13178 }
179 return base::FilePath();
180}
181
[email protected]d4975242014-06-02 18:16:20182void MostVisitedSites::OnMostVisitedURLsAvailable(
[email protected]d4975242014-06-02 18:16:20183 const history::MostVisitedURLList& visited_list) {
mastiz64840862017-01-05 12:42:31184 // Ignore the event if tiles provided by the Suggestions Service, which take
185 // precedence.
186 if (mv_source_ == NTPTileSource::SUGGESTIONS_SERVICE) {
187 return;
188 }
189
sfiera635d21d2016-08-04 07:56:09190 NTPTilesVector tiles;
knncbbd754d2015-09-09 15:43:40191 size_t num_tiles =
192 std::min(visited_list.size(), static_cast<size_t>(num_sites_));
193 for (size_t i = 0; i < num_tiles; ++i) {
knn6cf777fc2015-05-06 13:21:48194 const history::MostVisitedURL& visited = visited_list[i];
195 if (visited.url.is_empty()) {
196 num_tiles = i;
197 break; // This is the signal that there are no more real visited sites.
198 }
sfiera87db8582016-08-05 10:46:42199 if (supervisor_ && supervisor_->IsBlocked(visited.url))
atanasova9514b302016-02-26 23:09:28200 continue;
atanasova9514b302016-02-26 23:09:28201
sfiera635d21d2016-08-04 07:56:09202 NTPTile tile;
203 tile.title = visited.title;
204 tile.url = visited.url;
205 tile.source = NTPTileSource::TOP_SITES;
206 tile.whitelist_icon_path = GetWhitelistLargeIconPath(visited.url);
atanasovac3c25d12016-03-17 18:33:57207
sfiera635d21d2016-08-04 07:56:09208 tiles.push_back(std::move(tile));
knn6cf777fc2015-05-06 13:21:48209 }
[email protected]d4975242014-06-02 18:16:20210
sfiera635d21d2016-08-04 07:56:09211 mv_source_ = NTPTileSource::TOP_SITES;
212 SaveNewTiles(std::move(tiles));
knncbbd754d2015-09-09 15:43:40213 NotifyMostVisitedURLsObserver();
[email protected]d4975242014-06-02 18:16:20214}
215
mastizbad28af2017-01-30 16:04:37216void MostVisitedSites::OnSuggestionsProfileChanged(
[email protected]bc093e82014-03-04 21:49:11217 const SuggestionsProfile& suggestions_profile) {
mastizbad28af2017-01-30 16:04:37218 if (suggestions_profile.suggestions_size() == 0 &&
219 mv_source_ != NTPTileSource::SUGGESTIONS_SERVICE) {
220 return;
221 }
222
223 BuildCurrentTilesGivenSuggestionsProfile(suggestions_profile);
224}
225
226void MostVisitedSites::BuildCurrentTiles() {
227 BuildCurrentTilesGivenSuggestionsProfile(
228 suggestions_service_->GetSuggestionsDataFromCache().value_or(
229 SuggestionsProfile()));
230}
231
232void MostVisitedSites::BuildCurrentTilesGivenSuggestionsProfile(
233 const suggestions::SuggestionsProfile& suggestions_profile) {
knn6cf777fc2015-05-06 13:21:48234 int num_tiles = suggestions_profile.suggestions_size();
treibc1bd1f12016-04-29 15:06:05235 // With no server suggestions, fall back to local TopSites.
mastizf3468a82016-06-15 11:05:41236 if (num_tiles == 0 ||
237 !base::FeatureList::IsEnabled(kDisplaySuggestionsServiceTiles)) {
mastiz64840862017-01-05 12:42:31238 mv_source_ = NTPTileSource::TOP_SITES;
[email protected]bc093e82014-03-04 21:49:11239 InitiateTopSitesQuery();
240 return;
241 }
knn6cf777fc2015-05-06 13:21:48242 if (num_sites_ < num_tiles)
243 num_tiles = num_sites_;
[email protected]bc093e82014-03-04 21:49:11244
sfiera635d21d2016-08-04 07:56:09245 NTPTilesVector tiles;
knn6cf777fc2015-05-06 13:21:48246 for (int i = 0; i < num_tiles; ++i) {
treibd2698222016-07-14 11:32:44247 const ChromeSuggestion& suggestion_pb = suggestions_profile.suggestions(i);
248 GURL url(suggestion_pb.url());
sfiera87db8582016-08-05 10:46:42249 if (supervisor_ && supervisor_->IsBlocked(url))
atanasova9514b302016-02-26 23:09:28250 continue;
atanasova9514b302016-02-26 23:09:28251
sfiera635d21d2016-08-04 07:56:09252 NTPTile tile;
253 tile.title = base::UTF8ToUTF16(suggestion_pb.title());
254 tile.url = url;
255 tile.source = NTPTileSource::SUGGESTIONS_SERVICE;
256 tile.whitelist_icon_path = GetWhitelistLargeIconPath(url);
treibbb0c5af52016-12-09 17:34:15257 tile.thumbnail_url = GURL(suggestion_pb.thumbnail());
258 tile.favicon_url = GURL(suggestion_pb.favicon_url());
atanasovac3c25d12016-03-17 18:33:57259
sfiera635d21d2016-08-04 07:56:09260 tiles.push_back(std::move(tile));
[email protected]bc093e82014-03-04 21:49:11261 }
treib783a3372015-08-25 16:24:39262
sfiera635d21d2016-08-04 07:56:09263 mv_source_ = NTPTileSource::SUGGESTIONS_SERVICE;
264 SaveNewTiles(std::move(tiles));
knncbbd754d2015-09-09 15:43:40265 NotifyMostVisitedURLsObserver();
knn6cf777fc2015-05-06 13:21:48266}
[email protected]d4975242014-06-02 18:16:20267
sfiera635d21d2016-08-04 07:56:09268NTPTilesVector MostVisitedSites::CreateWhitelistEntryPointTiles(
269 const NTPTilesVector& personal_tiles) {
sfiera87db8582016-08-05 10:46:42270 if (!supervisor_) {
271 return NTPTilesVector();
272 }
273
sfiera635d21d2016-08-04 07:56:09274 size_t num_personal_tiles = personal_tiles.size();
275 DCHECK_LE(num_personal_tiles, static_cast<size_t>(num_sites_));
treibcffa6502015-08-06 09:12:27276
sfiera635d21d2016-08-04 07:56:09277 size_t num_whitelist_tiles = num_sites_ - num_personal_tiles;
278 NTPTilesVector whitelist_tiles;
atanasova9572aaf2016-02-26 18:08:26279
atanasova9514b302016-02-26 23:09:28280 std::set<std::string> personal_hosts;
sfiera635d21d2016-08-04 07:56:09281 for (const auto& tile : personal_tiles)
282 personal_hosts.insert(tile.url.host());
atanasova9572aaf2016-02-26 18:08:26283
sfiera79e643b2016-05-13 16:52:49284 for (const auto& whitelist : supervisor_->whitelists()) {
atanasova9514b302016-02-26 23:09:28285 // Skip blacklisted sites.
treibf7d11512016-06-29 09:06:15286 if (top_sites_ && top_sites_->IsBlacklisted(whitelist.entry_point))
atanasova9514b302016-02-26 23:09:28287 continue;
288
sfiera635d21d2016-08-04 07:56:09289 // Skip tiles already present.
sfiera79e643b2016-05-13 16:52:49290 if (personal_hosts.find(whitelist.entry_point.host()) !=
atanasova9514b302016-02-26 23:09:28291 personal_hosts.end())
292 continue;
293
294 // Skip whitelist entry points that are manually blocked.
sfiera79e643b2016-05-13 16:52:49295 if (supervisor_->IsBlocked(whitelist.entry_point))
atanasova9514b302016-02-26 23:09:28296 continue;
atanasova9514b302016-02-26 23:09:28297
sfiera635d21d2016-08-04 07:56:09298 NTPTile tile;
299 tile.title = whitelist.title;
300 tile.url = whitelist.entry_point;
301 tile.source = NTPTileSource::WHITELIST;
302 tile.whitelist_icon_path = whitelist.large_icon_path;
atanasovac3c25d12016-03-17 18:33:57303
sfiera635d21d2016-08-04 07:56:09304 whitelist_tiles.push_back(std::move(tile));
305 if (whitelist_tiles.size() >= num_whitelist_tiles)
atanasova9572aaf2016-02-26 18:08:26306 break;
307 }
308
sfiera635d21d2016-08-04 07:56:09309 return whitelist_tiles;
atanasova9572aaf2016-02-26 18:08:26310}
311
sfiera635d21d2016-08-04 07:56:09312NTPTilesVector MostVisitedSites::CreatePopularSitesTiles(
313 const NTPTilesVector& personal_tiles,
314 const NTPTilesVector& whitelist_tiles) {
315 // For child accounts popular sites tiles will not be added.
sfiera87db8582016-08-05 10:46:42316 if (supervisor_ && supervisor_->IsChildProfile())
sfiera635d21d2016-08-04 07:56:09317 return NTPTilesVector();
atanasova9514b302016-02-26 23:09:28318
sfiera635d21d2016-08-04 07:56:09319 size_t num_tiles = personal_tiles.size() + whitelist_tiles.size();
320 DCHECK_LE(num_tiles, static_cast<size_t>(num_sites_));
atanasova9572aaf2016-02-26 18:08:26321
knncbbd754d2015-09-09 15:43:40322 // Collect non-blacklisted popular suggestions, skipping those already present
323 // in the personal suggestions.
sfiera635d21d2016-08-04 07:56:09324 size_t num_popular_sites_tiles = num_sites_ - num_tiles;
325 NTPTilesVector popular_sites_tiles;
treibcffa6502015-08-06 09:12:27326
sfiera635d21d2016-08-04 07:56:09327 if (num_popular_sites_tiles > 0 && popular_sites_) {
atanasova9514b302016-02-26 23:09:28328 std::set<std::string> hosts;
sfiera635d21d2016-08-04 07:56:09329 for (const auto& tile : personal_tiles)
330 hosts.insert(tile.url.host());
331 for (const auto& tile : whitelist_tiles)
332 hosts.insert(tile.url.host());
knncbbd754d2015-09-09 15:43:40333 for (const PopularSites::Site& popular_site : popular_sites_->sites()) {
334 // Skip blacklisted sites.
treibf7d11512016-06-29 09:06:15335 if (top_sites_ && top_sites_->IsBlacklisted(popular_site.url))
knncbbd754d2015-09-09 15:43:40336 continue;
337 std::string host = popular_site.url.host();
sfiera635d21d2016-08-04 07:56:09338 // Skip tiles already present in personal or whitelists.
atanasova9514b302016-02-26 23:09:28339 if (hosts.find(host) != hosts.end())
knncbbd754d2015-09-09 15:43:40340 continue;
treibcffa6502015-08-06 09:12:27341
sfiera635d21d2016-08-04 07:56:09342 NTPTile tile;
343 tile.title = popular_site.title;
344 tile.url = GURL(popular_site.url);
345 tile.source = NTPTileSource::POPULAR;
atanasovac3c25d12016-03-17 18:33:57346
sfiera635d21d2016-08-04 07:56:09347 popular_sites_tiles.push_back(std::move(tile));
sfieraae1ae692016-10-24 18:19:15348 icon_cacher_->StartFetch(
349 popular_site, base::Bind(&MostVisitedSites::OnIconMadeAvailable,
350 base::Unretained(this), popular_site.url));
sfiera635d21d2016-08-04 07:56:09351 if (popular_sites_tiles.size() >= num_popular_sites_tiles)
knncbbd754d2015-09-09 15:43:40352 break;
353 }
treibcffa6502015-08-06 09:12:27354 }
sfiera635d21d2016-08-04 07:56:09355 return popular_sites_tiles;
atanasova9572aaf2016-02-26 18:08:26356}
357
sfiera635d21d2016-08-04 07:56:09358void MostVisitedSites::SaveNewTiles(NTPTilesVector personal_tiles) {
359 NTPTilesVector whitelist_tiles =
360 CreateWhitelistEntryPointTiles(personal_tiles);
361 NTPTilesVector popular_sites_tiles =
362 CreatePopularSitesTiles(personal_tiles, whitelist_tiles);
treib5a59f542016-05-18 12:17:29363
sfiera635d21d2016-08-04 07:56:09364 size_t num_actual_tiles = personal_tiles.size() + whitelist_tiles.size() +
365 popular_sites_tiles.size();
treib5a59f542016-05-18 12:17:29366 DCHECK_LE(num_actual_tiles, static_cast<size_t>(num_sites_));
367
sfiera635d21d2016-08-04 07:56:09368 current_tiles_ =
369 MergeTiles(std::move(personal_tiles), std::move(whitelist_tiles),
370 std::move(popular_sites_tiles));
371 DCHECK_EQ(num_actual_tiles, current_tiles_.size());
treib5a59f542016-05-18 12:17:29372
sfiera635d21d2016-08-04 07:56:09373 int num_personal_tiles = 0;
374 for (const auto& tile : current_tiles_) {
375 if (tile.source != NTPTileSource::POPULAR)
376 num_personal_tiles++;
treibcd3d2ef2016-07-13 16:53:31377 }
sfiera635d21d2016-08-04 07:56:09378 prefs_->SetInteger(prefs::kNumPersonalTiles, num_personal_tiles);
treibcf674e62015-08-17 15:43:01379}
380
381// static
sfiera635d21d2016-08-04 07:56:09382NTPTilesVector MostVisitedSites::MergeTiles(NTPTilesVector personal_tiles,
383 NTPTilesVector whitelist_tiles,
384 NTPTilesVector popular_tiles) {
385 NTPTilesVector merged_tiles;
386 std::move(personal_tiles.begin(), personal_tiles.end(),
387 std::back_inserter(merged_tiles));
388 std::move(whitelist_tiles.begin(), whitelist_tiles.end(),
389 std::back_inserter(merged_tiles));
390 std::move(popular_tiles.begin(), popular_tiles.end(),
391 std::back_inserter(merged_tiles));
392 return merged_tiles;
treibcffa6502015-08-06 09:12:27393}
394
knncbbd754d2015-09-09 15:43:40395void MostVisitedSites::NotifyMostVisitedURLsObserver() {
sfiera1e7993c62016-04-18 09:43:26396 if (!observer_)
treib16070ce2016-03-11 11:57:40397 return;
398
sfiera635d21d2016-08-04 07:56:09399 observer_->OnMostVisitedURLsAvailable(current_tiles_);
[email protected]bc093e82014-03-04 21:49:11400}
401
mastizfd2c7ab2017-01-27 19:35:00402void MostVisitedSites::OnPopularSitesDownloaded(bool success) {
treibcffa6502015-08-06 09:12:27403 if (!success) {
404 LOG(WARNING) << "Download of popular sites failed";
405 return;
406 }
407
sfiera635d21d2016-08-04 07:56:09408 // Re-build the tile list. Once done, this will notify the observer.
409 BuildCurrentTiles();
treibcffa6502015-08-06 09:12:27410}
411
sfieraae1ae692016-10-24 18:19:15412void MostVisitedSites::OnIconMadeAvailable(const GURL& site_url,
413 bool newly_available) {
414 if (newly_available)
415 observer_->OnIconMadeAvailable(site_url);
416}
417
treib16070ce2016-03-11 11:57:40418void MostVisitedSites::TopSitesLoaded(TopSites* top_sites) {}
sdefresneedf9e01f2015-01-13 19:45:41419
treib16070ce2016-03-11 11:57:40420void MostVisitedSites::TopSitesChanged(TopSites* top_sites,
fserbdb575112015-06-29 21:31:59421 ChangeReason change_reason) {
sfiera635d21d2016-08-04 07:56:09422 if (mv_source_ == NTPTileSource::TOP_SITES) {
423 // The displayed tiles are invalidated.
newt2a47ce72015-10-01 20:09:49424 InitiateTopSitesQuery();
sdefresneedf9e01f2015-01-13 19:45:41425 }
426}
sfiera08009fe2016-06-15 17:07:26427
428} // namespace ntp_tiles