Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: components/ntp_snippets/ntp_snippets_fetcher.cc

Issue 1974483002: Allow getting _only_ personalized snippets for NTP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: After code review #3 Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/ntp_snippets_fetcher.h" 5 #include "components/ntp_snippets/ntp_snippets_fetcher.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
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 30 matching lines...) Expand all
41 namespace ntp_snippets { 41 namespace ntp_snippets {
42 42
43 namespace { 43 namespace {
44 44
45 const char kApiScope[] = "https://www.googleapis.com/auth/webhistory"; 45 const char kApiScope[] = "https://www.googleapis.com/auth/webhistory";
46 const char kSnippetsServer[] = 46 const char kSnippetsServer[] =
47 "https://chromereader-pa.googleapis.com/v1/fetch"; 47 "https://chromereader-pa.googleapis.com/v1/fetch";
48 const char kSnippetsServerNonAuthorizedFormat[] = "%s?key=%s"; 48 const char kSnippetsServerNonAuthorizedFormat[] = "%s?key=%s";
49 const char kAuthorizationRequestHeaderFormat[] = "Bearer %s"; 49 const char kAuthorizationRequestHeaderFormat[] = "Bearer %s";
50 50
51 // Variation parameter for the variant of fetching to use. 51 // Variation parameter for personalizing fetching of snippets.
52 const char kVariantName[] = "fetching_variant"; 52 const char kPersonalizationName[] = "fetching_personalization";
53 const char kHostRestrictionName[] = "fetching_host_restrict";
53 54
54 // Constants listing possible values of the "fetching_variant" parameter. 55 // Constants for possible values of the "fetching_personalization" parameter.
55 const char kVariantRestrictedString[] = "restricted"; 56 const char kPersonalizationPersonalString[] = "personal";
56 const char kVariantPersonalizedString[] = "personalized"; 57 const char kPersonalizationNonPersonalString[] = "non_personal";
57 const char kVariantRestrictedPersonalizedString[] = "restricted_personalized"; 58 const char kPersonalizationBothString[] = "both"; // the default value
58 59
59 const char kRequestParameterFormat[] = 60 // Constants for possible values of the "fetching_host_restrict" parameter.
61 const char kHostRestrictionOnString[] = "on"; // the default value
62 const char kHostRestrictionOffString[] = "off";
63
64 const char kRequestFormat[] =
60 "{" 65 "{"
61 " \"response_detail_level\": \"STANDARD\"," 66 " \"response_detail_level\": \"STANDARD\","
62 "%s" // If authenticated - an obfuscated Gaia ID will be inserted here. 67 "%s" // If authenticated - an obfuscated Gaia ID will be inserted here.
63 " \"advanced_options\": {" 68 " \"advanced_options\": {"
64 " \"local_scoring_params\": {" 69 " \"local_scoring_params\": {"
65 " \"content_params\": {" 70 " \"content_params\": {"
66 " \"only_return_personalized_results\": false" 71 " \"only_return_personalized_results\": %s"
67 "%s" // If authenticated - user segment (lang code) will be inserted here. 72 "%s" // If authenticated - user segment (lang code) will be inserted here.
68 " }," 73 " },"
69 " \"content_restricts\": [" 74 " \"content_restricts\": ["
70 " {" 75 " {"
71 " \"type\": \"METADATA\"," 76 " \"type\": \"METADATA\","
72 " \"value\": \"TITLE\"" 77 " \"value\": \"TITLE\""
73 " }," 78 " },"
74 " {" 79 " {"
75 " \"type\": \"METADATA\"," 80 " \"type\": \"METADATA\","
76 " \"value\": \"SNIPPET\"" 81 " \"value\": \"SNIPPET\""
(...skipping 12 matching lines...) Expand all
89 " }" 94 " }"
90 "}"; 95 "}";
91 96
92 const char kGaiaIdFormat[] = " \"obfuscated_gaia_id\": \"%s\","; 97 const char kGaiaIdFormat[] = " \"obfuscated_gaia_id\": \"%s\",";
93 const char kUserSegmentFormat[] = " ,\"user_segment\": \"%s\""; 98 const char kUserSegmentFormat[] = " ,\"user_segment\": \"%s\"";
94 const char kHostRestrictFormat[] = 99 const char kHostRestrictFormat[] =
95 " {" 100 " {"
96 " \"type\": \"HOST_RESTRICT\"," 101 " \"type\": \"HOST_RESTRICT\","
97 " \"value\": \"%s\"" 102 " \"value\": \"%s\""
98 " }"; 103 " }";
104 const char kTrueString[] = "true";
105 const char kFalseString[] = "false";
99 106
100 std::string FetchResultToString(NTPSnippetsFetcher::FetchResult result) { 107 std::string FetchResultToString(NTPSnippetsFetcher::FetchResult result) {
101 switch (result) { 108 switch (result) {
102 case NTPSnippetsFetcher::FetchResult::SUCCESS: 109 case NTPSnippetsFetcher::FetchResult::SUCCESS:
103 return "OK"; 110 return "OK";
104 case NTPSnippetsFetcher::FetchResult::EMPTY_HOSTS: 111 case NTPSnippetsFetcher::FetchResult::EMPTY_HOSTS:
105 return "Cannot fetch for empty hosts list."; 112 return "Cannot fetch for empty hosts list.";
106 case NTPSnippetsFetcher::FetchResult::URL_REQUEST_STATUS_ERROR: 113 case NTPSnippetsFetcher::FetchResult::URL_REQUEST_STATUS_ERROR:
107 return "URLRequestStatus error"; 114 return "URLRequestStatus error";
108 case NTPSnippetsFetcher::FetchResult::HTTP_ERROR: 115 case NTPSnippetsFetcher::FetchResult::HTTP_ERROR:
109 return "HTTP error"; 116 return "HTTP error";
110 case NTPSnippetsFetcher::FetchResult::JSON_PARSE_ERROR: 117 case NTPSnippetsFetcher::FetchResult::JSON_PARSE_ERROR:
111 return "Received invalid JSON"; 118 return "Received invalid JSON";
112 case NTPSnippetsFetcher::FetchResult::INVALID_SNIPPET_CONTENT_ERROR: 119 case NTPSnippetsFetcher::FetchResult::INVALID_SNIPPET_CONTENT_ERROR:
113 return "Invalid / empty list."; 120 return "Invalid / empty list.";
121 case NTPSnippetsFetcher::FetchResult::OAUTH_TOKEN_ERROR:
122 return "Error in obtaining an oauth2 access token.";
Marc Treib 2016/05/12 13:57:59 nit: OAuth2
jkrcal 2016/05/12 14:14:04 Done.
114 case NTPSnippetsFetcher::FetchResult::RESULT_MAX: 123 case NTPSnippetsFetcher::FetchResult::RESULT_MAX:
115 break; 124 break;
116 } 125 }
117 NOTREACHED(); 126 NOTREACHED();
118 return "Unknown error"; 127 return "Unknown error";
119 } 128 }
120 129
130 std::string BuildRequest(const std::string& obfuscated_gaia_id,
131 bool only_return_personalized_results,
132 const std::string& user_segment,
133 const std::string& host_restricts,
134 int count_to_fetch) {
135 return base::StringPrintf(
136 kRequestFormat, obfuscated_gaia_id.c_str(),
137 only_return_personalized_results ? kTrueString : kFalseString,
138 user_segment.c_str(), host_restricts.c_str(), count_to_fetch);
139 }
140
121 } // namespace 141 } // namespace
122 142
123 NTPSnippetsFetcher::NTPSnippetsFetcher( 143 NTPSnippetsFetcher::NTPSnippetsFetcher(
124 SigninManagerBase* signin_manager, 144 SigninManagerBase* signin_manager,
125 OAuth2TokenService* token_service, 145 OAuth2TokenService* token_service,
126 scoped_refptr<URLRequestContextGetter> url_request_context_getter, 146 scoped_refptr<URLRequestContextGetter> url_request_context_getter,
127 const ParseJSONCallback& parse_json_callback, 147 const ParseJSONCallback& parse_json_callback,
128 bool is_stable_channel) 148 bool is_stable_channel)
129 : OAuth2TokenService::Consumer("ntp_snippets"), 149 : OAuth2TokenService::Consumer("ntp_snippets"),
130 signin_manager_(signin_manager), 150 signin_manager_(signin_manager),
131 token_service_(token_service), 151 token_service_(token_service),
132 waiting_for_refresh_token_(false), 152 waiting_for_refresh_token_(false),
133 url_request_context_getter_(url_request_context_getter), 153 url_request_context_getter_(url_request_context_getter),
134 parse_json_callback_(parse_json_callback), 154 parse_json_callback_(parse_json_callback),
135 is_stable_channel_(is_stable_channel), 155 is_stable_channel_(is_stable_channel),
136 tick_clock_(new base::DefaultTickClock()), 156 tick_clock_(new base::DefaultTickClock()),
137 weak_ptr_factory_(this) { 157 weak_ptr_factory_(this) {
138 // Parse the variation parameters and set the defaults if missing. 158 // Parse the variation parameters and set the defaults if missing.
139 std::string variant = variations::GetVariationParamValue( 159 std::string personalization = variations::GetVariationParamValue(
140 ntp_snippets::kStudyName, kVariantName); 160 ntp_snippets::kStudyName, kPersonalizationName);
141 if (variant == kVariantRestrictedString) { 161 if (personalization == kPersonalizationNonPersonalString) {
142 variant_ = Variant::kRestricted; 162 personalization_ = Personalization::kNonPersonal;
143 } else if (variant == kVariantPersonalizedString) { 163 } else if (personalization == kPersonalizationPersonalString) {
144 variant_ = Variant::kPersonalized; 164 personalization_ = Personalization::kPersonal;
145 } else { 165 } else {
146 variant_ = Variant::kRestrictedPersonalized; 166 personalization_ = Personalization::kBoth;
147 LOG_IF(WARNING, 167 LOG_IF(WARNING, !personalization.empty() &&
148 !variant.empty() && variant != kVariantRestrictedPersonalizedString) 168 personalization != kPersonalizationBothString)
149 << "Unknown fetching variant provided: " << variant; 169 << "Unknown value for " << kPersonalizationName << ": "
170 << personalization;
171 }
172
173 std::string host_restriction = variations::GetVariationParamValue(
174 ntp_snippets::kStudyName, kHostRestrictionName);
175 if (host_restriction == kHostRestrictionOffString) {
176 use_host_restriction_ = false;
177 } else {
178 use_host_restriction_ = true;
179 LOG_IF(WARNING, !host_restriction.empty() &&
180 host_restriction != kHostRestrictionOnString)
181 << "Unknown value for " << kHostRestrictionName << ": "
182 << host_restriction;
150 } 183 }
151 } 184 }
152 185
153 NTPSnippetsFetcher::~NTPSnippetsFetcher() { 186 NTPSnippetsFetcher::~NTPSnippetsFetcher() {
154 if (waiting_for_refresh_token_) 187 if (waiting_for_refresh_token_)
155 token_service_->RemoveObserver(this); 188 token_service_->RemoveObserver(this);
156 } 189 }
157 190
158 void NTPSnippetsFetcher::SetCallback( 191 void NTPSnippetsFetcher::SetCallback(
159 const SnippetsAvailableCallback& callback) { 192 const SnippetsAvailableCallback& callback) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 for (const std::string& host : hosts_) { 267 for (const std::string& host : hosts_) {
235 if (!host_restricts.empty()) 268 if (!host_restricts.empty())
236 host_restricts.push_back(','); 269 host_restricts.push_back(',');
237 host_restricts += base::StringPrintf(kHostRestrictFormat, host.c_str()); 270 host_restricts += base::StringPrintf(kHostRestrictFormat, host.c_str());
238 } 271 }
239 } 272 }
240 return host_restricts; 273 return host_restricts;
241 } 274 }
242 275
243 bool NTPSnippetsFetcher::UseHostRestriction() const { 276 bool NTPSnippetsFetcher::UseHostRestriction() const {
244 return (variant_ == Variant::kRestricted || 277 return use_host_restriction_ &&
245 variant_ == Variant::kRestrictedPersonalized) &&
246 !base::CommandLine::ForCurrentProcess()->HasSwitch( 278 !base::CommandLine::ForCurrentProcess()->HasSwitch(
247 switches::kDontRestrict); 279 switches::kDontRestrict);
248 } 280 }
249 281
250 bool NTPSnippetsFetcher::UseAuthentication() const { 282 bool NTPSnippetsFetcher::UseAuthentication() const {
251 return (variant_ == Variant::kPersonalized || 283 return (personalization_ == Personalization::kPersonal ||
252 variant_ == Variant::kRestrictedPersonalized); 284 personalization_ == Personalization::kBoth);
253 } 285 }
254 286
255 void NTPSnippetsFetcher::FetchSnippetsNonAuthenticated() { 287 void NTPSnippetsFetcher::FetchSnippetsNonAuthenticated() {
256 // When not providing OAuth token, we need to pass the Google API key. 288 // When not providing OAuth token, we need to pass the Google API key.
257 const std::string& key = is_stable_channel_ 289 const std::string& key = is_stable_channel_
258 ? google_apis::GetAPIKey() 290 ? google_apis::GetAPIKey()
259 : google_apis::GetNonStableAPIKey(); 291 : google_apis::GetNonStableAPIKey();
260 GURL url(base::StringPrintf(kSnippetsServerNonAuthorizedFormat, 292 GURL url(base::StringPrintf(kSnippetsServerNonAuthorizedFormat,
261 kSnippetsServer, key.c_str())); 293 kSnippetsServer, key.c_str()));
262 294
263 FetchSnippetsImpl( 295 FetchSnippetsImpl(url, std::string(),
264 url, std::string(), 296 BuildRequest(/*obfuscated_gaia_id=*/std::string(),
265 base::StringPrintf(kRequestParameterFormat, "", "", 297 /*only_return_personalized_results=*/false,
266 GetHostRestricts().c_str(), count_to_fetch_)); 298 /*user_segment=*/std::string(),
299 GetHostRestricts(), count_to_fetch_));
267 } 300 }
268 301
269 void NTPSnippetsFetcher::FetchSnippetsAuthenticated( 302 void NTPSnippetsFetcher::FetchSnippetsAuthenticated(
270 const std::string& account_id, 303 const std::string& account_id,
271 const std::string& oauth_access_token) { 304 const std::string& oauth_access_token) {
272 std::string auth = base::StringPrintf(kGaiaIdFormat, account_id.c_str()); 305 std::string gaia_id = base::StringPrintf(kGaiaIdFormat, account_id.c_str());
273 std::string user_segment = 306 std::string user_segment =
274 base::StringPrintf(kUserSegmentFormat, locale_.c_str()); 307 base::StringPrintf(kUserSegmentFormat, locale_.c_str());
275 308
276 FetchSnippetsImpl( 309 FetchSnippetsImpl(
277 GURL(kSnippetsServer), 310 GURL(kSnippetsServer),
278 base::StringPrintf(kAuthorizationRequestHeaderFormat, 311 base::StringPrintf(kAuthorizationRequestHeaderFormat,
279 oauth_access_token.c_str()), 312 oauth_access_token.c_str()),
280 base::StringPrintf(kRequestParameterFormat, auth.c_str(), 313 BuildRequest(gaia_id, personalization_ == Personalization::kPersonal,
281 user_segment.c_str(), GetHostRestricts().c_str(), 314 user_segment, GetHostRestricts(), count_to_fetch_));
282 count_to_fetch_));
283 } 315 }
284 316
285 void NTPSnippetsFetcher::StartTokenRequest() { 317 void NTPSnippetsFetcher::StartTokenRequest() {
286 OAuth2TokenService::ScopeSet scopes; 318 OAuth2TokenService::ScopeSet scopes;
287 scopes.insert(kApiScope); 319 scopes.insert(kApiScope);
288 oauth_request_ = token_service_->StartRequest( 320 oauth_request_ = token_service_->StartRequest(
289 signin_manager_->GetAuthenticatedAccountId(), scopes, this); 321 signin_manager_->GetAuthenticatedAccountId(), scopes, this);
290 } 322 }
291 323
292 //////////////////////////////////////////////////////////////////////////////// 324 ////////////////////////////////////////////////////////////////////////////////
(...skipping 10 matching lines...) Expand all
303 335
304 FetchSnippetsAuthenticated(oauth_request->GetAccountId(), access_token); 336 FetchSnippetsAuthenticated(oauth_request->GetAccountId(), access_token);
305 } 337 }
306 338
307 void NTPSnippetsFetcher::OnGetTokenFailure( 339 void NTPSnippetsFetcher::OnGetTokenFailure(
308 const OAuth2TokenService::Request* request, 340 const OAuth2TokenService::Request* request,
309 const GoogleServiceAuthError& error) { 341 const GoogleServiceAuthError& error) {
310 oauth_request_.reset(); 342 oauth_request_.reset();
311 DLOG(ERROR) << "Unable to get token: " << error.ToString() 343 DLOG(ERROR) << "Unable to get token: " << error.ToString()
312 << " - fetching the snippets without authentication."; 344 << " - fetching the snippets without authentication.";
313 345 FetchFinished(
314 // Fallback to fetching non-authenticated tokens. 346 OptionalSnippets(), FetchResult::OAUTH_TOKEN_ERROR,
315 FetchSnippetsNonAuthenticated(); 347 /*extra_message=*/base::StringPrintf(" (%s)", error.ToString().c_str()));
316 } 348 }
317 349
318 //////////////////////////////////////////////////////////////////////////////// 350 ////////////////////////////////////////////////////////////////////////////////
319 // OAuth2TokenService::Observer overrides 351 // OAuth2TokenService::Observer overrides
320 void NTPSnippetsFetcher::OnRefreshTokenAvailable( 352 void NTPSnippetsFetcher::OnRefreshTokenAvailable(
321 const std::string& account_id) { 353 const std::string& account_id) {
322 // Only react on tokens for the account the user has signed in with. 354 // Only react on tokens for the account the user has signed in with.
323 if (account_id != signin_manager_->GetAuthenticatedAccountId()) 355 if (account_id != signin_manager_->GetAuthenticatedAccountId())
324 return; 356 return;
325 357
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 tick_clock_->NowTicks() - fetch_start_time_); 432 tick_clock_->NowTicks() - fetch_start_time_);
401 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.FetchResult", 433 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.FetchResult",
402 static_cast<int>(result), 434 static_cast<int>(result),
403 static_cast<int>(FetchResult::RESULT_MAX)); 435 static_cast<int>(FetchResult::RESULT_MAX));
404 436
405 if (!snippets_available_callback_.is_null()) 437 if (!snippets_available_callback_.is_null())
406 snippets_available_callback_.Run(std::move(snippets)); 438 snippets_available_callback_.Run(std::move(snippets));
407 } 439 }
408 440
409 } // namespace ntp_snippets 441 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698