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

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

Powered by Google App Engine
This is Rietveld 408576698