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

Side by Side Diff: chrome/browser/translate/translate_tab_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: Use LazyInstance::Leaky for the mmap pointer 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 unified diff | Download patch
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 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 "chrome/browser/translate/translate_tab_helper.h" 5 #include "chrome/browser/translate/translate_tab_helper.h"
6 6
7 #include "base/basictypes.h"
8 #include "base/lazy_instance.h"
7 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/path_service.h"
11 #include "base/platform_file.h"
12 #include "base/synchronization/lock.h"
13 #include "base/task_runner.h"
8 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/translate/translate_accept_languages_factory.h" 16 #include "chrome/browser/translate/translate_accept_languages_factory.h"
11 #include "chrome/browser/translate/translate_infobar_delegate.h" 17 #include "chrome/browser/translate/translate_infobar_delegate.h"
12 #include "chrome/browser/translate/translate_manager.h" 18 #include "chrome/browser/translate/translate_manager.h"
13 #include "chrome/browser/translate/translate_service.h" 19 #include "chrome/browser/translate/translate_service.h"
14 #include "chrome/browser/ui/browser.h" 20 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_finder.h" 21 #include "chrome/browser/ui/browser_finder.h"
16 #include "chrome/browser/ui/browser_window.h" 22 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/browser/ui/translate/translate_bubble_factory.h" 24 #include "chrome/browser/ui/translate/translate_bubble_factory.h"
25 #include "chrome/common/chrome_paths.h"
19 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
20 #include "chrome/common/render_messages.h" 27 #include "chrome/common/render_messages.h"
21 #include "components/translate/core/browser/page_translated_details.h" 28 #include "components/translate/core/browser/page_translated_details.h"
22 #include "components/translate/core/browser/translate_accept_languages.h" 29 #include "components/translate/core/browser/translate_accept_languages.h"
23 #include "components/translate/core/browser/translate_prefs.h" 30 #include "components/translate/core/browser/translate_prefs.h"
24 #include "components/translate/core/common/language_detection_details.h" 31 #include "components/translate/core/common/language_detection_details.h"
32 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_service.h" 33 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/render_process_host.h"
35 #include "content/public/browser/render_view_host.h"
26 #include "content/public/browser/web_contents.h" 36 #include "content/public/browser/web_contents.h"
27 37
28 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TranslateTabHelper); 38 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TranslateTabHelper);
29 39
40 #if defined(CLD2_DYNAMIC_MODE)
41 // Statics defined in the .h file:
42 base::PlatformFile TranslateTabHelper::s_cached_platform_file_ =
43 base::kInvalidPlatformFileValue;
44 int64 TranslateTabHelper::s_cached_data_offset_ = -1;
45 int64 TranslateTabHelper::s_cached_data_length_ = -1;
46 base::LazyInstance<base::Lock> TranslateTabHelper::s_file_lock_ =
47 LAZY_INSTANCE_INITIALIZER;
48 #endif
49
30 TranslateTabHelper::TranslateTabHelper(content::WebContents* web_contents) 50 TranslateTabHelper::TranslateTabHelper(content::WebContents* web_contents)
31 : content::WebContentsObserver(web_contents), 51 : content::WebContentsObserver(web_contents),
52 #if defined(CLD2_DYNAMIC_MODE)
53 weak_pointer_factory_(this),
54 #endif
32 translate_driver_(&web_contents->GetController()), 55 translate_driver_(&web_contents->GetController()),
33 translate_manager_(new TranslateManager(this, prefs::kAcceptLanguages)) {} 56 translate_manager_(new TranslateManager(this, prefs::kAcceptLanguages)) {}
34 57
35 TranslateTabHelper::~TranslateTabHelper() { 58 TranslateTabHelper::~TranslateTabHelper() {
36 } 59 }
37 60
38 LanguageState& TranslateTabHelper::GetLanguageState() { 61 LanguageState& TranslateTabHelper::GetLanguageState() {
39 return translate_driver_.GetLanguageState(); 62 return translate_driver_.GetLanguageState();
40 } 63 }
41 64
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 DCHECK(web_contents()); 154 DCHECK(web_contents());
132 return GetTranslateAcceptLanguages(web_contents()->GetBrowserContext()); 155 return GetTranslateAcceptLanguages(web_contents()->GetBrowserContext());
133 } 156 }
134 157
135 bool TranslateTabHelper::OnMessageReceived(const IPC::Message& message) { 158 bool TranslateTabHelper::OnMessageReceived(const IPC::Message& message) {
136 bool handled = true; 159 bool handled = true;
137 IPC_BEGIN_MESSAGE_MAP(TranslateTabHelper, message) 160 IPC_BEGIN_MESSAGE_MAP(TranslateTabHelper, message)
138 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_TranslateLanguageDetermined, 161 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_TranslateLanguageDetermined,
139 OnLanguageDetermined) 162 OnLanguageDetermined)
140 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PageTranslated, OnPageTranslated) 163 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PageTranslated, OnPageTranslated)
164 #if defined(CLD2_DYNAMIC_MODE)
165 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_NeedCLDData, OnCLDDataRequested)
166 #endif
141 IPC_MESSAGE_UNHANDLED(handled = false) 167 IPC_MESSAGE_UNHANDLED(handled = false)
142 IPC_END_MESSAGE_MAP() 168 IPC_END_MESSAGE_MAP()
143 169
144 return handled; 170 return handled;
145 } 171 }
146 172
147 void TranslateTabHelper::DidNavigateAnyFrame( 173 void TranslateTabHelper::DidNavigateAnyFrame(
148 const content::LoadCommittedDetails& details, 174 const content::LoadCommittedDetails& details,
149 const content::FrameNavigateParams& params) { 175 const content::FrameNavigateParams& params) {
150 // Let the LanguageState clear its state. 176 // Let the LanguageState clear its state.
151 translate_driver_.DidNavigate(details); 177 translate_driver_.DidNavigate(details);
152 } 178 }
153 179
154 void TranslateTabHelper::WebContentsDestroyed( 180 void TranslateTabHelper::WebContentsDestroyed(
155 content::WebContents* web_contents) { 181 content::WebContents* web_contents) {
156 // Translation process can be interrupted. 182 // Translation process can be interrupted.
157 // Destroying the TranslateManager now guarantees that it never has to deal 183 // Destroying the TranslateManager now guarantees that it never has to deal
158 // with NULL WebContents. 184 // with NULL WebContents.
159 translate_manager_.reset(); 185 translate_manager_.reset();
160 } 186 }
161 187
188 #if defined(CLD2_DYNAMIC_MODE)
189 void TranslateTabHelper::OnCLDDataRequested() {
190 // Quickly try to read s_cached_platform_file_. If valid, the file handle is
191 // cached and can be used immediately. Else, queue the caching task to the
192 // blocking pool.
193 base::PlatformFile handle = base::kInvalidPlatformFileValue;
194 int64 data_offset = -1;
195 int64 data_length = -1;
196 {
197 base::AutoLock lock(s_file_lock_.Get());
198 handle = s_cached_platform_file_;
199 data_offset = s_cached_data_offset_;
200 data_length = s_cached_data_length_;
201 }
202
203 if (handle != base::kInvalidPlatformFileValue) {
204 // Cached data available. Respond to the request.
205 SendCLDDataAvailable(handle, data_offset, data_length);
206 return;
207 }
208
209 // Else, we don't have the data file yet. Queue a caching attempt.
210 // The caching attempt happens in the blocking pool because it may involve
211 // arbitrary filesystem access.
212 // After the caching attempt is made, we call MaybeSendCLDDataAvailable
213 // to pass the file handle to the renderer. This only results in an IPC
214 // message if the caching attempt was successful.
215 content::BrowserThread::PostBlockingPoolTaskAndReply(
216 FROM_HERE,
217 base::Bind(&TranslateTabHelper::HandleCLDDataRequest),
218 base::Bind(&TranslateTabHelper::MaybeSendCLDDataAvailable,
219 weak_pointer_factory_.GetWeakPtr()));
220 }
221
222 void TranslateTabHelper::MaybeSendCLDDataAvailable() {
223 base::PlatformFile handle = base::kInvalidPlatformFileValue;
224 int64 data_offset = -1;
225 int64 data_length = -1;
226 {
227 base::AutoLock lock(s_file_lock_.Get());
228 handle = s_cached_platform_file_;
229 data_offset = s_cached_data_offset_;
230 data_length = s_cached_data_length_;
231 }
232
233 if (handle != base::kInvalidPlatformFileValue)
234 SendCLDDataAvailable(handle, data_offset, data_length);
235 }
236
237 void TranslateTabHelper::SendCLDDataAvailable(const base::PlatformFile handle,
238 const int64 data_offset,
239 const int64 data_length) {
240 // Data available, respond to the request.
241 IPC::PlatformFileForTransit ipc_platform_file =
242 IPC::GetFileHandleForProcess(
243 handle,
244 GetWebContents()->GetRenderViewHost()->GetProcess()->GetHandle(),
245 false);
246 // In general, sending a response from within the code path that is processing
247 // a request is discouraged because there is potential for deadlock (if the
248 // methods are sent synchronously) or loops (if the response can trigger a
249 // new request). Neither of these concerns is relevant in this code, so
250 // sending the response from within the code path of the request handler is
251 // safe.
252 Send(new ChromeViewMsg_CLDDataAvailable(
253 GetWebContents()->GetRenderViewHost()->GetRoutingID(),
254 ipc_platform_file, data_offset, data_length));
255 }
256
257 void TranslateTabHelper::HandleCLDDataRequest() {
258 // Because this function involves arbitrary file system access, it must run
259 // on the blocking pool.
260 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
261 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
262
263 {
264 base::AutoLock lock(s_file_lock_.Get());
265 if (s_cached_platform_file_ != base::kInvalidPlatformFileValue)
266 return; // Already done, duplicate request
267 }
268
269 base::FilePath path;
270 if (!PathService::Get(chrome::DIR_USER_DATA, &path)) {
271 LOG(WARNING) << "Unable to locate user data directory";
272 return; // Chrome isn't properly installed.
273 }
274
275 // If the file exists, we can send an IPC-safe construct back to the
276 // renderer process immediately.
277 path = path.Append(chrome::kCLDDataFilename);
278 if (!base::PathExists(path))
279 return;
280
281 // Attempt to open the file for reading.
282 bool created = false;
283 base::PlatformFileError error;
284 const base::PlatformFile file = base::CreatePlatformFile(
285 path,
286 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
287 &created, &error);
288 DCHECK(!created);
289 if (error != base::PLATFORM_FILE_OK) {
290 LOG(WARNING) << "CLD data file exists but cannot be opened";
291 return;
292 }
293
294 base::PlatformFileInfo file_info;
295 if (!base::GetPlatformFileInfo(file, &file_info)) {
296 LOG(WARNING) << "CLD data file exists but cannot be inspected";
297 return;
298 }
299
300 // For now, our offset and length are simply 0 and the length of the file,
301 // respectively. If we later decide to include the CLD2 data file inside of
302 // a larger binary context, these params can be twiddled appropriately.
303 const int64 data_offset = 0;
304 const int64 data_length = file_info.size;
305
306 bool racing = false;
307 {
308 base::AutoLock lock(s_file_lock_.Get());
309 if (s_cached_platform_file_ != base::kInvalidPlatformFileValue) {
310 // Idempotence: Racing another request on the blocking pool, abort.
311 racing = true;
312 } else {
313 // Else, this request has taken care of it all. Cache all info.
314 s_cached_platform_file_ = file;
315 s_cached_data_offset_ = data_offset;
316 s_cached_data_length_ = data_length;
317 }
318 }
319
320 if (racing) {
321 // Other thread wins, give up the redundant file handle.
322 base::ClosePlatformFile(file);
323 }
324 }
325 #endif // defined(CLD2_DYNAMIC_MODE)
326
162 void TranslateTabHelper::OnLanguageDetermined( 327 void TranslateTabHelper::OnLanguageDetermined(
163 const LanguageDetectionDetails& details, 328 const LanguageDetectionDetails& details,
164 bool page_needs_translation) { 329 bool page_needs_translation) {
165 translate_driver_.GetLanguageState().LanguageDetermined( 330 translate_driver_.GetLanguageState().LanguageDetermined(
166 details.adopted_language, page_needs_translation); 331 details.adopted_language, page_needs_translation);
167 332
168 content::NotificationService::current()->Notify( 333 content::NotificationService::current()->Notify(
169 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, 334 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED,
170 content::Source<content::WebContents>(web_contents()), 335 content::Source<content::WebContents>(web_contents()),
171 content::Details<const LanguageDetectionDetails>(&details)); 336 content::Details<const LanguageDetectionDetails>(&details));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 if (GetLanguageState().InTranslateNavigation()) 385 if (GetLanguageState().InTranslateNavigation())
221 return; 386 return;
222 } 387 }
223 388
224 TranslateBubbleFactory::Show( 389 TranslateBubbleFactory::Show(
225 browser->window(), web_contents(), step, error_type); 390 browser->window(), web_contents(), step, error_type);
226 #else 391 #else
227 NOTREACHED(); 392 NOTREACHED();
228 #endif 393 #endif
229 } 394 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698