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/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "components/data_use_measurement/core/data_use_user_data.h" |
13 #include "components/doodle/pref_names.h" | 14 #include "components/doodle/pref_names.h" |
| 15 #include "components/image_fetcher/core/image_fetcher.h" |
| 16 #include "components/image_fetcher/core/request_metadata.h" |
14 #include "components/prefs/pref_registry.h" | 17 #include "components/prefs/pref_registry.h" |
15 #include "components/prefs/pref_registry_simple.h" | 18 #include "components/prefs/pref_registry_simple.h" |
16 #include "components/prefs/pref_service.h" | 19 #include "components/prefs/pref_service.h" |
| 20 #include "ui/gfx/image/image.h" |
17 | 21 |
18 namespace doodle { | 22 namespace doodle { |
19 | 23 |
20 namespace { | 24 namespace { |
21 | 25 |
22 // The maximum time-to-live we'll accept; any larger values will be clamped to | 26 // The maximum time-to-live we'll accept; any larger values will be clamped to |
23 // this one. This is a last resort in case the server sends bad data. | 27 // this one. This is a last resort in case the server sends bad data. |
24 const int64_t kMaxTimeToLiveSecs = 30 * 24 * 60 * 60; // 30 days | 28 const int64_t kMaxTimeToLiveSecs = 30 * 24 * 60 * 60; // 30 days |
25 | 29 |
26 // The default value for DoodleService::min_refresh_interval_. | 30 // The default value for DoodleService::min_refresh_interval_. |
27 const int64_t kDefaultMinRefreshIntervalSecs = 15 * 60; // 15 minutes | 31 const int64_t kDefaultMinRefreshIntervalSecs = 15 * 60; // 15 minutes |
28 | 32 |
| 33 // The maximum number of bytes to allow in a doodle image. This limits the |
| 34 // downloaded data to an amount that real images are unlikely to exceed. It is a |
| 35 // safeguard against server-side errors. |
| 36 const int64_t kMaxImageDownloadBytes = 1024 * 1024; |
| 37 |
29 } // namespace | 38 } // namespace |
30 | 39 |
31 // static | 40 // static |
32 void DoodleService::RegisterProfilePrefs(PrefRegistrySimple* pref_registry) { | 41 void DoodleService::RegisterProfilePrefs(PrefRegistrySimple* pref_registry) { |
33 pref_registry->RegisterDictionaryPref( | 42 pref_registry->RegisterDictionaryPref( |
34 prefs::kCachedConfig, base::MakeUnique<base::DictionaryValue>(), | 43 prefs::kCachedConfig, base::MakeUnique<base::DictionaryValue>(), |
35 PrefRegistry::LOSSY_PREF); | 44 PrefRegistry::LOSSY_PREF); |
36 pref_registry->RegisterInt64Pref(prefs::kCachedConfigExpiry, 0, | 45 pref_registry->RegisterInt64Pref(prefs::kCachedConfigExpiry, 0, |
37 PrefRegistry::LOSSY_PREF); | 46 PrefRegistry::LOSSY_PREF); |
38 } | 47 } |
39 | 48 |
40 DoodleService::DoodleService( | 49 DoodleService::DoodleService( |
41 PrefService* pref_service, | 50 PrefService* pref_service, |
42 std::unique_ptr<DoodleFetcher> fetcher, | 51 std::unique_ptr<DoodleFetcher> fetcher, |
43 std::unique_ptr<base::OneShotTimer> expiry_timer, | 52 std::unique_ptr<base::OneShotTimer> expiry_timer, |
44 std::unique_ptr<base::Clock> clock, | 53 std::unique_ptr<base::Clock> clock, |
45 std::unique_ptr<base::TickClock> tick_clock, | 54 std::unique_ptr<base::TickClock> tick_clock, |
46 base::Optional<base::TimeDelta> override_min_refresh_interval) | 55 base::Optional<base::TimeDelta> override_min_refresh_interval, |
| 56 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher) |
47 : pref_service_(pref_service), | 57 : pref_service_(pref_service), |
48 fetcher_(std::move(fetcher)), | 58 fetcher_(std::move(fetcher)), |
49 expiry_timer_(std::move(expiry_timer)), | 59 expiry_timer_(std::move(expiry_timer)), |
50 clock_(std::move(clock)), | 60 clock_(std::move(clock)), |
51 tick_clock_(std::move(tick_clock)), | 61 tick_clock_(std::move(tick_clock)), |
52 min_refresh_interval_( | 62 min_refresh_interval_( |
53 override_min_refresh_interval.has_value() | 63 override_min_refresh_interval.has_value() |
54 ? override_min_refresh_interval.value() | 64 ? override_min_refresh_interval.value() |
55 : base::TimeDelta::FromSeconds(kDefaultMinRefreshIntervalSecs)) { | 65 : base::TimeDelta::FromSeconds(kDefaultMinRefreshIntervalSecs)), |
| 66 image_fetcher_(std::move(image_fetcher)) { |
56 DCHECK(pref_service_); | 67 DCHECK(pref_service_); |
57 DCHECK(fetcher_); | 68 DCHECK(fetcher_); |
58 DCHECK(expiry_timer_); | 69 DCHECK(expiry_timer_); |
59 DCHECK(clock_); | 70 DCHECK(clock_); |
60 DCHECK(tick_clock_); | 71 DCHECK(tick_clock_); |
| 72 DCHECK(image_fetcher_); |
| 73 |
| 74 image_fetcher_->SetImageDownloadLimit(kMaxImageDownloadBytes); |
| 75 image_fetcher_->SetDataUseServiceName( |
| 76 data_use_measurement::DataUseUserData::DOODLE); |
61 | 77 |
62 base::Time expiry_date = base::Time::FromInternalValue( | 78 base::Time expiry_date = base::Time::FromInternalValue( |
63 pref_service_->GetInt64(prefs::kCachedConfigExpiry)); | 79 pref_service_->GetInt64(prefs::kCachedConfigExpiry)); |
64 base::Optional<DoodleConfig> config = DoodleConfig::FromDictionary( | 80 base::Optional<DoodleConfig> config = DoodleConfig::FromDictionary( |
65 *pref_service_->GetDictionary(prefs::kCachedConfig), base::nullopt); | 81 *pref_service_->GetDictionary(prefs::kCachedConfig), base::nullopt); |
66 DoodleState state = | 82 DoodleState state = |
67 config.has_value() ? DoodleState::AVAILABLE : DoodleState::NO_DOODLE; | 83 config.has_value() ? DoodleState::AVAILABLE : DoodleState::NO_DOODLE; |
68 HandleNewConfig(state, expiry_date - clock_->Now(), config); | 84 HandleNewConfig(state, expiry_date - clock_->Now(), config); |
69 | 85 |
70 // If we don't have a cached doodle, immediately start a fetch, so that the | 86 // If we don't have a cached doodle, immediately start a fetch, so that the |
71 // first NTP will get it quicker. | 87 // first NTP will get it quicker. |
72 if (state == DoodleState::NO_DOODLE) { | 88 if (state == DoodleState::NO_DOODLE) { |
73 Refresh(); | 89 Refresh(); |
74 } | 90 } |
75 } | 91 } |
76 | 92 |
77 DoodleService::~DoodleService() = default; | 93 DoodleService::~DoodleService() = default; |
78 | 94 |
79 void DoodleService::Shutdown() {} | 95 void DoodleService::Shutdown() {} |
80 | 96 |
| 97 void DoodleService::GetImage(const ImageCallback& callback) { |
| 98 if (!cached_config_.has_value()) { |
| 99 callback.Run(gfx::Image()); |
| 100 return; |
| 101 } |
| 102 |
| 103 // If there is a CTA image, that means the main image is animated. Show the |
| 104 // non-animated CTA image first, and load the animated one only when the |
| 105 // user requests it. |
| 106 bool has_cta = cached_config_->large_cta_image.has_value(); |
| 107 const GURL& image_url = has_cta ? cached_config_->large_cta_image->url |
| 108 : cached_config_->large_image.url; |
| 109 image_fetcher_->StartOrQueueNetworkRequest( |
| 110 image_url.spec(), image_url, |
| 111 base::Bind(&DoodleService::ImageFetched, base::Unretained(this), |
| 112 callback)); |
| 113 } |
| 114 |
81 void DoodleService::AddObserver(Observer* observer) { | 115 void DoodleService::AddObserver(Observer* observer) { |
82 observers_.AddObserver(observer); | 116 observers_.AddObserver(observer); |
83 } | 117 } |
84 | 118 |
85 void DoodleService::RemoveObserver(Observer* observer) { | 119 void DoodleService::RemoveObserver(Observer* observer) { |
86 observers_.RemoveObserver(observer); | 120 observers_.RemoveObserver(observer); |
87 } | 121 } |
88 | 122 |
89 void DoodleService::Refresh() { | 123 void DoodleService::Refresh() { |
90 // If we're already waiting for a fetch, don't start another one. The | 124 // If we're already waiting for a fetch, don't start another one. The |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 pref_service_->ClearPref(prefs::kCachedConfig); | 285 pref_service_->ClearPref(prefs::kCachedConfig); |
252 pref_service_->ClearPref(prefs::kCachedConfigExpiry); | 286 pref_service_->ClearPref(prefs::kCachedConfigExpiry); |
253 } | 287 } |
254 } | 288 } |
255 | 289 |
256 void DoodleService::DoodleExpired() { | 290 void DoodleService::DoodleExpired() { |
257 DCHECK(cached_config_.has_value()); | 291 DCHECK(cached_config_.has_value()); |
258 HandleNewConfig(DoodleState::NO_DOODLE, base::TimeDelta(), base::nullopt); | 292 HandleNewConfig(DoodleState::NO_DOODLE, base::TimeDelta(), base::nullopt); |
259 } | 293 } |
260 | 294 |
| 295 void DoodleService::ImageFetched( |
| 296 const ImageCallback& callback, |
| 297 const std::string& id, |
| 298 const gfx::Image& image, |
| 299 const image_fetcher::RequestMetadata& metadata) { |
| 300 if (image.IsEmpty()) { |
| 301 DLOG(WARNING) << "Failed to download doodle image"; |
| 302 } else { |
| 303 // TODO(treib): Rename this to "Doodle.*" after we've decided what to do |
| 304 // about crbug.com/719513. |
| 305 UMA_HISTOGRAM_BOOLEAN("NewTabPage.LogoImageDownloaded", |
| 306 metadata.from_http_cache); |
| 307 } |
| 308 |
| 309 callback.Run(image); |
| 310 } |
| 311 |
261 } // namespace doodle | 312 } // namespace doodle |
OLD | NEW |