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

Side by Side Diff: components/ntp_snippets/ntp_snippets_service.cc

Issue 1863133003: [NTP Snippets] Re-fetch snippets on ML changes only when the hosts actually change (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@snippets_thumbnails
Patch Set: s/vector/set/ Created 4 years, 8 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
« no previous file with comments | « components/ntp_snippets/ntp_snippets_service.h ('k') | components/ntp_snippets/pref_names.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_snippets/ntp_snippets_service.h" 5 #include "components/ntp_snippets/ntp_snippets_service.h"
6 6
7 #include <algorithm>
8 #include <utility>
9
7 #include "base/command_line.h" 10 #include "base/command_line.h"
8 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
9 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
10 #include "base/json/json_reader.h" 13 #include "base/json/json_reader.h"
11 #include "base/location.h" 14 #include "base/location.h"
12 #include "base/path_service.h" 15 #include "base/path_service.h"
13 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
14 #include "base/task_runner_util.h" 17 #include "base/task_runner_util.h"
15 #include "base/time/time.h" 18 #include "base/time/time.h"
16 #include "base/values.h" 19 #include "base/values.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 base::TimeDelta GetFetchingIntervalWifi() { 60 base::TimeDelta GetFetchingIntervalWifi() {
58 return GetFetchingInterval(switches::kFetchingIntervalWifiSeconds, 61 return GetFetchingInterval(switches::kFetchingIntervalWifiSeconds,
59 kFetchingIntervalWifiSeconds); 62 kFetchingIntervalWifiSeconds);
60 } 63 }
61 64
62 base::TimeDelta GetFetchingIntervalFallback() { 65 base::TimeDelta GetFetchingIntervalFallback() {
63 return GetFetchingInterval(switches::kFetchingIntervalFallbackSeconds, 66 return GetFetchingInterval(switches::kFetchingIntervalFallbackSeconds,
64 kFetchingIntervalFallbackSeconds); 67 kFetchingIntervalFallbackSeconds);
65 } 68 }
66 69
67 std::vector<std::string> GetSuggestionsHosts( 70 // Extracts the hosts from |suggestions| and returns them in a set.
71 std::set<std::string> GetSuggestionsHosts(
68 const SuggestionsProfile& suggestions) { 72 const SuggestionsProfile& suggestions) {
69 std::vector<std::string> hosts; 73 std::set<std::string> hosts;
70 for (int i = 0; i < suggestions.suggestions_size(); ++i) { 74 for (int i = 0; i < suggestions.suggestions_size(); ++i) {
71 const ChromeSuggestion& suggestion = suggestions.suggestions(i); 75 const ChromeSuggestion& suggestion = suggestions.suggestions(i);
72 GURL url(suggestion.url()); 76 GURL url(suggestion.url());
73 if (url.is_valid()) 77 if (url.is_valid())
74 hosts.push_back(url.host()); 78 hosts.insert(url.host());
75 } 79 }
76 return hosts; 80 return hosts;
77 } 81 }
78 82
79 const char kContentInfo[] = "contentInfo"; 83 const char kContentInfo[] = "contentInfo";
80 84
81 // Parses snippets from |list| and adds them to |snippets|. Returns true on 85 // Parses snippets from |list| and adds them to |snippets|. Returns true on
82 // success, false if anything went wrong. 86 // success, false if anything went wrong.
83 bool AddSnippetsFromListValue(const base::ListValue& list, 87 bool AddSnippetsFromListValue(const base::ListValue& list,
84 NTPSnippetsService::NTPSnippetStorage* snippets) { 88 NTPSnippetsService::NTPSnippetStorage* snippets) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 snippets_fetcher_subscription_ = snippets_fetcher_->AddCallback(base::Bind( 136 snippets_fetcher_subscription_ = snippets_fetcher_->AddCallback(base::Bind(
133 &NTPSnippetsService::OnSnippetsDownloaded, base::Unretained(this))); 137 &NTPSnippetsService::OnSnippetsDownloaded, base::Unretained(this)));
134 } 138 }
135 139
136 NTPSnippetsService::~NTPSnippetsService() {} 140 NTPSnippetsService::~NTPSnippetsService() {}
137 141
138 // static 142 // static
139 void NTPSnippetsService::RegisterProfilePrefs(PrefRegistrySimple* registry) { 143 void NTPSnippetsService::RegisterProfilePrefs(PrefRegistrySimple* registry) {
140 registry->RegisterListPref(prefs::kSnippets); 144 registry->RegisterListPref(prefs::kSnippets);
141 registry->RegisterListPref(prefs::kDiscardedSnippets); 145 registry->RegisterListPref(prefs::kDiscardedSnippets);
146 registry->RegisterListPref(prefs::kSnippetHosts);
142 } 147 }
143 148
144 void NTPSnippetsService::Init(bool enabled) { 149 void NTPSnippetsService::Init(bool enabled) {
145 if (enabled) { 150 if (enabled) {
146 // |suggestions_service_| can be null in tests. 151 // |suggestions_service_| can be null in tests.
147 if (suggestions_service_) { 152 if (suggestions_service_) {
148 suggestions_service_subscription_ = suggestions_service_->AddCallback( 153 suggestions_service_subscription_ = suggestions_service_->AddCallback(
149 base::Bind(&NTPSnippetsService::OnSuggestionsChanged, 154 base::Bind(&NTPSnippetsService::OnSuggestionsChanged,
150 base::Unretained(this))); 155 base::Unretained(this)));
151 } 156 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 if (loaded_) 211 if (loaded_)
207 observer->NTPSnippetsServiceLoaded(this); 212 observer->NTPSnippetsServiceLoaded(this);
208 } 213 }
209 214
210 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) { 215 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) {
211 observers_.RemoveObserver(observer); 216 observers_.RemoveObserver(observer);
212 } 217 }
213 218
214 void NTPSnippetsService::OnSuggestionsChanged( 219 void NTPSnippetsService::OnSuggestionsChanged(
215 const SuggestionsProfile& suggestions) { 220 const SuggestionsProfile& suggestions) {
216 std::vector<std::string> hosts = GetSuggestionsHosts(suggestions); 221 std::set<std::string> hosts = GetSuggestionsHosts(suggestions);
222 if (hosts == GetSnippetHostsFromPrefs())
223 return;
217 224
218 // Remove existing snippets that aren't in the suggestions anymore. 225 // Remove existing snippets that aren't in the suggestions anymore.
219 snippets_.erase( 226 snippets_.erase(
220 std::remove_if(snippets_.begin(), snippets_.end(), 227 std::remove_if(snippets_.begin(), snippets_.end(),
221 [&hosts](const scoped_ptr<NTPSnippet>& snippet) { 228 [&hosts](const scoped_ptr<NTPSnippet>& snippet) {
222 return std::find(hosts.begin(), hosts.end(), 229 return !hosts.count(snippet->url().host());
223 snippet->url().host()) == hosts.end();
224 }), 230 }),
225 snippets_.end()); 231 snippets_.end());
226 232
227 StoreSnippetsToPrefs(); 233 StoreSnippetsToPrefs();
234 StoreSnippetHostsToPrefs(hosts);
228 235
229 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, 236 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_,
230 NTPSnippetsServiceLoaded(this)); 237 NTPSnippetsServiceLoaded(this));
231 238
232 FetchSnippetsImpl(hosts); 239 FetchSnippetsImpl(hosts);
233 } 240 }
234 241
235 void NTPSnippetsService::OnSnippetsDownloaded( 242 void NTPSnippetsService::OnSnippetsDownloaded(
236 const std::string& snippets_json) { 243 const std::string& snippets_json) {
237 parse_json_callback_.Run( 244 parse_json_callback_.Run(
238 snippets_json, base::Bind(&NTPSnippetsService::OnJsonParsed, 245 snippets_json, base::Bind(&NTPSnippetsService::OnJsonParsed,
239 weak_ptr_factory_.GetWeakPtr(), snippets_json), 246 weak_ptr_factory_.GetWeakPtr(), snippets_json),
240 base::Bind(&NTPSnippetsService::OnJsonError, 247 base::Bind(&NTPSnippetsService::OnJsonError,
241 weak_ptr_factory_.GetWeakPtr(), snippets_json)); 248 weak_ptr_factory_.GetWeakPtr(), snippets_json));
242 } 249 }
243 250
244 void NTPSnippetsService::OnJsonParsed(const std::string& snippets_json, 251 void NTPSnippetsService::OnJsonParsed(const std::string& snippets_json,
245 scoped_ptr<base::Value> parsed) { 252 scoped_ptr<base::Value> parsed) {
246 LOG_IF(WARNING, !LoadFromValue(*parsed)) << "Received invalid snippets: " 253 LOG_IF(WARNING, !LoadFromValue(*parsed)) << "Received invalid snippets: "
247 << snippets_json; 254 << snippets_json;
248 } 255 }
249 256
250 void NTPSnippetsService::OnJsonError(const std::string& snippets_json, 257 void NTPSnippetsService::OnJsonError(const std::string& snippets_json,
251 const std::string& error) { 258 const std::string& error) {
252 LOG(WARNING) << "Received invalid JSON (" << error << "): " << snippets_json; 259 LOG(WARNING) << "Received invalid JSON (" << error << "): " << snippets_json;
253 } 260 }
254 261
255 void NTPSnippetsService::FetchSnippetsImpl( 262 void NTPSnippetsService::FetchSnippetsImpl(
256 const std::vector<std::string>& hosts) { 263 const std::set<std::string>& hosts) {
257 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 264 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
258 switches::kDontRestrict)) { 265 switches::kDontRestrict)) {
259 snippets_fetcher_->FetchSnippets(std::vector<std::string>()); 266 snippets_fetcher_->FetchSnippets(std::set<std::string>());
260 return; 267 return;
261 } 268 }
262 if (!hosts.empty()) 269 if (!hosts.empty())
263 snippets_fetcher_->FetchSnippets(hosts); 270 snippets_fetcher_->FetchSnippets(hosts);
264 } 271 }
265 272
266 bool NTPSnippetsService::LoadFromValue(const base::Value& value) { 273 bool NTPSnippetsService::LoadFromValue(const base::Value& value) {
267 const base::DictionaryValue* top_dict = nullptr; 274 const base::DictionaryValue* top_dict = nullptr;
268 if (!value.GetAsDictionary(&top_dict)) 275 if (!value.GetAsDictionary(&top_dict))
269 return false; 276 return false;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 *pref_service_->GetList(prefs::kDiscardedSnippets), 336 *pref_service_->GetList(prefs::kDiscardedSnippets),
330 &discarded_snippets_); 337 &discarded_snippets_);
331 DCHECK(success) << "Failed to parse discarded snippets from prefs"; 338 DCHECK(success) << "Failed to parse discarded snippets from prefs";
332 } 339 }
333 340
334 void NTPSnippetsService::StoreDiscardedSnippetsToPrefs() { 341 void NTPSnippetsService::StoreDiscardedSnippetsToPrefs() {
335 pref_service_->Set(prefs::kDiscardedSnippets, 342 pref_service_->Set(prefs::kDiscardedSnippets,
336 *SnippetsToListValue(discarded_snippets_)); 343 *SnippetsToListValue(discarded_snippets_));
337 } 344 }
338 345
346 std::set<std::string> NTPSnippetsService::GetSnippetHostsFromPrefs() const {
347 std::set<std::string> hosts;
348 const base::ListValue* list = pref_service_->GetList(prefs::kSnippetHosts);
349 for (const base::Value* value : *list) {
350 std::string str;
351 bool success = value->GetAsString(&str);
352 DCHECK(success) << "Failed to parse snippet host from prefs";
353 hosts.insert(std::move(str));
354 }
355 return hosts;
356 }
357
358 void NTPSnippetsService::StoreSnippetHostsToPrefs(
359 const std::set<std::string>& hosts) {
360 base::ListValue list;
361 for (const std::string& host : hosts)
362 list.AppendString(host);
363 pref_service_->Set(prefs::kSnippetHosts, list);
364 }
365
339 bool NTPSnippetsService::HasDiscardedSnippet(const GURL& url) const { 366 bool NTPSnippetsService::HasDiscardedSnippet(const GURL& url) const {
340 auto it = std::find_if(discarded_snippets_.begin(), discarded_snippets_.end(), 367 auto it = std::find_if(discarded_snippets_.begin(), discarded_snippets_.end(),
341 [&url](const scoped_ptr<NTPSnippet>& snippet) { 368 [&url](const scoped_ptr<NTPSnippet>& snippet) {
342 return snippet->url() == url; 369 return snippet->url() == url;
343 }); 370 });
344 return it != discarded_snippets_.end(); 371 return it != discarded_snippets_.end();
345 } 372 }
346 373
347 void NTPSnippetsService::RemoveExpiredSnippets() { 374 void NTPSnippetsService::RemoveExpiredSnippets() {
348 base::Time expiry = base::Time::Now(); 375 base::Time expiry = base::Time::Now();
(...skipping 30 matching lines...) Expand all
379 if (snippet->expiry_date() < next_expiry) 406 if (snippet->expiry_date() < next_expiry)
380 next_expiry = snippet->expiry_date(); 407 next_expiry = snippet->expiry_date();
381 } 408 }
382 DCHECK_GT(next_expiry, expiry); 409 DCHECK_GT(next_expiry, expiry);
383 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, 410 expiry_timer_.Start(FROM_HERE, next_expiry - expiry,
384 base::Bind(&NTPSnippetsService::RemoveExpiredSnippets, 411 base::Bind(&NTPSnippetsService::RemoveExpiredSnippets,
385 base::Unretained(this))); 412 base::Unretained(this)));
386 } 413 }
387 414
388 } // namespace ntp_snippets 415 } // namespace ntp_snippets
OLDNEW
« no previous file with comments | « components/ntp_snippets/ntp_snippets_service.h ('k') | components/ntp_snippets/pref_names.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698