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

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: Change based on 8/3 design review and simplified the use of ULP 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 // Name for params in config for considering ULP in GetTargetLanguage().
62 const char kTargetLanguageULPConfidenceThresholdName[] =
63 "target_language_ulp_confidence_threshold";
64 const char kTargetLanguageULPProbabilityThresholdName[] =
65 "target_language_ulp_probability_threshold";
66
67 // Name for params in config for considering ULP in InitiateTranslation().
68 const char kInitiateTranslationULPConfidenceThresholdName[] =
69 "initiate_translation_ulp_confidence_threshold";
70 const char kInitiateTranslationULPProbabilityThresholdName[] =
71 "initiate_translation_ulp_probability_threshold";
72
73 // Constants for considering ULP. These built-in constatants of default will be
74 // override by the value in config params if present.
75 // Default constants for the GetTargetLanguage() function:
76 // The confidence threshold that we will consider to use the ULP
77 // "reading list".
78 const double kDefaultTargetLanguageULPConfidenceThreshold = 0.7;
79 // The probability threshold that we will consider to use a language on
80 // ULP "reading list".
81 const double kDefaultTargetLanguageULPProbabilityThreshold = 0.55;
groby-ooo-7-16 2016/08/04 02:33:42 Can we share the same defaults? Since they can be
ftang 2016/08/05 04:45:27 No, we really cannot use the same threshold. These
82
83 // Default constants for the InitiateTranslation() function:
84 // The confidence threshold that we will consider to use the ULP
85 // "reading list".
86 const double kDefaultInitiateTranslationULPConfidenceThreshold = 0.75;
87 // The probability threshold that we will consider to use a language on
88 // ULP "reading list".
89 const double kDefaultInitiateTranslationULPProbabilityThreshold = 0.5;
90
91 // Return the probability of the |language| in the |list|, or 0.0 if it is not
92 // in
93 // the |list|.
94 double GetLanguageProbability(
95 const TranslatePrefs::LanguageAndProbabilityList& list,
96 const std::string language) {
97 for (const auto& it : list) {
98 if (language == it.first) {
99 return it.second;
100 }
101 }
102 return 0.0;
103 }
104
105 // Get a value from the |map| by |key| and return the converted double, if
106 // failed
107 // return the |default_value| instead.
108 double GetDoubleFromMap(std::map<std::string, std::string>& map,
109 const std::string& key,
110 double default_value) {
111 double value = default_value;
112 return base::StringToDouble(map[key], &value) ? value : default_value;
113 }
114
55 } // namespace 115 } // namespace
56 116
57 TranslateManager::~TranslateManager() {} 117 TranslateManager::~TranslateManager() {}
58 118
59 // static 119 // static
60 std::unique_ptr<TranslateManager::TranslateErrorCallbackList::Subscription> 120 std::unique_ptr<TranslateManager::TranslateErrorCallbackList::Subscription>
61 TranslateManager::RegisterTranslateErrorCallback( 121 TranslateManager::RegisterTranslateErrorCallback(
62 const TranslateManager::TranslateErrorCallback& callback) { 122 const TranslateManager::TranslateErrorCallback& callback) {
63 if (!g_callback_list_) 123 if (!g_callback_list_)
64 g_callback_list_ = new TranslateErrorCallbackList; 124 g_callback_list_ = new TranslateErrorCallbackList;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 TranslateBrowserMetrics::ReportInitiationStatus( 242 TranslateBrowserMetrics::ReportInitiationStatus(
183 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG); 243 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG);
184 return; 244 return;
185 } 245 }
186 246
187 // If the user has previously selected "always translate" for this language we 247 // If the user has previously selected "always translate" for this language we
188 // automatically translate. Note that in incognito mode we disable that 248 // automatically translate. Note that in incognito mode we disable that
189 // feature; the user will get an infobar, so they can control whether the 249 // feature; the user will get an infobar, so they can control whether the
190 // page's text is sent to the translate server. 250 // page's text is sent to the translate server.
191 if (!translate_driver_->IsOffTheRecord()) { 251 if (!translate_driver_->IsOffTheRecord()) {
192 std::unique_ptr<TranslatePrefs> translate_prefs =
193 translate_client_->GetTranslatePrefs();
194 std::string auto_target_lang = 252 std::string auto_target_lang =
195 GetAutoTargetLanguage(language_code, translate_prefs.get()); 253 GetAutoTargetLanguage(language_code, translate_prefs.get());
196 if (!auto_target_lang.empty()) { 254 if (!auto_target_lang.empty()) {
197 TranslateBrowserMetrics::ReportInitiationStatus( 255 TranslateBrowserMetrics::ReportInitiationStatus(
198 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG); 256 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG);
199 TranslatePage(language_code, auto_target_lang, false); 257 TranslatePage(language_code, auto_target_lang, false);
200 return; 258 return;
201 } 259 }
202 } 260 }
203 261
204 std::string auto_translate_to = language_state_.AutoTranslateTo(); 262 std::string auto_translate_to = language_state_.AutoTranslateTo();
205 if (!auto_translate_to.empty()) { 263 if (!auto_translate_to.empty()) {
206 // This page was navigated through a click from a translated page. 264 // This page was navigated through a click from a translated page.
207 TranslateBrowserMetrics::ReportInitiationStatus( 265 TranslateBrowserMetrics::ReportInitiationStatus(
208 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK); 266 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK);
209 TranslatePage(language_code, auto_translate_to, false); 267 TranslatePage(language_code, auto_translate_to, false);
210 return; 268 return;
211 } 269 }
212 270
271 if (LanguageInULP(translate_prefs.get(), language_code)) {
272 TranslateBrowserMetrics::ReportInitiationStatus(
273 TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IN_ULP);
274 return;
275 }
276
213 TranslateBrowserMetrics::ReportInitiationStatus( 277 TranslateBrowserMetrics::ReportInitiationStatus(
214 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); 278 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR);
215 279
216 // Prompts the user if they want the page translated. 280 // Prompts the user if they want the page translated.
217 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, 281 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE,
218 language_code, 282 language_code,
219 target_lang, 283 target_lang,
220 TranslateErrors::NONE, 284 TranslateErrors::NONE,
221 false); 285 false);
222 } 286 }
223 287
288 bool TranslateManager::LanguageInULP(const TranslatePrefs* translate_prefs,
289 const std::string& language) const {
290 if (!base::FeatureList::IsEnabled(kTranslateLanguageByULP))
291 return false;
292 std::map<std::string, std::string> params;
293 variations::GetVariationParamsByFeature(translate::kTranslateLanguageByULP,
294 &params);
295 // Check the language & probability on the reading list.
296 TranslatePrefs::LanguageAndProbabilityList reading;
297 if (translate_prefs->GetReadingFromUserLanguageProfile(&reading) >
298 GetDoubleFromMap(params,
299 kInitiateTranslationULPConfidenceThresholdName,
300 kDefaultInitiateTranslationULPConfidenceThreshold) &&
301 GetLanguageProbability(reading, language) >
302 GetDoubleFromMap(params,
303 kInitiateTranslationULPProbabilityThresholdName,
304 kDefaultInitiateTranslationULPProbabilityThreshold))
305 return true;
306 return false;
307 }
308
224 void TranslateManager::TranslatePage(const std::string& original_source_lang, 309 void TranslateManager::TranslatePage(const std::string& original_source_lang,
225 const std::string& target_lang, 310 const std::string& target_lang,
226 bool triggered_from_menu) { 311 bool triggered_from_menu) {
227 if (!translate_driver_->HasCurrentPage()) { 312 if (!translate_driver_->HasCurrentPage()) {
228 NOTREACHED(); 313 NOTREACHED();
229 return; 314 return;
230 } 315 }
231 316
232 // Translation can be kicked by context menu against unsupported languages. 317 // Translation can be kicked by context menu against unsupported languages.
233 // Unsupported language strings should be replaced with 318 // Unsupported language strings should be replaced with
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 source_lang, 433 source_lang,
349 target_lang, 434 target_lang,
350 TranslateErrors::NETWORK, 435 TranslateErrors::NETWORK,
351 false); 436 false);
352 NotifyTranslateError(TranslateErrors::NETWORK); 437 NotifyTranslateError(TranslateErrors::NETWORK);
353 } 438 }
354 } 439 }
355 440
356 // static 441 // static
357 std::string TranslateManager::GetTargetLanguage(const TranslatePrefs* prefs) { 442 std::string TranslateManager::GetTargetLanguage(const TranslatePrefs* prefs) {
358 std::string ui_lang = TranslateDownloadManager::GetLanguageCode( 443 std::string language;
359 TranslateDownloadManager::GetInstance()->application_locale());
360 translate::ToTranslateLanguageSynonym(&ui_lang);
361 444
362 TranslateExperiment::OverrideUiLanguage(prefs->GetCountry(), &ui_lang); 445 // Get the override UI language.
446 TranslateExperiment::OverrideUiLanguage(prefs->GetCountry(), &language);
363 447
364 if (TranslateDownloadManager::IsSupportedLanguage(ui_lang)) 448 // If there are no override.
365 return ui_lang; 449 if (language.empty()) {
450 // Get the language from ULP.
451 language = TranslateManager::GetTargetLanguageFromULP(prefs);
452 if (!language.empty())
453 return language;
454
455 // Get the browser's user interface language.
456 language = TranslateDownloadManager::GetLanguageCode(
457 TranslateDownloadManager::GetInstance()->application_locale());
458 }
459 if (TranslateDownloadManager::IsSupportedLanguage(language))
460 return language;
366 461
367 // Will translate to the first supported language on the Accepted Language 462 // Will translate to the first supported language on the Accepted Language
368 // list or not at all if no such candidate exists. 463 // list or not at all if no such candidate exists.
369 std::vector<std::string> accept_languages_list; 464 std::vector<std::string> accept_languages_list;
370 prefs->GetLanguageList(&accept_languages_list); 465 prefs->GetLanguageList(&accept_languages_list);
371 for (const auto& lang : accept_languages_list) { 466 for (const auto& lang : accept_languages_list) {
372 std::string lang_code = TranslateDownloadManager::GetLanguageCode(lang); 467 std::string lang_code = TranslateDownloadManager::GetLanguageCode(lang);
373 if (TranslateDownloadManager::IsSupportedLanguage(lang_code)) 468 if (TranslateDownloadManager::IsSupportedLanguage(lang_code))
374 return lang_code; 469 return lang_code;
375 } 470 }
376 return std::string(); 471 return std::string();
377 } 472 }
378 473
379 // static 474 // static
475 std::string TranslateManager::GetTargetLanguageFromULP(
476 const TranslatePrefs* prefs) {
477 if (!base::FeatureList::IsEnabled(kTranslateLanguageByULP))
478 return std::string();
479 std::map<std::string, std::string> params;
480 variations::GetVariationParamsByFeature(translate::kTranslateLanguageByULP,
481 &params);
482 double probability_threshold =
483 GetDoubleFromMap(params, kTargetLanguageULPProbabilityThresholdName,
484 kDefaultTargetLanguageULPProbabilityThreshold);
485 TranslatePrefs::LanguageAndProbabilityList reading;
486 // We only consider ULP if the confidence is greater than the threshold.
487 if (prefs->GetReadingFromUserLanguageProfile(&reading) <=
488 GetDoubleFromMap(params, kTargetLanguageULPConfidenceThresholdName,
489 kDefaultTargetLanguageULPConfidenceThreshold))
490 return std::string();
491
492 for (const auto& it : reading) {
groby-ooo-7-16 2016/08/04 02:33:42 Question: Isn't the list sorted by decreasing prob
ftang 2016/08/05 04:45:27 Done. You are right, the for loop is needed before
493 if (it.second > probability_threshold)
494 return it.first;
495 }
496 return std::string();
497 }
498
499 // static
380 std::string TranslateManager::GetAutoTargetLanguage( 500 std::string TranslateManager::GetAutoTargetLanguage(
381 const std::string& original_language, 501 const std::string& original_language,
382 TranslatePrefs* translate_prefs) { 502 TranslatePrefs* translate_prefs) {
383 std::string auto_target_lang; 503 std::string auto_target_lang;
384 if (translate_prefs->ShouldAutoTranslate(original_language, 504 if (translate_prefs->ShouldAutoTranslate(original_language,
385 &auto_target_lang)) { 505 &auto_target_lang)) {
386 // We need to confirm that the saved target language is still supported. 506 // We need to confirm that the saved target language is still supported.
387 // Also, GetLanguageCode will take care of removing country code if any. 507 // Also, GetLanguageCode will take care of removing country code if any.
388 auto_target_lang = 508 auto_target_lang =
389 TranslateDownloadManager::GetLanguageCode(auto_target_lang); 509 TranslateDownloadManager::GetLanguageCode(auto_target_lang);
390 if (TranslateDownloadManager::IsSupportedLanguage(auto_target_lang)) 510 if (TranslateDownloadManager::IsSupportedLanguage(auto_target_lang))
391 return auto_target_lang; 511 return auto_target_lang;
392 } 512 }
393 return std::string(); 513 return std::string();
394 } 514 }
395 515
396 LanguageState& TranslateManager::GetLanguageState() { 516 LanguageState& TranslateManager::GetLanguageState() {
397 return language_state_; 517 return language_state_;
398 } 518 }
399 519
400 bool TranslateManager::ignore_missing_key_for_testing_ = false; 520 bool TranslateManager::ignore_missing_key_for_testing_ = false;
401 521
402 // static 522 // static
403 void TranslateManager::SetIgnoreMissingKeyForTesting(bool ignore) { 523 void TranslateManager::SetIgnoreMissingKeyForTesting(bool ignore) {
404 ignore_missing_key_for_testing_ = ignore; 524 ignore_missing_key_for_testing_ = ignore;
405 } 525 }
406 526
407 } // namespace translate 527 } // namespace translate
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698