Chromium Code Reviews| 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; | |
|
Dan Beam
2013/05/17 00:19:57
opt nit: NaclDomHandler
| |
| 71 | |
| 72 // This class performs a check that the PNaCl path which was returned by | |
| 73 // PathService is valid. One class instance is created per NaClDOMHandler | |
| 74 // and it is destroyed after the check is completed. | |
| 75 class NaClDOMHandlerProxy : public | |
| 76 base::RefCountedThreadSafe<NaClDOMHandlerProxy> { | |
|
Dan Beam
2013/05/17 00:19:57
class NaClDOMHandlerProxy
: public base::RefCo
| |
| 77 public: | |
| 78 explicit NaClDOMHandlerProxy(NaClDOMHandler* handler); | |
| 79 | |
| 80 // A helper to check if PNaCl path exists. | |
| 81 void ValidatePnaclPath(); | |
| 82 | |
| 83 void set_handler(NaClDOMHandler* handler) { | |
|
Dan Beam
2013/05/17 00:19:57
void set_handler(NaClDOMHandler* handler) { handle
| |
| 84 handler_ = handler; | |
| 85 } | |
| 86 | |
| 87 private: | |
| 88 // A helper callback that receives the result of checking if PNaCl path | |
| 89 // exists. | |
| 90 void ValidatePnaclPathCallback(bool is_valid); | |
| 91 | |
| 92 virtual ~NaClDOMHandlerProxy() {} | |
|
Dan Beam
2013/05/17 00:19:57
put dtor second
| |
| 93 friend class base::RefCountedThreadSafe<NaClDOMHandlerProxy>; | |
|
Dan Beam
2013/05/17 00:19:57
put friend first
| |
| 94 | |
| 95 // The handler that requested checking PNaCl file path. | |
| 96 NaClDOMHandler* handler_; | |
|
Dan Beam
2013/05/17 00:19:57
NaclDomHandler* handler_; // weak.
(assuming thi
| |
| 97 | |
| 98 DISALLOW_COPY_AND_ASSIGN(NaClDOMHandlerProxy); | |
| 99 }; | |
| 100 | |
| 69 // The handler for JavaScript messages for the about:flags page. | 101 // The handler for JavaScript messages for the about:flags page. |
| 70 class NaClDOMHandler : public WebUIMessageHandler { | 102 class NaClDOMHandler : public WebUIMessageHandler { |
| 71 public: | 103 public: |
| 72 NaClDOMHandler(); | 104 NaClDOMHandler(); |
| 73 virtual ~NaClDOMHandler(); | 105 virtual ~NaClDOMHandler(); |
| 74 | 106 |
| 75 // WebUIMessageHandler implementation. | 107 // WebUIMessageHandler implementation. |
| 76 virtual void RegisterMessages() OVERRIDE; | 108 virtual void RegisterMessages() OVERRIDE; |
| 77 | 109 |
| 78 // Callback for the "requestNaClInfo" message. | 110 // Callback for the "requestNaClInfo" message. |
| 79 void HandleRequestNaClInfo(const ListValue* args); | 111 void HandleRequestNaClInfo(const ListValue* args); |
| 80 | 112 |
| 81 // Callback for the NaCl plugin information. | 113 // Callback for the NaCl plugin information. |
| 82 void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins); | 114 void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins); |
| 83 | 115 |
| 116 // A helper callback that receives the result of checking if PNaCl path | |
| 117 // exists. is_valid is true if the PNaCl path that was returned by | |
|
Dan Beam
2013/05/17 00:19:57
nit: |is_valid|
| |
| 118 // PathService is valid, and false otherwise. | |
| 119 void DidValidatePnaclPath(bool is_valid); | |
| 120 | |
| 84 private: | 121 private: |
| 85 // Called when enough information is gathered to return data back to the page. | 122 // Called when enough information is gathered to return data back to the page. |
| 86 void MaybeRespondToPage(); | 123 void MaybeRespondToPage(); |
| 87 | 124 |
| 88 // Helper for MaybeRespondToPage -- called after enough information | 125 // Helper for MaybeRespondToPage -- called after enough information |
| 89 // is gathered. | 126 // is gathered. |
| 90 void PopulatePageInformation(DictionaryValue* naclInfo); | 127 void PopulatePageInformation(DictionaryValue* naclInfo); |
| 91 | 128 |
| 92 // Factory for the creating refs in callbacks. | 129 // Factory for the creating refs in callbacks. |
| 93 base::WeakPtrFactory<NaClDOMHandler> weak_ptr_factory_; | 130 base::WeakPtrFactory<NaClDOMHandler> weak_ptr_factory_; |
| 94 | 131 |
| 95 // Whether the page has requested data. | 132 // Whether the page has requested data. |
| 96 bool page_has_requested_data_; | 133 bool page_has_requested_data_; |
| 97 | 134 |
| 98 // Whether the plugin information is ready. | 135 // Whether the plugin information is ready. |
| 99 bool has_plugin_info_; | 136 bool has_plugin_info_; |
| 100 | 137 |
| 138 // Whether PNaCl path was validated. PathService can return a path | |
| 139 // that does not exists, so it needs to be validated. | |
| 140 bool pnacl_path_validated_; | |
| 141 bool pnacl_path_exists_; | |
| 142 | |
| 143 // A proxy for handling cross threads messages. | |
| 144 scoped_refptr<NaClDOMHandlerProxy> proxy_; | |
| 145 | |
| 101 DISALLOW_COPY_AND_ASSIGN(NaClDOMHandler); | 146 DISALLOW_COPY_AND_ASSIGN(NaClDOMHandler); |
| 102 }; | 147 }; |
| 103 | 148 |
| 149 NaClDOMHandlerProxy::NaClDOMHandlerProxy(NaClDOMHandler* handler) | |
| 150 : handler_(handler) { | |
| 151 } | |
| 152 | |
| 153 void NaClDOMHandlerProxy::ValidatePnaclPath() { | |
| 154 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { | |
| 155 BrowserThread::PostTask( | |
| 156 BrowserThread::FILE, FROM_HERE, | |
| 157 base::Bind(&NaClDOMHandlerProxy::ValidatePnaclPath, this)); | |
| 158 return; | |
| 159 } | |
| 160 | |
| 161 bool is_valid = true; | |
| 162 base::FilePath pnacl_path; | |
| 163 bool got_path = PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_path); | |
| 164 // The PathService may return an empty string if PNaCl is not yet installed. | |
| 165 // However, do not trust that the path returned by the PathService exists. | |
| 166 // Check for existence here. | |
| 167 if (!got_path || pnacl_path.empty() || !file_util::PathExists(pnacl_path)) { | |
|
Dan Beam
2013/05/17 00:19:57
nit: no curlies
| |
| 168 is_valid = false; | |
| 169 } | |
| 170 ValidatePnaclPathCallback(is_valid); | |
|
Dan Beam
2013/05/17 00:19:57
nit:
ValidatePnaclPathCallback(
got_path && !
| |
| 171 } | |
| 172 | |
| 173 void NaClDOMHandlerProxy::ValidatePnaclPathCallback(bool is_valid) { | |
| 174 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
| 175 BrowserThread::PostTask( | |
| 176 BrowserThread::UI, FROM_HERE, | |
| 177 base::Bind(&NaClDOMHandlerProxy::ValidatePnaclPathCallback, | |
| 178 this, is_valid)); | |
| 179 return; | |
| 180 } | |
| 181 | |
| 182 // Check that handler_ is still valid, it could be set to NULL if navigation | |
| 183 // happened while checking that the PNaCl file exists. | |
| 184 if (handler_) | |
| 185 handler_->DidValidatePnaclPath(is_valid); | |
| 186 } | |
| 187 | |
| 104 NaClDOMHandler::NaClDOMHandler() | 188 NaClDOMHandler::NaClDOMHandler() |
| 105 : weak_ptr_factory_(this), | 189 : weak_ptr_factory_(this), |
| 106 page_has_requested_data_(false), | 190 page_has_requested_data_(false), |
| 107 has_plugin_info_(false) { | 191 has_plugin_info_(false), |
| 192 pnacl_path_validated_(false), | |
| 193 pnacl_path_exists_(false), | |
| 194 proxy_(new NaClDOMHandlerProxy(this)) { | |
|
Dan Beam
2013/05/17 00:19:57
ALLOW_THIS_IN_INITIALIZER_LIST()
| |
| 108 PluginService::GetInstance()->GetPlugins(base::Bind( | 195 PluginService::GetInstance()->GetPlugins(base::Bind( |
| 109 &NaClDOMHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr())); | 196 &NaClDOMHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr())); |
| 110 } | 197 } |
| 111 | 198 |
| 112 NaClDOMHandler::~NaClDOMHandler() { | 199 NaClDOMHandler::~NaClDOMHandler() { |
| 200 if (proxy_) | |
| 201 proxy_->set_handler(NULL); | |
| 113 } | 202 } |
| 114 | 203 |
| 115 void NaClDOMHandler::RegisterMessages() { | 204 void NaClDOMHandler::RegisterMessages() { |
| 116 web_ui()->RegisterMessageCallback( | 205 web_ui()->RegisterMessageCallback( |
| 117 "requestNaClInfo", | 206 "requestNaClInfo", |
| 118 base::Bind(&NaClDOMHandler::HandleRequestNaClInfo, | 207 base::Bind(&NaClDOMHandler::HandleRequestNaClInfo, |
| 119 base::Unretained(this))); | 208 base::Unretained(this))); |
| 120 } | 209 } |
| 121 | 210 |
| 122 // Helper functions for collecting a list of key-value pairs that will | 211 // Helper functions for collecting a list of key-value pairs that will |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 147 MaybeRespondToPage(); | 236 MaybeRespondToPage(); |
| 148 } | 237 } |
| 149 | 238 |
| 150 void NaClDOMHandler::OnGotPlugins( | 239 void NaClDOMHandler::OnGotPlugins( |
| 151 const std::vector<webkit::WebPluginInfo>& plugins) { | 240 const std::vector<webkit::WebPluginInfo>& plugins) { |
| 152 has_plugin_info_ = true; | 241 has_plugin_info_ = true; |
| 153 MaybeRespondToPage(); | 242 MaybeRespondToPage(); |
| 154 } | 243 } |
| 155 | 244 |
| 156 void NaClDOMHandler::PopulatePageInformation(DictionaryValue* naclInfo) { | 245 void NaClDOMHandler::PopulatePageInformation(DictionaryValue* naclInfo) { |
| 246 DCHECK(pnacl_path_validated_); | |
| 157 // Store Key-Value pairs of about-information. | 247 // Store Key-Value pairs of about-information. |
| 158 scoped_ptr<ListValue> list(new ListValue()); | 248 scoped_ptr<ListValue> list(new ListValue()); |
| 159 | 249 |
| 160 // Obtain the Chrome version info. | 250 // Obtain the Chrome version info. |
| 161 chrome::VersionInfo version_info; | 251 chrome::VersionInfo version_info; |
| 162 AddPair(list.get(), | 252 AddPair(list.get(), |
| 163 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | 253 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| 164 ASCIIToUTF16(version_info.Version() + " (" + | 254 ASCIIToUTF16(version_info.Version() + " (" + |
| 165 chrome::VersionInfo::GetVersionStringModifier() + ")")); | 255 chrome::VersionInfo::GetVersionStringModifier() + ")")); |
| 166 | 256 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 } | 316 } |
| 227 | 317 |
| 228 // Check that commandline flags are enabled. | 318 // Check that commandline flags are enabled. |
| 229 ListFlagStatus(list.get(), "Flag '--enable-nacl'", switches::kEnableNaCl); | 319 ListFlagStatus(list.get(), "Flag '--enable-nacl'", switches::kEnableNaCl); |
| 230 | 320 |
| 231 AddLineBreak(list.get()); | 321 AddLineBreak(list.get()); |
| 232 | 322 |
| 233 // Obtain the version of the PNaCl translator. | 323 // Obtain the version of the PNaCl translator. |
| 234 base::FilePath pnacl_path; | 324 base::FilePath pnacl_path; |
| 235 bool got_path = PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_path); | 325 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. | 326 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(), | 327 AddPair(list.get(), |
| 241 ASCIIToUTF16("PNaCl translator"), | 328 ASCIIToUTF16("PNaCl translator"), |
| 242 ASCIIToUTF16("Not installed")); | 329 ASCIIToUTF16("Not installed")); |
| 243 } else { | 330 } else { |
| 244 AddPair(list.get(), | 331 AddPair(list.get(), |
| 245 ASCIIToUTF16("PNaCl translator path"), | 332 ASCIIToUTF16("PNaCl translator path"), |
| 246 pnacl_path.LossyDisplayName()); | 333 pnacl_path.LossyDisplayName()); |
| 247 AddPair(list.get(), | 334 AddPair(list.get(), |
| 248 ASCIIToUTF16("PNaCl translator version"), | 335 ASCIIToUTF16("PNaCl translator version"), |
| 249 pnacl_path.BaseName().LossyDisplayName()); | 336 pnacl_path.BaseName().LossyDisplayName()); |
| 250 } | 337 } |
| 251 | 338 |
| 252 ListFlagStatus(list.get(), "Flag '--enable-pnacl'", switches::kEnablePnacl); | 339 ListFlagStatus(list.get(), "Flag '--enable-pnacl'", switches::kEnablePnacl); |
| 253 // naclInfo will take ownership of list, and clean it up on destruction. | 340 // naclInfo will take ownership of list, and clean it up on destruction. |
| 254 naclInfo->Set("naclInfo", list.release()); | 341 naclInfo->Set("naclInfo", list.release()); |
| 255 } | 342 } |
| 256 | 343 |
| 344 void NaClDOMHandler::DidValidatePnaclPath(bool is_valid) { | |
| 345 pnacl_path_validated_ = true; | |
| 346 pnacl_path_exists_ = is_valid; | |
| 347 MaybeRespondToPage(); | |
| 348 } | |
| 349 | |
| 257 void NaClDOMHandler::MaybeRespondToPage() { | 350 void NaClDOMHandler::MaybeRespondToPage() { |
| 258 // Don't reply until everything is ready. The page will show a 'loading' | 351 // Don't reply until everything is ready. The page will show a 'loading' |
| 259 // message until then. | 352 // message until then. |
| 260 if (!page_has_requested_data_ || !has_plugin_info_) | 353 if (!page_has_requested_data_ || !has_plugin_info_) |
| 261 return; | 354 return; |
| 262 | 355 |
| 356 if (!pnacl_path_validated_) { | |
| 357 DCHECK(proxy_); | |
| 358 proxy_->ValidatePnaclPath(); | |
| 359 return; | |
| 360 } | |
| 361 | |
| 263 DictionaryValue naclInfo; | 362 DictionaryValue naclInfo; |
| 264 PopulatePageInformation(&naclInfo); | 363 PopulatePageInformation(&naclInfo); |
| 265 web_ui()->CallJavascriptFunction("nacl.returnNaClInfo", naclInfo); | 364 web_ui()->CallJavascriptFunction("nacl.returnNaClInfo", naclInfo); |
| 266 } | 365 } |
| 267 | 366 |
| 268 } // namespace | 367 } // namespace |
| 269 | 368 |
| 270 /////////////////////////////////////////////////////////////////////////////// | 369 /////////////////////////////////////////////////////////////////////////////// |
| 271 // | 370 // |
| 272 // NaClUI | 371 // NaClUI |
| 273 // | 372 // |
| 274 /////////////////////////////////////////////////////////////////////////////// | 373 /////////////////////////////////////////////////////////////////////////////// |
| 275 | 374 |
| 276 NaClUI::NaClUI(content::WebUI* web_ui) : WebUIController(web_ui) { | 375 NaClUI::NaClUI(content::WebUI* web_ui) : WebUIController(web_ui) { |
| 277 content::RecordAction(UserMetricsAction("ViewAboutNaCl")); | 376 content::RecordAction(UserMetricsAction("ViewAboutNaCl")); |
| 278 | 377 |
| 279 web_ui->AddMessageHandler(new NaClDOMHandler()); | 378 web_ui->AddMessageHandler(new NaClDOMHandler()); |
| 280 | 379 |
| 281 // Set up the about:nacl source. | 380 // Set up the about:nacl source. |
| 282 Profile* profile = Profile::FromWebUI(web_ui); | 381 Profile* profile = Profile::FromWebUI(web_ui); |
| 283 content::WebUIDataSource::Add(profile, CreateNaClUIHTMLSource()); | 382 content::WebUIDataSource::Add(profile, CreateNaClUIHTMLSource()); |
| 284 } | 383 } |
| OLD | NEW |