| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "native_client/src/trusted/plugin/pnacl_coordinator.h" | 5 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "native_client/src/include/portability_io.h" | 10 #include "native_client/src/include/portability_io.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 namespace plugin { | 27 namespace plugin { |
| 28 | 28 |
| 29 class Plugin; | 29 class Plugin; |
| 30 | 30 |
| 31 namespace { | 31 namespace { |
| 32 | 32 |
| 33 const char kLlcUrl[] = "llc"; | 33 const char kLlcUrl[] = "llc"; |
| 34 const char kLdUrl[] = "ld"; | 34 const char kLdUrl[] = "ld"; |
| 35 | 35 |
| 36 nacl::string ResourceBaseUrl() { | 36 nacl::string ExtensionUrl() { |
| 37 return nacl::string("pnacl_support/") + GetSandboxISA() + "/"; | 37 // TODO(sehr,jvoung): Find a better way to express the URL for the pnacl |
| 38 // extension than a constant string here. |
| 39 const nacl::string kPnaclExtensionOrigin = |
| 40 "chrome-extension://gcodniebolpnpaiggndmcmmfpldlknih/"; |
| 41 return kPnaclExtensionOrigin + GetSandboxISA() + "/"; |
| 38 } | 42 } |
| 39 | 43 |
| 40 nacl::string Random32CharHexString(struct NaClDescRng* rng) { | 44 nacl::string Random32CharHexString(struct NaClDescRng* rng) { |
| 41 struct NaClDesc* desc = reinterpret_cast<struct NaClDesc*>(rng); | 45 struct NaClDesc* desc = reinterpret_cast<struct NaClDesc*>(rng); |
| 42 const struct NaClDescVtbl* vtbl = | 46 const struct NaClDescVtbl* vtbl = |
| 43 reinterpret_cast<const struct NaClDescVtbl*>(desc->base.vtbl); | 47 reinterpret_cast<const struct NaClDescVtbl*>(desc->base.vtbl); |
| 44 | 48 |
| 45 nacl::string hex_string; | 49 nacl::string hex_string; |
| 46 const int32_t kTempFileNameWords = 4; | 50 const int32_t kTempFileNameWords = 4; |
| 47 for (int32_t i = 0; i < kTempFileNameWords; ++i) { | 51 for (int32_t i = 0; i < kTempFileNameWords; ++i) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 // Run the client's completion callback. | 169 // Run the client's completion callback. |
| 166 pp::Core* core = pp::Module::Get()->core(); | 170 pp::Core* core = pp::Module::Get()->core(); |
| 167 core->CallOnMainThread(0, done_callback_, PP_OK); | 171 core->CallOnMainThread(0, done_callback_, PP_OK); |
| 168 } | 172 } |
| 169 | 173 |
| 170 ////////////////////////////////////////////////////////////////////// | 174 ////////////////////////////////////////////////////////////////////// |
| 171 // Pnacl-specific manifest support. | 175 // Pnacl-specific manifest support. |
| 172 ////////////////////////////////////////////////////////////////////// | 176 ////////////////////////////////////////////////////////////////////// |
| 173 class PnaclManifest : public Manifest { | 177 class PnaclManifest : public Manifest { |
| 174 public: | 178 public: |
| 175 PnaclManifest(const pp::URLUtil_Dev* url_util, | 179 PnaclManifest(const pp::URLUtil_Dev* url_util) |
| 176 const nacl::string& manifest_base_url) | 180 : Manifest(url_util, ExtensionUrl(), GetSandboxISA(), false) { |
| 177 : Manifest(url_util, manifest_base_url, GetSandboxISA(), false) { | |
| 178 size_t last_slash_pos = manifest_base_url_.rfind("/"); | |
| 179 CHECK(last_slash_pos != nacl::string::npos); | |
| 180 // url_prefix contains everything in manifest_base_url up to and including | |
| 181 // the last slash. | |
| 182 url_prefix_ = | |
| 183 manifest_base_url_.substr(0, last_slash_pos + 1) + ResourceBaseUrl(); | |
| 184 } | 181 } |
| 185 virtual ~PnaclManifest() { } | 182 virtual ~PnaclManifest() { } |
| 186 | 183 |
| 187 virtual bool GetProgramURL(nacl::string* full_url, | 184 virtual bool GetProgramURL(nacl::string* full_url, |
| 188 ErrorInfo* error_info, | 185 ErrorInfo* error_info, |
| 189 bool* is_portable) { | 186 bool* is_portable) { |
| 190 // Does not contain program urls. | 187 // Does not contain program urls. |
| 191 UNREFERENCED_PARAMETER(full_url); | 188 UNREFERENCED_PARAMETER(full_url); |
| 192 UNREFERENCED_PARAMETER(error_info); | 189 UNREFERENCED_PARAMETER(error_info); |
| 193 UNREFERENCED_PARAMETER(is_portable); | 190 UNREFERENCED_PARAMETER(is_portable); |
| 194 PLUGIN_PRINTF(("PnaclManifest does not contain a program\n")); | 191 PLUGIN_PRINTF(("PnaclManifest does not contain a program\n")); |
| 195 error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, | 192 error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, |
| 196 "pnacl manifest does not contain a program"); | 193 "pnacl manifest does not contain a program"); |
| 197 return false; | 194 return false; |
| 198 } | 195 } |
| 199 | 196 |
| 200 virtual bool ResolveURL(const nacl::string& relative_url, | 197 virtual bool ResolveURL(const nacl::string& relative_url, |
| 201 nacl::string* full_url, | 198 nacl::string* full_url, |
| 202 ErrorInfo* error_info) const { | 199 ErrorInfo* error_info) const { |
| 203 // Does not do general URL resolution, simply appends relative_url to | 200 // Does not do general URL resolution, simply appends relative_url to |
| 204 // the end of url_prefix_. | 201 // the end of manifest_base_url_. |
| 205 UNREFERENCED_PARAMETER(error_info); | 202 UNREFERENCED_PARAMETER(error_info); |
| 206 *full_url = url_prefix_ + relative_url; | 203 *full_url = manifest_base_url_ + relative_url; |
| 207 return true; | 204 return true; |
| 208 } | 205 } |
| 209 | 206 |
| 210 virtual bool GetFileKeys(std::set<nacl::string>* keys) const { | 207 virtual bool GetFileKeys(std::set<nacl::string>* keys) const { |
| 211 // Does not support enumeration. | 208 // Does not support enumeration. |
| 212 PLUGIN_PRINTF(("PnaclManifest does not support key enumeration\n")); | 209 PLUGIN_PRINTF(("PnaclManifest does not support key enumeration\n")); |
| 213 UNREFERENCED_PARAMETER(keys); | 210 UNREFERENCED_PARAMETER(keys); |
| 214 return false; | 211 return false; |
| 215 } | 212 } |
| 216 | 213 |
| 217 virtual bool ResolveKey(const nacl::string& key, | 214 virtual bool ResolveKey(const nacl::string& key, |
| 218 nacl::string* full_url, | 215 nacl::string* full_url, |
| 219 ErrorInfo* error_info, | 216 ErrorInfo* error_info, |
| 220 bool* is_portable) const { | 217 bool* is_portable) const { |
| 221 *is_portable = false; | 218 *is_portable = false; |
| 222 // We can only resolve keys in the files/ namespace. | 219 // We can only resolve keys in the files/ namespace. |
| 223 const nacl::string kFilesPrefix = "files/"; | 220 const nacl::string kFilesPrefix = "files/"; |
| 224 size_t files_prefix_pos = key.find(kFilesPrefix); | 221 size_t files_prefix_pos = key.find(kFilesPrefix); |
| 225 if (files_prefix_pos == nacl::string::npos) { | 222 if (files_prefix_pos == nacl::string::npos) { |
| 226 error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, | 223 error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, |
| 227 "key did not start with files/"); | 224 "key did not start with files/"); |
| 228 return false; | 225 return false; |
| 229 } | 226 } |
| 230 // Append what follows files to the pnacl URL prefix. | 227 // Append what follows files to the pnacl URL prefix. |
| 231 nacl::string key_basename = key.substr(kFilesPrefix.length()); | 228 nacl::string key_basename = key.substr(kFilesPrefix.length()); |
| 232 return ResolveURL(key_basename, full_url, error_info); | 229 return ResolveURL(key_basename, full_url, error_info); |
| 233 } | 230 } |
| 234 | 231 |
| 235 private: | 232 // Since the pnacl coordinator manifest provides access to resources |
| 236 nacl::string url_prefix_; | 233 // in the chrome extension, lookups will need to access resources in their |
| 234 // extension origin rather than the plugin's origin. |
| 235 virtual bool PermitsExtensionUrls() const { |
| 236 return true; |
| 237 } |
| 237 }; | 238 }; |
| 238 | 239 |
| 239 ////////////////////////////////////////////////////////////////////// | 240 ////////////////////////////////////////////////////////////////////// |
| 240 // The coordinator class. | 241 // The coordinator class. |
| 241 ////////////////////////////////////////////////////////////////////// | 242 ////////////////////////////////////////////////////////////////////// |
| 242 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( | 243 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( |
| 243 Plugin* plugin, | 244 Plugin* plugin, |
| 244 const nacl::string& pexe_url, | 245 const nacl::string& pexe_url, |
| 245 const pp::CompletionCallback& translate_notify_callback) { | 246 const pp::CompletionCallback& translate_notify_callback) { |
| 246 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", | 247 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", |
| 247 static_cast<void*>(plugin), pexe_url.c_str())); | 248 static_cast<void*>(plugin), pexe_url.c_str())); |
| 248 PnaclCoordinator* coordinator = | 249 PnaclCoordinator* coordinator = |
| 249 new PnaclCoordinator(plugin, | 250 new PnaclCoordinator(plugin, pexe_url, translate_notify_callback); |
| 250 pexe_url, | 251 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p)\n", |
| 251 translate_notify_callback, | 252 reinterpret_cast<const void*>(coordinator->manifest_))); |
| 252 ResourceBaseUrl()); | |
| 253 // Load llc and ld. | 253 // Load llc and ld. |
| 254 std::vector<nacl::string> resource_urls; | 254 std::vector<nacl::string> resource_urls; |
| 255 resource_urls.push_back(kLlcUrl); | 255 resource_urls.push_back(kLlcUrl); |
| 256 resource_urls.push_back(kLdUrl); | 256 resource_urls.push_back(kLdUrl); |
| 257 pp::CompletionCallback resources_cb = | 257 pp::CompletionCallback resources_cb = |
| 258 coordinator->callback_factory_.NewCallback( | 258 coordinator->callback_factory_.NewCallback( |
| 259 &PnaclCoordinator::ResourcesDidLoad); | 259 &PnaclCoordinator::ResourcesDidLoad); |
| 260 coordinator->resources_.reset( | 260 coordinator->resources_.reset( |
| 261 new PnaclResources(plugin, | 261 new PnaclResources(plugin, |
| 262 coordinator, | 262 coordinator, |
| 263 coordinator->resource_base_url_, | 263 coordinator->manifest_, |
| 264 resource_urls, | 264 resource_urls, |
| 265 resources_cb)); | 265 resources_cb)); |
| 266 CHECK(coordinator->resources_ != NULL); | 266 CHECK(coordinator->resources_ != NULL); |
| 267 coordinator->resources_->StartDownloads(); | 267 coordinator->resources_->StartDownloads(); |
| 268 // ResourcesDidLoad will be invoked when all resources have been received. | 268 // ResourcesDidLoad will be invoked when all resources have been received. |
| 269 return coordinator; | 269 return coordinator; |
| 270 } | 270 } |
| 271 | 271 |
| 272 int32_t PnaclCoordinator::GetLoadedFileDesc(int32_t pp_error, | 272 int32_t PnaclCoordinator::GetLoadedFileDesc(int32_t pp_error, |
| 273 const nacl::string& url, | 273 const nacl::string& url, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 290 if (file_desc_ok_to_close == NACL_NO_FILE_DESC) { | 290 if (file_desc_ok_to_close == NACL_NO_FILE_DESC) { |
| 291 ReportPpapiError(PP_ERROR_FAILED, component + " could not dup fd.\n"); | 291 ReportPpapiError(PP_ERROR_FAILED, component + " could not dup fd.\n"); |
| 292 return -1; | 292 return -1; |
| 293 } | 293 } |
| 294 return file_desc_ok_to_close; | 294 return file_desc_ok_to_close; |
| 295 } | 295 } |
| 296 | 296 |
| 297 PnaclCoordinator::PnaclCoordinator( | 297 PnaclCoordinator::PnaclCoordinator( |
| 298 Plugin* plugin, | 298 Plugin* plugin, |
| 299 const nacl::string& pexe_url, | 299 const nacl::string& pexe_url, |
| 300 const pp::CompletionCallback& translate_notify_callback, | 300 const pp::CompletionCallback& translate_notify_callback) |
| 301 const nacl::string& resource_base_url) | |
| 302 : plugin_(plugin), | 301 : plugin_(plugin), |
| 303 translate_notify_callback_(translate_notify_callback), | 302 translate_notify_callback_(translate_notify_callback), |
| 304 resource_base_url_(resource_base_url), | |
| 305 llc_subprocess_(NULL), | 303 llc_subprocess_(NULL), |
| 306 ld_subprocess_(NULL), | 304 ld_subprocess_(NULL), |
| 307 subprocesses_should_die_(false), | 305 subprocesses_should_die_(false), |
| 308 file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), | 306 file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), |
| 309 // TODO(sehr,jvoung): change base url to pnacl extension/testing url. | 307 manifest_(new PnaclManifest(plugin->url_util())), |
| 310 manifest_(new PnaclManifest(plugin->url_util(), | |
| 311 plugin->manifest_base_url())), | |
| 312 pexe_url_(pexe_url) { | 308 pexe_url_(pexe_url) { |
| 313 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", | 309 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", |
| 314 static_cast<void*>(this), static_cast<void*>(plugin))); | 310 static_cast<void*>(this), static_cast<void*>(plugin))); |
| 315 callback_factory_.Initialize(this); | 311 callback_factory_.Initialize(this); |
| 316 NaClXMutexCtor(&subprocess_mu_); | 312 NaClXMutexCtor(&subprocess_mu_); |
| 317 // Check the temporary file system. | |
| 318 CHECK(file_system_ != NULL); | |
| 319 } | 313 } |
| 320 | 314 |
| 321 PnaclCoordinator::~PnaclCoordinator() { | 315 PnaclCoordinator::~PnaclCoordinator() { |
| 322 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p)\n", | 316 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p)\n", |
| 323 static_cast<void*>(this))); | 317 static_cast<void*>(this))); |
| 324 // Join helper thread which will block the page from refreshing while a | 318 // Join helper thread which will block the page from refreshing while a |
| 325 // translation is happening. | 319 // translation is happening. |
| 326 if (translate_thread_.get() != NULL) { | 320 if (translate_thread_.get() != NULL) { |
| 327 SetSubprocessesShouldDie(true); | 321 SetSubprocessesShouldDie(true); |
| 328 NaClThreadJoin(translate_thread_.get()); | 322 NaClThreadJoin(translate_thread_.get()); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 PLUGIN_PRINTF(("PnaclCoordinator::NexePairDidOpen (pp_error=%" | 420 PLUGIN_PRINTF(("PnaclCoordinator::NexePairDidOpen (pp_error=%" |
| 427 NACL_PRId32")\n", pp_error)); | 421 NACL_PRId32")\n", pp_error)); |
| 428 if (pp_error != PP_OK) { | 422 if (pp_error != PP_OK) { |
| 429 ReportPpapiError(pp_error); | 423 ReportPpapiError(pp_error); |
| 430 return; | 424 return; |
| 431 } | 425 } |
| 432 // Load the pexe file and get the translation started. | 426 // Load the pexe file and get the translation started. |
| 433 pp::CompletionCallback cb = | 427 pp::CompletionCallback cb = |
| 434 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); | 428 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); |
| 435 | 429 |
| 436 if (!plugin_->StreamAsFile(pexe_url_, cb.pp_completion_callback())) { | 430 if (!plugin_->StreamAsFile(pexe_url_, |
| 431 manifest_->PermitsExtensionUrls(), |
| 432 cb.pp_completion_callback())) { |
| 437 ReportNonPpapiError(nacl::string("failed to download ") + pexe_url_ + "\n"); | 433 ReportNonPpapiError(nacl::string("failed to download ") + pexe_url_ + "\n"); |
| 438 } | 434 } |
| 439 } | 435 } |
| 440 | 436 |
| 441 void PnaclCoordinator::RunTranslate(int32_t pp_error) { | 437 void PnaclCoordinator::RunTranslate(int32_t pp_error) { |
| 442 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" | 438 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" |
| 443 NACL_PRId32")\n", pp_error)); | 439 NACL_PRId32")\n", pp_error)); |
| 444 int32_t fd = GetLoadedFileDesc(pp_error, pexe_url_, "pexe"); | 440 int32_t fd = GetLoadedFileDesc(pp_error, pexe_url_, "pexe"); |
| 445 if (fd < 0) { | 441 if (fd < 0) { |
| 446 return; | 442 return; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 nacl::MutexLocker ml(&subprocess_mu_); | 551 nacl::MutexLocker ml(&subprocess_mu_); |
| 556 return subprocesses_should_die_; | 552 return subprocesses_should_die_; |
| 557 } | 553 } |
| 558 | 554 |
| 559 void PnaclCoordinator::SetSubprocessesShouldDie(bool subprocesses_should_die) { | 555 void PnaclCoordinator::SetSubprocessesShouldDie(bool subprocesses_should_die) { |
| 560 nacl::MutexLocker ml(&subprocess_mu_); | 556 nacl::MutexLocker ml(&subprocess_mu_); |
| 561 subprocesses_should_die_ = subprocesses_should_die; | 557 subprocesses_should_die_ = subprocesses_should_die; |
| 562 } | 558 } |
| 563 | 559 |
| 564 } // namespace plugin | 560 } // namespace plugin |
| OLD | NEW |