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 |