| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/doodle/doodle_service.h" | 5 #include "components/doodle/doodle_service.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| 11 #include "base/values.h" |
| 12 #include "components/doodle/pref_names.h" |
| 13 #include "components/prefs/pref_registry.h" |
| 14 #include "components/prefs/pref_registry_simple.h" |
| 15 #include "components/prefs/pref_service.h" |
| 11 | 16 |
| 12 namespace doodle { | 17 namespace doodle { |
| 13 | 18 |
| 14 DoodleService::DoodleService(std::unique_ptr<DoodleFetcher> fetcher, | 19 // static |
| 15 std::unique_ptr<base::OneShotTimer> expiry_timer) | 20 void DoodleService::RegisterProfilePrefs(PrefRegistrySimple* pref_registry) { |
| 16 : fetcher_(std::move(fetcher)), expiry_timer_(std::move(expiry_timer)) { | 21 pref_registry->RegisterDictionaryPref(prefs::kCachedConfig, |
| 22 new base::DictionaryValue(), |
| 23 PrefRegistry::LOSSY_PREF); |
| 24 pref_registry->RegisterInt64Pref(prefs::kCachedConfigExpiry, 0, |
| 25 PrefRegistry::LOSSY_PREF); |
| 26 } |
| 27 |
| 28 DoodleService::DoodleService(PrefService* pref_service, |
| 29 std::unique_ptr<DoodleFetcher> fetcher, |
| 30 std::unique_ptr<base::OneShotTimer> expiry_timer, |
| 31 std::unique_ptr<base::Clock> clock) |
| 32 : pref_service_(pref_service), |
| 33 fetcher_(std::move(fetcher)), |
| 34 expiry_timer_(std::move(expiry_timer)), |
| 35 clock_(std::move(clock)) { |
| 36 DCHECK(pref_service_); |
| 17 DCHECK(fetcher_); | 37 DCHECK(fetcher_); |
| 18 DCHECK(expiry_timer_); | 38 DCHECK(expiry_timer_); |
| 39 DCHECK(clock_); |
| 40 |
| 41 base::Time expiry_date = base::Time::FromInternalValue( |
| 42 pref_service_->GetInt64(prefs::kCachedConfigExpiry)); |
| 43 base::Optional<DoodleConfig> config = DoodleConfig::FromDictionary( |
| 44 *pref_service_->GetDictionary(prefs::kCachedConfig), base::nullopt); |
| 45 UpdateCachedConfig(expiry_date - clock_->Now(), config); |
| 19 } | 46 } |
| 20 | 47 |
| 21 DoodleService::~DoodleService() = default; | 48 DoodleService::~DoodleService() = default; |
| 22 | 49 |
| 23 void DoodleService::AddObserver(Observer* observer) { | 50 void DoodleService::AddObserver(Observer* observer) { |
| 24 observers_.AddObserver(observer); | 51 observers_.AddObserver(observer); |
| 25 } | 52 } |
| 26 | 53 |
| 27 void DoodleService::RemoveObserver(Observer* observer) { | 54 void DoodleService::RemoveObserver(Observer* observer) { |
| 28 observers_.RemoveObserver(observer); | 55 observers_.RemoveObserver(observer); |
| 29 } | 56 } |
| 30 | 57 |
| 31 void DoodleService::Refresh() { | 58 void DoodleService::Refresh() { |
| 32 fetcher_->FetchDoodle( | 59 fetcher_->FetchDoodle( |
| 33 base::BindOnce(&DoodleService::DoodleFetched, base::Unretained(this))); | 60 base::BindOnce(&DoodleService::DoodleFetched, base::Unretained(this))); |
| 34 } | 61 } |
| 35 | 62 |
| 36 void DoodleService::DoodleFetched( | 63 void DoodleService::DoodleFetched( |
| 37 DoodleState state, | 64 DoodleState state, |
| 38 base::TimeDelta time_to_live, | 65 base::TimeDelta time_to_live, |
| 39 const base::Optional<DoodleConfig>& doodle_config) { | 66 const base::Optional<DoodleConfig>& doodle_config) { |
| 67 UpdateCachedConfig(time_to_live, doodle_config); |
| 68 } |
| 69 |
| 70 void DoodleService::UpdateCachedConfig( |
| 71 base::TimeDelta time_to_live, |
| 72 const base::Optional<DoodleConfig>& doodle_config) { |
| 40 // Handle the case where the new config is already expired. | 73 // Handle the case where the new config is already expired. |
| 41 bool expired = time_to_live <= base::TimeDelta(); | 74 bool expired = time_to_live <= base::TimeDelta(); |
| 42 const base::Optional<DoodleConfig>& new_config = | 75 const base::Optional<DoodleConfig>& new_config = |
| 43 expired ? base::nullopt : doodle_config; | 76 expired ? base::nullopt : doodle_config; |
| 44 | 77 |
| 45 // If the config changed, update our cache and notify observers. | 78 // If the config changed, update our cache and notify observers. |
| 46 // Note that this checks both for existence changes as well as changes of the | 79 // Note that this checks both for existence changes as well as changes of the |
| 47 // configs themselves. | 80 // configs themselves. |
| 48 if (cached_config_ != new_config) { | 81 if (cached_config_ != new_config) { |
| 49 cached_config_ = new_config; | 82 cached_config_ = new_config; |
| 83 |
| 84 if (cached_config_.has_value()) { |
| 85 pref_service_->Set(prefs::kCachedConfig, *cached_config_->ToDictionary()); |
| 86 base::Time expiry_date = clock_->Now() + time_to_live; |
| 87 pref_service_->SetInt64(prefs::kCachedConfigExpiry, |
| 88 expiry_date.ToInternalValue()); |
| 89 } else { |
| 90 pref_service_->ClearPref(prefs::kCachedConfig); |
| 91 pref_service_->ClearPref(prefs::kCachedConfigExpiry); |
| 92 } |
| 93 |
| 50 for (auto& observer : observers_) { | 94 for (auto& observer : observers_) { |
| 51 observer.OnDoodleConfigUpdated(cached_config_); | 95 observer.OnDoodleConfigUpdated(cached_config_); |
| 52 } | 96 } |
| 53 } | 97 } |
| 54 | 98 |
| 55 // Even if the configs are identical, the time-to-live might have changed. | 99 // Even if the configs are identical, the time-to-live might have changed. |
| 56 UpdateTimeToLive(time_to_live); | |
| 57 } | |
| 58 | |
| 59 void DoodleService::UpdateTimeToLive(base::TimeDelta time_to_live) { | |
| 60 // (Re-)schedule the cache expiry. | 100 // (Re-)schedule the cache expiry. |
| 61 if (cached_config_.has_value()) { | 101 if (cached_config_.has_value()) { |
| 62 expiry_timer_->Start( | 102 expiry_timer_->Start( |
| 63 FROM_HERE, time_to_live, | 103 FROM_HERE, time_to_live, |
| 64 base::Bind(&DoodleService::DoodleExpired, base::Unretained(this))); | 104 base::Bind(&DoodleService::DoodleExpired, base::Unretained(this))); |
| 65 } else { | 105 } else { |
| 66 expiry_timer_->Stop(); | 106 expiry_timer_->Stop(); |
| 67 } | 107 } |
| 68 } | 108 } |
| 69 | 109 |
| 70 void DoodleService::DoodleExpired() { | 110 void DoodleService::DoodleExpired() { |
| 71 DCHECK(cached_config_.has_value()); | 111 DCHECK(cached_config_.has_value()); |
| 72 cached_config_.reset(); | 112 UpdateCachedConfig(base::TimeDelta(), base::nullopt); |
| 73 for (auto& observer : observers_) { | |
| 74 observer.OnDoodleConfigUpdated(cached_config_); | |
| 75 } | |
| 76 } | 113 } |
| 77 | 114 |
| 78 } // namespace doodle | 115 } // namespace doodle |
| OLD | NEW |