translate_manager.h revision 868fa2fe829687343ffae624259930155e16dbd8
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.
4
5#ifndef CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_
6#define CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/gtest_prod_util.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/weak_ptr.h"
15#include "base/observer_list.h"
16#include "base/time.h"
17#include "chrome/common/translate/translate_errors.h"
18#include "content/public/browser/notification_observer.h"
19#include "content/public/browser/notification_registrar.h"
20#include "net/url_request/url_fetcher_delegate.h"
21
22template <typename T> struct DefaultSingletonTraits;
23class GURL;
24struct LanguageDetectionDetails;
25struct PageTranslatedDetails;
26class PrefService;
27struct ShortcutConfiguration;
28class TranslateAcceptLanguages;
29struct TranslateErrorDetails;
30struct TranslateEventDetails;
31class TranslateInfoBarDelegate;
32class TranslateLanguageList;
33
34namespace content {
35class WebContents;
36}
37
38namespace net {
39class URLFetcher;
40}
41
42// The TranslateManager class is responsible for showing an info-bar when a page
43// in a language different than the user language is loaded.  It triggers the
44// page translation the user requests.
45// It is a singleton.
46
47class TranslateManager : public content::NotificationObserver,
48                         public net::URLFetcherDelegate {
49 public:
50  // Returns the singleton instance.
51  static TranslateManager* GetInstance();
52
53  virtual ~TranslateManager();
54
55  // Returns true if the URL can be translated.
56  static bool IsTranslatableURL(const GURL& url);
57
58  // Fills |languages| with the list of languages that the translate server can
59  // translate to and from.
60  static void GetSupportedLanguages(std::vector<std::string>* languages);
61
62  // Returns the language code that can be used with the Translate method for a
63  // specified |chrome_locale|.
64  static std::string GetLanguageCode(const std::string& chrome_locale);
65
66  // Returns true if |language| is supported by the translation server.
67  static bool IsSupportedLanguage(const std::string& language);
68
69  // Returns true if |language| is supported by the translation server as a
70  // alpha language.
71  static bool IsAlphaLanguage(const std::string& language);
72
73  // Let the caller decide if and when we should fetch the language list from
74  // the translate server. This is a NOOP if switches::kDisableTranslate is set
75  // or if prefs::kEnableTranslate is set to false.
76  void FetchLanguageListFromTranslateServer(PrefService* prefs);
77
78  // Allows caller to cleanup pending URLFetcher objects to make sure they
79  // get released in the appropriate thread... Mainly for tests.
80  void CleanupPendingUlrFetcher();
81
82  // Translates the page contents from |source_lang| to |target_lang|.
83  // The actual translation might be performed asynchronously if the translate
84  // script is not yet available.
85  void TranslatePage(content::WebContents* web_contents,
86                     const std::string& source_lang,
87                     const std::string& target_lang);
88
89  // Reverts the contents of the page in |web_contents| to its original
90  // language.
91  void RevertTranslation(content::WebContents* web_contents);
92
93  // Reports to the Google translate server that a page language was incorrectly
94  // detected.  This call is initiated by the user selecting the "report" menu
95  // under options in the translate infobar.
96  void ReportLanguageDetectionError(content::WebContents* web_contents);
97
98  // Clears the translate script, so it will be fetched next time we translate.
99  void ClearTranslateScript() { translate_script_.clear(); }
100
101  // content::NotificationObserver implementation:
102  virtual void Observe(int type,
103                       const content::NotificationSource& source,
104                       const content::NotificationDetails& details) OVERRIDE;
105
106  // net::URLFetcherDelegate implementation:
107  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
108
109  // Used by unit-tests to override some defaults:
110  // Delay after which the translate script is fetched again from the
111  // translation server.
112  void set_translate_script_expiration_delay(int delay_ms) {
113    translate_script_expiration_delay_ =
114        base::TimeDelta::FromMilliseconds(delay_ms);
115  }
116
117  // Number of attempts before waiting for a page to be fully reloaded.
118  void set_translate_max_reload_attemps(int attempts) {
119    max_reload_check_attempts_ = attempts;
120  }
121
122  // The observer class for TranslateManager.
123  class Observer {
124   public:
125    virtual void OnLanguageDetection(
126        const LanguageDetectionDetails& details) = 0;
127    virtual void OnTranslateError(
128        const TranslateErrorDetails& details) = 0;
129    virtual void OnTranslateEvent(
130        const TranslateEventDetails& details) = 0;
131  };
132
133  // Adds/removes observer.
134  void AddObserver(Observer* obs);
135  void RemoveObserver(Observer* obs);
136
137  // Notifies to the observers when translate event happens.
138  void NotifyTranslateEvent(const TranslateEventDetails& details);
139
140 protected:
141  TranslateManager();
142
143 private:
144  friend struct DefaultSingletonTraits<TranslateManager>;
145
146  // Structure that describes a translate request.
147  // Translation may be deferred while the translate script is being retrieved
148  // from the translate server.
149  struct PendingRequest {
150    int render_process_id;
151    int render_view_id;
152    int page_id;
153    std::string source_lang;
154    std::string target_lang;
155  };
156
157  // Starts the translation process on |tab| containing the page in the
158  // |page_lang| language.
159  void InitiateTranslation(content::WebContents* web_contents,
160                           const std::string& page_lang);
161
162  // If the tab identified by |process_id| and |render_id| has been closed, this
163  // does nothing, otherwise it calls InitiateTranslation.
164  void InitiateTranslationPosted(int process_id, int render_id,
165                                 const std::string& page_lang, int attempt);
166
167  // Sends a translation request to the RenderView of |web_contents|.
168  void DoTranslatePage(content::WebContents* web_contents,
169                       const std::string& translate_script,
170                       const std::string& source_lang,
171                       const std::string& target_lang);
172
173  // Shows the after translate or error infobar depending on the details.
174  void PageTranslated(content::WebContents* web_contents,
175                      PageTranslatedDetails* details);
176
177  // Fetches the JS translate script (the script that is injected in the page
178  // to translate it).
179  void RequestTranslateScript();
180
181  // Notifies to the observers when a language is detected.
182  void NotifyLanguageDetection(const LanguageDetectionDetails& details);
183
184  // Notifies to the observers when translate failed.
185  void NotifyTranslateError(const TranslateErrorDetails& details);
186
187  // Returns the language to translate to. The language returned is the
188  // first language found in the following list that is supported by the
189  // translation service:
190  //     the UI language
191  //     the accept-language list
192  // If no language is found then an empty string is returned.
193  static std::string GetTargetLanguage(PrefService* prefs);
194
195  // Returns the different parameters used to decide whether extra shortcuts
196  // are needed.
197  static ShortcutConfiguration ShortcutConfig();
198
199  content::NotificationRegistrar notification_registrar_;
200
201  base::WeakPtrFactory<TranslateManager> weak_method_factory_;
202
203  // The JS injected in the page to do the translation.
204  std::string translate_script_;
205
206  // Delay after which the translate script is fetched again
207  // from the translate server.
208  base::TimeDelta translate_script_expiration_delay_;
209
210  // Max number of attempts before checking if a page has been reloaded.
211  int max_reload_check_attempts_;
212
213  // Set when the translate JS is currently being retrieved. NULL otherwise.
214  scoped_ptr<net::URLFetcher> translate_script_request_pending_;
215
216  // The list of pending translate requests.  Translate requests are queued when
217  // the translate script is not ready and has to be fetched from the translate
218  // server.
219  std::vector<PendingRequest> pending_requests_;
220
221  // List of registered observers.
222  ObserverList<Observer> observer_list_;
223
224  // An instance of TranslateLanguageList which manages supported language list.
225  scoped_ptr<TranslateLanguageList> language_list_;
226
227  // An instance of TranslateAcceptLanguages which manages Accept languages of
228  // each profiles.
229  scoped_ptr<TranslateAcceptLanguages> accept_languages_;
230
231  DISALLOW_COPY_AND_ASSIGN(TranslateManager);
232};
233
234#endif  // CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_
235