OLD | NEW |
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> | 7 #include <map> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 language_state_.translation_declined() || | 158 language_state_.translation_declined() || |
159 language_state_.IsPageTranslated()) { | 159 language_state_.IsPageTranslated()) { |
160 return; | 160 return; |
161 } | 161 } |
162 | 162 |
163 // Also, skip if the connection is currently offline - initiation doesn't make | 163 // Also, skip if the connection is currently offline - initiation doesn't make |
164 // sense there, either. | 164 // sense there, either. |
165 if (net::NetworkChangeNotifier::IsOffline()) | 165 if (net::NetworkChangeNotifier::IsOffline()) |
166 return; | 166 return; |
167 | 167 |
168 if (!ignore_missing_key_for_testing_ && | 168 if (!ignore_missing_key_for_testing_ && !::google_apis::HasKeysConfigured()) { |
169 !::google_apis::HasKeysConfigured()) { | |
170 // Without an API key, translate won't work, so don't offer to translate | 169 // Without an API key, translate won't work, so don't offer to translate |
171 // in the first place. Leave prefs::kEnableTranslate on, though, because | 170 // in the first place. Leave prefs::kEnableTranslate on, though, because |
172 // that settings syncs and we don't want to turn off translate everywhere | 171 // that settings syncs and we don't want to turn off translate everywhere |
173 // else. | 172 // else. |
174 TranslateBrowserMetrics::ReportInitiationStatus( | 173 TranslateBrowserMetrics::ReportInitiationStatus( |
175 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_KEY); | 174 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_KEY); |
176 return; | 175 return; |
177 } | 176 } |
178 | 177 |
179 std::unique_ptr<TranslatePrefs> translate_prefs( | 178 std::unique_ptr<TranslatePrefs> translate_prefs( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 | 220 |
222 InitTranslateEvent(language_code, target_lang, *translate_prefs); | 221 InitTranslateEvent(language_code, target_lang, *translate_prefs); |
223 | 222 |
224 // Don't translate similar languages (ex: en-US to en). | 223 // Don't translate similar languages (ex: en-US to en). |
225 if (language_code == target_lang) { | 224 if (language_code == target_lang) { |
226 TranslateBrowserMetrics::ReportInitiationStatus( | 225 TranslateBrowserMetrics::ReportInitiationStatus( |
227 TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES); | 226 TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES); |
228 return; | 227 return; |
229 } | 228 } |
230 | 229 |
231 bool ranker_should_offer_translation = true; | 230 // Querying the ranker now, but not exiting immediately so that we may log |
232 if (translate_ranker_->IsQueryEnabled() || | 231 // other potential suppression reasons. |
233 translate_ranker_->IsEnforcementEnabled()) { | 232 bool should_offer_translation = translate_ranker_->ShouldOfferTranslation( |
234 ranker_should_offer_translation = translate_ranker_->ShouldOfferTranslation( | 233 *translate_prefs, language_code, target_lang, translate_event_.get()); |
235 *translate_prefs, language_code, target_lang); | |
236 translate_event_->set_ranker_request_timestamp_sec( | |
237 (base::TimeTicks::Now() - base::TimeTicks()).InSeconds()); | |
238 translate_event_->set_ranker_version(translate_ranker_->GetModelVersion()); | |
239 translate_event_->set_ranker_response( | |
240 ranker_should_offer_translation | |
241 ? metrics::TranslateEventProto::SHOW | |
242 : metrics::TranslateEventProto::DONT_SHOW); | |
243 } | |
244 | 234 |
245 // Nothing to do if either the language Chrome is in or the language of the | 235 // Nothing to do if either the language Chrome is in or the language of |
246 // page is not supported by the translation server. | 236 // the page is not supported by the translation server. |
247 if (target_lang.empty() || | 237 if (target_lang.empty() || |
248 !TranslateDownloadManager::IsSupportedLanguage(language_code)) { | 238 !TranslateDownloadManager::IsSupportedLanguage(language_code)) { |
249 TranslateBrowserMetrics::ReportInitiationStatus( | 239 TranslateBrowserMetrics::ReportInitiationStatus( |
250 TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED); | 240 TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED); |
251 TranslateBrowserMetrics::ReportUnsupportedLanguageAtInitiation( | 241 TranslateBrowserMetrics::ReportUnsupportedLanguageAtInitiation( |
252 language_code); | 242 language_code); |
253 RecordTranslateEvent(metrics::TranslateEventProto::UNSUPPORTED_LANGUAGE); | 243 RecordTranslateEvent(metrics::TranslateEventProto::UNSUPPORTED_LANGUAGE); |
254 return; | 244 return; |
255 } | 245 } |
256 | 246 |
257 TranslateAcceptLanguages* accept_languages = | 247 TranslateAcceptLanguages* accept_languages = |
258 translate_client_->GetTranslateAcceptLanguages(); | 248 translate_client_->GetTranslateAcceptLanguages(); |
259 // Don't translate any user black-listed languages. | 249 // Don't translate any user black-listed languages. |
260 if (!translate_prefs->CanTranslateLanguage(accept_languages, | 250 if (!translate_prefs->CanTranslateLanguage(accept_languages, language_code)) { |
261 language_code)) { | |
262 TranslateBrowserMetrics::ReportInitiationStatus( | 251 TranslateBrowserMetrics::ReportInitiationStatus( |
263 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG); | 252 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG); |
264 RecordTranslateEvent( | 253 RecordTranslateEvent( |
265 metrics::TranslateEventProto::LANGUAGE_DISABLED_BY_USER_CONFIG); | 254 metrics::TranslateEventProto::LANGUAGE_DISABLED_BY_USER_CONFIG); |
266 return; | 255 return; |
267 } | 256 } |
268 | 257 |
269 // Don't translate any user black-listed URLs. | 258 // Don't translate any user black-listed URLs. |
270 if (translate_prefs->IsSiteBlacklisted(page_url.HostNoBrackets())) { | 259 if (translate_prefs->IsSiteBlacklisted(page_url.HostNoBrackets())) { |
271 TranslateBrowserMetrics::ReportInitiationStatus( | 260 TranslateBrowserMetrics::ReportInitiationStatus( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 return; | 294 return; |
306 } | 295 } |
307 | 296 |
308 if (LanguageInULP(language_code)) { | 297 if (LanguageInULP(language_code)) { |
309 TranslateBrowserMetrics::ReportInitiationStatus( | 298 TranslateBrowserMetrics::ReportInitiationStatus( |
310 TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IN_ULP); | 299 TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IN_ULP); |
311 RecordTranslateEvent(metrics::TranslateEventProto::LANGUAGE_IN_ULP); | 300 RecordTranslateEvent(metrics::TranslateEventProto::LANGUAGE_IN_ULP); |
312 return; | 301 return; |
313 } | 302 } |
314 | 303 |
315 if (!ranker_should_offer_translation && | 304 if (!should_offer_translation) { |
316 translate_ranker_->IsEnforcementEnabled()) { | |
317 TranslateBrowserMetrics::ReportInitiationStatus( | 305 TranslateBrowserMetrics::ReportInitiationStatus( |
318 TranslateBrowserMetrics::INITIATION_STATUS_ABORTED_BY_RANKER); | 306 TranslateBrowserMetrics::INITIATION_STATUS_ABORTED_BY_RANKER); |
319 RecordTranslateEvent(metrics::TranslateEventProto::DISABLED_BY_RANKER); | 307 RecordTranslateEvent(metrics::TranslateEventProto::DISABLED_BY_RANKER); |
320 return; | 308 return; |
321 } | 309 } |
322 | 310 |
323 TranslateBrowserMetrics::ReportInitiationStatus( | 311 TranslateBrowserMetrics::ReportInitiationStatus( |
324 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); | 312 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); |
325 | 313 |
326 // Prompts the user if they want the page translated. | 314 // Prompts the user if they want the page translated. |
327 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, | 315 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, |
328 language_code, | 316 language_code, target_lang, |
329 target_lang, | 317 TranslateErrors::NONE, false); |
330 TranslateErrors::NONE, | |
331 false); | |
332 } | 318 } |
333 | 319 |
334 bool TranslateManager::LanguageInULP(const std::string& language) const { | 320 bool TranslateManager::LanguageInULP(const std::string& language) const { |
335 if (!base::FeatureList::IsEnabled(kTranslateLanguageByULP)) | 321 if (!base::FeatureList::IsEnabled(kTranslateLanguageByULP)) |
336 return false; | 322 return false; |
337 std::map<std::string, std::string> params; | 323 std::map<std::string, std::string> params; |
338 variations::GetVariationParamsByFeature(translate::kTranslateLanguageByULP, | 324 variations::GetVariationParamsByFeature(translate::kTranslateLanguageByULP, |
339 ¶ms); | 325 ¶ms); |
340 // Check the language & probability on the reading list. | 326 // Check the language & probability on the reading list. |
341 TranslatePrefs::LanguageAndProbabilityList reading; | 327 TranslatePrefs::LanguageAndProbabilityList reading; |
(...skipping 26 matching lines...) Expand all Loading... |
368 if (!TranslateDownloadManager::IsSupportedLanguage(source_lang)) | 354 if (!TranslateDownloadManager::IsSupportedLanguage(source_lang)) |
369 source_lang = std::string(translate::kUnknownLanguageCode); | 355 source_lang = std::string(translate::kUnknownLanguageCode); |
370 | 356 |
371 // Capture the translate event if we were triggered from the menu. | 357 // Capture the translate event if we were triggered from the menu. |
372 if (triggered_from_menu) { | 358 if (triggered_from_menu) { |
373 RecordTranslateEvent( | 359 RecordTranslateEvent( |
374 metrics::TranslateEventProto::USER_CONTEXT_MENU_TRANSLATE); | 360 metrics::TranslateEventProto::USER_CONTEXT_MENU_TRANSLATE); |
375 } | 361 } |
376 | 362 |
377 // Trigger the "translating now" UI. | 363 // Trigger the "translating now" UI. |
378 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_TRANSLATING, | 364 translate_client_->ShowTranslateUI( |
379 source_lang, | 365 translate::TRANSLATE_STEP_TRANSLATING, source_lang, target_lang, |
380 target_lang, | 366 TranslateErrors::NONE, triggered_from_menu); |
381 TranslateErrors::NONE, | |
382 triggered_from_menu); | |
383 | 367 |
384 TranslateScript* script = TranslateDownloadManager::GetInstance()->script(); | 368 TranslateScript* script = TranslateDownloadManager::GetInstance()->script(); |
385 DCHECK(script != NULL); | 369 DCHECK(script != NULL); |
386 | 370 |
387 const std::string& script_data = script->data(); | 371 const std::string& script_data = script->data(); |
388 if (!script_data.empty()) { | 372 if (!script_data.empty()) { |
389 DoTranslatePage(script_data, source_lang, target_lang); | 373 DoTranslatePage(script_data, source_lang, target_lang); |
390 return; | 374 return; |
391 } | 375 } |
392 | 376 |
393 // The script is not available yet. Queue that request and query for the | 377 // The script is not available yet. Queue that request and query for the |
394 // script. Once it is downloaded we'll do the translate. | 378 // script. Once it is downloaded we'll do the translate. |
395 TranslateScript::RequestCallback callback = base::Bind( | 379 TranslateScript::RequestCallback callback = |
396 &TranslateManager::OnTranslateScriptFetchComplete, GetWeakPtr(), | 380 base::Bind(&TranslateManager::OnTranslateScriptFetchComplete, |
397 source_lang, target_lang); | 381 GetWeakPtr(), source_lang, target_lang); |
398 | 382 |
399 script->Request(callback); | 383 script->Request(callback); |
400 } | 384 } |
401 | 385 |
402 void TranslateManager::RevertTranslation() { | 386 void TranslateManager::RevertTranslation() { |
403 // Capture the revert event in the translate metrics | 387 // Capture the revert event in the translate metrics |
404 RecordTranslateEvent(metrics::TranslateEventProto::USER_REVERT); | 388 RecordTranslateEvent(metrics::TranslateEventProto::USER_REVERT); |
405 | 389 |
406 // Revert the translation. | 390 // Revert the translation. |
407 translate_driver_->RevertTranslation(page_seq_no_); | 391 translate_driver_->RevertTranslation(page_seq_no_); |
408 language_state_.SetCurrentLanguage(language_state_.original_language()); | 392 language_state_.SetCurrentLanguage(language_state_.original_language()); |
409 } | 393 } |
410 | 394 |
411 void TranslateManager::ReportLanguageDetectionError() { | 395 void TranslateManager::ReportLanguageDetectionError() { |
412 TranslateBrowserMetrics::ReportLanguageDetectionError(); | 396 TranslateBrowserMetrics::ReportLanguageDetectionError(); |
413 | 397 |
414 GURL report_error_url = GURL(kReportLanguageDetectionErrorURL); | 398 GURL report_error_url = GURL(kReportLanguageDetectionErrorURL); |
415 | 399 |
416 report_error_url = net::AppendQueryParameter( | 400 report_error_url = net::AppendQueryParameter( |
417 report_error_url, kUrlQueryName, | 401 report_error_url, kUrlQueryName, |
418 translate_driver_->GetLastCommittedURL().spec()); | 402 translate_driver_->GetLastCommittedURL().spec()); |
419 | 403 |
420 report_error_url = | 404 report_error_url = |
421 net::AppendQueryParameter(report_error_url, | 405 net::AppendQueryParameter(report_error_url, kSourceLanguageQueryName, |
422 kSourceLanguageQueryName, | |
423 language_state_.original_language()); | 406 language_state_.original_language()); |
424 | 407 |
425 report_error_url = translate::AddHostLocaleToUrl(report_error_url); | 408 report_error_url = translate::AddHostLocaleToUrl(report_error_url); |
426 report_error_url = translate::AddApiKeyToUrl(report_error_url); | 409 report_error_url = translate::AddApiKeyToUrl(report_error_url); |
427 | 410 |
428 translate_client_->ShowReportLanguageDetectionErrorUI(report_error_url); | 411 translate_client_->ShowReportLanguageDetectionErrorUI(report_error_url); |
429 } | 412 } |
430 | 413 |
431 void TranslateManager::DoTranslatePage(const std::string& translate_script, | 414 void TranslateManager::DoTranslatePage(const std::string& translate_script, |
432 const std::string& source_lang, | 415 const std::string& source_lang, |
433 const std::string& target_lang) { | 416 const std::string& target_lang) { |
434 language_state_.set_translation_pending(true); | 417 language_state_.set_translation_pending(true); |
435 translate_driver_->TranslatePage( | 418 translate_driver_->TranslatePage(page_seq_no_, translate_script, source_lang, |
436 page_seq_no_, translate_script, source_lang, target_lang); | 419 target_lang); |
437 } | 420 } |
438 | 421 |
439 // Notifies |g_callback_list_| of translate errors. | 422 // Notifies |g_callback_list_| of translate errors. |
440 void TranslateManager::NotifyTranslateError(TranslateErrors::Type error_type) { | 423 void TranslateManager::NotifyTranslateError(TranslateErrors::Type error_type) { |
441 if (!g_callback_list_ || error_type == TranslateErrors::NONE || | 424 if (!g_callback_list_ || error_type == TranslateErrors::NONE || |
442 translate_driver_->IsIncognito()) { | 425 translate_driver_->IsIncognito()) { |
443 return; | 426 return; |
444 } | 427 } |
445 | 428 |
446 TranslateErrorDetails error_details; | 429 TranslateErrorDetails error_details; |
447 error_details.time = base::Time::Now(); | 430 error_details.time = base::Time::Now(); |
448 error_details.url = translate_driver_->GetLastCommittedURL(); | 431 error_details.url = translate_driver_->GetLastCommittedURL(); |
449 error_details.error = error_type; | 432 error_details.error = error_type; |
450 g_callback_list_->Notify(error_details); | 433 g_callback_list_->Notify(error_details); |
451 } | 434 } |
452 | 435 |
453 void TranslateManager::PageTranslated(const std::string& source_lang, | 436 void TranslateManager::PageTranslated(const std::string& source_lang, |
454 const std::string& target_lang, | 437 const std::string& target_lang, |
455 TranslateErrors::Type error_type) { | 438 TranslateErrors::Type error_type) { |
456 language_state_.SetCurrentLanguage(target_lang); | 439 language_state_.SetCurrentLanguage(target_lang); |
457 language_state_.set_translation_pending(false); | 440 language_state_.set_translation_pending(false); |
458 | 441 |
459 if ((error_type == TranslateErrors::NONE) && | 442 if ((error_type == TranslateErrors::NONE) && |
460 source_lang != translate::kUnknownLanguageCode && | 443 source_lang != translate::kUnknownLanguageCode && |
461 !TranslateDownloadManager::IsSupportedLanguage(source_lang)) { | 444 !TranslateDownloadManager::IsSupportedLanguage(source_lang)) { |
462 error_type = TranslateErrors::UNSUPPORTED_LANGUAGE; | 445 error_type = TranslateErrors::UNSUPPORTED_LANGUAGE; |
463 } | 446 } |
464 | 447 |
465 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_AFTER_TRANSLATE, | 448 translate_client_->ShowTranslateUI(translate::TRANSLATE_STEP_AFTER_TRANSLATE, |
466 source_lang, | 449 source_lang, target_lang, error_type, |
467 target_lang, | |
468 error_type, | |
469 false); | 450 false); |
470 NotifyTranslateError(error_type); | 451 NotifyTranslateError(error_type); |
471 } | 452 } |
472 | 453 |
473 void TranslateManager::OnTranslateScriptFetchComplete( | 454 void TranslateManager::OnTranslateScriptFetchComplete( |
474 const std::string& source_lang, | 455 const std::string& source_lang, |
475 const std::string& target_lang, | 456 const std::string& target_lang, |
476 bool success, | 457 bool success, |
477 const std::string& data) { | 458 const std::string& data) { |
478 if (!translate_driver_->HasCurrentPage()) | 459 if (!translate_driver_->HasCurrentPage()) |
479 return; | 460 return; |
480 | 461 |
481 if (success) { | 462 if (success) { |
482 // Translate the page. | 463 // Translate the page. |
483 TranslateScript* translate_script = | 464 TranslateScript* translate_script = |
484 TranslateDownloadManager::GetInstance()->script(); | 465 TranslateDownloadManager::GetInstance()->script(); |
485 DCHECK(translate_script); | 466 DCHECK(translate_script); |
486 DoTranslatePage(translate_script->data(), source_lang, target_lang); | 467 DoTranslatePage(translate_script->data(), source_lang, target_lang); |
487 } else { | 468 } else { |
488 translate_client_->ShowTranslateUI( | 469 translate_client_->ShowTranslateUI( |
489 translate::TRANSLATE_STEP_TRANSLATE_ERROR, | 470 translate::TRANSLATE_STEP_TRANSLATE_ERROR, source_lang, target_lang, |
490 source_lang, | 471 TranslateErrors::NETWORK, false); |
491 target_lang, | |
492 TranslateErrors::NETWORK, | |
493 false); | |
494 NotifyTranslateError(TranslateErrors::NETWORK); | 472 NotifyTranslateError(TranslateErrors::NETWORK); |
495 } | 473 } |
496 } | 474 } |
497 | 475 |
498 // static | 476 // static |
499 std::string TranslateManager::GetTargetLanguage(const TranslatePrefs* prefs) { | 477 std::string TranslateManager::GetTargetLanguage(const TranslatePrefs* prefs) { |
500 std::string language; | 478 std::string language; |
501 | 479 |
502 // Get the override UI language. | 480 // Get the override UI language. |
503 TranslateExperiment::OverrideUiLanguage(prefs->GetCountry(), &language); | 481 TranslateExperiment::OverrideUiLanguage(prefs->GetCountry(), &language); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 prefs.GetTranslationDeniedCount(src_lang)); | 572 prefs.GetTranslationDeniedCount(src_lang)); |
595 translate_event_->set_ignore_count( | 573 translate_event_->set_ignore_count( |
596 prefs.GetTranslationIgnoredCount(src_lang)); | 574 prefs.GetTranslationIgnoredCount(src_lang)); |
597 translate_event_->set_ranker_response( | 575 translate_event_->set_ranker_response( |
598 metrics::TranslateEventProto::NOT_QUERIED); | 576 metrics::TranslateEventProto::NOT_QUERIED); |
599 translate_event_->set_event_type(metrics::TranslateEventProto::UNKNOWN); | 577 translate_event_->set_event_type(metrics::TranslateEventProto::UNKNOWN); |
600 // TODO(rogerm): Populate the language list. | 578 // TODO(rogerm): Populate the language list. |
601 } | 579 } |
602 | 580 |
603 void TranslateManager::RecordTranslateEvent(int event_type) { | 581 void TranslateManager::RecordTranslateEvent(int event_type) { |
604 DCHECK(metrics::TranslateEventProto::EventType_IsValid(event_type)); | 582 translate_ranker_->RecordTranslateEvent( |
605 translate_event_->set_event_type( | 583 event_type, translate_driver_->GetVisibleURL(), translate_event_.get()); |
606 static_cast<metrics::TranslateEventProto::EventType>(event_type)); | 584 } |
607 translate_event_->set_event_timestamp_sec( | 585 |
608 (base::TimeTicks::Now() - base::TimeTicks()).InSeconds()); | 586 bool TranslateManager::ShouldOverrideDecision(int event_type) { |
609 translate_ranker_->AddTranslateEvent(*translate_event_, | 587 return translate_ranker_->ShouldOverrideDecision( |
610 translate_driver_->GetVisibleURL()); | 588 event_type, translate_driver_->GetVisibleURL(), translate_event_.get()); |
| 589 } |
| 590 |
| 591 bool TranslateManager::ShouldSuppressBubbleUI( |
| 592 bool triggered_from_menu, |
| 593 const std::string& source_language) { |
| 594 // Suppress the UI if the user navigates to a page with |
| 595 // the same language as the previous page. In the new UI, |
| 596 // continue offering translation after the user navigates |
| 597 // to another page. |
| 598 language_state_.SetTranslateEnabled(true); |
| 599 if (!base::FeatureList::IsEnabled(translate::kTranslateUI2016Q2) && |
| 600 !language_state_.HasLanguageChanged() && |
| 601 !ShouldOverrideDecision( |
| 602 metrics::TranslateEventProto::MATCHES_PREVIOUS_LANGUAGE)) { |
| 603 return true; |
| 604 } |
| 605 |
| 606 // Suppress the UI if the user denied translation for this language |
| 607 // too often. |
| 608 if (!triggered_from_menu && |
| 609 translate_client_->GetTranslatePrefs()->IsTooOftenDenied( |
| 610 source_language) && |
| 611 !ShouldOverrideDecision( |
| 612 metrics::TranslateEventProto::LANGUAGE_DISABLED_BY_AUTO_BLACKLIST)) { |
| 613 return true; |
| 614 } |
| 615 |
| 616 return false; |
611 } | 617 } |
612 | 618 |
613 } // namespace translate | 619 } // namespace translate |
OLD | NEW |