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

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 #1 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') | no next file » | 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 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 " \"type\": \"METADATA\"," 75 " \"type\": \"METADATA\","
71 " \"value\": \"TITLE\"" 76 " \"value\": \"TITLE\""
72 " }," 77 " },"
73 " \"content_restricts\": {" 78 " \"content_restricts\": {"
74 " \"type\": \"METADATA\"," 79 " \"type\": \"METADATA\","
75 " \"value\": \"SNIPPET\"" 80 " \"value\": \"SNIPPET\""
76 " }," 81 " },"
(...skipping 10 matching lines...) Expand all
87 " }" 92 " }"
88 "}"; 93 "}";
89 94
90 const char kGaiaIdFormat[] = " \"obfuscated_gaia_id\": \"%s\","; 95 const char kGaiaIdFormat[] = " \"obfuscated_gaia_id\": \"%s\",";
91 const char kUserSegmentFormat[] = " ,\"user_segment\": \"%s\""; 96 const char kUserSegmentFormat[] = " ,\"user_segment\": \"%s\"";
92 const char kHostRestrictFormat[] = 97 const char kHostRestrictFormat[] =
93 " ,\"content_selectors\": {" 98 " ,\"content_selectors\": {"
94 " \"type\": \"HOST_RESTRICT\"," 99 " \"type\": \"HOST_RESTRICT\","
95 " \"value\": \"%s\"" 100 " \"value\": \"%s\""
96 " }"; 101 " }";
102 const char kTrueString[] = "true";
103 const char kFalseString[] = "false";
97 104
98 std::string FetchResultToString(NTPSnippetsFetcher::FetchResult result) { 105 std::string FetchResultToString(NTPSnippetsFetcher::FetchResult result) {
99 switch (result) { 106 switch (result) {
100 case NTPSnippetsFetcher::FetchResult::SUCCESS: 107 case NTPSnippetsFetcher::FetchResult::SUCCESS:
101 return "OK"; 108 return "OK";
102 case NTPSnippetsFetcher::FetchResult::EMPTY_HOSTS: 109 case NTPSnippetsFetcher::FetchResult::EMPTY_HOSTS:
103 return "Cannot fetch for empty hosts list."; 110 return "Cannot fetch for empty hosts list.";
104 case NTPSnippetsFetcher::FetchResult::URL_REQUEST_STATUS_ERROR: 111 case NTPSnippetsFetcher::FetchResult::URL_REQUEST_STATUS_ERROR:
105 return "URLRequestStatus error"; 112 return "URLRequestStatus error";
106 case NTPSnippetsFetcher::FetchResult::HTTP_ERROR: 113 case NTPSnippetsFetcher::FetchResult::HTTP_ERROR:
107 return "HTTP error"; 114 return "HTTP error";
108 case NTPSnippetsFetcher::FetchResult::JSON_PARSE_ERROR: 115 case NTPSnippetsFetcher::FetchResult::JSON_PARSE_ERROR:
109 return "Received invalid JSON"; 116 return "Received invalid JSON";
110 case NTPSnippetsFetcher::FetchResult::INVALID_SNIPPET_CONTENT_ERROR: 117 case NTPSnippetsFetcher::FetchResult::INVALID_SNIPPET_CONTENT_ERROR:
111 return "Invalid / empty list."; 118 return "Invalid / empty list.";
112 case NTPSnippetsFetcher::FetchResult::RESULT_MAX: 119 case NTPSnippetsFetcher::FetchResult::RESULT_MAX:
113 break; 120 break;
114 } 121 }
115 NOTREACHED(); 122 NOTREACHED();
116 return "Unknown error"; 123 return "Unknown error";
117 } 124 }
118 125
126 std::string BuildRequest(const std::string& obfuscated_gaia_id,
127 bool only_return_personalized_results,
128 const std::string& user_segment,
129 const std::string& host_restricts,
130 int count_to_fetch) {
131 return base::StringPrintf(
132 kRequestFormat, obfuscated_gaia_id.c_str(),
133 only_return_personalized_results ? kTrueString : kFalseString,
134 user_segment, host_restricts.c_str(), count_to_fetch);
135 }
136
119 } // namespace 137 } // namespace
120 138
121 NTPSnippetsFetcher::NTPSnippetsFetcher( 139 NTPSnippetsFetcher::NTPSnippetsFetcher(
122 SigninManagerBase* signin_manager, 140 SigninManagerBase* signin_manager,
123 OAuth2TokenService* token_service, 141 OAuth2TokenService* token_service,
124 scoped_refptr<URLRequestContextGetter> url_request_context_getter, 142 scoped_refptr<URLRequestContextGetter> url_request_context_getter,
125 const ParseJSONCallback& parse_json_callback, 143 const ParseJSONCallback& parse_json_callback,
126 bool is_stable_channel) 144 bool is_stable_channel)
127 : OAuth2TokenService::Consumer("ntp_snippets"), 145 : OAuth2TokenService::Consumer("ntp_snippets"),
128 signin_manager_(signin_manager), 146 signin_manager_(signin_manager),
129 token_service_(token_service), 147 token_service_(token_service),
130 waiting_for_refresh_token_(false), 148 waiting_for_refresh_token_(false),
131 url_request_context_getter_(url_request_context_getter), 149 url_request_context_getter_(url_request_context_getter),
132 parse_json_callback_(parse_json_callback), 150 parse_json_callback_(parse_json_callback),
133 is_stable_channel_(is_stable_channel), 151 is_stable_channel_(is_stable_channel),
134 tick_clock_(new base::DefaultTickClock()), 152 tick_clock_(new base::DefaultTickClock()),
135 weak_ptr_factory_(this) { 153 weak_ptr_factory_(this) {
136 // Parse the variation parameters and set the defaults if missing. 154 // Parse the variation parameters and set the defaults if missing.
137 std::string variant = variations::GetVariationParamValue( 155 std::string variant = variations::GetVariationParamValue(
138 ntp_snippets::kStudyName, kVariantName); 156 ntp_snippets::kStudyName, kPersonalizationName);
139 if (variant == kVariantRestrictedString) { 157 if (variant == kPersonalizationNonPersonalString) {
140 variant_ = Variant::kRestricted; 158 personalization_ = Personalization::kNonPersonal;
141 } else if (variant == kVariantPersonalizedString) { 159 } else if (variant == kPersonalizationPersonalString) {
142 variant_ = Variant::kPersonalized; 160 personalization_ = Personalization::kPersonal;
143 } else { 161 } else {
144 variant_ = Variant::kRestrictedPersonalized; 162 personalization_ = Personalization::kBoth;
145 LOG_IF(WARNING, 163 LOG_IF(WARNING, !variant.empty() && variant != kPersonalizationBothString)
146 !variant.empty() && variant != kVariantRestrictedPersonalizedString) 164 << "Unknown value for fetching_variant: " << variant;
Marc Treib 2016/05/12 10:06:15 "fetching_personalization" - just use kPersonaliza
jkrcal 2016/05/12 11:58:56 Done.
147 << "Unknown fetching variant provided: " << variant; 165 }
166
167 std::string host_restriction = variations::GetVariationParamValue(
168 ntp_snippets::kStudyName, kHostRestrictionName);
169 if (host_restriction == kHostRestrictionOffString) {
170 use_host_restriction_ = false;
171 } else {
172 use_host_restriction_ = true;
173 LOG_IF(WARNING, !host_restriction.empty() &&
174 host_restriction != kHostRestrictionOnString)
175 << "Unknown value for fetching_host_restrict: " << host_restriction;
Marc Treib 2016/05/12 10:06:15 Also here: kHostRestrictionName?
jkrcal 2016/05/12 11:58:56 Done.
148 } 176 }
149 } 177 }
150 178
151 NTPSnippetsFetcher::~NTPSnippetsFetcher() { 179 NTPSnippetsFetcher::~NTPSnippetsFetcher() {
152 if (waiting_for_refresh_token_) 180 if (waiting_for_refresh_token_)
153 token_service_->RemoveObserver(this); 181 token_service_->RemoveObserver(this);
154 } 182 }
155 183
156 void NTPSnippetsFetcher::SetCallback( 184 void NTPSnippetsFetcher::SetCallback(
157 const SnippetsAvailableCallback& callback) { 185 const SnippetsAvailableCallback& callback) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 std::string NTPSnippetsFetcher::GetHostRestricts() const { 257 std::string NTPSnippetsFetcher::GetHostRestricts() const {
230 std::string host_restricts; 258 std::string host_restricts;
231 if (UseHostRestriction()) { 259 if (UseHostRestriction()) {
232 for (const std::string& host : hosts_) 260 for (const std::string& host : hosts_)
233 host_restricts += base::StringPrintf(kHostRestrictFormat, host.c_str()); 261 host_restricts += base::StringPrintf(kHostRestrictFormat, host.c_str());
234 } 262 }
235 return host_restricts; 263 return host_restricts;
236 } 264 }
237 265
238 bool NTPSnippetsFetcher::UseHostRestriction() const { 266 bool NTPSnippetsFetcher::UseHostRestriction() const {
239 return (variant_ == Variant::kRestricted || 267 return use_host_restriction_ &&
240 variant_ == Variant::kRestrictedPersonalized) &&
241 !base::CommandLine::ForCurrentProcess()->HasSwitch( 268 !base::CommandLine::ForCurrentProcess()->HasSwitch(
242 switches::kDontRestrict); 269 switches::kDontRestrict);
243 } 270 }
244 271
245 bool NTPSnippetsFetcher::UseAuthentication() const { 272 bool NTPSnippetsFetcher::UseAuthentication() const {
246 return (variant_ == Variant::kPersonalized || 273 return (personalization_ == Personalization::kPersonal ||
247 variant_ == Variant::kRestrictedPersonalized); 274 personalization_ == Personalization::kBoth);
248 } 275 }
249 276
250 void NTPSnippetsFetcher::FetchSnippetsNonAuthenticated() { 277 void NTPSnippetsFetcher::FetchSnippetsNonAuthenticated() {
251 // When not providing OAuth token, we need to pass the Google API key. 278 // When not providing OAuth token, we need to pass the Google API key.
252 const std::string& key = is_stable_channel_ 279 const std::string& key = is_stable_channel_
253 ? google_apis::GetAPIKey() 280 ? google_apis::GetAPIKey()
254 : google_apis::GetNonStableAPIKey(); 281 : google_apis::GetNonStableAPIKey();
255 GURL url(base::StringPrintf(kSnippetsServerNonAuthorizedFormat, 282 GURL url(base::StringPrintf(kSnippetsServerNonAuthorizedFormat,
256 kSnippetsServer, key.c_str())); 283 kSnippetsServer, key.c_str()));
257 284
258 FetchSnippetsImpl( 285 FetchSnippetsImpl(url, std::string(),
259 url, std::string(), 286 BuildRequest(/*obfuscated_gaia_id=*/std::string(),
260 base::StringPrintf(kRequestParameterFormat, "", "", 287 /*only_return_personalized_results=*/false,
261 GetHostRestricts().c_str(), count_to_fetch_)); 288 /*user_segment=*/std::string(),
289 GetHostRestricts(), count_to_fetch_));
262 } 290 }
263 291
264 void NTPSnippetsFetcher::FetchSnippetsAuthenticated( 292 void NTPSnippetsFetcher::FetchSnippetsAuthenticated(
265 const std::string& account_id, 293 const std::string& account_id,
266 const std::string& oauth_access_token) { 294 const std::string& oauth_access_token) {
267 std::string auth = base::StringPrintf(kGaiaIdFormat, account_id.c_str()); 295 std::string gaia_id = base::StringPrintf(kGaiaIdFormat, account_id.c_str());
268 std::string user_segment = 296 std::string user_segment =
269 base::StringPrintf(kUserSegmentFormat, locale_.c_str()); 297 base::StringPrintf(kUserSegmentFormat, locale_.c_str());
270 298
271 FetchSnippetsImpl( 299 FetchSnippetsImpl(
272 GURL(kSnippetsServer), 300 GURL(kSnippetsServer),
273 base::StringPrintf(kAuthorizationRequestHeaderFormat, 301 base::StringPrintf(kAuthorizationRequestHeaderFormat,
274 oauth_access_token.c_str()), 302 oauth_access_token.c_str()),
275 base::StringPrintf(kRequestParameterFormat, auth.c_str(), 303 BuildRequest(gaia_id, personalization_ == Personalization::kPersonal,
276 user_segment.c_str(), GetHostRestricts().c_str(), 304 user_segment, GetHostRestricts(), count_to_fetch_));
277 count_to_fetch_));
278 } 305 }
279 306
280 void NTPSnippetsFetcher::StartTokenRequest() { 307 void NTPSnippetsFetcher::StartTokenRequest() {
281 OAuth2TokenService::ScopeSet scopes; 308 OAuth2TokenService::ScopeSet scopes;
282 scopes.insert(kApiScope); 309 scopes.insert(kApiScope);
283 oauth_request_ = token_service_->StartRequest( 310 oauth_request_ = token_service_->StartRequest(
284 signin_manager_->GetAuthenticatedAccountId(), scopes, this); 311 signin_manager_->GetAuthenticatedAccountId(), scopes, this);
285 } 312 }
286 313
287 //////////////////////////////////////////////////////////////////////////////// 314 ////////////////////////////////////////////////////////////////////////////////
(...skipping 10 matching lines...) Expand all
298 325
299 FetchSnippetsAuthenticated(oauth_request->GetAccountId(), access_token); 326 FetchSnippetsAuthenticated(oauth_request->GetAccountId(), access_token);
300 } 327 }
301 328
302 void NTPSnippetsFetcher::OnGetTokenFailure( 329 void NTPSnippetsFetcher::OnGetTokenFailure(
303 const OAuth2TokenService::Request* request, 330 const OAuth2TokenService::Request* request,
304 const GoogleServiceAuthError& error) { 331 const GoogleServiceAuthError& error) {
305 oauth_request_.reset(); 332 oauth_request_.reset();
306 DLOG(ERROR) << "Unable to get token: " << error.ToString() 333 DLOG(ERROR) << "Unable to get token: " << error.ToString()
307 << " - fetching the snippets without authentication."; 334 << " - fetching the snippets without authentication.";
308
309 // Fallback to fetching non-authenticated tokens.
310 FetchSnippetsNonAuthenticated();
Marc Treib 2016/05/12 10:06:15 If you remove this, you need to call FetchFinished
jkrcal 2016/05/12 11:58:56 Done. Huh, thanks. I was too quick to send it out
311 } 335 }
312 336
313 //////////////////////////////////////////////////////////////////////////////// 337 ////////////////////////////////////////////////////////////////////////////////
314 // OAuth2TokenService::Observer overrides 338 // OAuth2TokenService::Observer overrides
315 void NTPSnippetsFetcher::OnRefreshTokenAvailable( 339 void NTPSnippetsFetcher::OnRefreshTokenAvailable(
316 const std::string& account_id) { 340 const std::string& account_id) {
317 // Only react on tokens for the account the user has signed in with. 341 // Only react on tokens for the account the user has signed in with.
318 if (account_id != signin_manager_->GetAuthenticatedAccountId()) 342 if (account_id != signin_manager_->GetAuthenticatedAccountId())
319 return; 343 return;
320 344
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 tick_clock_->NowTicks() - fetch_start_time_); 419 tick_clock_->NowTicks() - fetch_start_time_);
396 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.FetchResult", 420 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.FetchResult",
397 static_cast<int>(result), 421 static_cast<int>(result),
398 static_cast<int>(FetchResult::RESULT_MAX)); 422 static_cast<int>(FetchResult::RESULT_MAX));
399 423
400 if (!snippets_available_callback_.is_null()) 424 if (!snippets_available_callback_.is_null())
401 snippets_available_callback_.Run(std::move(snippets)); 425 snippets_available_callback_.Run(std::move(snippets));
402 } 426 }
403 427
404 } // namespace ntp_snippets 428 } // namespace ntp_snippets
OLDNEW
« no previous file with comments | « components/ntp_snippets/ntp_snippets_fetcher.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698