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

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: windows fix and stuff for bill 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
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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 std::string url;
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 ProgressEventRateLimiter {
1260 public:
1261 explicit ProgressEventRateLimiter(PP_Instance instance)
1262 : instance_(instance) { }
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 base::PlatformFile target_file,
1286 PP_FileHandle* out_handle,
1287 FileDownloader::Status status,
1288 int http_status);
1289
1290 void DownloadNexe(PP_Instance instance,
1291 const char* url,
1292 PP_FileHandle* out_handle,
1293 PP_CompletionCallback callback) {
1294 CHECK(url);
1295 CHECK(out_handle);
1296 DownloadNexeRequest request;
1297 request.instance = instance;
1298 request.url = url;
1299 request.callback = callback;
1300 request.start_time = base::Time::Now();
1301
1302 // Try the fast path for retrieving the file first.
1303 uint64_t file_token_lo = 0;
1304 uint64_t file_token_hi = 0;
1305 PP_FileHandle file_handle = OpenNaClExecutable(instance,
1306 url,
1307 &file_token_lo,
1308 &file_token_hi);
1309 if (file_handle != PP_kInvalidFileHandle) {
1310 DownloadNexeCompletion(request,
1311 file_handle,
1312 out_handle,
1313 FileDownloader::SUCCESS,
1314 200);
1315 return;
1316 }
1317
1318 // The fast path didn't work, we'll fetch the file using URLLoader and write
1319 // it to local storage.
1320 base::PlatformFile target_file = CreateTemporaryFile(instance);
1321 GURL gurl(url);
1322
1323 content::PepperPluginInstance* plugin_instance =
1324 content::PepperPluginInstance::Get(instance);
1325 if (!plugin_instance) {
1326 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
1327 FROM_HERE,
1328 base::Bind(callback.func, callback.user_data,
1329 static_cast<int32_t>(PP_ERROR_FAILED)));
1330 }
1331 const blink::WebDocument& document =
1332 plugin_instance->GetContainer()->element().document();
1333 scoped_ptr<blink::WebURLLoader> url_loader(
1334 CreateWebURLLoader(document, gurl));
1335 blink::WebURLRequest url_request = CreateWebURLRequest(document, gurl);
1336
1337 ProgressEventRateLimiter* tracker = new ProgressEventRateLimiter(instance);
1338
1339 // FileDownloader deletes itself after invoking the callback.
bbudge 2014/05/16 17:20:51 s/callback/status callback ? or alternately, Downl
1340 FileDownloader* file_downloader = new FileDownloader(
1341 url_loader.Pass(),
1342 target_file,
1343 base::Bind(&DownloadNexeCompletion, request, target_file, out_handle),
1344 base::Bind(&ProgressEventRateLimiter::ReportProgress,
1345 base::Owned(tracker), url));
1346 file_downloader->Load(url_request);
1347 }
1348
1349 void DownloadNexeCompletion(const DownloadNexeRequest& request,
1350 base::PlatformFile target_file,
1351 PP_FileHandle* out_handle,
1352 FileDownloader::Status status,
1353 int http_status) {
1354 int32_t pp_error;
1355 switch (status) {
1356 case FileDownloader::SUCCESS:
1357 *out_handle = target_file;
1358 pp_error = PP_OK;
1359 break;
1360 case FileDownloader::ACCESS_DENIED:
1361 pp_error = PP_ERROR_NOACCESS;
1362 break;
1363 case FileDownloader::FAILED:
1364 pp_error = PP_ERROR_FAILED;
1365 break;
1366 default:
1367 NOTREACHED();
1368 return;
1369 }
1370
1371 int64_t bytes_read = -1;
1372 if (pp_error == PP_OK && target_file != base::kInvalidPlatformFileValue) {
1373 base::PlatformFileInfo info;
1374 if (GetPlatformFileInfo(target_file, &info))
1375 bytes_read = info.size;
1376 }
1377
1378 if (bytes_read == -1) {
1379 base::ClosePlatformFile(target_file);
1380 pp_error = PP_ERROR_FAILED;
1381 }
1382
1383 base::TimeDelta download_time = base::Time::Now() - request.start_time;
1384
1385 NexeLoadManager* load_manager = GetNexeLoadManager(request.instance);
1386 if (load_manager) {
1387 load_manager->NexeFileDidOpen(pp_error,
1388 target_file,
1389 http_status,
1390 bytes_read,
1391 request.url,
1392 download_time);
1393 }
1394
1395 request.callback.func(request.callback.user_data, pp_error);
1396 }
1397
1256 const PPB_NaCl_Private nacl_interface = { 1398 const PPB_NaCl_Private nacl_interface = {
1257 &LaunchSelLdr, 1399 &LaunchSelLdr,
1258 &StartPpapiProxy, 1400 &StartPpapiProxy,
1259 &UrandomFD, 1401 &UrandomFD,
1260 &Are3DInterfacesDisabled, 1402 &Are3DInterfacesDisabled,
1261 &BrokerDuplicateHandle, 1403 &BrokerDuplicateHandle,
1262 &GetReadonlyPnaclFD, 1404 &GetReadonlyPnaclFD,
1263 &CreateTemporaryFile, 1405 &CreateTemporaryFile,
1264 &GetNumberOfProcessors, 1406 &GetNumberOfProcessors,
1265 &PPIsNonSFIModeEnabled, 1407 &PPIsNonSFIModeEnabled,
1266 &GetNexeFd, 1408 &GetNexeFd,
1267 &ReportTranslationFinished, 1409 &ReportTranslationFinished,
1268 &OpenNaClExecutable, 1410 &OpenNaClExecutable,
1269 &DispatchEvent, 1411 &DispatchEvent,
1270 &NexeFileDidOpen,
1271 &ReportLoadSuccess, 1412 &ReportLoadSuccess,
1272 &ReportLoadError, 1413 &ReportLoadError,
1273 &ReportLoadAbort, 1414 &ReportLoadAbort,
1274 &NexeDidCrash, 1415 &NexeDidCrash,
1275 &InstanceCreated, 1416 &InstanceCreated,
1276 &InstanceDestroyed, 1417 &InstanceDestroyed,
1277 &NaClDebugEnabledForURL, 1418 &NaClDebugEnabledForURL,
1278 &GetSandboxArch, 1419 &GetSandboxArch,
1279 &LogToConsole, 1420 &LogToConsole,
1280 &GetNaClReadyState, 1421 &GetNaClReadyState,
(...skipping 11 matching lines...) Expand all
1292 &GetManifestURLArgument, 1433 &GetManifestURLArgument,
1293 &DevInterfacesEnabled, 1434 &DevInterfacesEnabled,
1294 &DownloadManifestToBuffer, 1435 &DownloadManifestToBuffer,
1295 &CreatePNaClManifest, 1436 &CreatePNaClManifest,
1296 &CreateJsonManifest, 1437 &CreateJsonManifest,
1297 &DestroyManifest, 1438 &DestroyManifest,
1298 &ManifestGetProgramURL, 1439 &ManifestGetProgramURL,
1299 &ManifestResolveKey, 1440 &ManifestResolveKey,
1300 &GetPNaClResourceInfo, 1441 &GetPNaClResourceInfo,
1301 &GetCpuFeatureAttrs, 1442 &GetCpuFeatureAttrs,
1302 &PostMessageToJavaScript 1443 &PostMessageToJavaScript,
1444 &DownloadNexe
1303 }; 1445 };
1304 1446
1305 } // namespace 1447 } // namespace
1306 1448
1307 const PPB_NaCl_Private* GetNaClPrivateInterface() { 1449 const PPB_NaCl_Private* GetNaClPrivateInterface() {
1308 return &nacl_interface; 1450 return &nacl_interface;
1309 } 1451 }
1310 1452
1311 } // namespace nacl 1453 } // namespace nacl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698