Chromium Code Reviews| OLD | NEW |
|---|---|
| 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> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
| 14 #include "base/json/json_reader.h" | 14 #include "base/json/json_reader.h" |
| 15 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/path_service.h" | 16 #include "base/path_service.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/stringprintf.h" | |
| 18 #include "base/task_runner_util.h" | 19 #include "base/task_runner_util.h" |
| 19 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 20 #include "base/values.h" | 21 #include "base/values.h" |
| 21 #include "components/ntp_snippets/pref_names.h" | 22 #include "components/ntp_snippets/pref_names.h" |
| 22 #include "components/ntp_snippets/switches.h" | 23 #include "components/ntp_snippets/switches.h" |
| 23 #include "components/prefs/pref_registry_simple.h" | 24 #include "components/prefs/pref_registry_simple.h" |
| 24 #include "components/prefs/pref_service.h" | 25 #include "components/prefs/pref_service.h" |
| 25 #include "components/suggestions/proto/suggestions.pb.h" | 26 #include "components/suggestions/proto/suggestions.pb.h" |
| 26 | 27 |
| 27 using suggestions::ChromeSuggestion; | 28 using suggestions::ChromeSuggestion; |
| 28 using suggestions::SuggestionsProfile; | 29 using suggestions::SuggestionsProfile; |
| 29 using suggestions::SuggestionsService; | 30 using suggestions::SuggestionsService; |
| 30 | 31 |
| 31 namespace ntp_snippets { | 32 namespace ntp_snippets { |
| 32 | 33 |
| 33 namespace { | 34 namespace { |
| 34 | 35 |
| 35 const int kFetchingIntervalWifiChargingSeconds = 30 * 60; | 36 const int kFetchingIntervalWifiChargingSeconds = 30 * 60; |
| 36 const int kFetchingIntervalWifiSeconds = 2 * 60 * 60; | 37 const int kFetchingIntervalWifiSeconds = 2 * 60 * 60; |
| 37 const int kFetchingIntervalFallbackSeconds = 24 * 60 * 60; | 38 const int kFetchingIntervalFallbackSeconds = 24 * 60 * 60; |
| 38 | 39 |
| 39 // These define the times of day during which we will fetch via Wifi (without | 40 // These define the times of day during which we will fetch via Wifi (without |
| 40 // charging) - 6 AM to 10 PM. | 41 // charging) - 6 AM to 10 PM. |
| 41 const int kWifiFetchingHourMin = 6; | 42 const int kWifiFetchingHourMin = 6; |
| 42 const int kWifiFetchingHourMax = 22; | 43 const int kWifiFetchingHourMax = 22; |
| 43 | 44 |
| 44 const int kDefaultExpiryTimeMins = 24 * 60; | 45 const int kDefaultExpiryTimeMins = 24 * 60; |
| 45 | 46 |
| 47 const char kStatusMessageEmptyHosts[] = "Cannot fetch for empty hosts list."; | |
| 48 const char kStatusMessageEmptyList[] = "Invalid / empty list."; | |
| 49 const char kStatusMessageJsonErrorFormat[] = "Received invalid JSON (error %s)"; | |
| 50 const char kStatusMessageOK[] = "OK"; | |
| 51 | |
| 46 base::TimeDelta GetFetchingInterval(const char* switch_name, | 52 base::TimeDelta GetFetchingInterval(const char* switch_name, |
| 47 int default_value_seconds) { | 53 int default_value_seconds) { |
| 48 int value_seconds = default_value_seconds; | 54 int value_seconds = default_value_seconds; |
| 49 const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess(); | 55 const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess(); |
| 50 if (cmdline.HasSwitch(switch_name)) { | 56 if (cmdline.HasSwitch(switch_name)) { |
| 51 std::string str = cmdline.GetSwitchValueASCII(switch_name); | 57 std::string str = cmdline.GetSwitchValueASCII(switch_name); |
| 52 int switch_value_seconds = 0; | 58 int switch_value_seconds = 0; |
| 53 if (base::StringToInt(str, &switch_value_seconds)) | 59 if (base::StringToInt(str, &switch_value_seconds)) |
| 54 value_seconds = switch_value_seconds; | 60 value_seconds = switch_value_seconds; |
| 55 else | 61 else |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 FetchSnippetsFromHosts(GetSuggestionsHosts()); | 231 FetchSnippetsFromHosts(GetSuggestionsHosts()); |
| 226 } | 232 } |
| 227 | 233 |
| 228 void NTPSnippetsService::FetchSnippetsFromHosts( | 234 void NTPSnippetsService::FetchSnippetsFromHosts( |
| 229 const std::set<std::string>& hosts) { | 235 const std::set<std::string>& hosts) { |
| 230 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 236 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 231 switches::kDontRestrict)) { | 237 switches::kDontRestrict)) { |
| 232 snippets_fetcher_->FetchSnippets(std::set<std::string>()); | 238 snippets_fetcher_->FetchSnippets(std::set<std::string>()); |
| 233 return; | 239 return; |
| 234 } | 240 } |
| 235 if (!hosts.empty()) | 241 if (!hosts.empty()) { |
| 236 snippets_fetcher_->FetchSnippets(hosts); | 242 snippets_fetcher_->FetchSnippets(hosts); |
| 243 } else { | |
| 244 last_fetch_status_ = kStatusMessageEmptyHosts; | |
| 245 LoadingSnippetsFinished(); | |
| 246 } | |
| 237 } | 247 } |
| 238 | 248 |
| 239 void NTPSnippetsService::RescheduleFetching() { | 249 void NTPSnippetsService::RescheduleFetching() { |
| 240 // The scheduler only exists on Android so far, it's null on other platforms. | 250 // The scheduler only exists on Android so far, it's null on other platforms. |
| 241 if (!scheduler_) | 251 if (!scheduler_) |
| 242 return; | 252 return; |
| 243 | 253 |
| 244 if (enabled_) { | 254 if (enabled_) { |
| 245 base::Time now = base::Time::Now(); | 255 base::Time now = base::Time::Now(); |
| 246 scheduler_->Schedule( | 256 scheduler_->Schedule( |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 StoreSnippetsToPrefs(); | 327 StoreSnippetsToPrefs(); |
| 318 StoreSnippetHostsToPrefs(hosts); | 328 StoreSnippetHostsToPrefs(hosts); |
| 319 | 329 |
| 320 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 330 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 321 NTPSnippetsServiceLoaded()); | 331 NTPSnippetsServiceLoaded()); |
| 322 | 332 |
| 323 FetchSnippetsFromHosts(hosts); | 333 FetchSnippetsFromHosts(hosts); |
| 324 } | 334 } |
| 325 | 335 |
| 326 void NTPSnippetsService::OnSnippetsDownloaded( | 336 void NTPSnippetsService::OnSnippetsDownloaded( |
| 327 const std::string& snippets_json) { | 337 const std::string& snippets_json, const std::string& status) { |
| 328 parse_json_callback_.Run( | 338 last_fetch_status_ = status; |
|
Marc Treib
2016/04/22 12:28:30
nit: Move this into the else branch? Otherwise it'
jkrcal
2016/04/22 13:04:37
Done.
Nothing gets overwritten (in the if branch,
Bernhard Bauer
2016/04/22 14:28:44
DCHECK that maybe? 🙂
| |
| 329 snippets_json, base::Bind(&NTPSnippetsService::OnJsonParsed, | 339 |
| 330 weak_ptr_factory_.GetWeakPtr(), snippets_json), | 340 if (!snippets_json.empty()) { |
| 331 base::Bind(&NTPSnippetsService::OnJsonError, | 341 parse_json_callback_.Run( |
| 332 weak_ptr_factory_.GetWeakPtr(), snippets_json)); | 342 snippets_json, |
| 343 base::Bind(&NTPSnippetsService::OnJsonParsed, | |
| 344 weak_ptr_factory_.GetWeakPtr(), snippets_json), | |
| 345 base::Bind(&NTPSnippetsService::OnJsonError, | |
| 346 weak_ptr_factory_.GetWeakPtr(), snippets_json)); | |
| 347 } else { | |
| 348 LoadingSnippetsFinished(); | |
| 349 } | |
| 333 } | 350 } |
| 334 | 351 |
| 335 void NTPSnippetsService::OnJsonParsed(const std::string& snippets_json, | 352 void NTPSnippetsService::OnJsonParsed(const std::string& snippets_json, |
| 336 scoped_ptr<base::Value> parsed) { | 353 scoped_ptr<base::Value> parsed) { |
| 337 LOG_IF(WARNING, !LoadFromValue(*parsed)) << "Received invalid snippets: " | 354 if (!LoadFromValue(*parsed)) { |
| 338 << snippets_json; | 355 LOG(WARNING) << "Received invalid snippets: " << snippets_json; |
| 356 last_fetch_status_ = kStatusMessageEmptyList; | |
| 357 } else { | |
| 358 last_fetch_status_ = kStatusMessageOK; | |
| 359 } | |
| 360 | |
| 361 LoadingSnippetsFinished(); | |
| 339 } | 362 } |
| 340 | 363 |
| 341 void NTPSnippetsService::OnJsonError(const std::string& snippets_json, | 364 void NTPSnippetsService::OnJsonError(const std::string& snippets_json, |
| 342 const std::string& error) { | 365 const std::string& error) { |
| 343 LOG(WARNING) << "Received invalid JSON (" << error << "): " << snippets_json; | 366 LOG(WARNING) << "Received invalid JSON (" << error << "): " << snippets_json; |
| 367 last_fetch_status_ = base::StringPrintf(kStatusMessageJsonErrorFormat, | |
| 368 error.c_str()); | |
| 369 | |
| 370 LoadingSnippetsFinished(); | |
| 344 } | 371 } |
| 345 | 372 |
| 346 bool NTPSnippetsService::LoadFromValue(const base::Value& value) { | 373 bool NTPSnippetsService::LoadFromValue(const base::Value& value) { |
| 347 const base::DictionaryValue* top_dict = nullptr; | 374 const base::DictionaryValue* top_dict = nullptr; |
| 348 if (!value.GetAsDictionary(&top_dict)) | 375 if (!value.GetAsDictionary(&top_dict)) |
| 349 return false; | 376 return false; |
| 350 | 377 |
| 351 const base::ListValue* list = nullptr; | 378 const base::ListValue* list = nullptr; |
| 352 if (!top_dict->GetList("recos", &list)) | 379 if (!top_dict->GetList("recos", &list)) |
| 353 return false; | 380 return false; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 378 snippet->publish_date() + | 405 snippet->publish_date() + |
| 379 base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins)); | 406 base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins)); |
| 380 } | 407 } |
| 381 } | 408 } |
| 382 | 409 |
| 383 // Insert the new snippets at the front. | 410 // Insert the new snippets at the front. |
| 384 snippets_.insert(snippets_.begin(), | 411 snippets_.insert(snippets_.begin(), |
| 385 std::make_move_iterator(new_snippets.begin()), | 412 std::make_move_iterator(new_snippets.begin()), |
| 386 std::make_move_iterator(new_snippets.end())); | 413 std::make_move_iterator(new_snippets.end())); |
| 387 | 414 |
| 388 // Immediately remove any already-expired snippets. This will also notify our | |
| 389 // observers and schedule the expiry timer. | |
| 390 RemoveExpiredSnippets(); | |
| 391 | |
| 392 return true; | 415 return true; |
| 393 } | 416 } |
| 394 | 417 |
| 395 void NTPSnippetsService::LoadSnippetsFromPrefs() { | 418 void NTPSnippetsService::LoadSnippetsFromPrefs() { |
| 396 bool success = LoadFromListValue(*pref_service_->GetList(prefs::kSnippets)); | 419 bool success = LoadFromListValue(*pref_service_->GetList(prefs::kSnippets)); |
| 397 DCHECK(success) << "Failed to parse snippets from prefs"; | 420 DCHECK(success) << "Failed to parse snippets from prefs"; |
| 421 | |
| 422 LoadingSnippetsFinished(); | |
| 398 } | 423 } |
| 399 | 424 |
| 400 void NTPSnippetsService::StoreSnippetsToPrefs() { | 425 void NTPSnippetsService::StoreSnippetsToPrefs() { |
| 401 pref_service_->Set(prefs::kSnippets, *SnippetsToListValue(snippets_)); | 426 pref_service_->Set(prefs::kSnippets, *SnippetsToListValue(snippets_)); |
| 402 } | 427 } |
| 403 | 428 |
| 404 void NTPSnippetsService::LoadDiscardedSnippetsFromPrefs() { | 429 void NTPSnippetsService::LoadDiscardedSnippetsFromPrefs() { |
| 405 discarded_snippets_.clear(); | 430 discarded_snippets_.clear(); |
| 406 bool success = AddSnippetsFromListValue( | 431 bool success = AddSnippetsFromListValue( |
| 407 *pref_service_->GetList(prefs::kDiscardedSnippets), | 432 *pref_service_->GetList(prefs::kDiscardedSnippets), |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 427 } | 452 } |
| 428 | 453 |
| 429 void NTPSnippetsService::StoreSnippetHostsToPrefs( | 454 void NTPSnippetsService::StoreSnippetHostsToPrefs( |
| 430 const std::set<std::string>& hosts) { | 455 const std::set<std::string>& hosts) { |
| 431 base::ListValue list; | 456 base::ListValue list; |
| 432 for (const std::string& host : hosts) | 457 for (const std::string& host : hosts) |
| 433 list.AppendString(host); | 458 list.AppendString(host); |
| 434 pref_service_->Set(prefs::kSnippetHosts, list); | 459 pref_service_->Set(prefs::kSnippetHosts, list); |
| 435 } | 460 } |
| 436 | 461 |
| 437 void NTPSnippetsService::RemoveExpiredSnippets() { | 462 void NTPSnippetsService::LoadingSnippetsFinished() { |
| 463 // Remove expired snippets. | |
| 438 base::Time expiry = base::Time::Now(); | 464 base::Time expiry = base::Time::Now(); |
| 439 | 465 |
| 440 snippets_.erase( | 466 snippets_.erase( |
| 441 std::remove_if(snippets_.begin(), snippets_.end(), | 467 std::remove_if(snippets_.begin(), snippets_.end(), |
| 442 [&expiry](const scoped_ptr<NTPSnippet>& snippet) { | 468 [&expiry](const scoped_ptr<NTPSnippet>& snippet) { |
| 443 return snippet->expiry_date() <= expiry; | 469 return snippet->expiry_date() <= expiry; |
| 444 }), | 470 }), |
| 445 snippets_.end()); | 471 snippets_.end()); |
| 446 StoreSnippetsToPrefs(); | 472 StoreSnippetsToPrefs(); |
| 447 | 473 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 464 for (const auto& snippet : snippets_) { | 490 for (const auto& snippet : snippets_) { |
| 465 if (snippet->expiry_date() < next_expiry) | 491 if (snippet->expiry_date() < next_expiry) |
| 466 next_expiry = snippet->expiry_date(); | 492 next_expiry = snippet->expiry_date(); |
| 467 } | 493 } |
| 468 for (const auto& snippet : discarded_snippets_) { | 494 for (const auto& snippet : discarded_snippets_) { |
| 469 if (snippet->expiry_date() < next_expiry) | 495 if (snippet->expiry_date() < next_expiry) |
| 470 next_expiry = snippet->expiry_date(); | 496 next_expiry = snippet->expiry_date(); |
| 471 } | 497 } |
| 472 DCHECK_GT(next_expiry, expiry); | 498 DCHECK_GT(next_expiry, expiry); |
| 473 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, | 499 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, |
| 474 base::Bind(&NTPSnippetsService::RemoveExpiredSnippets, | 500 base::Bind(&NTPSnippetsService::LoadingSnippetsFinished, |
| 475 base::Unretained(this))); | 501 base::Unretained(this))); |
| 476 } | 502 } |
| 477 | 503 |
| 478 } // namespace ntp_snippets | 504 } // namespace ntp_snippets |
| OLD | NEW |