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

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

Issue 2400133002: Sending LanguageModel info to suggestions server (Closed)
Patch Set: Small fixes Created 4 years, 2 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/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"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/json/json_writer.h" 12 #include "base/json/json_writer.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/metrics/sparse_histogram.h" 15 #include "base/metrics/sparse_histogram.h"
16 #include "base/path_service.h" 16 #include "base/path_service.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
21 #include "base/time/default_tick_clock.h" 21 #include "base/time/default_tick_clock.h"
22 #include "base/values.h" 22 #include "base/values.h"
23 #include "components/data_use_measurement/core/data_use_user_data.h" 23 #include "components/data_use_measurement/core/data_use_user_data.h"
24 #include "components/ntp_snippets/category_factory.h" 24 #include "components/ntp_snippets/category_factory.h"
25 #include "components/ntp_snippets/ntp_snippets_constants.h" 25 #include "components/ntp_snippets/ntp_snippets_constants.h"
26 #include "components/signin/core/browser/profile_oauth2_token_service.h" 26 #include "components/signin/core/browser/profile_oauth2_token_service.h"
27 #include "components/signin/core/browser/signin_manager.h" 27 #include "components/signin/core/browser/signin_manager.h"
28 #include "components/signin/core/browser/signin_manager_base.h" 28 #include "components/signin/core/browser/signin_manager_base.h"
29 #include "components/translate/core/browser/language_model.h"
29 #include "components/variations/net/variations_http_headers.h" 30 #include "components/variations/net/variations_http_headers.h"
30 #include "components/variations/variations_associated_data.h" 31 #include "components/variations/variations_associated_data.h"
31 #include "net/base/load_flags.h" 32 #include "net/base/load_flags.h"
32 #include "net/http/http_request_headers.h" 33 #include "net/http/http_request_headers.h"
33 #include "net/http/http_response_headers.h" 34 #include "net/http/http_response_headers.h"
34 #include "net/http/http_status_code.h" 35 #include "net/http/http_status_code.h"
35 #include "net/url_request/url_fetcher.h" 36 #include "net/url_request/url_fetcher.h"
36 #include "third_party/icu/source/common/unicode/uloc.h" 37 #include "third_party/icu/source/common/unicode/uloc.h"
37 #include "third_party/icu/source/common/unicode/utypes.h" 38 #include "third_party/icu/source/common/unicode/utypes.h"
38 39
39 using net::URLFetcher; 40 using net::URLFetcher;
40 using net::URLRequestContextGetter; 41 using net::URLRequestContextGetter;
41 using net::HttpRequestHeaders; 42 using net::HttpRequestHeaders;
42 using net::URLRequestStatus; 43 using net::URLRequestStatus;
44 using translate::LanguageModel;
43 45
44 namespace ntp_snippets { 46 namespace ntp_snippets {
45 47
46 namespace { 48 namespace {
47 49
48 const char kChromeReaderApiScope[] = 50 const char kChromeReaderApiScope[] =
49 "https://www.googleapis.com/auth/webhistory"; 51 "https://www.googleapis.com/auth/webhistory";
50 const char kContentSuggestionsApiScope[] = 52 const char kContentSuggestionsApiScope[] =
51 "https://www.googleapis.com/auth/chrome-content-suggestions"; 53 "https://www.googleapis.com/auth/chrome-content-suggestions";
52 const char kSnippetsServerNonAuthorizedFormat[] = "%s?key=%s"; 54 const char kSnippetsServerNonAuthorizedFormat[] = "%s?key=%s";
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 char locale[ULOC_FULLNAME_CAPACITY]; 161 char locale[ULOC_FULLNAME_CAPACITY];
160 UErrorCode error = U_ZERO_ERROR; 162 UErrorCode error = U_ZERO_ERROR;
161 // Translate the input to a posix locale. 163 // Translate the input to a posix locale.
162 uloc_forLanguageTag(language_code.c_str(), locale, ULOC_FULLNAME_CAPACITY, 164 uloc_forLanguageTag(language_code.c_str(), locale, ULOC_FULLNAME_CAPACITY,
163 nullptr, &error); 165 nullptr, &error);
164 DLOG_IF(WARNING, U_ZERO_ERROR != error) 166 DLOG_IF(WARNING, U_ZERO_ERROR != error)
165 << "Error in translating language code to a locale string: " << error; 167 << "Error in translating language code to a locale string: " << error;
166 return locale; 168 return locale;
167 } 169 }
168 170
171 std::string ISO639FromPosixLocale(const std::string& locale) {
172 char language[ULOC_LANG_CAPACITY];
Bernhard Bauer 2016/10/07 12:26:13 This is not going to be zero-initialized, right? S
jkrcal 2016/10/07 12:58:43 Good point! This applies to the function above as
173 UErrorCode error = U_ZERO_ERROR;
174 uloc_getLanguage(locale.c_str(), language, ULOC_LANG_CAPACITY, &error);
Bernhard Bauer 2016/10/07 12:26:13 #include "third_party/icu/source/common/unicode/ul
jkrcal 2016/10/07 12:58:43 It is already there, isn't it? ;)
175 DLOG_IF(WARNING, U_ZERO_ERROR != error)
Bernhard Bauer 2016/10/07 12:26:13 Write the condition the natural way around? A mode
jkrcal 2016/10/07 12:58:43 Done.
176 << "Error in translating locale string to a ISO639 language code: "
177 << error;
178 return language;
179 }
180
169 } // namespace 181 } // namespace
170 182
171 NTPSnippetsFetcher::FetchedCategory::FetchedCategory(Category c) 183 NTPSnippetsFetcher::FetchedCategory::FetchedCategory(Category c)
172 : category(c) {} 184 : category(c) {}
173 185
174 NTPSnippetsFetcher::FetchedCategory::FetchedCategory(FetchedCategory&&) = 186 NTPSnippetsFetcher::FetchedCategory::FetchedCategory(FetchedCategory&&) =
175 default; 187 default;
176 NTPSnippetsFetcher::FetchedCategory::~FetchedCategory() = default; 188 NTPSnippetsFetcher::FetchedCategory::~FetchedCategory() = default;
177 NTPSnippetsFetcher::FetchedCategory& NTPSnippetsFetcher::FetchedCategory:: 189 NTPSnippetsFetcher::FetchedCategory& NTPSnippetsFetcher::FetchedCategory::
178 operator=(FetchedCategory&&) = default; 190 operator=(FetchedCategory&&) = default;
179 191
180 NTPSnippetsFetcher::NTPSnippetsFetcher( 192 NTPSnippetsFetcher::NTPSnippetsFetcher(
181 SigninManagerBase* signin_manager, 193 SigninManagerBase* signin_manager,
182 OAuth2TokenService* token_service, 194 OAuth2TokenService* token_service,
183 scoped_refptr<URLRequestContextGetter> url_request_context_getter, 195 scoped_refptr<URLRequestContextGetter> url_request_context_getter,
184 PrefService* pref_service, 196 PrefService* pref_service,
185 CategoryFactory* category_factory, 197 CategoryFactory* category_factory,
198 LanguageModel* language_model,
186 const ParseJSONCallback& parse_json_callback, 199 const ParseJSONCallback& parse_json_callback,
187 const std::string& api_key) 200 const std::string& api_key)
188 : OAuth2TokenService::Consumer("ntp_snippets"), 201 : OAuth2TokenService::Consumer("ntp_snippets"),
189 signin_manager_(signin_manager), 202 signin_manager_(signin_manager),
190 token_service_(token_service), 203 token_service_(token_service),
191 waiting_for_refresh_token_(false), 204 waiting_for_refresh_token_(false),
192 url_request_context_getter_(std::move(url_request_context_getter)), 205 url_request_context_getter_(std::move(url_request_context_getter)),
193 category_factory_(category_factory), 206 category_factory_(category_factory),
207 language_model_(language_model),
194 parse_json_callback_(parse_json_callback), 208 parse_json_callback_(parse_json_callback),
195 count_to_fetch_(0), 209 count_to_fetch_(0),
196 fetch_url_(GetFetchEndpoint()), 210 fetch_url_(GetFetchEndpoint()),
197 fetch_api_(UsesChromeContentSuggestionsAPI(fetch_url_) 211 fetch_api_(UsesChromeContentSuggestionsAPI(fetch_url_)
198 ? CHROME_CONTENT_SUGGESTIONS_API 212 ? CHROME_CONTENT_SUGGESTIONS_API
199 : CHROME_READER_API), 213 : CHROME_READER_API),
200 api_key_(api_key), 214 api_key_(api_key),
201 interactive_request_(false), 215 interactive_request_(false),
202 tick_clock_(new base::DefaultTickClock()), 216 tick_clock_(new base::DefaultTickClock()),
203 request_throttler_( 217 request_throttler_(
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 // Wait until we get a refresh token. 281 // Wait until we get a refresh token.
268 waiting_for_refresh_token_ = true; 282 waiting_for_refresh_token_ = true;
269 token_service_->AddObserver(this); 283 token_service_->AddObserver(this);
270 } 284 }
271 } else { 285 } else {
272 // Not signed in: fetch snippets (without authentication). 286 // Not signed in: fetch snippets (without authentication).
273 FetchSnippetsNonAuthenticated(); 287 FetchSnippetsNonAuthenticated();
274 } 288 }
275 } 289 }
276 290
291 NTPSnippetsFetcher::ContentLanguageInfo::ContentLanguageInfo()
292 : language_code(), frequency(0) {}
293
294 void NTPSnippetsFetcher::ContentLanguageInfo::AppendToList(
295 base::ListValue* list) {
296 auto lang = base::MakeUnique<base::DictionaryValue>();
297 lang->SetString("language", language_code);
298 lang->SetDouble("frequency", frequency);
299 list->Append(std::move(lang));
300 }
301
277 NTPSnippetsFetcher::RequestParams::RequestParams() 302 NTPSnippetsFetcher::RequestParams::RequestParams()
278 : fetch_api(), 303 : fetch_api(),
279 obfuscated_gaia_id(), 304 obfuscated_gaia_id(),
280 only_return_personalized_results(), 305 only_return_personalized_results(),
281 user_locale(), 306 user_locale(),
282 host_restricts(), 307 host_restricts(),
283 count_to_fetch(), 308 count_to_fetch(),
284 interactive_request() {} 309 interactive_request() {}
285 310
286 NTPSnippetsFetcher::RequestParams::~RequestParams() = default; 311 NTPSnippetsFetcher::RequestParams::~RequestParams() = default;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 : "BACKGROUND_PREFETCH"); 375 : "BACKGROUND_PREFETCH");
351 376
352 auto excluded = base::MakeUnique<base::ListValue>(); 377 auto excluded = base::MakeUnique<base::ListValue>();
353 for (const auto& id : excluded_ids) { 378 for (const auto& id : excluded_ids) {
354 excluded->AppendString(id); 379 excluded->AppendString(id);
355 if (excluded->GetSize() >= kMaxExcludedIds) 380 if (excluded->GetSize() >= kMaxExcludedIds)
356 break; 381 break;
357 } 382 }
358 request->Set("excludedSuggestionIds", std::move(excluded)); 383 request->Set("excludedSuggestionIds", std::move(excluded));
359 384
385 if (ui_language.frequency == 0 && other_top_language.frequency == 0)
386 break;
387
388 auto language_list = base::MakeUnique<base::ListValue>();
389 if (ui_language.frequency > 0)
390 ui_language.AppendToList(language_list.get());
391 if (other_top_language.frequency > 0)
392 other_top_language.AppendToList(language_list.get());
393 request->Set("top_languages", std::move(language_list));
394
360 // TODO(sfiera): support authentication and personalization 395 // TODO(sfiera): support authentication and personalization
361 // TODO(sfiera): support count_to_fetch 396 // TODO(sfiera): support count_to_fetch
362 break; 397 break;
363 } 398 }
364 } 399 }
365 400
366 std::string request_json; 401 std::string request_json;
367 bool success = base::JSONWriter::WriteWithOptions( 402 bool success = base::JSONWriter::WriteWithOptions(
368 *request, base::JSONWriter::OPTIONS_PRETTY_PRINT, &request_json); 403 *request, base::JSONWriter::OPTIONS_PRETTY_PRINT, &request_json);
369 DCHECK(success); 404 DCHECK(success);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 // Try to make fetching the files bit more robust even with poor connection. 437 // Try to make fetching the files bit more robust even with poor connection.
403 url_fetcher_->SetMaxRetriesOn5xx(3); 438 url_fetcher_->SetMaxRetriesOn5xx(3);
404 url_fetcher_->Start(); 439 url_fetcher_->Start();
405 } 440 }
406 441
407 bool NTPSnippetsFetcher::UsesAuthentication() const { 442 bool NTPSnippetsFetcher::UsesAuthentication() const {
408 return (personalization_ == Personalization::kPersonal || 443 return (personalization_ == Personalization::kPersonal ||
409 personalization_ == Personalization::kBoth); 444 personalization_ == Personalization::kBoth);
410 } 445 }
411 446
447 void NTPSnippetsFetcher::SetUpCommonFetchingParameters(
448 RequestParams* params) const {
449 params->fetch_api = fetch_api_;
450 params->host_restricts = hosts_;
451 params->user_locale = locale_;
452 params->excluded_ids = excluded_ids_;
453 params->count_to_fetch = count_to_fetch_;
454 params->interactive_request = interactive_request_;
455
456 // TODO(jkrcal): Add language model factory for iOS and add fakes to tests so
457 // that |language_model_| is never nullptr. Remove this check and add a DCHECK
458 // into the constructor.
459 if (!language_model_)
460 return;
461
462 params->ui_language.language_code = ISO639FromPosixLocale(locale_);
463 params->ui_language.frequency =
464 language_model_->GetLanguageFrequency(params->ui_language.language_code);
465
466 std::vector<LanguageModel::LanguageInfo> top_languages =
467 language_model_->GetTopLanguages();
468 for (const LanguageModel::LanguageInfo& info : top_languages) {
469 if (info.language_code != params->ui_language.language_code) {
470 params->other_top_language.language_code = info.language_code;
471 params->other_top_language.frequency = info.frequency;
472 break;
473 }
474 }
475 }
476
412 void NTPSnippetsFetcher::FetchSnippetsNonAuthenticated() { 477 void NTPSnippetsFetcher::FetchSnippetsNonAuthenticated() {
413 // When not providing OAuth token, we need to pass the Google API key. 478 // When not providing OAuth token, we need to pass the Google API key.
414 GURL url(base::StringPrintf(kSnippetsServerNonAuthorizedFormat, 479 GURL url(base::StringPrintf(kSnippetsServerNonAuthorizedFormat,
415 fetch_url_.spec().c_str(), api_key_.c_str())); 480 fetch_url_.spec().c_str(), api_key_.c_str()));
416 481
417 RequestParams params; 482 RequestParams params;
418 params.fetch_api = fetch_api_; 483 SetUpCommonFetchingParameters(&params);
419 params.host_restricts = hosts_;
420 params.excluded_ids = excluded_ids_;
421 params.count_to_fetch = count_to_fetch_;
422 params.interactive_request = interactive_request_;
423 params.user_locale = locale_;
424 FetchSnippetsImpl(url, std::string(), params.BuildRequest()); 484 FetchSnippetsImpl(url, std::string(), params.BuildRequest());
425 } 485 }
426 486
427 void NTPSnippetsFetcher::FetchSnippetsAuthenticated( 487 void NTPSnippetsFetcher::FetchSnippetsAuthenticated(
428 const std::string& account_id, 488 const std::string& account_id,
429 const std::string& oauth_access_token) { 489 const std::string& oauth_access_token) {
430 RequestParams params; 490 RequestParams params;
431 params.fetch_api = fetch_api_; 491 SetUpCommonFetchingParameters(&params);
432 params.obfuscated_gaia_id = account_id; 492 params.obfuscated_gaia_id = account_id;
433 params.only_return_personalized_results = 493 params.only_return_personalized_results =
434 personalization_ == Personalization::kPersonal; 494 personalization_ == Personalization::kPersonal;
435 params.user_locale = locale_;
436 params.host_restricts = hosts_;
437 params.excluded_ids = excluded_ids_;
438 params.count_to_fetch = count_to_fetch_;
439 params.interactive_request = interactive_request_;
440 // TODO(jkrcal, treib): Add unit-tests for authenticated fetches. 495 // TODO(jkrcal, treib): Add unit-tests for authenticated fetches.
441 FetchSnippetsImpl(fetch_url_, 496 FetchSnippetsImpl(fetch_url_,
442 base::StringPrintf(kAuthorizationRequestHeaderFormat, 497 base::StringPrintf(kAuthorizationRequestHeaderFormat,
443 oauth_access_token.c_str()), 498 oauth_access_token.c_str()),
444 params.BuildRequest()); 499 params.BuildRequest());
445 } 500 }
446 501
447 void NTPSnippetsFetcher::StartTokenRequest() { 502 void NTPSnippetsFetcher::StartTokenRequest() {
448 OAuth2TokenService::ScopeSet scopes; 503 OAuth2TokenService::ScopeSet scopes;
449 scopes.insert(fetch_api_ == CHROME_CONTENT_SUGGESTIONS_API 504 scopes.insert(fetch_api_ == CHROME_CONTENT_SUGGESTIONS_API
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.FetchResult", 686 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.FetchResult",
632 static_cast<int>(result), 687 static_cast<int>(result),
633 static_cast<int>(FetchResult::RESULT_MAX)); 688 static_cast<int>(FetchResult::RESULT_MAX));
634 689
635 DVLOG(1) << "Fetch finished: " << last_status_; 690 DVLOG(1) << "Fetch finished: " << last_status_;
636 if (!snippets_available_callback_.is_null()) 691 if (!snippets_available_callback_.is_null())
637 snippets_available_callback_.Run(std::move(snippets)); 692 snippets_available_callback_.Run(std::move(snippets));
638 } 693 }
639 694
640 } // namespace ntp_snippets 695 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698