NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / translate / translate_manager.cc
blobc2e19d5ba35d0b823e708c99d675ef06549aa658
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
3 // found in the LICENSE file.
5 #include "chrome/browser/translate/translate_manager.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/memory/singleton.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/metrics/histogram.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/time/time.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/tab_contents/tab_util.h"
20 #include "chrome/browser/translate/translate_tab_helper.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_finder.h"
23 #include "chrome/browser/ui/browser_tabstrip.h"
24 #include "chrome/browser/ui/tabs/tab_strip_model.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/common/render_messages.h"
27 #include "chrome/common/url_constants.h"
28 #include "components/translate/core/browser/language_state.h"
29 #include "components/translate/core/browser/page_translated_details.h"
30 #include "components/translate/core/browser/translate_accept_languages.h"
31 #include "components/translate/core/browser/translate_browser_metrics.h"
32 #include "components/translate/core/browser/translate_download_manager.h"
33 #include "components/translate/core/browser/translate_error_details.h"
34 #include "components/translate/core/browser/translate_language_list.h"
35 #include "components/translate/core/browser/translate_prefs.h"
36 #include "components/translate/core/browser/translate_script.h"
37 #include "components/translate/core/browser/translate_url_util.h"
38 #include "components/translate/core/common/language_detection_details.h"
39 #include "components/translate/core/common/translate_constants.h"
40 #include "components/translate/core/common/translate_pref_names.h"
41 #include "components/translate/core/common/translate_switches.h"
42 #include "content/public/browser/navigation_controller.h"
43 #include "content/public/browser/navigation_details.h"
44 #include "content/public/browser/navigation_entry.h"
45 #include "content/public/browser/notification_details.h"
46 #include "content/public/browser/notification_service.h"
47 #include "content/public/browser/notification_source.h"
48 #include "content/public/browser/notification_types.h"
49 #include "content/public/browser/render_process_host.h"
50 #include "content/public/browser/render_view_host.h"
51 #include "content/public/browser/web_contents.h"
52 #include "net/base/url_util.h"
53 #include "net/http/http_status_code.h"
55 #if defined(OS_CHROMEOS)
56 #include "chrome/browser/chromeos/file_manager/app_id.h"
57 #include "extensions/common/constants.h"
58 #endif
60 using content::NavigationController;
61 using content::NavigationEntry;
62 using content::WebContents;
64 namespace {
66 const char kReportLanguageDetectionErrorURL[] =
67 "https://translate.google.com/translate_error?client=cr&action=langidc";
69 // Used in kReportLanguageDetectionErrorURL to specify the original page
70 // language.
71 const char kSourceLanguageQueryName[] = "sl";
73 // Used in kReportLanguageDetectionErrorURL to specify the page URL.
74 const char kUrlQueryName[] = "u";
76 // The maximum number of attempts we'll do to see if the page has finshed
77 // loading before giving up the translation
78 const int kMaxTranslateLoadCheckAttempts = 20;
80 } // namespace
82 TranslateManager::~TranslateManager() {
85 // static
86 TranslateManager* TranslateManager::GetInstance() {
87 return Singleton<TranslateManager>::get();
90 // static
91 bool TranslateManager::IsTranslatableURL(const GURL& url) {
92 // A URLs is translatable unless it is one of the following:
93 // - empty (can happen for popups created with window.open(""))
94 // - an internal URL (chrome:// and others)
95 // - the devtools (which is considered UI)
96 // - Chrome OS file manager extension
97 // - an FTP page (as FTP pages tend to have long lists of filenames that may
98 // confuse the CLD)
99 return !url.is_empty() &&
100 !url.SchemeIs(content::kChromeUIScheme) &&
101 !url.SchemeIs(chrome::kChromeDevToolsScheme) &&
102 #if defined(OS_CHROMEOS)
103 !(url.SchemeIs(extensions::kExtensionScheme) &&
104 url.DomainIs(file_manager::kFileManagerAppId)) &&
105 #endif
106 !url.SchemeIs(content::kFtpScheme);
109 void TranslateManager::Observe(int type,
110 const content::NotificationSource& source,
111 const content::NotificationDetails& details) {
112 switch (type) {
113 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
114 NavigationController* controller =
115 content::Source<NavigationController>(source).ptr();
116 content::LoadCommittedDetails* load_details =
117 content::Details<content::LoadCommittedDetails>(details).ptr();
118 NavigationEntry* entry = controller->GetActiveEntry();
119 if (!entry) {
120 NOTREACHED();
121 return;
124 TranslateTabHelper* translate_tab_helper =
125 TranslateTabHelper::FromWebContents(controller->GetWebContents());
126 if (!translate_tab_helper)
127 return;
129 // If the navigation happened while offline don't show the translate
130 // bar since there will be nothing to translate.
131 if (load_details->http_status_code == 0 ||
132 load_details->http_status_code == net::HTTP_INTERNAL_SERVER_ERROR) {
133 return;
136 if (!load_details->is_main_frame &&
137 translate_tab_helper->GetLanguageState().translation_declined()) {
138 // Some sites (such as Google map) may trigger sub-frame navigations
139 // when the user interacts with the page. We don't want to show a new
140 // infobar if the user already dismissed one in that case.
141 return;
143 if (entry->GetTransitionType() != content::PAGE_TRANSITION_RELOAD &&
144 load_details->type != content::NAVIGATION_TYPE_SAME_PAGE) {
145 return;
148 // When doing a page reload, TAB_LANGUAGE_DETERMINED is not sent,
149 // so the translation needs to be explicitly initiated, but only when the
150 // page needs translation.
151 if (!translate_tab_helper->GetLanguageState().page_needs_translation())
152 return;
153 // Note that we delay it as the TranslateManager gets this notification
154 // before the WebContents and the WebContents processing might remove the
155 // current infobars. Since InitTranslation might add an infobar, it must
156 // be done after that.
157 base::MessageLoop::current()->PostTask(FROM_HERE,
158 base::Bind(
159 &TranslateManager::InitiateTranslationPosted,
160 weak_method_factory_.GetWeakPtr(),
161 controller->GetWebContents()->GetRenderProcessHost()->GetID(),
162 controller->GetWebContents()->GetRenderViewHost()->GetRoutingID(),
163 translate_tab_helper->GetLanguageState().original_language(), 0));
164 break;
166 case chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED: {
167 const LanguageDetectionDetails* lang_det_details =
168 content::Details<const LanguageDetectionDetails>(details).ptr();
170 WebContents* tab = content::Source<WebContents>(source).ptr();
171 if (!tab->GetBrowserContext()->IsOffTheRecord())
172 NotifyLanguageDetection(*lang_det_details);
174 // We may get this notifications multiple times. Make sure to translate
175 // only once.
176 TranslateTabHelper* translate_tab_helper =
177 TranslateTabHelper::FromWebContents(tab);
178 if (!translate_tab_helper)
179 return;
181 LanguageState& language_state = translate_tab_helper->GetLanguageState();
182 if (language_state.page_needs_translation() &&
183 !language_state.translation_pending() &&
184 !language_state.translation_declined() &&
185 !language_state.IsPageTranslated()) {
186 std::string language = lang_det_details->adopted_language;
187 InitiateTranslation(tab, language);
189 break;
191 case chrome::NOTIFICATION_PAGE_TRANSLATED: {
192 // Only add translate infobar if it doesn't exist; if it already exists,
193 // just update the state, the actual infobar would have received the same
194 // notification and update the visual display accordingly.
195 WebContents* tab = content::Source<WebContents>(source).ptr();
196 PageTranslatedDetails* page_translated_details =
197 content::Details<PageTranslatedDetails>(details).ptr();
198 PageTranslated(tab, page_translated_details);
199 break;
201 default:
202 NOTREACHED();
206 void TranslateManager::AddObserver(Observer* obs) {
207 observer_list_.AddObserver(obs);
210 void TranslateManager::RemoveObserver(Observer* obs) {
211 observer_list_.RemoveObserver(obs);
214 void TranslateManager::NotifyLanguageDetection(
215 const LanguageDetectionDetails& details) {
216 FOR_EACH_OBSERVER(Observer, observer_list_, OnLanguageDetection(details));
219 void TranslateManager::NotifyTranslateError(
220 const TranslateErrorDetails& details) {
221 FOR_EACH_OBSERVER(Observer, observer_list_, OnTranslateError(details));
224 TranslateManager::TranslateManager()
225 : max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts),
226 weak_method_factory_(this) {
227 notification_registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
228 content::NotificationService::AllSources());
229 notification_registrar_.Add(this,
230 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED,
231 content::NotificationService::AllSources());
232 notification_registrar_.Add(this, chrome::NOTIFICATION_PAGE_TRANSLATED,
233 content::NotificationService::AllSources());
236 void TranslateManager::InitiateTranslation(WebContents* web_contents,
237 const std::string& page_lang) {
238 TranslateTabHelper* translate_tab_helper =
239 TranslateTabHelper::FromWebContents(web_contents);
240 if (!translate_tab_helper)
241 return;
243 Profile* profile =
244 Profile::FromBrowserContext(web_contents->GetBrowserContext());
245 Profile* original_profile = profile->GetOriginalProfile();
246 PrefService* prefs = original_profile->GetPrefs();
247 if (!prefs->GetBoolean(prefs::kEnableTranslate)) {
248 TranslateBrowserMetrics::ReportInitiationStatus(
249 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_PREFS);
250 const std::string& locale = g_browser_process->GetApplicationLocale();
251 TranslateBrowserMetrics::ReportLocalesOnDisabledByPrefs(locale);
252 return;
255 // Allow disabling of translate from the command line to assist with
256 // automated browser testing.
257 if (CommandLine::ForCurrentProcess()->HasSwitch(
258 translate::switches::kDisableTranslate)) {
259 TranslateBrowserMetrics::ReportInitiationStatus(
260 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_SWITCH);
261 return;
264 // MHTML pages currently cannot be translated.
265 // See bug: 217945.
266 if (web_contents->GetContentsMimeType() == "multipart/related") {
267 TranslateBrowserMetrics::ReportInitiationStatus(
268 TranslateBrowserMetrics::INITIATION_STATUS_MIME_TYPE_IS_NOT_SUPPORTED);
269 return;
272 // Don't translate any Chrome specific page, e.g., New Tab Page, Download,
273 // History, and so on.
274 GURL page_url = web_contents->GetURL();
275 if (!IsTranslatableURL(page_url)) {
276 TranslateBrowserMetrics::ReportInitiationStatus(
277 TranslateBrowserMetrics::INITIATION_STATUS_URL_IS_NOT_SUPPORTED);
278 return;
281 std::string target_lang = GetTargetLanguage(prefs);
282 std::string language_code =
283 TranslateDownloadManager::GetLanguageCode(page_lang);
285 // Don't translate similar languages (ex: en-US to en).
286 if (language_code == target_lang) {
287 TranslateBrowserMetrics::ReportInitiationStatus(
288 TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES);
289 return;
292 // Nothing to do if either the language Chrome is in or the language of the
293 // page is not supported by the translation server.
294 if (target_lang.empty() ||
295 !TranslateDownloadManager::IsSupportedLanguage(language_code)) {
296 TranslateBrowserMetrics::ReportInitiationStatus(
297 TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED);
298 TranslateBrowserMetrics::ReportUnsupportedLanguageAtInitiation(
299 language_code);
300 return;
303 scoped_ptr<TranslatePrefs> translate_prefs(
304 TranslateTabHelper::CreateTranslatePrefs(profile->GetPrefs()));
306 TranslateAcceptLanguages* accept_languages =
307 TranslateTabHelper::GetTranslateAcceptLanguages(profile);
308 // Don't translate any user black-listed languages.
309 if (!translate_prefs->CanTranslateLanguage(accept_languages,
310 language_code)) {
311 TranslateBrowserMetrics::ReportInitiationStatus(
312 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG);
313 return;
316 // Don't translate any user black-listed URLs.
317 if (translate_prefs->IsSiteBlacklisted(page_url.HostNoBrackets())) {
318 TranslateBrowserMetrics::ReportInitiationStatus(
319 TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG);
320 return;
323 // If the user has previously selected "always translate" for this language we
324 // automatically translate. Note that in incognito mode we disable that
325 // feature; the user will get an infobar, so they can control whether the
326 // page's text is sent to the translate server.
327 if (!web_contents->GetBrowserContext()->IsOffTheRecord()) {
328 std::string auto_target_lang = GetAutoTargetLanguage(language_code, prefs);
329 if (!auto_target_lang.empty()) {
330 TranslateBrowserMetrics::ReportInitiationStatus(
331 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG);
332 TranslatePage(web_contents, language_code, auto_target_lang);
333 return;
337 LanguageState& language_state = translate_tab_helper->GetLanguageState();
338 std::string auto_translate_to = language_state.AutoTranslateTo();
339 if (!auto_translate_to.empty()) {
340 // This page was navigated through a click from a translated page.
341 TranslateBrowserMetrics::ReportInitiationStatus(
342 TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK);
343 TranslatePage(web_contents, language_code, auto_translate_to);
344 return;
347 TranslateBrowserMetrics::ReportInitiationStatus(
348 TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR);
350 // Prompts the user if he/she wants the page translated.
351 translate_tab_helper->ShowTranslateUI(TranslateTabHelper::BEFORE_TRANSLATE,
352 web_contents,
353 language_code,
354 target_lang,
355 TranslateErrors::NONE);
358 void TranslateManager::InitiateTranslationPosted(int process_id,
359 int render_id,
360 const std::string& page_lang,
361 int attempt) {
362 // The tab might have been closed.
363 WebContents* web_contents =
364 tab_util::GetWebContentsByID(process_id, render_id);
365 if (!web_contents)
366 return;
368 TranslateTabHelper* translate_tab_helper =
369 TranslateTabHelper::FromWebContents(web_contents);
370 if (translate_tab_helper->GetLanguageState().translation_pending())
371 return;
373 // During a reload we need web content to be available before the
374 // translate script is executed. Otherwise we will run the translate script on
375 // an empty DOM which will fail. Therefore we wait a bit to see if the page
376 // has finished.
377 if ((web_contents->IsLoading()) && attempt < kMaxTranslateLoadCheckAttempts) {
378 int backoff = attempt * max_reload_check_attempts_;
379 base::MessageLoop::current()->PostDelayedTask(
380 FROM_HERE, base::Bind(&TranslateManager::InitiateTranslationPosted,
381 weak_method_factory_.GetWeakPtr(), process_id,
382 render_id, page_lang, ++attempt),
383 base::TimeDelta::FromMilliseconds(backoff));
384 return;
387 InitiateTranslation(web_contents,
388 TranslateDownloadManager::GetLanguageCode(page_lang));
391 void TranslateManager::TranslatePage(WebContents* web_contents,
392 const std::string& original_source_lang,
393 const std::string& target_lang) {
394 NavigationEntry* entry = web_contents->GetController().GetActiveEntry();
395 if (!entry) {
396 NOTREACHED();
397 return;
400 // Translation can be kicked by context menu against unsupported languages.
401 // Unsupported language strings should be replaced with
402 // kUnknownLanguageCode in order to send a translation request with enabling
403 // server side auto language detection.
404 std::string source_lang(original_source_lang);
405 if (!TranslateDownloadManager::IsSupportedLanguage(source_lang))
406 source_lang = std::string(translate::kUnknownLanguageCode);
408 TranslateTabHelper* translate_tab_helper =
409 TranslateTabHelper::FromWebContents(web_contents);
410 DCHECK(translate_tab_helper);
411 translate_tab_helper->ShowTranslateUI(TranslateTabHelper::TRANSLATING,
412 web_contents,
413 source_lang,
414 target_lang,
415 TranslateErrors::NONE);
417 TranslateScript* script = TranslateDownloadManager::GetInstance()->script();
418 DCHECK(script != NULL);
420 const std::string& script_data = script->data();
421 if (!script_data.empty()) {
422 DoTranslatePage(web_contents, script_data, source_lang, target_lang);
423 return;
426 // The script is not available yet. Queue that request and query for the
427 // script. Once it is downloaded we'll do the translate.
428 content::RenderViewHost* rvh = web_contents->GetRenderViewHost();
429 PendingRequest request;
430 request.render_process_id = rvh->GetProcess()->GetID();
431 request.render_view_id = rvh->GetRoutingID();
432 request.page_id = entry->GetPageID();
433 request.source_lang = source_lang;
434 request.target_lang = target_lang;
435 pending_requests_.push_back(request);
437 if (script->HasPendingRequest())
438 return;
440 script->Request(base::Bind(&TranslateManager::OnTranslateScriptFetchComplete,
441 base::Unretained(this)));
444 void TranslateManager::RevertTranslation(WebContents* web_contents) {
445 NavigationEntry* entry = web_contents->GetController().GetActiveEntry();
446 if (!entry) {
447 NOTREACHED();
448 return;
450 web_contents->GetRenderViewHost()->Send(new ChromeViewMsg_RevertTranslation(
451 web_contents->GetRenderViewHost()->GetRoutingID(), entry->GetPageID()));
453 TranslateTabHelper* translate_tab_helper =
454 TranslateTabHelper::FromWebContents(web_contents);
455 translate_tab_helper->GetLanguageState().SetCurrentLanguage(
456 translate_tab_helper->GetLanguageState().original_language());
459 void TranslateManager::ReportLanguageDetectionError(WebContents* web_contents) {
460 TranslateBrowserMetrics::ReportLanguageDetectionError();
461 // We'll open the URL in a new tab so that the user can tell us more.
462 Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
463 if (!browser) {
464 NOTREACHED();
465 return;
468 GURL report_error_url = GURL(kReportLanguageDetectionErrorURL);
470 GURL page_url = web_contents->GetController().GetActiveEntry()->GetURL();
471 report_error_url = net::AppendQueryParameter(
472 report_error_url,
473 kUrlQueryName,
474 page_url.spec());
476 TranslateTabHelper* translate_tab_helper =
477 TranslateTabHelper::FromWebContents(web_contents);
478 report_error_url = net::AppendQueryParameter(
479 report_error_url,
480 kSourceLanguageQueryName,
481 translate_tab_helper->GetLanguageState().original_language());
483 report_error_url = TranslateURLUtil::AddHostLocaleToUrl(report_error_url);
484 report_error_url = TranslateURLUtil::AddApiKeyToUrl(report_error_url);
486 chrome::AddSelectedTabWithURL(browser, report_error_url,
487 content::PAGE_TRANSITION_AUTO_BOOKMARK);
490 void TranslateManager::DoTranslatePage(WebContents* web_contents,
491 const std::string& translate_script,
492 const std::string& source_lang,
493 const std::string& target_lang) {
494 NavigationEntry* entry = web_contents->GetController().GetActiveEntry();
495 if (!entry) {
496 NOTREACHED();
497 return;
500 TranslateTabHelper* translate_tab_helper =
501 TranslateTabHelper::FromWebContents(web_contents);
502 if (!translate_tab_helper)
503 return;
505 translate_tab_helper->GetLanguageState().set_translation_pending(true);
506 web_contents->GetRenderViewHost()->Send(new ChromeViewMsg_TranslatePage(
507 web_contents->GetRenderViewHost()->GetRoutingID(), entry->GetPageID(),
508 translate_script, source_lang, target_lang));
511 void TranslateManager::PageTranslated(WebContents* web_contents,
512 PageTranslatedDetails* details) {
513 if ((details->error_type == TranslateErrors::NONE) &&
514 details->source_language != translate::kUnknownLanguageCode &&
515 !TranslateDownloadManager::IsSupportedLanguage(
516 details->source_language)) {
517 details->error_type = TranslateErrors::UNSUPPORTED_LANGUAGE;
520 TranslateTabHelper* translate_tab_helper =
521 TranslateTabHelper::FromWebContents(web_contents);
522 DCHECK(translate_tab_helper);
523 translate_tab_helper->ShowTranslateUI(TranslateTabHelper::AFTER_TRANSLATE,
524 web_contents,
525 details->source_language,
526 details->target_language,
527 details->error_type);
529 if (details->error_type != TranslateErrors::NONE &&
530 !web_contents->GetBrowserContext()->IsOffTheRecord()) {
531 TranslateErrorDetails error_details;
532 error_details.time = base::Time::Now();
533 error_details.url = web_contents->GetLastCommittedURL();
534 error_details.error = details->error_type;
535 NotifyTranslateError(error_details);
539 void TranslateManager::OnTranslateScriptFetchComplete(
540 bool success, const std::string& data) {
541 std::vector<PendingRequest>::const_iterator iter;
542 for (iter = pending_requests_.begin(); iter != pending_requests_.end();
543 ++iter) {
544 const PendingRequest& request = *iter;
545 WebContents* web_contents =
546 tab_util::GetWebContentsByID(request.render_process_id,
547 request.render_view_id);
548 if (!web_contents) {
549 // The tab went away while we were retrieving the script.
550 continue;
552 NavigationEntry* entry = web_contents->GetController().GetActiveEntry();
553 if (!entry || entry->GetPageID() != request.page_id) {
554 // We navigated away from the page the translation was triggered on.
555 continue;
558 if (success) {
559 // Translate the page.
560 TranslateScript* translate_script =
561 TranslateDownloadManager::GetInstance()->script();
562 DCHECK(translate_script);
563 DoTranslatePage(web_contents, translate_script->data(),
564 request.source_lang, request.target_lang);
565 } else {
566 TranslateTabHelper* translate_tab_helper =
567 TranslateTabHelper::FromWebContents(web_contents);
568 DCHECK(translate_tab_helper);
569 translate_tab_helper->ShowTranslateUI(TranslateTabHelper::TRANSLATE_ERROR,
570 web_contents,
571 request.source_lang,
572 request.target_lang,
573 TranslateErrors::NETWORK);
575 if (!web_contents->GetBrowserContext()->IsOffTheRecord()) {
576 TranslateErrorDetails error_details;
577 error_details.time = base::Time::Now();
578 error_details.url = entry->GetURL();
579 error_details.error = TranslateErrors::NETWORK;
580 NotifyTranslateError(error_details);
584 pending_requests_.clear();
587 // static
588 std::string TranslateManager::GetTargetLanguage(PrefService* prefs) {
589 std::string ui_lang = TranslatePrefs::ConvertLangCodeForTranslation(
590 TranslateDownloadManager::GetLanguageCode(
591 g_browser_process->GetApplicationLocale()));
593 if (TranslateDownloadManager::IsSupportedLanguage(ui_lang))
594 return ui_lang;
596 // Getting the accepted languages list
597 std::string accept_langs_str = prefs->GetString(prefs::kAcceptLanguages);
599 std::vector<std::string> accept_langs_list;
600 base::SplitString(accept_langs_str, ',', &accept_langs_list);
602 // Will translate to the first supported language on the Accepted Language
603 // list or not at all if no such candidate exists
604 std::vector<std::string>::iterator iter;
605 for (iter = accept_langs_list.begin();
606 iter != accept_langs_list.end(); ++iter) {
607 std::string lang_code = TranslateDownloadManager::GetLanguageCode(*iter);
608 if (TranslateDownloadManager::IsSupportedLanguage(lang_code))
609 return lang_code;
611 return std::string();
614 // static
615 std::string TranslateManager::GetAutoTargetLanguage(
616 const std::string& original_language,
617 PrefService* prefs) {
618 std::string auto_target_lang;
619 scoped_ptr<TranslatePrefs> translate_prefs(
620 TranslateTabHelper::CreateTranslatePrefs(prefs));
621 if (translate_prefs->ShouldAutoTranslate(original_language,
622 &auto_target_lang)) {
623 // We need to confirm that the saved target language is still supported.
624 // Also, GetLanguageCode will take care of removing country code if any.
625 auto_target_lang =
626 TranslateDownloadManager::GetLanguageCode(auto_target_lang);
627 if (TranslateDownloadManager::IsSupportedLanguage(auto_target_lang))
628 return auto_target_lang;
630 return std::string();