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/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/rand_util.h" | 18 #include "base/rand_util.h" |
19 #include "components/nacl/common/nacl_host_messages.h" | 19 #include "components/nacl/common/nacl_host_messages.h" |
20 #include "components/nacl/common/nacl_messages.h" | 20 #include "components/nacl/common/nacl_messages.h" |
21 #include "components/nacl/common/nacl_switches.h" | 21 #include "components/nacl/common/nacl_switches.h" |
22 #include "components/nacl/common/nacl_types.h" | 22 #include "components/nacl/common/nacl_types.h" |
23 #include "components/nacl/renderer/file_downloader.h" | |
23 #include "components/nacl/renderer/histogram.h" | 24 #include "components/nacl/renderer/histogram.h" |
24 #include "components/nacl/renderer/json_manifest.h" | 25 #include "components/nacl/renderer/json_manifest.h" |
25 #include "components/nacl/renderer/manifest_downloader.h" | 26 #include "components/nacl/renderer/manifest_downloader.h" |
26 #include "components/nacl/renderer/manifest_service_channel.h" | 27 #include "components/nacl/renderer/manifest_service_channel.h" |
27 #include "components/nacl/renderer/nexe_load_manager.h" | 28 #include "components/nacl/renderer/nexe_load_manager.h" |
28 #include "components/nacl/renderer/pnacl_translation_resource_host.h" | 29 #include "components/nacl/renderer/pnacl_translation_resource_host.h" |
29 #include "components/nacl/renderer/progress_event.h" | 30 #include "components/nacl/renderer/progress_event.h" |
30 #include "components/nacl/renderer/sandbox_arch.h" | 31 #include "components/nacl/renderer/sandbox_arch.h" |
31 #include "components/nacl/renderer/trusted_plugin_channel.h" | 32 #include "components/nacl/renderer/trusted_plugin_channel.h" |
32 #include "content/public/common/content_client.h" | 33 #include "content/public/common/content_client.h" |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 bool result = PP_ToBool(manifest_service_.Quit(user_data_)); | 245 bool result = PP_ToBool(manifest_service_.Quit(user_data_)); |
245 DCHECK(!result); | 246 DCHECK(!result); |
246 user_data_ = NULL; | 247 user_data_ = NULL; |
247 } | 248 } |
248 | 249 |
249 PPP_ManifestService manifest_service_; | 250 PPP_ManifestService manifest_service_; |
250 void* user_data_; | 251 void* user_data_; |
251 DISALLOW_COPY_AND_ASSIGN(ManifestServiceProxy); | 252 DISALLOW_COPY_AND_ASSIGN(ManifestServiceProxy); |
252 }; | 253 }; |
253 | 254 |
255 blink::WebURLLoader* CreateWebURLLoader(PP_Instance instance, | |
256 const GURL& gurl) { | |
257 content::PepperPluginInstance* plugin_instance = | |
258 content::PepperPluginInstance::Get(instance); | |
259 blink::WebURLLoaderOptions options; | |
260 options.untrustedHTTP = true; | |
261 | |
262 blink::WebSecurityOrigin security_origin = | |
263 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.
| |
264 // Options settings here follow the original behavior in the trusted | |
265 // plugin and PepperURLLoaderHost. | |
266 if (security_origin.canRequest(gurl)) { | |
267 options.allowCredentials = true; | |
268 } else { | |
269 // Allow CORS. | |
270 options.crossOriginRequestPolicy = | |
271 blink::WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl; | |
272 } | |
273 | |
274 blink::WebFrame* frame = | |
275 plugin_instance->GetContainer()->element().document().frame(); | |
276 return frame->createAssociatedURLLoader(options); | |
277 } | |
278 | |
279 blink::WebURLRequest CreateWebURLRequest(PP_Instance instance, | |
280 const GURL& gurl) { | |
281 content::PepperPluginInstance* plugin_instance = | |
282 content::PepperPluginInstance::Get(instance); | |
283 blink::WebFrame* frame = | |
284 plugin_instance->GetContainer()->element().document().frame(); | |
285 blink::WebURLRequest request; | |
286 request.initialize(); | |
287 request.setURL(gurl); | |
288 request.setFirstPartyForCookies(frame->document().firstPartyForCookies()); | |
289 return request; | |
290 } | |
291 | |
254 // Launch NaCl's sel_ldr process. | 292 // Launch NaCl's sel_ldr process. |
255 void LaunchSelLdr(PP_Instance instance, | 293 void LaunchSelLdr(PP_Instance instance, |
256 const char* alleged_url, | 294 const char* alleged_url, |
257 PP_Bool uses_irt, | 295 PP_Bool uses_irt, |
258 PP_Bool uses_ppapi, | 296 PP_Bool uses_ppapi, |
259 PP_Bool uses_nonsfi_mode, | 297 PP_Bool uses_nonsfi_mode, |
260 PP_Bool enable_ppapi_dev, | 298 PP_Bool enable_ppapi_dev, |
261 PP_Bool enable_dyncode_syscalls, | 299 PP_Bool enable_dyncode_syscalls, |
262 PP_Bool enable_exception_handling, | 300 PP_Bool enable_exception_handling, |
263 PP_Bool enable_crash_throttling, | 301 PP_Bool enable_crash_throttling, |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
662 uint64_t loaded_bytes, | 700 uint64_t loaded_bytes, |
663 uint64_t total_bytes) { | 701 uint64_t total_bytes) { |
664 ProgressEvent event(event_type, | 702 ProgressEvent event(event_type, |
665 resource_url, | 703 resource_url, |
666 PP_ToBool(length_is_computable), | 704 PP_ToBool(length_is_computable), |
667 loaded_bytes, | 705 loaded_bytes, |
668 total_bytes); | 706 total_bytes); |
669 DispatchProgressEvent(instance, event); | 707 DispatchProgressEvent(instance, event); |
670 } | 708 } |
671 | 709 |
672 void NexeFileDidOpen(PP_Instance instance, | |
673 int32_t pp_error, | |
674 int32_t fd, | |
675 int32_t http_status, | |
676 int64_t nexe_bytes_read, | |
677 const char* url, | |
678 int64_t time_since_open) { | |
679 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | |
680 if (load_manager) { | |
681 load_manager->NexeFileDidOpen(pp_error, | |
682 fd, | |
683 http_status, | |
684 nexe_bytes_read, | |
685 url, | |
686 time_since_open); | |
687 } | |
688 } | |
689 | |
690 void ReportLoadSuccess(PP_Instance instance, | 710 void ReportLoadSuccess(PP_Instance instance, |
691 const char* url, | 711 const char* url, |
692 uint64_t loaded_bytes, | 712 uint64_t loaded_bytes, |
693 uint64_t total_bytes) { | 713 uint64_t total_bytes) { |
694 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 714 NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
695 if (load_manager) | 715 if (load_manager) |
696 load_manager->ReportLoadSuccess(url, loaded_bytes, total_bytes); | 716 load_manager->ReportLoadSuccess(url, loaded_bytes, total_bytes); |
697 } | 717 } |
698 | 718 |
699 void ReportLoadError(PP_Instance instance, | 719 void ReportLoadError(PP_Instance instance, |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
899 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 919 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
900 DCHECK(load_manager); | 920 DCHECK(load_manager); |
901 if (!load_manager) { | 921 if (!load_manager) { |
902 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 922 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
903 FROM_HERE, | 923 FROM_HERE, |
904 base::Bind(callback.func, callback.user_data, | 924 base::Bind(callback.func, callback.user_data, |
905 static_cast<int32_t>(PP_ERROR_FAILED))); | 925 static_cast<int32_t>(PP_ERROR_FAILED))); |
906 } | 926 } |
907 | 927 |
908 const GURL& gurl = load_manager->manifest_base_url(); | 928 const GURL& gurl = load_manager->manifest_base_url(); |
909 | 929 blink::WebURLLoader* url_loader = CreateWebURLLoader(instance, gurl); |
910 content::PepperPluginInstance* plugin_instance = | 930 blink::WebURLRequest request = CreateWebURLRequest(instance, gurl); |
911 content::PepperPluginInstance::Get(instance); | |
912 blink::WebURLLoaderOptions options; | |
913 options.untrustedHTTP = true; | |
914 | |
915 blink::WebSecurityOrigin security_origin = | |
916 plugin_instance->GetContainer()->element().document().securityOrigin(); | |
917 // Options settings here follow the original behavior in the trusted | |
918 // plugin and PepperURLLoaderHost. | |
919 if (security_origin.canRequest(gurl)) { | |
920 options.allowCredentials = true; | |
921 } else { | |
922 // Allow CORS. | |
923 options.crossOriginRequestPolicy = | |
924 blink::WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl; | |
925 } | |
926 | |
927 blink::WebFrame* frame = | |
928 plugin_instance->GetContainer()->element().document().frame(); | |
929 blink::WebURLLoader* url_loader = frame->createAssociatedURLLoader(options); | |
930 blink::WebURLRequest request; | |
931 request.initialize(); | |
932 request.setURL(gurl); | |
933 request.setFirstPartyForCookies(frame->document().firstPartyForCookies()); | |
934 | 931 |
935 // ManifestDownloader deletes itself after invoking the callback. | 932 // ManifestDownloader deletes itself after invoking the callback. |
936 ManifestDownloader* client = new ManifestDownloader( | 933 ManifestDownloader* client = new ManifestDownloader( |
937 load_manager->is_installed(), | 934 load_manager->is_installed(), |
938 base::Bind(DownloadManifestToBufferCompletion, | 935 base::Bind(DownloadManifestToBufferCompletion, |
939 instance, callback, out_data, base::Time::Now())); | 936 instance, callback, out_data, base::Time::Now())); |
940 url_loader->loadAsynchronously(request, client); | 937 url_loader->loadAsynchronously(request, client); |
941 } | 938 } |
942 | 939 |
943 void DownloadManifestToBufferCompletion(PP_Instance instance, | 940 void DownloadManifestToBufferCompletion(PP_Instance instance, |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1244 } | 1241 } |
1245 | 1242 |
1246 void PostMessageToJavaScript(PP_Instance instance, const char* message) { | 1243 void PostMessageToJavaScript(PP_Instance instance, const char* message) { |
1247 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 1244 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
1248 FROM_HERE, | 1245 FROM_HERE, |
1249 base::Bind(&PostMessageToJavaScriptMainThread, | 1246 base::Bind(&PostMessageToJavaScriptMainThread, |
1250 instance, | 1247 instance, |
1251 std::string(message))); | 1248 std::string(message))); |
1252 } | 1249 } |
1253 | 1250 |
1251 // Encapsulates some of the state for a call to DownloadNexe to prevent | |
1252 // argument lists from getting too long. | |
1253 struct DownloadNexeRequest { | |
1254 PP_Instance instance; | |
1255 const char* url; | |
1256 PP_CompletionCallback callback; | |
1257 base::Time start_time; | |
1258 }; | |
1259 | |
1260 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
| |
1261 public: | |
1262 void ReportProgress(const std::string& url, | |
1263 int64_t total_bytes_received, | |
1264 int64_t total_bytes_to_be_received) { | |
1265 base::Time now = base::Time::Now(); | |
1266 if (now - last_event_ > base::TimeDelta::FromMilliseconds(10)) { | |
1267 // Actually dispatch the progress event. | |
1268 last_event_ = now; | |
1269 } | |
1270 } | |
1271 private: | |
1272 base::Time last_event_; | |
1273 }; | |
1274 | |
1275 void DownloadNexeProgress(PP_Instance instance, | |
1276 const std::string& url, | |
1277 int64_t total_bytes_received, | |
1278 int64_t total_bytes_to_be_received); | |
1279 | |
1280 void DownloadNexeCompletion(const DownloadNexeRequest& request, | |
1281 blink::WebURLLoader* loader, | |
1282 base::PlatformFile target_file, | |
1283 PP_FileHandle* out_handle, | |
1284 FileDownloader::Status status, | |
1285 int http_status); | |
1286 | |
1287 void DownloadNexe(PP_Instance instance, | |
1288 const char* url, | |
1289 PP_FileHandle* out_handle, | |
1290 PP_CompletionCallback callback) { | |
1291 CHECK(url); | |
1292 CHECK(out_handle); | |
1293 DownloadNexeRequest request; | |
1294 request.instance = instance; | |
1295 request.url = url; | |
1296 request.callback = callback; | |
1297 request.start_time = base::Time::Now(); | |
1298 | |
1299 // Try the fast path for retrieving the file first. | |
1300 uint64_t file_token_lo = 0; | |
1301 uint64_t file_token_hi = 0; | |
1302 PP_FileHandle file_handle = OpenNaClExecutable(instance, | |
1303 url, | |
1304 &file_token_lo, | |
1305 &file_token_hi); | |
1306 | |
1307 // 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.
| |
1308 if (file_handle != PP_kInvalidFileHandle) { | |
1309 DownloadNexeCompletion(request, NULL, file_handle, out_handle, | |
1310 FileDownloader::SUCCESS, 200); | |
1311 return; | |
1312 } | |
1313 | |
1314 // The fast path didn't work, we'll fetch the file using URLLoader and write | |
1315 // it to local storage. | |
1316 base::PlatformFile target_file = CreateTemporaryFile(instance); | |
1317 GURL gurl(url); | |
1318 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.
| |
1319 blink::WebURLRequest url_request = CreateWebURLRequest(instance, gurl); | |
1320 | |
1321 // FileDownloader deletes itself after invoking the callback. | |
1322 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
| |
1323 target_file, | |
1324 base::Bind(&DownloadNexeCompletion, request, url_loader, target_file, | |
1325 out_handle), | |
1326 base::Bind(&DownloadNexeProgress, instance, url)); | |
1327 url_loader->loadAsynchronously(url_request, client); | |
1328 } | |
1329 | |
1330 void DownloadNexeProgress(PP_Instance instance, | |
1331 const std::string& url, | |
1332 int64_t total_bytes_received, | |
1333 int64_t total_bytes_to_be_received) { | |
1334 ProgressEvent event(PP_NACL_EVENT_PROGRESS, | |
1335 url, | |
1336 total_bytes_to_be_received >= 0, | |
1337 total_bytes_received, | |
1338 total_bytes_to_be_received); | |
1339 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.
| |
1340 } | |
1341 | |
1342 void DownloadNexeCompletion(const DownloadNexeRequest& request, | |
1343 blink::WebURLLoader* loader, | |
bbudge
2014/05/12 22:32:06
scoped_ptr<blink::WebURLLoader>?
teravest
2014/05/13 17:05:32
Done.
| |
1344 base::PlatformFile target_file, | |
1345 PP_FileHandle* out_handle, | |
1346 FileDownloader::Status status, | |
1347 int http_status) { | |
1348 int32_t pp_error; | |
1349 switch (status) { | |
1350 case FileDownloader::SUCCESS: | |
1351 *out_handle = target_file; | |
1352 pp_error = PP_OK; | |
1353 break; | |
1354 case FileDownloader::ACCESS_DENIED: | |
1355 pp_error = PP_ERROR_NOACCESS; | |
1356 break; | |
1357 case FileDownloader::FAILED: | |
1358 pp_error = PP_ERROR_FAILED; | |
1359 break; | |
1360 default: | |
1361 NOTREACHED(); | |
1362 return; | |
1363 } | |
1364 delete loader; | |
1365 | |
1366 int64_t bytes_read = -1; | |
1367 if (pp_error == PP_OK && target_file != base::kInvalidPlatformFileValue) { | |
1368 base::PlatformFileInfo info; | |
1369 if (GetPlatformFileInfo(target_file, &info)) | |
1370 bytes_read = info.size; | |
1371 } | |
1372 | |
1373 if (bytes_read == -1) { | |
1374 base::ClosePlatformFile(target_file); | |
1375 pp_error = PP_ERROR_FAILED; | |
1376 } | |
1377 | |
1378 base::TimeDelta download_time = base::Time::Now() - request.start_time; | |
1379 | |
1380 NexeLoadManager* load_manager = GetNexeLoadManager(request.instance); | |
1381 if (load_manager) { | |
1382 load_manager->NexeFileDidOpen(pp_error, | |
1383 target_file, | |
1384 http_status, | |
1385 bytes_read, | |
1386 request.url, | |
1387 download_time); | |
1388 } | |
1389 | |
1390 request.callback.func(request.callback.user_data, pp_error); | |
1391 } | |
1392 | |
1254 const PPB_NaCl_Private nacl_interface = { | 1393 const PPB_NaCl_Private nacl_interface = { |
1255 &LaunchSelLdr, | 1394 &LaunchSelLdr, |
1256 &StartPpapiProxy, | 1395 &StartPpapiProxy, |
1257 &UrandomFD, | 1396 &UrandomFD, |
1258 &Are3DInterfacesDisabled, | 1397 &Are3DInterfacesDisabled, |
1259 &BrokerDuplicateHandle, | 1398 &BrokerDuplicateHandle, |
1260 &GetReadonlyPnaclFD, | 1399 &GetReadonlyPnaclFD, |
1261 &CreateTemporaryFile, | 1400 &CreateTemporaryFile, |
1262 &GetNumberOfProcessors, | 1401 &GetNumberOfProcessors, |
1263 &IsNonSFIModeEnabled, | 1402 &IsNonSFIModeEnabled, |
1264 &GetNexeFd, | 1403 &GetNexeFd, |
1265 &ReportTranslationFinished, | 1404 &ReportTranslationFinished, |
1266 &OpenNaClExecutable, | 1405 &OpenNaClExecutable, |
1267 &DispatchEvent, | 1406 &DispatchEvent, |
1268 &NexeFileDidOpen, | |
1269 &ReportLoadSuccess, | 1407 &ReportLoadSuccess, |
1270 &ReportLoadError, | 1408 &ReportLoadError, |
1271 &ReportLoadAbort, | 1409 &ReportLoadAbort, |
1272 &NexeDidCrash, | 1410 &NexeDidCrash, |
1273 &InstanceCreated, | 1411 &InstanceCreated, |
1274 &InstanceDestroyed, | 1412 &InstanceDestroyed, |
1275 &NaClDebugEnabledForURL, | 1413 &NaClDebugEnabledForURL, |
1276 &GetSandboxArch, | 1414 &GetSandboxArch, |
1277 &LogToConsole, | 1415 &LogToConsole, |
1278 &GetNaClReadyState, | 1416 &GetNaClReadyState, |
(...skipping 12 matching lines...) Expand all Loading... | |
1291 &IsPNaCl, | 1429 &IsPNaCl, |
1292 &DevInterfacesEnabled, | 1430 &DevInterfacesEnabled, |
1293 &DownloadManifestToBuffer, | 1431 &DownloadManifestToBuffer, |
1294 &CreatePNaClManifest, | 1432 &CreatePNaClManifest, |
1295 &CreateJsonManifest, | 1433 &CreateJsonManifest, |
1296 &DestroyManifest, | 1434 &DestroyManifest, |
1297 &ManifestGetProgramURL, | 1435 &ManifestGetProgramURL, |
1298 &ManifestResolveKey, | 1436 &ManifestResolveKey, |
1299 &GetPNaClResourceInfo, | 1437 &GetPNaClResourceInfo, |
1300 &GetCpuFeatureAttrs, | 1438 &GetCpuFeatureAttrs, |
1301 &PostMessageToJavaScript | 1439 &PostMessageToJavaScript, |
1440 &DownloadNexe | |
1302 }; | 1441 }; |
1303 | 1442 |
1304 } // namespace | 1443 } // namespace |
1305 | 1444 |
1306 const PPB_NaCl_Private* GetNaClPrivateInterface() { | 1445 const PPB_NaCl_Private* GetNaClPrivateInterface() { |
1307 return &nacl_interface; | 1446 return &nacl_interface; |
1308 } | 1447 } |
1309 | 1448 |
1310 } // namespace nacl | 1449 } // namespace nacl |
OLD | NEW |