OLD | NEW |
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/path_service.h" |
| 8 #include "base/platform_file.h" |
| 9 #include "base/synchronization/lock.h" |
| 10 #include "base/task_runner.h" |
7 #include "chrome/browser/chrome_notification_types.h" | 11 #include "chrome/browser/chrome_notification_types.h" |
8 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
9 #include "chrome/browser/translate/translate_accept_languages_factory.h" | 13 #include "chrome/browser/translate/translate_accept_languages_factory.h" |
10 #include "chrome/browser/translate/translate_infobar_delegate.h" | 14 #include "chrome/browser/translate/translate_infobar_delegate.h" |
11 #include "chrome/browser/translate/translate_manager.h" | 15 #include "chrome/browser/translate/translate_manager.h" |
12 #include "chrome/browser/translate/translate_service.h" | 16 #include "chrome/browser/translate/translate_service.h" |
13 #include "chrome/browser/ui/browser.h" | 17 #include "chrome/browser/ui/browser.h" |
14 #include "chrome/browser/ui/browser_finder.h" | 18 #include "chrome/browser/ui/browser_finder.h" |
15 #include "chrome/browser/ui/browser_window.h" | 19 #include "chrome/browser/ui/browser_window.h" |
16 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
17 #include "chrome/browser/ui/translate/translate_bubble_factory.h" | 21 #include "chrome/browser/ui/translate/translate_bubble_factory.h" |
| 22 #include "chrome/common/chrome_paths.h" |
18 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
19 #include "chrome/common/render_messages.h" | 24 #include "chrome/common/render_messages.h" |
20 #include "components/translate/core/browser/page_translated_details.h" | 25 #include "components/translate/core/browser/page_translated_details.h" |
21 #include "components/translate/core/browser/translate_accept_languages.h" | 26 #include "components/translate/core/browser/translate_accept_languages.h" |
22 #include "components/translate/core/browser/translate_prefs.h" | 27 #include "components/translate/core/browser/translate_prefs.h" |
23 #include "components/translate/core/common/language_detection_details.h" | 28 #include "components/translate/core/common/language_detection_details.h" |
| 29 #include "content/public/browser/browser_thread.h" |
24 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
| 31 #include "content/public/browser/render_process_host.h" |
| 32 #include "content/public/browser/render_view_host.h" |
25 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
26 | 34 |
27 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TranslateTabHelper); | 35 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TranslateTabHelper); |
28 | 36 |
| 37 #if defined(CLD2_DYNAMIC_MODE) |
| 38 // Statics defined in the .h file: |
| 39 base::PlatformFile TranslateTabHelper::s_cached_platform_file_ = 0; |
| 40 base::Lock TranslateTabHelper::s_file_lock_; |
| 41 #endif |
| 42 |
29 TranslateTabHelper::TranslateTabHelper(content::WebContents* web_contents) | 43 TranslateTabHelper::TranslateTabHelper(content::WebContents* web_contents) |
30 : content::WebContentsObserver(web_contents), | 44 : content::WebContentsObserver(web_contents), |
| 45 #if defined(CLD2_DYNAMIC_MODE) |
| 46 weak_pointer_factory_(this), |
| 47 #endif |
31 translate_driver_(&web_contents->GetController()), | 48 translate_driver_(&web_contents->GetController()), |
32 translate_manager_(new TranslateManager(this)) {} | 49 translate_manager_(new TranslateManager(this)) {} |
33 | 50 |
34 TranslateTabHelper::~TranslateTabHelper() { | 51 TranslateTabHelper::~TranslateTabHelper() { |
35 } | 52 } |
36 | 53 |
37 LanguageState& TranslateTabHelper::GetLanguageState() { | 54 LanguageState& TranslateTabHelper::GetLanguageState() { |
38 return translate_driver_.GetLanguageState(); | 55 return translate_driver_.GetLanguageState(); |
39 } | 56 } |
40 | 57 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 TranslateDriver* TranslateTabHelper::GetTranslateDriver() { | 128 TranslateDriver* TranslateTabHelper::GetTranslateDriver() { |
112 return &translate_driver_; | 129 return &translate_driver_; |
113 } | 130 } |
114 | 131 |
115 bool TranslateTabHelper::OnMessageReceived(const IPC::Message& message) { | 132 bool TranslateTabHelper::OnMessageReceived(const IPC::Message& message) { |
116 bool handled = true; | 133 bool handled = true; |
117 IPC_BEGIN_MESSAGE_MAP(TranslateTabHelper, message) | 134 IPC_BEGIN_MESSAGE_MAP(TranslateTabHelper, message) |
118 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_TranslateLanguageDetermined, | 135 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_TranslateLanguageDetermined, |
119 OnLanguageDetermined) | 136 OnLanguageDetermined) |
120 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PageTranslated, OnPageTranslated) | 137 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PageTranslated, OnPageTranslated) |
| 138 #if defined(CLD2_DYNAMIC_MODE) |
| 139 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_NeedCLDData, OnCLDDataRequested) |
| 140 #endif |
121 IPC_MESSAGE_UNHANDLED(handled = false) | 141 IPC_MESSAGE_UNHANDLED(handled = false) |
122 IPC_END_MESSAGE_MAP() | 142 IPC_END_MESSAGE_MAP() |
123 | 143 |
124 return handled; | 144 return handled; |
125 } | 145 } |
126 | 146 |
127 void TranslateTabHelper::DidNavigateAnyFrame( | 147 void TranslateTabHelper::DidNavigateAnyFrame( |
128 const content::LoadCommittedDetails& details, | 148 const content::LoadCommittedDetails& details, |
129 const content::FrameNavigateParams& params) { | 149 const content::FrameNavigateParams& params) { |
130 // Let the LanguageState clear its state. | 150 // Let the LanguageState clear its state. |
131 translate_driver_.DidNavigate(details); | 151 translate_driver_.DidNavigate(details); |
132 } | 152 } |
133 | 153 |
134 void TranslateTabHelper::WebContentsDestroyed( | 154 void TranslateTabHelper::WebContentsDestroyed( |
135 content::WebContents* web_contents) { | 155 content::WebContents* web_contents) { |
136 // Translation process can be interrupted. | 156 // Translation process can be interrupted. |
137 // Destroying the TranslateManager now guarantees that it never has to deal | 157 // Destroying the TranslateManager now guarantees that it never has to deal |
138 // with NULL WebContents. | 158 // with NULL WebContents. |
139 translate_manager_.reset(); | 159 translate_manager_.reset(); |
140 } | 160 } |
141 | 161 |
| 162 #if defined(CLD2_DYNAMIC_MODE) |
| 163 void TranslateTabHelper::OnCLDDataRequested() { |
| 164 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 165 // Quickly try to read s_cached_platform_file_. If it's non-zero, we have |
| 166 // cached the CLD data file and can answer immediately; else, we'll make |
| 167 // a request to the blocking pool to look up the file and cache it. |
| 168 // The value of s_cached_platform_file_ becomes non-zero is only set once, |
| 169 // so when it becomes non-zero we are guaranteed it will not change again. |
| 170 if (!s_file_lock_.Try()) |
| 171 return; // We'll get another request later, whatevs! |
| 172 const base::PlatformFile handle = s_cached_platform_file_; |
| 173 s_file_lock_.Release(); |
| 174 |
| 175 if (handle == 0) { |
| 176 // We don't have the data file yet. Queue an asynchronous caching attempt. |
| 177 // The caching attempt happens in the blocking pool because it may involve |
| 178 // arbitrary filesystem access. |
| 179 content::BrowserThread::PostBlockingPoolTask( |
| 180 FROM_HERE, |
| 181 base::Bind(&TranslateTabHelper::HandleCLDDataRequest, |
| 182 weak_pointer_factory_.GetWeakPtr())); |
| 183 } else { |
| 184 // We do have the data available. Respond to the request. |
| 185 SendCLDDataAvailable(handle); |
| 186 } |
| 187 } |
| 188 |
| 189 void TranslateTabHelper::SendCLDDataAvailable(const base::PlatformFile handle) { |
| 190 // WARNING: This method can be invoked from either the IO thread or the |
| 191 // blocking pool. Do not use the synchronous invocation style. |
| 192 |
| 193 // We have the data available, respond to the request. |
| 194 IPC::PlatformFileForTransit ipc_platform_file = |
| 195 IPC::GetFileHandleForProcess( |
| 196 handle, |
| 197 GetWebContents()->GetRenderViewHost()->GetProcess()->GetHandle(), |
| 198 false); |
| 199 Send(new ChromeViewMsg_CLDDataAvailable( |
| 200 GetWebContents()->GetRenderViewHost()->GetRoutingID(), |
| 201 ipc_platform_file)); |
| 202 } |
| 203 |
| 204 void TranslateTabHelper::HandleCLDDataRequest() { |
| 205 // Because this function involves arbitrary file system access, it must run |
| 206 // on the blocking pool. |
| 207 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 208 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 209 |
| 210 base::AutoLock lock(s_file_lock_); |
| 211 if (s_cached_platform_file_ != 0) |
| 212 return; // already done, duplicate request |
| 213 |
| 214 base::FilePath path; |
| 215 if (!PathService::Get(chrome::DIR_USER_DATA, &path)) { |
| 216 LOG(WARNING) << "Unable to locate user data directory"; |
| 217 return; // Chrome isn't properly installed. |
| 218 } |
| 219 |
| 220 // If the file exists, we can send an IPC-safe construct back to the |
| 221 // renderer process immediately. |
| 222 path = path.Append(chrome::kCLDDataFilename); |
| 223 if (!base::PathExists(path)) |
| 224 return; |
| 225 |
| 226 // Attempt to open the file for reading. It exists, so we should succeed. |
| 227 bool created = false; |
| 228 base::PlatformFileError error; |
| 229 s_cached_platform_file_ = base::CreatePlatformFile( |
| 230 path, |
| 231 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, |
| 232 &created, &error); |
| 233 DCHECK(!created); |
| 234 if (error != base::PLATFORM_FILE_OK) { |
| 235 s_cached_platform_file_ = 0; |
| 236 LOG(WARNING) << "CLD data file exists but cannot be opened"; |
| 237 return; |
| 238 } |
| 239 |
| 240 // If we get this far, we've just cached the file. Respond immediately. |
| 241 lock.~AutoLock(); // Release the lock now rather than after responding |
| 242 SendCLDDataAvailable(s_cached_platform_file_); |
| 243 } |
| 244 #endif // defined(CLD2_DYNAMIC_MODE) |
| 245 |
142 void TranslateTabHelper::OnLanguageDetermined( | 246 void TranslateTabHelper::OnLanguageDetermined( |
143 const LanguageDetectionDetails& details, | 247 const LanguageDetectionDetails& details, |
144 bool page_needs_translation) { | 248 bool page_needs_translation) { |
145 translate_driver_.GetLanguageState().LanguageDetermined( | 249 translate_driver_.GetLanguageState().LanguageDetermined( |
146 details.adopted_language, page_needs_translation); | 250 details.adopted_language, page_needs_translation); |
147 | 251 |
148 content::NotificationService::current()->Notify( | 252 content::NotificationService::current()->Notify( |
149 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, | 253 chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, |
150 content::Source<content::WebContents>(web_contents()), | 254 content::Source<content::WebContents>(web_contents()), |
151 content::Details<const LanguageDetectionDetails>(&details)); | 255 content::Details<const LanguageDetectionDetails>(&details)); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 if (GetLanguageState().InTranslateNavigation()) | 304 if (GetLanguageState().InTranslateNavigation()) |
201 return; | 305 return; |
202 } | 306 } |
203 | 307 |
204 TranslateBubbleFactory::Show( | 308 TranslateBubbleFactory::Show( |
205 browser->window(), web_contents(), step, error_type); | 309 browser->window(), web_contents(), step, error_type); |
206 #else | 310 #else |
207 NOTREACHED(); | 311 NOTREACHED(); |
208 #endif | 312 #endif |
209 } | 313 } |
OLD | NEW |