Don't preload rarely seen large images
[chromium-blink-merge.git] / components / translate / content / renderer / translate_helper.h
blobe768a3140fbde719c7396a1dda827d6e08aaa659
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.
5 #ifndef COMPONENTS_TRANSLATE_CONTENT_RENDERER_TRANSLATE_HELPER_H_
6 #define COMPONENTS_TRANSLATE_CONTENT_RENDERER_TRANSLATE_HELPER_H_
8 #include <string>
10 #include "base/gtest_prod_util.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/strings/string16.h"
14 #include "base/time/time.h"
15 #include "components/translate/content/renderer/renderer_cld_data_provider.h"
16 #include "components/translate/core/common/translate_errors.h"
17 #include "content/public/renderer/render_view_observer.h"
18 #include "url/gurl.h"
20 namespace blink {
21 class WebDocument;
22 class WebFrame;
25 namespace content {
26 class RendererCldDataProvider;
29 namespace translate {
31 // This class deals with page translation.
32 // There is one TranslateHelper per RenderView.
34 // This class provides metrics that allow tracking the user experience impact
35 // of non-static CldDataProvider implementations. For background on the data
36 // providers, please refer to the following documentation:
37 // http://www.chromium.org/developers/how-tos/compact-language-detector-cld-data-source-configuration
39 // Available metrics (from the LanguageDetectionTiming enum):
40 // 1. ON_TIME
41 // Recorded if PageCaptured(...) is invoked after CLD is available. This is
42 // the ideal case, indicating that CLD is available before it is needed.
43 // 2. DEFERRED
44 // Recorded if PageCaptured(...) is invoked before CLD is available.
45 // Sub-optimal case indicating that CLD wasn't available when it was needed,
46 // so the request for detection has been deferred until CLD is available or
47 // until the user navigates to a different page.
48 // 3. RESUMED
49 // Recorded if CLD becomes available after a language detection request was
50 // deferred, but before the user navigated to a different page. Language
51 // detection is ultimately completed, it just didn't happen on time.
53 // Note that there is NOT a metric that records the number of times that
54 // language detection had to be aborted because CLD never became available in
55 // time. This is because there is no reasonable way to cover all the cases
56 // under which this could occur, particularly the destruction of the renderer
57 // for which this object was created. However, this value can be synthetically
58 // derived, using the logic below.
60 // Every page load that triggers language detection will result in the
61 // recording of exactly one of the first two events: ON_TIME or DEFERRED. If
62 // CLD is available in time to satisfy the request, the third event (RESUMED)
63 // will be recorded; thus, the number of times when language detection
64 // ultimately fails because CLD isn't ever available is implied as the number of
65 // times that detection is deferred minus the number of times that language
66 // detection is late:
68 // count(FAILED) ~= count(DEFERRED) - count(RESUMED)
70 // Note that this is not 100% accurate: some renderer process are so short-lived
71 // that language detection wouldn't have been relevant anyway, and so a failure
72 // to detect the language in a timely manner might be completely innocuous. The
73 // overall problem with language detection is that it isn't possible to know
74 // whether it was required or not until after it has been performed!
76 // We use histograms for recording these metrics. On Android, the renderer can
77 // be killed without the chance to clean up or transmit these histograms,
78 // leading to dropped metrics. To work around this, this method forces an IPC
79 // message to be sent to the browser process immediately.
80 class TranslateHelper : public content::RenderViewObserver {
81 public:
82 explicit TranslateHelper(content::RenderView* render_view,
83 int world_id,
84 int extension_group,
85 const std::string& extension_scheme);
86 ~TranslateHelper() override;
88 // Informs us that the page's text has been extracted.
89 void PageCaptured(const base::string16& contents);
91 // Lets the translation system know that we are preparing to navigate to
92 // the specified URL. If there is anything that can or should be done before
93 // this URL loads, this is the time to prepare for it.
94 void PrepareForUrl(const GURL& url);
96 protected:
97 // The following methods are protected so they can be overridden in
98 // unit-tests.
99 void OnTranslatePage(int page_seq_no,
100 const std::string& translate_script,
101 const std::string& source_lang,
102 const std::string& target_lang);
103 void OnRevertTranslation(int page_seq_no);
105 // Returns true if the translate library is available, meaning the JavaScript
106 // has already been injected in that page.
107 virtual bool IsTranslateLibAvailable();
109 // Returns true if the translate library has been initialized successfully.
110 virtual bool IsTranslateLibReady();
112 // Returns true if the translation script has finished translating the page.
113 virtual bool HasTranslationFinished();
115 // Returns true if the translation script has reported an error performing the
116 // translation.
117 virtual bool HasTranslationFailed();
119 // Starts the translation by calling the translate library. This method
120 // should only be called when the translate script has been injected in the
121 // page. Returns false if the call failed immediately.
122 virtual bool StartTranslation();
124 // Asks the Translate element in the page what the language of the page is.
125 // Can only be called if a translation has happened and was successful.
126 // Returns the language code on success, an empty string on failure.
127 virtual std::string GetOriginalPageLanguage();
129 // Adjusts a delay time for a posted task. This is used in tests to do tasks
130 // immediately by returning 0.
131 virtual base::TimeDelta AdjustDelay(int delayInMs);
133 // Executes the JavaScript code in |script| in the main frame of RenderView.
134 virtual void ExecuteScript(const std::string& script);
136 // Executes the JavaScript code in |script| in the main frame of RenderView,
137 // and returns the boolean returned by the script evaluation if the script was
138 // run successfully. Otherwise, returns |fallback| value.
139 virtual bool ExecuteScriptAndGetBoolResult(const std::string& script,
140 bool fallback);
142 // Executes the JavaScript code in |script| in the main frame of RenderView,
143 // and returns the string returned by the script evaluation if the script was
144 // run successfully. Otherwise, returns empty string.
145 virtual std::string ExecuteScriptAndGetStringResult(
146 const std::string& script);
148 // Executes the JavaScript code in |script| in the main frame of RenderView.
149 // and returns the number returned by the script evaluation if the script was
150 // run successfully. Otherwise, returns 0.0.
151 virtual double ExecuteScriptAndGetDoubleResult(const std::string& script);
153 private:
154 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, AdoptHtmlLang);
155 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest,
156 CLDAgreeWithLanguageCodeHavingCountryCode);
157 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest,
158 CLDDisagreeWithWrongLanguageCode);
159 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest,
160 InvalidLanguageMetaTagProviding);
161 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, LanguageCodeTypoCorrection);
162 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, LanguageCodeSynonyms);
163 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, ResetInvalidLanguageCode);
164 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, SimilarLanguageCode);
165 FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, WellKnownWrongConfiguration);
167 enum LanguageDetectionTiming {
168 ON_TIME, // Language detection was performed as soon as it was requested
169 DEFERRED, // Language detection couldn't be performed when it was requested
170 RESUMED, // A deferred language detection attempt was completed later
171 LANGUAGE_DETECTION_TIMING_MAX_VALUE // The bounding value for this enum
174 // Converts language code to the one used in server supporting list.
175 static void ConvertLanguageCodeSynonym(std::string* code);
177 // RenderViewObserver implementation.
178 bool OnMessageReceived(const IPC::Message& message) override;
180 // Informs us that the page's text has been extracted.
181 void PageCapturedImpl(int page_seq_no, const base::string16& contents);
183 // Cancels any translation that is currently being performed. This does not
184 // revert existing translations.
185 void CancelPendingTranslation();
187 // Checks if the current running page translation is finished or errored and
188 // notifies the browser accordingly. If the translation has not terminated,
189 // posts a task to check again later.
190 void CheckTranslateStatus(int page_seq_no);
192 // Called by TranslatePage to do the actual translation. |count| is used to
193 // limit the number of retries.
194 void TranslatePageImpl(int page_seq_no, int count);
196 // Sends a message to the browser to notify it that the translation failed
197 // with |error|.
198 void NotifyBrowserTranslationFailed(TranslateErrors::Type error);
200 // Convenience method to access the main frame. Can return NULL, typically
201 // if the page is being closed.
202 blink::WebFrame* GetMainFrame();
204 // Do not ask for CLD data any more.
205 void CancelCldDataPolling();
207 // Start polling for CLD data.
208 // Polling will automatically halt as soon as the renderer obtains a
209 // reference to the data file.
210 void SendCldDataRequest(const int delay_millis, const int next_delay_millis);
212 // Callback triggered when CLD data becomes available.
213 void OnCldDataAvailable();
215 // Record the timing of language detection, immediately sending an IPC-based
216 // histogram delta update to the browser process in case the hosting renderer
217 // process terminates before the metrics would otherwise be transferred.
218 void RecordLanguageDetectionTiming(LanguageDetectionTiming timing);
220 // An ever-increasing sequence number of the current page, used to match up
221 // translation requests with responses.
222 int page_seq_no_;
224 // The states associated with the current translation.
225 bool translation_pending_;
226 std::string source_lang_;
227 std::string target_lang_;
229 // Time when a page langauge is determined. This is used to know a duration
230 // time from showing infobar to requesting translation.
231 base::TimeTicks language_determined_time_;
233 // Provides CLD data for this process.
234 scoped_ptr<RendererCldDataProvider> cld_data_provider_;
236 // Whether or not polling for CLD2 data has started.
237 bool cld_data_polling_started_;
239 // Whether or not CancelCldDataPolling has been called.
240 bool cld_data_polling_canceled_;
242 // Whether or not a PageCaptured event arrived prior to CLD data becoming
243 // available. If true, deferred_contents_ contains the most recent contents.
244 bool deferred_page_capture_;
246 // The ID of the page most recently reported to PageCaptured if
247 // deferred_page_capture_ is true.
248 int deferred_page_seq_no_;
250 // The world ID to use for script execution.
251 int world_id_;
253 // The extension group.
254 int extension_group_;
256 // The URL scheme for translate extensions.
257 std::string extension_scheme_;
259 // The contents of the page most recently reported to PageCaptured if
260 // deferred_page_capture_ is true.
261 base::string16 deferred_contents_;
263 // Method factory used to make calls to TranslatePageImpl.
264 base::WeakPtrFactory<TranslateHelper> weak_method_factory_;
266 DISALLOW_COPY_AND_ASSIGN(TranslateHelper);
269 } // namespace translate
271 #endif // COMPONENTS_TRANSLATE_CONTENT_RENDERER_TRANSLATE_HELPER_H_