OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/webui/nacl_ui.h" | 5 #include "chrome/browser/ui/webui/nacl_ui.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 22 matching lines...) Expand all Loading... | |
33 #include "grit/generated_resources.h" | 33 #include "grit/generated_resources.h" |
34 #include "grit/theme_resources.h" | 34 #include "grit/theme_resources.h" |
35 #include "ui/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
36 #include "ui/base/resource/resource_bundle.h" | 36 #include "ui/base/resource/resource_bundle.h" |
37 #include "webkit/plugins/webplugininfo.h" | 37 #include "webkit/plugins/webplugininfo.h" |
38 | 38 |
39 #if defined(OS_WIN) | 39 #if defined(OS_WIN) |
40 #include "base/win/windows_version.h" | 40 #include "base/win/windows_version.h" |
41 #endif | 41 #endif |
42 | 42 |
43 using content::BrowserThread; | |
43 using content::PluginService; | 44 using content::PluginService; |
44 using content::UserMetricsAction; | 45 using content::UserMetricsAction; |
45 using content::WebUIMessageHandler; | 46 using content::WebUIMessageHandler; |
46 | 47 |
47 namespace { | 48 namespace { |
48 | 49 |
49 content::WebUIDataSource* CreateNaClUIHTMLSource() { | 50 content::WebUIDataSource* CreateNaClUIHTMLSource() { |
50 content::WebUIDataSource* source = | 51 content::WebUIDataSource* source = |
51 content::WebUIDataSource::Create(chrome::kChromeUINaClHost); | 52 content::WebUIDataSource::Create(chrome::kChromeUINaClHost); |
52 | 53 |
53 source->SetUseJsonJSFormatV2(); | 54 source->SetUseJsonJSFormatV2(); |
54 source->AddLocalizedString("loadingMessage", IDS_NACL_LOADING_MESSAGE); | 55 source->AddLocalizedString("loadingMessage", IDS_NACL_LOADING_MESSAGE); |
55 source->AddLocalizedString("naclLongTitle", IDS_NACL_TITLE_MESSAGE); | 56 source->AddLocalizedString("naclLongTitle", IDS_NACL_TITLE_MESSAGE); |
56 source->SetJsonPath("strings.js"); | 57 source->SetJsonPath("strings.js"); |
57 source->AddResourcePath("about_nacl.css", IDR_ABOUT_NACL_CSS); | 58 source->AddResourcePath("about_nacl.css", IDR_ABOUT_NACL_CSS); |
58 source->AddResourcePath("about_nacl.js", IDR_ABOUT_NACL_JS); | 59 source->AddResourcePath("about_nacl.js", IDR_ABOUT_NACL_JS); |
59 source->SetDefaultResource(IDR_ABOUT_NACL_HTML); | 60 source->SetDefaultResource(IDR_ABOUT_NACL_HTML); |
60 return source; | 61 return source; |
61 } | 62 } |
62 | 63 |
63 //////////////////////////////////////////////////////////////////////////////// | 64 //////////////////////////////////////////////////////////////////////////////// |
64 // | 65 // |
65 // NaClDOMHandler | 66 // NaClDOMHandler |
66 // | 67 // |
67 //////////////////////////////////////////////////////////////////////////////// | 68 //////////////////////////////////////////////////////////////////////////////// |
68 | 69 |
70 class NaClDOMHandler; | |
71 | |
72 class NaClDOMHandlerProxy : public | |
73 base::RefCountedThreadSafe<NaClDOMHandlerProxy> { | |
74 public: | |
75 explicit NaClDOMHandlerProxy(NaClDOMHandler* handler); | |
76 // A helper to check if pnacl path exists. | |
77 // The check is done on the FILE thread. | |
78 void validatePnaclPath(); | |
jvoung (off chromium)
2013/05/15 20:28:28
style: Method names start with capital letter?
| |
79 | |
80 void setHandler(NaClDOMHandler* handler); | |
81 | |
82 private: | |
83 // A helper callback that receives the result of checking if pnacl path | |
jvoung (off chromium)
2013/05/15 20:28:28
In the comments, could you make it "PNaCl" instead
| |
84 // exists. It switches back to the UI thread and saves the result. | |
85 void validatePnaclPathCallback(bool is_valid); | |
86 | |
87 NaClDOMHandler* handler_; | |
88 | |
89 DISALLOW_COPY_AND_ASSIGN(NaClDOMHandlerProxy); | |
90 }; | |
91 | |
69 // The handler for JavaScript messages for the about:flags page. | 92 // The handler for JavaScript messages for the about:flags page. |
70 class NaClDOMHandler : public WebUIMessageHandler { | 93 class NaClDOMHandler : public WebUIMessageHandler { |
71 public: | 94 public: |
72 NaClDOMHandler(); | 95 NaClDOMHandler(); |
73 virtual ~NaClDOMHandler(); | 96 virtual ~NaClDOMHandler(); |
74 | 97 |
75 // WebUIMessageHandler implementation. | 98 // WebUIMessageHandler implementation. |
76 virtual void RegisterMessages() OVERRIDE; | 99 virtual void RegisterMessages() OVERRIDE; |
77 | 100 |
78 // Callback for the "requestNaClInfo" message. | 101 // Callback for the "requestNaClInfo" message. |
79 void HandleRequestNaClInfo(const ListValue* args); | 102 void HandleRequestNaClInfo(const ListValue* args); |
80 | 103 |
81 // Callback for the NaCl plugin information. | 104 // Callback for the NaCl plugin information. |
82 void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins); | 105 void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins); |
83 | 106 |
107 // A helper callback that receives the result of checking if pnacl path | |
108 // exists. It switches back to the UI thread and saves the result. | |
109 void validatePnaclPathCallback(bool is_valid); | |
jvoung (off chromium)
2013/05/15 20:28:28
style: Method names start with capital letter
| |
110 | |
84 private: | 111 private: |
85 // Called when enough information is gathered to return data back to the page. | 112 // Called when enough information is gathered to return data back to the page. |
86 void MaybeRespondToPage(); | 113 void MaybeRespondToPage(); |
87 | 114 |
88 // Helper for MaybeRespondToPage -- called after enough information | 115 // Helper for MaybeRespondToPage -- called after enough information |
89 // is gathered. | 116 // is gathered. |
90 void PopulatePageInformation(DictionaryValue* naclInfo); | 117 void PopulatePageInformation(DictionaryValue* naclInfo); |
91 | 118 |
92 // Factory for the creating refs in callbacks. | 119 // Factory for the creating refs in callbacks. |
93 base::WeakPtrFactory<NaClDOMHandler> weak_ptr_factory_; | 120 base::WeakPtrFactory<NaClDOMHandler> weak_ptr_factory_; |
94 | 121 |
95 // Whether the page has requested data. | 122 // Whether the page has requested data. |
96 bool page_has_requested_data_; | 123 bool page_has_requested_data_; |
97 | 124 |
98 // Whether the plugin information is ready. | 125 // Whether the plugin information is ready. |
99 bool has_plugin_info_; | 126 bool has_plugin_info_; |
100 | 127 |
128 // Whether pnacl path was validated. PathService can return a path | |
129 // that does not exists, so it needs to be validated. | |
130 bool pnacl_path_validated_; | |
131 bool pnacl_path_exists_; | |
132 | |
133 // A proxy for handling cross threads messages. | |
134 scoped_refptr<NaClDOMHandlerProxy> proxy_; | |
135 | |
101 DISALLOW_COPY_AND_ASSIGN(NaClDOMHandler); | 136 DISALLOW_COPY_AND_ASSIGN(NaClDOMHandler); |
102 }; | 137 }; |
103 | 138 |
139 NaClDOMHandlerProxy::NaClDOMHandlerProxy(NaClDOMHandler* handler) | |
140 : handler_(handler) { | |
141 } | |
142 | |
143 void NaClDOMHandlerProxy::validatePnaclPath() | |
144 { | |
jvoung (off chromium)
2013/05/15 20:28:28
put curly brace on previous line
| |
145 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { | |
146 BrowserThread::PostTask( | |
147 BrowserThread::FILE, FROM_HERE, | |
148 base::Bind(&NaClDOMHandlerProxy::validatePnaclPath, this)); | |
149 return; | |
150 } | |
151 | |
152 bool is_valid = true; | |
153 base::FilePath pnacl_path; | |
154 bool got_path = PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_path); | |
155 // The PathService may return an empty string if PNaCl is not yet installed. | |
156 // However, do not trust that the path returned by the PathService exists. | |
157 // Check for existence here. | |
158 if (!got_path || pnacl_path.empty() || !file_util::PathExists(pnacl_path)) { | |
159 is_valid = false; | |
160 } | |
161 handler_->validatePnaclPathCallback(is_valid); | |
162 } | |
163 | |
164 void NaClDOMHandlerProxy::validatePnaclPathCallback(bool is_valid) | |
165 { | |
jvoung (off chromium)
2013/05/15 20:28:28
same (curly)
| |
166 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
167 BrowserThread::PostTask( | |
168 BrowserThread::UI, FROM_HERE, | |
169 base::Bind(&NaClDOMHandlerProxy::validatePnaclPathCallback, | |
170 this, is_valid)); | |
171 return; | |
172 } | |
173 | |
174 handler_->validatePnaclPathCallback(is_valid); | |
175 } | |
176 | |
177 void NaClDOMHandlerProxy::setHandler(NaClDOMHandler* handler) { | |
178 handler_ = handler; | |
179 } | |
180 | |
104 NaClDOMHandler::NaClDOMHandler() | 181 NaClDOMHandler::NaClDOMHandler() |
105 : weak_ptr_factory_(this), | 182 : weak_ptr_factory_(this), |
106 page_has_requested_data_(false), | 183 page_has_requested_data_(false), |
107 has_plugin_info_(false) { | 184 has_plugin_info_(false), |
185 pnacl_path_validated_(false), | |
186 pnacl_path_exists_(false), | |
187 proxy_(new NaClDOMHandlerProxy(this)) { | |
108 PluginService::GetInstance()->GetPlugins(base::Bind( | 188 PluginService::GetInstance()->GetPlugins(base::Bind( |
109 &NaClDOMHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr())); | 189 &NaClDOMHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr())); |
110 } | 190 } |
111 | 191 |
112 NaClDOMHandler::~NaClDOMHandler() { | 192 NaClDOMHandler::~NaClDOMHandler() { |
193 if (proxy_) { | |
jvoung (off chromium)
2013/05/15 20:28:28
indentation 2 spaces instead of 4
| |
194 proxy_->setHandler(NULL); | |
195 } | |
113 } | 196 } |
114 | 197 |
115 void NaClDOMHandler::RegisterMessages() { | 198 void NaClDOMHandler::RegisterMessages() { |
116 web_ui()->RegisterMessageCallback( | 199 web_ui()->RegisterMessageCallback( |
117 "requestNaClInfo", | 200 "requestNaClInfo", |
118 base::Bind(&NaClDOMHandler::HandleRequestNaClInfo, | 201 base::Bind(&NaClDOMHandler::HandleRequestNaClInfo, |
119 base::Unretained(this))); | 202 base::Unretained(this))); |
120 } | 203 } |
121 | 204 |
122 // Helper functions for collecting a list of key-value pairs that will | 205 // Helper functions for collecting a list of key-value pairs that will |
(...skipping 24 matching lines...) Expand all Loading... | |
147 MaybeRespondToPage(); | 230 MaybeRespondToPage(); |
148 } | 231 } |
149 | 232 |
150 void NaClDOMHandler::OnGotPlugins( | 233 void NaClDOMHandler::OnGotPlugins( |
151 const std::vector<webkit::WebPluginInfo>& plugins) { | 234 const std::vector<webkit::WebPluginInfo>& plugins) { |
152 has_plugin_info_ = true; | 235 has_plugin_info_ = true; |
153 MaybeRespondToPage(); | 236 MaybeRespondToPage(); |
154 } | 237 } |
155 | 238 |
156 void NaClDOMHandler::PopulatePageInformation(DictionaryValue* naclInfo) { | 239 void NaClDOMHandler::PopulatePageInformation(DictionaryValue* naclInfo) { |
240 DCHECK(pnacl_path_validated_); | |
157 // Store Key-Value pairs of about-information. | 241 // Store Key-Value pairs of about-information. |
158 scoped_ptr<ListValue> list(new ListValue()); | 242 scoped_ptr<ListValue> list(new ListValue()); |
159 | 243 |
160 // Obtain the Chrome version info. | 244 // Obtain the Chrome version info. |
161 chrome::VersionInfo version_info; | 245 chrome::VersionInfo version_info; |
162 AddPair(list.get(), | 246 AddPair(list.get(), |
163 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | 247 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
164 ASCIIToUTF16(version_info.Version() + " (" + | 248 ASCIIToUTF16(version_info.Version() + " (" + |
165 chrome::VersionInfo::GetVersionStringModifier() + ")")); | 249 chrome::VersionInfo::GetVersionStringModifier() + ")")); |
166 | 250 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 } | 310 } |
227 | 311 |
228 // Check that commandline flags are enabled. | 312 // Check that commandline flags are enabled. |
229 ListFlagStatus(list.get(), "Flag '--enable-nacl'", switches::kEnableNaCl); | 313 ListFlagStatus(list.get(), "Flag '--enable-nacl'", switches::kEnableNaCl); |
230 | 314 |
231 AddLineBreak(list.get()); | 315 AddLineBreak(list.get()); |
232 | 316 |
233 // Obtain the version of the PNaCl translator. | 317 // Obtain the version of the PNaCl translator. |
234 base::FilePath pnacl_path; | 318 base::FilePath pnacl_path; |
235 bool got_path = PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_path); | 319 bool got_path = PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_path); |
236 // The PathService may return an empty string if PNaCl is not yet installed. | 320 if (!got_path || pnacl_path.empty() || !pnacl_path_exists_) { |
237 // However, do not trust that the path returned by the PathService exists. | |
238 // Check for existence here. | |
239 if (!got_path || pnacl_path.empty() || !file_util::PathExists(pnacl_path)) { | |
240 AddPair(list.get(), | 321 AddPair(list.get(), |
241 ASCIIToUTF16("PNaCl translator"), | 322 ASCIIToUTF16("PNaCl translator"), |
242 ASCIIToUTF16("Not installed")); | 323 ASCIIToUTF16("Not installed")); |
243 } else { | 324 } else { |
244 AddPair(list.get(), | 325 AddPair(list.get(), |
245 ASCIIToUTF16("PNaCl translator path"), | 326 ASCIIToUTF16("PNaCl translator path"), |
246 pnacl_path.LossyDisplayName()); | 327 pnacl_path.LossyDisplayName()); |
247 AddPair(list.get(), | 328 AddPair(list.get(), |
248 ASCIIToUTF16("PNaCl translator version"), | 329 ASCIIToUTF16("PNaCl translator version"), |
249 pnacl_path.BaseName().LossyDisplayName()); | 330 pnacl_path.BaseName().LossyDisplayName()); |
250 } | 331 } |
251 | 332 |
252 ListFlagStatus(list.get(), "Flag '--enable-pnacl'", switches::kEnablePnacl); | 333 ListFlagStatus(list.get(), "Flag '--enable-pnacl'", switches::kEnablePnacl); |
253 // naclInfo will take ownership of list, and clean it up on destruction. | 334 // naclInfo will take ownership of list, and clean it up on destruction. |
254 naclInfo->Set("naclInfo", list.release()); | 335 naclInfo->Set("naclInfo", list.release()); |
255 } | 336 } |
256 | 337 |
338 void NaClDOMHandler::validatePnaclPathCallback(bool is_valid) | |
339 { | |
jvoung (off chromium)
2013/05/15 20:28:28
style: put curly on the previous line
| |
340 pnacl_path_validated_ = true; | |
341 pnacl_path_exists_ = is_valid; | |
342 MaybeRespondToPage(); | |
343 } | |
344 | |
257 void NaClDOMHandler::MaybeRespondToPage() { | 345 void NaClDOMHandler::MaybeRespondToPage() { |
258 // Don't reply until everything is ready. The page will show a 'loading' | 346 // Don't reply until everything is ready. The page will show a 'loading' |
259 // message until then. | 347 // message until then. |
260 if (!page_has_requested_data_ || !has_plugin_info_) | 348 if (!page_has_requested_data_ || !has_plugin_info_) |
261 return; | 349 return; |
262 | 350 |
351 if (!pnacl_path_validated_) { | |
352 DCHECK(proxy_); | |
jvoung (off chromium)
2013/05/15 20:28:28
make DCHECK indentation consistent with the rest o
| |
353 proxy_->validatePnaclPath(); | |
354 return; | |
355 } | |
356 | |
263 DictionaryValue naclInfo; | 357 DictionaryValue naclInfo; |
264 PopulatePageInformation(&naclInfo); | 358 PopulatePageInformation(&naclInfo); |
265 web_ui()->CallJavascriptFunction("nacl.returnNaClInfo", naclInfo); | 359 web_ui()->CallJavascriptFunction("nacl.returnNaClInfo", naclInfo); |
266 } | 360 } |
267 | 361 |
268 } // namespace | 362 } // namespace |
269 | 363 |
270 /////////////////////////////////////////////////////////////////////////////// | 364 /////////////////////////////////////////////////////////////////////////////// |
271 // | 365 // |
272 // NaClUI | 366 // NaClUI |
273 // | 367 // |
274 /////////////////////////////////////////////////////////////////////////////// | 368 /////////////////////////////////////////////////////////////////////////////// |
275 | 369 |
276 NaClUI::NaClUI(content::WebUI* web_ui) : WebUIController(web_ui) { | 370 NaClUI::NaClUI(content::WebUI* web_ui) : WebUIController(web_ui) { |
277 content::RecordAction(UserMetricsAction("ViewAboutNaCl")); | 371 content::RecordAction(UserMetricsAction("ViewAboutNaCl")); |
278 | 372 |
279 web_ui->AddMessageHandler(new NaClDOMHandler()); | 373 web_ui->AddMessageHandler(new NaClDOMHandler()); |
280 | 374 |
281 // Set up the about:nacl source. | 375 // Set up the about:nacl source. |
282 Profile* profile = Profile::FromWebUI(web_ui); | 376 Profile* profile = Profile::FromWebUI(web_ui); |
283 content::WebUIDataSource::Add(profile, CreateNaClUIHTMLSource()); | 377 content::WebUIDataSource::Add(profile, CreateNaClUIHTMLSource()); |
284 } | 378 } |
OLD | NEW |