| 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/remote_suggestions_fetcher.h" | 5 #include "components/ntp_snippets/remote/remote_suggestions_fetcher.h" |
| 6 | 6 |
| 7 #include <cstdlib> | 7 #include <cstdlib> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 | 45 |
| 46 namespace { | 46 namespace { |
| 47 | 47 |
| 48 const char kChromeReaderApiScope[] = | 48 const char kChromeReaderApiScope[] = |
| 49 "https://www.googleapis.com/auth/webhistory"; | 49 "https://www.googleapis.com/auth/webhistory"; |
| 50 const char kContentSuggestionsApiScope[] = | 50 const char kContentSuggestionsApiScope[] = |
| 51 "https://www.googleapis.com/auth/chrome-content-suggestions"; | 51 "https://www.googleapis.com/auth/chrome-content-suggestions"; |
| 52 const char kSnippetsServerNonAuthorizedFormat[] = "%s?key=%s"; | 52 const char kSnippetsServerNonAuthorizedFormat[] = "%s?key=%s"; |
| 53 const char kAuthorizationRequestHeaderFormat[] = "Bearer %s"; | 53 const char kAuthorizationRequestHeaderFormat[] = "Bearer %s"; |
| 54 | 54 |
| 55 // Variation parameter for personalizing fetching of suggestions. | |
| 56 const char kPersonalizationName[] = "fetching_personalization"; | |
| 57 | |
| 58 // Variation parameter for chrome-content-suggestions backend. | 55 // Variation parameter for chrome-content-suggestions backend. |
| 59 const char kContentSuggestionsBackend[] = "content_suggestions_backend"; | 56 const char kContentSuggestionsBackend[] = "content_suggestions_backend"; |
| 60 | 57 |
| 61 // Constants for possible values of the "fetching_personalization" parameter. | |
| 62 const char kPersonalizationPersonalString[] = "personal"; | |
| 63 const char kPersonalizationNonPersonalString[] = "non_personal"; | |
| 64 const char kPersonalizationBothString[] = "both"; // the default value | |
| 65 | |
| 66 const int kFetchTimeHistogramResolution = 5; | 58 const int kFetchTimeHistogramResolution = 5; |
| 67 | 59 |
| 68 std::string FetchResultToString(FetchResult result) { | 60 std::string FetchResultToString(FetchResult result) { |
| 69 switch (result) { | 61 switch (result) { |
| 70 case FetchResult::SUCCESS: | 62 case FetchResult::SUCCESS: |
| 71 return "OK"; | 63 return "OK"; |
| 72 case FetchResult::DEPRECATED_EMPTY_HOSTS: | 64 case FetchResult::DEPRECATED_EMPTY_HOSTS: |
| 73 return "Cannot fetch for empty hosts list."; | 65 return "Cannot fetch for empty hosts list."; |
| 74 case FetchResult::URL_REQUEST_STATUS_ERROR: | 66 case FetchResult::URL_REQUEST_STATUS_ERROR: |
| 75 return "URLRequestStatus error"; | 67 return "URLRequestStatus error"; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 case FetchResult::JSON_PARSE_ERROR: | 104 case FetchResult::JSON_PARSE_ERROR: |
| 113 return Status(StatusCode::TEMPORARY_ERROR, FetchResultToString(result)); | 105 return Status(StatusCode::TEMPORARY_ERROR, FetchResultToString(result)); |
| 114 case FetchResult::RESULT_MAX: | 106 case FetchResult::RESULT_MAX: |
| 115 break; | 107 break; |
| 116 } | 108 } |
| 117 NOTREACHED(); | 109 NOTREACHED(); |
| 118 return Status(StatusCode::PERMANENT_ERROR, std::string()); | 110 return Status(StatusCode::PERMANENT_ERROR, std::string()); |
| 119 } | 111 } |
| 120 | 112 |
| 121 std::string GetFetchEndpoint() { | 113 std::string GetFetchEndpoint() { |
| 122 std::string endpoint = variations::GetVariationParamValue( | 114 std::string endpoint = variations::GetVariationParamValueByFeature( |
| 123 ntp_snippets::kStudyName, kContentSuggestionsBackend); | 115 ntp_snippets::kArticleSuggestionsFeature, kContentSuggestionsBackend); |
| 124 return endpoint.empty() ? kContentSuggestionsServer : endpoint; | 116 return endpoint.empty() ? kContentSuggestionsServer : endpoint; |
| 125 } | 117 } |
| 126 | 118 |
| 127 bool UsesChromeContentSuggestionsAPI(const GURL& endpoint) { | 119 bool UsesChromeContentSuggestionsAPI(const GURL& endpoint) { |
| 128 if (endpoint == kChromeReaderServer) { | 120 if (endpoint == kChromeReaderServer) { |
| 129 return false; | 121 return false; |
| 130 } | 122 } |
| 131 | 123 |
| 132 if (endpoint != kContentSuggestionsServer && | 124 if (endpoint != kContentSuggestionsServer && |
| 133 endpoint != kContentSuggestionsStagingServer && | 125 endpoint != kContentSuggestionsStagingServer && |
| 134 endpoint != kContentSuggestionsAlphaServer) { | 126 endpoint != kContentSuggestionsAlphaServer) { |
| 135 LOG(WARNING) << "Unknown value for " << kContentSuggestionsBackend << ": " | 127 LOG(WARNING) << "Unknown value for " << kContentSuggestionsBackend << ": " |
| 136 << "assuming chromecontentsuggestions-style API"; | 128 << endpoint << "; assuming chromecontentsuggestions-style API"; |
| 137 } | 129 } |
| 138 return true; | 130 return true; |
| 139 } | 131 } |
| 140 | 132 |
| 141 // Creates suggestions from dictionary values in |list| and adds them to | 133 // Creates suggestions from dictionary values in |list| and adds them to |
| 142 // |suggestions|. Returns true on success, false if anything went wrong. | 134 // |suggestions|. Returns true on success, false if anything went wrong. |
| 143 // |remote_category_id| is only used if |content_suggestions_api| is true. | 135 // |remote_category_id| is only used if |content_suggestions_api| is true. |
| 144 bool AddSuggestionsFromListValue(bool content_suggestions_api, | 136 bool AddSuggestionsFromListValue(bool content_suggestions_api, |
| 145 int remote_category_id, | 137 int remote_category_id, |
| 146 const base::ListValue& list, | 138 const base::ListValue& list, |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 RequestThrottler::RequestType:: | 262 RequestThrottler::RequestType:: |
| 271 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), | 263 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), |
| 272 request_throttler_active_ntp_user_( | 264 request_throttler_active_ntp_user_( |
| 273 pref_service, | 265 pref_service, |
| 274 RequestThrottler::RequestType:: | 266 RequestThrottler::RequestType:: |
| 275 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), | 267 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), |
| 276 request_throttler_active_suggestions_consumer_( | 268 request_throttler_active_suggestions_consumer_( |
| 277 pref_service, | 269 pref_service, |
| 278 RequestThrottler::RequestType:: | 270 RequestThrottler::RequestType:: |
| 279 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), | 271 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), |
| 280 weak_ptr_factory_(this) { | 272 weak_ptr_factory_(this) {} |
| 281 std::string personalization = variations::GetVariationParamValue( | |
| 282 ntp_snippets::kStudyName, kPersonalizationName); | |
| 283 if (personalization == kPersonalizationNonPersonalString) { | |
| 284 personalization_ = Personalization::kNonPersonal; | |
| 285 } else if (personalization == kPersonalizationPersonalString) { | |
| 286 personalization_ = Personalization::kPersonal; | |
| 287 } else { | |
| 288 personalization_ = Personalization::kBoth; | |
| 289 LOG_IF(WARNING, !personalization.empty() && | |
| 290 personalization != kPersonalizationBothString) | |
| 291 << "Unknown value for " << kPersonalizationName << ": " | |
| 292 << personalization; | |
| 293 } | |
| 294 } | |
| 295 | 273 |
| 296 RemoteSuggestionsFetcher::~RemoteSuggestionsFetcher() { | 274 RemoteSuggestionsFetcher::~RemoteSuggestionsFetcher() { |
| 297 if (waiting_for_refresh_token_) { | 275 if (waiting_for_refresh_token_) { |
| 298 token_service_->RemoveObserver(this); | 276 token_service_->RemoveObserver(this); |
| 299 } | 277 } |
| 300 } | 278 } |
| 301 | 279 |
| 302 void RemoteSuggestionsFetcher::FetchSnippets( | 280 void RemoteSuggestionsFetcher::FetchSnippets( |
| 303 const RequestParams& params, | 281 const RequestParams& params, |
| 304 SnippetsAvailableCallback callback) { | 282 SnippetsAvailableCallback callback) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 319 GetMinuteOfTheDay(/*local_time=*/false, | 297 GetMinuteOfTheDay(/*local_time=*/false, |
| 320 /*reduced_resolution=*/true)); | 298 /*reduced_resolution=*/true)); |
| 321 } | 299 } |
| 322 | 300 |
| 323 JsonRequest::Builder builder; | 301 JsonRequest::Builder builder; |
| 324 builder.SetFetchAPI(fetch_api_) | 302 builder.SetFetchAPI(fetch_api_) |
| 325 .SetFetchAPI(fetch_api_) | 303 .SetFetchAPI(fetch_api_) |
| 326 .SetLanguageModel(language_model_) | 304 .SetLanguageModel(language_model_) |
| 327 .SetParams(params) | 305 .SetParams(params) |
| 328 .SetParseJsonCallback(parse_json_callback_) | 306 .SetParseJsonCallback(parse_json_callback_) |
| 329 .SetPersonalization(personalization_) | |
| 330 .SetTickClock(tick_clock_.get()) | 307 .SetTickClock(tick_clock_.get()) |
| 331 .SetUrlRequestContextGetter(url_request_context_getter_) | 308 .SetUrlRequestContextGetter(url_request_context_getter_) |
| 332 .SetUserClassifier(*user_classifier_); | 309 .SetUserClassifier(*user_classifier_); |
| 333 | 310 |
| 334 if (NeedsAuthentication() && signin_manager_->IsAuthenticated()) { | 311 if (signin_manager_->IsAuthenticated()) { |
| 335 // Signed-in: get OAuth token --> fetch suggestions. | 312 // Signed-in: get OAuth token --> fetch suggestions. |
| 336 oauth_token_retried_ = false; | 313 oauth_token_retried_ = false; |
| 337 pending_requests_.emplace(std::move(builder), std::move(callback)); | 314 pending_requests_.emplace(std::move(builder), std::move(callback)); |
| 338 StartTokenRequest(); | 315 StartTokenRequest(); |
| 339 } else if (NeedsAuthentication() && signin_manager_->AuthInProgress()) { | 316 } else if (signin_manager_->AuthInProgress()) { |
| 340 // Currently signing in: wait for auth to finish (the refresh token) --> | 317 // Currently signing in: wait for auth to finish (the refresh token) --> |
| 341 // get OAuth token --> fetch suggestions. | 318 // get OAuth token --> fetch suggestions. |
| 342 pending_requests_.emplace(std::move(builder), std::move(callback)); | 319 pending_requests_.emplace(std::move(builder), std::move(callback)); |
| 343 if (!waiting_for_refresh_token_) { | 320 if (!waiting_for_refresh_token_) { |
| 344 // Wait until we get a refresh token. | 321 // Wait until we get a refresh token. |
| 345 waiting_for_refresh_token_ = true; | 322 waiting_for_refresh_token_ = true; |
| 346 token_service_->AddObserver(this); | 323 token_service_->AddObserver(this); |
| 347 } | 324 } |
| 348 } else { | 325 } else { |
| 349 // Not signed in: fetch suggestions (without authentication). | 326 // Not signed in: fetch suggestions (without authentication). |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 return request_throttler_active_ntp_user_.DemandQuotaForRequest( | 570 return request_throttler_active_ntp_user_.DemandQuotaForRequest( |
| 594 interactive_request); | 571 interactive_request); |
| 595 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: | 572 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: |
| 596 return request_throttler_active_suggestions_consumer_ | 573 return request_throttler_active_suggestions_consumer_ |
| 597 .DemandQuotaForRequest(interactive_request); | 574 .DemandQuotaForRequest(interactive_request); |
| 598 } | 575 } |
| 599 NOTREACHED(); | 576 NOTREACHED(); |
| 600 return false; | 577 return false; |
| 601 } | 578 } |
| 602 | 579 |
| 603 bool RemoteSuggestionsFetcher::NeedsAuthentication() const { | |
| 604 return (personalization_ == Personalization::kPersonal || | |
| 605 personalization_ == Personalization::kBoth); | |
| 606 } | |
| 607 | |
| 608 std::string RemoteSuggestionsFetcher::PersonalizationModeString() const { | |
| 609 switch (personalization_) { | |
| 610 case Personalization::kPersonal: | |
| 611 return "Only personalized"; | |
| 612 break; | |
| 613 case Personalization::kBoth: | |
| 614 return "Both personalized and non-personalized"; | |
| 615 break; | |
| 616 case Personalization::kNonPersonal: | |
| 617 return "Only non-personalized"; | |
| 618 break; | |
| 619 } | |
| 620 NOTREACHED(); | |
| 621 return std::string(); | |
| 622 } | |
| 623 | |
| 624 } // namespace ntp_snippets | 580 } // namespace ntp_snippets |
| OLD | NEW |