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