Chromium Code Reviews| Index: chrome/browser/translate/translate_manager.cc |
| diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc |
| index 1046922ec62af6e459ac1b4fa785e94b5041e1be..34ce89fff2f4add70ce0cb59d41ccaf369796a0f 100644 |
| --- a/chrome/browser/translate/translate_manager.cc |
| +++ b/chrome/browser/translate/translate_manager.cc |
| @@ -7,7 +7,6 @@ |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/compiler_specific.h" |
| -#include "base/json/json_reader.h" |
| #include "base/memory/singleton.h" |
| #include "base/message_loop.h" |
| #include "base/metrics/histogram.h" |
| @@ -24,9 +23,11 @@ |
| #include "chrome/browser/tab_contents/tab_util.h" |
| #include "chrome/browser/translate/page_translated_details.h" |
| #include "chrome/browser/translate/translate_infobar_delegate.h" |
| +#include "chrome/browser/translate/translate_language_list.h" |
| #include "chrome/browser/translate/translate_manager_metrics.h" |
| #include "chrome/browser/translate/translate_prefs.h" |
| #include "chrome/browser/translate/translate_tab_helper.h" |
| +#include "chrome/browser/translate/translate_url_util.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_finder.h" |
| #include "chrome/browser/ui/browser_tabstrip.h" |
| @@ -70,100 +71,17 @@ using content::WebContents; |
| namespace { |
| -// The default list of languages the Google translation server supports. |
| -// We use this list until we receive the list that the server exposes. |
| -// For information, here is the list of languages that Chrome can be run in |
| -// but that the translation server does not support: |
| -// am Amharic |
| -// bn Bengali |
| -// gu Gujarati |
| -// kn Kannada |
| -// ml Malayalam |
| -// mr Marathi |
| -// ta Tamil |
| -// te Telugu |
| -const char* const kDefaultSupportedLanguages[] = { |
| - "af", // Afrikaans |
| - "sq", // Albanian |
| - "ar", // Arabic |
| - "be", // Belarusian |
| - "bg", // Bulgarian |
| - "ca", // Catalan |
| - "zh-CN", // Chinese (Simplified) |
| - "zh-TW", // Chinese (Traditional) |
| - "hr", // Croatian |
| - "cs", // Czech |
| - "da", // Danish |
| - "nl", // Dutch |
| - "en", // English |
| - "eo", // Esperanto |
| - "et", // Estonian |
| - "tl", // Filipino |
| - "fi", // Finnish |
| - "fr", // French |
| - "gl", // Galician |
| - "de", // German |
| - "el", // Greek |
| - "ht", // Haitian Creole |
| - "iw", // Hebrew |
| - "hi", // Hindi |
| - "hu", // Hungarian |
| - "is", // Icelandic |
| - "id", // Indonesian |
| - "ga", // Irish |
| - "it", // Italian |
| - "ja", // Japanese |
| - "ko", // Korean |
| - "lv", // Latvian |
| - "lt", // Lithuanian |
| - "mk", // Macedonian |
| - "ms", // Malay |
| - "mt", // Maltese |
| - "no", // Norwegian |
| - "fa", // Persian |
| - "pl", // Polish |
| - "pt", // Portuguese |
| - "ro", // Romanian |
| - "ru", // Russian |
| - "sr", // Serbian |
| - "sk", // Slovak |
| - "sl", // Slovenian |
| - "es", // Spanish |
| - "sw", // Swahili |
| - "sv", // Swedish |
| - "th", // Thai |
| - "tr", // Turkish |
| - "uk", // Ukrainian |
| - "vi", // Vietnamese |
| - "cy", // Welsh |
| - "yi", // Yiddish |
| -}; |
| - |
| const char kTranslateScriptURL[] = |
| "https://translate.google.com/translate_a/element.js"; |
| const char kTranslateScriptHeader[] = "Google-Translate-Element-Mode: library"; |
| const char kReportLanguageDetectionErrorURL[] = |
| "https://translate.google.com/translate_error?client=cr&action=langidc"; |
| -const char kLanguageListFetchURL[] = |
| - "https://translate.googleapis.com/translate_a/l?client=chrome&cb=sl"; |
| - |
| -// Used in kTranslateScriptURL to request supporting languages list including |
| -// "alpha languages". |
| -const char kAlphaLanguageQueryName[] = "alpha"; |
| -const char kAlphaLanguageQueryValue[] = "1"; |
| - |
| -// Used in all translate URLs to specify API Key. |
| -const char kApiKeyName[] = "key"; |
| // Used in kTranslateScriptURL to specify a callback function name. |
| const char kCallbackQueryName[] = "cb"; |
| const char kCallbackQueryValue[] = |
| "cr.googleTranslate.onTranslateElementLoad"; |
| -// Used in kTranslateScriptURL and kLanguageListFetchURL to specify the |
| -// application locale. |
| -const char kHostLocaleQueryName[] = "hl"; |
| - |
| // Used in kReportLanguageDetectionErrorURL to specify the original page |
| // language. |
| const char kSourceLanguageQueryName[] = "sl"; |
| @@ -179,31 +97,10 @@ const int kTranslateLoadCheckDelayMs = 150; |
| // loading before giving up the translation |
| const int kMaxTranslateLoadCheckAttempts = 20; |
| -const int kMaxRetryLanguageListFetch = 5; |
| const int kTranslateScriptExpirationDelayDays = 1; |
| -GURL AddApiKeyToUrl(const GURL& url) { |
| - return net::AppendQueryParameter(url, kApiKeyName, google_apis::GetAPIKey()); |
| -} |
| - |
| -GURL AddHostLocaleToUrl(const GURL& url) { |
| - return net::AppendQueryParameter( |
| - url, |
| - kHostLocaleQueryName, |
| - TranslateManager::GetLanguageCode( |
| - g_browser_process->GetApplicationLocale())); |
| -} |
| - |
| } // namespace |
| -// This must be kept in sync with the &cb= value in the kLanguageListFetchURL. |
| -const char TranslateManager::kLanguageListCallbackName[] = "sl("; |
| -const char TranslateManager::kTargetLanguagesKey[] = "tl"; |
| - |
| -// static |
| -base::LazyInstance<std::set<std::string> > |
| - TranslateManager::supported_languages_ = LAZY_INSTANCE_INITIALIZER; |
| - |
| TranslateManager::~TranslateManager() { |
| weak_method_factory_.InvalidateWeakPtrs(); |
| } |
| @@ -233,88 +130,30 @@ bool TranslateManager::IsTranslatableURL(const GURL& url) { |
| } |
| // static |
| -void TranslateManager::SetSupportedLanguages(const std::string& language_list) { |
| - // The format is: |
| - // sl({"sl": {"XX": "LanguageName", ...}, "tl": {"XX": "LanguageName", ...}}) |
| - // Where "sl(" is set in kLanguageListCallbackName |
| - // and "tl" is kTargetLanguagesKey |
| - if (!StartsWithASCII(language_list, kLanguageListCallbackName, false) || |
| - !EndsWith(language_list, ")", false)) { |
| - // We don't have a NOTREACHED here since this can happen in ui_tests, even |
| - // though the the BrowserMain function won't call us with parameters.ui_task |
| - // is NULL some tests don't set it, so we must bail here. |
| - return; |
| - } |
| - static const size_t kLanguageListCallbackNameLength = |
| - strlen(kLanguageListCallbackName); |
| - std::string languages_json = language_list.substr( |
| - kLanguageListCallbackNameLength, |
| - language_list.size() - kLanguageListCallbackNameLength - 1); |
| - scoped_ptr<Value> json_value( |
| - base::JSONReader::Read(languages_json, base::JSON_ALLOW_TRAILING_COMMAS)); |
| - if (json_value == NULL || !json_value->IsType(Value::TYPE_DICTIONARY)) { |
| - NOTREACHED(); |
| - return; |
| - } |
| - // The first level dictionary contains two sub-dict, one for source languages |
| - // and the other for target languages, we want to use the target languages. |
| - DictionaryValue* language_dict = |
| - static_cast<DictionaryValue*>(json_value.get()); |
| - DictionaryValue* target_languages = NULL; |
| - if (!language_dict->GetDictionary(kTargetLanguagesKey, &target_languages) || |
| - target_languages == NULL) { |
| - NOTREACHED(); |
| - return; |
| - } |
| - // Now we can clear our current state... |
| - std::set<std::string>* supported_languages = supported_languages_.Pointer(); |
| - supported_languages->clear(); |
| - // ... and replace it with the values we just fetched from the server. |
| - for (DictionaryValue::Iterator iter(*target_languages); !iter.IsAtEnd(); |
| - iter.Advance()) { |
| - supported_languages_.Pointer()->insert(iter.key()); |
| - } |
| -} |
| - |
| -// static |
| -void TranslateManager::InitSupportedLanguages() { |
| - // If our list of supported languages have not been set yet, we default |
| - // to our hard coded list of languages in kDefaultSupportedLanguages. |
| - if (supported_languages_.Pointer()->empty()) { |
| - for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i) |
| - supported_languages_.Pointer()->insert(kDefaultSupportedLanguages[i]); |
| - } |
| -} |
| - |
| -// static |
| void TranslateManager::GetSupportedLanguages( |
| std::vector<std::string>* languages) { |
| - DCHECK(languages && languages->empty()); |
| - InitSupportedLanguages(); |
| - std::set<std::string>* supported_languages = supported_languages_.Pointer(); |
| - std::set<std::string>::const_iterator iter = supported_languages->begin(); |
| - for (; iter != supported_languages->end(); ++iter) |
| - languages->push_back(*iter); |
| + if (GetInstance()->language_list_.get()) { |
| + GetInstance()->language_list_->GetSupportedLanguages(languages); |
| + return; |
| + } |
| + NOTREACHED(); |
| } |
| // static |
| std::string TranslateManager::GetLanguageCode( |
| const std::string& chrome_locale) { |
| - // Only remove the country code for country specific languages we don't |
| - // support specifically yet. |
| - if (IsSupportedLanguage(chrome_locale)) |
| - return chrome_locale; |
| - |
| - size_t hypen_index = chrome_locale.find('-'); |
| - if (hypen_index == std::string::npos) |
| - return chrome_locale; |
| - return chrome_locale.substr(0, hypen_index); |
| + if (GetInstance()->language_list_.get()) |
| + return GetInstance()->language_list_->GetLanguageCode(chrome_locale); |
| + NOTREACHED(); |
| + return chrome_locale; |
| } |
| // static |
| -bool TranslateManager::IsSupportedLanguage(const std::string& page_language) { |
| - InitSupportedLanguages(); |
| - return supported_languages_.Pointer()->count(page_language) != 0; |
| +bool TranslateManager::IsSupportedLanguage(const std::string& language) { |
| + if (GetInstance()->language_list_.get()) |
| + return GetInstance()->language_list_->IsSupportedLanguage(language); |
| + NOTREACHED(); |
| + return false; |
| } |
| void TranslateManager::Observe(int type, |
| @@ -430,8 +269,7 @@ void TranslateManager::Observe(int type, |
| } |
| void TranslateManager::OnURLFetchComplete(const net::URLFetcher* source) { |
| - if (translate_script_request_pending_.get() != source && |
| - language_list_request_pending_.get() != source) { |
| + if (translate_script_request_pending_.get() != source) { |
| // Looks like crash on Mac is possibly caused with callback entering here |
| // with unknown fetcher when network is refreshed. |
| scoped_ptr<const net::URLFetcher> delete_ptr(source); |
| @@ -439,8 +277,8 @@ void TranslateManager::OnURLFetchComplete(const net::URLFetcher* source) { |
| } |
| bool error = |
| - (source->GetStatus().status() != net::URLRequestStatus::SUCCESS || |
| - source->GetResponseCode() != net::HTTP_OK); |
| + source->GetStatus().status() != net::URLRequestStatus::SUCCESS || |
| + source->GetResponseCode() != net::HTTP_OK; |
| if (translate_script_request_pending_.get() == source) { |
| scoped_ptr<const net::URLFetcher> delete_ptr( |
| translate_script_request_pending_.release()); |
| @@ -502,16 +340,6 @@ void TranslateManager::OnURLFetchComplete(const net::URLFetcher* source) { |
| } |
| } |
| pending_requests_.clear(); |
| - } else { // if (translate_script_request_pending_.get() == source) |
| - scoped_ptr<const net::URLFetcher> delete_ptr( |
| - language_list_request_pending_.release()); |
| - if (!error) { |
| - std::string data; |
| - source->GetResponseAsString(&data); |
| - SetSupportedLanguages(data); |
| - } else { |
| - VLOG(9) << "Failed to Fetch languages from: " << kLanguageListFetchURL; |
| - } |
| } |
| } |
| @@ -541,6 +369,7 @@ TranslateManager::TranslateManager() |
| content::NotificationService::AllSources()); |
| notification_registrar_.Add(this, chrome::NOTIFICATION_PAGE_TRANSLATED, |
| content::NotificationService::AllSources()); |
| + language_list_.reset(new TranslateLanguageList); |
| } |
| void TranslateManager::InitiateTranslation(WebContents* web_contents, |
| @@ -761,8 +590,8 @@ void TranslateManager::ReportLanguageDetectionError(WebContents* web_contents) { |
| kSourceLanguageQueryName, |
| translate_tab_helper->language_state().original_language()); |
| - report_error_url = AddHostLocaleToUrl(report_error_url); |
| - report_error_url = AddApiKeyToUrl(report_error_url); |
| + report_error_url = TranslateURLUtil::AddHostLocaleToUrl(report_error_url); |
| + report_error_url = TranslateURLUtil::AddApiKeyToUrl(report_error_url); |
| chrome::AddSelectedTabWithURL(browser, report_error_url, |
| content::PAGE_TRANSITION_AUTO_BOOKMARK); |
| @@ -878,8 +707,7 @@ void TranslateManager::InitAcceptLanguages(PrefService* prefs) { |
| void TranslateManager::FetchLanguageListFromTranslateServer( |
| PrefService* prefs) { |
| - if (language_list_request_pending_.get() != NULL) |
| - return; |
| + DCHECK(language_list_.get()); |
| // We don't want to do this when translate is disabled. |
| DCHECK(prefs != NULL); |
| @@ -889,34 +717,12 @@ void TranslateManager::FetchLanguageListFromTranslateServer( |
| return; |
| } |
| - GURL language_list_fetch_url = GURL(kLanguageListFetchURL); |
| - language_list_fetch_url = AddHostLocaleToUrl(language_list_fetch_url); |
| - language_list_fetch_url = AddApiKeyToUrl(language_list_fetch_url); |
| - |
| - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| - if (command_line.HasSwitch(switches::kEnableTranslateAlphaLanguages)) { |
| - language_list_fetch_url = net::AppendQueryParameter( |
| - language_list_fetch_url, |
| - kAlphaLanguageQueryName, |
| - kAlphaLanguageQueryValue); |
| - } |
| - |
| - VLOG(9) << "Fetch supporting language list from: " |
| - << language_list_fetch_url.spec().c_str(); |
| - |
| - language_list_request_pending_.reset(net::URLFetcher::Create( |
| - 1, language_list_fetch_url, net::URLFetcher::GET, this)); |
| - language_list_request_pending_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
| - net::LOAD_DO_NOT_SAVE_COOKIES); |
| - language_list_request_pending_->SetRequestContext( |
| - g_browser_process->system_request_context()); |
| - language_list_request_pending_->SetMaxRetriesOn5xx( |
| - kMaxRetryLanguageListFetch); |
| - language_list_request_pending_->Start(); |
| + if (language_list_.get()) |
|
MAD
2013/05/27 21:34:35
We usually don't have both a DCHECK and an if...
Takashi Toyoshima
2013/05/28 07:35:28
This is intended.
In the browser process, use-afte
|
| + language_list_->RequestLanguageList(); |
| } |
| void TranslateManager::CleanupPendingUlrFetcher() { |
| - language_list_request_pending_.reset(); |
| + language_list_.reset(); |
| translate_script_request_pending_.reset(); |
| } |
| @@ -948,8 +754,10 @@ void TranslateManager::RequestTranslateScript() { |
| kCallbackQueryName, |
| kCallbackQueryValue); |
| - translate_script_url = AddHostLocaleToUrl(translate_script_url); |
| - translate_script_url = AddApiKeyToUrl(translate_script_url); |
| + translate_script_url = |
| + TranslateURLUtil::AddHostLocaleToUrl(translate_script_url); |
| + translate_script_url = |
| + TranslateURLUtil::AddApiKeyToUrl(translate_script_url); |
| translate_script_request_pending_.reset(net::URLFetcher::Create( |
| 0, translate_script_url, net::URLFetcher::GET, this)); |
| @@ -965,7 +773,7 @@ void TranslateManager::RequestTranslateScript() { |
| // static |
| std::string TranslateManager::GetTargetLanguage(PrefService* prefs) { |
| std::string ui_lang = |
| - GetLanguageCode(g_browser_process->GetApplicationLocale()); |
| + GetLanguageCode(g_browser_process->GetApplicationLocale()); |
| if (IsSupportedLanguage(ui_lang)) |
| return ui_lang; |