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

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

Issue 276423003: Pepper: Nexe downloading out of the trusted plugin. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « components/nacl/renderer/nexe_load_manager.cc ('k') | ppapi/api/private/ppb_nacl_private.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 struct PP_Var* out_data, 921 struct PP_Var* out_data,
913 base::Time start_time, 922 base::Time start_time,
914 PP_NaClError pp_nacl_error, 923 PP_NaClError pp_nacl_error,
915 const std::string& data); 924 const std::string& data);
916 925
917 void DownloadManifestToBuffer(PP_Instance instance, 926 void DownloadManifestToBuffer(PP_Instance instance,
918 struct PP_Var* out_data, 927 struct PP_Var* out_data,
919 struct PP_CompletionCallback callback) { 928 struct PP_CompletionCallback callback) {
920 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); 929 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance);
921 DCHECK(load_manager); 930 DCHECK(load_manager);
922 if (!load_manager) { 931 content::PepperPluginInstance* plugin_instance =
932 content::PepperPluginInstance::Get(instance);
933 if (!load_manager || !plugin_instance) {
923 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( 934 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
924 FROM_HERE, 935 FROM_HERE,
925 base::Bind(callback.func, callback.user_data, 936 base::Bind(callback.func, callback.user_data,
926 static_cast<int32_t>(PP_ERROR_FAILED))); 937 static_cast<int32_t>(PP_ERROR_FAILED)));
927 } 938 }
939 const blink::WebDocument& document =
940 plugin_instance->GetContainer()->element().document();
928 941
929 const GURL& gurl = load_manager->manifest_base_url(); 942 const GURL& gurl = load_manager->manifest_base_url();
930 943 scoped_ptr<blink::WebURLLoader> url_loader(
931 content::PepperPluginInstance* plugin_instance = 944 CreateWebURLLoader(document, gurl));
932 content::PepperPluginInstance::Get(instance); 945 blink::WebURLRequest request = CreateWebURLRequest(document, gurl);
933 blink::WebURLLoaderOptions options;
934 options.untrustedHTTP = true;
935
936 blink::WebSecurityOrigin security_origin =
937 plugin_instance->GetContainer()->element().document().securityOrigin();
938 // Options settings here follow the original behavior in the trusted
939 // plugin and PepperURLLoaderHost.
940 if (security_origin.canRequest(gurl)) {
941 options.allowCredentials = true;
942 } else {
943 // Allow CORS.
944 options.crossOriginRequestPolicy =
945 blink::WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
946 }
947
948 blink::WebFrame* frame =
949 plugin_instance->GetContainer()->element().document().frame();
950 blink::WebURLLoader* url_loader = frame->createAssociatedURLLoader(options);
951 blink::WebURLRequest request;
952 request.initialize();
953 request.setURL(gurl);
954 request.setFirstPartyForCookies(frame->document().firstPartyForCookies());
955 946
956 // ManifestDownloader deletes itself after invoking the callback. 947 // ManifestDownloader deletes itself after invoking the callback.
957 ManifestDownloader* client = new ManifestDownloader( 948 ManifestDownloader* manifest_downloader = new ManifestDownloader(
949 url_loader.Pass(),
958 load_manager->is_installed(), 950 load_manager->is_installed(),
959 base::Bind(DownloadManifestToBufferCompletion, 951 base::Bind(DownloadManifestToBufferCompletion,
960 instance, callback, out_data, base::Time::Now())); 952 instance, callback, out_data, base::Time::Now()));
961 url_loader->loadAsynchronously(request, client); 953 manifest_downloader->Load(request);
962 } 954 }
963 955
964 void DownloadManifestToBufferCompletion(PP_Instance instance, 956 void DownloadManifestToBufferCompletion(PP_Instance instance,
965 struct PP_CompletionCallback callback, 957 struct PP_CompletionCallback callback,
966 struct PP_Var* out_data, 958 struct PP_Var* out_data,
967 base::Time start_time, 959 base::Time start_time,
968 PP_NaClError pp_nacl_error, 960 PP_NaClError pp_nacl_error,
969 const std::string& data) { 961 const std::string& data) {
970 base::TimeDelta download_time = base::Time::Now() - start_time; 962 base::TimeDelta download_time = base::Time::Now() - start_time;
971 HistogramTimeSmall("NaCl.Perf.StartupTime.ManifestDownload", 963 HistogramTimeSmall("NaCl.Perf.StartupTime.ManifestDownload",
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 } 1267 }
1276 1268
1277 void PostMessageToJavaScript(PP_Instance instance, const char* message) { 1269 void PostMessageToJavaScript(PP_Instance instance, const char* message) {
1278 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( 1270 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
1279 FROM_HERE, 1271 FROM_HERE,
1280 base::Bind(&PostMessageToJavaScriptMainThread, 1272 base::Bind(&PostMessageToJavaScriptMainThread,
1281 instance, 1273 instance,
1282 std::string(message))); 1274 std::string(message)));
1283 } 1275 }
1284 1276
1277 // Encapsulates some of the state for a call to DownloadNexe to prevent
1278 // argument lists from getting too long.
1279 struct DownloadNexeRequest {
1280 PP_Instance instance;
1281 std::string url;
1282 PP_CompletionCallback callback;
1283 base::Time start_time;
1284 };
1285
1286 // A utility class to ensure that we don't send progress events more often than
1287 // every 10ms for a given file.
1288 class ProgressEventRateLimiter {
1289 public:
1290 explicit ProgressEventRateLimiter(PP_Instance instance)
1291 : instance_(instance) { }
1292
1293 void ReportProgress(const std::string& url,
1294 int64_t total_bytes_received,
1295 int64_t total_bytes_to_be_received) {
1296 base::Time now = base::Time::Now();
1297 if (now - last_event_ > base::TimeDelta::FromMilliseconds(10)) {
1298 DispatchProgressEvent(instance_,
1299 ProgressEvent(PP_NACL_EVENT_PROGRESS,
1300 url,
1301 total_bytes_to_be_received >= 0,
1302 total_bytes_received,
1303 total_bytes_to_be_received));
1304 last_event_ = now;
1305 }
1306 }
1307
1308 private:
1309 PP_Instance instance_;
1310 base::Time last_event_;
1311 };
1312
1313 void DownloadNexeCompletion(const DownloadNexeRequest& request,
1314 base::PlatformFile target_file,
1315 PP_FileHandle* out_handle,
1316 FileDownloader::Status status,
1317 int http_status);
1318
1319 void DownloadNexe(PP_Instance instance,
1320 const char* url,
1321 PP_FileHandle* out_handle,
1322 PP_CompletionCallback callback) {
1323 CHECK(url);
1324 CHECK(out_handle);
1325 DownloadNexeRequest request;
1326 request.instance = instance;
1327 request.url = url;
1328 request.callback = callback;
1329 request.start_time = base::Time::Now();
1330
1331 // Try the fast path for retrieving the file first.
1332 uint64_t file_token_lo = 0;
1333 uint64_t file_token_hi = 0;
1334 PP_FileHandle file_handle = OpenNaClExecutable(instance,
1335 url,
1336 &file_token_lo,
1337 &file_token_hi);
1338 if (file_handle != PP_kInvalidFileHandle) {
1339 DownloadNexeCompletion(request,
1340 file_handle,
1341 out_handle,
1342 FileDownloader::SUCCESS,
1343 200);
1344 return;
1345 }
1346
1347 // The fast path didn't work, we'll fetch the file using URLLoader and write
1348 // it to local storage.
1349 base::PlatformFile target_file = CreateTemporaryFile(instance);
1350 GURL gurl(url);
1351
1352 content::PepperPluginInstance* plugin_instance =
1353 content::PepperPluginInstance::Get(instance);
1354 if (!plugin_instance) {
1355 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
1356 FROM_HERE,
1357 base::Bind(callback.func, callback.user_data,
1358 static_cast<int32_t>(PP_ERROR_FAILED)));
1359 }
1360 const blink::WebDocument& document =
1361 plugin_instance->GetContainer()->element().document();
1362 scoped_ptr<blink::WebURLLoader> url_loader(
1363 CreateWebURLLoader(document, gurl));
1364 blink::WebURLRequest url_request = CreateWebURLRequest(document, gurl);
1365
1366 ProgressEventRateLimiter* tracker = new ProgressEventRateLimiter(instance);
1367
1368 // FileDownloader deletes itself after invoking DownloadNexeCompletion.
1369 FileDownloader* file_downloader = new FileDownloader(
1370 url_loader.Pass(),
1371 target_file,
1372 base::Bind(&DownloadNexeCompletion, request, target_file, out_handle),
1373 base::Bind(&ProgressEventRateLimiter::ReportProgress,
1374 base::Owned(tracker), url));
1375 file_downloader->Load(url_request);
1376 }
1377
1378 void DownloadNexeCompletion(const DownloadNexeRequest& request,
1379 base::PlatformFile target_file,
1380 PP_FileHandle* out_handle,
1381 FileDownloader::Status status,
1382 int http_status) {
1383 int32_t pp_error;
1384 switch (status) {
1385 case FileDownloader::SUCCESS:
1386 *out_handle = target_file;
1387 pp_error = PP_OK;
1388 break;
1389 case FileDownloader::ACCESS_DENIED:
1390 pp_error = PP_ERROR_NOACCESS;
1391 break;
1392 case FileDownloader::FAILED:
1393 pp_error = PP_ERROR_FAILED;
1394 break;
1395 default:
1396 NOTREACHED();
1397 return;
1398 }
1399
1400 int64_t bytes_read = -1;
1401 if (pp_error == PP_OK && target_file != base::kInvalidPlatformFileValue) {
1402 base::PlatformFileInfo info;
1403 if (GetPlatformFileInfo(target_file, &info))
1404 bytes_read = info.size;
1405 }
1406
1407 if (bytes_read == -1) {
1408 base::ClosePlatformFile(target_file);
1409 pp_error = PP_ERROR_FAILED;
1410 }
1411
1412 base::TimeDelta download_time = base::Time::Now() - request.start_time;
1413
1414 NexeLoadManager* load_manager = GetNexeLoadManager(request.instance);
1415 if (load_manager) {
1416 load_manager->NexeFileDidOpen(pp_error,
1417 target_file,
1418 http_status,
1419 bytes_read,
1420 request.url,
1421 download_time);
1422 }
1423
1424 request.callback.func(request.callback.user_data, pp_error);
1425 }
1426
1285 const PPB_NaCl_Private nacl_interface = { 1427 const PPB_NaCl_Private nacl_interface = {
1286 &LaunchSelLdr, 1428 &LaunchSelLdr,
1287 &StartPpapiProxy, 1429 &StartPpapiProxy,
1288 &UrandomFD, 1430 &UrandomFD,
1289 &Are3DInterfacesDisabled, 1431 &Are3DInterfacesDisabled,
1290 &BrokerDuplicateHandle, 1432 &BrokerDuplicateHandle,
1291 &GetReadonlyPnaclFD, 1433 &GetReadonlyPnaclFD,
1292 &CreateTemporaryFile, 1434 &CreateTemporaryFile,
1293 &GetNumberOfProcessors, 1435 &GetNumberOfProcessors,
1294 &PPIsNonSFIModeEnabled, 1436 &PPIsNonSFIModeEnabled,
1295 &GetNexeFd, 1437 &GetNexeFd,
1296 &ReportTranslationFinished, 1438 &ReportTranslationFinished,
1297 &OpenNaClExecutable, 1439 &OpenNaClExecutable,
1298 &DispatchEvent, 1440 &DispatchEvent,
1299 &NexeFileDidOpen,
1300 &ReportLoadSuccess, 1441 &ReportLoadSuccess,
1301 &ReportLoadError, 1442 &ReportLoadError,
1302 &ReportLoadAbort, 1443 &ReportLoadAbort,
1303 &NexeDidCrash, 1444 &NexeDidCrash,
1304 &InstanceCreated, 1445 &InstanceCreated,
1305 &InstanceDestroyed, 1446 &InstanceDestroyed,
1306 &NaClDebugEnabledForURL, 1447 &NaClDebugEnabledForURL,
1307 &GetSandboxArch, 1448 &GetSandboxArch,
1308 &LogToConsole, 1449 &LogToConsole,
1309 &GetNaClReadyState, 1450 &GetNaClReadyState,
1310 &GetIsInstalled, 1451 &GetIsInstalled,
1311 &GetExitStatus, 1452 &GetExitStatus,
1312 &SetExitStatus, 1453 &SetExitStatus,
1313 &Vlog, 1454 &Vlog,
1314 &InitializePlugin, 1455 &InitializePlugin,
1315 &GetNexeSize, 1456 &GetNexeSize,
1316 &RequestNaClManifest, 1457 &RequestNaClManifest,
1317 &GetManifestBaseURL, 1458 &GetManifestBaseURL,
1318 &ResolvesRelativeToPluginBaseURL, 1459 &ResolvesRelativeToPluginBaseURL,
1319 &ProcessNaClManifest, 1460 &ProcessNaClManifest,
1320 &GetManifestURLArgument, 1461 &GetManifestURLArgument,
1321 &DevInterfacesEnabled, 1462 &DevInterfacesEnabled,
1322 &CreatePNaClManifest, 1463 &CreatePNaClManifest,
1323 &CreateJsonManifest, 1464 &CreateJsonManifest,
1324 &DestroyManifest, 1465 &DestroyManifest,
1325 &ManifestGetProgramURL, 1466 &ManifestGetProgramURL,
1326 &ManifestResolveKey, 1467 &ManifestResolveKey,
1327 &GetPNaClResourceInfo, 1468 &GetPNaClResourceInfo,
1328 &GetCpuFeatureAttrs, 1469 &GetCpuFeatureAttrs,
1329 &PostMessageToJavaScript 1470 &PostMessageToJavaScript,
1471 &DownloadNexe
1330 }; 1472 };
1331 1473
1332 } // namespace 1474 } // namespace
1333 1475
1334 const PPB_NaCl_Private* GetNaClPrivateInterface() { 1476 const PPB_NaCl_Private* GetNaClPrivateInterface() {
1335 return &nacl_interface; 1477 return &nacl_interface;
1336 } 1478 }
1337 1479
1338 } // namespace nacl 1480 } // namespace nacl
OLDNEW
« no previous file with comments | « components/nacl/renderer/nexe_load_manager.cc ('k') | ppapi/api/private/ppb_nacl_private.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698