| 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_tiles/popular_sites.h" | 5 #include "components/ntp_tiles/popular_sites.h" | 
| 6 | 6 | 
| 7 #include <stddef.h> | 7 #include <stddef.h> | 
| 8 | 8 | 
| 9 #include "base/bind.h" | 9 #include "base/bind.h" | 
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 120     : title(title), | 120     : title(title), | 
| 121       url(url), | 121       url(url), | 
| 122       favicon_url(favicon_url), | 122       favicon_url(favicon_url), | 
| 123       large_icon_url(large_icon_url), | 123       large_icon_url(large_icon_url), | 
| 124       thumbnail_url(thumbnail_url) {} | 124       thumbnail_url(thumbnail_url) {} | 
| 125 | 125 | 
| 126 PopularSites::Site::Site(const Site& other) = default; | 126 PopularSites::Site::Site(const Site& other) = default; | 
| 127 | 127 | 
| 128 PopularSites::Site::~Site() {} | 128 PopularSites::Site::~Site() {} | 
| 129 | 129 | 
| 130 PopularSites::PopularSites( | 130 PopularSitesImpl::PopularSitesImpl( | 
| 131     const scoped_refptr<base::SequencedWorkerPool>& blocking_pool, | 131     const scoped_refptr<base::SequencedWorkerPool>& blocking_pool, | 
| 132     PrefService* prefs, | 132     PrefService* prefs, | 
| 133     const TemplateURLService* template_url_service, | 133     const TemplateURLService* template_url_service, | 
| 134     VariationsService* variations_service, | 134     VariationsService* variations_service, | 
| 135     net::URLRequestContextGetter* download_context, | 135     net::URLRequestContextGetter* download_context, | 
| 136     const base::FilePath& directory, | 136     const base::FilePath& directory, | 
| 137     ParseJSONCallback parse_json) | 137     ParseJSONCallback parse_json) | 
| 138     : blocking_runner_(blocking_pool->GetTaskRunnerWithShutdownBehavior( | 138     : blocking_runner_(blocking_pool->GetTaskRunnerWithShutdownBehavior( | 
| 139           base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)), | 139           base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)), | 
| 140       prefs_(prefs), | 140       prefs_(prefs), | 
| 141       template_url_service_(template_url_service), | 141       template_url_service_(template_url_service), | 
| 142       variations_(variations_service), | 142       variations_(variations_service), | 
| 143       download_context_(download_context), | 143       download_context_(download_context), | 
| 144       local_path_(directory.empty() | 144       local_path_(directory.empty() | 
| 145                       ? base::FilePath() | 145                       ? base::FilePath() | 
| 146                       : directory.AppendASCII(kPopularSitesLocalFilename)), | 146                       : directory.AppendASCII(kPopularSitesLocalFilename)), | 
| 147       parse_json_(std::move(parse_json)), | 147       parse_json_(std::move(parse_json)), | 
| 148       is_fallback_(false), | 148       is_fallback_(false), | 
| 149       weak_ptr_factory_(this) {} | 149       weak_ptr_factory_(this) {} | 
| 150 | 150 | 
| 151 PopularSites::~PopularSites() {} | 151 PopularSitesImpl::~PopularSitesImpl() {} | 
| 152 | 152 | 
| 153 void PopularSites::StartFetch(bool force_download, | 153 void PopularSitesImpl::StartFetch(bool force_download, | 
| 154                               const FinishedCallback& callback) { | 154                                   const FinishedCallback& callback) { | 
| 155   DCHECK(!callback_); | 155   DCHECK(!callback_); | 
| 156   callback_ = callback; | 156   callback_ = callback; | 
| 157 | 157 | 
| 158   const base::Time last_download_time = base::Time::FromInternalValue( | 158   const base::Time last_download_time = base::Time::FromInternalValue( | 
| 159       prefs_->GetInt64(kPopularSitesLastDownloadPref)); | 159       prefs_->GetInt64(kPopularSitesLastDownloadPref)); | 
| 160   const base::TimeDelta time_since_last_download = | 160   const base::TimeDelta time_since_last_download = | 
| 161       base::Time::Now() - last_download_time; | 161       base::Time::Now() - last_download_time; | 
| 162   const base::TimeDelta redownload_interval = | 162   const base::TimeDelta redownload_interval = | 
| 163       base::TimeDelta::FromHours(kPopularSitesRedownloadIntervalHours); | 163       base::TimeDelta::FromHours(kPopularSitesRedownloadIntervalHours); | 
| 164   const bool download_time_is_future = base::Time::Now() < last_download_time; | 164   const bool download_time_is_future = base::Time::Now() < last_download_time; | 
| 165 | 165 | 
| 166   pending_url_ = GetURLToUse(); | 166   pending_url_ = GetURLToFetch(); | 
| 167   const bool url_changed = | 167   const bool url_changed = | 
| 168       pending_url_.spec() != prefs_->GetString(kPopularSitesURLPref); | 168       pending_url_.spec() != prefs_->GetString(kPopularSitesURLPref); | 
| 169 | 169 | 
| 170   // No valid path to save to. Immediately post failure. | 170   // No valid path to save to. Immediately post failure. | 
| 171   if (local_path_.empty()) { | 171   if (local_path_.empty()) { | 
| 172     base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 172     base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 
| 173                                                   base::Bind(callback_, false)); | 173                                                   base::Bind(callback_, false)); | 
| 174     return; | 174     return; | 
| 175   } | 175   } | 
| 176 | 176 | 
| 177   // Download forced, or we need to download a new file. | 177   // Download forced, or we need to download a new file. | 
| 178   if (force_download || download_time_is_future || | 178   if (force_download || download_time_is_future || | 
| 179       (time_since_last_download > redownload_interval) || url_changed) { | 179       (time_since_last_download > redownload_interval) || url_changed) { | 
| 180     FetchPopularSites(); | 180     FetchPopularSites(); | 
| 181     return; | 181     return; | 
| 182   } | 182   } | 
| 183 | 183 | 
| 184   std::unique_ptr<std::string> file_data(new std::string); | 184   std::unique_ptr<std::string> file_data(new std::string); | 
| 185   std::string* file_data_ptr = file_data.get(); | 185   std::string* file_data_ptr = file_data.get(); | 
| 186   base::PostTaskAndReplyWithResult( | 186   base::PostTaskAndReplyWithResult( | 
| 187       blocking_runner_.get(), FROM_HERE, | 187       blocking_runner_.get(), FROM_HERE, | 
| 188       base::Bind(&base::ReadFileToString, local_path_, file_data_ptr), | 188       base::Bind(&base::ReadFileToString, local_path_, file_data_ptr), | 
| 189       base::Bind(&PopularSites::OnReadFileDone, weak_ptr_factory_.GetWeakPtr(), | 189       base::Bind(&PopularSitesImpl::OnReadFileDone, | 
|  | 190                  weak_ptr_factory_.GetWeakPtr(), | 
| 190                  base::Passed(std::move(file_data)))); | 191                  base::Passed(std::move(file_data)))); | 
| 191 } | 192 } | 
| 192 | 193 | 
| 193 GURL PopularSites::LastURL() const { | 194 const PopularSites::SitesVector& PopularSitesImpl::sites() const { | 
|  | 195   return sites_; | 
|  | 196 } | 
|  | 197 | 
|  | 198 GURL PopularSitesImpl::GetLastURLFetched() const { | 
| 194   return GURL(prefs_->GetString(kPopularSitesURLPref)); | 199   return GURL(prefs_->GetString(kPopularSitesURLPref)); | 
| 195 } | 200 } | 
| 196 | 201 | 
| 197 GURL PopularSites::GetURLToUse() { | 202 const base::FilePath& PopularSitesImpl::local_path() const { | 
| 198   const std::string country = GetCountryToUse(); | 203   return local_path_; | 
| 199   const std::string version = GetVersionToUse(); | 204 } | 
|  | 205 | 
|  | 206 GURL PopularSitesImpl::GetURLToFetch() { | 
|  | 207   const std::string country = GetCountryToFetch(); | 
|  | 208   const std::string version = GetVersionToFetch(); | 
| 200 | 209 | 
| 201   const GURL override_url = | 210   const GURL override_url = | 
| 202       GURL(prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL)); | 211       GURL(prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL)); | 
| 203   return override_url.is_valid() ? override_url | 212   return override_url.is_valid() ? override_url | 
| 204                                  : GetPopularSitesURL(country, version); | 213                                  : GetPopularSitesURL(country, version); | 
| 205 } | 214 } | 
| 206 | 215 | 
| 207 // Determine the country code to use. In order of precedence: | 216 // Determine the country code to use. In order of precedence: | 
| 208 // - The explicit "override country" pref set by the user. | 217 // - The explicit "override country" pref set by the user. | 
| 209 // - The country code from the field trial config (variation parameter). | 218 // - The country code from the field trial config (variation parameter). | 
| 210 // - The Google country code if Google is the default search engine (and the | 219 // - The Google country code if Google is the default search engine (and the | 
| 211 //   "--enable-ntp-search-engine-country-detection" switch is present). | 220 //   "--enable-ntp-search-engine-country-detection" switch is present). | 
| 212 // - The country provided by the VariationsService. | 221 // - The country provided by the VariationsService. | 
| 213 // - A default fallback. | 222 // - A default fallback. | 
| 214 std::string PopularSites::GetCountryToUse() { | 223 std::string PopularSitesImpl::GetCountryToFetch() { | 
| 215   std::string country_code = | 224   std::string country_code = | 
| 216       prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideCountry); | 225       prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideCountry); | 
| 217 | 226 | 
| 218   if (country_code.empty()) | 227   if (country_code.empty()) | 
| 219     country_code = GetVariationCountry(); | 228     country_code = GetVariationCountry(); | 
| 220 | 229 | 
| 221   if (country_code.empty()) | 230   if (country_code.empty()) | 
| 222     country_code = GetDefaultSearchEngineCountryCode(template_url_service_); | 231     country_code = GetDefaultSearchEngineCountryCode(template_url_service_); | 
| 223 | 232 | 
| 224   if (country_code.empty() && variations_) | 233   if (country_code.empty() && variations_) | 
| 225     country_code = variations_->GetStoredPermanentCountry(); | 234     country_code = variations_->GetStoredPermanentCountry(); | 
| 226 | 235 | 
| 227 #if defined(OS_IOS) | 236 #if defined(OS_IOS) | 
| 228   if (country_code.empty()) | 237   if (country_code.empty()) | 
| 229     country_code = GetDeviceCountryCode(); | 238     country_code = GetDeviceCountryCode(); | 
| 230 #endif | 239 #endif | 
| 231 | 240 | 
| 232   if (country_code.empty()) | 241   if (country_code.empty()) | 
| 233     country_code = kPopularSitesDefaultCountryCode; | 242     country_code = kPopularSitesDefaultCountryCode; | 
| 234 | 243 | 
| 235   return base::ToUpperASCII(country_code); | 244   return base::ToUpperASCII(country_code); | 
| 236 } | 245 } | 
| 237 | 246 | 
| 238 // Determine the version to use. In order of precedence: | 247 // Determine the version to use. In order of precedence: | 
| 239 // - The explicit "override version" pref set by the user. | 248 // - The explicit "override version" pref set by the user. | 
| 240 // - The version from the field trial config (variation parameter). | 249 // - The version from the field trial config (variation parameter). | 
| 241 // - A default fallback. | 250 // - A default fallback. | 
| 242 std::string PopularSites::GetVersionToUse() { | 251 std::string PopularSitesImpl::GetVersionToFetch() { | 
| 243   std::string version = | 252   std::string version = | 
| 244       prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideVersion); | 253       prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideVersion); | 
| 245 | 254 | 
| 246   if (version.empty()) | 255   if (version.empty()) | 
| 247     version = GetVariationVersion(); | 256     version = GetVariationVersion(); | 
| 248 | 257 | 
| 249   if (version.empty()) | 258   if (version.empty()) | 
| 250     version = kPopularSitesDefaultVersion; | 259     version = kPopularSitesDefaultVersion; | 
| 251 | 260 | 
| 252   return version; | 261   return version; | 
| 253 } | 262 } | 
| 254 | 263 | 
| 255 // static | 264 // static | 
| 256 void PopularSites::RegisterProfilePrefs( | 265 void PopularSitesImpl::RegisterProfilePrefs( | 
| 257     user_prefs::PrefRegistrySyncable* user_prefs) { | 266     user_prefs::PrefRegistrySyncable* user_prefs) { | 
| 258   user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideURL, | 267   user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideURL, | 
| 259                                  std::string()); | 268                                  std::string()); | 
| 260   user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideCountry, | 269   user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideCountry, | 
| 261                                  std::string()); | 270                                  std::string()); | 
| 262   user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideVersion, | 271   user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideVersion, | 
| 263                                  std::string()); | 272                                  std::string()); | 
| 264 | 273 | 
| 265   user_prefs->RegisterInt64Pref(kPopularSitesLastDownloadPref, 0); | 274   user_prefs->RegisterInt64Pref(kPopularSitesLastDownloadPref, 0); | 
| 266   user_prefs->RegisterStringPref(kPopularSitesURLPref, std::string()); | 275   user_prefs->RegisterStringPref(kPopularSitesURLPref, std::string()); | 
| 267 } | 276 } | 
| 268 | 277 | 
| 269 void PopularSites::OnReadFileDone(std::unique_ptr<std::string> data, | 278 void PopularSitesImpl::OnReadFileDone(std::unique_ptr<std::string> data, | 
| 270                                   bool success) { | 279                                       bool success) { | 
| 271   if (success) { | 280   if (success) { | 
| 272     auto json = base::JSONReader::Read(*data, base::JSON_ALLOW_TRAILING_COMMAS); | 281     auto json = base::JSONReader::Read(*data, base::JSON_ALLOW_TRAILING_COMMAS); | 
| 273     if (json) { | 282     if (json) { | 
| 274       ParseSiteList(std::move(json)); | 283       ParseSiteList(std::move(json)); | 
| 275     } else { | 284     } else { | 
| 276       OnJsonParseFailed("previously-fetched JSON was no longer parseable"); | 285       OnJsonParseFailed("previously-fetched JSON was no longer parseable"); | 
| 277     } | 286     } | 
| 278   } else { | 287   } else { | 
| 279     // File didn't exist, or couldn't be read for some other reason. | 288     // File didn't exist, or couldn't be read for some other reason. | 
| 280     FetchPopularSites(); | 289     FetchPopularSites(); | 
| 281   } | 290   } | 
| 282 } | 291 } | 
| 283 | 292 | 
| 284 void PopularSites::FetchPopularSites() { | 293 void PopularSitesImpl::FetchPopularSites() { | 
| 285   fetcher_ = URLFetcher::Create(pending_url_, URLFetcher::GET, this); | 294   fetcher_ = URLFetcher::Create(pending_url_, URLFetcher::GET, this); | 
| 286   data_use_measurement::DataUseUserData::AttachToFetcher( | 295   data_use_measurement::DataUseUserData::AttachToFetcher( | 
| 287       fetcher_.get(), data_use_measurement::DataUseUserData::NTP_TILES); | 296       fetcher_.get(), data_use_measurement::DataUseUserData::NTP_TILES); | 
| 288   fetcher_->SetRequestContext(download_context_); | 297   fetcher_->SetRequestContext(download_context_); | 
| 289   fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 298   fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 
| 290                          net::LOAD_DO_NOT_SAVE_COOKIES); | 299                          net::LOAD_DO_NOT_SAVE_COOKIES); | 
| 291   fetcher_->SetAutomaticallyRetryOnNetworkChanges(1); | 300   fetcher_->SetAutomaticallyRetryOnNetworkChanges(1); | 
| 292   fetcher_->Start(); | 301   fetcher_->Start(); | 
| 293 } | 302 } | 
| 294 | 303 | 
| 295 void PopularSites::OnURLFetchComplete(const net::URLFetcher* source) { | 304 void PopularSitesImpl::OnURLFetchComplete(const net::URLFetcher* source) { | 
| 296   DCHECK_EQ(fetcher_.get(), source); | 305   DCHECK_EQ(fetcher_.get(), source); | 
| 297   std::unique_ptr<net::URLFetcher> free_fetcher = std::move(fetcher_); | 306   std::unique_ptr<net::URLFetcher> free_fetcher = std::move(fetcher_); | 
| 298 | 307 | 
| 299   std::string json_string; | 308   std::string json_string; | 
| 300   if (!(source->GetStatus().is_success() && | 309   if (!(source->GetStatus().is_success() && | 
| 301         source->GetResponseCode() == net::HTTP_OK && | 310         source->GetResponseCode() == net::HTTP_OK && | 
| 302         source->GetResponseAsString(&json_string))) { | 311         source->GetResponseAsString(&json_string))) { | 
| 303     OnDownloadFailed(); | 312     OnDownloadFailed(); | 
| 304     return; | 313     return; | 
| 305   } | 314   } | 
| 306 | 315 | 
| 307   parse_json_.Run( | 316   parse_json_.Run(json_string, base::Bind(&PopularSitesImpl::OnJsonParsed, | 
| 308       json_string, | 317                                           weak_ptr_factory_.GetWeakPtr()), | 
| 309       base::Bind(&PopularSites::OnJsonParsed, weak_ptr_factory_.GetWeakPtr()), | 318                   base::Bind(&PopularSitesImpl::OnJsonParseFailed, | 
| 310       base::Bind(&PopularSites::OnJsonParseFailed, | 319                              weak_ptr_factory_.GetWeakPtr())); | 
| 311                  weak_ptr_factory_.GetWeakPtr())); |  | 
| 312 } | 320 } | 
| 313 | 321 | 
| 314 void PopularSites::OnJsonParsed(std::unique_ptr<base::Value> json) { | 322 void PopularSitesImpl::OnJsonParsed(std::unique_ptr<base::Value> json) { | 
| 315   const base::Value* json_ptr = json.get(); | 323   const base::Value* json_ptr = json.get(); | 
| 316   base::PostTaskAndReplyWithResult( | 324   base::PostTaskAndReplyWithResult( | 
| 317       blocking_runner_.get(), FROM_HERE, | 325       blocking_runner_.get(), FROM_HERE, | 
| 318       base::Bind(&WriteJsonToFile, local_path_, json_ptr), | 326       base::Bind(&WriteJsonToFile, local_path_, json_ptr), | 
| 319       base::Bind(&PopularSites::OnFileWriteDone, weak_ptr_factory_.GetWeakPtr(), | 327       base::Bind(&PopularSitesImpl::OnFileWriteDone, | 
|  | 328                  weak_ptr_factory_.GetWeakPtr(), | 
| 320                  base::Passed(std::move(json)))); | 329                  base::Passed(std::move(json)))); | 
| 321 } | 330 } | 
| 322 | 331 | 
| 323 void PopularSites::OnJsonParseFailed(const std::string& error_message) { | 332 void PopularSitesImpl::OnJsonParseFailed(const std::string& error_message) { | 
| 324   DLOG(WARNING) << "JSON parsing failed: " << error_message; | 333   DLOG(WARNING) << "JSON parsing failed: " << error_message; | 
| 325   OnDownloadFailed(); | 334   OnDownloadFailed(); | 
| 326 } | 335 } | 
| 327 | 336 | 
| 328 void PopularSites::OnFileWriteDone(std::unique_ptr<base::Value> json, | 337 void PopularSitesImpl::OnFileWriteDone(std::unique_ptr<base::Value> json, | 
| 329                                    bool success) { | 338                                        bool success) { | 
| 330   if (success) { | 339   if (success) { | 
| 331     prefs_->SetInt64(kPopularSitesLastDownloadPref, | 340     prefs_->SetInt64(kPopularSitesLastDownloadPref, | 
| 332                      base::Time::Now().ToInternalValue()); | 341                      base::Time::Now().ToInternalValue()); | 
| 333     prefs_->SetString(kPopularSitesURLPref, pending_url_.spec()); | 342     prefs_->SetString(kPopularSitesURLPref, pending_url_.spec()); | 
| 334     ParseSiteList(std::move(json)); | 343     ParseSiteList(std::move(json)); | 
| 335   } else { | 344   } else { | 
| 336     DLOG(WARNING) << "Could not write file to " | 345     DLOG(WARNING) << "Could not write file to " | 
| 337                   << local_path_.LossyDisplayName(); | 346                   << local_path_.LossyDisplayName(); | 
| 338     OnDownloadFailed(); | 347     OnDownloadFailed(); | 
| 339   } | 348   } | 
| 340 } | 349 } | 
| 341 | 350 | 
| 342 void PopularSites::ParseSiteList(std::unique_ptr<base::Value> json) { | 351 void PopularSitesImpl::ParseSiteList(std::unique_ptr<base::Value> json) { | 
| 343   base::ListValue* list = nullptr; | 352   base::ListValue* list = nullptr; | 
| 344   if (!json || !json->GetAsList(&list)) { | 353   if (!json || !json->GetAsList(&list)) { | 
| 345     DLOG(WARNING) << "JSON is not a list"; | 354     DLOG(WARNING) << "JSON is not a list"; | 
| 346     sites_.clear(); | 355     sites_.clear(); | 
| 347     callback_.Run(false); | 356     callback_.Run(false); | 
| 348     return; | 357     return; | 
| 349   } | 358   } | 
| 350 | 359 | 
| 351   std::vector<PopularSites::Site> sites; | 360   SitesVector sites; | 
| 352   for (size_t i = 0; i < list->GetSize(); i++) { | 361   for (size_t i = 0; i < list->GetSize(); i++) { | 
| 353     base::DictionaryValue* item; | 362     base::DictionaryValue* item; | 
| 354     if (!list->GetDictionary(i, &item)) | 363     if (!list->GetDictionary(i, &item)) | 
| 355       continue; | 364       continue; | 
| 356     base::string16 title; | 365     base::string16 title; | 
| 357     std::string url; | 366     std::string url; | 
| 358     if (!item->GetString("title", &title) || !item->GetString("url", &url)) | 367     if (!item->GetString("title", &title) || !item->GetString("url", &url)) | 
| 359       continue; | 368       continue; | 
| 360     std::string favicon_url; | 369     std::string favicon_url; | 
| 361     item->GetString("favicon_url", &favicon_url); | 370     item->GetString("favicon_url", &favicon_url); | 
| 362     std::string thumbnail_url; | 371     std::string thumbnail_url; | 
| 363     item->GetString("thumbnail_url", &thumbnail_url); | 372     item->GetString("thumbnail_url", &thumbnail_url); | 
| 364     std::string large_icon_url; | 373     std::string large_icon_url; | 
| 365     item->GetString("large_icon_url", &large_icon_url); | 374     item->GetString("large_icon_url", &large_icon_url); | 
| 366 | 375 | 
| 367     sites.push_back(PopularSites::Site(title, GURL(url), GURL(favicon_url), | 376     sites.push_back(PopularSitesImpl::Site(title, GURL(url), GURL(favicon_url), | 
| 368                                        GURL(large_icon_url), | 377                                            GURL(large_icon_url), | 
| 369                                        GURL(thumbnail_url))); | 378                                            GURL(thumbnail_url))); | 
| 370   } | 379   } | 
| 371 | 380 | 
| 372   sites_.swap(sites); | 381   sites_.swap(sites); | 
| 373   callback_.Run(true); | 382   callback_.Run(true); | 
| 374 } | 383 } | 
| 375 | 384 | 
| 376 void PopularSites::OnDownloadFailed() { | 385 void PopularSitesImpl::OnDownloadFailed() { | 
| 377   if (!is_fallback_) { | 386   if (!is_fallback_) { | 
| 378     DLOG(WARNING) << "Download country site list failed"; | 387     DLOG(WARNING) << "Download country site list failed"; | 
| 379     is_fallback_ = true; | 388     is_fallback_ = true; | 
| 380     pending_url_ = GetPopularSitesURL(kPopularSitesDefaultCountryCode, | 389     pending_url_ = GetPopularSitesURL(kPopularSitesDefaultCountryCode, | 
| 381                                       kPopularSitesDefaultVersion); | 390                                       kPopularSitesDefaultVersion); | 
| 382     FetchPopularSites(); | 391     FetchPopularSites(); | 
| 383   } else { | 392   } else { | 
| 384     DLOG(WARNING) << "Download fallback site list failed"; | 393     DLOG(WARNING) << "Download fallback site list failed"; | 
| 385     callback_.Run(false); | 394     callback_.Run(false); | 
| 386   } | 395   } | 
| 387 } | 396 } | 
| 388 | 397 | 
| 389 }  // namespace ntp_tiles | 398 }  // namespace ntp_tiles | 
| OLD | NEW | 
|---|