Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/remote/ntp_snippets_fetcher.h" | 5 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" |
| 6 | 6 |
| 7 #include <cstdlib> | 7 #include <cstdlib> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 return true; | 137 return true; |
| 138 } | 138 } |
| 139 | 139 |
| 140 // Creates snippets from dictionary values in |list| and adds them to | 140 // Creates snippets from dictionary values in |list| and adds them to |
| 141 // |snippets|. Returns true on success, false if anything went wrong. | 141 // |snippets|. Returns true on success, false if anything went wrong. |
| 142 bool AddSnippetsFromListValue(bool content_suggestions_api, | 142 bool AddSnippetsFromListValue(bool content_suggestions_api, |
| 143 const base::ListValue& list, | 143 const base::ListValue& list, |
| 144 NTPSnippet::PtrVector* snippets) { | 144 NTPSnippet::PtrVector* snippets) { |
| 145 for (const auto& value : list) { | 145 for (const auto& value : list) { |
| 146 const base::DictionaryValue* dict = nullptr; | 146 const base::DictionaryValue* dict = nullptr; |
| 147 if (!value->GetAsDictionary(&dict)) | 147 if (!value->GetAsDictionary(&dict)) { |
|
Marc Treib
2016/10/06 15:36:13
Ah, a fan of braces for single-line bodies... I'm
tschumann
2016/10/06 17:57:42
added those after adding debug statements and wond
| |
| 148 return false; | 148 return false; |
| 149 } | |
| 149 | 150 |
| 150 std::unique_ptr<NTPSnippet> snippet; | 151 std::unique_ptr<NTPSnippet> snippet; |
| 151 if (content_suggestions_api) { | 152 if (content_suggestions_api) { |
| 152 snippet = NTPSnippet::CreateFromContentSuggestionsDictionary(*dict); | 153 snippet = NTPSnippet::CreateFromContentSuggestionsDictionary(*dict); |
| 153 } else { | 154 } else { |
| 154 snippet = NTPSnippet::CreateFromChromeReaderDictionary(*dict); | 155 snippet = NTPSnippet::CreateFromChromeReaderDictionary(*dict); |
| 155 } | 156 } |
| 156 if (!snippet) | 157 if (!snippet) { |
| 157 return false; | 158 return false; |
| 159 } | |
| 158 | 160 |
| 159 snippets->push_back(std::move(snippet)); | 161 snippets->push_back(std::move(snippet)); |
| 160 } | 162 } |
| 161 return true; | 163 return true; |
| 162 } | 164 } |
| 163 | 165 |
| 164 // Translate the BCP 47 |language_code| into a posix locale string. | 166 // Translate the BCP 47 |language_code| into a posix locale string. |
| 165 std::string PosixLocaleFromBCP47Language(const std::string& language_code) { | 167 std::string PosixLocaleFromBCP47Language(const std::string& language_code) { |
| 166 char locale[ULOC_FULLNAME_CAPACITY]; | 168 char locale[ULOC_FULLNAME_CAPACITY]; |
| 167 UErrorCode error = U_ZERO_ERROR; | 169 UErrorCode error = U_ZERO_ERROR; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 snippets_available_callback_ = callback; | 252 snippets_available_callback_ = callback; |
| 251 } | 253 } |
| 252 | 254 |
| 253 void NTPSnippetsFetcher::FetchSnippetsFromHosts( | 255 void NTPSnippetsFetcher::FetchSnippetsFromHosts( |
| 254 const std::set<std::string>& hosts, | 256 const std::set<std::string>& hosts, |
| 255 const std::string& language_code, | 257 const std::string& language_code, |
| 256 const std::set<std::string>& excluded_ids, | 258 const std::set<std::string>& excluded_ids, |
| 257 int count, | 259 int count, |
| 258 bool interactive_request) { | 260 bool interactive_request) { |
| 259 if (!request_throttler_.DemandQuotaForRequest(interactive_request)) { | 261 if (!request_throttler_.DemandQuotaForRequest(interactive_request)) { |
| 260 FetchFinished(OptionalSnippets(), | 262 FetchFinished(OptionalFetchedCategories(), |
| 261 interactive_request | 263 interactive_request |
| 262 ? FetchResult::INTERACTIVE_QUOTA_ERROR | 264 ? FetchResult::INTERACTIVE_QUOTA_ERROR |
| 263 : FetchResult::NON_INTERACTIVE_QUOTA_ERROR, | 265 : FetchResult::NON_INTERACTIVE_QUOTA_ERROR, |
| 264 /*extra_message=*/std::string()); | 266 /*extra_message=*/std::string()); |
| 265 return; | 267 return; |
| 266 } | 268 } |
| 267 | 269 |
| 268 hosts_ = hosts; | 270 hosts_ = hosts; |
| 269 fetch_start_time_ = tick_clock_->NowTicks(); | 271 fetch_start_time_ = tick_clock_->NowTicks(); |
| 270 excluded_ids_ = excluded_ids; | 272 excluded_ids_ = excluded_ids; |
| 271 | 273 |
| 272 if (UsesHostRestrictions() && hosts_.empty()) { | 274 if (UsesHostRestrictions() && hosts_.empty()) { |
| 273 FetchFinished(OptionalSnippets(), FetchResult::EMPTY_HOSTS, | 275 FetchFinished(OptionalFetchedCategories(), FetchResult::EMPTY_HOSTS, |
| 274 /*extra_message=*/std::string()); | 276 /*extra_message=*/std::string()); |
| 275 return; | 277 return; |
| 276 } | 278 } |
| 277 | 279 |
| 278 locale_ = PosixLocaleFromBCP47Language(language_code); | 280 locale_ = PosixLocaleFromBCP47Language(language_code); |
| 279 count_to_fetch_ = count; | 281 count_to_fetch_ = count; |
| 280 | 282 |
| 281 bool use_authentication = UsesAuthentication(); | 283 bool use_authentication = UsesAuthentication(); |
| 282 interactive_request_ = interactive_request; | 284 interactive_request_ = interactive_request; |
| 283 | 285 |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 error.state() == GoogleServiceAuthError::State::REQUEST_CANCELED) { | 512 error.state() == GoogleServiceAuthError::State::REQUEST_CANCELED) { |
| 511 // The request (especially on startup) can get reset by loading the refresh | 513 // The request (especially on startup) can get reset by loading the refresh |
| 512 // token - do it one more time. | 514 // token - do it one more time. |
| 513 oauth_token_retried_ = true; | 515 oauth_token_retried_ = true; |
| 514 StartTokenRequest(); | 516 StartTokenRequest(); |
| 515 return; | 517 return; |
| 516 } | 518 } |
| 517 | 519 |
| 518 DLOG(ERROR) << "Unable to get token: " << error.ToString(); | 520 DLOG(ERROR) << "Unable to get token: " << error.ToString(); |
| 519 FetchFinished( | 521 FetchFinished( |
| 520 OptionalSnippets(), FetchResult::OAUTH_TOKEN_ERROR, | 522 OptionalFetchedCategories(), FetchResult::OAUTH_TOKEN_ERROR, |
| 521 /*extra_message=*/base::StringPrintf(" (%s)", error.ToString().c_str())); | 523 /*extra_message=*/base::StringPrintf(" (%s)", error.ToString().c_str())); |
| 522 } | 524 } |
| 523 | 525 |
| 524 //////////////////////////////////////////////////////////////////////////////// | 526 //////////////////////////////////////////////////////////////////////////////// |
| 525 // OAuth2TokenService::Observer overrides | 527 // OAuth2TokenService::Observer overrides |
| 526 void NTPSnippetsFetcher::OnRefreshTokenAvailable( | 528 void NTPSnippetsFetcher::OnRefreshTokenAvailable( |
| 527 const std::string& account_id) { | 529 const std::string& account_id) { |
| 528 // Only react on tokens for the account the user has signed in with. | 530 // Only react on tokens for the account the user has signed in with. |
| 529 if (account_id != signin_manager_->GetAuthenticatedAccountId()) | 531 if (account_id != signin_manager_->GetAuthenticatedAccountId()) |
| 530 return; | 532 return; |
| 531 | 533 |
| 532 token_service_->RemoveObserver(this); | 534 token_service_->RemoveObserver(this); |
| 533 waiting_for_refresh_token_ = false; | 535 waiting_for_refresh_token_ = false; |
| 534 oauth_token_retried_ = false; | 536 oauth_token_retried_ = false; |
| 535 StartTokenRequest(); | 537 StartTokenRequest(); |
| 536 } | 538 } |
| 537 | 539 |
| 538 //////////////////////////////////////////////////////////////////////////////// | 540 //////////////////////////////////////////////////////////////////////////////// |
| 539 // URLFetcherDelegate overrides | 541 // URLFetcherDelegate overrides |
| 540 void NTPSnippetsFetcher::OnURLFetchComplete(const URLFetcher* source) { | 542 void NTPSnippetsFetcher::OnURLFetchComplete(const URLFetcher* source) { |
| 541 DCHECK_EQ(url_fetcher_.get(), source); | 543 DCHECK_EQ(url_fetcher_.get(), source); |
| 542 | 544 |
| 543 const URLRequestStatus& status = source->GetStatus(); | 545 const URLRequestStatus& status = source->GetStatus(); |
| 544 | 546 |
| 545 UMA_HISTOGRAM_SPARSE_SLOWLY( | 547 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 546 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode", | 548 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode", |
| 547 status.is_success() ? source->GetResponseCode() : status.error()); | 549 status.is_success() ? source->GetResponseCode() : status.error()); |
| 548 | 550 |
| 549 if (!status.is_success()) { | 551 if (!status.is_success()) { |
| 550 FetchFinished(OptionalSnippets(), FetchResult::URL_REQUEST_STATUS_ERROR, | 552 FetchFinished(OptionalFetchedCategories(), |
| 553 FetchResult::URL_REQUEST_STATUS_ERROR, | |
| 551 /*extra_message=*/base::StringPrintf(" %d", status.error())); | 554 /*extra_message=*/base::StringPrintf(" %d", status.error())); |
| 552 } else if (source->GetResponseCode() != net::HTTP_OK) { | 555 } else if (source->GetResponseCode() != net::HTTP_OK) { |
| 553 // TODO(jkrcal): https://crbug.com/609084 | 556 // TODO(jkrcal): https://crbug.com/609084 |
| 554 // We need to deal with the edge case again where the auth | 557 // We need to deal with the edge case again where the auth |
| 555 // token expires just before we send the request (in which case we need to | 558 // token expires just before we send the request (in which case we need to |
| 556 // fetch a new auth token). We should extract that into a common class | 559 // fetch a new auth token). We should extract that into a common class |
| 557 // instead of adding it to every single class that uses auth tokens. | 560 // instead of adding it to every single class that uses auth tokens. |
| 558 FetchFinished( | 561 FetchFinished( |
| 559 OptionalSnippets(), FetchResult::HTTP_ERROR, | 562 OptionalFetchedCategories(), FetchResult::HTTP_ERROR, |
| 560 /*extra_message=*/base::StringPrintf(" %d", source->GetResponseCode())); | 563 /*extra_message=*/base::StringPrintf(" %d", source->GetResponseCode())); |
| 561 } else { | 564 } else { |
| 562 bool stores_result_to_string = | 565 bool stores_result_to_string = |
| 563 source->GetResponseAsString(&last_fetch_json_); | 566 source->GetResponseAsString(&last_fetch_json_); |
| 564 DCHECK(stores_result_to_string); | 567 DCHECK(stores_result_to_string); |
| 565 | 568 |
| 566 parse_json_callback_.Run(last_fetch_json_, | 569 parse_json_callback_.Run(last_fetch_json_, |
| 567 base::Bind(&NTPSnippetsFetcher::OnJsonParsed, | 570 base::Bind(&NTPSnippetsFetcher::OnJsonParsed, |
| 568 weak_ptr_factory_.GetWeakPtr()), | 571 weak_ptr_factory_.GetWeakPtr()), |
| 569 base::Bind(&NTPSnippetsFetcher::OnJsonError, | 572 base::Bind(&NTPSnippetsFetcher::OnJsonError, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 return true; | 627 return true; |
| 625 } | 628 } |
| 626 } | 629 } |
| 627 NOTREACHED(); | 630 NOTREACHED(); |
| 628 return false; | 631 return false; |
| 629 } | 632 } |
| 630 | 633 |
| 631 void NTPSnippetsFetcher::OnJsonParsed(std::unique_ptr<base::Value> parsed) { | 634 void NTPSnippetsFetcher::OnJsonParsed(std::unique_ptr<base::Value> parsed) { |
| 632 FetchedCategoriesVector categories; | 635 FetchedCategoriesVector categories; |
| 633 if (JsonToSnippets(*parsed, &categories)) { | 636 if (JsonToSnippets(*parsed, &categories)) { |
| 634 FetchFinished(OptionalSnippets(std::move(categories)), FetchResult::SUCCESS, | 637 FetchFinished(OptionalFetchedCategories(std::move(categories)), |
| 638 FetchResult::SUCCESS, | |
| 635 /*extra_message=*/std::string()); | 639 /*extra_message=*/std::string()); |
| 636 } else { | 640 } else { |
| 637 LOG(WARNING) << "Received invalid snippets: " << last_fetch_json_; | 641 LOG(WARNING) << "Received invalid snippets: " << last_fetch_json_; |
| 638 FetchFinished(OptionalSnippets(), | 642 FetchFinished(OptionalFetchedCategories(), |
| 639 FetchResult::INVALID_SNIPPET_CONTENT_ERROR, | 643 FetchResult::INVALID_SNIPPET_CONTENT_ERROR, |
| 640 /*extra_message=*/std::string()); | 644 /*extra_message=*/std::string()); |
| 641 } | 645 } |
| 642 } | 646 } |
| 643 | 647 |
| 644 void NTPSnippetsFetcher::OnJsonError(const std::string& error) { | 648 void NTPSnippetsFetcher::OnJsonError(const std::string& error) { |
| 645 LOG(WARNING) << "Received invalid JSON (" << error | 649 LOG(WARNING) << "Received invalid JSON (" << error |
| 646 << "): " << last_fetch_json_; | 650 << "): " << last_fetch_json_; |
| 647 FetchFinished( | 651 FetchFinished( |
| 648 OptionalSnippets(), FetchResult::JSON_PARSE_ERROR, | 652 OptionalFetchedCategories(), FetchResult::JSON_PARSE_ERROR, |
| 649 /*extra_message=*/base::StringPrintf(" (error %s)", error.c_str())); | 653 /*extra_message=*/base::StringPrintf(" (error %s)", error.c_str())); |
| 650 } | 654 } |
| 651 | 655 |
| 652 void NTPSnippetsFetcher::FetchFinished(OptionalSnippets snippets, | 656 void NTPSnippetsFetcher::FetchFinished( |
| 653 FetchResult result, | 657 OptionalFetchedCategories fetched_categories, |
| 654 const std::string& extra_message) { | 658 FetchResult result, |
| 655 DCHECK(result == FetchResult::SUCCESS || !snippets); | 659 const std::string& extra_message) { |
| 660 DCHECK(result == FetchResult::SUCCESS || !fetched_categories); | |
| 656 last_status_ = FetchResultToString(result) + extra_message; | 661 last_status_ = FetchResultToString(result) + extra_message; |
| 657 | 662 |
| 658 // Don't record FetchTimes if the result indicates that a precondition | 663 // Don't record FetchTimes if the result indicates that a precondition |
| 659 // failed and we never actually sent a network request | 664 // failed and we never actually sent a network request |
| 660 if (!IsFetchPreconditionFailed(result)) { | 665 if (!IsFetchPreconditionFailed(result)) { |
| 661 UMA_HISTOGRAM_TIMES("NewTabPage.Snippets.FetchTime", | 666 UMA_HISTOGRAM_TIMES("NewTabPage.Snippets.FetchTime", |
| 662 tick_clock_->NowTicks() - fetch_start_time_); | 667 tick_clock_->NowTicks() - fetch_start_time_); |
| 663 } | 668 } |
| 664 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.FetchResult", | 669 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.FetchResult", |
| 665 static_cast<int>(result), | 670 static_cast<int>(result), |
| 666 static_cast<int>(FetchResult::RESULT_MAX)); | 671 static_cast<int>(FetchResult::RESULT_MAX)); |
| 667 | 672 |
| 668 DVLOG(1) << "Fetch finished: " << last_status_; | 673 DVLOG(1) << "Fetch finished: " << last_status_; |
| 669 if (!snippets_available_callback_.is_null()) | 674 if (!snippets_available_callback_.is_null()) |
| 670 snippets_available_callback_.Run(std::move(snippets)); | 675 snippets_available_callback_.Run(std::move(fetched_categories)); |
| 671 } | 676 } |
| 672 | 677 |
| 673 } // namespace ntp_snippets | 678 } // namespace ntp_snippets |
| OLD | NEW |