Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/nacl/renderer/ppb_nacl_private_impl.h" | 5 #include "components/nacl/renderer/ppb_nacl_private_impl.h" |
| 6 | 6 |
| 7 #include <numeric> | 7 #include <numeric> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/containers/scoped_ptr_hash_map.h" | 14 #include "base/containers/scoped_ptr_hash_map.h" |
| 15 #include "base/cpu.h" | 15 #include "base/cpu.h" |
| 16 #include "base/files/file.h" | 16 #include "base/files/file.h" |
| 17 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/rand_util.h" | 19 #include "base/rand_util.h" |
| 20 #include "base/strings/string_split.h" | |
| 21 #include "base/strings/string_util.h" | |
| 20 #include "components/nacl/common/nacl_host_messages.h" | 22 #include "components/nacl/common/nacl_host_messages.h" |
| 21 #include "components/nacl/common/nacl_messages.h" | 23 #include "components/nacl/common/nacl_messages.h" |
| 22 #include "components/nacl/common/nacl_nonsfi_util.h" | 24 #include "components/nacl/common/nacl_nonsfi_util.h" |
| 23 #include "components/nacl/common/nacl_switches.h" | 25 #include "components/nacl/common/nacl_switches.h" |
| 24 #include "components/nacl/common/nacl_types.h" | 26 #include "components/nacl/common/nacl_types.h" |
| 25 #include "components/nacl/renderer/file_downloader.h" | 27 #include "components/nacl/renderer/file_downloader.h" |
| 26 #include "components/nacl/renderer/histogram.h" | 28 #include "components/nacl/renderer/histogram.h" |
| 27 #include "components/nacl/renderer/json_manifest.h" | 29 #include "components/nacl/renderer/json_manifest.h" |
| 28 #include "components/nacl/renderer/manifest_downloader.h" | 30 #include "components/nacl/renderer/manifest_downloader.h" |
| 29 #include "components/nacl/renderer/manifest_service_channel.h" | 31 #include "components/nacl/renderer/manifest_service_channel.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 45 #include "net/http/http_util.h" | 47 #include "net/http/http_util.h" |
| 46 #include "ppapi/c/pp_bool.h" | 48 #include "ppapi/c/pp_bool.h" |
| 47 #include "ppapi/c/private/pp_file_handle.h" | 49 #include "ppapi/c/private/pp_file_handle.h" |
| 48 #include "ppapi/shared_impl/ppapi_globals.h" | 50 #include "ppapi/shared_impl/ppapi_globals.h" |
| 49 #include "ppapi/shared_impl/ppapi_permissions.h" | 51 #include "ppapi/shared_impl/ppapi_permissions.h" |
| 50 #include "ppapi/shared_impl/ppapi_preferences.h" | 52 #include "ppapi/shared_impl/ppapi_preferences.h" |
| 51 #include "ppapi/shared_impl/var.h" | 53 #include "ppapi/shared_impl/var.h" |
| 52 #include "ppapi/shared_impl/var_tracker.h" | 54 #include "ppapi/shared_impl/var_tracker.h" |
| 53 #include "ppapi/thunk/enter.h" | 55 #include "ppapi/thunk/enter.h" |
| 54 #include "third_party/WebKit/public/platform/WebURLLoader.h" | 56 #include "third_party/WebKit/public/platform/WebURLLoader.h" |
| 57 #include "third_party/WebKit/public/platform/WebURLResponse.h" | |
| 55 #include "third_party/WebKit/public/web/WebDocument.h" | 58 #include "third_party/WebKit/public/web/WebDocument.h" |
| 56 #include "third_party/WebKit/public/web/WebElement.h" | 59 #include "third_party/WebKit/public/web/WebElement.h" |
| 57 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 60 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 58 #include "third_party/WebKit/public/web/WebPluginContainer.h" | 61 #include "third_party/WebKit/public/web/WebPluginContainer.h" |
| 59 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" | 62 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" |
| 60 #include "third_party/WebKit/public/web/WebURLLoaderOptions.h" | 63 #include "third_party/WebKit/public/web/WebURLLoaderOptions.h" |
| 61 #include "third_party/jsoncpp/source/include/json/reader.h" | 64 #include "third_party/jsoncpp/source/include/json/reader.h" |
| 62 #include "third_party/jsoncpp/source/include/json/value.h" | 65 #include "third_party/jsoncpp/source/include/json/value.h" |
| 63 | 66 |
| 64 namespace nacl { | 67 namespace nacl { |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 if(!sender->Send(new NaClHostMsg_NaClGetNumProcessors(&num_processors))) { | 583 if(!sender->Send(new NaClHostMsg_NaClGetNumProcessors(&num_processors))) { |
| 581 return 1; | 584 return 1; |
| 582 } | 585 } |
| 583 return num_processors; | 586 return num_processors; |
| 584 } | 587 } |
| 585 | 588 |
| 586 PP_Bool PPIsNonSFIModeEnabled() { | 589 PP_Bool PPIsNonSFIModeEnabled() { |
| 587 return PP_FromBool(IsNonSFIModeEnabled()); | 590 return PP_FromBool(IsNonSFIModeEnabled()); |
| 588 } | 591 } |
| 589 | 592 |
| 590 void GetNexeFdContinuation(scoped_refptr<ppapi::TrackedCallback> callback, | 593 std::string GetCpuFeatureAttrs() { |
|
dmichael (off chromium)
2014/07/17 16:13:21
Maybe it would make sense to combine this with the
teravest
2014/07/21 18:33:21
Done (in a separate change).
| |
| 591 PP_Bool* out_is_hit, | 594 // PNaCl's translator from pexe to nexe can be told exactly what |
| 592 PP_FileHandle* out_handle, | 595 // capabilities the user's machine has because the pexe to nexe |
| 593 int32_t pp_error, | 596 // translation is specific to the machine, and CPU information goes |
| 594 bool is_hit, | 597 // into the translation cache. This allows the translator to generate |
| 595 PP_FileHandle handle) { | 598 // faster code. |
| 596 if (pp_error == PP_OK) { | 599 // |
| 597 *out_is_hit = PP_FromBool(is_hit); | 600 // Care must be taken to avoid instructions which aren't supported by |
| 598 *out_handle = handle; | 601 // the NaCl sandbox. Ideally the translator would do this, but there's |
| 599 } | 602 // no point in not doing the whitelist here. |
| 600 callback->PostRun(pp_error); | 603 // |
| 604 // TODO(jfb) Some features are missing, either because the NaCl | |
| 605 // sandbox doesn't support them, because base::CPU doesn't | |
| 606 // detect them, or because they don't help vector shuffles | |
| 607 // (and we omit them because it simplifies testing). Add the | |
| 608 // other features. | |
| 609 // | |
| 610 // TODO(jfb) The following is x86-specific. The base::CPU class | |
| 611 // doesn't handle other architectures very well, and we | |
| 612 // should at least detect the presence of ARM's integer | |
| 613 // divide. | |
| 614 std::vector<std::string> attrs; | |
| 615 base::CPU cpu; | |
| 616 | |
| 617 // On x86, SSE features are ordered: the most recent one implies the | |
| 618 // others. Care is taken here to only specify the latest SSE version, | |
| 619 // whereas non-SSE features don't follow this model: POPCNT is | |
| 620 // effectively always implied by SSE4.2 but has to be specified | |
| 621 // separately. | |
| 622 // | |
| 623 // TODO: AVX2, AVX, SSE 4.2. | |
| 624 if (cpu.has_sse41()) attrs.push_back("+sse4.1"); | |
| 625 // TODO: SSE 4A, SSE 4. | |
| 626 else if (cpu.has_ssse3()) attrs.push_back("+ssse3"); | |
| 627 // TODO: SSE 3 | |
| 628 else if (cpu.has_sse2()) attrs.push_back("+sse2"); | |
| 629 | |
| 630 // TODO: AES, POPCNT, LZCNT, ... | |
| 631 | |
| 632 return JoinString(attrs, ","); | |
| 601 } | 633 } |
| 602 | 634 |
| 603 int32_t GetNexeFd(PP_Instance instance, | 635 void GetNexeFd(PP_Instance instance, |
| 604 const char* pexe_url, | 636 const std::string& pexe_url, |
| 605 uint32_t abi_version, | 637 uint32_t opt_level, |
| 606 uint32_t opt_level, | 638 const base::Time& last_modified_time, |
| 607 const char* http_headers_param, | 639 const std::string& etag, |
| 608 const char* extra_flags, | 640 bool has_no_store_header, |
| 609 PP_Bool* is_hit, | 641 base::Callback<void(int32_t, bool, PP_FileHandle)> callback) { |
| 610 PP_FileHandle* handle, | 642 if (!InitializePnaclResourceHost()) { |
| 611 struct PP_CompletionCallback callback) { | 643 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 612 ppapi::thunk::EnterInstance enter(instance, callback); | 644 FROM_HERE, |
| 613 if (enter.failed()) | 645 base::Bind(callback, |
| 614 return enter.retval(); | 646 static_cast<int32_t>(PP_ERROR_FAILED), |
| 615 if (!pexe_url || !is_hit || !handle) | 647 false, |
| 616 return enter.SetResult(PP_ERROR_BADARGUMENT); | 648 PP_kInvalidFileHandle)); |
| 617 if (!InitializePnaclResourceHost()) | 649 return; |
| 618 return enter.SetResult(PP_ERROR_FAILED); | |
| 619 | |
| 620 std::string http_headers(http_headers_param); | |
| 621 net::HttpUtil::HeadersIterator iter( | |
| 622 http_headers.begin(), http_headers.end(), "\r\n"); | |
| 623 | |
| 624 std::string last_modified; | |
| 625 std::string etag; | |
| 626 bool has_no_store_header = false; | |
| 627 while (iter.GetNext()) { | |
| 628 if (StringToLowerASCII(iter.name()) == "last-modified") | |
| 629 last_modified = iter.values(); | |
| 630 if (StringToLowerASCII(iter.name()) == "etag") | |
| 631 etag = iter.values(); | |
| 632 if (StringToLowerASCII(iter.name()) == "cache-control") { | |
| 633 net::HttpUtil::ValuesIterator values_iter( | |
| 634 iter.values_begin(), iter.values_end(), ','); | |
| 635 while (values_iter.GetNext()) { | |
| 636 if (StringToLowerASCII(values_iter.value()) == "no-store") | |
| 637 has_no_store_header = true; | |
| 638 } | |
| 639 } | |
| 640 } | 650 } |
| 641 | 651 |
| 642 base::Time last_modified_time; | |
| 643 // If FromString fails, it doesn't touch last_modified_time and we just send | |
| 644 // the default-constructed null value. | |
| 645 base::Time::FromString(last_modified.c_str(), &last_modified_time); | |
| 646 | |
| 647 PnaclCacheInfo cache_info; | 652 PnaclCacheInfo cache_info; |
| 648 cache_info.pexe_url = GURL(pexe_url); | 653 cache_info.pexe_url = GURL(pexe_url); |
| 649 cache_info.abi_version = abi_version; | 654 // TODO(dschuff): Get this value from the pnacl json file after it |
| 655 // rolls in from NaCl. | |
| 656 cache_info.abi_version = 1; | |
| 650 cache_info.opt_level = opt_level; | 657 cache_info.opt_level = opt_level; |
| 651 cache_info.last_modified = last_modified_time; | 658 cache_info.last_modified = last_modified_time; |
| 652 cache_info.etag = etag; | 659 cache_info.etag = etag; |
| 653 cache_info.has_no_store_header = has_no_store_header; | 660 cache_info.has_no_store_header = has_no_store_header; |
| 654 cache_info.sandbox_isa = GetSandboxArch(); | 661 cache_info.sandbox_isa = GetSandboxArch(); |
| 655 cache_info.extra_flags = std::string(extra_flags); | 662 cache_info.extra_flags = GetCpuFeatureAttrs(); |
| 656 | 663 |
| 657 g_pnacl_resource_host.Get()->RequestNexeFd( | 664 g_pnacl_resource_host.Get()->RequestNexeFd( |
| 658 GetRoutingID(instance), | 665 GetRoutingID(instance), |
| 659 instance, | 666 instance, |
| 660 cache_info, | 667 cache_info, |
| 661 base::Bind(&GetNexeFdContinuation, enter.callback(), is_hit, handle)); | 668 callback); |
| 662 | |
| 663 return enter.SetResult(PP_OK_COMPLETIONPENDING); | |
| 664 } | 669 } |
| 665 | 670 |
| 666 void ReportTranslationFinished(PP_Instance instance, | 671 void ReportTranslationFinished(PP_Instance instance, |
| 667 PP_Bool success, | 672 PP_Bool success, |
| 668 int32_t opt_level, | 673 int32_t opt_level, |
| 669 int64_t pexe_size, | 674 int64_t pexe_size, |
| 670 int64_t compile_time_us) { | 675 int64_t compile_time_us) { |
| 671 if (success == PP_TRUE) { | 676 if (success == PP_TRUE) { |
| 672 static const int32_t kUnknownOptLevel = 4; | 677 static const int32_t kUnknownOptLevel = 4; |
| 673 if (opt_level < 0 || opt_level > 3) | 678 if (opt_level < 0 || opt_level > 3) |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1212 if (json_data.isMember("pnacl-ld-name")) { | 1217 if (json_data.isMember("pnacl-ld-name")) { |
| 1213 Json::Value json_name = json_data["pnacl-ld-name"]; | 1218 Json::Value json_name = json_data["pnacl-ld-name"]; |
| 1214 if (json_name.isString()) { | 1219 if (json_name.isString()) { |
| 1215 std::string ld_tool_name_str = json_name.asString(); | 1220 std::string ld_tool_name_str = json_name.asString(); |
| 1216 *ld_tool_name = ppapi::StringVar::StringToPPVar(ld_tool_name_str); | 1221 *ld_tool_name = ppapi::StringVar::StringToPPVar(ld_tool_name_str); |
| 1217 } | 1222 } |
| 1218 } | 1223 } |
| 1219 return PP_TRUE; | 1224 return PP_TRUE; |
| 1220 } | 1225 } |
| 1221 | 1226 |
| 1222 // Helper to std::accumulate that creates a comma-separated list from the input. | 1227 PP_Var ExternalGetCpuFeatureAttrs() { |
| 1223 std::string CommaAccumulator(const std::string &lhs, const std::string &rhs) { | 1228 return ppapi::StringVar::StringToPPVar(GetCpuFeatureAttrs()); |
| 1224 if (lhs.empty()) | |
| 1225 return rhs; | |
| 1226 return lhs + "," + rhs; | |
| 1227 } | |
| 1228 | |
| 1229 PP_Var GetCpuFeatureAttrs() { | |
| 1230 // PNaCl's translator from pexe to nexe can be told exactly what | |
| 1231 // capabilities the user's machine has because the pexe to nexe | |
| 1232 // translation is specific to the machine, and CPU information goes | |
| 1233 // into the translation cache. This allows the translator to generate | |
| 1234 // faster code. | |
| 1235 // | |
| 1236 // Care must be taken to avoid instructions which aren't supported by | |
| 1237 // the NaCl sandbox. Ideally the translator would do this, but there's | |
| 1238 // no point in not doing the whitelist here. | |
| 1239 // | |
| 1240 // TODO(jfb) Some features are missing, either because the NaCl | |
| 1241 // sandbox doesn't support them, because base::CPU doesn't | |
| 1242 // detect them, or because they don't help vector shuffles | |
| 1243 // (and we omit them because it simplifies testing). Add the | |
| 1244 // other features. | |
| 1245 // | |
| 1246 // TODO(jfb) The following is x86-specific. The base::CPU class | |
| 1247 // doesn't handle other architectures very well, and we | |
| 1248 // should at least detect the presence of ARM's integer | |
| 1249 // divide. | |
| 1250 std::vector<std::string> attrs; | |
| 1251 base::CPU cpu; | |
| 1252 | |
| 1253 // On x86, SSE features are ordered: the most recent one implies the | |
| 1254 // others. Care is taken here to only specify the latest SSE version, | |
| 1255 // whereas non-SSE features don't follow this model: POPCNT is | |
| 1256 // effectively always implied by SSE4.2 but has to be specified | |
| 1257 // separately. | |
| 1258 // | |
| 1259 // TODO: AVX2, AVX, SSE 4.2. | |
| 1260 if (cpu.has_sse41()) attrs.push_back("+sse4.1"); | |
| 1261 // TODO: SSE 4A, SSE 4. | |
| 1262 else if (cpu.has_ssse3()) attrs.push_back("+ssse3"); | |
| 1263 // TODO: SSE 3 | |
| 1264 else if (cpu.has_sse2()) attrs.push_back("+sse2"); | |
| 1265 | |
| 1266 // TODO: AES, POPCNT, LZCNT, ... | |
| 1267 | |
| 1268 return ppapi::StringVar::StringToPPVar(std::accumulate( | |
| 1269 attrs.begin(), attrs.end(), std::string(), CommaAccumulator)); | |
| 1270 } | 1229 } |
| 1271 | 1230 |
| 1272 void PostMessageToJavaScriptMainThread(PP_Instance instance, | 1231 void PostMessageToJavaScriptMainThread(PP_Instance instance, |
| 1273 const std::string& message) { | 1232 const std::string& message) { |
| 1274 content::PepperPluginInstance* plugin_instance = | 1233 content::PepperPluginInstance* plugin_instance = |
| 1275 content::PepperPluginInstance::Get(instance); | 1234 content::PepperPluginInstance::Get(instance); |
| 1276 if (plugin_instance) { | 1235 if (plugin_instance) { |
| 1277 PP_Var message_var = ppapi::StringVar::StringToPPVar(message); | 1236 PP_Var message_var = ppapi::StringVar::StringToPPVar(message); |
| 1278 plugin_instance->PostMessageToJavaScript(message_var); | 1237 plugin_instance->PostMessageToJavaScript(message_var); |
| 1279 ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(message_var); | 1238 ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(message_var); |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1602 DownloadFile(instance, url, | 1561 DownloadFile(instance, url, |
| 1603 base::Bind(&DidOpenManifestEntry, out_file_info, callback)); | 1562 base::Bind(&DidOpenManifestEntry, out_file_info, callback)); |
| 1604 } | 1563 } |
| 1605 | 1564 |
| 1606 void SetPNaClStartTime(PP_Instance instance) { | 1565 void SetPNaClStartTime(PP_Instance instance) { |
| 1607 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 1566 NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
| 1608 if (load_manager) | 1567 if (load_manager) |
| 1609 load_manager->set_pnacl_start_time(base::Time::Now()); | 1568 load_manager->set_pnacl_start_time(base::Time::Now()); |
| 1610 } | 1569 } |
| 1611 | 1570 |
| 1571 class PexeDownloader : public blink::WebURLLoaderClient { | |
| 1572 public: | |
| 1573 PexeDownloader(PP_Instance instance, | |
| 1574 scoped_ptr<blink::WebURLLoader> url_loader, | |
| 1575 const std::string& pexe_url, | |
| 1576 int32_t pexe_opt_level, | |
| 1577 const PPP_PexeStreamHandler* stream_handler, | |
| 1578 void* stream_handler_user_data) | |
| 1579 : instance_(instance), | |
| 1580 url_loader_(url_loader.Pass()), | |
| 1581 pexe_url_(pexe_url), | |
| 1582 pexe_opt_level_(pexe_opt_level), | |
| 1583 stream_handler_(stream_handler), | |
| 1584 stream_handler_user_data_(stream_handler_user_data), | |
| 1585 success_(false), | |
| 1586 expected_content_length_(-1), | |
| 1587 weak_factory_(this) { } | |
| 1588 | |
| 1589 void Load(const blink::WebURLRequest& request) { | |
| 1590 url_loader_->loadAsynchronously(request, this); | |
| 1591 } | |
| 1592 | |
| 1593 private: | |
| 1594 virtual void didReceiveResponse(blink::WebURLLoader* loader, | |
| 1595 const blink::WebURLResponse& response) { | |
| 1596 success_ = (response.httpStatusCode() == 200); | |
| 1597 if (!success_) | |
| 1598 return; | |
| 1599 | |
| 1600 expected_content_length_ = response.expectedContentLength(); | |
| 1601 | |
| 1602 // Defer loading after receiving headers. This is because we may already | |
| 1603 // have a cached translated nexe, so check for that now. | |
| 1604 url_loader_->setDefersLoading(true); | |
| 1605 | |
| 1606 std::string etag = response.httpHeaderField("etag").utf8(); | |
| 1607 std::string last_modified = | |
| 1608 response.httpHeaderField("last-modified").utf8(); | |
| 1609 base::Time last_modified_time; | |
| 1610 base::Time::FromString(last_modified.c_str(), &last_modified_time); | |
| 1611 | |
| 1612 bool has_no_store_header = false; | |
| 1613 std::string cache_control = | |
| 1614 response.httpHeaderField("cache-control").utf8(); | |
| 1615 | |
| 1616 std::vector<std::string> values; | |
| 1617 base::SplitString(cache_control, ',', &values); | |
| 1618 for (std::vector<std::string>::const_iterator it = values.begin(); | |
| 1619 it != values.end(); | |
| 1620 ++it) { | |
| 1621 if (StringToLowerASCII(*it) == "no-store") | |
| 1622 has_no_store_header = true; | |
| 1623 } | |
| 1624 | |
| 1625 GetNexeFd(instance_, | |
| 1626 pexe_url_, | |
| 1627 pexe_opt_level_, | |
| 1628 last_modified_time, | |
| 1629 etag, | |
| 1630 has_no_store_header, | |
| 1631 base::Bind(&PexeDownloader::didGetNexeFd, | |
| 1632 weak_factory_.GetWeakPtr())); | |
| 1633 } | |
| 1634 | |
| 1635 virtual void didGetNexeFd(int32_t pp_error, | |
| 1636 bool cache_hit, | |
| 1637 PP_FileHandle file_handle) { | |
| 1638 if (cache_hit) { | |
| 1639 stream_handler_->DidCacheHit(stream_handler_user_data_, file_handle); | |
| 1640 | |
| 1641 // We delete the PexeDownloader at this point since we successfully got a | |
| 1642 // cached, translated nexe. | |
| 1643 delete this; | |
| 1644 return; | |
| 1645 } | |
| 1646 stream_handler_->DidCacheMiss(stream_handler_user_data_, | |
| 1647 expected_content_length_); | |
| 1648 | |
| 1649 // No translated nexe was found in the cache, so we should download the | |
| 1650 // file to start streaming it. | |
| 1651 url_loader_->setDefersLoading(false); | |
| 1652 } | |
| 1653 | |
| 1654 virtual void didReceiveData(blink::WebURLLoader* loader, | |
| 1655 const char* data, | |
| 1656 int data_length, | |
| 1657 int encoded_data_length) { | |
| 1658 // Stream the data we received to the stream callback. | |
| 1659 stream_handler_->DidStreamData(stream_handler_user_data_, | |
| 1660 data, | |
| 1661 data_length); | |
| 1662 } | |
| 1663 | |
| 1664 virtual void didFinishLoading(blink::WebURLLoader* loader, | |
| 1665 double finish_time, | |
| 1666 int64_t total_encoded_data_length) { | |
| 1667 int32_t result = success_ ? PP_OK : PP_ERROR_FAILED; | |
| 1668 stream_handler_->DidFinishStream(stream_handler_user_data_, result); | |
| 1669 delete this; | |
| 1670 } | |
| 1671 | |
| 1672 virtual void didFail(blink::WebURLLoader* loader, | |
| 1673 const blink::WebURLError& error) { | |
| 1674 success_ = false; | |
| 1675 } | |
| 1676 | |
| 1677 PP_Instance instance_; | |
| 1678 scoped_ptr<blink::WebURLLoader> url_loader_; | |
| 1679 std::string pexe_url_; | |
| 1680 int32_t pexe_opt_level_; | |
| 1681 const PPP_PexeStreamHandler* stream_handler_; | |
| 1682 void* stream_handler_user_data_; | |
| 1683 bool success_; | |
| 1684 int64_t expected_content_length_; | |
| 1685 base::WeakPtrFactory<PexeDownloader> weak_factory_; | |
| 1686 }; | |
| 1687 | |
| 1688 void StreamPexe(PP_Instance instance, | |
| 1689 const char* pexe_url, | |
| 1690 int32_t opt_level, | |
| 1691 const PPP_PexeStreamHandler* handler, | |
| 1692 void* handler_user_data) { | |
| 1693 content::PepperPluginInstance* plugin_instance = | |
| 1694 content::PepperPluginInstance::Get(instance); | |
| 1695 if (!plugin_instance) { | |
| 1696 base::MessageLoop::current()->PostTask( | |
| 1697 FROM_HERE, | |
| 1698 base::Bind(handler->DidFinishStream, | |
| 1699 handler_user_data, | |
| 1700 static_cast<int32_t>(PP_ERROR_FAILED))); | |
| 1701 return; | |
| 1702 } | |
| 1703 | |
| 1704 GURL gurl(pexe_url); | |
| 1705 const blink::WebDocument& document = | |
| 1706 plugin_instance->GetContainer()->element().document(); | |
| 1707 scoped_ptr<blink::WebURLLoader> url_loader( | |
| 1708 CreateWebURLLoader(document, gurl)); | |
| 1709 PexeDownloader* downloader = new PexeDownloader(instance, | |
| 1710 url_loader.Pass(), | |
| 1711 pexe_url, | |
| 1712 opt_level, | |
| 1713 handler, | |
| 1714 handler_user_data); | |
| 1715 | |
| 1716 blink::WebURLRequest url_request = CreateWebURLRequest(document, gurl); | |
| 1717 // Mark the request as requesting a PNaCl bitcode file, | |
| 1718 // so that component updater can detect this user action. | |
| 1719 url_request.addHTTPHeaderField( | |
| 1720 blink::WebString::fromUTF8("Accept"), | |
| 1721 blink::WebString::fromUTF8("application/x-pnacl, */*")); | |
| 1722 downloader->Load(url_request); | |
| 1723 } | |
| 1724 | |
| 1612 const PPB_NaCl_Private nacl_interface = { | 1725 const PPB_NaCl_Private nacl_interface = { |
| 1613 &LaunchSelLdr, | 1726 &LaunchSelLdr, |
| 1614 &StartPpapiProxy, | 1727 &StartPpapiProxy, |
| 1615 &UrandomFD, | 1728 &UrandomFD, |
| 1616 &Are3DInterfacesDisabled, | 1729 &Are3DInterfacesDisabled, |
| 1617 &BrokerDuplicateHandle, | 1730 &BrokerDuplicateHandle, |
| 1618 &GetReadExecPnaclFd, | 1731 &GetReadExecPnaclFd, |
| 1619 &CreateTemporaryFile, | 1732 &CreateTemporaryFile, |
| 1620 &GetNumberOfProcessors, | 1733 &GetNumberOfProcessors, |
| 1621 &PPIsNonSFIModeEnabled, | 1734 &PPIsNonSFIModeEnabled, |
| 1622 &GetNexeFd, | |
| 1623 &ReportTranslationFinished, | 1735 &ReportTranslationFinished, |
| 1624 &DispatchEvent, | 1736 &DispatchEvent, |
| 1625 &ReportLoadSuccess, | 1737 &ReportLoadSuccess, |
| 1626 &ReportLoadError, | 1738 &ReportLoadError, |
| 1627 &ReportLoadAbort, | 1739 &ReportLoadAbort, |
| 1628 &NexeDidCrash, | 1740 &NexeDidCrash, |
| 1629 &InstanceCreated, | 1741 &InstanceCreated, |
| 1630 &InstanceDestroyed, | 1742 &InstanceDestroyed, |
| 1631 &NaClDebugEnabledForURL, | 1743 &NaClDebugEnabledForURL, |
| 1632 &GetSandboxArch, | 1744 &GetSandboxArch, |
| 1633 &LogToConsole, | 1745 &LogToConsole, |
| 1634 &GetNaClReadyState, | 1746 &GetNaClReadyState, |
| 1635 &GetExitStatus, | 1747 &GetExitStatus, |
| 1636 &SetExitStatus, | 1748 &SetExitStatus, |
| 1637 &Vlog, | 1749 &Vlog, |
| 1638 &InitializePlugin, | 1750 &InitializePlugin, |
| 1639 &GetNexeSize, | 1751 &GetNexeSize, |
| 1640 &RequestNaClManifest, | 1752 &RequestNaClManifest, |
| 1641 &GetManifestBaseURL, | 1753 &GetManifestBaseURL, |
| 1642 &ProcessNaClManifest, | 1754 &ProcessNaClManifest, |
| 1643 &DevInterfacesEnabled, | 1755 &DevInterfacesEnabled, |
| 1644 &ManifestGetProgramURL, | 1756 &ManifestGetProgramURL, |
| 1645 &GetPNaClResourceInfo, | 1757 &GetPNaClResourceInfo, |
| 1646 &GetCpuFeatureAttrs, | 1758 &ExternalGetCpuFeatureAttrs, |
| 1647 &PostMessageToJavaScript, | 1759 &PostMessageToJavaScript, |
| 1648 &DownloadNexe, | 1760 &DownloadNexe, |
| 1649 &ReportSelLdrStatus, | 1761 &ReportSelLdrStatus, |
| 1650 &LogTranslateTime, | 1762 &LogTranslateTime, |
| 1651 &OpenManifestEntry, | 1763 &OpenManifestEntry, |
| 1652 &SetPNaClStartTime | 1764 &SetPNaClStartTime, |
| 1765 &StreamPexe | |
| 1653 }; | 1766 }; |
| 1654 | 1767 |
| 1655 } // namespace | 1768 } // namespace |
| 1656 | 1769 |
| 1657 const PPB_NaCl_Private* GetNaClPrivateInterface() { | 1770 const PPB_NaCl_Private* GetNaClPrivateInterface() { |
| 1658 return &nacl_interface; | 1771 return &nacl_interface; |
| 1659 } | 1772 } |
| 1660 | 1773 |
| 1661 } // namespace nacl | 1774 } // namespace nacl |
| OLD | NEW |