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 |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 275 |
276 blink::WebURLRequest CreateWebURLRequest(const blink::WebDocument& document, | 276 blink::WebURLRequest CreateWebURLRequest(const blink::WebDocument& document, |
277 const GURL& gurl) { | 277 const GURL& gurl) { |
278 blink::WebURLRequest request; | 278 blink::WebURLRequest request; |
279 request.initialize(); | 279 request.initialize(); |
280 request.setURL(gurl); | 280 request.setURL(gurl); |
281 request.setFirstPartyForCookies(document.firstPartyForCookies()); | 281 request.setFirstPartyForCookies(document.firstPartyForCookies()); |
282 return request; | 282 return request; |
283 } | 283 } |
284 | 284 |
| 285 int32_t FileDownloaderToPepperError(FileDownloader::Status status) { |
| 286 switch (status) { |
| 287 case FileDownloader::SUCCESS: |
| 288 return PP_OK; |
| 289 case FileDownloader::ACCESS_DENIED: |
| 290 return PP_ERROR_NOACCESS; |
| 291 case FileDownloader::FAILED: |
| 292 return PP_ERROR_FAILED; |
| 293 // No default case, to catch unhandled Status values. |
| 294 } |
| 295 return PP_ERROR_FAILED; |
| 296 } |
| 297 |
285 // Launch NaCl's sel_ldr process. | 298 // Launch NaCl's sel_ldr process. |
286 void LaunchSelLdr(PP_Instance instance, | 299 void LaunchSelLdr(PP_Instance instance, |
287 PP_Bool main_service_runtime, | 300 PP_Bool main_service_runtime, |
288 const char* alleged_url, | 301 const char* alleged_url, |
289 PP_Bool uses_irt, | 302 PP_Bool uses_irt, |
290 PP_Bool uses_ppapi, | 303 PP_Bool uses_ppapi, |
291 PP_Bool uses_nonsfi_mode, | 304 PP_Bool uses_nonsfi_mode, |
292 PP_Bool enable_ppapi_dev, | 305 PP_Bool enable_ppapi_dev, |
293 PP_Bool enable_dyncode_syscalls, | 306 PP_Bool enable_dyncode_syscalls, |
294 PP_Bool enable_exception_handling, | 307 PP_Bool enable_exception_handling, |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 892 NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
880 DCHECK(load_manager); | 893 DCHECK(load_manager); |
881 if (!load_manager) | 894 if (!load_manager) |
882 return PP_MakeUndefined(); | 895 return PP_MakeUndefined(); |
883 const GURL& gurl = load_manager->manifest_base_url(); | 896 const GURL& gurl = load_manager->manifest_base_url(); |
884 if (!gurl.is_valid()) | 897 if (!gurl.is_valid()) |
885 return PP_MakeUndefined(); | 898 return PP_MakeUndefined(); |
886 return ppapi::StringVar::StringToPPVar(gurl.spec()); | 899 return ppapi::StringVar::StringToPPVar(gurl.spec()); |
887 } | 900 } |
888 | 901 |
889 PP_Bool ResolvesRelativeToPluginBaseURL(PP_Instance instance, | |
890 const char *url) { | |
891 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | |
892 DCHECK(load_manager); | |
893 if (!load_manager) | |
894 return PP_FALSE; | |
895 const GURL& gurl = load_manager->plugin_base_url().Resolve(url); | |
896 if (!gurl.is_valid()) | |
897 return PP_FALSE; | |
898 return PP_TRUE; | |
899 } | |
900 | |
901 void ProcessNaClManifest(PP_Instance instance, const char* program_url) { | 902 void ProcessNaClManifest(PP_Instance instance, const char* program_url) { |
902 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 903 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
903 if (load_manager) | 904 if (load_manager) |
904 load_manager->ProcessNaClManifest(program_url); | 905 load_manager->ProcessNaClManifest(program_url); |
905 } | 906 } |
906 | 907 |
907 PP_Var GetManifestURLArgument(PP_Instance instance) { | 908 PP_Var GetManifestURLArgument(PP_Instance instance) { |
908 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 909 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
909 if (load_manager) { | 910 if (load_manager) { |
910 return ppapi::StringVar::StringToPPVar( | 911 return ppapi::StringVar::StringToPPVar( |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1380 base::Bind(&ProgressEventRateLimiter::ReportProgress, | 1381 base::Bind(&ProgressEventRateLimiter::ReportProgress, |
1381 base::Owned(tracker), url)); | 1382 base::Owned(tracker), url)); |
1382 file_downloader->Load(url_request); | 1383 file_downloader->Load(url_request); |
1383 } | 1384 } |
1384 | 1385 |
1385 void DownloadNexeCompletion(const DownloadNexeRequest& request, | 1386 void DownloadNexeCompletion(const DownloadNexeRequest& request, |
1386 base::PlatformFile target_file, | 1387 base::PlatformFile target_file, |
1387 PP_FileHandle* out_handle, | 1388 PP_FileHandle* out_handle, |
1388 FileDownloader::Status status, | 1389 FileDownloader::Status status, |
1389 int http_status) { | 1390 int http_status) { |
1390 int32_t pp_error; | 1391 int32_t pp_error = FileDownloaderToPepperError(status); |
1391 switch (status) { | 1392 if (pp_error == PP_OK) |
1392 case FileDownloader::SUCCESS: | 1393 *out_handle = target_file; |
1393 *out_handle = target_file; | |
1394 pp_error = PP_OK; | |
1395 break; | |
1396 case FileDownloader::ACCESS_DENIED: | |
1397 pp_error = PP_ERROR_NOACCESS; | |
1398 break; | |
1399 case FileDownloader::FAILED: | |
1400 pp_error = PP_ERROR_FAILED; | |
1401 break; | |
1402 default: | |
1403 NOTREACHED(); | |
1404 return; | |
1405 } | |
1406 | 1394 |
1407 int64_t bytes_read = -1; | 1395 int64_t bytes_read = -1; |
1408 if (pp_error == PP_OK && target_file != base::kInvalidPlatformFileValue) { | 1396 if (pp_error == PP_OK && target_file != base::kInvalidPlatformFileValue) { |
1409 base::PlatformFileInfo info; | 1397 base::PlatformFileInfo info; |
1410 if (GetPlatformFileInfo(target_file, &info)) | 1398 if (GetPlatformFileInfo(target_file, &info)) |
1411 bytes_read = info.size; | 1399 bytes_read = info.size; |
1412 } | 1400 } |
1413 | 1401 |
1414 if (bytes_read == -1) { | 1402 if (bytes_read == -1) { |
1415 base::ClosePlatformFile(target_file); | 1403 base::ClosePlatformFile(target_file); |
1416 pp_error = PP_ERROR_FAILED; | 1404 pp_error = PP_ERROR_FAILED; |
1417 } | 1405 } |
1418 | 1406 |
1419 base::TimeDelta download_time = base::Time::Now() - request.start_time; | 1407 base::TimeDelta download_time = base::Time::Now() - request.start_time; |
1420 | 1408 |
1421 NexeLoadManager* load_manager = GetNexeLoadManager(request.instance); | 1409 NexeLoadManager* load_manager = GetNexeLoadManager(request.instance); |
1422 if (load_manager) { | 1410 if (load_manager) { |
1423 load_manager->NexeFileDidOpen(pp_error, | 1411 load_manager->NexeFileDidOpen(pp_error, |
1424 target_file, | 1412 target_file, |
1425 http_status, | 1413 http_status, |
1426 bytes_read, | 1414 bytes_read, |
1427 request.url, | 1415 request.url, |
1428 download_time); | 1416 download_time); |
1429 } | 1417 } |
1430 | 1418 |
1431 request.callback.func(request.callback.user_data, pp_error); | 1419 request.callback.func(request.callback.user_data, pp_error); |
1432 } | 1420 } |
1433 | 1421 |
| 1422 void DownloadFileCompletion(base::PlatformFile file, |
| 1423 PP_NaClFileInfo* file_info, |
| 1424 PP_CompletionCallback callback, |
| 1425 FileDownloader::Status status, |
| 1426 int http_status) { |
| 1427 int32_t pp_error = FileDownloaderToPepperError(status); |
| 1428 if (pp_error == PP_OK) { |
| 1429 file_info->handle = file; |
| 1430 file_info->token_lo = 0; |
| 1431 file_info->token_hi = 0; |
| 1432 } |
| 1433 callback.func(callback.user_data, pp_error); |
| 1434 } |
| 1435 |
| 1436 void DownloadFile(PP_Instance instance, |
| 1437 const char* url, |
| 1438 struct PP_NaClFileInfo* file_info, |
| 1439 struct PP_CompletionCallback callback) { |
| 1440 CHECK(url); |
| 1441 CHECK(file_info); |
| 1442 |
| 1443 NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
| 1444 DCHECK(load_manager); |
| 1445 if (!load_manager) { |
| 1446 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 1447 FROM_HERE, |
| 1448 base::Bind(callback.func, callback.user_data, |
| 1449 static_cast<int32_t>(PP_ERROR_FAILED))); |
| 1450 return; |
| 1451 } |
| 1452 |
| 1453 // We have to ensure that this url resolves relative to the plugin base url |
| 1454 // before downloading it. |
| 1455 const GURL& test_gurl = load_manager->plugin_base_url().Resolve(url); |
| 1456 if (!test_gurl.is_valid()) { |
| 1457 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 1458 FROM_HERE, |
| 1459 base::Bind(callback.func, callback.user_data, |
| 1460 static_cast<int32_t>(PP_ERROR_FAILED))); |
| 1461 return; |
| 1462 } |
| 1463 |
| 1464 // Try the fast path for retrieving the file first. |
| 1465 uint64_t file_token_lo = 0; |
| 1466 uint64_t file_token_hi = 0; |
| 1467 PP_FileHandle file_handle = OpenNaClExecutable(instance, |
| 1468 url, |
| 1469 &file_token_lo, |
| 1470 &file_token_hi); |
| 1471 if (file_handle != PP_kInvalidFileHandle) { |
| 1472 file_info->handle = file_handle; |
| 1473 file_info->token_lo = file_token_lo; |
| 1474 file_info->token_hi = file_token_hi; |
| 1475 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 1476 FROM_HERE, |
| 1477 base::Bind(callback.func, callback.user_data, |
| 1478 static_cast<int32_t>(PP_OK))); |
| 1479 return; |
| 1480 } |
| 1481 |
| 1482 // The fast path didn't work, we'll fetch the file using URLLoader and write |
| 1483 // it to local storage. |
| 1484 base::PlatformFile target_file = CreateTemporaryFile(instance); |
| 1485 GURL gurl(url); |
| 1486 |
| 1487 content::PepperPluginInstance* plugin_instance = |
| 1488 content::PepperPluginInstance::Get(instance); |
| 1489 if (!plugin_instance) { |
| 1490 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 1491 FROM_HERE, |
| 1492 base::Bind(callback.func, callback.user_data, |
| 1493 static_cast<int32_t>(PP_ERROR_FAILED))); |
| 1494 } |
| 1495 const blink::WebDocument& document = |
| 1496 plugin_instance->GetContainer()->element().document(); |
| 1497 scoped_ptr<blink::WebURLLoader> url_loader( |
| 1498 CreateWebURLLoader(document, gurl)); |
| 1499 blink::WebURLRequest url_request = CreateWebURLRequest(document, gurl); |
| 1500 |
| 1501 ProgressEventRateLimiter* tracker = new ProgressEventRateLimiter(instance); |
| 1502 |
| 1503 // FileDownloader deletes itself after invoking DownloadNexeCompletion. |
| 1504 FileDownloader* file_downloader = new FileDownloader( |
| 1505 url_loader.Pass(), |
| 1506 target_file, |
| 1507 base::Bind(&DownloadFileCompletion, target_file, file_info, callback), |
| 1508 base::Bind(&ProgressEventRateLimiter::ReportProgress, |
| 1509 base::Owned(tracker), url)); |
| 1510 file_downloader->Load(url_request); |
| 1511 } |
| 1512 |
1434 const PPB_NaCl_Private nacl_interface = { | 1513 const PPB_NaCl_Private nacl_interface = { |
1435 &LaunchSelLdr, | 1514 &LaunchSelLdr, |
1436 &StartPpapiProxy, | 1515 &StartPpapiProxy, |
1437 &UrandomFD, | 1516 &UrandomFD, |
1438 &Are3DInterfacesDisabled, | 1517 &Are3DInterfacesDisabled, |
1439 &BrokerDuplicateHandle, | 1518 &BrokerDuplicateHandle, |
1440 &GetReadonlyPnaclFD, | 1519 &GetReadonlyPnaclFD, |
1441 &CreateTemporaryFile, | 1520 &CreateTemporaryFile, |
1442 &GetNumberOfProcessors, | 1521 &GetNumberOfProcessors, |
1443 &PPIsNonSFIModeEnabled, | 1522 &PPIsNonSFIModeEnabled, |
1444 &GetNexeFd, | 1523 &GetNexeFd, |
1445 &ReportTranslationFinished, | 1524 &ReportTranslationFinished, |
1446 &OpenNaClExecutable, | |
1447 &DispatchEvent, | 1525 &DispatchEvent, |
1448 &ReportLoadSuccess, | 1526 &ReportLoadSuccess, |
1449 &ReportLoadError, | 1527 &ReportLoadError, |
1450 &ReportLoadAbort, | 1528 &ReportLoadAbort, |
1451 &NexeDidCrash, | 1529 &NexeDidCrash, |
1452 &InstanceCreated, | 1530 &InstanceCreated, |
1453 &InstanceDestroyed, | 1531 &InstanceDestroyed, |
1454 &NaClDebugEnabledForURL, | 1532 &NaClDebugEnabledForURL, |
1455 &GetSandboxArch, | 1533 &GetSandboxArch, |
1456 &LogToConsole, | 1534 &LogToConsole, |
1457 &GetNaClReadyState, | 1535 &GetNaClReadyState, |
1458 &GetIsInstalled, | 1536 &GetIsInstalled, |
1459 &GetExitStatus, | 1537 &GetExitStatus, |
1460 &SetExitStatus, | 1538 &SetExitStatus, |
1461 &Vlog, | 1539 &Vlog, |
1462 &InitializePlugin, | 1540 &InitializePlugin, |
1463 &GetNexeSize, | 1541 &GetNexeSize, |
1464 &RequestNaClManifest, | 1542 &RequestNaClManifest, |
1465 &GetManifestBaseURL, | 1543 &GetManifestBaseURL, |
1466 &ResolvesRelativeToPluginBaseURL, | |
1467 &ProcessNaClManifest, | 1544 &ProcessNaClManifest, |
1468 &GetManifestURLArgument, | 1545 &GetManifestURLArgument, |
1469 &DevInterfacesEnabled, | 1546 &DevInterfacesEnabled, |
1470 &CreatePNaClManifest, | 1547 &CreatePNaClManifest, |
1471 &DestroyManifest, | 1548 &DestroyManifest, |
1472 &ManifestGetProgramURL, | 1549 &ManifestGetProgramURL, |
1473 &ManifestResolveKey, | 1550 &ManifestResolveKey, |
1474 &GetPNaClResourceInfo, | 1551 &GetPNaClResourceInfo, |
1475 &GetCpuFeatureAttrs, | 1552 &GetCpuFeatureAttrs, |
1476 &PostMessageToJavaScript, | 1553 &PostMessageToJavaScript, |
1477 &DownloadNexe | 1554 &DownloadNexe, |
| 1555 &DownloadFile |
1478 }; | 1556 }; |
1479 | 1557 |
1480 } // namespace | 1558 } // namespace |
1481 | 1559 |
1482 const PPB_NaCl_Private* GetNaClPrivateInterface() { | 1560 const PPB_NaCl_Private* GetNaClPrivateInterface() { |
1483 return &nacl_interface; | 1561 return &nacl_interface; |
1484 } | 1562 } |
1485 | 1563 |
1486 } // namespace nacl | 1564 } // namespace nacl |
OLD | NEW |