Chromium Code Reviews| 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 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 Loading... | |
| 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 |
| OLD | NEW |