OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 // NOT DEAD CODE! | |
6 // This code isn't dead, even if it isn't currently being used. Please refer to: | |
7 // https://www.chromium.org/developers/how-tos/compact-language-detector-cld-dat
a-source-configuration | |
8 | |
9 #include "components/translate/content/renderer/data_file_renderer_cld_data_prov
ider.h" | |
10 | |
11 #include <utility> | |
12 | |
13 #include "base/files/file.h" | |
14 #include "base/files/memory_mapped_file.h" | |
15 #include "base/lazy_instance.h" | |
16 #include "base/logging.h" | |
17 #include "components/translate/content/common/data_file_cld_data_provider_messag
es.h" | |
18 #include "content/public/renderer/render_frame_observer.h" | |
19 #include "ipc/ipc_message.h" | |
20 #include "ipc/ipc_message_macros.h" | |
21 #include "ipc/ipc_platform_file.h" | |
22 #include "third_party/cld_2/src/public/compact_lang_det.h" | |
23 | |
24 namespace { | |
25 | |
26 // A struct that contains the pointer to the CLD mmap. Used so that we can | |
27 // leverage LazyInstance:Leaky to properly scope the lifetime of the mmap. | |
28 struct CLDMmapWrapper { | |
29 CLDMmapWrapper() { value = NULL; } | |
30 base::MemoryMappedFile* value; | |
31 }; | |
32 base::LazyInstance<CLDMmapWrapper>::Leaky g_cld_mmap = | |
33 LAZY_INSTANCE_INITIALIZER; | |
34 | |
35 } // namespace | |
36 | |
37 namespace translate { | |
38 | |
39 DataFileRendererCldDataProvider::DataFileRendererCldDataProvider( | |
40 content::RenderFrameObserver* render_frame_observer) | |
41 : render_frame_observer_(render_frame_observer) { | |
42 } | |
43 | |
44 DataFileRendererCldDataProvider::~DataFileRendererCldDataProvider() { | |
45 } | |
46 | |
47 bool DataFileRendererCldDataProvider::OnMessageReceived( | |
48 const IPC::Message& message) { | |
49 bool handled = true; | |
50 IPC_BEGIN_MESSAGE_MAP(DataFileRendererCldDataProvider, message) | |
51 IPC_MESSAGE_HANDLER(ChromeFrameMsg_CldDataFileAvailable, OnCldDataAvailable) | |
52 IPC_MESSAGE_UNHANDLED(handled = false) | |
53 IPC_END_MESSAGE_MAP() | |
54 return handled; | |
55 } | |
56 | |
57 void DataFileRendererCldDataProvider::SendCldDataRequest() { | |
58 // Else, send the IPC message to the browser process requesting the data... | |
59 render_frame_observer_->Send(new ChromeFrameHostMsg_NeedCldDataFile( | |
60 render_frame_observer_->routing_id())); | |
61 } | |
62 | |
63 bool DataFileRendererCldDataProvider::IsCldDataAvailable() { | |
64 // This neatly removes the need for code that depends on the generalized | |
65 // RendererCldDataProvider to #ifdef on CLD2_DYNAMIC_MODE | |
66 return CLD2::isDataLoaded(); // ground truth, independent of our state. | |
67 } | |
68 | |
69 void DataFileRendererCldDataProvider::SetCldAvailableCallback( | |
70 base::Callback<void(void)> callback) { | |
71 cld_available_callback_ = callback; | |
72 } | |
73 | |
74 void DataFileRendererCldDataProvider::OnCldDataAvailable( | |
75 const IPC::PlatformFileForTransit ipc_file_handle, | |
76 const uint64_t data_offset, | |
77 const uint64_t data_length) { | |
78 LoadCldData(IPC::PlatformFileForTransitToFile(ipc_file_handle), | |
79 data_offset, | |
80 data_length); | |
81 } | |
82 | |
83 void DataFileRendererCldDataProvider::LoadCldData(base::File file, | |
84 const uint64_t data_offset, | |
85 const uint64_t data_length) { | |
86 // Terminate immediately if data is already loaded. | |
87 if (IsCldDataAvailable()) | |
88 return; | |
89 | |
90 if (!file.IsValid()) { | |
91 LOG(ERROR) << "Can't find the CLD data file."; | |
92 return; | |
93 } | |
94 | |
95 // mmap the file | |
96 g_cld_mmap.Get().value = new base::MemoryMappedFile(); | |
97 bool initialized = g_cld_mmap.Get().value->Initialize(std::move(file)); | |
98 if (!initialized) { | |
99 LOG(ERROR) << "mmap initialization failed"; | |
100 delete g_cld_mmap.Get().value; | |
101 g_cld_mmap.Get().value = NULL; | |
102 return; | |
103 } | |
104 | |
105 // Sanity checks | |
106 uint64_t max_int32 = std::numeric_limits<int32_t>::max(); | |
107 if (data_length + data_offset > g_cld_mmap.Get().value->length() || | |
108 data_length > max_int32) { // max signed 32 bit integer | |
109 LOG(ERROR) << "Illegal mmap config: data_offset=" << data_offset | |
110 << ", data_length=" << data_length | |
111 << ", mmap->length()=" << g_cld_mmap.Get().value->length(); | |
112 delete g_cld_mmap.Get().value; | |
113 g_cld_mmap.Get().value = NULL; | |
114 return; | |
115 } | |
116 | |
117 // Initialize the CLD subsystem... and it's all done! | |
118 const uint8_t* data_ptr = g_cld_mmap.Get().value->data() + data_offset; | |
119 CLD2::loadDataFromRawAddress(data_ptr, data_length); | |
120 DCHECK(CLD2::isDataLoaded()) << "Failed to load CLD data from mmap"; | |
121 if (!cld_available_callback_.is_null()) { | |
122 cld_available_callback_.Run(); | |
123 } | |
124 } | |
125 | |
126 } // namespace translate | |
OLD | NEW |