Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: components/translate/content/renderer/translate_helper.cc

Issue 2034413003: Delete the non-static CLD data source logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase to latest master Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/translate/content/renderer/translate_helper.h" 5 #include "components/translate/content/renderer/translate_helper.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string16.h" 13 #include "base/strings/string16.h"
14 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "components/translate/content/common/translate_messages.h" 17 #include "components/translate/content/common/translate_messages.h"
18 #include "components/translate/content/renderer/renderer_cld_data_provider.h"
19 #include "components/translate/content/renderer/renderer_cld_data_provider_facto ry.h"
20 #include "components/translate/content/renderer/renderer_cld_utils.h"
21 #include "components/translate/core/common/translate_constants.h" 18 #include "components/translate/core/common/translate_constants.h"
22 #include "components/translate/core/common/translate_metrics.h" 19 #include "components/translate/core/common/translate_metrics.h"
23 #include "components/translate/core/common/translate_util.h" 20 #include "components/translate/core/common/translate_util.h"
24 #include "components/translate/core/language_detection/language_detection_util.h " 21 #include "components/translate/core/language_detection/language_detection_util.h "
25 #include "content/public/common/content_constants.h" 22 #include "content/public/common/content_constants.h"
26 #include "content/public/common/url_constants.h" 23 #include "content/public/common/url_constants.h"
27 #include "content/public/renderer/render_frame.h" 24 #include "content/public/renderer/render_frame.h"
28 #include "content/public/renderer/render_thread.h" 25 #include "content/public/renderer/render_thread.h"
29 #include "ipc/ipc_platform_file.h" 26 #include "ipc/ipc_platform_file.h"
30 #include "third_party/WebKit/public/web/WebDocument.h" 27 #include "third_party/WebKit/public/web/WebDocument.h"
(...skipping 27 matching lines...) Expand all
58 // The delay we wait in milliseconds before checking whether the translation has 55 // The delay we wait in milliseconds before checking whether the translation has
59 // finished. 56 // finished.
60 const int kTranslateStatusCheckDelayMs = 400; 57 const int kTranslateStatusCheckDelayMs = 400;
61 58
62 // Language name passed to the Translate element for it to detect the language. 59 // Language name passed to the Translate element for it to detect the language.
63 const char kAutoDetectionLanguage[] = "auto"; 60 const char kAutoDetectionLanguage[] = "auto";
64 61
65 // Isolated world sets following content-security-policy. 62 // Isolated world sets following content-security-policy.
66 const char kContentSecurityPolicy[] = "script-src 'self' 'unsafe-eval'"; 63 const char kContentSecurityPolicy[] = "script-src 'self' 'unsafe-eval'";
67 64
68 // Whether or not we have set the CLD callback yet.
69 bool g_cld_callback_set = false;
70
71 // Obtain a new CLD data provider. Defined as a standalone method for ease of
72 // use in constructor initialization list.
73 std::unique_ptr<translate::RendererCldDataProvider> CreateDataProvider(
74 content::RenderFrameObserver* render_frame_observer) {
75 translate::RendererCldUtils::ConfigureDefaultDataProvider();
76 return translate::RendererCldDataProviderFactory::Get()
77 ->CreateRendererCldDataProvider(render_frame_observer);
78 }
79
80 // Returns whether the page associated with |document| is a candidate for 65 // Returns whether the page associated with |document| is a candidate for
81 // translation. Some pages can explictly specify (via a meta-tag) that they 66 // translation. Some pages can explictly specify (via a meta-tag) that they
82 // should not be translated. 67 // should not be translated.
83 // TODO(dglazkov): This logic should be moved into Blink. 68 // TODO(dglazkov): This logic should be moved into Blink.
84 bool HasNoTranslateMeta(WebDocument* document) { 69 bool HasNoTranslateMeta(WebDocument* document) {
85 WebElement head = document->head(); 70 WebElement head = document->head();
86 if (head.isNull() || !head.hasChildNodes()) 71 if (head.isNull() || !head.hasChildNodes())
87 return false; 72 return false;
88 73
89 const WebString meta(ASCIIToUTF16("meta")); 74 const WebString meta(ASCIIToUTF16("meta"));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 //////////////////////////////////////////////////////////////////////////////// 109 ////////////////////////////////////////////////////////////////////////////////
125 // TranslateHelper, public: 110 // TranslateHelper, public:
126 // 111 //
127 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame, 112 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame,
128 int world_id, 113 int world_id,
129 int extension_group, 114 int extension_group,
130 const std::string& extension_scheme) 115 const std::string& extension_scheme)
131 : content::RenderFrameObserver(render_frame), 116 : content::RenderFrameObserver(render_frame),
132 page_seq_no_(0), 117 page_seq_no_(0),
133 translation_pending_(false), 118 translation_pending_(false),
134 cld_data_provider_(CreateDataProvider(this)),
135 cld_data_polling_started_(false),
136 cld_data_polling_canceled_(false),
137 deferred_page_capture_(false), 119 deferred_page_capture_(false),
138 deferred_page_seq_no_(-1), 120 deferred_page_seq_no_(-1),
139 world_id_(world_id), 121 world_id_(world_id),
140 extension_group_(extension_group), 122 extension_group_(extension_group),
141 extension_scheme_(extension_scheme), 123 extension_scheme_(extension_scheme),
142 weak_method_factory_(this) {} 124 weak_method_factory_(this) {}
143 125
144 TranslateHelper::~TranslateHelper() { 126 TranslateHelper::~TranslateHelper() {
145 CancelPendingTranslation();
146 CancelCldDataPolling();
147 } 127 }
148 128
149 void TranslateHelper::PrepareForUrl(const GURL& url) { 129 void TranslateHelper::PrepareForUrl(const GURL& url) {
150 ++page_seq_no_; 130 ++page_seq_no_;
151 Send(new ChromeFrameHostMsg_TranslateAssignedSequenceNumber(routing_id(), 131 Send(new ChromeFrameHostMsg_TranslateAssignedSequenceNumber(routing_id(),
152 page_seq_no_)); 132 page_seq_no_));
153 deferred_page_capture_ = false; 133 deferred_page_capture_ = false;
154 deferred_page_seq_no_ = -1; 134 deferred_page_seq_no_ = -1;
155 deferred_contents_.clear(); 135 deferred_contents_.clear();
156 if (cld_data_polling_started_)
157 return;
158
159 // TODO(andrewhayden): Refactor translate_manager.cc's IsTranslatableURL to
160 // components/translate/core/common/translate_util.cc, and ignore any URL
161 // that fails that check. This will require moving unit tests and rewiring
162 // other function calls as well, so for now replicate the logic here.
163 if (url.is_empty())
164 return;
165 if (url.SchemeIs(content::kChromeUIScheme))
166 return;
167 if (url.SchemeIs(content::kChromeDevToolsScheme))
168 return;
169 if (url.SchemeIs(url::kFtpScheme))
170 return;
171 if (url.SchemeIs(extension_scheme_.c_str()))
172 return;
173
174 // Start polling for CLD data.
175 cld_data_polling_started_ = true;
176 TranslateHelper::SendCldDataRequest(0, 1000);
177 } 136 }
178 137
179 void TranslateHelper::PageCaptured(const base::string16& contents) { 138 void TranslateHelper::PageCaptured(const base::string16& contents) {
180 PageCapturedImpl(page_seq_no_, contents); 139 PageCapturedImpl(page_seq_no_, contents);
181 } 140 }
182 141
183 void TranslateHelper::PageCapturedImpl(int page_seq_no, 142 void TranslateHelper::PageCapturedImpl(int page_seq_no,
184 const base::string16& contents) { 143 const base::string16& contents) {
185 // Get the document language as set by WebKit from the http-equiv 144 // Get the document language as set by WebKit from the http-equiv
186 // meta tag for "content-language". This may or may not also 145 // meta tag for "content-language". This may or may not also
187 // have a value derived from the actual Content-Language HTTP 146 // have a value derived from the actual Content-Language HTTP
188 // header. The two actually have different meanings (despite the 147 // header. The two actually have different meanings (despite the
189 // original intent of http-equiv to be an equivalent) with the former 148 // original intent of http-equiv to be an equivalent) with the former
190 // being the language of the document and the latter being the 149 // being the language of the document and the latter being the
191 // language of the intended audience (a distinction really only 150 // language of the intended audience (a distinction really only
192 // relevant for things like langauge textbooks). This distinction 151 // relevant for things like langauge textbooks). This distinction
193 // shouldn't affect translation. 152 // shouldn't affect translation.
194 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); 153 WebLocalFrame* main_frame = render_frame()->GetWebFrame();
195 if (!main_frame || page_seq_no_ != page_seq_no) 154 if (!main_frame || page_seq_no_ != page_seq_no)
196 return; 155 return;
197 156
198 if (!cld_data_provider_->IsCldDataAvailable()) {
199 // We're in dynamic mode and CLD data isn't loaded. Retry when CLD data
200 // is loaded, if ever.
201 deferred_page_capture_ = true;
202 deferred_page_seq_no_ = page_seq_no;
203 deferred_contents_ = contents;
204 RecordLanguageDetectionTiming(DEFERRED);
205 return;
206 }
207
208 if (deferred_page_seq_no_ == -1) {
209 // CLD data was available before language detection was requested.
210 RecordLanguageDetectionTiming(ON_TIME);
211 } else {
212 // This is a request that was triggered because CLD data is now available
213 // and was previously deferred.
214 RecordLanguageDetectionTiming(RESUMED);
215 }
216
217 WebDocument document = main_frame->document(); 157 WebDocument document = main_frame->document();
218 std::string content_language = document.contentLanguage().utf8(); 158 std::string content_language = document.contentLanguage().utf8();
219 WebElement html_element = document.documentElement(); 159 WebElement html_element = document.documentElement();
220 std::string html_lang; 160 std::string html_lang;
221 // |html_element| can be null element, e.g. in 161 // |html_element| can be null element, e.g. in
222 // BrowserTest.WindowOpenClose. 162 // BrowserTest.WindowOpenClose.
223 if (!html_element.isNull()) 163 if (!html_element.isNull())
224 html_lang = html_element.getAttribute("lang").utf8(); 164 html_lang = html_element.getAttribute("lang").utf8();
225 std::string cld_language; 165 std::string cld_language;
226 bool is_cld_reliable; 166 bool is_cld_reliable;
(...skipping 22 matching lines...) Expand all
249 189
250 Send(new ChromeFrameHostMsg_TranslateLanguageDetermined( 190 Send(new ChromeFrameHostMsg_TranslateLanguageDetermined(
251 routing_id(), details, !details.has_notranslate && !language.empty())); 191 routing_id(), details, !details.has_notranslate && !language.empty()));
252 } 192 }
253 193
254 void TranslateHelper::CancelPendingTranslation() { 194 void TranslateHelper::CancelPendingTranslation() {
255 weak_method_factory_.InvalidateWeakPtrs(); 195 weak_method_factory_.InvalidateWeakPtrs();
256 translation_pending_ = false; 196 translation_pending_ = false;
257 source_lang_.clear(); 197 source_lang_.clear();
258 target_lang_.clear(); 198 target_lang_.clear();
259 CancelCldDataPolling();
260 } 199 }
261 200
262 //////////////////////////////////////////////////////////////////////////////// 201 ////////////////////////////////////////////////////////////////////////////////
263 // TranslateHelper, protected: 202 // TranslateHelper, protected:
264 // 203 //
265 bool TranslateHelper::IsTranslateLibAvailable() { 204 bool TranslateHelper::IsTranslateLibAvailable() {
266 return ExecuteScriptAndGetBoolResult( 205 return ExecuteScriptAndGetBoolResult(
267 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && " 206 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && "
268 "typeof cr.googleTranslate.translate == 'function'", false); 207 "typeof cr.googleTranslate.translate == 'function'", false);
269 } 208 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 //////////////////////////////////////////////////////////////////////////////// 312 ////////////////////////////////////////////////////////////////////////////////
374 // TranslateHelper, private: 313 // TranslateHelper, private:
375 // 314 //
376 bool TranslateHelper::OnMessageReceived(const IPC::Message& message) { 315 bool TranslateHelper::OnMessageReceived(const IPC::Message& message) {
377 bool handled = true; 316 bool handled = true;
378 IPC_BEGIN_MESSAGE_MAP(TranslateHelper, message) 317 IPC_BEGIN_MESSAGE_MAP(TranslateHelper, message)
379 IPC_MESSAGE_HANDLER(ChromeFrameMsg_TranslatePage, OnTranslatePage) 318 IPC_MESSAGE_HANDLER(ChromeFrameMsg_TranslatePage, OnTranslatePage)
380 IPC_MESSAGE_HANDLER(ChromeFrameMsg_RevertTranslation, OnRevertTranslation) 319 IPC_MESSAGE_HANDLER(ChromeFrameMsg_RevertTranslation, OnRevertTranslation)
381 IPC_MESSAGE_UNHANDLED(handled = false) 320 IPC_MESSAGE_UNHANDLED(handled = false)
382 IPC_END_MESSAGE_MAP() 321 IPC_END_MESSAGE_MAP()
383 if (!handled) {
384 handled = cld_data_provider_->OnMessageReceived(message);
385 }
386 return handled; 322 return handled;
387 } 323 }
388 324
389 void TranslateHelper::OnTranslatePage(int page_seq_no, 325 void TranslateHelper::OnTranslatePage(int page_seq_no,
390 const std::string& translate_script, 326 const std::string& translate_script,
391 const std::string& source_lang, 327 const std::string& source_lang,
392 const std::string& target_lang) { 328 const std::string& target_lang) {
393 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); 329 WebLocalFrame* main_frame = render_frame()->GetWebFrame();
394 if (!main_frame || page_seq_no_ != page_seq_no) 330 if (!main_frame || page_seq_no_ != page_seq_no)
395 return; // We navigated away, nothing to do. 331 return; // We navigated away, nothing to do.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 } 477 }
542 478
543 void TranslateHelper::NotifyBrowserTranslationFailed( 479 void TranslateHelper::NotifyBrowserTranslationFailed(
544 TranslateErrors::Type error) { 480 TranslateErrors::Type error) {
545 translation_pending_ = false; 481 translation_pending_ = false;
546 // Notify the browser there was an error. 482 // Notify the browser there was an error.
547 render_frame()->Send(new ChromeFrameHostMsg_PageTranslated( 483 render_frame()->Send(new ChromeFrameHostMsg_PageTranslated(
548 render_frame()->GetRoutingID(), source_lang_, target_lang_, error)); 484 render_frame()->GetRoutingID(), source_lang_, target_lang_, error));
549 } 485 }
550 486
551 void TranslateHelper::CancelCldDataPolling() {
552 cld_data_polling_canceled_ = true;
553 }
554
555 void TranslateHelper::SendCldDataRequest(const int delay_millis,
556 const int next_delay_millis) {
557 DCHECK_GE(delay_millis, 0);
558 DCHECK_GT(next_delay_millis, 0);
559
560 // Terminate immediately if told to stop polling.
561 if (cld_data_polling_canceled_) {
562 DVLOG(1) << "Aborting CLD data request (polling canceled)";
563 return;
564 }
565
566 // Terminate immediately if data is already loaded.
567 if (cld_data_provider_->IsCldDataAvailable()) {
568 DVLOG(1) << "Aborting CLD data request (data available)";
569 return;
570 }
571
572 // Terminate immediately if the decayed delay is sufficiently large.
573 if (next_delay_millis > std::numeric_limits<int>::max() / 2) {
574 DVLOG(1) << "Aborting CLD data request (exceeded max number of requests)";
575 cld_data_polling_started_ = false;
576 return;
577 }
578
579 if (!g_cld_callback_set) {
580 g_cld_callback_set = true;
581 cld_data_provider_->SetCldAvailableCallback(
582 base::Bind(&TranslateHelper::OnCldDataAvailable,
583 weak_method_factory_.GetWeakPtr()));
584 }
585
586 // Else, make an asynchronous request to get the data we need.
587 DVLOG(1) << "Requesting CLD data from data provider";
588 cld_data_provider_->SendCldDataRequest();
589
590 // ... and enqueue another delayed task to call again. This will start a
591 // chain of polling that will last until the pointer stops being NULL,
592 // which is the right thing to do.
593 // NB: In the great majority of cases, the data file will be available and
594 // the very first delayed task will be a no-op that terminates the chain.
595 // It's only while downloading the file that this will chain for a
596 // nontrivial amount of time.
597 // Use a weak pointer to avoid keeping this helper object around forever.
598 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
599 FROM_HERE, base::Bind(&TranslateHelper::SendCldDataRequest,
600 weak_method_factory_.GetWeakPtr(),
601 next_delay_millis, next_delay_millis * 2),
602 base::TimeDelta::FromMilliseconds(delay_millis));
603 }
604
605 void TranslateHelper::OnCldDataAvailable() {
606 if (deferred_page_capture_) {
607 deferred_page_capture_ = false; // Don't do this a second time.
608 PageCapturedImpl(deferred_page_seq_no_, deferred_contents_);
609 deferred_page_seq_no_ = -1; // Clean up for sanity
610 deferred_contents_.clear(); // Clean up for sanity
611 }
612 }
613
614 void TranslateHelper::RecordLanguageDetectionTiming(
615 LanguageDetectionTiming timing) {
616 // The following comment is copied from page_load_histograms.cc, and applies
617 // just as equally here:
618 //
619 // Since there are currently no guarantees that renderer histograms will be
620 // sent to the browser, we initiate a PostTask here to be sure that we send
621 // the histograms we generated. Without this call, pages that don't have an
622 // on-close-handler might generate data that is lost when the renderer is
623 // shutdown abruptly (perchance because the user closed the tab).
624 DVLOG(1) << "Language detection timing: " << timing;
625 UMA_HISTOGRAM_ENUMERATION("Translate.LanguageDetectionTiming", timing,
626 LANGUAGE_DETECTION_TIMING_MAX_VALUE);
627
628 // Note on performance: Under normal circumstances, this should get called
629 // once per page load. The code will either manage to do it ON_TIME or will
630 // be DEFERRED until CLD is ready. In the latter case, CLD is in dynamic mode
631 // and may eventually become available, triggering the RESUMED event; after
632 // this, everything should start being ON_TIME. This should never run more
633 // than twice in a page load, under any conditions.
634 // Also note that language detection is triggered off of a delay AFTER the
635 // page load completed event has fired, making this very much off the critical
636 // path.
637 content::RenderThread::Get()->UpdateHistograms(
638 content::kHistogramSynchronizerReservedSequenceNumber);
639 }
640
641 void TranslateHelper::OnDestruct() { 487 void TranslateHelper::OnDestruct() {
642 delete this; 488 delete this;
643 } 489 }
644 490
645 } // namespace translate 491 } // namespace translate
OLDNEW
« no previous file with comments | « components/translate/content/renderer/translate_helper.h ('k') | components/translate/core/language_detection/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698