| 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/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
| 12 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 15 #include "chrome/browser/chrome_notification_types.h" | |
| 16 #include "chrome/browser/translate/translate_tab_helper.h" | 15 #include "chrome/browser/translate/translate_tab_helper.h" |
| 17 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
| 18 #include "chrome/browser/ui/browser_finder.h" | 17 #include "chrome/browser/ui/browser_finder.h" |
| 19 #include "chrome/browser/ui/browser_tabstrip.h" | 18 #include "chrome/browser/ui/browser_tabstrip.h" |
| 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 19 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 21 #include "chrome/common/url_constants.h" | 20 #include "chrome/common/url_constants.h" |
| 22 #include "components/translate/content/common/translate_messages.h" | 21 #include "components/translate/content/common/translate_messages.h" |
| 23 #include "components/translate/core/browser/language_state.h" | 22 #include "components/translate/core/browser/language_state.h" |
| 24 #include "components/translate/core/browser/page_translated_details.h" | 23 #include "components/translate/core/browser/page_translated_details.h" |
| 25 #include "components/translate/core/browser/translate_accept_languages.h" | 24 #include "components/translate/core/browser/translate_accept_languages.h" |
| 26 #include "components/translate/core/browser/translate_browser_metrics.h" | 25 #include "components/translate/core/browser/translate_browser_metrics.h" |
| 27 #include "components/translate/core/browser/translate_client.h" | 26 #include "components/translate/core/browser/translate_client.h" |
| 28 #include "components/translate/core/browser/translate_download_manager.h" | 27 #include "components/translate/core/browser/translate_download_manager.h" |
| 29 #include "components/translate/core/browser/translate_driver.h" | 28 #include "components/translate/core/browser/translate_driver.h" |
| 30 #include "components/translate/core/browser/translate_error_details.h" | 29 #include "components/translate/core/browser/translate_error_details.h" |
| 31 #include "components/translate/core/browser/translate_language_list.h" | 30 #include "components/translate/core/browser/translate_language_list.h" |
| 32 #include "components/translate/core/browser/translate_prefs.h" | 31 #include "components/translate/core/browser/translate_prefs.h" |
| 33 #include "components/translate/core/browser/translate_script.h" | 32 #include "components/translate/core/browser/translate_script.h" |
| 34 #include "components/translate/core/browser/translate_url_util.h" | 33 #include "components/translate/core/browser/translate_url_util.h" |
| 35 #include "components/translate/core/common/language_detection_details.h" | 34 #include "components/translate/core/common/language_detection_details.h" |
| 36 #include "components/translate/core/common/translate_constants.h" | 35 #include "components/translate/core/common/translate_constants.h" |
| 37 #include "components/translate/core/common/translate_pref_names.h" | 36 #include "components/translate/core/common/translate_pref_names.h" |
| 38 #include "components/translate/core/common/translate_switches.h" | 37 #include "components/translate/core/common/translate_switches.h" |
| 39 #include "content/public/browser/navigation_controller.h" | 38 #include "content/public/browser/navigation_controller.h" |
| 40 #include "content/public/browser/navigation_details.h" | |
| 41 #include "content/public/browser/navigation_entry.h" | 39 #include "content/public/browser/navigation_entry.h" |
| 42 #include "content/public/browser/notification_details.h" | |
| 43 #include "content/public/browser/notification_service.h" | |
| 44 #include "content/public/browser/notification_source.h" | |
| 45 #include "content/public/browser/notification_types.h" | |
| 46 #include "content/public/browser/render_process_host.h" | 40 #include "content/public/browser/render_process_host.h" |
| 47 #include "content/public/browser/render_view_host.h" | 41 #include "content/public/browser/render_view_host.h" |
| 48 #include "content/public/browser/web_contents.h" | 42 #include "content/public/browser/web_contents.h" |
| 49 #include "net/base/url_util.h" | 43 #include "net/base/url_util.h" |
| 50 #include "net/http/http_status_code.h" | 44 #include "net/http/http_status_code.h" |
| 51 | 45 |
| 52 #if defined(OS_CHROMEOS) | 46 #if defined(OS_CHROMEOS) |
| 53 #include "chrome/browser/chromeos/file_manager/app_id.h" | 47 #include "chrome/browser/chromeos/file_manager/app_id.h" |
| 54 #include "extensions/common/constants.h" | 48 #include "extensions/common/constants.h" |
| 55 #endif | 49 #endif |
| (...skipping 10 matching lines...) Expand all Loading... |
| 66 const char kReportLanguageDetectionErrorURL[] = | 60 const char kReportLanguageDetectionErrorURL[] = |
| 67 "https://translate.google.com/translate_error?client=cr&action=langidc"; | 61 "https://translate.google.com/translate_error?client=cr&action=langidc"; |
| 68 | 62 |
| 69 // Used in kReportLanguageDetectionErrorURL to specify the original page | 63 // Used in kReportLanguageDetectionErrorURL to specify the original page |
| 70 // language. | 64 // language. |
| 71 const char kSourceLanguageQueryName[] = "sl"; | 65 const char kSourceLanguageQueryName[] = "sl"; |
| 72 | 66 |
| 73 // Used in kReportLanguageDetectionErrorURL to specify the page URL. | 67 // Used in kReportLanguageDetectionErrorURL to specify the page URL. |
| 74 const char kUrlQueryName[] = "u"; | 68 const char kUrlQueryName[] = "u"; |
| 75 | 69 |
| 76 // The maximum number of attempts we'll do to see if the page has finshed | |
| 77 // loading before giving up the translation | |
| 78 const int kMaxTranslateLoadCheckAttempts = 20; | |
| 79 | |
| 80 // Notifies |g_callback_list_| of translate errors. | 70 // Notifies |g_callback_list_| of translate errors. |
| 81 void NotifyTranslateError(const TranslateErrorDetails& details) { | 71 void NotifyTranslateError(const TranslateErrorDetails& details) { |
| 82 if (!g_callback_list_) | 72 if (!g_callback_list_) |
| 83 return; | 73 return; |
| 84 | 74 |
| 85 g_callback_list_->Notify(details); | 75 g_callback_list_->Notify(details); |
| 86 } | 76 } |
| 87 | 77 |
| 88 } // namespace | 78 } // namespace |
| 89 | 79 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 101 return !url.is_empty() && | 91 return !url.is_empty() && |
| 102 !url.SchemeIs(content::kChromeUIScheme) && | 92 !url.SchemeIs(content::kChromeUIScheme) && |
| 103 !url.SchemeIs(content::kChromeDevToolsScheme) && | 93 !url.SchemeIs(content::kChromeDevToolsScheme) && |
| 104 #if defined(OS_CHROMEOS) | 94 #if defined(OS_CHROMEOS) |
| 105 !(url.SchemeIs(extensions::kExtensionScheme) && | 95 !(url.SchemeIs(extensions::kExtensionScheme) && |
| 106 url.DomainIs(file_manager::kFileManagerAppId)) && | 96 url.DomainIs(file_manager::kFileManagerAppId)) && |
| 107 #endif | 97 #endif |
| 108 !url.SchemeIs(content::kFtpScheme); | 98 !url.SchemeIs(content::kFtpScheme); |
| 109 } | 99 } |
| 110 | 100 |
| 111 void TranslateManager::Observe(int type, | |
| 112 const content::NotificationSource& source, | |
| 113 const content::NotificationDetails& details) { | |
| 114 switch (type) { | |
| 115 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { | |
| 116 NavigationController* controller = | |
| 117 content::Source<NavigationController>(source).ptr(); | |
| 118 DCHECK_EQ(&translate_tab_helper_->GetWebContents()->GetController(), | |
| 119 controller); | |
| 120 content::LoadCommittedDetails* load_details = | |
| 121 content::Details<content::LoadCommittedDetails>(details).ptr(); | |
| 122 NavigationEntry* entry = controller->GetActiveEntry(); | |
| 123 if (!entry) { | |
| 124 NOTREACHED(); | |
| 125 return; | |
| 126 } | |
| 127 | |
| 128 if (!translate_tab_helper_->GetWebContents()) | |
| 129 return; | |
| 130 | |
| 131 // If the navigation happened while offline don't show the translate | |
| 132 // bar since there will be nothing to translate. | |
| 133 if (load_details->http_status_code == 0 || | |
| 134 load_details->http_status_code == net::HTTP_INTERNAL_SERVER_ERROR) { | |
| 135 return; | |
| 136 } | |
| 137 | |
| 138 if (!load_details->is_main_frame && | |
| 139 translate_driver_->GetLanguageState().translation_declined()) { | |
| 140 // Some sites (such as Google map) may trigger sub-frame navigations | |
| 141 // when the user interacts with the page. We don't want to show a new | |
| 142 // infobar if the user already dismissed one in that case. | |
| 143 return; | |
| 144 } | |
| 145 if (entry->GetTransitionType() != content::PAGE_TRANSITION_RELOAD && | |
| 146 load_details->type != content::NAVIGATION_TYPE_SAME_PAGE) { | |
| 147 return; | |
| 148 } | |
| 149 | |
| 150 // When doing a page reload, TAB_LANGUAGE_DETERMINED is not sent, | |
| 151 // so the translation needs to be explicitly initiated, but only when the | |
| 152 // page needs translation. | |
| 153 if (!translate_driver_->GetLanguageState().page_needs_translation()) | |
| 154 return; | |
| 155 // Note that we delay it as the TranslateManager gets this notification | |
| 156 // before the WebContents and the WebContents processing might remove the | |
| 157 // current infobars. Since InitTranslation might add an infobar, it must | |
| 158 // be done after that. | |
| 159 base::MessageLoop::current()->PostTask( | |
| 160 FROM_HERE, | |
| 161 base::Bind( | |
| 162 &TranslateManager::InitiateTranslationPosted, | |
| 163 weak_method_factory_.GetWeakPtr(), | |
| 164 translate_driver_->GetLanguageState().original_language(), | |
| 165 0)); | |
| 166 break; | |
| 167 } | |
| 168 default: | |
| 169 NOTREACHED(); | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 // static | 101 // static |
| 174 scoped_ptr<TranslateManager::TranslateErrorCallbackList::Subscription> | 102 scoped_ptr<TranslateManager::TranslateErrorCallbackList::Subscription> |
| 175 TranslateManager::RegisterTranslateErrorCallback( | 103 TranslateManager::RegisterTranslateErrorCallback( |
| 176 const TranslateManager::TranslateErrorCallback& callback) { | 104 const TranslateManager::TranslateErrorCallback& callback) { |
| 177 if (!g_callback_list_) | 105 if (!g_callback_list_) |
| 178 g_callback_list_ = new TranslateErrorCallbackList; | 106 g_callback_list_ = new TranslateErrorCallbackList; |
| 179 return g_callback_list_->Add(callback); | 107 return g_callback_list_->Add(callback); |
| 180 } | 108 } |
| 181 | 109 |
| 182 TranslateManager::TranslateManager( | 110 TranslateManager::TranslateManager( |
| 183 TranslateTabHelper* helper, | 111 TranslateTabHelper* helper, |
| 184 const std::string& accept_languages_pref_name) | 112 const std::string& accept_languages_pref_name) |
| 185 : max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts), | 113 : accept_languages_pref_name_(accept_languages_pref_name), |
| 186 accept_languages_pref_name_(accept_languages_pref_name), | |
| 187 translate_tab_helper_(helper), | 114 translate_tab_helper_(helper), |
| 188 translate_client_(helper), | 115 translate_client_(helper), |
| 189 translate_driver_(translate_client_->GetTranslateDriver()), | 116 translate_driver_(translate_client_->GetTranslateDriver()), |
| 190 weak_method_factory_(this) { | 117 weak_method_factory_(this) {} |
| 191 | |
| 192 WebContents* web_contents = translate_tab_helper_->GetWebContents(); | |
| 193 | |
| 194 notification_registrar_.Add( | |
| 195 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | |
| 196 content::Source<NavigationController>(&web_contents->GetController())); | |
| 197 } | |
| 198 | 118 |
| 199 void TranslateManager::InitiateTranslation(const std::string& page_lang) { | 119 void TranslateManager::InitiateTranslation(const std::string& page_lang) { |
| 200 // Short-circuit out if not in a state where initiating translation makes | 120 // Short-circuit out if not in a state where initiating translation makes |
| 201 // sense. | 121 // sense. |
| 202 LanguageState& language_state = translate_driver_->GetLanguageState(); | 122 LanguageState& language_state = translate_driver_->GetLanguageState(); |
| 203 if (!language_state.page_needs_translation() || | 123 if (!language_state.page_needs_translation() || |
| 204 language_state.translation_pending() || | 124 language_state.translation_pending() || |
| 205 language_state.translation_declined() || | 125 language_state.translation_declined() || |
| 206 language_state.IsPageTranslated()) { | 126 language_state.IsPageTranslated()) { |
| 207 return; | 127 return; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); | 238 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); |
| 319 | 239 |
| 320 // Prompts the user if he/she wants the page translated. | 240 // Prompts the user if he/she wants the page translated. |
| 321 translate_tab_helper_->ShowTranslateUI(TranslateTabHelper::BEFORE_TRANSLATE, | 241 translate_tab_helper_->ShowTranslateUI(TranslateTabHelper::BEFORE_TRANSLATE, |
| 322 language_code, | 242 language_code, |
| 323 target_lang, | 243 target_lang, |
| 324 TranslateErrors::NONE, | 244 TranslateErrors::NONE, |
| 325 false); | 245 false); |
| 326 } | 246 } |
| 327 | 247 |
| 328 void TranslateManager::InitiateTranslationPosted(const std::string& page_lang, | |
| 329 int attempt) { | |
| 330 WebContents* web_contents = translate_tab_helper_->GetWebContents(); | |
| 331 DCHECK(web_contents); | |
| 332 | |
| 333 if (translate_driver_->GetLanguageState().translation_pending()) | |
| 334 return; | |
| 335 | |
| 336 // During a reload we need web content to be available before the | |
| 337 // translate script is executed. Otherwise we will run the translate script on | |
| 338 // an empty DOM which will fail. Therefore we wait a bit to see if the page | |
| 339 // has finished. | |
| 340 if ((web_contents->IsLoading()) && attempt < kMaxTranslateLoadCheckAttempts) { | |
| 341 int backoff = attempt * max_reload_check_attempts_; | |
| 342 base::MessageLoop::current()->PostDelayedTask( | |
| 343 FROM_HERE, base::Bind(&TranslateManager::InitiateTranslationPosted, | |
| 344 weak_method_factory_.GetWeakPtr(), | |
| 345 page_lang, ++attempt), | |
| 346 base::TimeDelta::FromMilliseconds(backoff)); | |
| 347 return; | |
| 348 } | |
| 349 | |
| 350 InitiateTranslation(TranslateDownloadManager::GetLanguageCode(page_lang)); | |
| 351 } | |
| 352 | |
| 353 void TranslateManager::TranslatePage(const std::string& original_source_lang, | 248 void TranslateManager::TranslatePage(const std::string& original_source_lang, |
| 354 const std::string& target_lang, | 249 const std::string& target_lang, |
| 355 bool triggered_from_menu) { | 250 bool triggered_from_menu) { |
| 356 WebContents* web_contents = translate_tab_helper_->GetWebContents(); | 251 WebContents* web_contents = translate_tab_helper_->GetWebContents(); |
| 357 DCHECK(web_contents); | 252 DCHECK(web_contents); |
| 358 NavigationEntry* entry = web_contents->GetController().GetActiveEntry(); | 253 NavigationEntry* entry = web_contents->GetController().GetActiveEntry(); |
| 359 if (!entry) { | 254 if (!entry) { |
| 360 NOTREACHED(); | 255 NOTREACHED(); |
| 361 return; | 256 return; |
| 362 } | 257 } |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 &auto_target_lang)) { | 450 &auto_target_lang)) { |
| 556 // We need to confirm that the saved target language is still supported. | 451 // We need to confirm that the saved target language is still supported. |
| 557 // Also, GetLanguageCode will take care of removing country code if any. | 452 // Also, GetLanguageCode will take care of removing country code if any. |
| 558 auto_target_lang = | 453 auto_target_lang = |
| 559 TranslateDownloadManager::GetLanguageCode(auto_target_lang); | 454 TranslateDownloadManager::GetLanguageCode(auto_target_lang); |
| 560 if (TranslateDownloadManager::IsSupportedLanguage(auto_target_lang)) | 455 if (TranslateDownloadManager::IsSupportedLanguage(auto_target_lang)) |
| 561 return auto_target_lang; | 456 return auto_target_lang; |
| 562 } | 457 } |
| 563 return std::string(); | 458 return std::string(); |
| 564 } | 459 } |
| OLD | NEW |