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

Side by Side Diff: components/translate/core/browser/translate_manager.cc

Issue 2200493002: using ulp to improve TranslateManager GetTargetLanguage() and InitiateTranslation() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add unit tests Created 4 years, 4 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/translate/core/browser/translate_manager.h" 5 #include "components/translate/core/browser/translate_manager.h"
6 6
7 #include <map>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/command_line.h" 10 #include "base/command_line.h"
9 #include "base/metrics/field_trial.h" 11 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
12 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
13 #include "base/time/time.h" 16 #include "base/time/time.h"
14 #include "components/prefs/pref_service.h" 17 #include "components/prefs/pref_service.h"
15 #include "components/translate/core/browser/language_state.h" 18 #include "components/translate/core/browser/language_state.h"
16 #include "components/translate/core/browser/page_translated_details.h" 19 #include "components/translate/core/browser/page_translated_details.h"
17 #include "components/translate/core/browser/translate_accept_languages.h" 20 #include "components/translate/core/browser/translate_accept_languages.h"
18 #include "components/translate/core/browser/translate_browser_metrics.h" 21 #include "components/translate/core/browser/translate_browser_metrics.h"
19 #include "components/translate/core/browser/translate_client.h" 22 #include "components/translate/core/browser/translate_client.h"
20 #include "components/translate/core/browser/translate_download_manager.h" 23 #include "components/translate/core/browser/translate_download_manager.h"
21 #include "components/translate/core/browser/translate_driver.h" 24 #include "components/translate/core/browser/translate_driver.h"
22 #include "components/translate/core/browser/translate_error_details.h" 25 #include "components/translate/core/browser/translate_error_details.h"
23 #include "components/translate/core/browser/translate_experiment.h" 26 #include "components/translate/core/browser/translate_experiment.h"
24 #include "components/translate/core/browser/translate_language_list.h" 27 #include "components/translate/core/browser/translate_language_list.h"
25 #include "components/translate/core/browser/translate_prefs.h" 28 #include "components/translate/core/browser/translate_prefs.h"
26 #include "components/translate/core/browser/translate_script.h" 29 #include "components/translate/core/browser/translate_script.h"
27 #include "components/translate/core/browser/translate_url_util.h" 30 #include "components/translate/core/browser/translate_url_util.h"
28 #include "components/translate/core/common/language_detection_details.h" 31 #include "components/translate/core/common/language_detection_details.h"
29 #include "components/translate/core/common/translate_constants.h" 32 #include "components/translate/core/common/translate_constants.h"
30 #include "components/translate/core/common/translate_pref_names.h" 33 #include "components/translate/core/common/translate_pref_names.h"
31 #include "components/translate/core/common/translate_switches.h" 34 #include "components/translate/core/common/translate_switches.h"
32 #include "components/translate/core/common/translate_util.h" 35 #include "components/translate/core/common/translate_util.h"
36 #include "components/variations/variations_associated_data.h"
33 #include "google_apis/google_api_keys.h" 37 #include "google_apis/google_api_keys.h"
34 #include "net/base/network_change_notifier.h" 38 #include "net/base/network_change_notifier.h"
35 #include "net/base/url_util.h" 39 #include "net/base/url_util.h"
36 #include "net/http/http_status_code.h" 40 #include "net/http/http_status_code.h"
37 41
38 namespace translate { 42 namespace translate {
39 43
44 const base::Feature kTranslateLanguageByULP{"TranslateLanguageByULP",
45 base::FEATURE_DISABLED_BY_DEFAULT};
40 namespace { 46 namespace {
41 47
42 // Callbacks for translate errors. 48 // Callbacks for translate errors.
43 TranslateManager::TranslateErrorCallbackList* g_callback_list_ = NULL; 49 TranslateManager::TranslateErrorCallbackList* g_callback_list_ = NULL;
44 50
45 const char kReportLanguageDetectionErrorURL[] = 51 const char kReportLanguageDetectionErrorURL[] =
46 "https://translate.google.com/translate_error?client=cr&action=langidc"; 52 "https://translate.google.com/translate_error?client=cr&action=langidc";
47 53
48 // Used in kReportLanguageDetectionErrorURL to specify the original page 54 // Used in kReportLanguageDetectionErrorURL to specify the original page
49 // language. 55 // language.
50 const char kSourceLanguageQueryName[] = "sl"; 56 const char kSourceLanguageQueryName[] = "sl";
51 57
52 // Used in kReportLanguageDetectionErrorURL to specify the page URL. 58 // Used in kReportLanguageDetectionErrorURL to specify the page URL.
53 const char kUrlQueryName[] = "u"; 59 const char kUrlQueryName[] = "u";
54 60
61 // Used for ULP in GetTargetLanguage and InitiateTranslation
62 const char kTranslateLanguageByULPTrialName[] = "TranslateLanguageByULP";
groby-ooo-7-16 2016/08/02 00:38:20 Don't need the trial name - just use GetVariationP
ftang 2016/08/03 02:01:18 Done.
63 const char kTargetLanguageReadingConfidenceThreshold[] =
64 "target_language_reading_confidence_threshold";
65 const char kTargetLanguageReadingProbabilityThreshold[] =
66 "target_language_reading_probability_threshold";
67 const char kInitiateTranslationReadingConfidenceThreshold[] =
groby-ooo-7-16 2016/08/02 00:38:20 I'm not sure what this threshold (and the followin
ftang 2016/08/03 02:01:17 Done.
68 "initiate_translation_reading_confidence_threshold";
69 const char kInitiateTranslationReadingProbabilityThreshold[] =
70 "initiate_translation_reading_probability_threshold";
71 const char kInitiateTranslationWritingConfidenceThreshold[] =
72 "initiate_translation_writing_confidence_threshold";
73 const char kInitiateTranslationWritingProbabilityThreshold[] =
74 "initiate_translation_writing_probability_threshold";
75
76 bool InListAboveThreshold(const std::string language_code,
groby-ooo-7-16 2016/08/02 00:38:20 That combines logic and retrieval - how about just
ftang 2016/08/03 02:01:17 Done.
77 const TranslatePrefs::LanguageProbabilityList& list,
78 double threshold) {
79 for (auto it = list.begin(); it != list.end(); ++it) {
80 // We only consider the language if the probability > the thresold.
groby-ooo-7-16 2016/08/02 00:38:20 c++11 loop iteration, please for(const auto&
ftang 2016/08/03 02:01:17 Done.
81 if (it->second > threshold &&
82 language_code == TranslateDownloadManager::GetLanguageCode(it->first)) {
83 return true;
84 }
85 }
86 return false;
87 }
88
55 } // namespace 89 } // namespace
56 90
57 TranslateManager::~TranslateManager() {} 91 TranslateManager::~TranslateManager() {}
58 92
59 // static 93 // static
60 std::unique_ptr<TranslateManager::TranslateErrorCallbackList::Subscription> 94 std::unique_ptr<TranslateManager::TranslateErrorCallbackList::Subscription>
61 TranslateManager::RegisterTranslateErrorCallback( 95 TranslateManager::RegisterTranslateErrorCallback(
62 const TranslateManager::TranslateErrorCallback& callback) { 96 const TranslateManager::TranslateErrorCallback& callback) {
63 if (!g_callback_list_) 97 if (!g_callback_list_)
64 g_callback_list_ = new TranslateErrorCallbackList; 98 g_callback_list_ = new TranslateErrorCallbackList;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 TranslateBrowserMetrics::ReportInitiationStatus( 216 TranslateBrowserMetrics::ReportInitiationStatus(
183 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG); 217 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG);
184 return; 218 return;
185 } 219 }
186 220
187 // If the user has previously selected "always translate" for this language we 221 // If the user has previously selected "always translate" for this language we
188 // automatically translate. Note that in incognito mode we disable that 222 // automatically translate. Note that in incognito mode we disable that
189 // feature; the user will get an infobar, so they can control whether the 223 // feature; the user will get an infobar, so they can control whether the
190 // page's text is sent to the translate server. 224 // page's text is sent to the translate server.
191 if (!translate_driver_->IsOffTheRecord()) { 225 if (!translate_driver_->IsOffTheRecord()) {
192 std::unique_ptr<TranslatePrefs> translate_prefs =
193 translate_client_->GetTranslatePrefs();
194 std::string auto_target_lang = 226 std::string auto_target_lang =
195 GetAutoTargetLanguage(language_code, translate_prefs.get()); 227 GetAutoTargetLanguage(language_code, translate_prefs.get());
196 if (!auto_target_lang.empty()) { 228 if (!auto_target_lang.empty()) {
197 TranslateBrowserMetrics::ReportInitiationStatus( 229 TranslateBrowserMetrics::ReportInitiationStatus(
198 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG); 230 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG);
199 TranslatePage(language_code, auto_target_lang, false); 231 TranslatePage(language_code, auto_target_lang, false);
200 return; 232 return;
201 } 233 }
202 } 234 }
203 235
204 std::string auto_translate_to = language_state_.AutoTranslateTo(); 236 std::string auto_translate_to = language_state_.AutoTranslateTo();
205 if (!auto_translate_to.empty()) { 237 if (!auto_translate_to.empty()) {
206 // This page was navigated through a click from a translated page. 238 // This page was navigated through a click from a translated page.
207 TranslateBrowserMetrics::ReportInitiationStatus( 239 TranslateBrowserMetrics::ReportInitiationStatus(
208 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK); 240 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK);
209 TranslatePage(language_code, auto_translate_to, false); 241 TranslatePage(language_code, auto_translate_to, false);
210 return; 242 return;
211 } 243 }
212 244
245 if (LanguageInULP(translate_prefs.get(), language_code)) {
246 TranslateBrowserMetrics::ReportInitiationStatus(
247 TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IN_ULP);
248 return;
249 }
250
213 TranslateBrowserMetrics::ReportInitiationStatus( 251 TranslateBrowserMetrics::ReportInitiationStatus(
214 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); 252 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR);
215 253
216 // Prompts the user if they want the page translated. 254 // Prompts the user if they want the page translated.
217 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, 255 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE,
218 language_code, 256 language_code,
219 target_lang, 257 target_lang,
220 TranslateErrors::NONE, 258 TranslateErrors::NONE,
221 false); 259 false);
222 } 260 }
223 261
262 bool TranslateManager::LanguageInULP(const TranslatePrefs* translate_prefs,
263 const std::string& language) const {
264 if (base::FeatureList::IsEnabled(kTranslateLanguageByULP)) {
265 std::map<std::string, std::string> params;
266 variations::GetVariationParams(translate::kTranslateLanguageByULPTrialName,
267 &params);
268 double temp;
269 double reading_confidence_threshold =
270 base::StringToDouble(
groby-ooo-7-16 2016/08/02 00:38:20 Probably worth factoring out to make this a bit mo
ftang 2016/08/03 02:01:17 Done.
271 params[kInitiateTranslationReadingConfidenceThreshold], &temp)
272 ? temp
273 : 0.75;
274 double reading_probability_threshold =
275 base::StringToDouble(
276 params[kInitiateTranslationReadingProbabilityThreshold], &temp)
277 ? temp
278 : 0.5;
279 double writing_confidence_threshold =
280 base::StringToDouble(
281 params[kInitiateTranslationWritingConfidenceThreshold], &temp)
282 ? temp
283 : 0.8;
284 double writing_probability_threshold =
285 base::StringToDouble(
286 params[kInitiateTranslationWritingProbabilityThreshold], &temp)
287 ? temp
288 : 0.3;
289
290 TranslatePrefs::LanguageProbabilityList writing;
291 TranslatePrefs::LanguageProbabilityList reading;
groby-ooo-7-16 2016/08/02 00:38:20 It seems odd we get this data piece by piece, and
ftang 2016/08/03 02:01:17 Made some changes, not sure it fit what you ask fo
292 return (translate_prefs->GetWritingFromUserLanguageProfile(&writing) >
293 writing_confidence_threshold &&
294 InListAboveThreshold(language, writing,
295 writing_probability_threshold)) ||
296 (translate_prefs->GetReadingFromUserLanguageProfile(&reading) >
297 reading_confidence_threshold &&
298 InListAboveThreshold(language, reading,
299 reading_probability_threshold));
300 }
301 return false;
302 }
303
224 void TranslateManager::TranslatePage(const std::string& original_source_lang, 304 void TranslateManager::TranslatePage(const std::string& original_source_lang,
225 const std::string& target_lang, 305 const std::string& target_lang,
226 bool triggered_from_menu) { 306 bool triggered_from_menu) {
227 if (!translate_driver_->HasCurrentPage()) { 307 if (!translate_driver_->HasCurrentPage()) {
228 NOTREACHED(); 308 NOTREACHED();
229 return; 309 return;
230 } 310 }
231 311
232 // Translation can be kicked by context menu against unsupported languages. 312 // Translation can be kicked by context menu against unsupported languages.
233 // Unsupported language strings should be replaced with 313 // Unsupported language strings should be replaced with
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 source_lang, 428 source_lang,
349 target_lang, 429 target_lang,
350 TranslateErrors::NETWORK, 430 TranslateErrors::NETWORK,
351 false); 431 false);
352 NotifyTranslateError(TranslateErrors::NETWORK); 432 NotifyTranslateError(TranslateErrors::NETWORK);
353 } 433 }
354 } 434 }
355 435
356 // static 436 // static
357 std::string TranslateManager::GetTargetLanguage(const TranslatePrefs* prefs) { 437 std::string TranslateManager::GetTargetLanguage(const TranslatePrefs* prefs) {
358 std::string ui_lang = TranslateDownloadManager::GetLanguageCode( 438 std::string language = TranslateDownloadManager::GetLanguageCode(
groby-ooo-7-16 2016/08/02 00:38:20 Please keep a comment that this is the user's UI l
ftang 2016/08/03 02:01:17 Done.
359 TranslateDownloadManager::GetInstance()->application_locale()); 439 TranslateDownloadManager::GetInstance()->application_locale());
360 translate::ToTranslateLanguageSynonym(&ui_lang);
361 440
362 TranslateExperiment::OverrideUiLanguage(prefs->GetCountry(), &ui_lang); 441 std::string ulp_language = TranslateManager::GetTargetLanguageFromULP(prefs);
442 if (!ulp_language.empty())
443 language = ulp_language;
363 444
364 if (TranslateDownloadManager::IsSupportedLanguage(ui_lang)) 445 translate::ToTranslateLanguageSynonym(&language);
groby-ooo-7-16 2016/08/02 00:38:20 I'm not happy we duplicate this here and in GetTar
ftang 2016/08/03 02:01:17 Done.
365 return ui_lang; 446
447 TranslateExperiment::OverrideUiLanguage(prefs->GetCountry(), &language);
groby-ooo-7-16 2016/08/02 00:38:20 Are you sure you want to do this after ULP? This t
ftang 2016/08/03 02:01:18 Done.
448
449 if (TranslateDownloadManager::IsSupportedLanguage(language))
450 return language;
366 451
367 // Will translate to the first supported language on the Accepted Language 452 // Will translate to the first supported language on the Accepted Language
368 // list or not at all if no such candidate exists. 453 // list or not at all if no such candidate exists.
369 std::vector<std::string> accept_languages_list; 454 std::vector<std::string> accept_languages_list;
370 prefs->GetLanguageList(&accept_languages_list); 455 prefs->GetLanguageList(&accept_languages_list);
371 for (const auto& lang : accept_languages_list) { 456 for (const auto& lang : accept_languages_list) {
372 std::string lang_code = TranslateDownloadManager::GetLanguageCode(lang); 457 std::string lang_code = TranslateDownloadManager::GetLanguageCode(lang);
373 if (TranslateDownloadManager::IsSupportedLanguage(lang_code)) 458 if (TranslateDownloadManager::IsSupportedLanguage(lang_code))
374 return lang_code; 459 return lang_code;
375 } 460 }
376 return std::string(); 461 return std::string();
377 } 462 }
378 463
379 // static 464 // static
465 std::string TranslateManager::GetTargetLanguageFromULP(
466 const TranslatePrefs* prefs) {
467 if (base::FeatureList::IsEnabled(kTranslateLanguageByULP)) {
468 std::map<std::string, std::string> params;
469 variations::GetVariationParams(translate::kTranslateLanguageByULPTrialName,
470 &params);
471 double temp;
472 double reading_confidence_threshold =
groby-ooo-7-16 2016/08/02 00:38:20 We have default values duplicated across two funct
ftang 2016/08/03 02:01:17 no they are not. We are not reuse threhold in thes
groby-ooo-7-16 2016/08/04 02:33:42 I'm absolutely on board with configuring via Finch
473 base::StringToDouble(params[kTargetLanguageReadingConfidenceThreshold],
474 &temp)
475 ? temp
476 : 0.75;
477 double reading_probability_threshold =
478 base::StringToDouble(params[kTargetLanguageReadingProbabilityThreshold],
479 &temp)
480 ? temp
481 : 0.5;
482 TranslatePrefs::LanguageProbabilityList reading;
483 // We only consider ULP if the confidence is greater than the threshold.
484 if (prefs->GetReadingFromUserLanguageProfile(&reading) >
485 reading_confidence_threshold) {
486 for (auto it = reading.begin(); it != reading.end(); ++it) {
groby-ooo-7-16 2016/08/02 00:38:20 We do a lot of "iterate and compare language code"
groby-ooo-7-16 2016/08/02 00:38:20 C++11 style loop, please.
ftang 2016/08/03 02:01:17 I think about that, but then we will lost the "ord
ftang 2016/08/03 02:01:17 Done.
487 // We only consider the language if the probability > the thresold.
488 if (it->second > reading_probability_threshold) {
489 std::string ulp_language = it->first;
490 translate::ToTranslateLanguageSynonym(&ulp_language);
groby-ooo-7-16 2016/08/02 00:38:20 It seems we _always_ treat ulp languages as Transl
ftang 2016/08/03 02:01:17 Done in the TranslatePrefs now.
491 // Also the language to be supported by Translate.
groby-ooo-7-16 2016/08/02 00:38:20 s/to be/is/
ftang 2016/08/03 02:01:17 Acknowledged.
492 if (TranslateDownloadManager::IsSupportedLanguage(ulp_language)) {
493 return ulp_language;
494 }
groby-ooo-7-16 2016/08/02 00:38:20 In general, this is very deeply nested. I'd prefer
495 }
496 }
497 }
498 }
499 return std::string();
500 }
501
502 // static
380 std::string TranslateManager::GetAutoTargetLanguage( 503 std::string TranslateManager::GetAutoTargetLanguage(
381 const std::string& original_language, 504 const std::string& original_language,
382 TranslatePrefs* translate_prefs) { 505 TranslatePrefs* translate_prefs) {
383 std::string auto_target_lang; 506 std::string auto_target_lang;
384 if (translate_prefs->ShouldAutoTranslate(original_language, 507 if (translate_prefs->ShouldAutoTranslate(original_language,
385 &auto_target_lang)) { 508 &auto_target_lang)) {
386 // We need to confirm that the saved target language is still supported. 509 // We need to confirm that the saved target language is still supported.
387 // Also, GetLanguageCode will take care of removing country code if any. 510 // Also, GetLanguageCode will take care of removing country code if any.
388 auto_target_lang = 511 auto_target_lang =
389 TranslateDownloadManager::GetLanguageCode(auto_target_lang); 512 TranslateDownloadManager::GetLanguageCode(auto_target_lang);
390 if (TranslateDownloadManager::IsSupportedLanguage(auto_target_lang)) 513 if (TranslateDownloadManager::IsSupportedLanguage(auto_target_lang))
391 return auto_target_lang; 514 return auto_target_lang;
392 } 515 }
393 return std::string(); 516 return std::string();
394 } 517 }
395 518
396 LanguageState& TranslateManager::GetLanguageState() { 519 LanguageState& TranslateManager::GetLanguageState() {
397 return language_state_; 520 return language_state_;
398 } 521 }
399 522
400 bool TranslateManager::ignore_missing_key_for_testing_ = false; 523 bool TranslateManager::ignore_missing_key_for_testing_ = false;
401 524
402 // static 525 // static
403 void TranslateManager::SetIgnoreMissingKeyForTesting(bool ignore) { 526 void TranslateManager::SetIgnoreMissingKeyForTesting(bool ignore) {
404 ignore_missing_key_for_testing_ = ignore; 527 ignore_missing_key_for_testing_ = ignore;
405 } 528 }
406 529
407 } // namespace translate 530 } // namespace translate
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698