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

Side by Side Diff: chrome/browser/translate/translate_manager.cc

Issue 15317007: Translate: split supporting language list handling to TranslateLanguageList (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: for review Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
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/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/json/json_reader.h"
11 #include "base/memory/singleton.h" 10 #include "base/memory/singleton.h"
12 #include "base/message_loop.h" 11 #include "base/message_loop.h"
13 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
14 #include "base/prefs/pref_service.h" 13 #include "base/prefs/pref_service.h"
15 #include "base/string_util.h" 14 #include "base/string_util.h"
16 #include "base/stringprintf.h" 15 #include "base/stringprintf.h"
17 #include "base/strings/string_split.h" 16 #include "base/strings/string_split.h"
18 #include "base/values.h"
19 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/infobars/infobar_service.h" 18 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/tab_contents/language_state.h" 20 #include "chrome/browser/tab_contents/language_state.h"
23 #include "chrome/browser/tab_contents/tab_util.h" 21 #include "chrome/browser/tab_contents/tab_util.h"
24 #include "chrome/browser/translate/page_translated_details.h" 22 #include "chrome/browser/translate/page_translated_details.h"
25 #include "chrome/browser/translate/translate_infobar_delegate.h" 23 #include "chrome/browser/translate/translate_infobar_delegate.h"
24 #include "chrome/browser/translate/translate_language_list.h"
26 #include "chrome/browser/translate/translate_manager_metrics.h" 25 #include "chrome/browser/translate/translate_manager_metrics.h"
27 #include "chrome/browser/translate/translate_prefs.h" 26 #include "chrome/browser/translate/translate_prefs.h"
28 #include "chrome/browser/translate/translate_tab_helper.h" 27 #include "chrome/browser/translate/translate_tab_helper.h"
28 #include "chrome/browser/translate/translate_url_util.h"
29 #include "chrome/browser/ui/browser.h" 29 #include "chrome/browser/ui/browser.h"
30 #include "chrome/browser/ui/browser_finder.h" 30 #include "chrome/browser/ui/browser_finder.h"
31 #include "chrome/browser/ui/browser_tabstrip.h" 31 #include "chrome/browser/ui/browser_tabstrip.h"
32 #include "chrome/browser/ui/tabs/tab_strip_model.h" 32 #include "chrome/browser/ui/tabs/tab_strip_model.h"
33 #include "chrome/common/chrome_notification_types.h" 33 #include "chrome/common/chrome_notification_types.h"
34 #include "chrome/common/chrome_switches.h" 34 #include "chrome/common/chrome_switches.h"
35 #include "chrome/common/pref_names.h" 35 #include "chrome/common/pref_names.h"
36 #include "chrome/common/render_messages.h" 36 #include "chrome/common/render_messages.h"
37 #include "chrome/common/translate_errors.h" 37 #include "chrome/common/translate_errors.h"
38 #include "chrome/common/url_constants.h" 38 #include "chrome/common/url_constants.h"
(...skipping 21 matching lines...) Expand all
60 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h" 60 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
61 #include "extensions/common/constants.h" 61 #include "extensions/common/constants.h"
62 #endif 62 #endif
63 63
64 using content::NavigationController; 64 using content::NavigationController;
65 using content::NavigationEntry; 65 using content::NavigationEntry;
66 using content::WebContents; 66 using content::WebContents;
67 67
68 namespace { 68 namespace {
69 69
70 // The default list of languages the Google translation server supports.
71 // We use this list until we receive the list that the server exposes.
72 // For information, here is the list of languages that Chrome can be run in
73 // but that the translation server does not support:
74 // am Amharic
75 // bn Bengali
76 // gu Gujarati
77 // kn Kannada
78 // ml Malayalam
79 // mr Marathi
80 // ta Tamil
81 // te Telugu
82 const char* const kDefaultSupportedLanguages[] = {
83 "af", // Afrikaans
84 "sq", // Albanian
85 "ar", // Arabic
86 "be", // Belarusian
87 "bg", // Bulgarian
88 "ca", // Catalan
89 "zh-CN", // Chinese (Simplified)
90 "zh-TW", // Chinese (Traditional)
91 "hr", // Croatian
92 "cs", // Czech
93 "da", // Danish
94 "nl", // Dutch
95 "en", // English
96 "eo", // Esperanto
97 "et", // Estonian
98 "tl", // Filipino
99 "fi", // Finnish
100 "fr", // French
101 "gl", // Galician
102 "de", // German
103 "el", // Greek
104 "ht", // Haitian Creole
105 "iw", // Hebrew
106 "hi", // Hindi
107 "hu", // Hungarian
108 "is", // Icelandic
109 "id", // Indonesian
110 "ga", // Irish
111 "it", // Italian
112 "ja", // Japanese
113 "ko", // Korean
114 "lv", // Latvian
115 "lt", // Lithuanian
116 "mk", // Macedonian
117 "ms", // Malay
118 "mt", // Maltese
119 "no", // Norwegian
120 "fa", // Persian
121 "pl", // Polish
122 "pt", // Portuguese
123 "ro", // Romanian
124 "ru", // Russian
125 "sr", // Serbian
126 "sk", // Slovak
127 "sl", // Slovenian
128 "es", // Spanish
129 "sw", // Swahili
130 "sv", // Swedish
131 "th", // Thai
132 "tr", // Turkish
133 "uk", // Ukrainian
134 "vi", // Vietnamese
135 "cy", // Welsh
136 "yi", // Yiddish
137 };
138
139 const char kTranslateScriptURL[] = 70 const char kTranslateScriptURL[] =
140 "https://translate.google.com/translate_a/element.js"; 71 "https://translate.google.com/translate_a/element.js";
141 const char kTranslateScriptHeader[] = "Google-Translate-Element-Mode: library"; 72 const char kTranslateScriptHeader[] = "Google-Translate-Element-Mode: library";
142 const char kReportLanguageDetectionErrorURL[] = 73 const char kReportLanguageDetectionErrorURL[] =
143 "https://translate.google.com/translate_error?client=cr&action=langidc"; 74 "https://translate.google.com/translate_error?client=cr&action=langidc";
144 const char kLanguageListFetchURL[] =
145 "https://translate.googleapis.com/translate_a/l?client=chrome&cb=sl";
146
147 // Used in kTranslateScriptURL to request supporting languages list including
148 // "alpha languages".
149 const char kAlphaLanguageQueryName[] = "alpha";
150 const char kAlphaLanguageQueryValue[] = "1";
151
152 // Used in all translate URLs to specify API Key.
153 const char kApiKeyName[] = "key";
154 75
155 // Used in kTranslateScriptURL to specify a callback function name. 76 // Used in kTranslateScriptURL to specify a callback function name.
156 const char kCallbackQueryName[] = "cb"; 77 const char kCallbackQueryName[] = "cb";
157 const char kCallbackQueryValue[] = 78 const char kCallbackQueryValue[] =
158 "cr.googleTranslate.onTranslateElementLoad"; 79 "cr.googleTranslate.onTranslateElementLoad";
159 80
160 // Used in kTranslateScriptURL and kLanguageListFetchURL to specify the
161 // application locale.
162 const char kHostLocaleQueryName[] = "hl";
163
164 // Used in kReportLanguageDetectionErrorURL to specify the original page 81 // Used in kReportLanguageDetectionErrorURL to specify the original page
165 // language. 82 // language.
166 const char kSourceLanguageQueryName[] = "sl"; 83 const char kSourceLanguageQueryName[] = "sl";
167 84
168 // Used in kReportLanguageDetectionErrorURL to specify the page URL. 85 // Used in kReportLanguageDetectionErrorURL to specify the page URL.
169 const char kUrlQueryName[] = "u"; 86 const char kUrlQueryName[] = "u";
170 87
171 // The delay in ms that we'll wait to check if a page has finished loading 88 // The delay in ms that we'll wait to check if a page has finished loading
172 // before attempting a translation. 89 // before attempting a translation.
173 const int kTranslateLoadCheckDelayMs = 150; 90 const int kTranslateLoadCheckDelayMs = 150;
174 91
175 // The maximum number of attempts we'll do to see if the page has finshed 92 // The maximum number of attempts we'll do to see if the page has finshed
176 // loading before giving up the translation 93 // loading before giving up the translation
177 const int kMaxTranslateLoadCheckAttempts = 20; 94 const int kMaxTranslateLoadCheckAttempts = 20;
178 95
179 const int kMaxRetryLanguageListFetch = 5;
180 const int kTranslateScriptExpirationDelayDays = 1; 96 const int kTranslateScriptExpirationDelayDays = 1;
181 97
182 GURL AddApiKeyToUrl(const GURL& url) {
183 return net::AppendQueryParameter(url, kApiKeyName, google_apis::GetAPIKey());
184 }
185
186 GURL AddHostLocaleToUrl(const GURL& url) {
187 return net::AppendQueryParameter(
188 url,
189 kHostLocaleQueryName,
190 TranslateManager::GetLanguageCode(
191 g_browser_process->GetApplicationLocale()));
192 }
193
194 } // namespace 98 } // namespace
195 99
196 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL.
197 const char TranslateManager::kLanguageListCallbackName[] = "sl(";
198 const char TranslateManager::kTargetLanguagesKey[] = "tl";
199
200 // static
201 base::LazyInstance<std::set<std::string> >
202 TranslateManager::supported_languages_ = LAZY_INSTANCE_INITIALIZER;
203
204 TranslateManager::~TranslateManager() { 100 TranslateManager::~TranslateManager() {
205 weak_method_factory_.InvalidateWeakPtrs(); 101 weak_method_factory_.InvalidateWeakPtrs();
206 } 102 }
207 103
208 // static 104 // static
209 TranslateManager* TranslateManager::GetInstance() { 105 TranslateManager* TranslateManager::GetInstance() {
210 return Singleton<TranslateManager>::get(); 106 return Singleton<TranslateManager>::get();
211 } 107 }
212 108
213 // static 109 // static
214 bool TranslateManager::IsTranslatableURL(const GURL& url) { 110 bool TranslateManager::IsTranslatableURL(const GURL& url) {
215 // A URLs is translatable unless it is one of the following: 111 // A URLs is translatable unless it is one of the following:
216 // - empty (can happen for popups created with window.open("")) 112 // - empty (can happen for popups created with window.open(""))
217 // - an internal URL (chrome:// and others) 113 // - an internal URL (chrome:// and others)
218 // - the devtools (which is considered UI) 114 // - the devtools (which is considered UI)
219 // - Chrome OS file manager extension 115 // - Chrome OS file manager extension
220 // - an FTP page (as FTP pages tend to have long lists of filenames that may 116 // - an FTP page (as FTP pages tend to have long lists of filenames that may
221 // confuse the CLD) 117 // confuse the CLD)
222 return !url.is_empty() && 118 return !url.is_empty() &&
223 !url.SchemeIs(chrome::kChromeUIScheme) && 119 !url.SchemeIs(chrome::kChromeUIScheme) &&
224 !url.SchemeIs(chrome::kChromeDevToolsScheme) && 120 !url.SchemeIs(chrome::kChromeDevToolsScheme) &&
225 #ifdef FILE_MANAGER_EXTENSION 121 #ifdef FILE_MANAGER_EXTENSION
226 !(url.SchemeIs(extensions::kExtensionScheme) && 122 !(url.SchemeIs(extensions::kExtensionScheme) &&
227 url.DomainIs(kFileBrowserDomain)) && 123 url.DomainIs(kFileBrowserDomain)) &&
228 #endif 124 #endif
229 !url.SchemeIs(chrome::kFtpScheme); 125 !url.SchemeIs(chrome::kFtpScheme);
230 } 126 }
231 127
232 // static
233 void TranslateManager::SetSupportedLanguages(const std::string& language_list) {
234 // The format is:
235 // sl({"sl": {"XX": "LanguageName", ...}, "tl": {"XX": "LanguageName", ...}})
236 // Where "sl(" is set in kLanguageListCallbackName
237 // and "tl" is kTargetLanguagesKey
238 if (!StartsWithASCII(language_list, kLanguageListCallbackName, false) ||
239 !EndsWith(language_list, ")", false)) {
240 // We don't have a NOTREACHED here since this can happen in ui_tests, even
241 // though the the BrowserMain function won't call us with parameters.ui_task
242 // is NULL some tests don't set it, so we must bail here.
243 return;
244 }
245 static const size_t kLanguageListCallbackNameLength =
246 strlen(kLanguageListCallbackName);
247 std::string languages_json = language_list.substr(
248 kLanguageListCallbackNameLength,
249 language_list.size() - kLanguageListCallbackNameLength - 1);
250 scoped_ptr<Value> json_value(
251 base::JSONReader::Read(languages_json, base::JSON_ALLOW_TRAILING_COMMAS));
252 if (json_value == NULL || !json_value->IsType(Value::TYPE_DICTIONARY)) {
253 NOTREACHED();
254 return;
255 }
256 // The first level dictionary contains two sub-dict, one for source languages
257 // and the other for target languages, we want to use the target languages.
258 DictionaryValue* language_dict =
259 static_cast<DictionaryValue*>(json_value.get());
260 DictionaryValue* target_languages = NULL;
261 if (!language_dict->GetDictionary(kTargetLanguagesKey, &target_languages) ||
262 target_languages == NULL) {
263 NOTREACHED();
264 return;
265 }
266 // Now we can clear our current state...
267 std::set<std::string>* supported_languages = supported_languages_.Pointer();
268 supported_languages->clear();
269 // ... and replace it with the values we just fetched from the server.
270 for (DictionaryValue::Iterator iter(*target_languages); !iter.IsAtEnd();
271 iter.Advance()) {
272 supported_languages_.Pointer()->insert(iter.key());
273 }
274 }
275
276 // static
277 void TranslateManager::InitSupportedLanguages() {
278 // If our list of supported languages have not been set yet, we default
279 // to our hard coded list of languages in kDefaultSupportedLanguages.
280 if (supported_languages_.Pointer()->empty()) {
281 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i)
282 supported_languages_.Pointer()->insert(kDefaultSupportedLanguages[i]);
283 }
284 }
285
286 // static
287 void TranslateManager::GetSupportedLanguages(
288 std::vector<std::string>* languages) {
289 DCHECK(languages && languages->empty());
290 InitSupportedLanguages();
291 std::set<std::string>* supported_languages = supported_languages_.Pointer();
292 std::set<std::string>::const_iterator iter = supported_languages->begin();
293 for (; iter != supported_languages->end(); ++iter)
294 languages->push_back(*iter);
295 }
296
297 // static
298 std::string TranslateManager::GetLanguageCode(
299 const std::string& chrome_locale) {
300 // Only remove the country code for country specific languages we don't
301 // support specifically yet.
302 if (IsSupportedLanguage(chrome_locale))
303 return chrome_locale;
304
305 size_t hypen_index = chrome_locale.find('-');
306 if (hypen_index == std::string::npos)
307 return chrome_locale;
308 return chrome_locale.substr(0, hypen_index);
309 }
310
311 // static
312 bool TranslateManager::IsSupportedLanguage(const std::string& page_language) {
313 InitSupportedLanguages();
314 return supported_languages_.Pointer()->count(page_language) != 0;
315 }
316
317 void TranslateManager::Observe(int type, 128 void TranslateManager::Observe(int type,
318 const content::NotificationSource& source, 129 const content::NotificationSource& source,
319 const content::NotificationDetails& details) { 130 const content::NotificationDetails& details) {
320 switch (type) { 131 switch (type) {
321 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { 132 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
322 NavigationController* controller = 133 NavigationController* controller =
323 content::Source<NavigationController>(source).ptr(); 134 content::Source<NavigationController>(source).ptr();
324 content::LoadCommittedDetails* load_details = 135 content::LoadCommittedDetails* load_details =
325 content::Details<content::LoadCommittedDetails>(details).ptr(); 136 content::Details<content::LoadCommittedDetails>(details).ptr();
326 NavigationEntry* entry = controller->GetActiveEntry(); 137 NavigationEntry* entry = controller->GetActiveEntry();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 DCHECK(count == 1u); 227 DCHECK(count == 1u);
417 delete pref_change_registrar; 228 delete pref_change_registrar;
418 break; 229 break;
419 } 230 }
420 default: 231 default:
421 NOTREACHED(); 232 NOTREACHED();
422 } 233 }
423 } 234 }
424 235
425 void TranslateManager::OnURLFetchComplete(const net::URLFetcher* source) { 236 void TranslateManager::OnURLFetchComplete(const net::URLFetcher* source) {
426 if (translate_script_request_pending_.get() != source && 237 if (translate_script_request_pending_.get() != source) {
427 language_list_request_pending_.get() != source) {
428 // Looks like crash on Mac is possibly caused with callback entering here 238 // Looks like crash on Mac is possibly caused with callback entering here
429 // with unknown fetcher when network is refreshed. 239 // with unknown fetcher when network is refreshed.
430 scoped_ptr<const net::URLFetcher> delete_ptr(source); 240 scoped_ptr<const net::URLFetcher> delete_ptr(source);
431 return; 241 return;
432 } 242 }
433 243
434 bool error = 244 bool error =
435 (source->GetStatus().status() != net::URLRequestStatus::SUCCESS || 245 source->GetStatus().status() != net::URLRequestStatus::SUCCESS ||
436 source->GetResponseCode() != net::HTTP_OK); 246 source->GetResponseCode() != net::HTTP_OK;
437 if (translate_script_request_pending_.get() == source) { 247 if (translate_script_request_pending_.get() == source) {
438 scoped_ptr<const net::URLFetcher> delete_ptr( 248 scoped_ptr<const net::URLFetcher> delete_ptr(
439 translate_script_request_pending_.release()); 249 translate_script_request_pending_.release());
440 if (!error) { 250 if (!error) {
441 base::StringPiece str = ResourceBundle::GetSharedInstance(). 251 base::StringPiece str = ResourceBundle::GetSharedInstance().
442 GetRawDataResource(IDR_TRANSLATE_JS); 252 GetRawDataResource(IDR_TRANSLATE_JS);
443 DCHECK(translate_script_.empty()); 253 DCHECK(translate_script_.empty());
444 str.CopyToString(&translate_script_); 254 str.CopyToString(&translate_script_);
445 std::string argument = "('"; 255 std::string argument = "('";
446 std::string api_key = google_apis::GetAPIKey(); 256 std::string api_key = google_apis::GetAPIKey();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 ShortcutConfig(), 298 ShortcutConfig(),
489 request.source_lang, 299 request.source_lang,
490 request.target_lang); 300 request.target_lang);
491 } else { 301 } else {
492 // Translate the page. 302 // Translate the page.
493 DoTranslatePage(web_contents, translate_script_, 303 DoTranslatePage(web_contents, translate_script_,
494 request.source_lang, request.target_lang); 304 request.source_lang, request.target_lang);
495 } 305 }
496 } 306 }
497 pending_requests_.clear(); 307 pending_requests_.clear();
498 } else { // if (translate_script_request_pending_.get() == source)
499 scoped_ptr<const net::URLFetcher> delete_ptr(
500 language_list_request_pending_.release());
501 if (!error) {
502 std::string data;
503 source->GetResponseAsString(&data);
504 SetSupportedLanguages(data);
505 } else {
506 VLOG(9) << "Failed to Fetch languages from: " << kLanguageListFetchURL;
507 }
508 } 308 }
509 } 309 }
510 310
511 TranslateManager::TranslateManager() 311 TranslateManager::TranslateManager()
512 : weak_method_factory_(this), 312 : weak_method_factory_(this),
513 translate_script_expiration_delay_(base::TimeDelta::FromDays( 313 translate_script_expiration_delay_(base::TimeDelta::FromDays(
514 kTranslateScriptExpirationDelayDays)), 314 kTranslateScriptExpirationDelayDays)),
515 max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts) { 315 max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts) {
516 notification_registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 316 notification_registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
517 content::NotificationService::AllSources()); 317 content::NotificationService::AllSources());
(...skipping 28 matching lines...) Expand all
546 // History, and so on. 346 // History, and so on.
547 GURL page_url = web_contents->GetURL(); 347 GURL page_url = web_contents->GetURL();
548 if (!IsTranslatableURL(page_url)) { 348 if (!IsTranslatableURL(page_url)) {
549 TranslateManagerMetrics::ReportInitiationStatus( 349 TranslateManagerMetrics::ReportInitiationStatus(
550 TranslateManagerMetrics::INITIATION_STATUS_URL_IS_NOT_SUPPORTED); 350 TranslateManagerMetrics::INITIATION_STATUS_URL_IS_NOT_SUPPORTED);
551 return; 351 return;
552 } 352 }
553 353
554 // Don't translate similar languages (ex: en-US to en). 354 // Don't translate similar languages (ex: en-US to en).
555 std::string target_lang = GetTargetLanguage(prefs); 355 std::string target_lang = GetTargetLanguage(prefs);
556 std::string language_code = GetLanguageCode(page_lang); 356 std::string language_code =
357 TranslateLanguageList::GetLanguageCode(page_lang);
557 if (language_code == target_lang) { 358 if (language_code == target_lang) {
558 TranslateManagerMetrics::ReportInitiationStatus( 359 TranslateManagerMetrics::ReportInitiationStatus(
559 TranslateManagerMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES); 360 TranslateManagerMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES);
560 return; 361 return;
561 } 362 }
562 363
563 // Don't translate any language the user configured as accepted languages. 364 // Don't translate any language the user configured as accepted languages.
564 if (IsAcceptLanguage(web_contents, language_code)) { 365 if (IsAcceptLanguage(web_contents, language_code)) {
565 TranslateManagerMetrics::ReportInitiationStatus( 366 TranslateManagerMetrics::ReportInitiationStatus(
566 TranslateManagerMetrics::INITIATION_STATUS_ACCEPT_LANGUAGES); 367 TranslateManagerMetrics::INITIATION_STATUS_ACCEPT_LANGUAGES);
567 return; 368 return;
568 } 369 }
569 370
570 // Nothing to do if either the language Chrome is in or the language of the 371 // Nothing to do if either the language Chrome is in or the language of the
571 // page is not supported by the translation server. 372 // page is not supported by the translation server.
572 if (target_lang.empty() || !IsSupportedLanguage(language_code)) { 373 if (target_lang.empty() ||
374 !TranslateLanguageList::IsSupportedLanguage(language_code)) {
573 TranslateManagerMetrics::ReportInitiationStatus( 375 TranslateManagerMetrics::ReportInitiationStatus(
574 TranslateManagerMetrics::INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED); 376 TranslateManagerMetrics::INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED);
575 return; 377 return;
576 } 378 }
577 379
578 // Don't translate any user black-listed URLs or user selected language 380 // Don't translate any user black-listed URLs or user selected language
579 // combination. 381 // combination.
580 if (!TranslatePrefs::CanTranslate(prefs, language_code, page_url)) { 382 if (!TranslatePrefs::CanTranslate(prefs, language_code, page_url)) {
581 TranslateManagerMetrics::ReportInitiationStatus( 383 TranslateManagerMetrics::ReportInitiationStatus(
582 TranslateManagerMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG); 384 TranslateManagerMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG);
583 return; 385 return;
584 } 386 }
585 387
586 // If the user has previously selected "always translate" for this language we 388 // If the user has previously selected "always translate" for this language we
587 // automatically translate. Note that in incognito mode we disable that 389 // automatically translate. Note that in incognito mode we disable that
588 // feature; the user will get an infobar, so they can control whether the 390 // feature; the user will get an infobar, so they can control whether the
589 // page's text is sent to the translate server. 391 // page's text is sent to the translate server.
590 std::string auto_target_lang; 392 std::string auto_target_lang;
591 if (!web_contents->GetBrowserContext()->IsOffTheRecord() && 393 if (!web_contents->GetBrowserContext()->IsOffTheRecord() &&
592 TranslatePrefs::ShouldAutoTranslate(prefs, language_code, 394 TranslatePrefs::ShouldAutoTranslate(prefs, language_code,
593 &auto_target_lang)) { 395 &auto_target_lang)) {
594 // We need to confirm that the saved target language is still supported. 396 // We need to confirm that the saved target language is still supported.
595 // Also, GetLanguageCode will take care of removing country code if any. 397 // Also, GetLanguageCode will take care of removing country code if any.
596 auto_target_lang = GetLanguageCode(auto_target_lang); 398 auto_target_lang = TranslateLanguageList::GetLanguageCode(auto_target_lang);
597 if (IsSupportedLanguage(auto_target_lang)) { 399 if (TranslateLanguageList::IsSupportedLanguage(auto_target_lang)) {
598 TranslateManagerMetrics::ReportInitiationStatus( 400 TranslateManagerMetrics::ReportInitiationStatus(
599 TranslateManagerMetrics::INITIATION_STATUS_AUTO_BY_CONFIG); 401 TranslateManagerMetrics::INITIATION_STATUS_AUTO_BY_CONFIG);
600 TranslatePage(web_contents, language_code, auto_target_lang); 402 TranslatePage(web_contents, language_code, auto_target_lang);
601 return; 403 return;
602 } 404 }
603 } 405 }
604 406
605 TranslateTabHelper* translate_tab_helper = 407 TranslateTabHelper* translate_tab_helper =
606 TranslateTabHelper::FromWebContents(web_contents); 408 TranslateTabHelper::FromWebContents(web_contents);
607 if (!translate_tab_helper) 409 if (!translate_tab_helper)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 if ((web_contents->IsLoading()) && attempt < kMaxTranslateLoadCheckAttempts) { 449 if ((web_contents->IsLoading()) && attempt < kMaxTranslateLoadCheckAttempts) {
648 int backoff = attempt * max_reload_check_attempts_; 450 int backoff = attempt * max_reload_check_attempts_;
649 MessageLoop::current()->PostDelayedTask( 451 MessageLoop::current()->PostDelayedTask(
650 FROM_HERE, base::Bind(&TranslateManager::InitiateTranslationPosted, 452 FROM_HERE, base::Bind(&TranslateManager::InitiateTranslationPosted,
651 weak_method_factory_.GetWeakPtr(), process_id, 453 weak_method_factory_.GetWeakPtr(), process_id,
652 render_id, page_lang, ++attempt), 454 render_id, page_lang, ++attempt),
653 base::TimeDelta::FromMilliseconds(backoff)); 455 base::TimeDelta::FromMilliseconds(backoff));
654 return; 456 return;
655 } 457 }
656 458
657 InitiateTranslation(web_contents, GetLanguageCode(page_lang)); 459 InitiateTranslation(web_contents,
460 TranslateLanguageList::GetLanguageCode(page_lang));
658 } 461 }
659 462
660 void TranslateManager::TranslatePage(WebContents* web_contents, 463 void TranslateManager::TranslatePage(WebContents* web_contents,
661 const std::string& source_lang, 464 const std::string& source_lang,
662 const std::string& target_lang) { 465 const std::string& target_lang) {
663 NavigationEntry* entry = web_contents->GetController().GetActiveEntry(); 466 NavigationEntry* entry = web_contents->GetController().GetActiveEntry();
664 if (!entry) { 467 if (!entry) {
665 NOTREACHED(); 468 NOTREACHED();
666 return; 469 return;
667 } 470 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 kUrlQueryName, 527 kUrlQueryName,
725 page_url.spec()); 528 page_url.spec());
726 529
727 TranslateTabHelper* translate_tab_helper = 530 TranslateTabHelper* translate_tab_helper =
728 TranslateTabHelper::FromWebContents(web_contents); 531 TranslateTabHelper::FromWebContents(web_contents);
729 report_error_url = net::AppendQueryParameter( 532 report_error_url = net::AppendQueryParameter(
730 report_error_url, 533 report_error_url,
731 kSourceLanguageQueryName, 534 kSourceLanguageQueryName,
732 translate_tab_helper->language_state().original_language()); 535 translate_tab_helper->language_state().original_language());
733 536
734 report_error_url = AddHostLocaleToUrl(report_error_url); 537 report_error_url = TranslateURLUtil::AddHostLocaleToUrl(report_error_url);
735 report_error_url = AddApiKeyToUrl(report_error_url); 538 report_error_url = TranslateURLUtil::AddApiKeyToUrl(report_error_url);
736 539
737 chrome::AddSelectedTabWithURL(browser, report_error_url, 540 chrome::AddSelectedTabWithURL(browser, report_error_url,
738 content::PAGE_TRANSITION_AUTO_BOOKMARK); 541 content::PAGE_TRANSITION_AUTO_BOOKMARK);
739 } 542 }
740 543
741 void TranslateManager::DoTranslatePage(WebContents* web_contents, 544 void TranslateManager::DoTranslatePage(WebContents* web_contents,
742 const std::string& translate_script, 545 const std::string& translate_script,
743 const std::string& source_lang, 546 const std::string& source_lang,
744 const std::string& target_lang) { 547 const std::string& target_lang) {
745 NavigationEntry* entry = web_contents->GetController().GetActiveEntry(); 548 NavigationEntry* entry = web_contents->GetController().GetActiveEntry();
746 if (!entry) { 549 if (!entry) {
747 NOTREACHED(); 550 NOTREACHED();
748 return; 551 return;
749 } 552 }
750 553
751 TranslateTabHelper* translate_tab_helper = 554 TranslateTabHelper* translate_tab_helper =
752 TranslateTabHelper::FromWebContents(web_contents); 555 TranslateTabHelper::FromWebContents(web_contents);
753 if (!translate_tab_helper) 556 if (!translate_tab_helper)
754 return; 557 return;
755 558
756 translate_tab_helper->language_state().set_translation_pending(true); 559 translate_tab_helper->language_state().set_translation_pending(true);
757 web_contents->GetRenderViewHost()->Send(new ChromeViewMsg_TranslatePage( 560 web_contents->GetRenderViewHost()->Send(new ChromeViewMsg_TranslatePage(
758 web_contents->GetRenderViewHost()->GetRoutingID(), entry->GetPageID(), 561 web_contents->GetRenderViewHost()->GetRoutingID(), entry->GetPageID(),
759 translate_script, source_lang, target_lang)); 562 translate_script, source_lang, target_lang));
760 } 563 }
761 564
762 void TranslateManager::PageTranslated(WebContents* web_contents, 565 void TranslateManager::PageTranslated(WebContents* web_contents,
763 PageTranslatedDetails* details) { 566 PageTranslatedDetails* details) {
764 if ((details->error_type == TranslateErrors::NONE) && 567 if ((details->error_type == TranslateErrors::NONE) &&
765 !IsSupportedLanguage(details->source_language)) { 568 !TranslateLanguageList::IsSupportedLanguage(details->source_language)) {
766 // TODO(jcivelli): http://crbug.com/9390 We should change the "after 569 // TODO(jcivelli): http://crbug.com/9390 We should change the "after
767 // translate" infobar to support unknown as the original 570 // translate" infobar to support unknown as the original
768 // language. 571 // language.
769 TranslateManagerMetrics::ReportUnsupportedLanguage(); 572 TranslateManagerMetrics::ReportUnsupportedLanguage();
770 details->error_type = TranslateErrors::UNSUPPORTED_LANGUAGE; 573 details->error_type = TranslateErrors::UNSUPPORTED_LANGUAGE;
771 } 574 }
772 Profile* profile = 575 Profile* profile =
773 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 576 Profile::FromBrowserContext(web_contents->GetBrowserContext());
774 PrefService* prefs = profile->GetPrefs(); 577 PrefService* prefs = profile->GetPrefs();
775 TranslateInfoBarDelegate::Create( 578 TranslateInfoBarDelegate::Create(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 return iter->second.count(language) != 0; 616 return iter->second.count(language) != 0;
814 } 617 }
815 618
816 void TranslateManager::InitAcceptLanguages(PrefService* prefs) { 619 void TranslateManager::InitAcceptLanguages(PrefService* prefs) {
817 // We have been asked for this profile, build the languages. 620 // We have been asked for this profile, build the languages.
818 std::string accept_langs_str = prefs->GetString(prefs::kAcceptLanguages); 621 std::string accept_langs_str = prefs->GetString(prefs::kAcceptLanguages);
819 std::vector<std::string> accept_langs_list; 622 std::vector<std::string> accept_langs_list;
820 LanguageSet accept_langs_set; 623 LanguageSet accept_langs_set;
821 base::SplitString(accept_langs_str, ',', &accept_langs_list); 624 base::SplitString(accept_langs_str, ',', &accept_langs_list);
822 std::vector<std::string>::const_iterator iter; 625 std::vector<std::string>::const_iterator iter;
823 std::string ui_lang = 626 std::string ui_lang = TranslateLanguageList::GetLanguageCode(
824 GetLanguageCode(g_browser_process->GetApplicationLocale()); 627 g_browser_process->GetApplicationLocale());
825 bool is_ui_english = StartsWithASCII(ui_lang, "en-", false); 628 bool is_ui_english = StartsWithASCII(ui_lang, "en-", false);
826 for (iter = accept_langs_list.begin(); 629 for (iter = accept_langs_list.begin();
827 iter != accept_langs_list.end(); ++iter) { 630 iter != accept_langs_list.end(); ++iter) {
828 // Get rid of the locale extension if any (ex: en-US -> en), but for Chinese 631 // Get rid of the locale extension if any (ex: en-US -> en), but for Chinese
829 // for which the CLD reports zh-CN and zh-TW. 632 // for which the CLD reports zh-CN and zh-TW.
830 std::string accept_lang(*iter); 633 std::string accept_lang(*iter);
831 size_t index = iter->find("-"); 634 size_t index = iter->find("-");
832 if (index != std::string::npos && *iter != "zh-CN" && *iter != "zh-TW") 635 if (index != std::string::npos && *iter != "zh-CN" && *iter != "zh-TW")
833 accept_lang = iter->substr(0, index); 636 accept_lang = iter->substr(0, index);
834 // Special-case English until we resolve bug 36182 properly. 637 // Special-case English until we resolve bug 36182 properly.
835 // Add English only if the UI language is not English. This will annoy 638 // Add English only if the UI language is not English. This will annoy
836 // users of non-English Chrome who can comprehend English until English is 639 // users of non-English Chrome who can comprehend English until English is
837 // black-listed. 640 // black-listed.
838 // TODO(jungshik): Once we determine that it's safe to remove English from 641 // TODO(jungshik): Once we determine that it's safe to remove English from
839 // the default Accept-Language values for most locales, remove this 642 // the default Accept-Language values for most locales, remove this
840 // special-casing. 643 // special-casing.
841 if (accept_lang != "en" || is_ui_english) 644 if (accept_lang != "en" || is_ui_english)
842 accept_langs_set.insert(accept_lang); 645 accept_langs_set.insert(accept_lang);
843 } 646 }
844 accept_languages_[prefs] = accept_langs_set; 647 accept_languages_[prefs] = accept_langs_set;
845 } 648 }
846 649
847 void TranslateManager::FetchLanguageListFromTranslateServer( 650 void TranslateManager::FetchLanguageListFromTranslateServer(
848 PrefService* prefs) { 651 PrefService* prefs) {
849 if (language_list_request_pending_.get() != NULL) 652 if (TranslateLanguageList::HasPendingRequest())
850 return; 653 return;
851 654
852 // We don't want to do this when translate is disabled. 655 // We don't want to do this when translate is disabled.
853 DCHECK(prefs != NULL); 656 DCHECK(prefs != NULL);
854 if (CommandLine::ForCurrentProcess()->HasSwitch( 657 if (CommandLine::ForCurrentProcess()->HasSwitch(
855 switches::kDisableTranslate) || 658 switches::kDisableTranslate) ||
856 (prefs != NULL && !prefs->GetBoolean(prefs::kEnableTranslate))) { 659 (prefs != NULL && !prefs->GetBoolean(prefs::kEnableTranslate))) {
857 return; 660 return;
858 } 661 }
859 662
860 GURL language_list_fetch_url = GURL(kLanguageListFetchURL); 663 TranslateLanguageList::RequestLanguageList();
861 language_list_fetch_url = AddHostLocaleToUrl(language_list_fetch_url);
862 language_list_fetch_url = AddApiKeyToUrl(language_list_fetch_url);
863
864 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
865 if (command_line.HasSwitch(switches::kEnableTranslateAlphaLanguages)) {
866 language_list_fetch_url = net::AppendQueryParameter(
867 language_list_fetch_url,
868 kAlphaLanguageQueryName,
869 kAlphaLanguageQueryValue);
870 }
871
872 VLOG(9) << "Fetch supporting language list from: "
873 << language_list_fetch_url.spec().c_str();
874
875 language_list_request_pending_.reset(net::URLFetcher::Create(
876 1, language_list_fetch_url, net::URLFetcher::GET, this));
877 language_list_request_pending_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
878 net::LOAD_DO_NOT_SAVE_COOKIES);
879 language_list_request_pending_->SetRequestContext(
880 g_browser_process->system_request_context());
881 language_list_request_pending_->SetMaxRetriesOn5xx(
882 kMaxRetryLanguageListFetch);
883 language_list_request_pending_->Start();
884 } 664 }
885 665
886 void TranslateManager::CleanupPendingUlrFetcher() { 666 void TranslateManager::CleanupPendingUlrFetcher() {
Takashi Toyoshima 2013/05/22 16:00:45 This function is called from browser main thread b
887 language_list_request_pending_.reset(); 667 TranslateLanguageList::ResetPendingRequest();
888 translate_script_request_pending_.reset(); 668 translate_script_request_pending_.reset();
889 } 669 }
890 670
891 void TranslateManager::RequestTranslateScript() { 671 void TranslateManager::RequestTranslateScript() {
892 if (translate_script_request_pending_.get() != NULL) 672 if (translate_script_request_pending_.get() != NULL)
893 return; 673 return;
894 674
895 GURL translate_script_url; 675 GURL translate_script_url;
896 // Check if command-line contains an alternative URL for translate service. 676 // Check if command-line contains an alternative URL for translate service.
897 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 677 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
(...skipping 11 matching lines...) Expand all
909 // Use default URL when command-line argument is not specified, or specified 689 // Use default URL when command-line argument is not specified, or specified
910 // URL is invalid. 690 // URL is invalid.
911 if (translate_script_url.is_empty()) 691 if (translate_script_url.is_empty())
912 translate_script_url = GURL(kTranslateScriptURL); 692 translate_script_url = GURL(kTranslateScriptURL);
913 693
914 translate_script_url = net::AppendQueryParameter( 694 translate_script_url = net::AppendQueryParameter(
915 translate_script_url, 695 translate_script_url,
916 kCallbackQueryName, 696 kCallbackQueryName,
917 kCallbackQueryValue); 697 kCallbackQueryValue);
918 698
919 translate_script_url = AddHostLocaleToUrl(translate_script_url); 699 translate_script_url =
920 translate_script_url = AddApiKeyToUrl(translate_script_url); 700 TranslateURLUtil::AddHostLocaleToUrl(translate_script_url);
701 translate_script_url =
702 TranslateURLUtil::AddApiKeyToUrl(translate_script_url);
921 703
922 translate_script_request_pending_.reset(net::URLFetcher::Create( 704 translate_script_request_pending_.reset(net::URLFetcher::Create(
923 0, translate_script_url, net::URLFetcher::GET, this)); 705 0, translate_script_url, net::URLFetcher::GET, this));
924 translate_script_request_pending_->SetLoadFlags( 706 translate_script_request_pending_->SetLoadFlags(
925 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); 707 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
926 translate_script_request_pending_->SetRequestContext( 708 translate_script_request_pending_->SetRequestContext(
927 g_browser_process->system_request_context()); 709 g_browser_process->system_request_context());
928 translate_script_request_pending_->SetExtraRequestHeaders( 710 translate_script_request_pending_->SetExtraRequestHeaders(
929 kTranslateScriptHeader); 711 kTranslateScriptHeader);
930 translate_script_request_pending_->Start(); 712 translate_script_request_pending_->Start();
931 } 713 }
932 714
933 // static 715 // static
934 std::string TranslateManager::GetTargetLanguage(PrefService* prefs) { 716 std::string TranslateManager::GetTargetLanguage(PrefService* prefs) {
935 std::string ui_lang = 717 std::string ui_lang = TranslateLanguageList::GetLanguageCode(
936 GetLanguageCode(g_browser_process->GetApplicationLocale()); 718 g_browser_process->GetApplicationLocale());
937 if (IsSupportedLanguage(ui_lang)) 719 if (TranslateLanguageList::IsSupportedLanguage(ui_lang))
938 return ui_lang; 720 return ui_lang;
939 721
940 // Getting the accepted languages list 722 // Getting the accepted languages list
941 std::string accept_langs_str = prefs->GetString(prefs::kAcceptLanguages); 723 std::string accept_langs_str = prefs->GetString(prefs::kAcceptLanguages);
942 724
943 std::vector<std::string> accept_langs_list; 725 std::vector<std::string> accept_langs_list;
944 base::SplitString(accept_langs_str, ',', &accept_langs_list); 726 base::SplitString(accept_langs_str, ',', &accept_langs_list);
945 727
946 // Will translate to the first supported language on the Accepted Language 728 // Will translate to the first supported language on the Accepted Language
947 // list or not at all if no such candidate exists 729 // list or not at all if no such candidate exists
948 std::vector<std::string>::iterator iter; 730 std::vector<std::string>::iterator iter;
949 for (iter = accept_langs_list.begin(); 731 for (iter = accept_langs_list.begin();
950 iter != accept_langs_list.end(); ++iter) { 732 iter != accept_langs_list.end(); ++iter) {
951 std::string lang_code = GetLanguageCode(*iter); 733 std::string lang_code = TranslateLanguageList::GetLanguageCode(*iter);
952 if (IsSupportedLanguage(lang_code)) 734 if (TranslateLanguageList::IsSupportedLanguage(lang_code))
953 return lang_code; 735 return lang_code;
954 } 736 }
955 return std::string(); 737 return std::string();
956 } 738 }
957 739
958 // static 740 // static
959 ShortcutConfiguration TranslateManager::ShortcutConfig() { 741 ShortcutConfiguration TranslateManager::ShortcutConfig() {
960 ShortcutConfiguration config; 742 ShortcutConfiguration config;
961 743
962 // The android implementation does not offer a drop down for space 744 // The android implementation does not offer a drop down for space
963 // reason so we are more aggressive showing the shortcuts for never translate. 745 // reason so we are more aggressive showing the shortcuts for never translate.
964 #if defined(OS_ANDROID) 746 #if defined(OS_ANDROID)
965 config.never_translate_min_count = 1; 747 config.never_translate_min_count = 1;
966 #else 748 #else
967 config.never_translate_min_count = 3; 749 config.never_translate_min_count = 3;
968 #endif // defined(OS_ANDROID) 750 #endif // defined(OS_ANDROID)
969 751
970 config.always_translate_min_count = 3; 752 config.always_translate_min_count = 3;
971 return config; 753 return config;
972 } 754 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698