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

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: Address Marcus' 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 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/lazy_instance.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/path_service.h"
10 #include "base/platform_file.h"
11 #include "base/synchronization/lock.h"
12 #include "base/task_runner.h"
8 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/translate/translate_accept_languages_factory.h" 15 #include "chrome/browser/translate/translate_accept_languages_factory.h"
11 #include "chrome/browser/translate/translate_infobar_delegate.h" 16 #include "chrome/browser/translate/translate_infobar_delegate.h"
12 #include "chrome/browser/translate/translate_manager.h" 17 #include "chrome/browser/translate/translate_manager.h"
13 #include "chrome/browser/translate/translate_service.h" 18 #include "chrome/browser/translate/translate_service.h"
14 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_finder.h" 20 #include "chrome/browser/ui/browser_finder.h"
16 #include "chrome/browser/ui/browser_window.h" 21 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h" 22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/browser/ui/translate/translate_bubble_factory.h" 23 #include "chrome/browser/ui/translate/translate_bubble_factory.h"
24 #include "chrome/common/chrome_paths.h"
19 #include "chrome/common/pref_names.h" 25 #include "chrome/common/pref_names.h"
20 #include "chrome/common/render_messages.h" 26 #include "chrome/common/render_messages.h"
21 #include "components/translate/core/browser/page_translated_details.h" 27 #include "components/translate/core/browser/page_translated_details.h"
22 #include "components/translate/core/browser/translate_accept_languages.h" 28 #include "components/translate/core/browser/translate_accept_languages.h"
23 #include "components/translate/core/browser/translate_prefs.h" 29 #include "components/translate/core/browser/translate_prefs.h"
24 #include "components/translate/core/common/language_detection_details.h" 30 #include "components/translate/core/common/language_detection_details.h"
31 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_service.h" 32 #include "content/public/browser/notification_service.h"
33 #include "content/public/browser/render_process_host.h"
34 #include "content/public/browser/render_view_host.h"
26 #include "content/public/browser/web_contents.h" 35 #include "content/public/browser/web_contents.h"
27 36
28 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TranslateTabHelper); 37 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TranslateTabHelper);
29 38
39 #if defined(CLD2_DYNAMIC_MODE)
40 // Statics defined in the .h file:
41 base::PlatformFile TranslateTabHelper::s_cached_platform_file_
42 = base::kInvalidPlatformFileValue;
bulach 2014/03/25 09:29:26 nit: move the = to the previous line, and indent b
Andrew Hayden (chromium.org) 2014/03/26 15:34:11 Done.
43 base::LazyInstance<base::Lock> TranslateTabHelper::s_file_lock_
44 = LAZY_INSTANCE_INITIALIZER;
45 #endif
46
30 TranslateTabHelper::TranslateTabHelper(content::WebContents* web_contents) 47 TranslateTabHelper::TranslateTabHelper(content::WebContents* web_contents)
31 : content::WebContentsObserver(web_contents), 48 : content::WebContentsObserver(web_contents),
49 #if defined(CLD2_DYNAMIC_MODE)
50 weak_pointer_factory_(this),
51 #endif
32 translate_driver_(&web_contents->GetController()), 52 translate_driver_(&web_contents->GetController()),
33 translate_manager_(new TranslateManager(this, prefs::kAcceptLanguages)) {} 53 translate_manager_(new TranslateManager(this, prefs::kAcceptLanguages)) {}
34 54
35 TranslateTabHelper::~TranslateTabHelper() { 55 TranslateTabHelper::~TranslateTabHelper() {
36 } 56 }
37 57
38 LanguageState& TranslateTabHelper::GetLanguageState() { 58 LanguageState& TranslateTabHelper::GetLanguageState() {
39 return translate_driver_.GetLanguageState(); 59 return translate_driver_.GetLanguageState();
40 } 60 }
41 61
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 DCHECK(web_contents()); 151 DCHECK(web_contents());
132 return GetTranslateAcceptLanguages(web_contents()->GetBrowserContext()); 152 return GetTranslateAcceptLanguages(web_contents()->GetBrowserContext());
133 } 153 }
134 154
135 bool TranslateTabHelper::OnMessageReceived(const IPC::Message& message) { 155 bool TranslateTabHelper::OnMessageReceived(const IPC::Message& message) {
136 bool handled = true; 156 bool handled = true;
137 IPC_BEGIN_MESSAGE_MAP(TranslateTabHelper, message) 157 IPC_BEGIN_MESSAGE_MAP(TranslateTabHelper, message)
138 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_TranslateLanguageDetermined, 158 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_TranslateLanguageDetermined,
139 OnLanguageDetermined) 159 OnLanguageDetermined)
140 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PageTranslated, OnPageTranslated) 160 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PageTranslated, OnPageTranslated)
161 #if defined(CLD2_DYNAMIC_MODE)
162 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_NeedCLDData, OnCLDDataRequested)
163 #endif
141 IPC_MESSAGE_UNHANDLED(handled = false) 164 IPC_MESSAGE_UNHANDLED(handled = false)
142 IPC_END_MESSAGE_MAP() 165 IPC_END_MESSAGE_MAP()
143 166
144 return handled; 167 return handled;
145 } 168 }
146 169
147 void TranslateTabHelper::DidNavigateAnyFrame( 170 void TranslateTabHelper::DidNavigateAnyFrame(
148 const content::LoadCommittedDetails& details, 171 const content::LoadCommittedDetails& details,
149 const content::FrameNavigateParams& params) { 172 const content::FrameNavigateParams& params) {
150 // Let the LanguageState clear its state. 173 // Let the LanguageState clear its state.
151 translate_driver_.DidNavigate(details); 174 translate_driver_.DidNavigate(details);
152 } 175 }
153 176
154 void TranslateTabHelper::WebContentsDestroyed( 177 void TranslateTabHelper::WebContentsDestroyed(
155 content::WebContents* web_contents) { 178 content::WebContents* web_contents) {
156 // Translation process can be interrupted. 179 // Translation process can be interrupted.
157 // Destroying the TranslateManager now guarantees that it never has to deal 180 // Destroying the TranslateManager now guarantees that it never has to deal
158 // with NULL WebContents. 181 // with NULL WebContents.
159 translate_manager_.reset(); 182 translate_manager_.reset();
160 } 183 }
161 184
185 #if defined(CLD2_DYNAMIC_MODE)
186 void TranslateTabHelper::OnCLDDataRequested() {
187 // Quickly try to read s_cached_platform_file_. If valid, the file handle is
188 // cached and can be used immediately. Else, queue the caching task to the
189 // blocking pool.
190 s_file_lock_.Get().Acquire();
bulach 2014/03/25 09:29:26 AutoLock in its own scope?
Andrew Hayden (chromium.org) 2014/03/26 15:34:11 Done.
191 const base::PlatformFile handle = s_cached_platform_file_;
192 s_file_lock_.Get().Release();
193
194 if (handle != base::kInvalidPlatformFileValue) {
195 // Cached data available. Respond to the request.
196 SendCLDDataAvailable(handle);
197 return;
198 }
199
200 // Else, we don't have the data file yet. Queue a caching 0attempt.
palmer 2014/03/24 19:01:47 is "0attempt" a typo?
Andrew Hayden (chromium.org) 2014/03/26 15:34:11 yes, fixed.
201 // The caching attempt happens in the blocking pool because it may involve
202 // arbitrary filesystem access.
203 // After the caching attempt is made, we call MaybeSendCLDDataAvailable
204 // to pass the file handle to the renderer. This only results in an IPC
205 // message if the caching attempt was successful.
206 content::BrowserThread::PostBlockingPoolTaskAndReply(
207 FROM_HERE,
208 base::Bind(&TranslateTabHelper::HandleCLDDataRequest),
209 base::Bind(&TranslateTabHelper::MaybeSendCLDDataAvailable,
210 weak_pointer_factory_.GetWeakPtr()));
211 }
212
213 void TranslateTabHelper::MaybeSendCLDDataAvailable() {
214 if (!s_file_lock_.Get().Try())
bulach 2014/03/25 09:29:26 since the scope for the locks are much narrower no
Andrew Hayden (chromium.org) 2014/03/26 15:34:11 Done.
215 return; // We'll get another request later, whatevs!
216 const base::PlatformFile handle = s_cached_platform_file_;
217 s_file_lock_.Get().Release();
218 if (handle == base::kInvalidPlatformFileValue)
219 return; // Nope, not ready yet
bulach 2014/03/25 09:29:26 in this case, the early return is not buying much.
Andrew Hayden (chromium.org) 2014/03/26 15:34:11 Done.
220 SendCLDDataAvailable(handle);
221 }
222
223 void TranslateTabHelper::SendCLDDataAvailable(const base::PlatformFile handle) {
224 // Data available, respond to the request.
225 IPC::PlatformFileForTransit ipc_platform_file =
226 IPC::GetFileHandleForProcess(
227 handle,
228 GetWebContents()->GetRenderViewHost()->GetProcess()->GetHandle(),
229 false);
230 // In general, sending a response from within the code path that is processing
231 // a request is discouraged because there is potential for deadlock (if the
232 // methods are sent synchronously) or loops (if the response can trigger a
233 // new request). Neither of these concerns is relevant in this code, so
234 // sending the response from within the code path of the request handler is
235 // safe.
236 Send(new ChromeViewMsg_CLDDataAvailable(
237 GetWebContents()->GetRenderViewHost()->GetRoutingID(),
238 ipc_platform_file));
239 }
240
241 void TranslateTabHelper::HandleCLDDataRequest() {
242 // Because this function involves arbitrary file system access, it must run
243 // on the blocking pool.
244 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
245 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
246
247 {
248 base::AutoLock lock(s_file_lock_.Get());
249 if (s_cached_platform_file_ != base::kInvalidPlatformFileValue)
250 return; // Already done, duplicate request
251 }
252
253 base::FilePath path;
254 if (!PathService::Get(chrome::DIR_USER_DATA, &path)) {
255 LOG(WARNING) << "Unable to locate user data directory";
256 return; // Chrome isn't properly installed.
257 }
258
259 // If the file exists, we can send an IPC-safe construct back to the
260 // renderer process immediately.
261 path = path.Append(chrome::kCLDDataFilename);
262 if (!base::PathExists(path))
263 return;
264
265 // Attempt to open the file for reading.
266 bool created = false;
267 base::PlatformFileError error;
268 const base::PlatformFile file = base::CreatePlatformFile(
269 path,
270 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
271 &created, &error);
272 DCHECK(!created);
palmer 2014/03/24 19:01:47 I wonder if this should be a cause for LOG and ret
Andrew Hayden (chromium.org) 2014/03/26 15:34:11 Probably not. We're attempting to open a file for
273 if (error != base::PLATFORM_FILE_OK) {
274 LOG(WARNING) << "CLD data file exists but cannot be opened";
275 return;
276 }
277
278 s_file_lock_.Get().Acquire();
279 if (s_cached_platform_file_ != base::kInvalidPlatformFileValue) {
280 // Idempotence: Racing another request on the blocking pool, abort.
281 s_file_lock_.Get().Release();
palmer 2014/03/24 19:01:47 This, and line 288, make me think you want an Auto
bulach 2014/03/25 09:29:26 yep, something like: { AutoLock(...); if (s_c
Andrew Hayden (chromium.org) 2014/03/26 15:34:11 Done.
282 base::ClosePlatformFile(file);
283 return;
284 }
285
286 // Else, this request has taken care of it all. Cache the handle and return.
287 s_cached_platform_file_ = file;
288 s_file_lock_.Get().Release();
289 }
290 #endif // defined(CLD2_DYNAMIC_MODE)
291
162 void TranslateTabHelper::OnLanguageDetermined( 292 void TranslateTabHelper::OnLanguageDetermined(
163 const LanguageDetectionDetails& details, 293 const LanguageDetectionDetails& details,
164 bool page_needs_translation) { 294 bool page_needs_translation) {
165 translate_driver_.GetLanguageState().LanguageDetermined( 295 translate_driver_.GetLanguageState().LanguageDetermined(
166 details.adopted_language, page_needs_translation); 296 details.adopted_language, page_needs_translation);
167 297
168 content::NotificationService::current()->Notify( 298 content::NotificationService::current()->Notify(
169 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, 299 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED,
170 content::Source<content::WebContents>(web_contents()), 300 content::Source<content::WebContents>(web_contents()),
171 content::Details<const LanguageDetectionDetails>(&details)); 301 content::Details<const LanguageDetectionDetails>(&details));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 if (GetLanguageState().InTranslateNavigation()) 350 if (GetLanguageState().InTranslateNavigation())
221 return; 351 return;
222 } 352 }
223 353
224 TranslateBubbleFactory::Show( 354 TranslateBubbleFactory::Show(
225 browser->window(), web_contents(), step, error_type); 355 browser->window(), web_contents(), step, error_type);
226 #else 356 #else
227 NOTREACHED(); 357 NOTREACHED();
228 #endif 358 #endif
229 } 359 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698