| 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_fetcher_impl.h" | 5 #include "components/doodle/doodle_fetcher_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 const char kResponsePreamble[] = ")]}'"; | 31 const char kResponsePreamble[] = ")]}'"; |
| 32 | 32 |
| 33 base::StringPiece json_sp(json); | 33 base::StringPiece json_sp(json); |
| 34 if (json_sp.starts_with(kResponsePreamble)) { | 34 if (json_sp.starts_with(kResponsePreamble)) { |
| 35 json_sp.remove_prefix(strlen(kResponsePreamble)); | 35 json_sp.remove_prefix(strlen(kResponsePreamble)); |
| 36 } | 36 } |
| 37 | 37 |
| 38 return json_sp.as_string(); | 38 return json_sp.as_string(); |
| 39 } | 39 } |
| 40 | 40 |
| 41 DoodleType ParseDoodleType(const base::DictionaryValue& ddljson) { | |
| 42 std::string type_str; | |
| 43 ddljson.GetString("doodle_type", &type_str); | |
| 44 if (type_str == "SIMPLE") { | |
| 45 return DoodleType::SIMPLE; | |
| 46 } | |
| 47 if (type_str == "RANDOM") { | |
| 48 return DoodleType::RANDOM; | |
| 49 } | |
| 50 if (type_str == "VIDEO") { | |
| 51 return DoodleType::VIDEO; | |
| 52 } | |
| 53 if (type_str == "INTERACTIVE") { | |
| 54 return DoodleType::INTERACTIVE; | |
| 55 } | |
| 56 if (type_str == "INLINE_INTERACTIVE") { | |
| 57 return DoodleType::INLINE_INTERACTIVE; | |
| 58 } | |
| 59 if (type_str == "SLIDESHOW") { | |
| 60 return DoodleType::SLIDESHOW; | |
| 61 } | |
| 62 return DoodleType::UNKNOWN; | |
| 63 } | |
| 64 | |
| 65 } // namespace | 41 } // namespace |
| 66 | 42 |
| 67 DoodleImage::DoodleImage() | |
| 68 : height(0), width(0), is_animated_gif(false), is_cta(false) {} | |
| 69 DoodleImage::~DoodleImage() = default; | |
| 70 | |
| 71 DoodleConfig::DoodleConfig() : doodle_type(DoodleType::UNKNOWN) {} | |
| 72 DoodleConfig::DoodleConfig(const DoodleConfig& config) = default; | |
| 73 DoodleConfig::~DoodleConfig() = default; | |
| 74 | |
| 75 DoodleFetcherImpl::DoodleFetcherImpl( | 43 DoodleFetcherImpl::DoodleFetcherImpl( |
| 76 scoped_refptr<net::URLRequestContextGetter> download_context, | 44 scoped_refptr<net::URLRequestContextGetter> download_context, |
| 77 GoogleURLTracker* google_url_tracker, | 45 GoogleURLTracker* google_url_tracker, |
| 78 const ParseJSONCallback& json_parsing_callback) | 46 const ParseJSONCallback& json_parsing_callback) |
| 79 : download_context_(download_context), | 47 : download_context_(download_context), |
| 80 json_parsing_callback_(json_parsing_callback), | 48 json_parsing_callback_(json_parsing_callback), |
| 81 google_url_tracker_(google_url_tracker), | 49 google_url_tracker_(google_url_tracker), |
| 82 weak_ptr_factory_(this) { | 50 weak_ptr_factory_(this) { |
| 83 DCHECK(google_url_tracker_); | 51 DCHECK(google_url_tracker_); |
| 84 } | 52 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 125 |
| 158 void DoodleFetcherImpl::OnJsonParseFailed(const std::string& error_message) { | 126 void DoodleFetcherImpl::OnJsonParseFailed(const std::string& error_message) { |
| 159 DLOG(WARNING) << "JSON parsing failed: " << error_message; | 127 DLOG(WARNING) << "JSON parsing failed: " << error_message; |
| 160 RespondToAllCallbacks(DoodleState::PARSING_ERROR, base::TimeDelta(), | 128 RespondToAllCallbacks(DoodleState::PARSING_ERROR, base::TimeDelta(), |
| 161 base::nullopt); | 129 base::nullopt); |
| 162 } | 130 } |
| 163 | 131 |
| 164 base::Optional<DoodleConfig> DoodleFetcherImpl::ParseDoodleConfigAndTimeToLive( | 132 base::Optional<DoodleConfig> DoodleFetcherImpl::ParseDoodleConfigAndTimeToLive( |
| 165 const base::DictionaryValue& ddljson, | 133 const base::DictionaryValue& ddljson, |
| 166 base::TimeDelta* time_to_live) const { | 134 base::TimeDelta* time_to_live) const { |
| 167 DoodleConfig doodle; | 135 base::Optional<DoodleConfig> doodle = |
| 168 // The |large_image| field is required (it's the "default" representation for | 136 DoodleConfig::FromDictionary(ddljson, GetGoogleBaseUrl()); |
| 169 // the doodle). | |
| 170 if (!ParseImage(ddljson, "large_image", &doodle.large_image)) { | |
| 171 return base::nullopt; | |
| 172 } | |
| 173 ParseBaseInformation(ddljson, &doodle, time_to_live); | |
| 174 ParseImage(ddljson, "transparent_large_image", | |
| 175 &doodle.transparent_large_image); | |
| 176 ParseImage(ddljson, "large_cta_image", &doodle.large_cta_image); | |
| 177 return doodle; | |
| 178 } | |
| 179 | |
| 180 bool DoodleFetcherImpl::ParseImage(const base::DictionaryValue& image_parent, | |
| 181 const std::string& image_name, | |
| 182 DoodleImage* image) const { | |
| 183 DCHECK(image); | |
| 184 const base::DictionaryValue* image_dict = nullptr; | |
| 185 if (!image_parent.GetDictionary(image_name, &image_dict)) { | |
| 186 return false; | |
| 187 } | |
| 188 image->url = ParseRelativeUrl(*image_dict, "url"); | |
| 189 if (!image->url.is_valid()) { | |
| 190 DLOG(WARNING) << "Image URL for \"" << image_name << "\" is invalid."; | |
| 191 return false; | |
| 192 } | |
| 193 image_dict->GetInteger("height", &image->height); | |
| 194 image_dict->GetInteger("width", &image->width); | |
| 195 image_dict->GetBoolean("is_animated_gif", &image->is_animated_gif); | |
| 196 image_dict->GetBoolean("is_cta", &image->is_cta); | |
| 197 return true; | |
| 198 } | |
| 199 | |
| 200 void DoodleFetcherImpl::ParseBaseInformation( | |
| 201 const base::DictionaryValue& ddljson, | |
| 202 DoodleConfig* config, | |
| 203 base::TimeDelta* time_to_live) const { | |
| 204 config->search_url = ParseRelativeUrl(ddljson, "search_url"); | |
| 205 config->target_url = ParseRelativeUrl(ddljson, "target_url"); | |
| 206 config->fullpage_interactive_url = | |
| 207 ParseRelativeUrl(ddljson, "fullpage_interactive_url"); | |
| 208 | |
| 209 config->doodle_type = ParseDoodleType(ddljson); | |
| 210 ddljson.GetString("alt_text", &config->alt_text); | |
| 211 ddljson.GetString("interactive_html", &config->interactive_html); | |
| 212 | 137 |
| 213 // The JSON doesn't guarantee the number to fit into an int. | 138 // The JSON doesn't guarantee the number to fit into an int. |
| 214 double ttl = 0; // Expires immediately if the parameter is missing. | 139 double ttl = 0; // Expires immediately if the parameter is missing. |
| 215 if (!ddljson.GetDouble("time_to_live_ms", &ttl) || ttl < 0) { | 140 if (!ddljson.GetDouble("time_to_live_ms", &ttl) || ttl < 0) { |
| 216 DLOG(WARNING) << "No valid Doodle TTL present in ddljson!"; | 141 DLOG(WARNING) << "No valid Doodle TTL present in ddljson!"; |
| 217 ttl = 0; | 142 ttl = 0; |
| 218 } | 143 } |
| 219 // TODO(treib,fhorschig): Move this logic into the service. | 144 // TODO(treib,fhorschig): Move this logic into the service. |
| 220 if (ttl > kMaxTimeToLiveMS) { | 145 if (ttl > kMaxTimeToLiveMS) { |
| 221 ttl = kMaxTimeToLiveMS; | 146 ttl = kMaxTimeToLiveMS; |
| 222 DLOG(WARNING) << "Clamping Doodle TTL to 30 days!"; | 147 DLOG(WARNING) << "Clamping Doodle TTL to 30 days!"; |
| 223 } | 148 } |
| 224 *time_to_live = base::TimeDelta::FromMillisecondsD(ttl); | 149 *time_to_live = base::TimeDelta::FromMillisecondsD(ttl); |
| 225 } | |
| 226 | 150 |
| 227 GURL DoodleFetcherImpl::ParseRelativeUrl( | 151 return doodle; |
| 228 const base::DictionaryValue& dict_value, | |
| 229 const std::string& key) const { | |
| 230 std::string str_url; | |
| 231 dict_value.GetString(key, &str_url); | |
| 232 if (str_url.empty()) { | |
| 233 return GURL(); | |
| 234 } | |
| 235 return GetGoogleBaseUrl().Resolve(str_url); | |
| 236 } | 152 } |
| 237 | 153 |
| 238 void DoodleFetcherImpl::RespondToAllCallbacks( | 154 void DoodleFetcherImpl::RespondToAllCallbacks( |
| 239 DoodleState state, | 155 DoodleState state, |
| 240 base::TimeDelta time_to_live, | 156 base::TimeDelta time_to_live, |
| 241 const base::Optional<DoodleConfig>& config) { | 157 const base::Optional<DoodleConfig>& config) { |
| 242 for (auto& callback : callbacks_) { | 158 for (auto& callback : callbacks_) { |
| 243 std::move(callback).Run(state, time_to_live, config); | 159 std::move(callback).Run(state, time_to_live, config); |
| 244 } | 160 } |
| 245 callbacks_.clear(); | 161 callbacks_.clear(); |
| 246 } | 162 } |
| 247 | 163 |
| 248 GURL DoodleFetcherImpl::GetGoogleBaseUrl() const { | 164 GURL DoodleFetcherImpl::GetGoogleBaseUrl() const { |
| 249 GURL cmd_line_url = google_util::CommandLineGoogleBaseURL(); | 165 GURL cmd_line_url = google_util::CommandLineGoogleBaseURL(); |
| 250 if (cmd_line_url.is_valid()) { | 166 if (cmd_line_url.is_valid()) { |
| 251 return cmd_line_url; | 167 return cmd_line_url; |
| 252 } | 168 } |
| 253 return google_url_tracker_->google_url(); | 169 return google_url_tracker_->google_url(); |
| 254 } | 170 } |
| 255 | 171 |
| 256 } // namespace doodle | 172 } // namespace doodle |
| OLD | NEW |