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_switches.h" | 21 #include "components/nacl/common/nacl_switches.h" |
| 22 #include "components/nacl/common/nacl_types.h" | 22 #include "components/nacl/common/nacl_types.h" |
| 23 #include "components/nacl/renderer/file_downloader.h" | |
| 23 #include "components/nacl/renderer/histogram.h" | 24 #include "components/nacl/renderer/histogram.h" |
| 24 #include "components/nacl/renderer/json_manifest.h" | 25 #include "components/nacl/renderer/json_manifest.h" |
| 25 #include "components/nacl/renderer/manifest_downloader.h" | 26 #include "components/nacl/renderer/manifest_downloader.h" |
| 26 #include "components/nacl/renderer/manifest_service_channel.h" | 27 #include "components/nacl/renderer/manifest_service_channel.h" |
| 27 #include "components/nacl/renderer/nexe_load_manager.h" | 28 #include "components/nacl/renderer/nexe_load_manager.h" |
| 28 #include "components/nacl/renderer/pnacl_translation_resource_host.h" | 29 #include "components/nacl/renderer/pnacl_translation_resource_host.h" |
| 29 #include "components/nacl/renderer/progress_event.h" | 30 #include "components/nacl/renderer/progress_event.h" |
| 30 #include "components/nacl/renderer/sandbox_arch.h" | 31 #include "components/nacl/renderer/sandbox_arch.h" |
| 31 #include "components/nacl/renderer/trusted_plugin_channel.h" | 32 #include "components/nacl/renderer/trusted_plugin_channel.h" |
| 32 #include "content/public/common/content_client.h" | 33 #include "content/public/common/content_client.h" |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 bool result = PP_ToBool(manifest_service_.Quit(user_data_)); | 245 bool result = PP_ToBool(manifest_service_.Quit(user_data_)); |
| 245 DCHECK(!result); | 246 DCHECK(!result); |
| 246 user_data_ = NULL; | 247 user_data_ = NULL; |
| 247 } | 248 } |
| 248 | 249 |
| 249 PPP_ManifestService manifest_service_; | 250 PPP_ManifestService manifest_service_; |
| 250 void* user_data_; | 251 void* user_data_; |
| 251 DISALLOW_COPY_AND_ASSIGN(ManifestServiceProxy); | 252 DISALLOW_COPY_AND_ASSIGN(ManifestServiceProxy); |
| 252 }; | 253 }; |
| 253 | 254 |
| 255 blink::WebURLLoader* CreateWebURLLoader(PP_Instance instance, | |
| 256 const GURL& gurl) { | |
| 257 content::PepperPluginInstance* plugin_instance = | |
| 258 content::PepperPluginInstance::Get(instance); | |
| 259 blink::WebURLLoaderOptions options; | |
| 260 options.untrustedHTTP = true; | |
| 261 | |
| 262 blink::WebSecurityOrigin security_origin = | |
| 263 plugin_instance->GetContainer()->element().document().securityOrigin(); | |
|
bbudge
2014/05/12 22:32:06
This function and the following one could be simpl
teravest
2014/05/13 17:05:32
Done.
| |
| 264 // Options settings here follow the original behavior in the trusted | |
| 265 // plugin and PepperURLLoaderHost. | |
| 266 if (security_origin.canRequest(gurl)) { | |
| 267 options.allowCredentials = true; | |
| 268 } else { | |
| 269 // Allow CORS. | |
| 270 options.crossOriginRequestPolicy = | |
| 271 blink::WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl; | |
| 272 } | |
| 273 | |
| 274 blink::WebFrame* frame = | |
| 275 plugin_instance->GetContainer()->element().document().frame(); | |
| 276 return frame->createAssociatedURLLoader(options); | |
| 277 } | |
| 278 | |
| 279 blink::WebURLRequest CreateWebURLRequest(PP_Instance instance, | |
| 280 const GURL& gurl) { | |
| 281 content::PepperPluginInstance* plugin_instance = | |
| 282 content::PepperPluginInstance::Get(instance); | |
| 283 blink::WebFrame* frame = | |
| 284 plugin_instance->GetContainer()->element().document().frame(); | |
| 285 blink::WebURLRequest request; | |
| 286 request.initialize(); | |
| 287 request.setURL(gurl); | |
| 288 request.setFirstPartyForCookies(frame->document().firstPartyForCookies()); | |
| 289 return request; | |
| 290 } | |
| 291 | |
| 254 // Launch NaCl's sel_ldr process. | 292 // Launch NaCl's sel_ldr process. |
| 255 void LaunchSelLdr(PP_Instance instance, | 293 void LaunchSelLdr(PP_Instance instance, |
| 256 const char* alleged_url, | 294 const char* alleged_url, |
| 257 PP_Bool uses_irt, | 295 PP_Bool uses_irt, |
| 258 PP_Bool uses_ppapi, | 296 PP_Bool uses_ppapi, |
| 259 PP_Bool uses_nonsfi_mode, | 297 PP_Bool uses_nonsfi_mode, |
| 260 PP_Bool enable_ppapi_dev, | 298 PP_Bool enable_ppapi_dev, |
| 261 PP_Bool enable_dyncode_syscalls, | 299 PP_Bool enable_dyncode_syscalls, |
| 262 PP_Bool enable_exception_handling, | 300 PP_Bool enable_exception_handling, |
| 263 PP_Bool enable_crash_throttling, | 301 PP_Bool enable_crash_throttling, |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 uint64_t loaded_bytes, | 700 uint64_t loaded_bytes, |
| 663 uint64_t total_bytes) { | 701 uint64_t total_bytes) { |
| 664 ProgressEvent event(event_type, | 702 ProgressEvent event(event_type, |
| 665 resource_url, | 703 resource_url, |
| 666 PP_ToBool(length_is_computable), | 704 PP_ToBool(length_is_computable), |
| 667 loaded_bytes, | 705 loaded_bytes, |
| 668 total_bytes); | 706 total_bytes); |
| 669 DispatchProgressEvent(instance, event); | 707 DispatchProgressEvent(instance, event); |
| 670 } | 708 } |
| 671 | 709 |
| 672 void NexeFileDidOpen(PP_Instance instance, | |
| 673 int32_t pp_error, | |
| 674 int32_t fd, | |
| 675 int32_t http_status, | |
| 676 int64_t nexe_bytes_read, | |
| 677 const char* url, | |
| 678 int64_t time_since_open) { | |
| 679 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | |
| 680 if (load_manager) { | |
| 681 load_manager->NexeFileDidOpen(pp_error, | |
| 682 fd, | |
| 683 http_status, | |
| 684 nexe_bytes_read, | |
| 685 url, | |
| 686 time_since_open); | |
| 687 } | |
| 688 } | |
| 689 | |
| 690 void ReportLoadSuccess(PP_Instance instance, | 710 void ReportLoadSuccess(PP_Instance instance, |
| 691 const char* url, | 711 const char* url, |
| 692 uint64_t loaded_bytes, | 712 uint64_t loaded_bytes, |
| 693 uint64_t total_bytes) { | 713 uint64_t total_bytes) { |
| 694 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 714 NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
| 695 if (load_manager) | 715 if (load_manager) |
| 696 load_manager->ReportLoadSuccess(url, loaded_bytes, total_bytes); | 716 load_manager->ReportLoadSuccess(url, loaded_bytes, total_bytes); |
| 697 } | 717 } |
| 698 | 718 |
| 699 void ReportLoadError(PP_Instance instance, | 719 void ReportLoadError(PP_Instance instance, |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 899 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 919 nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
| 900 DCHECK(load_manager); | 920 DCHECK(load_manager); |
| 901 if (!load_manager) { | 921 if (!load_manager) { |
| 902 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 922 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 903 FROM_HERE, | 923 FROM_HERE, |
| 904 base::Bind(callback.func, callback.user_data, | 924 base::Bind(callback.func, callback.user_data, |
| 905 static_cast<int32_t>(PP_ERROR_FAILED))); | 925 static_cast<int32_t>(PP_ERROR_FAILED))); |
| 906 } | 926 } |
| 907 | 927 |
| 908 const GURL& gurl = load_manager->manifest_base_url(); | 928 const GURL& gurl = load_manager->manifest_base_url(); |
| 909 | 929 blink::WebURLLoader* url_loader = CreateWebURLLoader(instance, gurl); |
| 910 content::PepperPluginInstance* plugin_instance = | 930 blink::WebURLRequest request = CreateWebURLRequest(instance, gurl); |
| 911 content::PepperPluginInstance::Get(instance); | |
| 912 blink::WebURLLoaderOptions options; | |
| 913 options.untrustedHTTP = true; | |
| 914 | |
| 915 blink::WebSecurityOrigin security_origin = | |
| 916 plugin_instance->GetContainer()->element().document().securityOrigin(); | |
| 917 // Options settings here follow the original behavior in the trusted | |
| 918 // plugin and PepperURLLoaderHost. | |
| 919 if (security_origin.canRequest(gurl)) { | |
| 920 options.allowCredentials = true; | |
| 921 } else { | |
| 922 // Allow CORS. | |
| 923 options.crossOriginRequestPolicy = | |
| 924 blink::WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl; | |
| 925 } | |
| 926 | |
| 927 blink::WebFrame* frame = | |
| 928 plugin_instance->GetContainer()->element().document().frame(); | |
| 929 blink::WebURLLoader* url_loader = frame->createAssociatedURLLoader(options); | |
| 930 blink::WebURLRequest request; | |
| 931 request.initialize(); | |
| 932 request.setURL(gurl); | |
| 933 request.setFirstPartyForCookies(frame->document().firstPartyForCookies()); | |
| 934 | 931 |
| 935 // ManifestDownloader deletes itself after invoking the callback. | 932 // ManifestDownloader deletes itself after invoking the callback. |
| 936 ManifestDownloader* client = new ManifestDownloader( | 933 ManifestDownloader* client = new ManifestDownloader( |
| 937 load_manager->is_installed(), | 934 load_manager->is_installed(), |
| 938 base::Bind(DownloadManifestToBufferCompletion, | 935 base::Bind(DownloadManifestToBufferCompletion, |
| 939 instance, callback, out_data, base::Time::Now())); | 936 instance, callback, out_data, base::Time::Now())); |
| 940 url_loader->loadAsynchronously(request, client); | 937 url_loader->loadAsynchronously(request, client); |
| 941 } | 938 } |
| 942 | 939 |
| 943 void DownloadManifestToBufferCompletion(PP_Instance instance, | 940 void DownloadManifestToBufferCompletion(PP_Instance instance, |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1244 } | 1241 } |
| 1245 | 1242 |
| 1246 void PostMessageToJavaScript(PP_Instance instance, const char* message) { | 1243 void PostMessageToJavaScript(PP_Instance instance, const char* message) { |
| 1247 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 1244 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 1248 FROM_HERE, | 1245 FROM_HERE, |
| 1249 base::Bind(&PostMessageToJavaScriptMainThread, | 1246 base::Bind(&PostMessageToJavaScriptMainThread, |
| 1250 instance, | 1247 instance, |
| 1251 std::string(message))); | 1248 std::string(message))); |
| 1252 } | 1249 } |
| 1253 | 1250 |
| 1251 // Encapsulates some of the state for a call to DownloadNexe to prevent | |
| 1252 // argument lists from getting too long. | |
| 1253 struct DownloadNexeRequest { | |
| 1254 PP_Instance instance; | |
| 1255 const char* url; | |
| 1256 PP_CompletionCallback callback; | |
| 1257 base::Time start_time; | |
| 1258 }; | |
| 1259 | |
| 1260 class DownloadNexeProgressTracker { | |
|
bbudge
2014/05/12 22:32:06
I don't see where this is used. Also, it doesn't s
teravest
2014/05/13 17:05:32
Thanks for pointing that out. I'd completely forgo
| |
| 1261 public: | |
| 1262 void ReportProgress(const std::string& url, | |
| 1263 int64_t total_bytes_received, | |
| 1264 int64_t total_bytes_to_be_received) { | |
| 1265 base::Time now = base::Time::Now(); | |
| 1266 if (now - last_event_ > base::TimeDelta::FromMilliseconds(10)) { | |
| 1267 // Actually dispatch the progress event. | |
| 1268 last_event_ = now; | |
| 1269 } | |
| 1270 } | |
| 1271 private: | |
| 1272 base::Time last_event_; | |
| 1273 }; | |
| 1274 | |
| 1275 void DownloadNexeProgress(PP_Instance instance, | |
| 1276 const std::string& url, | |
| 1277 int64_t total_bytes_received, | |
| 1278 int64_t total_bytes_to_be_received); | |
| 1279 | |
| 1280 void DownloadNexeCompletion(const DownloadNexeRequest& request, | |
| 1281 blink::WebURLLoader* loader, | |
| 1282 base::PlatformFile target_file, | |
| 1283 PP_FileHandle* out_handle, | |
| 1284 FileDownloader::Status status, | |
| 1285 int http_status); | |
| 1286 | |
| 1287 void DownloadNexe(PP_Instance instance, | |
| 1288 const char* url, | |
| 1289 PP_FileHandle* out_handle, | |
| 1290 PP_CompletionCallback callback) { | |
| 1291 CHECK(url); | |
| 1292 CHECK(out_handle); | |
| 1293 DownloadNexeRequest request; | |
| 1294 request.instance = instance; | |
| 1295 request.url = url; | |
| 1296 request.callback = callback; | |
| 1297 request.start_time = base::Time::Now(); | |
| 1298 | |
| 1299 // Try the fast path for retrieving the file first. | |
| 1300 uint64_t file_token_lo = 0; | |
| 1301 uint64_t file_token_hi = 0; | |
| 1302 PP_FileHandle file_handle = OpenNaClExecutable(instance, | |
| 1303 url, | |
| 1304 &file_token_lo, | |
| 1305 &file_token_hi); | |
| 1306 | |
| 1307 // We shouldn't hit this if the file URL is in an installed app. | |
|
bbudge
2014/05/12 22:32:06
comment seems wrong.
teravest
2014/05/13 17:05:32
Removed.
| |
| 1308 if (file_handle != PP_kInvalidFileHandle) { | |
| 1309 DownloadNexeCompletion(request, NULL, file_handle, out_handle, | |
| 1310 FileDownloader::SUCCESS, 200); | |
| 1311 return; | |
| 1312 } | |
| 1313 | |
| 1314 // The fast path didn't work, we'll fetch the file using URLLoader and write | |
| 1315 // it to local storage. | |
| 1316 base::PlatformFile target_file = CreateTemporaryFile(instance); | |
| 1317 GURL gurl(url); | |
| 1318 blink::WebURLLoader* url_loader = CreateWebURLLoader(instance, gurl); | |
|
bbudge
2014/05/12 22:32:06
Now that we're in Chrome-land, can we use scoped_p
teravest
2014/05/13 17:05:32
Done.
| |
| 1319 blink::WebURLRequest url_request = CreateWebURLRequest(instance, gurl); | |
| 1320 | |
| 1321 // FileDownloader deletes itself after invoking the callback. | |
| 1322 FileDownloader* client = new FileDownloader( | |
|
bbudge
2014/05/12 22:32:06
'client' is a slightly confusing name.
teravest
2014/05/13 17:05:32
Changed to file_downloader
| |
| 1323 target_file, | |
| 1324 base::Bind(&DownloadNexeCompletion, request, url_loader, target_file, | |
| 1325 out_handle), | |
| 1326 base::Bind(&DownloadNexeProgress, instance, url)); | |
| 1327 url_loader->loadAsynchronously(url_request, client); | |
| 1328 } | |
| 1329 | |
| 1330 void DownloadNexeProgress(PP_Instance instance, | |
| 1331 const std::string& url, | |
| 1332 int64_t total_bytes_received, | |
| 1333 int64_t total_bytes_to_be_received) { | |
| 1334 ProgressEvent event(PP_NACL_EVENT_PROGRESS, | |
| 1335 url, | |
| 1336 total_bytes_to_be_received >= 0, | |
| 1337 total_bytes_received, | |
| 1338 total_bytes_to_be_received); | |
| 1339 DispatchProgressEvent(instance, event); | |
|
bbudge
2014/05/12 22:32:06
Might be a little more readable if you create the
teravest
2014/05/13 17:05:32
Done.
| |
| 1340 } | |
| 1341 | |
| 1342 void DownloadNexeCompletion(const DownloadNexeRequest& request, | |
| 1343 blink::WebURLLoader* loader, | |
|
bbudge
2014/05/12 22:32:06
scoped_ptr<blink::WebURLLoader>?
teravest
2014/05/13 17:05:32
Done.
| |
| 1344 base::PlatformFile target_file, | |
| 1345 PP_FileHandle* out_handle, | |
| 1346 FileDownloader::Status status, | |
| 1347 int http_status) { | |
| 1348 int32_t pp_error; | |
| 1349 switch (status) { | |
| 1350 case FileDownloader::SUCCESS: | |
| 1351 *out_handle = target_file; | |
| 1352 pp_error = PP_OK; | |
| 1353 break; | |
| 1354 case FileDownloader::ACCESS_DENIED: | |
| 1355 pp_error = PP_ERROR_NOACCESS; | |
| 1356 break; | |
| 1357 case FileDownloader::FAILED: | |
| 1358 pp_error = PP_ERROR_FAILED; | |
| 1359 break; | |
| 1360 default: | |
| 1361 NOTREACHED(); | |
| 1362 return; | |
| 1363 } | |
| 1364 delete loader; | |
| 1365 | |
| 1366 int64_t bytes_read = -1; | |
| 1367 if (pp_error == PP_OK && target_file != base::kInvalidPlatformFileValue) { | |
| 1368 base::PlatformFileInfo info; | |
| 1369 if (GetPlatformFileInfo(target_file, &info)) | |
| 1370 bytes_read = info.size; | |
| 1371 } | |
| 1372 | |
| 1373 if (bytes_read == -1) { | |
| 1374 base::ClosePlatformFile(target_file); | |
| 1375 pp_error = PP_ERROR_FAILED; | |
| 1376 } | |
| 1377 | |
| 1378 base::TimeDelta download_time = base::Time::Now() - request.start_time; | |
| 1379 | |
| 1380 NexeLoadManager* load_manager = GetNexeLoadManager(request.instance); | |
| 1381 if (load_manager) { | |
| 1382 load_manager->NexeFileDidOpen(pp_error, | |
| 1383 target_file, | |
| 1384 http_status, | |
| 1385 bytes_read, | |
| 1386 request.url, | |
| 1387 download_time); | |
| 1388 } | |
| 1389 | |
| 1390 request.callback.func(request.callback.user_data, pp_error); | |
| 1391 } | |
| 1392 | |
| 1254 const PPB_NaCl_Private nacl_interface = { | 1393 const PPB_NaCl_Private nacl_interface = { |
| 1255 &LaunchSelLdr, | 1394 &LaunchSelLdr, |
| 1256 &StartPpapiProxy, | 1395 &StartPpapiProxy, |
| 1257 &UrandomFD, | 1396 &UrandomFD, |
| 1258 &Are3DInterfacesDisabled, | 1397 &Are3DInterfacesDisabled, |
| 1259 &BrokerDuplicateHandle, | 1398 &BrokerDuplicateHandle, |
| 1260 &GetReadonlyPnaclFD, | 1399 &GetReadonlyPnaclFD, |
| 1261 &CreateTemporaryFile, | 1400 &CreateTemporaryFile, |
| 1262 &GetNumberOfProcessors, | 1401 &GetNumberOfProcessors, |
| 1263 &IsNonSFIModeEnabled, | 1402 &IsNonSFIModeEnabled, |
| 1264 &GetNexeFd, | 1403 &GetNexeFd, |
| 1265 &ReportTranslationFinished, | 1404 &ReportTranslationFinished, |
| 1266 &OpenNaClExecutable, | 1405 &OpenNaClExecutable, |
| 1267 &DispatchEvent, | 1406 &DispatchEvent, |
| 1268 &NexeFileDidOpen, | |
| 1269 &ReportLoadSuccess, | 1407 &ReportLoadSuccess, |
| 1270 &ReportLoadError, | 1408 &ReportLoadError, |
| 1271 &ReportLoadAbort, | 1409 &ReportLoadAbort, |
| 1272 &NexeDidCrash, | 1410 &NexeDidCrash, |
| 1273 &InstanceCreated, | 1411 &InstanceCreated, |
| 1274 &InstanceDestroyed, | 1412 &InstanceDestroyed, |
| 1275 &NaClDebugEnabledForURL, | 1413 &NaClDebugEnabledForURL, |
| 1276 &GetSandboxArch, | 1414 &GetSandboxArch, |
| 1277 &LogToConsole, | 1415 &LogToConsole, |
| 1278 &GetNaClReadyState, | 1416 &GetNaClReadyState, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1291 &IsPNaCl, | 1429 &IsPNaCl, |
| 1292 &DevInterfacesEnabled, | 1430 &DevInterfacesEnabled, |
| 1293 &DownloadManifestToBuffer, | 1431 &DownloadManifestToBuffer, |
| 1294 &CreatePNaClManifest, | 1432 &CreatePNaClManifest, |
| 1295 &CreateJsonManifest, | 1433 &CreateJsonManifest, |
| 1296 &DestroyManifest, | 1434 &DestroyManifest, |
| 1297 &ManifestGetProgramURL, | 1435 &ManifestGetProgramURL, |
| 1298 &ManifestResolveKey, | 1436 &ManifestResolveKey, |
| 1299 &GetPNaClResourceInfo, | 1437 &GetPNaClResourceInfo, |
| 1300 &GetCpuFeatureAttrs, | 1438 &GetCpuFeatureAttrs, |
| 1301 &PostMessageToJavaScript | 1439 &PostMessageToJavaScript, |
| 1440 &DownloadNexe | |
| 1302 }; | 1441 }; |
| 1303 | 1442 |
| 1304 } // namespace | 1443 } // namespace |
| 1305 | 1444 |
| 1306 const PPB_NaCl_Private* GetNaClPrivateInterface() { | 1445 const PPB_NaCl_Private* GetNaClPrivateInterface() { |
| 1307 return &nacl_interface; | 1446 return &nacl_interface; |
| 1308 } | 1447 } |
| 1309 | 1448 |
| 1310 } // namespace nacl | 1449 } // namespace nacl |
| OLD | NEW |