| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/translate/translate_manager.h" | 5 #include "chrome/browser/translate/translate_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/memory/singleton.h" | 9 #include "base/memory/singleton.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "chrome/browser/translate/translate_event_details.h" | 25 #include "chrome/browser/translate/translate_event_details.h" |
| 26 #include "chrome/browser/translate/translate_infobar_delegate.h" | 26 #include "chrome/browser/translate/translate_infobar_delegate.h" |
| 27 #include "chrome/browser/translate/translate_language_list.h" | 27 #include "chrome/browser/translate/translate_language_list.h" |
| 28 #include "chrome/browser/translate/translate_prefs.h" | 28 #include "chrome/browser/translate/translate_prefs.h" |
| 29 #include "chrome/browser/translate/translate_script.h" | 29 #include "chrome/browser/translate/translate_script.h" |
| 30 #include "chrome/browser/translate/translate_tab_helper.h" | 30 #include "chrome/browser/translate/translate_tab_helper.h" |
| 31 #include "chrome/browser/translate/translate_url_util.h" | 31 #include "chrome/browser/translate/translate_url_util.h" |
| 32 #include "chrome/browser/ui/browser.h" | 32 #include "chrome/browser/ui/browser.h" |
| 33 #include "chrome/browser/ui/browser_finder.h" | 33 #include "chrome/browser/ui/browser_finder.h" |
| 34 #include "chrome/browser/ui/browser_tabstrip.h" | 34 #include "chrome/browser/ui/browser_tabstrip.h" |
| 35 #include "chrome/browser/ui/browser_window.h" |
| 35 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 36 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 37 #include "chrome/browser/ui/translate/translate_bubble_model.h" |
| 36 #include "chrome/common/chrome_switches.h" | 38 #include "chrome/common/chrome_switches.h" |
| 37 #include "chrome/common/pref_names.h" | 39 #include "chrome/common/pref_names.h" |
| 38 #include "chrome/common/render_messages.h" | 40 #include "chrome/common/render_messages.h" |
| 39 #include "chrome/common/translate/language_detection_details.h" | 41 #include "chrome/common/translate/language_detection_details.h" |
| 40 #include "chrome/common/url_constants.h" | 42 #include "chrome/common/url_constants.h" |
| 41 #include "components/translate/common/translate_constants.h" | 43 #include "components/translate/common/translate_constants.h" |
| 42 #include "content/public/browser/navigation_controller.h" | 44 #include "content/public/browser/navigation_controller.h" |
| 43 #include "content/public/browser/navigation_details.h" | 45 #include "content/public/browser/navigation_details.h" |
| 44 #include "content/public/browser/navigation_entry.h" | 46 #include "content/public/browser/navigation_entry.h" |
| 45 #include "content/public/browser/notification_details.h" | 47 #include "content/public/browser/notification_details.h" |
| 46 #include "content/public/browser/notification_service.h" | 48 #include "content/public/browser/notification_service.h" |
| 47 #include "content/public/browser/notification_source.h" | 49 #include "content/public/browser/notification_source.h" |
| 48 #include "content/public/browser/notification_types.h" | 50 #include "content/public/browser/notification_types.h" |
| 49 #include "content/public/browser/render_process_host.h" | 51 #include "content/public/browser/render_process_host.h" |
| 50 #include "content/public/browser/render_view_host.h" | 52 #include "content/public/browser/render_view_host.h" |
| 51 #include "content/public/browser/web_contents.h" | 53 #include "content/public/browser/web_contents.h" |
| 52 #include "net/base/url_util.h" | 54 #include "net/base/url_util.h" |
| 53 #include "net/http/http_status_code.h" | 55 #include "net/http/http_status_code.h" |
| 54 | 56 |
| 55 #ifdef FILE_MANAGER_EXTENSION | 57 #ifdef FILE_MANAGER_EXTENSION |
| 56 #include "chrome/browser/chromeos/file_manager/app_id.h" | 58 #include "chrome/browser/chromeos/file_manager/app_id.h" |
| 57 #include "extensions/common/constants.h" | 59 #include "extensions/common/constants.h" |
| 58 #endif | 60 #endif |
| 59 | 61 |
| 60 using content::NavigationController; | 62 using content::NavigationController; |
| 61 using content::NavigationEntry; | 63 using content::NavigationEntry; |
| 62 using content::WebContents; | 64 using content::WebContents; |
| 63 | 65 |
| 66 namespace { |
| 67 |
| 64 const char kReportLanguageDetectionErrorURL[] = | 68 const char kReportLanguageDetectionErrorURL[] = |
| 65 "https://translate.google.com/translate_error?client=cr&action=langidc"; | 69 "https://translate.google.com/translate_error?client=cr&action=langidc"; |
| 66 | 70 |
| 67 // Used in kReportLanguageDetectionErrorURL to specify the original page | 71 // Used in kReportLanguageDetectionErrorURL to specify the original page |
| 68 // language. | 72 // language. |
| 69 const char kSourceLanguageQueryName[] = "sl"; | 73 const char kSourceLanguageQueryName[] = "sl"; |
| 70 | 74 |
| 71 // Used in kReportLanguageDetectionErrorURL to specify the page URL. | 75 // Used in kReportLanguageDetectionErrorURL to specify the page URL. |
| 72 const char kUrlQueryName[] = "u"; | 76 const char kUrlQueryName[] = "u"; |
| 73 | 77 |
| 74 // The maximum number of attempts we'll do to see if the page has finshed | 78 // The maximum number of attempts we'll do to see if the page has finshed |
| 75 // loading before giving up the translation | 79 // loading before giving up the translation |
| 76 const int kMaxTranslateLoadCheckAttempts = 20; | 80 const int kMaxTranslateLoadCheckAttempts = 20; |
| 77 | 81 |
| 82 bool IsEnabledTranslateNewUX() { |
| 83 return CommandLine::ForCurrentProcess()->HasSwitch( |
| 84 switches::kEnableTranslateNewUX); |
| 85 } |
| 86 |
| 87 void ShowBubble(WebContents* web_contents, |
| 88 TranslateBubbleModel::ViewState view_state) { |
| 89 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); |
| 90 if (!browser) |
| 91 return; |
| 92 |
| 93 BrowserWindow* window = browser->window(); |
| 94 if (!window) |
| 95 return; |
| 96 |
| 97 window->ShowTranslateBubble(web_contents, view_state); |
| 98 } |
| 99 |
| 100 } // namespace |
| 101 |
| 78 TranslateManager::~TranslateManager() { | 102 TranslateManager::~TranslateManager() { |
| 79 } | 103 } |
| 80 | 104 |
| 81 // static | 105 // static |
| 82 TranslateManager* TranslateManager::GetInstance() { | 106 TranslateManager* TranslateManager::GetInstance() { |
| 83 return Singleton<TranslateManager>::get(); | 107 return Singleton<TranslateManager>::get(); |
| 84 } | 108 } |
| 85 | 109 |
| 86 // static | 110 // static |
| 87 bool TranslateManager::IsTranslatableURL(const GURL& url) { | 111 bool TranslateManager::IsTranslatableURL(const GURL& url) { |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 content::NotificationService::AllSources()); | 319 content::NotificationService::AllSources()); |
| 296 notification_registrar_.Add(this, chrome::NOTIFICATION_PAGE_TRANSLATED, | 320 notification_registrar_.Add(this, chrome::NOTIFICATION_PAGE_TRANSLATED, |
| 297 content::NotificationService::AllSources()); | 321 content::NotificationService::AllSources()); |
| 298 language_list_.reset(new TranslateLanguageList); | 322 language_list_.reset(new TranslateLanguageList); |
| 299 accept_languages_.reset(new TranslateAcceptLanguages); | 323 accept_languages_.reset(new TranslateAcceptLanguages); |
| 300 script_.reset(new TranslateScript); | 324 script_.reset(new TranslateScript); |
| 301 } | 325 } |
| 302 | 326 |
| 303 void TranslateManager::InitiateTranslation(WebContents* web_contents, | 327 void TranslateManager::InitiateTranslation(WebContents* web_contents, |
| 304 const std::string& page_lang) { | 328 const std::string& page_lang) { |
| 329 TranslateTabHelper* translate_tab_helper = |
| 330 TranslateTabHelper::FromWebContents(web_contents); |
| 331 if (!translate_tab_helper) |
| 332 return; |
| 333 |
| 305 Profile* profile = | 334 Profile* profile = |
| 306 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 335 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 307 Profile* original_profile = profile->GetOriginalProfile(); | 336 Profile* original_profile = profile->GetOriginalProfile(); |
| 308 PrefService* prefs = original_profile->GetPrefs(); | 337 PrefService* prefs = original_profile->GetPrefs(); |
| 309 if (!prefs->GetBoolean(prefs::kEnableTranslate)) { | 338 if (!prefs->GetBoolean(prefs::kEnableTranslate)) { |
| 310 TranslateBrowserMetrics::ReportInitiationStatus( | 339 TranslateBrowserMetrics::ReportInitiationStatus( |
| 311 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_PREFS); | 340 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_PREFS); |
| 312 const std::string& locale = g_browser_process->GetApplicationLocale(); | 341 const std::string& locale = g_browser_process->GetApplicationLocale(); |
| 313 TranslateBrowserMetrics::ReportLocalesOnDisabledByPrefs(locale); | 342 TranslateBrowserMetrics::ReportLocalesOnDisabledByPrefs(locale); |
| 314 return; | 343 return; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 // Also, GetLanguageCode will take care of removing country code if any. | 417 // Also, GetLanguageCode will take care of removing country code if any. |
| 389 auto_target_lang = GetLanguageCode(auto_target_lang); | 418 auto_target_lang = GetLanguageCode(auto_target_lang); |
| 390 if (IsSupportedLanguage(auto_target_lang)) { | 419 if (IsSupportedLanguage(auto_target_lang)) { |
| 391 TranslateBrowserMetrics::ReportInitiationStatus( | 420 TranslateBrowserMetrics::ReportInitiationStatus( |
| 392 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG); | 421 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG); |
| 393 TranslatePage(web_contents, language_code, auto_target_lang); | 422 TranslatePage(web_contents, language_code, auto_target_lang); |
| 394 return; | 423 return; |
| 395 } | 424 } |
| 396 } | 425 } |
| 397 | 426 |
| 398 TranslateTabHelper* translate_tab_helper = | 427 LanguageState& language_state = translate_tab_helper->language_state(); |
| 399 TranslateTabHelper::FromWebContents(web_contents); | 428 std::string auto_translate_to = language_state.AutoTranslateTo(); |
| 400 if (!translate_tab_helper) | |
| 401 return; | |
| 402 std::string auto_translate_to = | |
| 403 translate_tab_helper->language_state().AutoTranslateTo(); | |
| 404 if (!auto_translate_to.empty()) { | 429 if (!auto_translate_to.empty()) { |
| 405 // This page was navigated through a click from a translated page. | 430 // This page was navigated through a click from a translated page. |
| 406 TranslateBrowserMetrics::ReportInitiationStatus( | 431 TranslateBrowserMetrics::ReportInitiationStatus( |
| 407 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK); | 432 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK); |
| 408 TranslatePage(web_contents, language_code, auto_translate_to); | 433 TranslatePage(web_contents, language_code, auto_translate_to); |
| 409 return; | 434 return; |
| 410 } | 435 } |
| 411 | 436 |
| 412 // Prompts the user if he/she wants the page translated. | |
| 413 TranslateBrowserMetrics::ReportInitiationStatus( | 437 TranslateBrowserMetrics::ReportInitiationStatus( |
| 414 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); | 438 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); |
| 415 TranslateInfoBarDelegate::Create( | 439 |
| 416 false, InfoBarService::FromWebContents(web_contents), | 440 if (IsEnabledTranslateNewUX()) { |
| 417 TranslateInfoBarDelegate::BEFORE_TRANSLATE, language_code, target_lang, | 441 language_state.SetTranslateEnabled(true); |
| 418 TranslateErrors::NONE, profile->GetPrefs(), ShortcutConfig()); | 442 if (language_state.IsLanguageChanged()) |
| 443 ShowBubble(web_contents, |
| 444 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE); |
| 445 } else { |
| 446 // Prompts the user if he/she wants the page translated. |
| 447 TranslateInfoBarDelegate::Create( |
| 448 false, InfoBarService::FromWebContents(web_contents), |
| 449 TranslateInfoBarDelegate::BEFORE_TRANSLATE, language_code, target_lang, |
| 450 TranslateErrors::NONE, profile->GetPrefs(), ShortcutConfig()); |
| 451 } |
| 419 } | 452 } |
| 420 | 453 |
| 421 void TranslateManager::InitiateTranslationPosted(int process_id, | 454 void TranslateManager::InitiateTranslationPosted(int process_id, |
| 422 int render_id, | 455 int render_id, |
| 423 const std::string& page_lang, | 456 const std::string& page_lang, |
| 424 int attempt) { | 457 int attempt) { |
| 425 // The tab might have been closed. | 458 // The tab might have been closed. |
| 426 WebContents* web_contents = | 459 WebContents* web_contents = |
| 427 tab_util::GetWebContentsByID(process_id, render_id); | 460 tab_util::GetWebContentsByID(process_id, render_id); |
| 428 if (!web_contents) | 461 if (!web_contents) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 } | 493 } |
| 461 | 494 |
| 462 // Translation can be kicked by context menu against unsupported languages. | 495 // Translation can be kicked by context menu against unsupported languages. |
| 463 // Unsupported language strings should be replaced with | 496 // Unsupported language strings should be replaced with |
| 464 // kUnknownLanguageCode in order to send a translation request with enabling | 497 // kUnknownLanguageCode in order to send a translation request with enabling |
| 465 // server side auto language detection. | 498 // server side auto language detection. |
| 466 std::string source_lang(original_source_lang); | 499 std::string source_lang(original_source_lang); |
| 467 if (!IsSupportedLanguage(source_lang)) | 500 if (!IsSupportedLanguage(source_lang)) |
| 468 source_lang = std::string(translate::kUnknownLanguageCode); | 501 source_lang = std::string(translate::kUnknownLanguageCode); |
| 469 | 502 |
| 470 Profile* profile = | 503 if (IsEnabledTranslateNewUX()) { |
| 471 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 504 ShowBubble(web_contents, TranslateBubbleModel::VIEW_STATE_TRANSLATING); |
| 472 TranslateInfoBarDelegate::Create( | 505 } else { |
| 473 true, InfoBarService::FromWebContents(web_contents), | 506 Profile* profile = |
| 474 TranslateInfoBarDelegate::TRANSLATING, source_lang, target_lang, | 507 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 475 TranslateErrors::NONE, profile->GetPrefs(), ShortcutConfig()); | 508 TranslateInfoBarDelegate::Create( |
| 509 true, InfoBarService::FromWebContents(web_contents), |
| 510 TranslateInfoBarDelegate::TRANSLATING, source_lang, target_lang, |
| 511 TranslateErrors::NONE, profile->GetPrefs(), ShortcutConfig()); |
| 512 } |
| 476 | 513 |
| 477 DCHECK(script_.get() != NULL); | 514 DCHECK(script_.get() != NULL); |
| 478 | 515 |
| 479 const std::string& translate_script = script_->data(); | 516 const std::string& translate_script = script_->data(); |
| 480 if (!translate_script.empty()) { | 517 if (!translate_script.empty()) { |
| 481 DoTranslatePage(web_contents, translate_script, source_lang, target_lang); | 518 DoTranslatePage(web_contents, translate_script, source_lang, target_lang); |
| 482 return; | 519 return; |
| 483 } | 520 } |
| 484 | 521 |
| 485 // The script is not available yet. Queue that request and query for the | 522 // The script is not available yet. Queue that request and query for the |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 } | 614 } |
| 578 | 615 |
| 579 void TranslateManager::PageTranslated(WebContents* web_contents, | 616 void TranslateManager::PageTranslated(WebContents* web_contents, |
| 580 PageTranslatedDetails* details) { | 617 PageTranslatedDetails* details) { |
| 581 if ((details->error_type == TranslateErrors::NONE) && | 618 if ((details->error_type == TranslateErrors::NONE) && |
| 582 details->source_language != translate::kUnknownLanguageCode && | 619 details->source_language != translate::kUnknownLanguageCode && |
| 583 !IsSupportedLanguage(details->source_language)) { | 620 !IsSupportedLanguage(details->source_language)) { |
| 584 details->error_type = TranslateErrors::UNSUPPORTED_LANGUAGE; | 621 details->error_type = TranslateErrors::UNSUPPORTED_LANGUAGE; |
| 585 } | 622 } |
| 586 | 623 |
| 587 PrefService* prefs = Profile::FromBrowserContext( | 624 if (IsEnabledTranslateNewUX()) { |
| 588 web_contents->GetBrowserContext())->GetPrefs(); | 625 TranslateBubbleModel::ViewState view_state = |
| 589 TranslateInfoBarDelegate::Create( | 626 (details->error_type == TranslateErrors::NONE) ? |
| 590 true, InfoBarService::FromWebContents(web_contents), | 627 TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE : |
| 591 (details->error_type == TranslateErrors::NONE) ? | 628 TranslateBubbleModel::VIEW_STATE_ERROR; |
| 592 TranslateInfoBarDelegate::AFTER_TRANSLATE : | 629 ShowBubble(web_contents, view_state); |
| 593 TranslateInfoBarDelegate::TRANSLATION_ERROR, | 630 } else { |
| 594 details->source_language, details->target_language, details->error_type, | 631 PrefService* prefs = Profile::FromBrowserContext( |
| 595 prefs, ShortcutConfig()); | 632 web_contents->GetBrowserContext())->GetPrefs(); |
| 633 TranslateInfoBarDelegate::Create( |
| 634 true, InfoBarService::FromWebContents(web_contents), |
| 635 (details->error_type == TranslateErrors::NONE) ? |
| 636 TranslateInfoBarDelegate::AFTER_TRANSLATE : |
| 637 TranslateInfoBarDelegate::TRANSLATION_ERROR, |
| 638 details->source_language, details->target_language, details->error_type, |
| 639 prefs, ShortcutConfig()); |
| 640 } |
| 596 | 641 |
| 597 if (details->error_type != TranslateErrors::NONE && | 642 if (details->error_type != TranslateErrors::NONE && |
| 598 !web_contents->GetBrowserContext()->IsOffTheRecord()) { | 643 !web_contents->GetBrowserContext()->IsOffTheRecord()) { |
| 599 TranslateErrorDetails error_details; | 644 TranslateErrorDetails error_details; |
| 600 error_details.time = base::Time::Now(); | 645 error_details.time = base::Time::Now(); |
| 601 error_details.url = web_contents->GetLastCommittedURL(); | 646 error_details.url = web_contents->GetLastCommittedURL(); |
| 602 error_details.error = details->error_type; | 647 error_details.error = details->error_type; |
| 603 NotifyTranslateError(error_details); | 648 NotifyTranslateError(error_details); |
| 604 } | 649 } |
| 605 } | 650 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 // We navigated away from the page the translation was triggered on. | 688 // We navigated away from the page the translation was triggered on. |
| 644 continue; | 689 continue; |
| 645 } | 690 } |
| 646 | 691 |
| 647 if (success) { | 692 if (success) { |
| 648 // Translate the page. | 693 // Translate the page. |
| 649 const std::string& translate_script = script_->data(); | 694 const std::string& translate_script = script_->data(); |
| 650 DoTranslatePage(web_contents, translate_script, | 695 DoTranslatePage(web_contents, translate_script, |
| 651 request.source_lang, request.target_lang); | 696 request.source_lang, request.target_lang); |
| 652 } else { | 697 } else { |
| 653 Profile* profile = | 698 if (IsEnabledTranslateNewUX()) { |
| 654 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 699 ShowBubble(web_contents, TranslateBubbleModel::VIEW_STATE_ERROR); |
| 655 TranslateInfoBarDelegate::Create( | 700 } else { |
| 656 true, InfoBarService::FromWebContents(web_contents), | 701 Profile* profile = |
| 657 TranslateInfoBarDelegate::TRANSLATION_ERROR, request.source_lang, | 702 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 658 request.target_lang, TranslateErrors::NETWORK, profile->GetPrefs(), | 703 TranslateInfoBarDelegate::Create( |
| 659 ShortcutConfig()); | 704 true, InfoBarService::FromWebContents(web_contents), |
| 705 TranslateInfoBarDelegate::TRANSLATION_ERROR, request.source_lang, |
| 706 request.target_lang, TranslateErrors::NETWORK, profile->GetPrefs(), |
| 707 ShortcutConfig()); |
| 708 } |
| 660 | 709 |
| 661 if (!web_contents->GetBrowserContext()->IsOffTheRecord()) { | 710 if (!web_contents->GetBrowserContext()->IsOffTheRecord()) { |
| 662 TranslateErrorDetails error_details; | 711 TranslateErrorDetails error_details; |
| 663 error_details.time = base::Time::Now(); | 712 error_details.time = base::Time::Now(); |
| 664 error_details.url = entry->GetURL(); | 713 error_details.url = entry->GetURL(); |
| 665 error_details.error = TranslateErrors::NETWORK; | 714 error_details.error = TranslateErrors::NETWORK; |
| 666 NotifyTranslateError(error_details); | 715 NotifyTranslateError(error_details); |
| 667 } | 716 } |
| 668 } | 717 } |
| 669 } | 718 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 // so we are more aggressive about showing the shortcut to never translate. | 752 // so we are more aggressive about showing the shortcut to never translate. |
| 704 #if defined(OS_ANDROID) | 753 #if defined(OS_ANDROID) |
| 705 config.never_translate_min_count = 1; | 754 config.never_translate_min_count = 1; |
| 706 #else | 755 #else |
| 707 config.never_translate_min_count = 3; | 756 config.never_translate_min_count = 3; |
| 708 #endif // defined(OS_ANDROID) | 757 #endif // defined(OS_ANDROID) |
| 709 | 758 |
| 710 config.always_translate_min_count = 3; | 759 config.always_translate_min_count = 3; |
| 711 return config; | 760 return config; |
| 712 } | 761 } |
| OLD | NEW |