Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(383)

Side by Side Diff: components/ntp_tiles/most_visited_sites.cc

Issue 2619993002: ntp_tiles: Migrate to multi-observer model
Patch Set: Fixed build. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/ntp_tiles/most_visited_sites.h" 5 #include "components/ntp_tiles/most_visited_sites.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 12 matching lines...) Expand all
23 23
24 using history::TopSites; 24 using history::TopSites;
25 using suggestions::ChromeSuggestion; 25 using suggestions::ChromeSuggestion;
26 using suggestions::SuggestionsProfile; 26 using suggestions::SuggestionsProfile;
27 using suggestions::SuggestionsService; 27 using suggestions::SuggestionsService;
28 28
29 namespace ntp_tiles { 29 namespace ntp_tiles {
30 30
31 namespace { 31 namespace {
32 32
33 constexpr int kNumTilesForObservers = 12;
34
33 const base::Feature kDisplaySuggestionsServiceTiles{ 35 const base::Feature kDisplaySuggestionsServiceTiles{
34 "DisplaySuggestionsServiceTiles", base::FEATURE_ENABLED_BY_DEFAULT}; 36 "DisplaySuggestionsServiceTiles", base::FEATURE_ENABLED_BY_DEFAULT};
35 37
36 // Determine whether we need any tiles from PopularSites to fill up a grid of 38 // Determine whether we need any tiles from PopularSites to fill up a grid of
37 // |num_tiles| tiles. 39 // |num_tiles| tiles.
38 bool NeedPopularSites(const PrefService* prefs, int num_tiles) { 40 bool NeedPopularSites(const PrefService* prefs, int num_tiles) {
39 return prefs->GetInteger(prefs::kNumPersonalTiles) < num_tiles; 41 return prefs->GetInteger(prefs::kNumPersonalTiles) < num_tiles;
40 } 42 }
41 43
42 bool AreURLsEquivalent(const GURL& url1, const GURL& url2) { 44 bool AreURLsEquivalent(const GURL& url1, const GURL& url2) {
43 return url1.host_piece() == url2.host_piece() && 45 return url1.host_piece() == url2.host_piece() &&
44 url1.path_piece() == url2.path_piece(); 46 url1.path_piece() == url2.path_piece();
45 } 47 }
46 48
47 } // namespace 49 } // namespace
48 50
49 MostVisitedSites::MostVisitedSites( 51 MostVisitedSites::MostVisitedSites(
50 PrefService* prefs, 52 PrefService* prefs,
51 scoped_refptr<history::TopSites> top_sites, 53 scoped_refptr<history::TopSites> top_sites,
52 SuggestionsService* suggestions, 54 SuggestionsService* suggestions,
53 std::unique_ptr<PopularSites> popular_sites, 55 std::unique_ptr<PopularSites> popular_sites,
54 std::unique_ptr<IconCacher> icon_cacher, 56 std::unique_ptr<IconCacher> icon_cacher,
55 std::unique_ptr<MostVisitedSitesSupervisor> supervisor) 57 std::unique_ptr<MostVisitedSitesSupervisor> supervisor)
56 : prefs_(prefs), 58 : prefs_(prefs),
57 top_sites_(top_sites), 59 top_sites_(top_sites),
58 suggestions_service_(suggestions), 60 suggestions_service_(suggestions),
59 popular_sites_(std::move(popular_sites)), 61 popular_sites_(std::move(popular_sites)),
60 icon_cacher_(std::move(icon_cacher)), 62 icon_cacher_(std::move(icon_cacher)),
61 supervisor_(std::move(supervisor)), 63 supervisor_(std::move(supervisor)),
62 observer_(nullptr),
63 num_sites_(0),
64 top_sites_observer_(this), 64 top_sites_observer_(this),
65 mv_source_(NTPTileSource::TOP_SITES), 65 mv_source_(NTPTileSource::TOP_SITES),
66 top_sites_weak_ptr_factory_(this) { 66 top_sites_weak_ptr_factory_(this) {
67 DCHECK(prefs_); 67 DCHECK(prefs_);
68 // top_sites_ can be null in tests. 68 // top_sites_ can be null in tests.
69 // TODO(sfiera): have iOS use a dummy TopSites in its tests. 69 // TODO(sfiera): have iOS use a dummy TopSites in its tests.
70 DCHECK(suggestions_service_); 70 DCHECK(suggestions_service_);
71 if (supervisor_) 71 if (supervisor_)
72 supervisor_->SetObserver(this); 72 supervisor_->SetObserver(this);
73 }
74
75 MostVisitedSites::~MostVisitedSites() {
76 if (supervisor_)
77 supervisor_->SetObserver(nullptr);
78 }
79
80 void MostVisitedSites::SetMostVisitedURLsObserver(Observer* observer,
81 int num_sites) {
82 DCHECK(observer);
83 observer_ = observer;
84 num_sites_ = num_sites;
85 73
86 // The order for this condition is important, ShouldShowPopularSites() should 74 // The order for this condition is important, ShouldShowPopularSites() should
87 // always be called last to keep metrics as relevant as possible. 75 // always be called last to keep metrics as relevant as possible.
88 if (popular_sites_ && NeedPopularSites(prefs_, num_sites_) && 76 if (popular_sites_ && NeedPopularSites(prefs_, kNumTilesForObservers) &&
89 ShouldShowPopularSites()) { 77 ShouldShowPopularSites()) {
90 popular_sites_->StartFetch( 78 popular_sites_->StartFetch(
91 false, base::Bind(&MostVisitedSites::OnPopularSitesAvailable, 79 false, base::Bind(&MostVisitedSites::OnPopularSitesAvailable,
92 base::Unretained(this))); 80 base::Unretained(this)));
93 } 81 }
94 82
95 if (top_sites_) { 83 if (top_sites_) {
96 // TopSites updates itself after a delay. To ensure up-to-date results,
97 // force an update now.
98 top_sites_->SyncWithHistory();
99
100 // Register as TopSitesObserver so that we can update ourselves when the 84 // Register as TopSitesObserver so that we can update ourselves when the
101 // TopSites changes. 85 // TopSites changes.
102 top_sites_observer_.Add(top_sites_.get()); 86 top_sites_observer_.Add(top_sites_.get());
103 } 87 }
104 88
105 suggestions_subscription_ = suggestions_service_->AddCallback( 89 suggestions_subscription_ = suggestions_service_->AddCallback(
106 base::Bind(&MostVisitedSites::OnSuggestionsProfileAvailable, 90 base::Bind(&MostVisitedSites::OnSuggestionsProfileAvailable,
107 base::Unretained(this))); 91 base::Unretained(this)));
92 }
93
94 MostVisitedSites::~MostVisitedSites() {
95 if (supervisor_)
96 supervisor_->SetObserver(nullptr);
97 }
98
99 void MostVisitedSites::AddObserver(Observer* observer) {
100 observer_list_.AddObserver(observer);
101 }
102
103 void MostVisitedSites::RemoveObserver(Observer* observer) {
104 observer_list_.RemoveObserver(observer);
105 }
106
107 void MostVisitedSites::Refresh() {
108 // TODO(mastiz): Refresh PopularSites too if enabled.
109
110 // TopSites updates itself after a delay. To ensure up-to-date results, force
111 // an update now.
112 if (top_sites_)
113 top_sites_->SyncWithHistory();
108 114
109 // Immediately build the current set of tiles, getting suggestions from the 115 // Immediately build the current set of tiles, getting suggestions from the
110 // SuggestionsService's cache or, if that is empty, sites from TopSites. 116 // SuggestionsService's cache or, if that is empty, sites from TopSites.
111 BuildCurrentTiles(); 117 BuildCurrentTiles();
112 // Also start a request for fresh suggestions. 118 // Also start a request for fresh suggestions.
113 Refresh();
114 }
115
116 void MostVisitedSites::Refresh() {
117 suggestions_service_->FetchSuggestionsData(); 119 suggestions_service_->FetchSuggestionsData();
118 } 120 }
119 121
120 void MostVisitedSites::AddOrRemoveBlacklistedUrl(const GURL& url, 122 void MostVisitedSites::AddOrRemoveBlacklistedUrl(const GURL& url,
121 bool add_url) { 123 bool add_url) {
122 if (top_sites_) { 124 if (top_sites_) {
123 // Always blacklist in the local TopSites. 125 // Always blacklist in the local TopSites.
124 if (add_url) 126 if (add_url)
125 top_sites_->AddBlacklistedURL(url); 127 top_sites_->AddBlacklistedURL(url);
126 else 128 else
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 void MostVisitedSites::OnMostVisitedURLsAvailable( 192 void MostVisitedSites::OnMostVisitedURLsAvailable(
191 const history::MostVisitedURLList& visited_list) { 193 const history::MostVisitedURLList& visited_list) {
192 // Ignore the event if tiles provided by the Suggestions Service, which take 194 // Ignore the event if tiles provided by the Suggestions Service, which take
193 // precedence. 195 // precedence.
194 if (mv_source_ == NTPTileSource::SUGGESTIONS_SERVICE) { 196 if (mv_source_ == NTPTileSource::SUGGESTIONS_SERVICE) {
195 return; 197 return;
196 } 198 }
197 199
198 NTPTilesVector tiles; 200 NTPTilesVector tiles;
199 size_t num_tiles = 201 size_t num_tiles =
200 std::min(visited_list.size(), static_cast<size_t>(num_sites_)); 202 std::min(visited_list.size(), static_cast<size_t>(kNumTilesForObservers));
201 for (size_t i = 0; i < num_tiles; ++i) { 203 for (size_t i = 0; i < num_tiles; ++i) {
202 const history::MostVisitedURL& visited = visited_list[i]; 204 const history::MostVisitedURL& visited = visited_list[i];
203 if (visited.url.is_empty()) { 205 if (visited.url.is_empty()) {
204 num_tiles = i; 206 num_tiles = i;
205 break; // This is the signal that there are no more real visited sites. 207 break; // This is the signal that there are no more real visited sites.
206 } 208 }
207 if (supervisor_ && supervisor_->IsBlocked(visited.url)) 209 if (supervisor_ && supervisor_->IsBlocked(visited.url))
208 continue; 210 continue;
209 211
210 NTPTile tile; 212 NTPTile tile;
211 tile.title = visited.title; 213 tile.title = visited.title;
212 tile.url = visited.url; 214 tile.url = visited.url;
213 tile.source = NTPTileSource::TOP_SITES; 215 tile.source = NTPTileSource::TOP_SITES;
214 tile.whitelist_icon_path = GetWhitelistLargeIconPath(visited.url); 216 tile.whitelist_icon_path = GetWhitelistLargeIconPath(visited.url);
215 217
216 tiles.push_back(std::move(tile)); 218 tiles.push_back(std::move(tile));
217 } 219 }
218 220
219 mv_source_ = NTPTileSource::TOP_SITES; 221 mv_source_ = NTPTileSource::TOP_SITES;
220 SaveNewTiles(std::move(tiles)); 222 SaveNewTiles(std::move(tiles));
221 NotifyMostVisitedURLsObserver(); 223 NotifyMostVisitedURLsObservers();
222 } 224 }
223 225
224 void MostVisitedSites::OnSuggestionsProfileAvailable( 226 void MostVisitedSites::OnSuggestionsProfileAvailable(
225 const SuggestionsProfile& suggestions_profile) { 227 const SuggestionsProfile& suggestions_profile) {
226 int num_tiles = suggestions_profile.suggestions_size(); 228 int num_tiles = suggestions_profile.suggestions_size();
227 // With no server suggestions, fall back to local TopSites. 229 // With no server suggestions, fall back to local TopSites.
228 if (num_tiles == 0 || 230 if (num_tiles == 0 ||
229 !base::FeatureList::IsEnabled(kDisplaySuggestionsServiceTiles)) { 231 !base::FeatureList::IsEnabled(kDisplaySuggestionsServiceTiles)) {
230 mv_source_ = NTPTileSource::TOP_SITES; 232 mv_source_ = NTPTileSource::TOP_SITES;
231 InitiateTopSitesQuery(); 233 InitiateTopSitesQuery();
232 return; 234 return;
233 } 235 }
234 if (num_sites_ < num_tiles) 236 if (kNumTilesForObservers < num_tiles)
235 num_tiles = num_sites_; 237 num_tiles = kNumTilesForObservers;
236 238
237 NTPTilesVector tiles; 239 NTPTilesVector tiles;
238 for (int i = 0; i < num_tiles; ++i) { 240 for (int i = 0; i < num_tiles; ++i) {
239 const ChromeSuggestion& suggestion_pb = suggestions_profile.suggestions(i); 241 const ChromeSuggestion& suggestion_pb = suggestions_profile.suggestions(i);
240 GURL url(suggestion_pb.url()); 242 GURL url(suggestion_pb.url());
241 if (supervisor_ && supervisor_->IsBlocked(url)) 243 if (supervisor_ && supervisor_->IsBlocked(url))
242 continue; 244 continue;
243 245
244 NTPTile tile; 246 NTPTile tile;
245 tile.title = base::UTF8ToUTF16(suggestion_pb.title()); 247 tile.title = base::UTF8ToUTF16(suggestion_pb.title());
246 tile.url = url; 248 tile.url = url;
247 tile.source = NTPTileSource::SUGGESTIONS_SERVICE; 249 tile.source = NTPTileSource::SUGGESTIONS_SERVICE;
248 tile.whitelist_icon_path = GetWhitelistLargeIconPath(url); 250 tile.whitelist_icon_path = GetWhitelistLargeIconPath(url);
249 tile.thumbnail_url = GURL(suggestion_pb.thumbnail()); 251 tile.thumbnail_url = GURL(suggestion_pb.thumbnail());
250 tile.favicon_url = GURL(suggestion_pb.favicon_url()); 252 tile.favicon_url = GURL(suggestion_pb.favicon_url());
251 253
252 tiles.push_back(std::move(tile)); 254 tiles.push_back(std::move(tile));
253 } 255 }
254 256
255 mv_source_ = NTPTileSource::SUGGESTIONS_SERVICE; 257 mv_source_ = NTPTileSource::SUGGESTIONS_SERVICE;
256 SaveNewTiles(std::move(tiles)); 258 SaveNewTiles(std::move(tiles));
257 NotifyMostVisitedURLsObserver(); 259 NotifyMostVisitedURLsObservers();
258 } 260 }
259 261
260 NTPTilesVector MostVisitedSites::CreateWhitelistEntryPointTiles( 262 NTPTilesVector MostVisitedSites::CreateWhitelistEntryPointTiles(
261 const NTPTilesVector& personal_tiles) { 263 const NTPTilesVector& personal_tiles) {
262 if (!supervisor_) { 264 if (!supervisor_) {
263 return NTPTilesVector(); 265 return NTPTilesVector();
264 } 266 }
265 267
266 size_t num_personal_tiles = personal_tiles.size(); 268 size_t num_personal_tiles = personal_tiles.size();
267 DCHECK_LE(num_personal_tiles, static_cast<size_t>(num_sites_)); 269 DCHECK_LE(num_personal_tiles, static_cast<size_t>(kNumTilesForObservers));
268 270
269 size_t num_whitelist_tiles = num_sites_ - num_personal_tiles; 271 size_t num_whitelist_tiles = kNumTilesForObservers - num_personal_tiles;
270 NTPTilesVector whitelist_tiles; 272 NTPTilesVector whitelist_tiles;
271 273
272 std::set<std::string> personal_hosts; 274 std::set<std::string> personal_hosts;
273 for (const auto& tile : personal_tiles) 275 for (const auto& tile : personal_tiles)
274 personal_hosts.insert(tile.url.host()); 276 personal_hosts.insert(tile.url.host());
275 277
276 for (const auto& whitelist : supervisor_->whitelists()) { 278 for (const auto& whitelist : supervisor_->whitelists()) {
277 // Skip blacklisted sites. 279 // Skip blacklisted sites.
278 if (top_sites_ && top_sites_->IsBlacklisted(whitelist.entry_point)) 280 if (top_sites_ && top_sites_->IsBlacklisted(whitelist.entry_point))
279 continue; 281 continue;
(...skipping 22 matching lines...) Expand all
302 } 304 }
303 305
304 NTPTilesVector MostVisitedSites::CreatePopularSitesTiles( 306 NTPTilesVector MostVisitedSites::CreatePopularSitesTiles(
305 const NTPTilesVector& personal_tiles, 307 const NTPTilesVector& personal_tiles,
306 const NTPTilesVector& whitelist_tiles) { 308 const NTPTilesVector& whitelist_tiles) {
307 // For child accounts popular sites tiles will not be added. 309 // For child accounts popular sites tiles will not be added.
308 if (supervisor_ && supervisor_->IsChildProfile()) 310 if (supervisor_ && supervisor_->IsChildProfile())
309 return NTPTilesVector(); 311 return NTPTilesVector();
310 312
311 size_t num_tiles = personal_tiles.size() + whitelist_tiles.size(); 313 size_t num_tiles = personal_tiles.size() + whitelist_tiles.size();
312 DCHECK_LE(num_tiles, static_cast<size_t>(num_sites_)); 314 DCHECK_LE(num_tiles, static_cast<size_t>(kNumTilesForObservers));
313 315
314 // Collect non-blacklisted popular suggestions, skipping those already present 316 // Collect non-blacklisted popular suggestions, skipping those already present
315 // in the personal suggestions. 317 // in the personal suggestions.
316 size_t num_popular_sites_tiles = num_sites_ - num_tiles; 318 size_t num_popular_sites_tiles = kNumTilesForObservers - num_tiles;
317 NTPTilesVector popular_sites_tiles; 319 NTPTilesVector popular_sites_tiles;
318 320
319 if (num_popular_sites_tiles > 0 && popular_sites_) { 321 if (num_popular_sites_tiles > 0 && popular_sites_) {
320 std::set<std::string> hosts; 322 std::set<std::string> hosts;
321 for (const auto& tile : personal_tiles) 323 for (const auto& tile : personal_tiles)
322 hosts.insert(tile.url.host()); 324 hosts.insert(tile.url.host());
323 for (const auto& tile : whitelist_tiles) 325 for (const auto& tile : whitelist_tiles)
324 hosts.insert(tile.url.host()); 326 hosts.insert(tile.url.host());
325 for (const PopularSites::Site& popular_site : popular_sites_->sites()) { 327 for (const PopularSites::Site& popular_site : popular_sites_->sites()) {
326 // Skip blacklisted sites. 328 // Skip blacklisted sites.
(...skipping 21 matching lines...) Expand all
348 } 350 }
349 351
350 void MostVisitedSites::SaveNewTiles(NTPTilesVector personal_tiles) { 352 void MostVisitedSites::SaveNewTiles(NTPTilesVector personal_tiles) {
351 NTPTilesVector whitelist_tiles = 353 NTPTilesVector whitelist_tiles =
352 CreateWhitelistEntryPointTiles(personal_tiles); 354 CreateWhitelistEntryPointTiles(personal_tiles);
353 NTPTilesVector popular_sites_tiles = 355 NTPTilesVector popular_sites_tiles =
354 CreatePopularSitesTiles(personal_tiles, whitelist_tiles); 356 CreatePopularSitesTiles(personal_tiles, whitelist_tiles);
355 357
356 size_t num_actual_tiles = personal_tiles.size() + whitelist_tiles.size() + 358 size_t num_actual_tiles = personal_tiles.size() + whitelist_tiles.size() +
357 popular_sites_tiles.size(); 359 popular_sites_tiles.size();
358 DCHECK_LE(num_actual_tiles, static_cast<size_t>(num_sites_)); 360 DCHECK_LE(num_actual_tiles, static_cast<size_t>(kNumTilesForObservers));
359 361
360 current_tiles_ = 362 current_tiles_ =
361 MergeTiles(std::move(personal_tiles), std::move(whitelist_tiles), 363 MergeTiles(std::move(personal_tiles), std::move(whitelist_tiles),
362 std::move(popular_sites_tiles)); 364 std::move(popular_sites_tiles));
363 DCHECK_EQ(num_actual_tiles, current_tiles_.size()); 365 DCHECK_EQ(num_actual_tiles, current_tiles_.size());
364 366
365 int num_personal_tiles = 0; 367 int num_personal_tiles = 0;
366 for (const auto& tile : current_tiles_) { 368 for (const auto& tile : current_tiles_) {
367 if (tile.source != NTPTileSource::POPULAR) 369 if (tile.source != NTPTileSource::POPULAR)
368 num_personal_tiles++; 370 num_personal_tiles++;
369 } 371 }
370 prefs_->SetInteger(prefs::kNumPersonalTiles, num_personal_tiles); 372 prefs_->SetInteger(prefs::kNumPersonalTiles, num_personal_tiles);
371 } 373 }
372 374
373 // static 375 // static
374 NTPTilesVector MostVisitedSites::MergeTiles(NTPTilesVector personal_tiles, 376 NTPTilesVector MostVisitedSites::MergeTiles(NTPTilesVector personal_tiles,
375 NTPTilesVector whitelist_tiles, 377 NTPTilesVector whitelist_tiles,
376 NTPTilesVector popular_tiles) { 378 NTPTilesVector popular_tiles) {
377 NTPTilesVector merged_tiles; 379 NTPTilesVector merged_tiles;
378 std::move(personal_tiles.begin(), personal_tiles.end(), 380 std::move(personal_tiles.begin(), personal_tiles.end(),
379 std::back_inserter(merged_tiles)); 381 std::back_inserter(merged_tiles));
380 std::move(whitelist_tiles.begin(), whitelist_tiles.end(), 382 std::move(whitelist_tiles.begin(), whitelist_tiles.end(),
381 std::back_inserter(merged_tiles)); 383 std::back_inserter(merged_tiles));
382 std::move(popular_tiles.begin(), popular_tiles.end(), 384 std::move(popular_tiles.begin(), popular_tiles.end(),
383 std::back_inserter(merged_tiles)); 385 std::back_inserter(merged_tiles));
384 return merged_tiles; 386 return merged_tiles;
385 } 387 }
386 388
387 void MostVisitedSites::NotifyMostVisitedURLsObserver() { 389 void MostVisitedSites::NotifyMostVisitedURLsObservers() {
388 if (!observer_) 390 for (Observer& observer : observer_list_)
389 return; 391 observer.OnMostVisitedURLsAvailable(current_tiles_);
390
391 observer_->OnMostVisitedURLsAvailable(current_tiles_);
392 } 392 }
393 393
394 void MostVisitedSites::OnPopularSitesAvailable(bool success) { 394 void MostVisitedSites::OnPopularSitesAvailable(bool success) {
395 if (!success) { 395 if (!success) {
396 LOG(WARNING) << "Download of popular sites failed"; 396 LOG(WARNING) << "Download of popular sites failed";
397 return; 397 return;
398 } 398 }
399 399
400 // Re-build the tile list. Once done, this will notify the observer. 400 // Re-build the tile list. Once done, this will notify the observer.
401 BuildCurrentTiles(); 401 BuildCurrentTiles();
402 } 402 }
403 403
404 void MostVisitedSites::OnIconMadeAvailable(const GURL& site_url, 404 void MostVisitedSites::OnIconMadeAvailable(const GURL& site_url,
405 bool newly_available) { 405 bool newly_available) {
406 if (newly_available) 406 for (Observer& observer : observer_list_)
407 observer_->OnIconMadeAvailable(site_url); 407 observer.OnIconMadeAvailable(site_url);
408 } 408 }
409 409
410 void MostVisitedSites::TopSitesLoaded(TopSites* top_sites) {} 410 void MostVisitedSites::TopSitesLoaded(TopSites* top_sites) {}
411 411
412 void MostVisitedSites::TopSitesChanged(TopSites* top_sites, 412 void MostVisitedSites::TopSitesChanged(TopSites* top_sites,
413 ChangeReason change_reason) { 413 ChangeReason change_reason) {
414 if (mv_source_ == NTPTileSource::TOP_SITES) { 414 if (mv_source_ == NTPTileSource::TOP_SITES) {
415 // The displayed tiles are invalidated. 415 // The displayed tiles are invalidated.
416 InitiateTopSitesQuery(); 416 InitiateTopSitesQuery();
417 } 417 }
418 } 418 }
419 419
420 } // namespace ntp_tiles 420 } // namespace ntp_tiles
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698