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

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

Powered by Google App Engine
This is Rietveld 408576698