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 |