Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(564)

Side by Side Diff: components/nacl/renderer/ppb_nacl_private_impl.cc

Issue 649603004: Non-SFI NaCl: Batch-open resource files (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: code review Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/macros.h"
19 #include "base/rand_util.h" 20 #include "base/rand_util.h"
20 #include "base/strings/string_split.h" 21 #include "base/strings/string_split.h"
21 #include "base/strings/string_util.h" 22 #include "base/strings/string_util.h"
22 #include "components/nacl/common/nacl_host_messages.h" 23 #include "components/nacl/common/nacl_host_messages.h"
23 #include "components/nacl/common/nacl_messages.h" 24 #include "components/nacl/common/nacl_messages.h"
24 #include "components/nacl/common/nacl_nonsfi_util.h" 25 #include "components/nacl/common/nacl_nonsfi_util.h"
25 #include "components/nacl/common/nacl_switches.h" 26 #include "components/nacl/common/nacl_switches.h"
26 #include "components/nacl/common/nacl_types.h" 27 #include "components/nacl/common/nacl_types.h"
27 #include "components/nacl/renderer/file_downloader.h" 28 #include "components/nacl/renderer/file_downloader.h"
28 #include "components/nacl/renderer/histogram.h" 29 #include "components/nacl/renderer/histogram.h"
29 #include "components/nacl/renderer/json_manifest.h" 30 #include "components/nacl/renderer/json_manifest.h"
30 #include "components/nacl/renderer/manifest_downloader.h" 31 #include "components/nacl/renderer/manifest_downloader.h"
31 #include "components/nacl/renderer/manifest_service_channel.h" 32 #include "components/nacl/renderer/manifest_service_channel.h"
32 #include "components/nacl/renderer/nexe_load_manager.h" 33 #include "components/nacl/renderer/nexe_load_manager.h"
33 #include "components/nacl/renderer/platform_info.h" 34 #include "components/nacl/renderer/platform_info.h"
34 #include "components/nacl/renderer/pnacl_translation_resource_host.h" 35 #include "components/nacl/renderer/pnacl_translation_resource_host.h"
35 #include "components/nacl/renderer/progress_event.h" 36 #include "components/nacl/renderer/progress_event.h"
36 #include "components/nacl/renderer/trusted_plugin_channel.h" 37 #include "components/nacl/renderer/trusted_plugin_channel.h"
37 #include "content/public/common/content_client.h" 38 #include "content/public/common/content_client.h"
38 #include "content/public/common/content_switches.h" 39 #include "content/public/common/content_switches.h"
39 #include "content/public/common/sandbox_init.h" 40 #include "content/public/common/sandbox_init.h"
40 #include "content/public/renderer/pepper_plugin_instance.h" 41 #include "content/public/renderer/pepper_plugin_instance.h"
41 #include "content/public/renderer/render_thread.h" 42 #include "content/public/renderer/render_thread.h"
42 #include "content/public/renderer/render_view.h" 43 #include "content/public/renderer/render_view.h"
43 #include "content/public/renderer/renderer_ppapi_host.h" 44 #include "content/public/renderer/renderer_ppapi_host.h"
45 #include "ipc/ipc_message_attachment_set.h"
44 #include "native_client/src/public/imc_types.h" 46 #include "native_client/src/public/imc_types.h"
45 #include "net/base/data_url.h" 47 #include "net/base/data_url.h"
46 #include "net/base/net_errors.h" 48 #include "net/base/net_errors.h"
47 #include "net/http/http_util.h" 49 #include "net/http/http_util.h"
48 #include "ppapi/c/pp_bool.h" 50 #include "ppapi/c/pp_bool.h"
49 #include "ppapi/c/private/pp_file_handle.h" 51 #include "ppapi/c/private/pp_file_handle.h"
50 #include "ppapi/shared_impl/ppapi_globals.h" 52 #include "ppapi/shared_impl/ppapi_globals.h"
51 #include "ppapi/shared_impl/ppapi_permissions.h" 53 #include "ppapi/shared_impl/ppapi_permissions.h"
52 #include "ppapi/shared_impl/ppapi_preferences.h" 54 #include "ppapi/shared_impl/ppapi_preferences.h"
53 #include "ppapi/shared_impl/var.h" 55 #include "ppapi/shared_impl/var.h"
(...skipping 12 matching lines...) Expand all
66 68
67 namespace nacl { 69 namespace nacl {
68 namespace { 70 namespace {
69 71
70 // The pseudo-architecture used to indicate portable native client. 72 // The pseudo-architecture used to indicate portable native client.
71 const char* const kPortableArch = "portable"; 73 const char* const kPortableArch = "portable";
72 74
73 // The base URL for resources used by the PNaCl translator processes. 75 // The base URL for resources used by the PNaCl translator processes.
74 const char* kPNaClTranslatorBaseUrl = "chrome://pnacl-translator/"; 76 const char* kPNaClTranslatorBaseUrl = "chrome://pnacl-translator/";
75 77
78 // The maximum number of resource files DownloadNexe() can open.
79 const size_t kMaxPreOpenResourceFiles = 2;
Mark Seaborn 2015/02/09 04:48:34 Why so low? I thought your aim was to pass more t
Yusuke Sato 2015/02/11 05:54:21 This is currently 2 because kMaxDescriptorsPerMess
Mark Seaborn 2015/02/12 03:57:33 OK, so the test is still covering the fast path.
Yusuke Sato 2015/02/13 23:01:16 Done.
80
81 #if defined(OS_POSIX)
82 // On POSIX platforms, the maximum number of files a process can pass to
83 // another is limited to kMaxDescriptorsPerMessage. Since the browser process
84 // may use up to 5 descriptors for passing non-resource files when creating
85 // the NaCl plugin process, kMaxPreOpenResourceFiles must be smaller than or
86 // equal to (IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage - 5).
87 COMPILE_ASSERT(kMaxPreOpenResourceFiles <=
88 IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage - 5,
89 k_max_pre_open_resource_files_too_large);
90 #endif
91
76 base::LazyInstance<scoped_refptr<PnaclTranslationResourceHost> > 92 base::LazyInstance<scoped_refptr<PnaclTranslationResourceHost> >
77 g_pnacl_resource_host = LAZY_INSTANCE_INITIALIZER; 93 g_pnacl_resource_host = LAZY_INSTANCE_INITIALIZER;
78 94
79 bool InitializePnaclResourceHost() { 95 bool InitializePnaclResourceHost() {
80 // Must run on the main thread. 96 // Must run on the main thread.
81 content::RenderThread* render_thread = content::RenderThread::Get(); 97 content::RenderThread* render_thread = content::RenderThread::Get();
82 if (!render_thread) 98 if (!render_thread)
83 return false; 99 return false;
84 if (!g_pnacl_resource_host.Get().get()) { 100 if (!g_pnacl_resource_host.Get().get()) {
85 g_pnacl_resource_host.Get() = new PnaclTranslationResourceHost( 101 g_pnacl_resource_host.Get() = new PnaclTranslationResourceHost(
(...skipping 15 matching lines...) Expand all
101 }; 117 };
102 118
103 class NaClPluginInstance { 119 class NaClPluginInstance {
104 public: 120 public:
105 NaClPluginInstance(PP_Instance instance): 121 NaClPluginInstance(PP_Instance instance):
106 nexe_load_manager(instance), pexe_size(0) {} 122 nexe_load_manager(instance), pexe_size(0) {}
107 123
108 NexeLoadManager nexe_load_manager; 124 NexeLoadManager nexe_load_manager;
109 scoped_ptr<JsonManifest> json_manifest; 125 scoped_ptr<JsonManifest> json_manifest;
110 scoped_ptr<InstanceInfo> instance_info; 126 scoped_ptr<InstanceInfo> instance_info;
127 std::vector<NaClLaunchParams::ResourceFileInfo> resource_files_info;
Mark Seaborn 2015/02/09 04:48:34 If I read this right, NaClLaunchParams::ResourceFi
Yusuke Sato 2015/02/11 05:54:21 You're right. The IPC::PlatformFileForTransit hand
111 128
112 // When translation is complete, this records the size of the pexe in 129 // When translation is complete, this records the size of the pexe in
113 // bytes so that it can be reported in a later load event. 130 // bytes so that it can be reported in a later load event.
114 uint64_t pexe_size; 131 uint64_t pexe_size;
115 }; 132 };
116 133
117 typedef base::ScopedPtrHashMap<PP_Instance, NaClPluginInstance> InstanceMap; 134 typedef base::ScopedPtrHashMap<PP_Instance, NaClPluginInstance> InstanceMap;
118 base::LazyInstance<InstanceMap> g_instance_map = LAZY_INSTANCE_INITIALIZER; 135 base::LazyInstance<InstanceMap> g_instance_map = LAZY_INSTANCE_INITIALIZER;
119 136
120 NaClPluginInstance* GetNaClPluginInstance(PP_Instance instance) { 137 NaClPluginInstance* GetNaClPluginInstance(PP_Instance instance) {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 // must also check on the trusted side of the proxy. 411 // must also check on the trusted side of the proxy.
395 if (load_manager->DevInterfacesEnabled()) 412 if (load_manager->DevInterfacesEnabled())
396 perm_bits |= ppapi::PERMISSION_DEV; 413 perm_bits |= ppapi::PERMISSION_DEV;
397 instance_info.permissions = 414 instance_info.permissions =
398 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); 415 ppapi::PpapiPermissions::GetForCommandLine(perm_bits);
399 std::string error_message_string; 416 std::string error_message_string;
400 NaClLaunchResult launch_result; 417 NaClLaunchResult launch_result;
401 418
402 IPC::PlatformFileForTransit nexe_for_transit = 419 IPC::PlatformFileForTransit nexe_for_transit =
403 IPC::InvalidPlatformFileForTransit(); 420 IPC::InvalidPlatformFileForTransit();
421
422 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance);
404 #if defined(OS_POSIX) 423 #if defined(OS_POSIX)
405 if (nexe_file_info->handle != PP_kInvalidFileHandle) 424 if (nexe_file_info->handle != PP_kInvalidFileHandle)
406 nexe_for_transit = base::FileDescriptor(nexe_file_info->handle, true); 425 nexe_for_transit = base::FileDescriptor(nexe_file_info->handle, true);
426 const std::vector<NaClLaunchParams::ResourceFileInfo>& resource_files_info =
427 nacl_plugin_instance->resource_files_info;
Mark Seaborn 2015/02/09 04:48:34 Shouldn't nacl_plugin_instance->resource_files_inf
Yusuke Sato 2015/02/11 05:54:21 Done.
407 #elif defined(OS_WIN) 428 #elif defined(OS_WIN)
408 // Duplicate the handle on the browser side instead of the renderer. 429 // Duplicate the handle on the browser side instead of the renderer.
409 // This is because BrokerGetFileForProcess isn't part of content/public, and 430 // This is because BrokerGetFileForProcess isn't part of content/public, and
410 // it's simpler to do the duplication in the browser anyway. 431 // it's simpler to do the duplication in the browser anyway.
411 nexe_for_transit = nexe_file_info->handle; 432 nexe_for_transit = nexe_file_info->handle;
433 // TODO(yusukes): Support pre-opening resource files.
Mark Seaborn 2015/02/09 04:48:34 Add "on Windows"?
Yusuke Sato 2015/02/11 05:54:21 Done.
434 std::vector<NaClLaunchParams::ResourceFileInfo> resource_files_info; // empty
412 #else 435 #else
413 #error Unsupported target platform. 436 #error Unsupported target platform.
414 #endif 437 #endif
415 if (!sender->Send(new NaClHostMsg_LaunchNaCl( 438 if (!sender->Send(new NaClHostMsg_LaunchNaCl(
416 NaClLaunchParams( 439 NaClLaunchParams(
417 instance_info.url.spec(), 440 instance_info.url.spec(),
418 nexe_for_transit, 441 nexe_for_transit,
419 nexe_file_info->token_lo, 442 nexe_file_info->token_lo,
420 nexe_file_info->token_hi, 443 nexe_file_info->token_hi,
444 resource_files_info,
421 routing_id, 445 routing_id,
422 perm_bits, 446 perm_bits,
423 PP_ToBool(uses_nonsfi_mode), 447 PP_ToBool(uses_nonsfi_mode),
424 process_type), 448 process_type),
425 &launch_result, 449 &launch_result,
426 &error_message_string))) { 450 &error_message_string))) {
427 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( 451 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
428 FROM_HERE, 452 FROM_HERE,
429 base::Bind(callback.func, callback.user_data, 453 base::Bind(callback.func, callback.user_data,
430 static_cast<int32_t>(PP_ERROR_FAILED))); 454 static_cast<int32_t>(PP_ERROR_FAILED)));
(...skipping 13 matching lines...) Expand all
444 base::Bind(callback.func, callback.user_data, 468 base::Bind(callback.func, callback.user_data,
445 static_cast<int32_t>(PP_ERROR_FAILED))); 469 static_cast<int32_t>(PP_ERROR_FAILED)));
446 return; 470 return;
447 } 471 }
448 result_socket = launch_result.imc_channel_handle; 472 result_socket = launch_result.imc_channel_handle;
449 instance_info.channel_handle = launch_result.ppapi_ipc_channel_handle; 473 instance_info.channel_handle = launch_result.ppapi_ipc_channel_handle;
450 instance_info.plugin_pid = launch_result.plugin_pid; 474 instance_info.plugin_pid = launch_result.plugin_pid;
451 instance_info.plugin_child_id = launch_result.plugin_child_id; 475 instance_info.plugin_child_id = launch_result.plugin_child_id;
452 476
453 // Don't save instance_info if channel handle is invalid. 477 // Don't save instance_info if channel handle is invalid.
454 if (IsValidChannelHandle(instance_info.channel_handle)) { 478 if (IsValidChannelHandle(instance_info.channel_handle))
455 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance);
456 nacl_plugin_instance->instance_info.reset(new InstanceInfo(instance_info)); 479 nacl_plugin_instance->instance_info.reset(new InstanceInfo(instance_info));
457 }
458 480
459 *(static_cast<NaClHandle*>(imc_handle)) = ToNativeHandle(result_socket); 481 *(static_cast<NaClHandle*>(imc_handle)) = ToNativeHandle(result_socket);
460 482
461 // Store the crash information shared memory handle. 483 // Store the crash information shared memory handle.
462 load_manager->set_crash_info_shmem_handle( 484 load_manager->set_crash_info_shmem_handle(
463 launch_result.crash_info_shmem_handle); 485 launch_result.crash_info_shmem_handle);
464 486
465 // Create the trusted plugin channel. 487 // Create the trusted plugin channel.
466 if (IsValidChannelHandle(launch_result.trusted_ipc_channel_handle)) { 488 if (IsValidChannelHandle(launch_result.trusted_ipc_channel_handle)) {
467 bool report_exit_status = PP_ToBool(main_service_runtime); 489 bool report_exit_status = PP_ToBool(main_service_runtime);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 replace_pos = r.find_first_not_of(white_list); 598 replace_pos = r.find_first_not_of(white_list);
577 } 599 }
578 return r; 600 return r;
579 } 601 }
580 602
581 PP_FileHandle GetReadonlyPnaclFd(const char* url, 603 PP_FileHandle GetReadonlyPnaclFd(const char* url,
582 bool is_executable, 604 bool is_executable,
583 uint64_t* nonce_lo, 605 uint64_t* nonce_lo,
584 uint64_t* nonce_hi) { 606 uint64_t* nonce_hi) {
585 std::string filename = PnaclComponentURLToFilename(url); 607 std::string filename = PnaclComponentURLToFilename(url);
586 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit();
587 IPC::Sender* sender = content::RenderThread::Get(); 608 IPC::Sender* sender = content::RenderThread::Get();
609 NaClFileInfo file_info;
588 DCHECK(sender); 610 DCHECK(sender);
589 if (!sender->Send(new NaClHostMsg_GetReadonlyPnaclFD( 611 if (!sender->Send(new NaClHostMsg_GetReadonlyPnaclFD(
590 std::string(filename), is_executable, 612 std::string(filename), is_executable, &file_info))) {
591 &out_fd, nonce_lo, nonce_hi))) {
592 return PP_kInvalidFileHandle; 613 return PP_kInvalidFileHandle;
593 } 614 }
594 if (out_fd == IPC::InvalidPlatformFileForTransit()) { 615 if (file_info.file == IPC::InvalidPlatformFileForTransit()) {
595 return PP_kInvalidFileHandle; 616 return PP_kInvalidFileHandle;
596 } 617 }
597 return IPC::PlatformFileForTransitToPlatformFile(out_fd); 618 *nonce_lo = file_info.file_token_lo;
619 *nonce_hi = file_info.file_token_hi;
620 return IPC::PlatformFileForTransitToPlatformFile(file_info.file);
598 } 621 }
599 622
600 void GetReadExecPnaclFd(const char* url, 623 void GetReadExecPnaclFd(const char* url,
601 PP_NaClFileInfo* out_file_info) { 624 PP_NaClFileInfo* out_file_info) {
602 *out_file_info = kInvalidNaClFileInfo; 625 *out_file_info = kInvalidNaClFileInfo;
603 out_file_info->handle = GetReadonlyPnaclFd(url, true /* is_executable */, 626 out_file_info->handle = GetReadonlyPnaclFd(url, true /* is_executable */,
604 &out_file_info->token_lo, 627 &out_file_info->token_lo,
605 &out_file_info->token_hi); 628 &out_file_info->token_hi);
606 } 629 }
607 630
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 return; 723 return;
701 g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success); 724 g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success);
702 725
703 // Record the pexe size for reporting in a later load event. 726 // Record the pexe size for reporting in a later load event.
704 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); 727 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance);
705 if (nacl_plugin_instance) { 728 if (nacl_plugin_instance) {
706 nacl_plugin_instance->pexe_size = pexe_size; 729 nacl_plugin_instance->pexe_size = pexe_size;
707 } 730 }
708 } 731 }
709 732
710 PP_FileHandle OpenNaClExecutable(PP_Instance instance, 733 bool OpenNaClResources(
711 const char* file_url, 734 PP_Instance instance,
712 uint64_t* nonce_lo, 735 const std::vector<std::string>& resource_file_urls,
713 uint64_t* nonce_hi) { 736 std::vector<NaClFileInfo>* out_resource_file_handles) {
714 // Fast path only works for installed file URLs. 737 DCHECK(out_resource_file_handles);
715 GURL gurl(file_url); 738 if (resource_file_urls.empty())
716 if (!gurl.SchemeIs("chrome-extension")) 739 return false;
717 return PP_kInvalidFileHandle;
718 740
719 NexeLoadManager* load_manager = GetNexeLoadManager(instance); 741 NexeLoadManager* load_manager = GetNexeLoadManager(instance);
720 DCHECK(load_manager); 742 DCHECK(load_manager);
721 if (!load_manager) 743 if (!load_manager)
722 return PP_kInvalidFileHandle; 744 return PP_kInvalidFileHandle;
723 745
724 content::PepperPluginInstance* plugin_instance = 746 content::PepperPluginInstance* plugin_instance =
725 content::PepperPluginInstance::Get(instance); 747 content::PepperPluginInstance::Get(instance);
726 if (!plugin_instance) 748 if (!plugin_instance)
727 return PP_kInvalidFileHandle; 749 return false;
728 // IMPORTANT: Make sure the document can request the given URL. If we don't
729 // check, a malicious app could probe the extension system. This enforces a
730 // same-origin policy which prevents the app from requesting resources from
731 // another app.
732 blink::WebSecurityOrigin security_origin = 750 blink::WebSecurityOrigin security_origin =
733 plugin_instance->GetContainer()->element().document().securityOrigin(); 751 plugin_instance->GetContainer()->element().document().securityOrigin();
734 if (!security_origin.canRequest(gurl))
735 return PP_kInvalidFileHandle;
736
737 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit();
738 IPC::Sender* sender = content::RenderThread::Get(); 752 IPC::Sender* sender = content::RenderThread::Get();
739 DCHECK(sender); 753 DCHECK(sender);
740 *nonce_lo = 0; 754
741 *nonce_hi = 0; 755 std::vector<GURL> resource_gurls;
742 base::FilePath file_path; 756 for (size_t i = 0; i < resource_file_urls.size(); ++i) {
743 if (!sender->Send( 757 resource_gurls.push_back(GURL(resource_file_urls[i]));
744 new NaClHostMsg_OpenNaClExecutable(GetRoutingID(instance),
745 GURL(file_url),
746 !load_manager->nonsfi(),
747 &out_fd,
748 nonce_lo,
749 nonce_hi))) {
750 return PP_kInvalidFileHandle;
751 } 758 }
752 759
753 if (out_fd == IPC::InvalidPlatformFileForTransit()) 760 for (size_t i = 0; i < resource_gurls.size(); ++i) {
754 return PP_kInvalidFileHandle; 761 const GURL& gurl = resource_gurls[i];
762 // Fast path only works for installed file URLs.
763 if (!gurl.SchemeIs("chrome-extension"))
764 return false;
765 // IMPORTANT: Make sure the document can request the given URL. If we don't
766 // check, a malicious app could probe the extension system. This enforces a
767 // same-origin policy which prevents the app from requesting resources from
768 // another app.
769 if (!security_origin.canRequest(gurl))
770 return false;
771 }
755 772
756 return IPC::PlatformFileForTransitToPlatformFile(out_fd); 773 if (!sender->Send(new NaClHostMsg_OpenNaClResources(
774 GetRoutingID(instance),
775 resource_gurls,
776 !load_manager->nonsfi(),
777 out_resource_file_handles))) {
778 return false;
779 }
780
781 if (out_resource_file_handles->empty() ||
782 (out_resource_file_handles->at(0).file ==
783 IPC::InvalidPlatformFileForTransit())) {
784 DLOG(ERROR) << "Could not open the main nexe: " << resource_gurls[0];
785 return false;
786 }
787 return true;
757 } 788 }
758 789
759 void DispatchEvent(PP_Instance instance, 790 void DispatchEvent(PP_Instance instance,
760 PP_NaClEventType event_type, 791 PP_NaClEventType event_type,
761 const char* resource_url, 792 const char* resource_url,
762 PP_Bool length_is_computable, 793 PP_Bool length_is_computable,
763 uint64_t loaded_bytes, 794 uint64_t loaded_bytes,
764 uint64_t total_bytes) { 795 uint64_t total_bytes) {
765 ProgressEvent event(event_type, 796 ProgressEvent event(event_type,
766 resource_url, 797 resource_url,
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 }; 1235 };
1205 1236
1206 void DownloadNexeCompletion(const DownloadNexeRequest& request, 1237 void DownloadNexeCompletion(const DownloadNexeRequest& request,
1207 PP_NaClFileInfo* out_file_info, 1238 PP_NaClFileInfo* out_file_info,
1208 FileDownloader::Status status, 1239 FileDownloader::Status status,
1209 base::File target_file, 1240 base::File target_file,
1210 int http_status); 1241 int http_status);
1211 1242
1212 void DownloadNexe(PP_Instance instance, 1243 void DownloadNexe(PP_Instance instance,
1213 const char* url, 1244 const char* url,
1245 PP_Bool download_resource_files,
1214 PP_NaClFileInfo* out_file_info, 1246 PP_NaClFileInfo* out_file_info,
1215 PP_CompletionCallback callback) { 1247 PP_CompletionCallback callback) {
1216 CHECK(url); 1248 CHECK(url);
1217 CHECK(out_file_info); 1249 CHECK(out_file_info);
1218 DownloadNexeRequest request; 1250 DownloadNexeRequest request;
1219 request.instance = instance; 1251 request.instance = instance;
1220 request.url = url; 1252 request.url = url;
1221 request.callback = callback; 1253 request.callback = callback;
1222 request.start_time = base::Time::Now(); 1254 request.start_time = base::Time::Now();
1223 1255
1256 std::vector<std::string> file_urls;
1257 file_urls.push_back(url); // the main nexe must be the first element.
1258
1259 std::vector<
1260 std::pair<std::string /*url*/, std::string /*key*/> > resource_files;
1261 if (download_resource_files) {
1262 JsonManifest* manifest = GetJsonManifest(instance);
1263 if (manifest)
1264 manifest->GetFiles(&resource_files);
1265 if (resource_files.size() > kMaxPreOpenResourceFiles)
1266 resource_files.resize(kMaxPreOpenResourceFiles);
1267 for (size_t i = 0; i < resource_files.size(); ++i) {
1268 file_urls.push_back(resource_files[i].first);
1269 }
1270 }
1271
1224 // Try the fast path for retrieving the file first. 1272 // Try the fast path for retrieving the file first.
1225 PP_FileHandle handle = OpenNaClExecutable(instance, 1273 std::vector<NaClFileInfo> file_handles;
1226 url, 1274 if (OpenNaClResources(instance, file_urls, &file_handles)) {
1227 &out_file_info->token_lo, 1275 DCHECK(!file_handles.empty());
1228 &out_file_info->token_hi); 1276 out_file_info->handle =
1229 if (handle != PP_kInvalidFileHandle) { 1277 IPC::PlatformFileForTransitToPlatformFile(file_handles[0].file);
1278 out_file_info->token_lo = file_handles[0].file_token_lo;
1279 out_file_info->token_hi = file_handles[0].file_token_hi;
1280 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance);
1281 for (size_t i = 1; i < file_handles.size(); ++i) {
1282 std::string key = resource_files[i - 1].second;
1283 nacl_plugin_instance->resource_files_info.push_back(
1284 NaClLaunchParams::ResourceFileInfo(file_handles[i], key));
1285 }
1230 DownloadNexeCompletion(request, 1286 DownloadNexeCompletion(request,
1231 out_file_info, 1287 out_file_info,
1232 FileDownloader::SUCCESS, 1288 FileDownloader::SUCCESS,
1233 base::File(handle), 1289 base::File(out_file_info->handle),
1234 200); 1290 200);
1235 return; 1291 return;
1236 } 1292 }
1237 1293
1238 // The fast path didn't work, we'll fetch the file using URLLoader and write 1294 // The fast path didn't work, we'll fetch the file using URLLoader and write
1239 // it to local storage. 1295 // it to local storage.
1240 base::File target_file(CreateTemporaryFile(instance)); 1296 base::File target_file(CreateTemporaryFile(instance));
1241 GURL gurl(url); 1297 GURL gurl(url);
1242 1298
1299 // On the slow path, do not retry to pre-open the resource files.
1243 content::PepperPluginInstance* plugin_instance = 1300 content::PepperPluginInstance* plugin_instance =
1244 content::PepperPluginInstance::Get(instance); 1301 content::PepperPluginInstance::Get(instance);
1245 if (!plugin_instance) { 1302 if (!plugin_instance) {
1246 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( 1303 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
1247 FROM_HERE, 1304 FROM_HERE,
1248 base::Bind(callback.func, callback.user_data, 1305 base::Bind(callback.func, callback.user_data,
1249 static_cast<int32_t>(PP_ERROR_FAILED))); 1306 static_cast<int32_t>(PP_ERROR_FAILED)));
1250 } 1307 }
1251 const blink::WebDocument& document = 1308 const blink::WebDocument& document =
1252 plugin_instance->GetContainer()->element().document(); 1309 plugin_instance->GetContainer()->element().document();
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1368 if (!test_gurl.is_valid()) { 1425 if (!test_gurl.is_valid()) {
1369 base::MessageLoop::current()->PostTask( 1426 base::MessageLoop::current()->PostTask(
1370 FROM_HERE, 1427 FROM_HERE,
1371 base::Bind(callback, 1428 base::Bind(callback,
1372 static_cast<int32_t>(PP_ERROR_FAILED), 1429 static_cast<int32_t>(PP_ERROR_FAILED),
1373 kInvalidNaClFileInfo)); 1430 kInvalidNaClFileInfo));
1374 return; 1431 return;
1375 } 1432 }
1376 1433
1377 // Try the fast path for retrieving the file first. 1434 // Try the fast path for retrieving the file first.
1378 uint64_t file_token_lo = 0; 1435 std::vector<std::string> file_urls;
1379 uint64_t file_token_hi = 0; 1436 file_urls.push_back(url);
1380 PP_FileHandle file_handle = OpenNaClExecutable(instance, 1437 std::vector<NaClFileInfo> out_handles;
1381 url.c_str(), 1438 if (OpenNaClResources(instance, file_urls, &out_handles)) {
Mark Seaborn 2015/02/09 04:48:35 I think there's a potential performance regression
Yusuke Sato 2015/02/11 05:54:21 I wasn't aware that HTTP(S) URL was allowed in "fi
1382 &file_token_lo,
1383 &file_token_hi);
1384 if (file_handle != PP_kInvalidFileHandle) {
1385 PP_NaClFileInfo file_info; 1439 PP_NaClFileInfo file_info;
1386 file_info.handle = file_handle; 1440 file_info.handle =
1387 file_info.token_lo = file_token_lo; 1441 IPC::PlatformFileForTransitToPlatformFile(out_handles[0].file);
1388 file_info.token_hi = file_token_hi; 1442 file_info.token_lo = out_handles[0].file_token_lo;
1443 file_info.token_hi = out_handles[0].file_token_hi;
1389 base::MessageLoop::current()->PostTask( 1444 base::MessageLoop::current()->PostTask(
1390 FROM_HERE, 1445 FROM_HERE,
1391 base::Bind(callback, static_cast<int32_t>(PP_OK), file_info)); 1446 base::Bind(callback, static_cast<int32_t>(PP_OK), file_info));
1392 return; 1447 return;
1393 } 1448 }
1394 1449
1395 // The fast path didn't work, we'll fetch the file using URLLoader and write 1450 // The fast path didn't work, we'll fetch the file using URLLoader and write
1396 // it to local storage. 1451 // it to local storage.
1397 base::File target_file(CreateTemporaryFile(instance)); 1452 base::File target_file(CreateTemporaryFile(instance));
1398 GURL gurl(url); 1453 GURL gurl(url);
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 &StreamPexe 1706 &StreamPexe
1652 }; 1707 };
1653 1708
1654 } // namespace 1709 } // namespace
1655 1710
1656 const PPB_NaCl_Private* GetNaClPrivateInterface() { 1711 const PPB_NaCl_Private* GetNaClPrivateInterface() {
1657 return &nacl_interface; 1712 return &nacl_interface;
1658 } 1713 }
1659 1714
1660 } // namespace nacl 1715 } // namespace nacl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698