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

Unified Diff: chrome/renderer/translate/translate_helper.cc

Issue 187393005: Make it possible to read CLD data from a file (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Marcus' and Jochen's comments Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/translate/translate_helper.cc
diff --git a/chrome/renderer/translate/translate_helper.cc b/chrome/renderer/translate/translate_helper.cc
index ccd2279a294de5603fb918002707f27b268f5817..488a38e9e38cb0fc4cbf28ec5dc492877c071416 100644
--- a/chrome/renderer/translate/translate_helper.cc
+++ b/chrome/renderer/translate/translate_helper.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
@@ -19,6 +20,11 @@
#include "components/translate/core/common/translate_util.h"
#include "components/translate/language_detection/language_detection_util.h"
#include "content/public/renderer/render_view.h"
+#include "extensions/common/constants.h"
+#include "ipc/ipc_platform_file.h"
+#if defined(CLD2_DYNAMIC_MODE)
+#include "third_party/cld_2/src/public/compact_lang_det.h"
+#endif
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebFrame.h"
@@ -53,7 +59,7 @@ const int kTranslateInitCheckDelayMs = 150;
const int kMaxTranslateInitCheckAttempts = 5;
// The delay we wait in milliseconds before checking whether the translation has
-// finished.
+// finished.cld2_data_file = NULL;
Takashi Toyoshima 2014/03/13 18:37:37 paste it mistakenly?
Andrew Hayden (chromium.org) 2014/03/14 10:10:52 Done.
const int kTranslateStatusCheckDelayMs = 400;
// Language name passed to the Translate element for it to detect the language.
@@ -72,12 +78,48 @@ TranslateHelper::TranslateHelper(content::RenderView* render_view)
page_id_(-1),
translation_pending_(false),
weak_method_factory_(this) {
+#if defined(CLD2_DYNAMIC_MODE)
+ cld2_data_file_polling_started = false;
+ cld2_data_file_polling_canceled = false;
+ deferred_page_capture_ = false;
+ deferred_page_id_ = -1;
palmer 2014/03/13 17:59:50 Put these up above in the : initialization list.
Andrew Hayden (chromium.org) 2014/03/13 23:20:21 Done.
+ deferred_contents_ = ASCIIToUTF16("");
+#endif
}
TranslateHelper::~TranslateHelper() {
CancelPendingTranslation();
+#if defined(CLD2_DYNAMIC_MODE)
+ CancelCLD2DataFilePolling();
+#endif
}
+void TranslateHelper::PrepareForUrl(const GURL& url) {
+#if defined(CLD2_DYNAMIC_MODE)
Takashi Toyoshima 2014/03/13 18:37:37 you may want to reset deferred_* here?
Andrew Hayden (chromium.org) 2014/03/14 10:10:52 Hmm, good thought. It's SAFE to leave it alone, be
+ if (cld2_data_file_polling_started) return;
palmer 2014/03/13 17:59:50 Style nit.
Andrew Hayden (chromium.org) 2014/03/13 23:20:21 Done.
+
+ // There is no reason to ever bother loading CLD data for an extension URL.
+ // There's also no render_view_host_observer to answer us, so don't ask for
+ // CLD data!
+ if (url.SchemeIs(extensions::kExtensionScheme)) return;
Takashi Toyoshima 2014/03/13 18:37:37 TranslateManager::IsTranslatableURL() is the funct
Andrew Hayden (chromium.org) 2014/03/14 10:10:52 For clarity I'll submit a separate patchset in thi
+
+ // If the URL isn't an extension URL, we might conceivably want translation
+ // capabilities. Start polling for CLD data.
+ cld2_data_file_polling_started = true;
+ TranslateHelper::SendCLD2DataFileRequest(0, 1000);
+#endif
+}
+
+#if defined(CLD2_DYNAMIC_MODE)
+void TranslateHelper::DeferPageCaptured(const int page_id,
+ const base::string16& contents) {
palmer 2014/03/13 17:59:50 Nit: indentation.
Takashi Toyoshima 2014/03/13 18:37:37 wrong indent
Andrew Hayden (chromium.org) 2014/03/13 23:20:21 Done.
+ deferred_page_capture_ = true;
+ deferred_page_id_ = page_id;
+ deferred_contents_.clear();
+ deferred_contents_.append(contents);
Takashi Toyoshima 2014/03/13 18:37:37 Just a question. Why don't you simply assign it, b
Andrew Hayden (chromium.org) 2014/03/14 10:10:52 I'll assign it instead. I was concerned about the
+}
+#endif
+
void TranslateHelper::PageCaptured(int page_id,
const base::string16& contents) {
// Get the document language as set by WebKit from the http-equiv
@@ -92,6 +134,17 @@ void TranslateHelper::PageCaptured(int page_id,
WebFrame* main_frame = GetMainFrame();
if (!main_frame || render_view()->GetPageId() != page_id)
return;
+
+ // TODO(andrewhayden): UMA insertion point here: Track if data is available.
Takashi Toyoshima 2014/03/13 18:37:37 Just a question: How long time does it take from c
Andrew Hayden (chromium.org) 2014/03/14 10:10:52 I don't have data but I'd be happy to measure it :
+ // TODO(andrewhayden): Retry insertion point here, retry till data available.
+#if defined(CLD2_DYNAMIC_MODE)
+ if (!CLD2::isDataLoaded()) {
+ // We're in dynamic mode and CLD data isn't loaded. Retry when CLD data
+ // is loaded, if ever.
+ TranslateHelper::DeferPageCaptured(page_id, contents);
+ return;
+ }
+#endif
page_id_ = page_id;
WebDocument document = main_frame->document();
std::string content_language = document.contentLanguage().utf8();
@@ -136,6 +189,9 @@ void TranslateHelper::CancelPendingTranslation() {
translation_pending_ = false;
source_lang_.clear();
target_lang_.clear();
+#if defined(CLD2_DYNAMIC_MODE)
+ CancelCLD2DataFilePolling();
+#endif
}
////////////////////////////////////////////////////////////////////////////////
@@ -310,6 +366,9 @@ bool TranslateHelper::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(TranslateHelper, message)
IPC_MESSAGE_HANDLER(ChromeViewMsg_TranslatePage, OnTranslatePage)
IPC_MESSAGE_HANDLER(ChromeViewMsg_RevertTranslation, OnRevertTranslation)
+#if defined(CLD2_DYNAMIC_MODE)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_CLDDataAvailable, OnCLDDataAvailable);
+#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -499,3 +558,92 @@ WebFrame* TranslateHelper::GetMainFrame() {
return web_view->mainFrame();
}
+
+#if defined(CLD2_DYNAMIC_MODE)
+void TranslateHelper::CancelCLD2DataFilePolling() {
+ cld2_data_file_polling_canceled = true;
+}
+
+void TranslateHelper::SendCLD2DataFileRequest(int delay_millis,
+ int next_delay_millis) {
+ // We terminate immediately if we've been told to stop polling
+ if (cld2_data_file_polling_canceled) return;
palmer 2014/03/13 17:59:50 Style (everywhere this occurs).
Andrew Hayden (chromium.org) 2014/03/13 23:20:21 Done.
+
+ // We terminate immediately if we've already loaded the data.
+ if (CLD2::isDataLoaded()) return;
+
+ // Else, send the IPC message to the browser process requesting the data...
+ Send(new ChromeViewHostMsg_NeedCLDData(routing_id()));
+
+ // ... and enqueue another delayed task to call again. This will start a
+ // chain of polling that will last until the pointer stops being null,
+ // which is the right thing to do.
+ // NB: In the great majority of cases, the data file will be available and
+ // the very first delayed task will be a no-op that terminates the chain.
+ // It's only while downloading the file that we expect this to chain for a
+ // nontrivial amount of time.
+ // Use a weak pointer so that we don't keep this helper object around forever.
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&TranslateHelper::SendCLD2DataFileRequest,
+ weak_method_factory_.GetWeakPtr(),
+ next_delay_millis, next_delay_millis),
+ base::TimeDelta::FromMilliseconds(delay_millis));
+}
+
+void TranslateHelper::OnCLDDataAvailable(
+ IPC::PlatformFileForTransit ipc_file_handle) {
+ LoadCLDDData(ipc_file_handle);
+ if (deferred_page_capture_) {
+ if (CLD2::isDataLoaded()) {
+ // We have data available now, and we previously deferred a request to
+ // start translation. Finish that request up and clear our state.
+ // The real situation this translates to is as follows:
+ // The user loaded a page before the CLD data was available - either
+ // because the browser process took too long to respond to our CLD data
+ // request, or because the data truly hasn't been available;
+ // The data is now available, so we should get that language check
+ // done and post the message back to the browser ASAP.
+ deferred_page_capture_ = false; // Don't do this a second time.
+ PageCaptured(deferred_page_id_, deferred_contents_);
+ deferred_page_id_ = -1; // clean up for sanity
+ deferred_contents_.clear(); // clean up for sanity
+ }
+ }
+}
+
+void TranslateHelper::LoadCLDDData(
+ IPC::PlatformFileForTransit ipc_file_handle) {
+ // We terminate immediately if we've been told to stop polling
+ if (cld2_data_file_polling_canceled) return;
+
+ // We terminate immediately if we've already loaded the data.
+ if (CLD2::isDataLoaded()) return;
+
+ // The mmap must outlive this function and must not be destroyed because
+ // the destructor for mmap will unmap the memory segment and close the file
+ // handle. Thus, declare it static.
+ static base::MemoryMappedFile* mmap = NULL;
+ DCHECK(mmap != NULL) << "Lost CLD mmap!"; // Should be impossible!
+
+ // Grab the file handle
+ base::PlatformFile platformFile =
+ IPC::PlatformFileForTransitToPlatformFile(ipc_file_handle);
+ DCHECK(platformFile > 0) << "Can't find the CLD data file!";
+ base::File basicFile(platformFile);
+
+ // mmap the file
+ mmap = new base::MemoryMappedFile();
+ bool loadedOk = mmap->Initialize(basicFile.Pass());
+ DCHECK(loadedOk) << "Failed to initialize CLD data mmap";
+ if (!loadedOk) {
+ delete mmap;
+ mmap = NULL;
+ return;
+ }
+
+ // Initialize the CLD subsystem... we're done!
+ CLD2::loadDataFromRawAddress(mmap->data(), mmap->length());
+ DCHECK(CLD2::isDataLoaded()) << "Failed to load CLD data from mmap";
+}
+#endif

Powered by Google App Engine
This is Rietveld 408576698