Home | History | Annotate | Download | only in translate
      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 {
    204     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