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 |