| 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/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/time.h" | 17 #include "base/time.h" |
| 19 #include "base/values.h" | 18 #include "base/values.h" |
| 20 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
| 21 #include "chrome/browser/infobars/infobar_service.h" | 20 #include "chrome/browser/infobars/infobar_service.h" |
| 22 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/browser/tab_contents/language_state.h" | 22 #include "chrome/browser/tab_contents/language_state.h" |
| 24 #include "chrome/browser/tab_contents/tab_util.h" | 23 #include "chrome/browser/tab_contents/tab_util.h" |
| 25 #include "chrome/browser/translate/page_translated_details.h" | 24 #include "chrome/browser/translate/page_translated_details.h" |
| 26 #include "chrome/browser/translate/translate_infobar_delegate.h" | 25 #include "chrome/browser/translate/translate_infobar_delegate.h" |
| 26 #include "chrome/browser/translate/translate_language_list.h" |
| 27 #include "chrome/browser/translate/translate_manager_metrics.h" | 27 #include "chrome/browser/translate/translate_manager_metrics.h" |
| 28 #include "chrome/browser/translate/translate_prefs.h" | 28 #include "chrome/browser/translate/translate_prefs.h" |
| 29 #include "chrome/browser/translate/translate_tab_helper.h" | 29 #include "chrome/browser/translate/translate_tab_helper.h" |
| 30 #include "chrome/browser/translate/translate_url_util.h" |
| 30 #include "chrome/browser/ui/browser.h" | 31 #include "chrome/browser/ui/browser.h" |
| 31 #include "chrome/browser/ui/browser_finder.h" | 32 #include "chrome/browser/ui/browser_finder.h" |
| 32 #include "chrome/browser/ui/browser_tabstrip.h" | 33 #include "chrome/browser/ui/browser_tabstrip.h" |
| 33 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 34 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 34 #include "chrome/common/chrome_constants.h" | 35 #include "chrome/common/chrome_constants.h" |
| 35 #include "chrome/common/chrome_notification_types.h" | 36 #include "chrome/common/chrome_notification_types.h" |
| 36 #include "chrome/common/chrome_switches.h" | 37 #include "chrome/common/chrome_switches.h" |
| 37 #include "chrome/common/language_detection_details.h" | 38 #include "chrome/common/language_detection_details.h" |
| 38 #include "chrome/common/pref_names.h" | 39 #include "chrome/common/pref_names.h" |
| 39 #include "chrome/common/render_messages.h" | 40 #include "chrome/common/render_messages.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 63 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h" | 64 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h" |
| 64 #include "extensions/common/constants.h" | 65 #include "extensions/common/constants.h" |
| 65 #endif | 66 #endif |
| 66 | 67 |
| 67 using content::NavigationController; | 68 using content::NavigationController; |
| 68 using content::NavigationEntry; | 69 using content::NavigationEntry; |
| 69 using content::WebContents; | 70 using content::WebContents; |
| 70 | 71 |
| 71 namespace { | 72 namespace { |
| 72 | 73 |
| 73 // The default list of languages the Google translation server supports. | |
| 74 // We use this list until we receive the list that the server exposes. | |
| 75 // For information, here is the list of languages that Chrome can be run in | |
| 76 // but that the translation server does not support: | |
| 77 // am Amharic | |
| 78 // bn Bengali | |
| 79 // gu Gujarati | |
| 80 // kn Kannada | |
| 81 // ml Malayalam | |
| 82 // mr Marathi | |
| 83 // ta Tamil | |
| 84 // te Telugu | |
| 85 const char* const kDefaultSupportedLanguages[] = { | |
| 86 "af", // Afrikaans | |
| 87 "sq", // Albanian | |
| 88 "ar", // Arabic | |
| 89 "be", // Belarusian | |
| 90 "bg", // Bulgarian | |
| 91 "ca", // Catalan | |
| 92 "zh-CN", // Chinese (Simplified) | |
| 93 "zh-TW", // Chinese (Traditional) | |
| 94 "hr", // Croatian | |
| 95 "cs", // Czech | |
| 96 "da", // Danish | |
| 97 "nl", // Dutch | |
| 98 "en", // English | |
| 99 "eo", // Esperanto | |
| 100 "et", // Estonian | |
| 101 "tl", // Filipino | |
| 102 "fi", // Finnish | |
| 103 "fr", // French | |
| 104 "gl", // Galician | |
| 105 "de", // German | |
| 106 "el", // Greek | |
| 107 "ht", // Haitian Creole | |
| 108 "iw", // Hebrew | |
| 109 "hi", // Hindi | |
| 110 "hu", // Hungarian | |
| 111 "is", // Icelandic | |
| 112 "id", // Indonesian | |
| 113 "ga", // Irish | |
| 114 "it", // Italian | |
| 115 "ja", // Japanese | |
| 116 "ko", // Korean | |
| 117 "lv", // Latvian | |
| 118 "lt", // Lithuanian | |
| 119 "mk", // Macedonian | |
| 120 "ms", // Malay | |
| 121 "mt", // Maltese | |
| 122 "no", // Norwegian | |
| 123 "fa", // Persian | |
| 124 "pl", // Polish | |
| 125 "pt", // Portuguese | |
| 126 "ro", // Romanian | |
| 127 "ru", // Russian | |
| 128 "sr", // Serbian | |
| 129 "sk", // Slovak | |
| 130 "sl", // Slovenian | |
| 131 "es", // Spanish | |
| 132 "sw", // Swahili | |
| 133 "sv", // Swedish | |
| 134 "th", // Thai | |
| 135 "tr", // Turkish | |
| 136 "uk", // Ukrainian | |
| 137 "vi", // Vietnamese | |
| 138 "cy", // Welsh | |
| 139 "yi", // Yiddish | |
| 140 }; | |
| 141 | |
| 142 const char kTranslateScriptURL[] = | 74 const char kTranslateScriptURL[] = |
| 143 "https://translate.google.com/translate_a/element.js"; | 75 "https://translate.google.com/translate_a/element.js"; |
| 144 const char kTranslateScriptHeader[] = "Google-Translate-Element-Mode: library"; | 76 const char kTranslateScriptHeader[] = "Google-Translate-Element-Mode: library"; |
| 145 const char kReportLanguageDetectionErrorURL[] = | 77 const char kReportLanguageDetectionErrorURL[] = |
| 146 "https://translate.google.com/translate_error?client=cr&action=langidc"; | 78 "https://translate.google.com/translate_error?client=cr&action=langidc"; |
| 147 const char kLanguageListFetchURL[] = | |
| 148 "https://translate.googleapis.com/translate_a/l?client=chrome&cb=sl"; | |
| 149 | |
| 150 // Used in kTranslateScriptURL to request supporting languages list including | |
| 151 // "alpha languages". | |
| 152 const char kAlphaLanguageQueryName[] = "alpha"; | |
| 153 const char kAlphaLanguageQueryValue[] = "1"; | |
| 154 | |
| 155 // Used in all translate URLs to specify API Key. | |
| 156 const char kApiKeyName[] = "key"; | |
| 157 | 79 |
| 158 // Used in kTranslateScriptURL to specify a callback function name. | 80 // Used in kTranslateScriptURL to specify a callback function name. |
| 159 const char kCallbackQueryName[] = "cb"; | 81 const char kCallbackQueryName[] = "cb"; |
| 160 const char kCallbackQueryValue[] = | 82 const char kCallbackQueryValue[] = |
| 161 "cr.googleTranslate.onTranslateElementLoad"; | 83 "cr.googleTranslate.onTranslateElementLoad"; |
| 162 | 84 |
| 163 // Used in kTranslateScriptURL and kLanguageListFetchURL to specify the | |
| 164 // application locale. | |
| 165 const char kHostLocaleQueryName[] = "hl"; | |
| 166 | |
| 167 // Used in kReportLanguageDetectionErrorURL to specify the original page | 85 // Used in kReportLanguageDetectionErrorURL to specify the original page |
| 168 // language. | 86 // language. |
| 169 const char kSourceLanguageQueryName[] = "sl"; | 87 const char kSourceLanguageQueryName[] = "sl"; |
| 170 | 88 |
| 171 // Used in kReportLanguageDetectionErrorURL to specify the page URL. | 89 // Used in kReportLanguageDetectionErrorURL to specify the page URL. |
| 172 const char kUrlQueryName[] = "u"; | 90 const char kUrlQueryName[] = "u"; |
| 173 | 91 |
| 174 // The delay in ms that we'll wait to check if a page has finished loading | 92 // The delay in ms that we'll wait to check if a page has finished loading |
| 175 // before attempting a translation. | 93 // before attempting a translation. |
| 176 const int kTranslateLoadCheckDelayMs = 150; | 94 const int kTranslateLoadCheckDelayMs = 150; |
| 177 | 95 |
| 178 // The maximum number of attempts we'll do to see if the page has finshed | 96 // The maximum number of attempts we'll do to see if the page has finshed |
| 179 // loading before giving up the translation | 97 // loading before giving up the translation |
| 180 const int kMaxTranslateLoadCheckAttempts = 20; | 98 const int kMaxTranslateLoadCheckAttempts = 20; |
| 181 | 99 |
| 182 const int kMaxRetryLanguageListFetch = 5; | |
| 183 const int kTranslateScriptExpirationDelayDays = 1; | 100 const int kTranslateScriptExpirationDelayDays = 1; |
| 184 | 101 |
| 185 GURL AddApiKeyToUrl(const GURL& url) { | |
| 186 return net::AppendQueryParameter(url, kApiKeyName, google_apis::GetAPIKey()); | |
| 187 } | |
| 188 | |
| 189 GURL AddHostLocaleToUrl(const GURL& url) { | |
| 190 return net::AppendQueryParameter( | |
| 191 url, | |
| 192 kHostLocaleQueryName, | |
| 193 TranslateManager::GetLanguageCode( | |
| 194 g_browser_process->GetApplicationLocale())); | |
| 195 } | |
| 196 | |
| 197 } // namespace | 102 } // namespace |
| 198 | 103 |
| 199 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL. | |
| 200 const char TranslateManager::kLanguageListCallbackName[] = "sl("; | |
| 201 const char TranslateManager::kTargetLanguagesKey[] = "tl"; | |
| 202 | |
| 203 // static | |
| 204 base::LazyInstance<std::set<std::string> > | |
| 205 TranslateManager::supported_languages_ = LAZY_INSTANCE_INITIALIZER; | |
| 206 | |
| 207 TranslateManager::~TranslateManager() { | 104 TranslateManager::~TranslateManager() { |
| 208 weak_method_factory_.InvalidateWeakPtrs(); | 105 weak_method_factory_.InvalidateWeakPtrs(); |
| 209 } | 106 } |
| 210 | 107 |
| 211 // static | 108 // static |
| 212 TranslateManager* TranslateManager::GetInstance() { | 109 TranslateManager* TranslateManager::GetInstance() { |
| 213 return Singleton<TranslateManager>::get(); | 110 return Singleton<TranslateManager>::get(); |
| 214 } | 111 } |
| 215 | 112 |
| 216 // static | 113 // static |
| 217 bool TranslateManager::IsTranslatableURL(const GURL& url) { | 114 bool TranslateManager::IsTranslatableURL(const GURL& url) { |
| 218 // A URLs is translatable unless it is one of the following: | 115 // A URLs is translatable unless it is one of the following: |
| 219 // - empty (can happen for popups created with window.open("")) | 116 // - empty (can happen for popups created with window.open("")) |
| 220 // - an internal URL (chrome:// and others) | 117 // - an internal URL (chrome:// and others) |
| 221 // - the devtools (which is considered UI) | 118 // - the devtools (which is considered UI) |
| 222 // - Chrome OS file manager extension | 119 // - Chrome OS file manager extension |
| 223 // - an FTP page (as FTP pages tend to have long lists of filenames that may | 120 // - an FTP page (as FTP pages tend to have long lists of filenames that may |
| 224 // confuse the CLD) | 121 // confuse the CLD) |
| 225 return !url.is_empty() && | 122 return !url.is_empty() && |
| 226 !url.SchemeIs(chrome::kChromeUIScheme) && | 123 !url.SchemeIs(chrome::kChromeUIScheme) && |
| 227 !url.SchemeIs(chrome::kChromeDevToolsScheme) && | 124 !url.SchemeIs(chrome::kChromeDevToolsScheme) && |
| 228 #ifdef FILE_MANAGER_EXTENSION | 125 #ifdef FILE_MANAGER_EXTENSION |
| 229 !(url.SchemeIs(extensions::kExtensionScheme) && | 126 !(url.SchemeIs(extensions::kExtensionScheme) && |
| 230 url.DomainIs(kFileBrowserDomain)) && | 127 url.DomainIs(kFileBrowserDomain)) && |
| 231 #endif | 128 #endif |
| 232 !url.SchemeIs(chrome::kFtpScheme); | 129 !url.SchemeIs(chrome::kFtpScheme); |
| 233 } | 130 } |
| 234 | 131 |
| 235 // static | 132 // static |
| 236 void TranslateManager::SetSupportedLanguages(const std::string& language_list) { | |
| 237 // The format is: | |
| 238 // sl({"sl": {"XX": "LanguageName", ...}, "tl": {"XX": "LanguageName", ...}}) | |
| 239 // Where "sl(" is set in kLanguageListCallbackName | |
| 240 // and "tl" is kTargetLanguagesKey | |
| 241 if (!StartsWithASCII(language_list, kLanguageListCallbackName, false) || | |
| 242 !EndsWith(language_list, ")", false)) { | |
| 243 // We don't have a NOTREACHED here since this can happen in ui_tests, even | |
| 244 // though the the BrowserMain function won't call us with parameters.ui_task | |
| 245 // is NULL some tests don't set it, so we must bail here. | |
| 246 return; | |
| 247 } | |
| 248 static const size_t kLanguageListCallbackNameLength = | |
| 249 strlen(kLanguageListCallbackName); | |
| 250 std::string languages_json = language_list.substr( | |
| 251 kLanguageListCallbackNameLength, | |
| 252 language_list.size() - kLanguageListCallbackNameLength - 1); | |
| 253 scoped_ptr<Value> json_value( | |
| 254 base::JSONReader::Read(languages_json, base::JSON_ALLOW_TRAILING_COMMAS)); | |
| 255 if (json_value == NULL || !json_value->IsType(Value::TYPE_DICTIONARY)) { | |
| 256 NOTREACHED(); | |
| 257 return; | |
| 258 } | |
| 259 // The first level dictionary contains two sub-dict, one for source languages | |
| 260 // and the other for target languages, we want to use the target languages. | |
| 261 DictionaryValue* language_dict = | |
| 262 static_cast<DictionaryValue*>(json_value.get()); | |
| 263 DictionaryValue* target_languages = NULL; | |
| 264 if (!language_dict->GetDictionary(kTargetLanguagesKey, &target_languages) || | |
| 265 target_languages == NULL) { | |
| 266 NOTREACHED(); | |
| 267 return; | |
| 268 } | |
| 269 // Now we can clear our current state... | |
| 270 std::set<std::string>* supported_languages = supported_languages_.Pointer(); | |
| 271 supported_languages->clear(); | |
| 272 // ... and replace it with the values we just fetched from the server. | |
| 273 for (DictionaryValue::Iterator iter(*target_languages); !iter.IsAtEnd(); | |
| 274 iter.Advance()) { | |
| 275 supported_languages_.Pointer()->insert(iter.key()); | |
| 276 } | |
| 277 } | |
| 278 | |
| 279 // static | |
| 280 void TranslateManager::InitSupportedLanguages() { | |
| 281 // If our list of supported languages have not been set yet, we default | |
| 282 // to our hard coded list of languages in kDefaultSupportedLanguages. | |
| 283 if (supported_languages_.Pointer()->empty()) { | |
| 284 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i) | |
| 285 supported_languages_.Pointer()->insert(kDefaultSupportedLanguages[i]); | |
| 286 } | |
| 287 } | |
| 288 | |
| 289 // static | |
| 290 void TranslateManager::GetSupportedLanguages( | 133 void TranslateManager::GetSupportedLanguages( |
| 291 std::vector<std::string>* languages) { | 134 std::vector<std::string>* languages) { |
| 292 DCHECK(languages && languages->empty()); | 135 if (GetInstance()->language_list_.get()) { |
| 293 InitSupportedLanguages(); | 136 GetInstance()->language_list_->GetSupportedLanguages(languages); |
| 294 std::set<std::string>* supported_languages = supported_languages_.Pointer(); | 137 return; |
| 295 std::set<std::string>::const_iterator iter = supported_languages->begin(); | 138 } |
| 296 for (; iter != supported_languages->end(); ++iter) | 139 NOTREACHED(); |
| 297 languages->push_back(*iter); | |
| 298 } | 140 } |
| 299 | 141 |
| 300 // static | 142 // static |
| 301 std::string TranslateManager::GetLanguageCode( | 143 std::string TranslateManager::GetLanguageCode( |
| 302 const std::string& chrome_locale) { | 144 const std::string& chrome_locale) { |
| 303 // Only remove the country code for country specific languages we don't | 145 if (GetInstance()->language_list_.get()) |
| 304 // support specifically yet. | 146 return GetInstance()->language_list_->GetLanguageCode(chrome_locale); |
| 305 if (IsSupportedLanguage(chrome_locale)) | 147 NOTREACHED(); |
| 306 return chrome_locale; | 148 return chrome_locale; |
| 307 | |
| 308 size_t hypen_index = chrome_locale.find('-'); | |
| 309 if (hypen_index == std::string::npos) | |
| 310 return chrome_locale; | |
| 311 return chrome_locale.substr(0, hypen_index); | |
| 312 } | 149 } |
| 313 | 150 |
| 314 // static | 151 // static |
| 315 bool TranslateManager::IsSupportedLanguage(const std::string& page_language) { | 152 bool TranslateManager::IsSupportedLanguage(const std::string& language) { |
| 316 InitSupportedLanguages(); | 153 if (GetInstance()->language_list_.get()) |
| 317 return supported_languages_.Pointer()->count(page_language) != 0; | 154 return GetInstance()->language_list_->IsSupportedLanguage(language); |
| 155 NOTREACHED(); |
| 156 return false; |
| 318 } | 157 } |
| 319 | 158 |
| 320 void TranslateManager::Observe(int type, | 159 void TranslateManager::Observe(int type, |
| 321 const content::NotificationSource& source, | 160 const content::NotificationSource& source, |
| 322 const content::NotificationDetails& details) { | 161 const content::NotificationDetails& details) { |
| 323 switch (type) { | 162 switch (type) { |
| 324 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { | 163 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { |
| 325 NavigationController* controller = | 164 NavigationController* controller = |
| 326 content::Source<NavigationController>(source).ptr(); | 165 content::Source<NavigationController>(source).ptr(); |
| 327 content::LoadCommittedDetails* load_details = | 166 content::LoadCommittedDetails* load_details = |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 DCHECK(count == 1u); | 262 DCHECK(count == 1u); |
| 424 delete pref_change_registrar; | 263 delete pref_change_registrar; |
| 425 break; | 264 break; |
| 426 } | 265 } |
| 427 default: | 266 default: |
| 428 NOTREACHED(); | 267 NOTREACHED(); |
| 429 } | 268 } |
| 430 } | 269 } |
| 431 | 270 |
| 432 void TranslateManager::OnURLFetchComplete(const net::URLFetcher* source) { | 271 void TranslateManager::OnURLFetchComplete(const net::URLFetcher* source) { |
| 433 if (translate_script_request_pending_.get() != source && | 272 if (translate_script_request_pending_.get() != source) { |
| 434 language_list_request_pending_.get() != source) { | |
| 435 // Looks like crash on Mac is possibly caused with callback entering here | 273 // Looks like crash on Mac is possibly caused with callback entering here |
| 436 // with unknown fetcher when network is refreshed. | 274 // with unknown fetcher when network is refreshed. |
| 437 scoped_ptr<const net::URLFetcher> delete_ptr(source); | 275 scoped_ptr<const net::URLFetcher> delete_ptr(source); |
| 438 return; | 276 return; |
| 439 } | 277 } |
| 440 | 278 |
| 441 bool error = | 279 bool error = |
| 442 (source->GetStatus().status() != net::URLRequestStatus::SUCCESS || | 280 source->GetStatus().status() != net::URLRequestStatus::SUCCESS || |
| 443 source->GetResponseCode() != net::HTTP_OK); | 281 source->GetResponseCode() != net::HTTP_OK; |
| 444 if (translate_script_request_pending_.get() == source) { | 282 if (translate_script_request_pending_.get() == source) { |
| 445 scoped_ptr<const net::URLFetcher> delete_ptr( | 283 scoped_ptr<const net::URLFetcher> delete_ptr( |
| 446 translate_script_request_pending_.release()); | 284 translate_script_request_pending_.release()); |
| 447 if (!error) { | 285 if (!error) { |
| 448 base::StringPiece str = ResourceBundle::GetSharedInstance(). | 286 base::StringPiece str = ResourceBundle::GetSharedInstance(). |
| 449 GetRawDataResource(IDR_TRANSLATE_JS); | 287 GetRawDataResource(IDR_TRANSLATE_JS); |
| 450 DCHECK(translate_script_.empty()); | 288 DCHECK(translate_script_.empty()); |
| 451 str.CopyToString(&translate_script_); | 289 str.CopyToString(&translate_script_); |
| 452 std::string argument = "('"; | 290 std::string argument = "('"; |
| 453 std::string api_key = google_apis::GetAPIKey(); | 291 std::string api_key = google_apis::GetAPIKey(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 ShortcutConfig(), | 333 ShortcutConfig(), |
| 496 request.source_lang, | 334 request.source_lang, |
| 497 request.target_lang); | 335 request.target_lang); |
| 498 } else { | 336 } else { |
| 499 // Translate the page. | 337 // Translate the page. |
| 500 DoTranslatePage(web_contents, translate_script_, | 338 DoTranslatePage(web_contents, translate_script_, |
| 501 request.source_lang, request.target_lang); | 339 request.source_lang, request.target_lang); |
| 502 } | 340 } |
| 503 } | 341 } |
| 504 pending_requests_.clear(); | 342 pending_requests_.clear(); |
| 505 } else { // if (translate_script_request_pending_.get() == source) | |
| 506 scoped_ptr<const net::URLFetcher> delete_ptr( | |
| 507 language_list_request_pending_.release()); | |
| 508 if (!error) { | |
| 509 std::string data; | |
| 510 source->GetResponseAsString(&data); | |
| 511 SetSupportedLanguages(data); | |
| 512 } else { | |
| 513 VLOG(9) << "Failed to Fetch languages from: " << kLanguageListFetchURL; | |
| 514 } | |
| 515 } | 343 } |
| 516 } | 344 } |
| 517 | 345 |
| 518 void TranslateManager::AddObserver(Observer* obs) { | 346 void TranslateManager::AddObserver(Observer* obs) { |
| 519 observer_list_.AddObserver(obs); | 347 observer_list_.AddObserver(obs); |
| 520 } | 348 } |
| 521 | 349 |
| 522 void TranslateManager::RemoveObserver(Observer* obs) { | 350 void TranslateManager::RemoveObserver(Observer* obs) { |
| 523 observer_list_.RemoveObserver(obs); | 351 observer_list_.RemoveObserver(obs); |
| 524 } | 352 } |
| 525 | 353 |
| 526 void TranslateManager::NotifyLanguageDetection( | 354 void TranslateManager::NotifyLanguageDetection( |
| 527 const LanguageDetectionDetails& details) { | 355 const LanguageDetectionDetails& details) { |
| 528 FOR_EACH_OBSERVER(Observer, observer_list_, OnLanguageDetection(details)); | 356 FOR_EACH_OBSERVER(Observer, observer_list_, OnLanguageDetection(details)); |
| 529 } | 357 } |
| 530 | 358 |
| 531 | 359 |
| 532 TranslateManager::TranslateManager() | 360 TranslateManager::TranslateManager() |
| 533 : weak_method_factory_(this), | 361 : weak_method_factory_(this), |
| 534 translate_script_expiration_delay_(base::TimeDelta::FromDays( | 362 translate_script_expiration_delay_(base::TimeDelta::FromDays( |
| 535 kTranslateScriptExpirationDelayDays)), | 363 kTranslateScriptExpirationDelayDays)), |
| 536 max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts) { | 364 max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts) { |
| 537 notification_registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 365 notification_registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 538 content::NotificationService::AllSources()); | 366 content::NotificationService::AllSources()); |
| 539 notification_registrar_.Add(this, | 367 notification_registrar_.Add(this, |
| 540 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, | 368 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, |
| 541 content::NotificationService::AllSources()); | 369 content::NotificationService::AllSources()); |
| 542 notification_registrar_.Add(this, chrome::NOTIFICATION_PAGE_TRANSLATED, | 370 notification_registrar_.Add(this, chrome::NOTIFICATION_PAGE_TRANSLATED, |
| 543 content::NotificationService::AllSources()); | 371 content::NotificationService::AllSources()); |
| 372 language_list_.reset(new TranslateLanguageList); |
| 544 } | 373 } |
| 545 | 374 |
| 546 void TranslateManager::InitiateTranslation(WebContents* web_contents, | 375 void TranslateManager::InitiateTranslation(WebContents* web_contents, |
| 547 const std::string& page_lang) { | 376 const std::string& page_lang) { |
| 548 Profile* profile = | 377 Profile* profile = |
| 549 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 378 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 550 PrefService* prefs = profile->GetOriginalProfile()->GetPrefs(); | 379 PrefService* prefs = profile->GetOriginalProfile()->GetPrefs(); |
| 551 if (!prefs->GetBoolean(prefs::kEnableTranslate)) { | 380 if (!prefs->GetBoolean(prefs::kEnableTranslate)) { |
| 552 TranslateManagerMetrics::ReportInitiationStatus( | 381 TranslateManagerMetrics::ReportInitiationStatus( |
| 553 TranslateManagerMetrics::INITIATION_STATUS_DISABLED_BY_PREFS); | 382 TranslateManagerMetrics::INITIATION_STATUS_DISABLED_BY_PREFS); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 kUrlQueryName, | 583 kUrlQueryName, |
| 755 page_url.spec()); | 584 page_url.spec()); |
| 756 | 585 |
| 757 TranslateTabHelper* translate_tab_helper = | 586 TranslateTabHelper* translate_tab_helper = |
| 758 TranslateTabHelper::FromWebContents(web_contents); | 587 TranslateTabHelper::FromWebContents(web_contents); |
| 759 report_error_url = net::AppendQueryParameter( | 588 report_error_url = net::AppendQueryParameter( |
| 760 report_error_url, | 589 report_error_url, |
| 761 kSourceLanguageQueryName, | 590 kSourceLanguageQueryName, |
| 762 translate_tab_helper->language_state().original_language()); | 591 translate_tab_helper->language_state().original_language()); |
| 763 | 592 |
| 764 report_error_url = AddHostLocaleToUrl(report_error_url); | 593 report_error_url = TranslateURLUtil::AddHostLocaleToUrl(report_error_url); |
| 765 report_error_url = AddApiKeyToUrl(report_error_url); | 594 report_error_url = TranslateURLUtil::AddApiKeyToUrl(report_error_url); |
| 766 | 595 |
| 767 chrome::AddSelectedTabWithURL(browser, report_error_url, | 596 chrome::AddSelectedTabWithURL(browser, report_error_url, |
| 768 content::PAGE_TRANSITION_AUTO_BOOKMARK); | 597 content::PAGE_TRANSITION_AUTO_BOOKMARK); |
| 769 } | 598 } |
| 770 | 599 |
| 771 void TranslateManager::DoTranslatePage(WebContents* web_contents, | 600 void TranslateManager::DoTranslatePage(WebContents* web_contents, |
| 772 const std::string& translate_script, | 601 const std::string& translate_script, |
| 773 const std::string& source_lang, | 602 const std::string& source_lang, |
| 774 const std::string& target_lang) { | 603 const std::string& target_lang) { |
| 775 NavigationEntry* entry = web_contents->GetController().GetActiveEntry(); | 604 NavigationEntry* entry = web_contents->GetController().GetActiveEntry(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 // the default Accept-Language values for most locales, remove this | 700 // the default Accept-Language values for most locales, remove this |
| 872 // special-casing. | 701 // special-casing. |
| 873 if (accept_lang != "en" || is_ui_english) | 702 if (accept_lang != "en" || is_ui_english) |
| 874 accept_langs_set.insert(accept_lang); | 703 accept_langs_set.insert(accept_lang); |
| 875 } | 704 } |
| 876 accept_languages_[prefs] = accept_langs_set; | 705 accept_languages_[prefs] = accept_langs_set; |
| 877 } | 706 } |
| 878 | 707 |
| 879 void TranslateManager::FetchLanguageListFromTranslateServer( | 708 void TranslateManager::FetchLanguageListFromTranslateServer( |
| 880 PrefService* prefs) { | 709 PrefService* prefs) { |
| 881 if (language_list_request_pending_.get() != NULL) | 710 DCHECK(language_list_.get()); |
| 882 return; | |
| 883 | 711 |
| 884 // We don't want to do this when translate is disabled. | 712 // We don't want to do this when translate is disabled. |
| 885 DCHECK(prefs != NULL); | 713 DCHECK(prefs != NULL); |
| 886 if (CommandLine::ForCurrentProcess()->HasSwitch( | 714 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 887 switches::kDisableTranslate) || | 715 switches::kDisableTranslate) || |
| 888 (prefs != NULL && !prefs->GetBoolean(prefs::kEnableTranslate))) { | 716 (prefs != NULL && !prefs->GetBoolean(prefs::kEnableTranslate))) { |
| 889 return; | 717 return; |
| 890 } | 718 } |
| 891 | 719 |
| 892 GURL language_list_fetch_url = GURL(kLanguageListFetchURL); | 720 if (language_list_.get()) |
| 893 language_list_fetch_url = AddHostLocaleToUrl(language_list_fetch_url); | 721 language_list_->RequestLanguageList(); |
| 894 language_list_fetch_url = AddApiKeyToUrl(language_list_fetch_url); | |
| 895 | |
| 896 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
| 897 if (command_line.HasSwitch(switches::kEnableTranslateAlphaLanguages)) { | |
| 898 language_list_fetch_url = net::AppendQueryParameter( | |
| 899 language_list_fetch_url, | |
| 900 kAlphaLanguageQueryName, | |
| 901 kAlphaLanguageQueryValue); | |
| 902 } | |
| 903 | |
| 904 VLOG(9) << "Fetch supporting language list from: " | |
| 905 << language_list_fetch_url.spec().c_str(); | |
| 906 | |
| 907 language_list_request_pending_.reset(net::URLFetcher::Create( | |
| 908 1, language_list_fetch_url, net::URLFetcher::GET, this)); | |
| 909 language_list_request_pending_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
| 910 net::LOAD_DO_NOT_SAVE_COOKIES); | |
| 911 language_list_request_pending_->SetRequestContext( | |
| 912 g_browser_process->system_request_context()); | |
| 913 language_list_request_pending_->SetMaxRetriesOn5xx( | |
| 914 kMaxRetryLanguageListFetch); | |
| 915 language_list_request_pending_->Start(); | |
| 916 } | 722 } |
| 917 | 723 |
| 918 void TranslateManager::CleanupPendingUlrFetcher() { | 724 void TranslateManager::CleanupPendingUlrFetcher() { |
| 919 language_list_request_pending_.reset(); | 725 language_list_.reset(); |
| 920 translate_script_request_pending_.reset(); | 726 translate_script_request_pending_.reset(); |
| 921 } | 727 } |
| 922 | 728 |
| 923 void TranslateManager::RequestTranslateScript() { | 729 void TranslateManager::RequestTranslateScript() { |
| 924 if (translate_script_request_pending_.get() != NULL) | 730 if (translate_script_request_pending_.get() != NULL) |
| 925 return; | 731 return; |
| 926 | 732 |
| 927 GURL translate_script_url; | 733 GURL translate_script_url; |
| 928 // Check if command-line contains an alternative URL for translate service. | 734 // Check if command-line contains an alternative URL for translate service. |
| 929 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 735 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 941 // Use default URL when command-line argument is not specified, or specified | 747 // Use default URL when command-line argument is not specified, or specified |
| 942 // URL is invalid. | 748 // URL is invalid. |
| 943 if (translate_script_url.is_empty()) | 749 if (translate_script_url.is_empty()) |
| 944 translate_script_url = GURL(kTranslateScriptURL); | 750 translate_script_url = GURL(kTranslateScriptURL); |
| 945 | 751 |
| 946 translate_script_url = net::AppendQueryParameter( | 752 translate_script_url = net::AppendQueryParameter( |
| 947 translate_script_url, | 753 translate_script_url, |
| 948 kCallbackQueryName, | 754 kCallbackQueryName, |
| 949 kCallbackQueryValue); | 755 kCallbackQueryValue); |
| 950 | 756 |
| 951 translate_script_url = AddHostLocaleToUrl(translate_script_url); | 757 translate_script_url = |
| 952 translate_script_url = AddApiKeyToUrl(translate_script_url); | 758 TranslateURLUtil::AddHostLocaleToUrl(translate_script_url); |
| 759 translate_script_url = |
| 760 TranslateURLUtil::AddApiKeyToUrl(translate_script_url); |
| 953 | 761 |
| 954 translate_script_request_pending_.reset(net::URLFetcher::Create( | 762 translate_script_request_pending_.reset(net::URLFetcher::Create( |
| 955 0, translate_script_url, net::URLFetcher::GET, this)); | 763 0, translate_script_url, net::URLFetcher::GET, this)); |
| 956 translate_script_request_pending_->SetLoadFlags( | 764 translate_script_request_pending_->SetLoadFlags( |
| 957 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); | 765 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); |
| 958 translate_script_request_pending_->SetRequestContext( | 766 translate_script_request_pending_->SetRequestContext( |
| 959 g_browser_process->system_request_context()); | 767 g_browser_process->system_request_context()); |
| 960 translate_script_request_pending_->SetExtraRequestHeaders( | 768 translate_script_request_pending_->SetExtraRequestHeaders( |
| 961 kTranslateScriptHeader); | 769 kTranslateScriptHeader); |
| 962 translate_script_request_pending_->Start(); | 770 translate_script_request_pending_->Start(); |
| 963 } | 771 } |
| 964 | 772 |
| 965 // static | 773 // static |
| 966 std::string TranslateManager::GetTargetLanguage(PrefService* prefs) { | 774 std::string TranslateManager::GetTargetLanguage(PrefService* prefs) { |
| 967 std::string ui_lang = | 775 std::string ui_lang = |
| 968 GetLanguageCode(g_browser_process->GetApplicationLocale()); | 776 GetLanguageCode(g_browser_process->GetApplicationLocale()); |
| 969 if (IsSupportedLanguage(ui_lang)) | 777 if (IsSupportedLanguage(ui_lang)) |
| 970 return ui_lang; | 778 return ui_lang; |
| 971 | 779 |
| 972 // Getting the accepted languages list | 780 // Getting the accepted languages list |
| 973 std::string accept_langs_str = prefs->GetString(prefs::kAcceptLanguages); | 781 std::string accept_langs_str = prefs->GetString(prefs::kAcceptLanguages); |
| 974 | 782 |
| 975 std::vector<std::string> accept_langs_list; | 783 std::vector<std::string> accept_langs_list; |
| 976 base::SplitString(accept_langs_str, ',', &accept_langs_list); | 784 base::SplitString(accept_langs_str, ',', &accept_langs_list); |
| 977 | 785 |
| 978 // Will translate to the first supported language on the Accepted Language | 786 // Will translate to the first supported language on the Accepted Language |
| (...skipping 16 matching lines...) Expand all Loading... |
| 995 // reason so we are more aggressive showing the shortcuts for never translate. | 803 // reason so we are more aggressive showing the shortcuts for never translate. |
| 996 #if defined(OS_ANDROID) | 804 #if defined(OS_ANDROID) |
| 997 config.never_translate_min_count = 1; | 805 config.never_translate_min_count = 1; |
| 998 #else | 806 #else |
| 999 config.never_translate_min_count = 3; | 807 config.never_translate_min_count = 3; |
| 1000 #endif // defined(OS_ANDROID) | 808 #endif // defined(OS_ANDROID) |
| 1001 | 809 |
| 1002 config.always_translate_min_count = 3; | 810 config.always_translate_min_count = 3; |
| 1003 return config; | 811 return config; |
| 1004 } | 812 } |
| OLD | NEW |