• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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_RENDERER_TRANSLATE_TRANSLATE_HELPER_H_
6 #define CHROME_RENDERER_TRANSLATE_TRANSLATE_HELPER_H_
7 
8 #include <string>
9 
10 #include "base/gtest_prod_util.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/strings/string16.h"
13 #include "base/time/time.h"
14 #include "components/translate/core/common/translate_errors.h"
15 #include "content/public/renderer/render_view_observer.h"
16 
17 #if defined(CLD2_DYNAMIC_MODE)
18 #include "base/files/file.h"
19 #include "base/files/memory_mapped_file.h"
20 #include "base/lazy_instance.h"
21 #include "ipc/ipc_platform_file.h"
22 #include "url/gurl.h"
23 #endif
24 
25 namespace blink {
26 class WebDocument;
27 class WebFrame;
28 }
29 
30 // This class deals with page translation.
31 // There is one TranslateHelper per RenderView.
32 
33 class TranslateHelper : public content::RenderViewObserver {
34  public:
35   explicit TranslateHelper(content::RenderView* render_view);
36   virtual ~TranslateHelper();
37 
38   // Informs us that the page's text has been extracted.
39   void PageCaptured(int page_id, const base::string16& contents);
40 
41   // Lets the translation system know that we are preparing to navigate to
42   // the specified URL. If there is anything that can or should be done before
43   // this URL loads, this is the time to prepare for it.
44   void PrepareForUrl(const GURL& url);
45 
46  protected:
47   // The following methods are protected so they can be overridden in
48   // unit-tests.
49   void OnTranslatePage(int page_id,
50                        const std::string& translate_script,
51                        const std::string& source_lang,
52                        const std::string& target_lang);
53   void OnRevertTranslation(int page_id);
54 
55   // Returns true if the translate library is available, meaning the JavaScript
56   // has already been injected in that page.
57   virtual bool IsTranslateLibAvailable();
58 
59   // Returns true if the translate library has been initialized successfully.
60   virtual bool IsTranslateLibReady();
61 
62   // Returns true if the translation script has finished translating the page.
63   virtual bool HasTranslationFinished();
64 
65   // Returns true if the translation script has reported an error performing the
66   // translation.
67   virtual bool HasTranslationFailed();
68 
69   // Starts the translation by calling the translate library.  This method
70   // should only be called when the translate script has been injected in the
71   // page.  Returns false if the call failed immediately.
72   virtual bool StartTranslation();
73 
74   // Asks the Translate element in the page what the language of the page is.
75   // Can only be called if a translation has happened and was successful.
76   // Returns the language code on success, an empty string on failure.
77   virtual std::string GetOriginalPageLanguage();
78 
79   // Adjusts a delay time for a posted task. This is used in tests to do tasks
80   // immediately by returning 0.
81   virtual base::TimeDelta AdjustDelay(int delayInMs);
82 
83   // Executes the JavaScript code in |script| in the main frame of RenderView.
84   virtual void ExecuteScript(const std::string& script);
85 
86   // Executes the JavaScript code in |script| in the main frame of RenderView,
87   // and returns the boolean returned by the script evaluation if the script was
88   // run successfully. Otherwise, returns |fallback| value.
89   virtual bool ExecuteScriptAndGetBoolResult(const std::string& script,
90                                              bool fallback);
91 
92   // Executes the JavaScript code in |script| in the main frame of RenderView,
93   // and returns the string returned by the script evaluation if the script was
94   // run successfully. Otherwise, returns empty string.
95   virtual std::string ExecuteScriptAndGetStringResult(
96       const std::string& script);
97 
98   // Executes the JavaScript code in |script| in the main frame of RenderView.
99   // and returns the number returned by the script evaluation if the script was
100   // run successfully. Otherwise, returns 0.0.
101   virtual double ExecuteScriptAndGetDoubleResult(const std::string& script);
102 
103  private:
104   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, AdoptHtmlLang);
105   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest,
106                            CLDAgreeWithLanguageCodeHavingCountryCode);
107   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest,
108                            CLDDisagreeWithWrongLanguageCode);
109   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest,
110                            InvalidLanguageMetaTagProviding);
111   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, LanguageCodeTypoCorrection);
112   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, LanguageCodeSynonyms);
113   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, ResetInvalidLanguageCode);
114   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, SimilarLanguageCode);
115   FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, WellKnownWrongConfiguration);
116 
117   // Converts language code to the one used in server supporting list.
118   static void ConvertLanguageCodeSynonym(std::string* code);
119 
120   // Returns whether the page associated with |document| is a candidate for
121   // translation.  Some pages can explictly specify (via a meta-tag) that they
122   // should not be translated.
123   static bool IsTranslationAllowed(blink::WebDocument* document);
124 
125   // RenderViewObserver implementation.
126   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
127 
128   // Cancels any translation that is currently being performed.  This does not
129   // revert existing translations.
130   void CancelPendingTranslation();
131 
132   // Checks if the current running page translation is finished or errored and
133   // notifies the browser accordingly.  If the translation has not terminated,
134   // posts a task to check again later.
135   void CheckTranslateStatus();
136 
137   // Called by TranslatePage to do the actual translation.  |count| is used to
138   // limit the number of retries.
139   void TranslatePageImpl(int count);
140 
141   // Sends a message to the browser to notify it that the translation failed
142   // with |error|.
143   void NotifyBrowserTranslationFailed(TranslateErrors::Type error);
144 
145   // Convenience method to access the main frame.  Can return NULL, typically
146   // if the page is being closed.
147   blink::WebFrame* GetMainFrame();
148 
149   // ID to represent a page which TranslateHelper captured and determined a
150   // content language.
151   int page_id_;
152 
153   // The states associated with the current translation.
154   bool translation_pending_;
155   std::string source_lang_;
156   std::string target_lang_;
157 
158   // Time when a page langauge is determined. This is used to know a duration
159   // time from showing infobar to requesting translation.
160   base::TimeTicks language_determined_time_;
161 
162   // Method factory used to make calls to TranslatePageImpl.
163   base::WeakPtrFactory<TranslateHelper> weak_method_factory_;
164 
165 #if defined(CLD2_DYNAMIC_MODE)
166   // Do not ask for CLD data any more.
167   void CancelCLD2DataFilePolling();
168 
169   // Invoked when PageCaptured is called prior to obtaining CLD data. This
170   // method stores the page ID into deferred_page_id_ and COPIES the contents
171   // of the page, then sets deferred_page_capture_ to true. When CLD data is
172   // eventually received (in OnCLDDataAvailable), any deferred request will be
173   // "resurrected" and allowed to proceed automatically, assuming that the
174   // page ID has not changed.
175   void DeferPageCaptured(const int page_id, const base::string16& contents);
176 
177   // Immediately send an IPC request to the browser process to get the CLD
178   // data file. In most cases, the file will already exist and we will only
179   // poll once; but since the file might need to be downloaded first, poll
180   // indefinitely until a ChromeViewMsg_CLDDataAvailable message is received
181   // from the browser process.
182   // Polling will automatically halt as soon as the renderer obtains a
183   // reference to the data file.
184   void SendCLD2DataFileRequest(const int delay_millis,
185                                const int next_delay_millis);
186 
187   // Invoked when a ChromeViewMsg_CLDDataAvailable message is received from
188   // the browser process, providing a file handle for the CLD data file. If a
189   // PageCaptured request was previously deferred with DeferPageCaptured and
190   // the page ID has not yet changed, the PageCaptured is reinvoked to
191   // "resurrect" the language detection pathway.
192   void OnCLDDataAvailable(const IPC::PlatformFileForTransit ipc_file_handle,
193                           const uint64 data_offset,
194                           const uint64 data_length);
195 
196   // After receiving data in OnCLDDataAvailable, loads the data into CLD2.
197   void LoadCLDDData(base::File file,
198                     const uint64 data_offset,
199                     const uint64 data_length);
200 
201   // A struct that contains the pointer to the CLD mmap. Used so that we can
202   // leverage LazyInstance:Leaky to properly scope the lifetime of the mmap.
203   struct CLDMmapWrapper {
CLDMmapWrapperCLDMmapWrapper204     CLDMmapWrapper() {
205       value = NULL;
206     }
207     base::MemoryMappedFile* value;
208   };
209   static base::LazyInstance<CLDMmapWrapper>::Leaky s_cld_mmap_;
210 
211   // Whether or not polling for CLD2 data has started.
212   bool cld2_data_file_polling_started_;
213 
214   // Whether or not CancelCLD2DataFilePolling has been called.
215   bool cld2_data_file_polling_canceled_;
216 
217   // Whether or not a PageCaptured event arrived prior to CLD data becoming
218   // available. If true, deferred_page_id_ contains the most recent page ID
219   // and deferred_contents_ contains the most recent contents.
220   bool deferred_page_capture_;
221 
222   // The ID of the page most recently reported to PageCaptured if
223   // deferred_page_capture_ is true.
224   int deferred_page_id_;
225 
226   // The contents of the page most recently reported to PageCaptured if
227   // deferred_page_capture_ is true.
228   base::string16 deferred_contents_;
229 
230 #endif
231 
232   DISALLOW_COPY_AND_ASSIGN(TranslateHelper);
233 };
234 
235 #endif  // CHROME_RENDERER_TRANSLATE_TRANSLATE_HELPER_H_
236