13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/lazy_instance.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_change_registrar.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/url_fetcher.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/translate_errors.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_observer.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsentemplate <typename T> struct DefaultSingletonTraits; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GURL; 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct PageTranslatedDetails; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass PrefService; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TabContents; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TranslateInfoBarDelegate; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The TranslateManager class is responsible for showing an info-bar when a page 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in a language different than the user language is loaded. It triggers the 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// page translation the user requests. 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// It is a singleton. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TranslateManager : public NotificationObserver, 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public URLFetcher::Delegate { 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Returns the singleton instance. 3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static TranslateManager* GetInstance(); 3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~TranslateManager(); 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Translates the page contents from |source_lang| to |target_lang|. 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The actual translation might be performed asynchronously if the translate 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // script is not yet available. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void TranslatePage(TabContents* tab_contents, 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& source_lang, 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& target_lang); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reverts the contents of the page in |tab_contents| to its original 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // language. 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RevertTranslation(TabContents* tab_contents); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reports to the Google translate server that a page language was incorrectly 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // detected. This call is initiated by the user selecting the "report" menu 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // under options in the translate infobar. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ReportLanguageDetectionError(TabContents* tab_contents); 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Clears the translate script, so it will be fetched next time we translate. 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ClearTranslateScript() { translate_script_.clear(); } 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NotificationObserver implementation: 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Observe(NotificationType type, 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // URLFetcher::Delegate implementation: 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnURLFetchComplete(const URLFetcher* source, 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const net::URLRequestStatus& status, 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int response_code, 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ResponseCookies& cookies, 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& data); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Used by unit-tests to override the default delay after which the translate 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // script is fetched again from the translation server. 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_translate_script_expiration_delay(int delay_ms) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch translate_script_expiration_delay_ = delay_ms; 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Convenience method to know if a tab is showing a translate infobar. 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static bool IsShowingTranslateInfobar(TabContents* tab); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Returns true if the URL can be translated. 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static bool IsTranslatableURL(const GURL& url); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fills |languages| with the list of languages that the translate server can 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // translate to and from. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void GetSupportedLanguages(std::vector<std::string>* languages); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the language code that can be used with the Translate method for a 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // specified |chrome_locale|. 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static std::string GetLanguageCode(const std::string& chrome_locale); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if |language| is supported by the translation server. 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static bool IsSupportedLanguage(const std::string& language); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TranslateManager(); 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend struct DefaultSingletonTraits<TranslateManager>; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Structure that describes a translate request. 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Translation may be deferred while the translate script is being retrieved 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // from the translate server. 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct PendingRequest { 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_process_id; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_view_id; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int page_id; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string source_lang; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string target_lang; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Starts the translation process on |tab| containing the page in the 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |page_lang| language. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void InitiateTranslation(TabContents* tab, const std::string& page_lang); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the tab identified by |process_id| and |render_id| has been closed, this 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // does nothing, otherwise it calls InitiateTranslation. 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void InitiateTranslationPosted(int process_id, 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int render_id, 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& page_lang); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sends a translation request to the RenderView of |tab_contents|. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void DoTranslatePage(TabContents* tab_contents, 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& translate_script, 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& source_lang, 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& target_lang); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shows the after translate or error infobar depending on the details. 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void PageTranslated(TabContents* tab, PageTranslatedDetails* details); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if the passed language has been configured by the user as an 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // accept language. 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool IsAcceptLanguage(TabContents* tab, const std::string& language); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initializes the |accept_languages_| language table based on the associated 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // preference in |prefs|. 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void InitAcceptLanguages(PrefService* prefs); 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fetches the JS translate script (the script that is injected in the page 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to translate it). 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RequestTranslateScript(); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shows the specified translate |infobar| in the given |tab|. If a current 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // translate infobar is showing, it just replaces it with the new one. 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ShowInfoBar(TabContents* tab, TranslateInfoBarDelegate* infobar); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the language to translate to, which is the language the UI is 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // configured in. Returns an empty string if that language is not supported 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // by the translation service. 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static std::string GetTargetLanguage(); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the translate info bar showing in |tab| or NULL if none is showing. 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static TranslateInfoBarDelegate* GetTranslateInfoBarDelegate( 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationRegistrar notification_registrar_; 1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PrefChangeRegistrar pref_change_registrar_; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A map that associates a profile with its parsed "accept languages". 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::set<std::string> LanguageSet; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::map<PrefService*, LanguageSet> PrefServiceLanguagesMap; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefServiceLanguagesMap accept_languages_; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedRunnableMethodFactory<TranslateManager> method_factory_; 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The JS injected in the page to do the translation. 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string translate_script_; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Delay in milli-seconds after which the translate script is fetched again 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // from the translate server. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int translate_script_expiration_delay_; 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Whether the translate JS is currently being retrieved. 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool translate_script_request_pending_; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The list of pending translate requests. Translate requests are queued when 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the translate script is not ready and has to be fetched from the translate 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // server. 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PendingRequest> pending_requests_; 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The languages supported by the translation server. 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static base::LazyInstance<std::set<std::string> > supported_languages_; 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(TranslateManager); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_ 190