| OLD | NEW |
| 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" | |
| 18 #include "components/translate/core/common/translate_constants.h" | 17 #include "components/translate/core/common/translate_constants.h" |
| 19 #include "components/translate/core/common/translate_metrics.h" | 18 #include "components/translate/core/common/translate_metrics.h" |
| 20 #include "components/translate/core/common/translate_util.h" | 19 #include "components/translate/core/common/translate_util.h" |
| 21 #include "components/translate/core/language_detection/language_detection_util.h
" | 20 #include "components/translate/core/language_detection/language_detection_util.h
" |
| 22 #include "content/public/common/content_constants.h" | 21 #include "content/public/common/content_constants.h" |
| 23 #include "content/public/common/url_constants.h" | 22 #include "content/public/common/url_constants.h" |
| 24 #include "content/public/renderer/render_frame.h" | 23 #include "content/public/renderer/render_frame.h" |
| 25 #include "content/public/renderer/render_thread.h" | 24 #include "content/public/renderer/render_thread.h" |
| 26 #include "ipc/ipc_platform_file.h" | 25 #include "services/shell/public/cpp/interface_provider.h" |
| 27 #include "third_party/WebKit/public/web/WebDocument.h" | 26 #include "third_party/WebKit/public/web/WebDocument.h" |
| 28 #include "third_party/WebKit/public/web/WebElement.h" | 27 #include "third_party/WebKit/public/web/WebElement.h" |
| 29 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 28 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 30 #include "third_party/WebKit/public/web/WebNode.h" | 29 #include "third_party/WebKit/public/web/WebNode.h" |
| 31 #include "third_party/WebKit/public/web/WebScriptSource.h" | 30 #include "third_party/WebKit/public/web/WebScriptSource.h" |
| 32 #include "url/gurl.h" | 31 #include "url/gurl.h" |
| 33 #include "v8/include/v8.h" | 32 #include "v8/include/v8.h" |
| 34 | 33 |
| 35 using base::ASCIIToUTF16; | 34 using base::ASCIIToUTF16; |
| 36 using blink::WebDocument; | 35 using blink::WebDocument; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 if (head.isNull() || !head.hasChildNodes()) | 70 if (head.isNull() || !head.hasChildNodes()) |
| 72 return false; | 71 return false; |
| 73 | 72 |
| 74 const WebString meta(ASCIIToUTF16("meta")); | 73 const WebString meta(ASCIIToUTF16("meta")); |
| 75 const WebString name(ASCIIToUTF16("name")); | 74 const WebString name(ASCIIToUTF16("name")); |
| 76 const WebString google(ASCIIToUTF16("google")); | 75 const WebString google(ASCIIToUTF16("google")); |
| 77 const WebString value(ASCIIToUTF16("value")); | 76 const WebString value(ASCIIToUTF16("value")); |
| 78 const WebString content(ASCIIToUTF16("content")); | 77 const WebString content(ASCIIToUTF16("content")); |
| 79 | 78 |
| 80 for (WebNode child = head.firstChild(); !child.isNull(); | 79 for (WebNode child = head.firstChild(); !child.isNull(); |
| 81 child = child.nextSibling()) { | 80 child = child.nextSibling()) { |
| 82 if (!child.isElementNode()) | 81 if (!child.isElementNode()) |
| 83 continue; | 82 continue; |
| 84 WebElement element = child.to<WebElement>(); | 83 WebElement element = child.to<WebElement>(); |
| 85 // Check if a tag is <meta>. | 84 // Check if a tag is <meta>. |
| 86 if (!element.hasHTMLTagName(meta)) | 85 if (!element.hasHTMLTagName(meta)) |
| 87 continue; | 86 continue; |
| 88 // Check if the tag contains name="google". | 87 // Check if the tag contains name="google". |
| 89 WebString attribute = element.getAttribute(name); | 88 WebString attribute = element.getAttribute(name); |
| 90 if (attribute.isNull() || attribute != google) | 89 if (attribute.isNull() || attribute != google) |
| 91 continue; | 90 continue; |
| 92 // Check if the tag contains value="notranslate", or content="notranslate". | 91 // Check if the tag contains value="notranslate", or content="notranslate". |
| 93 attribute = element.getAttribute(value); | 92 attribute = element.getAttribute(value); |
| 94 if (attribute.isNull()) | 93 if (attribute.isNull()) |
| 95 attribute = element.getAttribute(content); | 94 attribute = element.getAttribute(content); |
| 96 if (attribute.isNull()) | 95 if (attribute.isNull()) |
| 97 continue; | 96 continue; |
| 98 if (base::LowerCaseEqualsASCII(base::StringPiece16(attribute), | 97 if (base::LowerCaseEqualsASCII(base::StringPiece16(attribute), |
| 99 "notranslate")) | 98 "notranslate")) |
| 100 return true; | 99 return true; |
| 101 } | 100 } |
| 102 return false; | 101 return false; |
| 103 } | 102 } |
| 104 | 103 |
| 105 } // namespace | 104 } // namespace |
| 106 | 105 |
| 107 namespace translate { | 106 namespace translate { |
| 108 | 107 |
| 109 //////////////////////////////////////////////////////////////////////////////// | 108 //////////////////////////////////////////////////////////////////////////////// |
| 110 // TranslateHelper, public: | 109 // TranslateHelper, public: |
| 111 // | |
| 112 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame, | 110 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame, |
| 113 int world_id, | 111 int world_id, |
| 114 int extension_group, | 112 int extension_group, |
| 115 const std::string& extension_scheme) | 113 const std::string& extension_scheme) |
| 116 : content::RenderFrameObserver(render_frame), | 114 : content::RenderFrameObserver(render_frame), |
| 117 page_seq_no_(0), | |
| 118 translation_pending_(false), | |
| 119 world_id_(world_id), | 115 world_id_(world_id), |
| 120 extension_group_(extension_group), | 116 extension_group_(extension_group), |
| 121 extension_scheme_(extension_scheme), | 117 extension_scheme_(extension_scheme), |
| 118 binding_(this), |
| 122 weak_method_factory_(this) {} | 119 weak_method_factory_(this) {} |
| 123 | 120 |
| 124 TranslateHelper::~TranslateHelper() { | 121 TranslateHelper::~TranslateHelper() { |
| 125 } | 122 } |
| 126 | 123 |
| 127 void TranslateHelper::PrepareForUrl(const GURL& url) { | 124 void TranslateHelper::PrepareForUrl(const GURL& url) { |
| 128 ++page_seq_no_; | 125 // Navigated to a new page, close the binding for previous page. |
| 129 Send(new ChromeFrameHostMsg_TranslateAssignedSequenceNumber(routing_id(), | 126 binding_.Close(); |
| 130 page_seq_no_)); | 127 translate_callback_pending_.Reset(); |
| 131 } | 128 } |
| 132 | 129 |
| 133 void TranslateHelper::PageCaptured(const base::string16& contents) { | 130 void TranslateHelper::PageCaptured(const base::string16& contents) { |
| 134 PageCapturedImpl(page_seq_no_, contents); | |
| 135 } | |
| 136 | |
| 137 void TranslateHelper::PageCapturedImpl(int page_seq_no, | |
| 138 const base::string16& contents) { | |
| 139 // Get the document language as set by WebKit from the http-equiv | 131 // Get the document language as set by WebKit from the http-equiv |
| 140 // meta tag for "content-language". This may or may not also | 132 // meta tag for "content-language". This may or may not also |
| 141 // have a value derived from the actual Content-Language HTTP | 133 // have a value derived from the actual Content-Language HTTP |
| 142 // header. The two actually have different meanings (despite the | 134 // header. The two actually have different meanings (despite the |
| 143 // original intent of http-equiv to be an equivalent) with the former | 135 // original intent of http-equiv to be an equivalent) with the former |
| 144 // being the language of the document and the latter being the | 136 // being the language of the document and the latter being the |
| 145 // language of the intended audience (a distinction really only | 137 // language of the intended audience (a distinction really only |
| 146 // relevant for things like langauge textbooks). This distinction | 138 // relevant for things like langauge textbooks). This distinction |
| 147 // shouldn't affect translation. | 139 // shouldn't affect translation. |
| 148 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); | 140 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); |
| 149 if (!main_frame || page_seq_no_ != page_seq_no) | 141 if (!main_frame) |
| 150 return; | 142 return; |
| 151 | 143 |
| 152 WebDocument document = main_frame->document(); | 144 WebDocument document = main_frame->document(); |
| 153 std::string content_language = document.contentLanguage().utf8(); | 145 std::string content_language = document.contentLanguage().utf8(); |
| 154 WebElement html_element = document.documentElement(); | 146 WebElement html_element = document.documentElement(); |
| 155 std::string html_lang; | 147 std::string html_lang; |
| 156 // |html_element| can be null element, e.g. in | 148 // |html_element| can be null element, e.g. in |
| 157 // BrowserTest.WindowOpenClose. | 149 // BrowserTest.WindowOpenClose. |
| 158 if (!html_element.isNull()) | 150 if (!html_element.isNull()) |
| 159 html_lang = html_element.getAttribute("lang").utf8(); | 151 html_lang = html_element.getAttribute("lang").utf8(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 175 details.cld_language = cld_language; | 167 details.cld_language = cld_language; |
| 176 details.is_cld_reliable = is_cld_reliable; | 168 details.is_cld_reliable = is_cld_reliable; |
| 177 details.has_notranslate = HasNoTranslateMeta(&document); | 169 details.has_notranslate = HasNoTranslateMeta(&document); |
| 178 details.html_root_language = html_lang; | 170 details.html_root_language = html_lang; |
| 179 details.adopted_language = language; | 171 details.adopted_language = language; |
| 180 | 172 |
| 181 // TODO(hajimehoshi): If this affects performance, it should be set only if | 173 // TODO(hajimehoshi): If this affects performance, it should be set only if |
| 182 // translate-internals tab exists. | 174 // translate-internals tab exists. |
| 183 details.contents = contents; | 175 details.contents = contents; |
| 184 | 176 |
| 185 Send(new ChromeFrameHostMsg_TranslateLanguageDetermined( | 177 // For the same render frame with the same url, each time when its texts are |
| 186 routing_id(), details, !details.has_notranslate && !language.empty())); | 178 // captured, it should be treated as a new page to do translation. |
| 179 binding_.Close(); |
| 180 GetTranslateDriver()->RegisterPage( |
| 181 binding_.CreateInterfacePtrAndBind(), details, |
| 182 !details.has_notranslate && !language.empty()); |
| 187 } | 183 } |
| 188 | 184 |
| 189 void TranslateHelper::CancelPendingTranslation() { | 185 void TranslateHelper::CancelPendingTranslation() { |
| 190 weak_method_factory_.InvalidateWeakPtrs(); | 186 weak_method_factory_.InvalidateWeakPtrs(); |
| 191 translation_pending_ = false; | 187 // Make sure to send the cancelled response back. |
| 188 if (translate_callback_pending_) { |
| 189 translate_callback_pending_.Run(true, source_lang_, target_lang_, |
| 190 TranslateErrors::NONE); |
| 191 translate_callback_pending_.Reset(); |
| 192 } |
| 192 source_lang_.clear(); | 193 source_lang_.clear(); |
| 193 target_lang_.clear(); | 194 target_lang_.clear(); |
| 194 } | 195 } |
| 195 | 196 |
| 196 //////////////////////////////////////////////////////////////////////////////// | 197 //////////////////////////////////////////////////////////////////////////////// |
| 197 // TranslateHelper, protected: | 198 // TranslateHelper, protected: |
| 198 // | |
| 199 bool TranslateHelper::IsTranslateLibAvailable() { | 199 bool TranslateHelper::IsTranslateLibAvailable() { |
| 200 return ExecuteScriptAndGetBoolResult( | 200 return ExecuteScriptAndGetBoolResult( |
| 201 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && " | 201 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && " |
| 202 "typeof cr.googleTranslate.translate == 'function'", false); | 202 "typeof cr.googleTranslate.translate == 'function'", false); |
| 203 } | 203 } |
| 204 | 204 |
| 205 bool TranslateHelper::IsTranslateLibReady() { | 205 bool TranslateHelper::IsTranslateLibReady() { |
| 206 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.libReady", false); | 206 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.libReady", false); |
| 207 } | 207 } |
| 208 | 208 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 main_frame->executeScriptInIsolatedWorld( | 297 main_frame->executeScriptInIsolatedWorld( |
| 298 world_id_, &source, 1, extension_group_, &results); | 298 world_id_, &source, 1, extension_group_, &results); |
| 299 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsNumber()) { | 299 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsNumber()) { |
| 300 NOTREACHED(); | 300 NOTREACHED(); |
| 301 return 0.0; | 301 return 0.0; |
| 302 } | 302 } |
| 303 | 303 |
| 304 return results[0]->NumberValue(); | 304 return results[0]->NumberValue(); |
| 305 } | 305 } |
| 306 | 306 |
| 307 //////////////////////////////////////////////////////////////////////////////// | 307 // mojom::Page implementations. |
| 308 // TranslateHelper, private: | 308 void TranslateHelper::Translate(const std::string& translate_script, |
| 309 // | 309 const std::string& source_lang, |
| 310 bool TranslateHelper::OnMessageReceived(const IPC::Message& message) { | 310 const std::string& target_lang, |
| 311 bool handled = true; | 311 const TranslateCallback& callback) { |
| 312 IPC_BEGIN_MESSAGE_MAP(TranslateHelper, message) | |
| 313 IPC_MESSAGE_HANDLER(ChromeFrameMsg_TranslatePage, OnTranslatePage) | |
| 314 IPC_MESSAGE_HANDLER(ChromeFrameMsg_RevertTranslation, OnRevertTranslation) | |
| 315 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 316 IPC_END_MESSAGE_MAP() | |
| 317 return handled; | |
| 318 } | |
| 319 | |
| 320 void TranslateHelper::OnTranslatePage(int page_seq_no, | |
| 321 const std::string& translate_script, | |
| 322 const std::string& source_lang, | |
| 323 const std::string& target_lang) { | |
| 324 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); | 312 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); |
| 325 if (!main_frame || page_seq_no_ != page_seq_no) | 313 if (!main_frame) { |
| 314 // Cancelled. |
| 315 callback.Run(true, source_lang, target_lang, TranslateErrors::NONE); |
| 326 return; // We navigated away, nothing to do. | 316 return; // We navigated away, nothing to do. |
| 317 } |
| 327 | 318 |
| 328 // A similar translation is already under way, nothing to do. | 319 // A similar translation is already under way, nothing to do. |
| 329 if (translation_pending_ && target_lang_ == target_lang) | 320 if (translate_callback_pending_ && target_lang_ == target_lang) { |
| 321 // This request is ignored. |
| 322 callback.Run(true, source_lang, target_lang, TranslateErrors::NONE); |
| 330 return; | 323 return; |
| 324 } |
| 331 | 325 |
| 332 // Any pending translation is now irrelevant. | 326 // Any pending translation is now irrelevant. |
| 333 CancelPendingTranslation(); | 327 CancelPendingTranslation(); |
| 334 | 328 |
| 335 // Set our states. | 329 // Set our states. |
| 336 translation_pending_ = true; | 330 translate_callback_pending_ = callback; |
| 337 | 331 |
| 338 // If the source language is undetermined, we'll let the translate element | 332 // If the source language is undetermined, we'll let the translate element |
| 339 // detect it. | 333 // detect it. |
| 340 source_lang_ = (source_lang != kUnknownLanguageCode) ? source_lang | 334 source_lang_ = (source_lang != kUnknownLanguageCode) ? source_lang |
| 341 : kAutoDetectionLanguage; | 335 : kAutoDetectionLanguage; |
| 342 target_lang_ = target_lang; | 336 target_lang_ = target_lang; |
| 343 | 337 |
| 344 ReportUserActionDuration(language_determined_time_, base::TimeTicks::Now()); | 338 ReportUserActionDuration(language_determined_time_, base::TimeTicks::Now()); |
| 345 | 339 |
| 346 GURL url(main_frame->document().url()); | 340 GURL url(main_frame->document().url()); |
| 347 ReportPageScheme(url.scheme()); | 341 ReportPageScheme(url.scheme()); |
| 348 | 342 |
| 349 // Set up v8 isolated world with proper content-security-policy and | 343 // Set up v8 isolated world with proper content-security-policy and |
| 350 // security-origin. | 344 // security-origin. |
| 351 main_frame->setIsolatedWorldContentSecurityPolicy( | 345 main_frame->setIsolatedWorldContentSecurityPolicy( |
| 352 world_id_, WebString::fromUTF8(kContentSecurityPolicy)); | 346 world_id_, WebString::fromUTF8(kContentSecurityPolicy)); |
| 353 | 347 |
| 354 GURL security_origin = GetTranslateSecurityOrigin(); | 348 GURL security_origin = GetTranslateSecurityOrigin(); |
| 355 main_frame->setIsolatedWorldSecurityOrigin( | 349 main_frame->setIsolatedWorldSecurityOrigin( |
| 356 world_id_, WebSecurityOrigin::create(security_origin)); | 350 world_id_, WebSecurityOrigin::create(security_origin)); |
| 357 | 351 |
| 358 if (!IsTranslateLibAvailable()) { | 352 if (!IsTranslateLibAvailable()) { |
| 359 // Evaluate the script to add the translation related method to the global | 353 // Evaluate the script to add the translation related method to the global |
| 360 // context of the page. | 354 // context of the page. |
| 361 ExecuteScript(translate_script); | 355 ExecuteScript(translate_script); |
| 362 DCHECK(IsTranslateLibAvailable()); | 356 DCHECK(IsTranslateLibAvailable()); |
| 363 } | 357 } |
| 364 | 358 |
| 365 TranslatePageImpl(page_seq_no, 0); | 359 TranslatePageImpl(0); |
| 366 } | 360 } |
| 367 | 361 |
| 368 void TranslateHelper::OnRevertTranslation(int page_seq_no) { | 362 void TranslateHelper::RevertTranslation() { |
| 369 if (page_seq_no_ != page_seq_no) | |
| 370 return; // We navigated away, nothing to do. | |
| 371 | |
| 372 if (!IsTranslateLibAvailable()) { | 363 if (!IsTranslateLibAvailable()) { |
| 373 NOTREACHED(); | 364 NOTREACHED(); |
| 374 return; | 365 return; |
| 375 } | 366 } |
| 376 | 367 |
| 377 CancelPendingTranslation(); | 368 CancelPendingTranslation(); |
| 378 | 369 |
| 379 ExecuteScript("cr.googleTranslate.revert()"); | 370 ExecuteScript("cr.googleTranslate.revert()"); |
| 380 } | 371 } |
| 381 | 372 |
| 382 void TranslateHelper::CheckTranslateStatus(int page_seq_no) { | 373 //////////////////////////////////////////////////////////////////////////////// |
| 383 // If this is not the same page, the translation has been canceled. | 374 // TranslateHelper, private: |
| 384 if (page_seq_no_ != page_seq_no) | 375 void TranslateHelper::CheckTranslateStatus() { |
| 385 return; | |
| 386 | |
| 387 // First check if there was an error. | 376 // First check if there was an error. |
| 388 if (HasTranslationFailed()) { | 377 if (HasTranslationFailed()) { |
| 389 // TODO(toyoshim): Check |errorCode| of translate.js and notify it here. | 378 // TODO(toyoshim): Check |errorCode| of translate.js and notify it here. |
| 390 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); | 379 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); |
| 391 return; // There was an error. | 380 return; // There was an error. |
| 392 } | 381 } |
| 393 | 382 |
| 394 if (HasTranslationFinished()) { | 383 if (HasTranslationFinished()) { |
| 395 std::string actual_source_lang; | 384 std::string actual_source_lang; |
| 396 // Translation was successfull, if it was auto, retrieve the source | 385 // Translation was successfull, if it was auto, retrieve the source |
| 397 // language the Translate Element detected. | 386 // language the Translate Element detected. |
| 398 if (source_lang_ == kAutoDetectionLanguage) { | 387 if (source_lang_ == kAutoDetectionLanguage) { |
| 399 actual_source_lang = GetOriginalPageLanguage(); | 388 actual_source_lang = GetOriginalPageLanguage(); |
| 400 if (actual_source_lang.empty()) { | 389 if (actual_source_lang.empty()) { |
| 401 NotifyBrowserTranslationFailed(TranslateErrors::UNKNOWN_LANGUAGE); | 390 NotifyBrowserTranslationFailed(TranslateErrors::UNKNOWN_LANGUAGE); |
| 402 return; | 391 return; |
| 403 } else if (actual_source_lang == target_lang_) { | 392 } else if (actual_source_lang == target_lang_) { |
| 404 NotifyBrowserTranslationFailed(TranslateErrors::IDENTICAL_LANGUAGES); | 393 NotifyBrowserTranslationFailed(TranslateErrors::IDENTICAL_LANGUAGES); |
| 405 return; | 394 return; |
| 406 } | 395 } |
| 407 } else { | 396 } else { |
| 408 actual_source_lang = source_lang_; | 397 actual_source_lang = source_lang_; |
| 409 } | 398 } |
| 410 | 399 |
| 411 if (!translation_pending_) { | 400 if (!translate_callback_pending_) { |
| 412 NOTREACHED(); | 401 NOTREACHED(); |
| 413 return; | 402 return; |
| 414 } | 403 } |
| 415 | 404 |
| 416 translation_pending_ = false; | |
| 417 | |
| 418 // Check JavaScript performance counters for UMA reports. | 405 // Check JavaScript performance counters for UMA reports. |
| 419 ReportTimeToTranslate( | 406 ReportTimeToTranslate( |
| 420 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.translationTime")); | 407 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.translationTime")); |
| 421 | 408 |
| 422 // Notify the browser we are done. | 409 // Notify the browser we are done. |
| 423 render_frame()->Send(new ChromeFrameHostMsg_PageTranslated( | 410 translate_callback_pending_.Run(false, actual_source_lang, target_lang_, |
| 424 render_frame()->GetRoutingID(), actual_source_lang, target_lang_, | 411 TranslateErrors::NONE); |
| 425 TranslateErrors::NONE)); | 412 translate_callback_pending_.Reset(); |
| 426 return; | 413 return; |
| 427 } | 414 } |
| 428 | 415 |
| 429 // The translation is still pending, check again later. | 416 // The translation is still pending, check again later. |
| 430 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 417 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 431 FROM_HERE, base::Bind(&TranslateHelper::CheckTranslateStatus, | 418 FROM_HERE, base::Bind(&TranslateHelper::CheckTranslateStatus, |
| 432 weak_method_factory_.GetWeakPtr(), page_seq_no), | 419 weak_method_factory_.GetWeakPtr()), |
| 433 AdjustDelay(kTranslateStatusCheckDelayMs)); | 420 AdjustDelay(kTranslateStatusCheckDelayMs)); |
| 434 } | 421 } |
| 435 | 422 |
| 436 void TranslateHelper::TranslatePageImpl(int page_seq_no, int count) { | 423 void TranslateHelper::TranslatePageImpl(int count) { |
| 437 DCHECK_LT(count, kMaxTranslateInitCheckAttempts); | 424 DCHECK_LT(count, kMaxTranslateInitCheckAttempts); |
| 438 if (page_seq_no_ != page_seq_no) | |
| 439 return; | |
| 440 | |
| 441 if (!IsTranslateLibReady()) { | 425 if (!IsTranslateLibReady()) { |
| 442 // The library is not ready, try again later, unless we have tried several | 426 // The library is not ready, try again later, unless we have tried several |
| 443 // times unsuccessfully already. | 427 // times unsuccessfully already. |
| 444 if (++count >= kMaxTranslateInitCheckAttempts) { | 428 if (++count >= kMaxTranslateInitCheckAttempts) { |
| 445 NotifyBrowserTranslationFailed(TranslateErrors::INITIALIZATION_ERROR); | 429 NotifyBrowserTranslationFailed(TranslateErrors::INITIALIZATION_ERROR); |
| 446 return; | 430 return; |
| 447 } | 431 } |
| 448 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 432 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 449 FROM_HERE, | 433 FROM_HERE, base::Bind(&TranslateHelper::TranslatePageImpl, |
| 450 base::Bind(&TranslateHelper::TranslatePageImpl, | 434 weak_method_factory_.GetWeakPtr(), count), |
| 451 weak_method_factory_.GetWeakPtr(), page_seq_no, count), | |
| 452 AdjustDelay(count * kTranslateInitCheckDelayMs)); | 435 AdjustDelay(count * kTranslateInitCheckDelayMs)); |
| 453 return; | 436 return; |
| 454 } | 437 } |
| 455 | 438 |
| 456 // The library is loaded, and ready for translation now. | 439 // The library is loaded, and ready for translation now. |
| 457 // Check JavaScript performance counters for UMA reports. | 440 // Check JavaScript performance counters for UMA reports. |
| 458 ReportTimeToBeReady( | 441 ReportTimeToBeReady( |
| 459 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.readyTime")); | 442 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.readyTime")); |
| 460 ReportTimeToLoad( | 443 ReportTimeToLoad( |
| 461 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.loadTime")); | 444 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.loadTime")); |
| 462 | 445 |
| 463 if (!StartTranslation()) { | 446 if (!StartTranslation()) { |
| 464 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); | 447 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); |
| 465 return; | 448 return; |
| 466 } | 449 } |
| 467 // Check the status of the translation. | 450 // Check the status of the translation. |
| 468 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 451 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 469 FROM_HERE, base::Bind(&TranslateHelper::CheckTranslateStatus, | 452 FROM_HERE, base::Bind(&TranslateHelper::CheckTranslateStatus, |
| 470 weak_method_factory_.GetWeakPtr(), page_seq_no), | 453 weak_method_factory_.GetWeakPtr()), |
| 471 AdjustDelay(kTranslateStatusCheckDelayMs)); | 454 AdjustDelay(kTranslateStatusCheckDelayMs)); |
| 472 } | 455 } |
| 473 | 456 |
| 474 void TranslateHelper::NotifyBrowserTranslationFailed( | 457 void TranslateHelper::NotifyBrowserTranslationFailed( |
| 475 TranslateErrors::Type error) { | 458 TranslateErrors::Type error) { |
| 476 translation_pending_ = false; | 459 DCHECK(translate_callback_pending_); |
| 477 // Notify the browser there was an error. | 460 // Notify the browser there was an error. |
| 478 render_frame()->Send(new ChromeFrameHostMsg_PageTranslated( | 461 translate_callback_pending_.Run(false, source_lang_, target_lang_, error); |
| 479 render_frame()->GetRoutingID(), source_lang_, target_lang_, error)); | 462 translate_callback_pending_.Reset(); |
| 463 } |
| 464 |
| 465 const mojom::ContentTranslateDriverPtr& TranslateHelper::GetTranslateDriver() { |
| 466 if (!translate_driver_) { |
| 467 render_frame()->GetRemoteInterfaces()->GetInterface( |
| 468 mojo::GetProxy(&translate_driver_)); |
| 469 } |
| 470 |
| 471 return translate_driver_; |
| 480 } | 472 } |
| 481 | 473 |
| 482 void TranslateHelper::OnDestruct() { | 474 void TranslateHelper::OnDestruct() { |
| 483 delete this; | 475 delete this; |
| 484 } | 476 } |
| 485 | 477 |
| 486 } // namespace translate | 478 } // namespace translate |
| OLD | NEW |