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