Chromium Code Reviews| Index: components/nacl/renderer/ppb_nacl_private_impl.cc |
| diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc |
| index 3926b440403cc1760c424b709db4a791dfa4fdfb..04a75e96a6be42bb5c4d9bde40417203a3043df6 100644 |
| --- a/components/nacl/renderer/ppb_nacl_private_impl.cc |
| +++ b/components/nacl/renderer/ppb_nacl_private_impl.cc |
| @@ -20,6 +20,7 @@ |
| #include "components/nacl/common/nacl_messages.h" |
| #include "components/nacl/common/nacl_switches.h" |
| #include "components/nacl/common/nacl_types.h" |
| +#include "components/nacl/renderer/file_downloader.h" |
| #include "components/nacl/renderer/histogram.h" |
| #include "components/nacl/renderer/json_manifest.h" |
| #include "components/nacl/renderer/manifest_downloader.h" |
| @@ -251,6 +252,43 @@ class ManifestServiceProxy : public ManifestServiceChannel::Delegate { |
| DISALLOW_COPY_AND_ASSIGN(ManifestServiceProxy); |
| }; |
| +blink::WebURLLoader* CreateWebURLLoader(PP_Instance instance, |
| + const GURL& gurl) { |
| + content::PepperPluginInstance* plugin_instance = |
| + content::PepperPluginInstance::Get(instance); |
| + blink::WebURLLoaderOptions options; |
| + options.untrustedHTTP = true; |
| + |
| + blink::WebSecurityOrigin security_origin = |
| + plugin_instance->GetContainer()->element().document().securityOrigin(); |
|
bbudge
2014/05/12 22:32:06
This function and the following one could be simpl
teravest
2014/05/13 17:05:32
Done.
|
| + // Options settings here follow the original behavior in the trusted |
| + // plugin and PepperURLLoaderHost. |
| + if (security_origin.canRequest(gurl)) { |
| + options.allowCredentials = true; |
| + } else { |
| + // Allow CORS. |
| + options.crossOriginRequestPolicy = |
| + blink::WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl; |
| + } |
| + |
| + blink::WebFrame* frame = |
| + plugin_instance->GetContainer()->element().document().frame(); |
| + return frame->createAssociatedURLLoader(options); |
| +} |
| + |
| +blink::WebURLRequest CreateWebURLRequest(PP_Instance instance, |
| + const GURL& gurl) { |
| + content::PepperPluginInstance* plugin_instance = |
| + content::PepperPluginInstance::Get(instance); |
| + blink::WebFrame* frame = |
| + plugin_instance->GetContainer()->element().document().frame(); |
| + blink::WebURLRequest request; |
| + request.initialize(); |
| + request.setURL(gurl); |
| + request.setFirstPartyForCookies(frame->document().firstPartyForCookies()); |
| + return request; |
| +} |
| + |
| // Launch NaCl's sel_ldr process. |
| void LaunchSelLdr(PP_Instance instance, |
| const char* alleged_url, |
| @@ -669,24 +707,6 @@ void DispatchEvent(PP_Instance instance, |
| DispatchProgressEvent(instance, event); |
| } |
| -void NexeFileDidOpen(PP_Instance instance, |
| - int32_t pp_error, |
| - int32_t fd, |
| - int32_t http_status, |
| - int64_t nexe_bytes_read, |
| - const char* url, |
| - int64_t time_since_open) { |
| - NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
| - if (load_manager) { |
| - load_manager->NexeFileDidOpen(pp_error, |
| - fd, |
| - http_status, |
| - nexe_bytes_read, |
| - url, |
| - time_since_open); |
| - } |
| -} |
| - |
| void ReportLoadSuccess(PP_Instance instance, |
| const char* url, |
| uint64_t loaded_bytes, |
| @@ -906,31 +926,8 @@ void DownloadManifestToBuffer(PP_Instance instance, |
| } |
| const GURL& gurl = load_manager->manifest_base_url(); |
| - |
| - content::PepperPluginInstance* plugin_instance = |
| - content::PepperPluginInstance::Get(instance); |
| - blink::WebURLLoaderOptions options; |
| - options.untrustedHTTP = true; |
| - |
| - blink::WebSecurityOrigin security_origin = |
| - plugin_instance->GetContainer()->element().document().securityOrigin(); |
| - // Options settings here follow the original behavior in the trusted |
| - // plugin and PepperURLLoaderHost. |
| - if (security_origin.canRequest(gurl)) { |
| - options.allowCredentials = true; |
| - } else { |
| - // Allow CORS. |
| - options.crossOriginRequestPolicy = |
| - blink::WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl; |
| - } |
| - |
| - blink::WebFrame* frame = |
| - plugin_instance->GetContainer()->element().document().frame(); |
| - blink::WebURLLoader* url_loader = frame->createAssociatedURLLoader(options); |
| - blink::WebURLRequest request; |
| - request.initialize(); |
| - request.setURL(gurl); |
| - request.setFirstPartyForCookies(frame->document().firstPartyForCookies()); |
| + blink::WebURLLoader* url_loader = CreateWebURLLoader(instance, gurl); |
| + blink::WebURLRequest request = CreateWebURLRequest(instance, gurl); |
| // ManifestDownloader deletes itself after invoking the callback. |
| ManifestDownloader* client = new ManifestDownloader( |
| @@ -1251,6 +1248,148 @@ void PostMessageToJavaScript(PP_Instance instance, const char* message) { |
| std::string(message))); |
| } |
| +// Encapsulates some of the state for a call to DownloadNexe to prevent |
| +// argument lists from getting too long. |
| +struct DownloadNexeRequest { |
| + PP_Instance instance; |
| + const char* url; |
| + PP_CompletionCallback callback; |
| + base::Time start_time; |
| +}; |
| + |
| +class DownloadNexeProgressTracker { |
|
bbudge
2014/05/12 22:32:06
I don't see where this is used. Also, it doesn't s
teravest
2014/05/13 17:05:32
Thanks for pointing that out. I'd completely forgo
|
| + public: |
| + void ReportProgress(const std::string& url, |
| + int64_t total_bytes_received, |
| + int64_t total_bytes_to_be_received) { |
| + base::Time now = base::Time::Now(); |
| + if (now - last_event_ > base::TimeDelta::FromMilliseconds(10)) { |
| + // Actually dispatch the progress event. |
| + last_event_ = now; |
| + } |
| + } |
| + private: |
| + base::Time last_event_; |
| +}; |
| + |
| +void DownloadNexeProgress(PP_Instance instance, |
| + const std::string& url, |
| + int64_t total_bytes_received, |
| + int64_t total_bytes_to_be_received); |
| + |
| +void DownloadNexeCompletion(const DownloadNexeRequest& request, |
| + blink::WebURLLoader* loader, |
| + base::PlatformFile target_file, |
| + PP_FileHandle* out_handle, |
| + FileDownloader::Status status, |
| + int http_status); |
| + |
| +void DownloadNexe(PP_Instance instance, |
| + const char* url, |
| + PP_FileHandle* out_handle, |
| + PP_CompletionCallback callback) { |
| + CHECK(url); |
| + CHECK(out_handle); |
| + DownloadNexeRequest request; |
| + request.instance = instance; |
| + request.url = url; |
| + request.callback = callback; |
| + request.start_time = base::Time::Now(); |
| + |
| + // Try the fast path for retrieving the file first. |
| + uint64_t file_token_lo = 0; |
| + uint64_t file_token_hi = 0; |
| + PP_FileHandle file_handle = OpenNaClExecutable(instance, |
| + url, |
| + &file_token_lo, |
| + &file_token_hi); |
| + |
| + // We shouldn't hit this if the file URL is in an installed app. |
|
bbudge
2014/05/12 22:32:06
comment seems wrong.
teravest
2014/05/13 17:05:32
Removed.
|
| + if (file_handle != PP_kInvalidFileHandle) { |
| + DownloadNexeCompletion(request, NULL, file_handle, out_handle, |
| + FileDownloader::SUCCESS, 200); |
| + return; |
| + } |
| + |
| + // The fast path didn't work, we'll fetch the file using URLLoader and write |
| + // it to local storage. |
| + base::PlatformFile target_file = CreateTemporaryFile(instance); |
| + GURL gurl(url); |
| + blink::WebURLLoader* url_loader = CreateWebURLLoader(instance, gurl); |
|
bbudge
2014/05/12 22:32:06
Now that we're in Chrome-land, can we use scoped_p
teravest
2014/05/13 17:05:32
Done.
|
| + blink::WebURLRequest url_request = CreateWebURLRequest(instance, gurl); |
| + |
| + // FileDownloader deletes itself after invoking the callback. |
| + FileDownloader* client = new FileDownloader( |
|
bbudge
2014/05/12 22:32:06
'client' is a slightly confusing name.
teravest
2014/05/13 17:05:32
Changed to file_downloader
|
| + target_file, |
| + base::Bind(&DownloadNexeCompletion, request, url_loader, target_file, |
| + out_handle), |
| + base::Bind(&DownloadNexeProgress, instance, url)); |
| + url_loader->loadAsynchronously(url_request, client); |
| +} |
| + |
| +void DownloadNexeProgress(PP_Instance instance, |
| + const std::string& url, |
| + int64_t total_bytes_received, |
| + int64_t total_bytes_to_be_received) { |
| + ProgressEvent event(PP_NACL_EVENT_PROGRESS, |
| + url, |
| + total_bytes_to_be_received >= 0, |
| + total_bytes_received, |
| + total_bytes_to_be_received); |
| + DispatchProgressEvent(instance, event); |
|
bbudge
2014/05/12 22:32:06
Might be a little more readable if you create the
teravest
2014/05/13 17:05:32
Done.
|
| +} |
| + |
| +void DownloadNexeCompletion(const DownloadNexeRequest& request, |
| + blink::WebURLLoader* loader, |
|
bbudge
2014/05/12 22:32:06
scoped_ptr<blink::WebURLLoader>?
teravest
2014/05/13 17:05:32
Done.
|
| + base::PlatformFile target_file, |
| + PP_FileHandle* out_handle, |
| + FileDownloader::Status status, |
| + int http_status) { |
| + int32_t pp_error; |
| + switch (status) { |
| + case FileDownloader::SUCCESS: |
| + *out_handle = target_file; |
| + pp_error = PP_OK; |
| + break; |
| + case FileDownloader::ACCESS_DENIED: |
| + pp_error = PP_ERROR_NOACCESS; |
| + break; |
| + case FileDownloader::FAILED: |
| + pp_error = PP_ERROR_FAILED; |
| + break; |
| + default: |
| + NOTREACHED(); |
| + return; |
| + } |
| + delete loader; |
| + |
| + int64_t bytes_read = -1; |
| + if (pp_error == PP_OK && target_file != base::kInvalidPlatformFileValue) { |
| + base::PlatformFileInfo info; |
| + if (GetPlatformFileInfo(target_file, &info)) |
| + bytes_read = info.size; |
| + } |
| + |
| + if (bytes_read == -1) { |
| + base::ClosePlatformFile(target_file); |
| + pp_error = PP_ERROR_FAILED; |
| + } |
| + |
| + base::TimeDelta download_time = base::Time::Now() - request.start_time; |
| + |
| + NexeLoadManager* load_manager = GetNexeLoadManager(request.instance); |
| + if (load_manager) { |
| + load_manager->NexeFileDidOpen(pp_error, |
| + target_file, |
| + http_status, |
| + bytes_read, |
| + request.url, |
| + download_time); |
| + } |
| + |
| + request.callback.func(request.callback.user_data, pp_error); |
| +} |
| + |
| const PPB_NaCl_Private nacl_interface = { |
| &LaunchSelLdr, |
| &StartPpapiProxy, |
| @@ -1265,7 +1404,6 @@ const PPB_NaCl_Private nacl_interface = { |
| &ReportTranslationFinished, |
| &OpenNaClExecutable, |
| &DispatchEvent, |
| - &NexeFileDidOpen, |
| &ReportLoadSuccess, |
| &ReportLoadError, |
| &ReportLoadAbort, |
| @@ -1298,7 +1436,8 @@ const PPB_NaCl_Private nacl_interface = { |
| &ManifestResolveKey, |
| &GetPNaClResourceInfo, |
| &GetCpuFeatureAttrs, |
| - &PostMessageToJavaScript |
| + &PostMessageToJavaScript, |
| + &DownloadNexe |
| }; |
| } // namespace |