summaryrefslogtreecommitdiff
path: root/ppapi
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2014-04-24 10:50:13 +0100
committerBen Murdoch <benm@google.com>2014-04-24 10:50:13 +0100
commit0529e5d033099cbfc42635f6f6183833b09dff6e (patch)
treebadea60062e611382d8a37e3b0bfda8d69760c2b /ppapi
parent8346740f6fb555ccbb9b4148ab63402ae8f6e4ca (diff)
downloadchromium_org-0529e5d033099cbfc42635f6f6183833b09dff6e.tar.gz
Merge from Chromium at DEPS revision 265802
This commit was generated by merge_to_master.py. Change-Id: I6fac2dbbce472b18ca943b6e6f247835b0bd6281
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/api/private/ppb_nacl_private.idl56
-rw-r--r--ppapi/c/private/ppb_nacl_private.h85
-rw-r--r--ppapi/cpp/private/find_private.cc6
-rw-r--r--ppapi/nacl_irt/irt_start.cc4
-rw-r--r--ppapi/nacl_irt/manifest_service.cc34
-rw-r--r--ppapi/nacl_irt/manifest_service.h43
-rw-r--r--ppapi/nacl_irt/plugin_main.cc6
-rw-r--r--ppapi/nacl_irt/plugin_startup.cc55
-rw-r--r--ppapi/nacl_irt/plugin_startup.h10
-rw-r--r--ppapi/nacl_irt/ppapi_dispatcher.cc7
-rw-r--r--ppapi/native_client/src/trusted/plugin/file_downloader.cc72
-rw-r--r--ppapi/native_client/src/trusted/plugin/file_downloader.h18
-rw-r--r--ppapi/native_client/src/trusted/plugin/json_manifest.cc33
-rw-r--r--ppapi/native_client/src/trusted/plugin/json_manifest.h11
-rw-r--r--ppapi/native_client/src/trusted/plugin/manifest.h7
-rw-r--r--ppapi/native_client/src/trusted/plugin/nacl_entry_points.h3
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.cc179
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.gypi1
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.h20
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc14
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h8
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_options.cc52
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_options.h44
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc24
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h7
-rw-r--r--ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc27
-rw-r--r--ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h3
-rw-r--r--ppapi/native_client/src/trusted/plugin/service_runtime.cc74
-rw-r--r--ppapi/native_client/src/untrusted/irt_stub/thread_creator.h8
-rw-r--r--ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c58
-rw-r--r--ppapi/native_client/tests/nacl_browser/fault_injection/fault_pm_nameservice_test.cc34
-rw-r--r--ppapi/ppapi_proxy.gypi2
-rw-r--r--ppapi/proxy/file_system_resource_unittest.cc40
-rw-r--r--ppapi/proxy/ppapi_command_buffer_proxy.cc1
-rw-r--r--ppapi/proxy/ppapi_messages.h3
-rw-r--r--ppapi/proxy/ppb_audio_proxy.cc2
-rw-r--r--ppapi/proxy/ppb_instance_proxy.cc5
-rw-r--r--ppapi/shared_impl/ppb_audio_shared.cc107
-rw-r--r--ppapi/shared_impl/ppb_audio_shared.h24
-rw-r--r--ppapi/tests/DEPS5
-rw-r--r--ppapi/tests/test_audio.cc167
-rw-r--r--ppapi/tests/test_audio.h5
42 files changed, 803 insertions, 561 deletions
diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl
index 418310dc2b..4bc02e0749 100644
--- a/ppapi/api/private/ppb_nacl_private.idl
+++ b/ppapi/api/private/ppb_nacl_private.idl
@@ -133,6 +133,27 @@ enum PP_NaClReadyState {
PP_NACL_READY_STATE_DONE = 4
};
+struct PP_PNaClOptions {
+ PP_Bool translate;
+ PP_Bool is_debug;
+ int32_t opt_level;
+};
+
+/* ManifestService to support irt_open_resource() function.
+ * All functions of the service should have PP_Bool return value. It represents
+ * whether the service is still alive or not. Trivially Quit() should always
+ * return false. However, other functions also can return false.
+ * Once false is called, as the service has been destructed, all functions
+ * should never be called afterwords.
+ */
+interface PP_ManifestService {
+ /* Called when ManifestService should be destructed. */
+ PP_Bool Quit([inout] mem_t user_data);
+
+ /* Called when PPAPI initialization in the NaCl plugin is finished. */
+ PP_Bool StartupInitializationComplete([inout] mem_t user_data);
+};
+
/* PPB_NaCl_Private */
interface PPB_NaCl_Private {
/* Launches NaCl's sel_ldr process. Returns PP_EXTERNAL_PLUGIN_OK on success
@@ -163,6 +184,8 @@ interface PPB_NaCl_Private {
[in] PP_Bool enable_dyncode_syscalls,
[in] PP_Bool enable_exception_handling,
[in] PP_Bool enable_crash_throttling,
+ [in] PP_ManifestService manifest_service_interface,
+ [inout] mem_t manifest_service_user_data,
[out] mem_t imc_handle,
[out] PP_Var error_message,
[in] PP_CompletionCallback callback);
@@ -325,17 +348,9 @@ interface PPB_NaCl_Private {
/* Returns the NaCl readiness status for this instance. */
PP_NaClReadyState GetNaClReadyState([in] PP_Instance instance);
- /* Sets the NaCl readiness status for this instance. */
- void SetNaClReadyState([in] PP_Instance instance,
- [in] PP_NaClReadyState ready_state);
-
/* Returns true if the plugin is an installed app. */
PP_Bool GetIsInstalled([in] PP_Instance instance);
- /* Sets whether the plugin is an installed app. */
- void SetIsInstalled([in] PP_Instance instance,
- [in] PP_Bool is_installed);
-
/* Returns the exit status of the plugin process. */
int32_t GetExitStatus([in] PP_Instance instance);
@@ -346,13 +361,28 @@ interface PPB_NaCl_Private {
/* Logs the message via VLOG. */
void Vlog([in] str_t message);
- /* Sets the time the plugin was initialized. */
- void SetInitTime([in] PP_Instance instance);
+ /* Initializes internal state for a NaCl plugin. */
+ void InitializePlugin([in] PP_Instance instance);
/* Returns the size of the nexe. */
int64_t GetNexeSize([in] PP_Instance instance);
- /* Sets the size of the nexe. */
- void SetNexeSize([in] PP_Instance instance,
- [in] int64_t nexe_size);
+ /* Performs accounting for requesting the NaCl manifest at the given URL. */
+ PP_Bool RequestNaClManifest([in] PP_Instance instance,
+ [in] str_t manifest_url,
+ [out] PP_Bool is_data_uri);
+
+ PP_Var GetManifestBaseURL([in] PP_Instance instance);
+
+ PP_Bool ResolvesRelativeToPluginBaseUrl([in] PP_Instance instance,
+ [in] str_t url);
+
+ PP_Var ParseDataURL([in] str_t data_url);
+
+ /* Processes the NaCl manifest once it's been retrieved.
+ * TODO(teravest): Move the rest of the supporting logic out of the trusted
+ * plugin.
+ */
+ void ProcessNaClManifest([in] PP_Instance instance,
+ [in] str_t program_url);
};
diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h
index 709463e159..ab85b738d7 100644
--- a/ppapi/c/private/ppb_nacl_private.h
+++ b/ppapi/c/private/ppb_nacl_private.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From private/ppb_nacl_private.idl modified Tue Apr 15 09:24:03 2014. */
+/* From private/ppb_nacl_private.idl modified Wed Apr 23 12:56:55 2014. */
#ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
#define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
@@ -15,6 +15,9 @@
#include "ppapi/c/pp_stdint.h"
#include "ppapi/c/pp_var.h"
+#define PP_MANIFESTSERVICE_INTERFACE_1_0 "PP_ManifestService;1.0"
+#define PP_MANIFESTSERVICE_INTERFACE PP_MANIFESTSERVICE_INTERFACE_1_0
+
#define PPB_NACL_PRIVATE_INTERFACE_1_0 "PPB_NaCl_Private;1.0"
#define PPB_NACL_PRIVATE_INTERFACE PPB_NACL_PRIVATE_INTERFACE_1_0
@@ -152,9 +155,38 @@ typedef enum {
*/
/**
+ * @addtogroup Structs
+ * @{
+ */
+struct PP_PNaClOptions {
+ PP_Bool translate;
+ PP_Bool is_debug;
+ int32_t opt_level;
+};
+/**
+ * @}
+ */
+
+/**
* @addtogroup Interfaces
* @{
*/
+/* ManifestService to support irt_open_resource() function.
+ * All functions of the service should have PP_Bool return value. It represents
+ * whether the service is still alive or not. Trivially Quit() should always
+ * return false. However, other functions also can return false.
+ * Once false is called, as the service has been destructed, all functions
+ * should never be called afterwords.
+ */
+struct PP_ManifestService_1_0 {
+ /* Called when ManifestService should be destructed. */
+ PP_Bool (*Quit)(void* user_data);
+ /* Called when PPAPI initialization in the NaCl plugin is finished. */
+ PP_Bool (*StartupInitializationComplete)(void* user_data);
+};
+
+typedef struct PP_ManifestService_1_0 PP_ManifestService;
+
/* PPB_NaCl_Private */
struct PPB_NaCl_Private_1_0 {
/* Launches NaCl's sel_ldr process. Returns PP_EXTERNAL_PLUGIN_OK on success
@@ -176,18 +208,21 @@ struct PPB_NaCl_Private_1_0 {
* the nexe contribute to crash throttling statisics and whether nexe starts
* are throttled by crash throttling.
*/
- void (*LaunchSelLdr)(PP_Instance instance,
- const char* alleged_url,
- PP_Bool uses_irt,
- PP_Bool uses_ppapi,
- PP_Bool uses_nonsfi_mode,
- PP_Bool enable_ppapi_dev,
- PP_Bool enable_dyncode_syscalls,
- PP_Bool enable_exception_handling,
- PP_Bool enable_crash_throttling,
- void* imc_handle,
- struct PP_Var* error_message,
- struct PP_CompletionCallback callback);
+ void (*LaunchSelLdr)(
+ PP_Instance instance,
+ const char* alleged_url,
+ PP_Bool uses_irt,
+ PP_Bool uses_ppapi,
+ PP_Bool uses_nonsfi_mode,
+ PP_Bool enable_ppapi_dev,
+ PP_Bool enable_dyncode_syscalls,
+ PP_Bool enable_exception_handling,
+ PP_Bool enable_crash_throttling,
+ const struct PP_ManifestService_1_0* manifest_service_interface,
+ void* manifest_service_user_data,
+ void* imc_handle,
+ struct PP_Var* error_message,
+ struct PP_CompletionCallback callback);
/* This function starts the IPC proxy so the nexe can communicate with the
* browser.
*/
@@ -318,25 +353,31 @@ struct PPB_NaCl_Private_1_0 {
void (*LogToConsole)(PP_Instance instance, const char* message);
/* Returns the NaCl readiness status for this instance. */
PP_NaClReadyState (*GetNaClReadyState)(PP_Instance instance);
- /* Sets the NaCl readiness status for this instance. */
- void (*SetNaClReadyState)(PP_Instance instance,
- PP_NaClReadyState ready_state);
/* Returns true if the plugin is an installed app. */
PP_Bool (*GetIsInstalled)(PP_Instance instance);
- /* Sets whether the plugin is an installed app. */
- void (*SetIsInstalled)(PP_Instance instance, PP_Bool is_installed);
/* Returns the exit status of the plugin process. */
int32_t (*GetExitStatus)(PP_Instance instance);
/* Sets the exit status of the plugin process. */
void (*SetExitStatus)(PP_Instance instance, int32_t exit_status);
/* Logs the message via VLOG. */
void (*Vlog)(const char* message);
- /* Sets the time the plugin was initialized. */
- void (*SetInitTime)(PP_Instance instance);
+ /* Initializes internal state for a NaCl plugin. */
+ void (*InitializePlugin)(PP_Instance instance);
/* Returns the size of the nexe. */
int64_t (*GetNexeSize)(PP_Instance instance);
- /* Sets the size of the nexe. */
- void (*SetNexeSize)(PP_Instance instance, int64_t nexe_size);
+ /* Performs accounting for requesting the NaCl manifest at the given URL. */
+ PP_Bool (*RequestNaClManifest)(PP_Instance instance,
+ const char* manifest_url,
+ PP_Bool* is_data_uri);
+ struct PP_Var (*GetManifestBaseURL)(PP_Instance instance);
+ PP_Bool (*ResolvesRelativeToPluginBaseUrl)(PP_Instance instance,
+ const char* url);
+ struct PP_Var (*ParseDataURL)(const char* data_url);
+ /* Processes the NaCl manifest once it's been retrieved.
+ * TODO(teravest): Move the rest of the supporting logic out of the trusted
+ * plugin.
+ */
+ void (*ProcessNaClManifest)(PP_Instance instance, const char* program_url);
};
typedef struct PPB_NaCl_Private_1_0 PPB_NaCl_Private;
diff --git a/ppapi/cpp/private/find_private.cc b/ppapi/cpp/private/find_private.cc
index 440bc7444c..2765ae02eb 100644
--- a/ppapi/cpp/private/find_private.cc
+++ b/ppapi/cpp/private/find_private.cc
@@ -86,12 +86,12 @@ void Find_Private::SelectedFindResultChanged(int32_t index) {
void Find_Private::SetTickmarks(const std::vector<pp::Rect>& tickmarks) {
if (has_interface<PPB_Find_Private>()) {
- if (tickmarks.empty())
- return;
std::vector<PP_Rect> tickmarks_converted(tickmarks.begin(),
tickmarks.end());
+ PP_Rect* array =
+ tickmarks_converted.empty() ? NULL : &tickmarks_converted[0];
get_interface<PPB_Find_Private>()->SetTickmarks(
- associated_instance_.pp_instance(), &tickmarks_converted[0],
+ associated_instance_.pp_instance(), array,
static_cast<uint32_t>(tickmarks.size()));
}
}
diff --git a/ppapi/nacl_irt/irt_start.cc b/ppapi/nacl_irt/irt_start.cc
index a286737882..a7c12e6c31 100644
--- a/ppapi/nacl_irt/irt_start.cc
+++ b/ppapi/nacl_irt/irt_start.cc
@@ -17,7 +17,9 @@ void nacl_irt_start(uint32_t* info) {
// In SFI mode, the FDs of IPC channels are NACL_CHROME_DESC_BASE and its
// successor, which is set in nacl_listener.cc.
ppapi::SetIPCFileDescriptors(
- NACL_CHROME_DESC_BASE, NACL_CHROME_DESC_BASE + 1);
+ NACL_CHROME_DESC_BASE,
+ NACL_CHROME_DESC_BASE + 1,
+ -1); // Currently manifest service is disabled on NaCl in SFI mode.
ppapi::StartUpPlugin();
nacl_irt_enter_user_code(info, chrome_irt_query);
diff --git a/ppapi/nacl_irt/manifest_service.cc b/ppapi/nacl_irt/manifest_service.cc
new file mode 100644
index 0000000000..ed7c4ebf96
--- /dev/null
+++ b/ppapi/nacl_irt/manifest_service.cc
@@ -0,0 +1,34 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/nacl_irt/manifest_service.h"
+
+#include "base/message_loop/message_loop_proxy.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_channel_proxy.h"
+#include "ipc/ipc_sync_message_filter.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace ppapi {
+
+ManifestService::ManifestService(
+ const IPC::ChannelHandle& handle,
+ scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ base::WaitableEvent* shutdown_event) {
+ filter_ = new IPC::SyncMessageFilter(shutdown_event);
+ channel_.reset(new IPC::ChannelProxy(handle,
+ IPC::Channel::MODE_SERVER,
+ NULL, // Listener
+ io_message_loop));
+ channel_->AddFilter(filter_.get());
+}
+
+ManifestService::~ManifestService() {
+}
+
+void ManifestService::StartupInitializationComplete() {
+ filter_->Send(new PpapiHostMsg_StartupInitializationComplete);
+}
+
+} // namespace ppapi
diff --git a/ppapi/nacl_irt/manifest_service.h b/ppapi/nacl_irt/manifest_service.h
new file mode 100644
index 0000000000..ec5e38c979
--- /dev/null
+++ b/ppapi/nacl_irt/manifest_service.h
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_NACL_IRT_MANIFEST_SERVICE_H_
+#define PPAPI_NACL_IRT_MANIFEST_SERVICE_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class MessageLoopProxy;
+class WaitableEvent;
+} // namespace base
+
+namespace IPC {
+struct ChannelHandle;
+class ChannelProxy;
+class SyncMessageFilter;
+} // namespace IPC
+
+namespace ppapi {
+
+class ManifestService {
+ public:
+ ManifestService(const IPC::ChannelHandle& handle,
+ scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ base::WaitableEvent* shutdown_event);
+ ~ManifestService();
+
+ void StartupInitializationComplete();
+
+ private:
+ scoped_ptr<IPC::ChannelProxy> channel_;
+ scoped_refptr<IPC::SyncMessageFilter> filter_;
+
+ DISALLOW_COPY_AND_ASSIGN(ManifestService);
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_NACL_IRT_MANIFEST_SERVICE_H_
diff --git a/ppapi/nacl_irt/plugin_main.cc b/ppapi/nacl_irt/plugin_main.cc
index eeeb50b737..668f67a3b0 100644
--- a/ppapi/nacl_irt/plugin_main.cc
+++ b/ppapi/nacl_irt/plugin_main.cc
@@ -24,15 +24,9 @@
void PpapiPluginRegisterThreadCreator(
const struct PP_ThreadFunctions* thread_functions) {
-#if defined(__native_client__)
- // TODO(hidehiko): The thread creation for the PPB_Audio is not yet
- // implemented on non-SFI mode. Support this. Now, this function invocation
- // is just ignored.
-
// Initialize all classes that need to create threads that call back into
// user code.
ppapi::PPB_Audio_Shared::SetThreadFunctions(thread_functions);
-#endif
}
int PpapiPluginMain() {
diff --git a/ppapi/nacl_irt/plugin_startup.cc b/ppapi/nacl_irt/plugin_startup.cc
index a3b5bc207e..2061fc831e 100644
--- a/ppapi/nacl_irt/plugin_startup.cc
+++ b/ppapi/nacl_irt/plugin_startup.cc
@@ -2,28 +2,59 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ppapi/nacl_irt/plugin_startup.h"
+
+#include "base/bind.h"
+#include "base/file_descriptor_posix.h"
#include "base/logging.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
-#include "ppapi/nacl_irt/plugin_startup.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ppapi/nacl_irt/manifest_service.h"
+#include "ppapi/shared_impl/ppb_audio_shared.h"
namespace ppapi {
namespace {
int g_nacl_browser_ipc_fd = -1;
int g_nacl_renderer_ipc_fd = -1;
+int g_manifest_service_fd = -1;
base::WaitableEvent* g_shutdown_event = NULL;
base::Thread* g_io_thread = NULL;
+ManifestService* g_manifest_service = NULL;
+
+// Creates the manifest service on IO thread so that its Listener's thread and
+// IO thread are shared. Upon completion of the manifest service creation,
+// event is signaled.
+void StartUpManifestServiceOnIOThread(base::WaitableEvent* event) {
+ // The start up must be called only once.
+ DCHECK(!g_manifest_service);
+ // manifest_service_fd must be set.
+ DCHECK_NE(g_manifest_service_fd, -1);
+ // IOThread and shutdown event must be initialized in advance.
+ DCHECK(g_io_thread);
+ DCHECK(g_shutdown_event);
+
+ g_manifest_service = new ManifestService(
+ IPC::ChannelHandle(
+ "NaCl IPC", base::FileDescriptor(g_manifest_service_fd, false)),
+ g_io_thread->message_loop_proxy(),
+ g_shutdown_event);
+ event->Signal();
+}
} // namespace
-void SetIPCFileDescriptors(int browser_ipc_fd, int renderer_ipc_fd) {
+void SetIPCFileDescriptors(
+ int browser_ipc_fd, int renderer_ipc_fd, int manifest_service_fd) {
// The initialization must be only once.
DCHECK_EQ(g_nacl_browser_ipc_fd, -1);
DCHECK_EQ(g_nacl_renderer_ipc_fd, -1);
+ DCHECK_EQ(g_manifest_service_fd, -1);
g_nacl_browser_ipc_fd = browser_ipc_fd;
g_nacl_renderer_ipc_fd = renderer_ipc_fd;
+ g_manifest_service_fd = manifest_service_fd;
}
void StartUpPlugin() {
@@ -35,6 +66,22 @@ void StartUpPlugin() {
g_io_thread = new base::Thread("Chrome_NaClIOThread");
g_io_thread->StartWithOptions(
base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
+
+ if (g_manifest_service_fd != -1) {
+ // Manifest service must be created on IOThread so that the main message
+ // handling will be done on the thread, which has a message loop
+ // even before irt_ppapi_start invocation.
+ // TODO(hidehiko,dmichael): This works, but is probably not well designed
+ // usage. Once a better approach is made, replace this by that way.
+ // (crbug.com/364241).
+ base::WaitableEvent event(true, false);
+ g_io_thread->message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(StartUpManifestServiceOnIOThread, &event));
+ event.Wait();
+ }
+
+ PPB_Audio_Shared::SetNaClMode();
}
int GetBrowserIPCFileDescriptor() {
@@ -61,4 +108,8 @@ base::Thread* GetIOThread() {
return g_io_thread;
}
+ManifestService* GetManifestService() {
+ return g_manifest_service;
+}
+
} // namespace ppapi
diff --git a/ppapi/nacl_irt/plugin_startup.h b/ppapi/nacl_irt/plugin_startup.h
index 73c34957a4..ea14836e60 100644
--- a/ppapi/nacl_irt/plugin_startup.h
+++ b/ppapi/nacl_irt/plugin_startup.h
@@ -14,11 +14,13 @@ class WaitableEvent;
namespace ppapi {
+class ManifestService;
+
// Sets the IPC channels for the browser and the renderer by the given FD
// numbers. This will be used for non-SFI mode. Must be called before
// PpapiPluginMain is called.
PPAPI_PROXY_EXPORT void SetIPCFileDescriptors(
- int browser_ipc_fd, int renderer_ipc_fd);
+ int browser_ipc_fd, int renderer_ipc_fd, int manifest_service_fd);
// Runs start up procedure for the plugin.
// Specifically, start background IO thread for IPC, and prepare
@@ -38,6 +40,12 @@ base::WaitableEvent* GetShutdownEvent();
// Returns the IOThread for the plugin. Must be called after StartUpPlugin().
base::Thread* GetIOThread();
+// Returns the ManifestService interface. To use this, manifest_service_fd
+// needs to be set via SetIPCFileDescriptors. Must be called after
+// StartUpPlugin().
+// If not available, returns NULL.
+ManifestService* GetManifestService();
+
} // namespace ppapi
#endif // PPAPI_NACL_IRT_PLUGIN_STARTUP_H_
diff --git a/ppapi/nacl_irt/ppapi_dispatcher.cc b/ppapi/nacl_irt/ppapi_dispatcher.cc
index c0aa400037..9ca76b28b8 100644
--- a/ppapi/nacl_irt/ppapi_dispatcher.cc
+++ b/ppapi/nacl_irt/ppapi_dispatcher.cc
@@ -23,6 +23,8 @@
#include "ipc/ipc_message.h"
#include "ppapi/c/ppp.h"
#include "ppapi/c/ppp_instance.h"
+#include "ppapi/nacl_irt/manifest_service.h"
+#include "ppapi/nacl_irt/plugin_startup.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/plugin_message_filter.h"
@@ -199,6 +201,11 @@ void PpapiDispatcher::OnMsgInitializeNaClDispatcher(
}
// From here, the dispatcher will manage its own lifetime according to the
// lifetime of the attached channel.
+
+ // Notify the renderer process, if necessary.
+ ManifestService* manifest_service = GetManifestService();
+ if (manifest_service)
+ manifest_service->StartupInitializationComplete();
}
void PpapiDispatcher::OnPluginDispatcherMessageReceived(
diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.cc b/ppapi/native_client/src/trusted/plugin/file_downloader.cc
index 9bfe0e9736..1118e1dba3 100644
--- a/ppapi/native_client/src/trusted/plugin/file_downloader.cc
+++ b/ppapi/native_client/src/trusted/plugin/file_downloader.cc
@@ -23,9 +23,6 @@
namespace {
-const int32_t kExtensionUrlRequestStatusOk = 200;
-const int32_t kDataUriRequestStatusOk = 0;
-
struct NaClFileInfo NoFileInfo() {
struct NaClFileInfo info;
memset(&info, 0, sizeof(info));
@@ -125,12 +122,10 @@ bool FileDownloader::Open(
return false;
CHECK(instance_ != NULL);
- open_time_ = NaClGetTimeOfDayMicroseconds();
status_code_ = -1;
url_ = url;
file_open_notify_callback_ = callback;
mode_ = mode;
- buffer_.clear();
file_info_.FreeResources();
pp::URLRequestInfo url_request(instance_);
@@ -149,34 +144,10 @@ bool FileDownloader::Open(
// Note that we have the only reference to the underlying objects, so
// this will implicitly close any pending IO and destroy them.
url_loader_ = pp::URLLoader(instance_);
- pp::Var url_var = pp::Var(url);
- url_scheme_ = instance_->nacl_interface()->GetUrlScheme(url_var.pp_var());
- bool grant_universal_access = false;
- if (url_scheme_ == PP_SCHEME_DATA) {
- // TODO(elijahtaylor) Remove this when data URIs can be read without
- // universal access.
- // https://bugs.webkit.org/show_bug.cgi?id=17352
- if (mode_ == DOWNLOAD_TO_BUFFER) {
- grant_universal_access = true;
- } else {
- // Open is to invoke a callback on success or failure. Schedule
- // it asynchronously to follow PPAPI's convention and avoid reentrancy.
- pp::Core* core = pp::Module::Get()->core();
- core->CallOnMainThread(0, callback, PP_ERROR_NOACCESS);
- PLUGIN_PRINTF(("FileDownloader::Open (pp_error=PP_ERROR_NOACCESS)\n"));
- return true;
- }
- }
url_request.SetRecordDownloadProgress(record_progress);
if (url_loader_trusted_interface_ != NULL) {
- if (grant_universal_access) {
- // TODO(sehr,jvoung): See if we can remove this -- currently
- // only used for data URIs.
- url_loader_trusted_interface_->GrantUniversalAccess(
- url_loader_.pp_resource());
- }
if (progress_callback != NULL) {
url_loader_trusted_interface_->RegisterStatusCallback(
url_loader_.pp_resource(), progress_callback);
@@ -211,7 +182,6 @@ void FileDownloader::OpenFast(const nacl::string& url,
file_info_.FreeResources();
CHECK(instance_ != NULL);
- open_time_ = NaClGetTimeOfDayMicroseconds();
status_code_ = NACL_HTTP_STATUS_OK;
url_ = url;
mode_ = DOWNLOAD_NONE;
@@ -236,15 +206,6 @@ NaClFileInfo FileDownloader::GetFileInfo() {
return info_to_return;
}
-int64_t FileDownloader::TimeSinceOpenMilliseconds() const {
- int64_t now = NaClGetTimeOfDayMicroseconds();
- // If Open() wasn't called or we somehow return an earlier time now, just
- // return the 0 rather than worse nonsense values.
- if (open_time_ < 0 || now < open_time_)
- return 0;
- return (now - open_time_) / NACL_MICROS_PER_MILLI;
-}
-
bool FileDownloader::InitialResponseIsValid() {
// Process the response, validating the headers to confirm successful loading.
url_response_ = url_loader_.GetResponseInfo();
@@ -262,30 +223,10 @@ bool FileDownloader::InitialResponseIsValid() {
}
full_url_ = full_url.AsString();
- // Note that URLs in the data-URI scheme produce different error
- // codes than other schemes. This is because data-URI are really a
- // special kind of file scheme, and therefore do not produce HTTP
- // status codes.
- bool status_ok = false;
status_code_ = url_response_.GetStatusCode();
- switch (url_scheme_) {
- case PP_SCHEME_CHROME_EXTENSION:
- PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (chrome-extension "
- "response status_code=%" NACL_PRId32 ")\n", status_code_));
- status_ok = (status_code_ == kExtensionUrlRequestStatusOk);
- break;
- case PP_SCHEME_DATA:
- PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (data URI "
- "response status_code=%" NACL_PRId32 ")\n", status_code_));
- status_ok = (status_code_ == kDataUriRequestStatusOk);
- break;
- case PP_SCHEME_OTHER:
- PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (HTTP response "
- "status_code=%" NACL_PRId32 ")\n", status_code_));
- status_ok = (status_code_ == NACL_HTTP_STATUS_OK);
- break;
- }
- return status_ok;
+ PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid ("
+ "response status_code=%" NACL_PRId32 ")\n", status_code_));
+ return status_code_ == NACL_HTTP_STATUS_OK;
}
void FileDownloader::URLLoadStartNotify(int32_t pp_error) {
@@ -356,8 +297,7 @@ void FileDownloader::URLLoadFinishNotify(int32_t pp_error) {
// Validate response again on load (though it should be the same
// as it was during InitialResponseIsValid?).
url_response_ = url_loader_.GetResponseInfo();
- CHECK(url_response_.GetStatusCode() == NACL_HTTP_STATUS_OK ||
- url_response_.GetStatusCode() == kExtensionUrlRequestStatusOk);
+ CHECK(url_response_.GetStatusCode() == NACL_HTTP_STATUS_OK);
// Record the full url from the response.
pp::Var full_url = url_response_.GetURL();
@@ -403,9 +343,7 @@ void FileDownloader::URLReadBodyNotify(int32_t pp_error) {
}
StreamFinishNotify(PP_OK);
} else {
- if (mode_ == DOWNLOAD_TO_BUFFER) {
- buffer_.insert(buffer_.end(), &temp_buffer_[0], &temp_buffer_[pp_error]);
- } else if (mode_ == DOWNLOAD_TO_BUFFER_AND_STREAM) {
+ if (mode_ == DOWNLOAD_TO_BUFFER_AND_STREAM) {
PLUGIN_PRINTF(("Running data_stream_callback, temp_buffer_=%p\n",
&temp_buffer_[0]));
StreamCallback cb = data_stream_callback_source_->GetCallback();
diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.h b/ppapi/native_client/src/trusted/plugin/file_downloader.h
index 86fa6ea4bd..fa70a700be 100644
--- a/ppapi/native_client/src/trusted/plugin/file_downloader.h
+++ b/ppapi/native_client/src/trusted/plugin/file_downloader.h
@@ -27,7 +27,6 @@ class Plugin;
typedef enum {
DOWNLOAD_TO_FILE = 0,
- DOWNLOAD_TO_BUFFER,
DOWNLOAD_TO_BUFFER_AND_STREAM,
DOWNLOAD_NONE
} DownloadMode;
@@ -79,9 +78,7 @@ class FileDownloader {
stream_finish_callback_(pp::BlockUntilComplete()),
file_io_private_interface_(NULL),
url_loader_trusted_interface_(NULL),
- open_time_(-1),
mode_(DOWNLOAD_NONE),
- url_scheme_(PP_SCHEME_OTHER),
data_stream_callback_source_(NULL) {}
~FileDownloader() {}
@@ -133,9 +130,6 @@ class FileDownloader {
// delegate does not have to close it.
struct NaClFileInfo GetFileInfo();
- // Returns the time delta between the call to Open() and this function.
- int64_t TimeSinceOpenMilliseconds() const;
-
// Returns the url passed to Open().
const nacl::string& url() const { return url_; }
@@ -161,9 +155,6 @@ class FileDownloader {
bool GetDownloadProgress(int64_t* bytes_received,
int64_t* total_bytes_to_be_received) const;
- // Returns the buffer used for DOWNLOAD_TO_BUFFER mode.
- const std::deque<char>& buffer() const { return buffer_; }
-
int status_code() const { return status_code_; }
nacl::string GetResponseHeaders() const;
@@ -178,14 +169,12 @@ class FileDownloader {
// 1) Ask the browser to start streaming |url_| as a file.
// 2) Ask the browser to finish streaming if headers indicate success.
// 3) Ask the browser to open the file, so we can get the file descriptor.
- // For DOWNLOAD_TO_BUFFER, the process is very similar:
+ // For DOWNLOAD_TO_BUFFER_AND_STREAM, the process is very similar:
// 1) Ask the browser to start streaming |url_| to an internal buffer.
// 2) Ask the browser to finish streaming to |temp_buffer_| on success.
- // 3) Wait for streaming to finish, filling |buffer_| incrementally.
+ // 3) Wait for streaming to finish, passing the data directly to the user.
// Each step is done asynchronously using callbacks. We create callbacks
// through a factory to take advantage of ref-counting.
- // DOWNLOAD_STREAM is similar to DOWNLOAD_TO_BUFFER except the downloaded
- // data is passed directly to the user instead of saved in a buffer.
// The public Open*() functions start step 1), and the public FinishStreaming
// function proceeds to step 2) and 3).
bool InitialResponseIsValid();
@@ -208,13 +197,10 @@ class FileDownloader {
const PPB_URLLoaderTrusted* url_loader_trusted_interface_;
pp::URLLoader url_loader_;
pp::CompletionCallbackFactory<FileDownloader> callback_factory_;
- int64_t open_time_;
int32_t status_code_;
DownloadMode mode_;
static const uint32_t kTempBufferSize = 16384;
std::vector<char> temp_buffer_;
- std::deque<char> buffer_;
- PP_UrlSchemeType url_scheme_;
StreamCallbackSource* data_stream_callback_source_;
NaClFileInfoAutoCloser file_info_;
};
diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.cc b/ppapi/native_client/src/trusted/plugin/json_manifest.cc
index 4ab502345f..1fb51ea40c 100644
--- a/ppapi/native_client/src/trusted/plugin/json_manifest.cc
+++ b/ppapi/native_client/src/trusted/plugin/json_manifest.cc
@@ -15,10 +15,10 @@
#include "native_client/src/include/nacl_string.h"
#include "native_client/src/include/portability.h"
#include "native_client/src/shared/platform/nacl_check.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
#include "ppapi/cpp/dev/url_util_dev.h"
#include "ppapi/cpp/var.h"
#include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
-#include "ppapi/native_client/src/trusted/plugin/pnacl_options.h"
#include "ppapi/native_client/src/trusted/plugin/utility.h"
#include "third_party/jsoncpp/source/include/json/reader.h"
@@ -381,15 +381,20 @@ bool IsValidISADictionary(const Json::Value& dictionary,
return true;
}
-void GrabUrlAndPnaclOptions(const Json::Value& url_spec,
+void GrabUrlAndPNaClOptions(const Json::Value& url_spec,
nacl::string* url,
- PnaclOptions* pnacl_options) {
+ PP_PNaClOptions* pnacl_options) {
*url = url_spec[kUrlKey].asString();
- pnacl_options->set_translate(true);
+ pnacl_options->translate = PP_TRUE;
if (url_spec.isMember(kOptLevelKey)) {
int32_t opt_raw = url_spec[kOptLevelKey].asInt();
- // set_opt_level will normalize the values.
- pnacl_options->set_opt_level(opt_raw);
+ int32_t opt_level;
+ // Currently only allow 0 or 2, since that is what we test.
+ if (opt_raw <= 0)
+ opt_level = 0;
+ else
+ opt_level = 2;
+ pnacl_options->opt_level = opt_level;
}
}
@@ -503,7 +508,7 @@ bool JsonManifest::MatchesSchema(ErrorInfo* error_info) {
bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary,
const nacl::string& parent_key,
nacl::string* url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
bool* uses_nonsfi_mode,
ErrorInfo* error_info) const {
DCHECK(url != NULL && pnacl_options != NULL && error_info != NULL);
@@ -546,14 +551,14 @@ bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary,
// If found, mark that it is a debug URL. Otherwise, fall back to
// checking for pnacl-translate URLs, etc. and don't mark it as a debug URL.
if (pnacl_debug_ && isa_spec.isMember(kPnaclDebugKey)) {
- GrabUrlAndPnaclOptions(isa_spec[kPnaclDebugKey], url, pnacl_options);
- pnacl_options->set_debug(true);
+ GrabUrlAndPNaClOptions(isa_spec[kPnaclDebugKey], url, pnacl_options);
+ pnacl_options->is_debug = PP_TRUE;
} else if (isa_spec.isMember(kPnaclTranslateKey)) {
- GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options);
+ GrabUrlAndPNaClOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options);
} else {
// NaCl
*url = isa_spec[kUrlKey].asString();
- pnacl_options->set_translate(false);
+ pnacl_options->translate = PP_FALSE;
}
return true;
@@ -562,7 +567,7 @@ bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary,
bool JsonManifest::GetKeyUrl(const Json::Value& dictionary,
const nacl::string& key,
nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
ErrorInfo* error_info) const {
DCHECK(full_url != NULL && pnacl_options != NULL && error_info != NULL);
if (!dictionary.isMember(key)) {
@@ -581,7 +586,7 @@ bool JsonManifest::GetKeyUrl(const Json::Value& dictionary,
}
bool JsonManifest::GetProgramURL(nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
bool* uses_nonsfi_mode,
ErrorInfo* error_info) const {
if (full_url == NULL || pnacl_options == NULL || error_info == NULL)
@@ -620,7 +625,7 @@ bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const {
bool JsonManifest::ResolveKey(const nacl::string& key,
nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
ErrorInfo* error_info) const {
NaClLog(3, "JsonManifest::ResolveKey(%s)\n", key.c_str());
// key must be one of kProgramKey or kFileKey '/' file-section-key
diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.h b/ppapi/native_client/src/trusted/plugin/json_manifest.h
index e71abebaa6..1f4180ce35 100644
--- a/ppapi/native_client/src/trusted/plugin/json_manifest.h
+++ b/ppapi/native_client/src/trusted/plugin/json_manifest.h
@@ -18,6 +18,8 @@
#include "ppapi/native_client/src/trusted/plugin/manifest.h"
#include "third_party/jsoncpp/source/include/json/value.h"
+struct PP_PNaClOptions;
+
namespace pp {
class URLUtil_Dev;
} // namespace pp
@@ -25,7 +27,6 @@ class URLUtil_Dev;
namespace plugin {
class ErrorInfo;
-class PnaclOptions;
class JsonManifest : public Manifest {
public:
@@ -49,7 +50,7 @@ class JsonManifest : public Manifest {
// Gets the full program URL for the current sandbox ISA from the
// manifest file.
virtual bool GetProgramURL(nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
bool* uses_nonsfi_mode,
ErrorInfo* error_info) const;
@@ -65,7 +66,7 @@ class JsonManifest : public Manifest {
// If there was an error, details are reported via error_info.
virtual bool ResolveKey(const nacl::string& key,
nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
ErrorInfo* error_info) const;
private:
@@ -84,13 +85,13 @@ class JsonManifest : public Manifest {
bool GetKeyUrl(const Json::Value& dictionary,
const nacl::string& key,
nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
ErrorInfo* error_info) const;
bool GetURLFromISADictionary(const Json::Value& dictionary,
const nacl::string& parent_key,
nacl::string* url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
bool* uses_nonsfi_mode,
ErrorInfo* error_info) const;
diff --git a/ppapi/native_client/src/trusted/plugin/manifest.h b/ppapi/native_client/src/trusted/plugin/manifest.h
index c430e1f346..aa1ad3bce6 100644
--- a/ppapi/native_client/src/trusted/plugin/manifest.h
+++ b/ppapi/native_client/src/trusted/plugin/manifest.h
@@ -17,6 +17,8 @@
#include "native_client/src/include/nacl_string.h"
#include "third_party/jsoncpp/source/include/json/value.h"
+struct PP_PNaClOptions;
+
namespace pp {
class URLUtil_Dev;
} // namespace pp
@@ -24,7 +26,6 @@ class URLUtil_Dev;
namespace plugin {
class ErrorInfo;
-class PnaclOptions;
class Manifest {
public:
@@ -42,7 +43,7 @@ class Manifest {
// manifest file. Fills in |pnacl_options| if the program requires
// PNaCl translation.
virtual bool GetProgramURL(nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
bool* uses_nonsfi_mode,
ErrorInfo* error_info) const = 0;
@@ -60,7 +61,7 @@ class Manifest {
// If there was an error, details are reported via error_info.
virtual bool ResolveKey(const nacl::string& key,
nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
ErrorInfo* error_info) const = 0;
protected:
diff --git a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
index 2f02d6b298..4d4c92328a 100644
--- a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
+++ b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
@@ -16,6 +16,7 @@
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/private/ppb_instance_private.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
typedef PP_ExternalPluginResult (*LaunchNaClProcessFunc)(
PP_Instance instance,
@@ -27,6 +28,8 @@ typedef PP_ExternalPluginResult (*LaunchNaClProcessFunc)(
PP_Bool enable_dyncode_syscalls,
PP_Bool enable_exception_handling,
PP_Bool enable_crash_throttling,
+ const PP_ManifestService* manifest_service_interface,
+ void* manifest_service_user_data,
NaClHandle* result_socket,
struct PP_Var* error_message,
PP_CompletionCallback callback);
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc
index 270d71d844..c4b1aafbc1 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.cc
+++ b/ppapi/native_client/src/trusted/plugin/plugin.cc
@@ -268,7 +268,10 @@ void Plugin::LoadNaClModule(nacl::DescWrapper* wrapper,
// associated listener threads do not go unjoined because if they
// outlive the Plugin object, they will not be memory safe.
ShutDownSubprocesses();
- SelLdrStartParams params(manifest_base_url(),
+ pp::Var manifest_base_url =
+ pp::Var(pp::PASS_REF, nacl_interface_->GetManifestBaseURL(pp_instance()));
+ std::string manifest_base_url_str = manifest_base_url.AsString();
+ SelLdrStartParams params(manifest_base_url_str,
true /* uses_irt */,
true /* uses_ppapi */,
uses_nonsfi_mode,
@@ -431,7 +434,7 @@ Plugin* Plugin::New(PP_Instance pp_instance) {
// failure. Note that module loading functions will log their own errors.
bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) {
PLUGIN_PRINTF(("Plugin::Init (argc=%" NACL_PRIu32 ")\n", argc));
- nacl_interface_->SetInitTime(pp_instance());
+ nacl_interface_->InitializePlugin(pp_instance());
url_util_ = pp::URLUtil_Dev::Get();
if (url_util_ == NULL)
@@ -461,16 +464,6 @@ bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) {
} else {
manifest_url = LookupArgument(kSrcManifestAttribute);
}
- // Use the document URL as the base for resolving relative URLs to find the
- // manifest. This takes into account the setting of <base> tags that
- // precede the embed/object.
- CHECK(url_util_ != NULL);
- pp::Var base_var = url_util_->GetDocumentURL(this);
- if (!base_var.is_string()) {
- PLUGIN_PRINTF(("Plugin::Init (unable to find document url)\n"));
- return false;
- }
- set_plugin_base_url(base_var.AsString());
if (manifest_url.empty()) {
// TODO(sehr,polina): this should be a hard error when scripting
// the src property is no longer allowed.
@@ -484,7 +477,7 @@ bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) {
// Issue a GET for the manifest_url. The manifest file will be parsed to
// determine the nexe URL.
// Sets src property to full manifest URL.
- RequestNaClManifest(manifest_url.c_str());
+ RequestNaClManifest(manifest_url);
}
}
@@ -499,6 +492,8 @@ Plugin::Plugin(PP_Instance pp_instance)
wrapper_factory_(NULL),
enable_dev_interfaces_(false),
time_of_last_progress_event_(0),
+ manifest_open_time_(-1),
+ nexe_open_time_(-1),
nacl_interface_(NULL),
uma_interface_(this) {
PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%"
@@ -592,6 +587,13 @@ void Plugin::NexeFileDidOpen(int32_t pp_error) {
nexe_bytes_read = stat_buf.st_size;
}
+ int64_t now = NaClGetTimeOfDayMicroseconds();
+ int64_t download_time;
+ if (now < nexe_open_time_)
+ download_time = 0;
+ else
+ download_time = now - nexe_open_time_;
+
nacl_interface_->NexeFileDidOpen(
pp_instance(),
pp_error,
@@ -599,7 +601,7 @@ void Plugin::NexeFileDidOpen(int32_t pp_error) {
nexe_downloader_.status_code(),
nexe_bytes_read,
nexe_downloader_.url().c_str(),
- nexe_downloader_.TimeSinceOpenMilliseconds());
+ download_time / 1000);
if (nexe_bytes_read == -1)
return;
@@ -683,47 +685,17 @@ void Plugin::BitcodeDidTranslateContinuation(int32_t pp_error) {
}
}
-void Plugin::NaClManifestBufferReady(int32_t pp_error) {
- PLUGIN_PRINTF(("Plugin::NaClManifestBufferReady (pp_error=%"
- NACL_PRId32 ")\n", pp_error));
- ErrorInfo error_info;
- if (pp_error != PP_OK) {
- if (pp_error == PP_ERROR_ABORTED) {
- ReportLoadAbort();
- } else {
- error_info.SetReport(PP_NACL_ERROR_MANIFEST_LOAD_URL,
- "could not load manifest url.");
- ReportLoadError(error_info);
- }
- return;
- }
-
- const std::deque<char>& buffer = nexe_downloader_.buffer();
- size_t buffer_size = buffer.size();
- if (buffer_size > kNaClManifestMaxFileBytes) {
- error_info.SetReport(PP_NACL_ERROR_MANIFEST_TOO_LARGE,
- "manifest file too large.");
- ReportLoadError(error_info);
- return;
- }
- nacl::scoped_array<char> json_buffer(new char[buffer_size + 1]);
- if (json_buffer == NULL) {
- error_info.SetReport(PP_NACL_ERROR_MANIFEST_MEMORY_ALLOC,
- "could not allocate manifest memory.");
- ReportLoadError(error_info);
- return;
- }
- std::copy(buffer.begin(), buffer.begin() + buffer_size, &json_buffer[0]);
- json_buffer[buffer_size] = '\0';
-
- ProcessNaClManifest(json_buffer.get());
-}
-
void Plugin::NaClManifestFileDidOpen(int32_t pp_error) {
PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen (pp_error=%"
NACL_PRId32 ")\n", pp_error));
+ int64_t now = NaClGetTimeOfDayMicroseconds();
+ int64_t download_time;
+ if (now < manifest_open_time_)
+ download_time = 0;
+ else
+ download_time = now - manifest_open_time_;
HistogramTimeSmall("NaCl.Perf.StartupTime.ManifestDownload",
- nexe_downloader_.TimeSinceOpenMilliseconds());
+ download_time / 1000);
HistogramHTTPStatusCode(
nacl_interface_->GetIsInstalled(pp_instance()) ?
"NaCl.HttpStatusCodeClass.Manifest.InstalledApp" :
@@ -796,22 +768,15 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) {
}
nacl::string program_url;
- PnaclOptions pnacl_options;
+ PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2};
bool uses_nonsfi_mode;
if (manifest_->GetProgramURL(
&program_url, &pnacl_options, &uses_nonsfi_mode, &error_info)) {
- pp::Var program_url_var(program_url);
- nacl_interface_->SetIsInstalled(
- pp_instance(),
- PP_FromBool(
- nacl_interface_->GetUrlScheme(program_url_var.pp_var()) ==
- PP_SCHEME_CHROME_EXTENSION));
+ // TODO(teravest): Make ProcessNaClManifest take responsibility for more of
+ // this function.
+ nacl_interface_->ProcessNaClManifest(pp_instance(), program_url.c_str());
uses_nonsfi_mode_ = uses_nonsfi_mode;
- nacl_interface_->SetNaClReadyState(pp_instance(),
- PP_NACL_READY_STATE_LOADING);
- // Inform JavaScript that we found a nexe URL to load.
- EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS);
- if (pnacl_options.translate()) {
+ if (pnacl_options.translate) {
pp::CompletionCallback translate_callback =
callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate);
// Will always call the callback on success or failure.
@@ -822,6 +787,7 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) {
translate_callback));
return;
} else {
+ nexe_open_time_ = NaClGetTimeOfDayMicroseconds();
// Try the fast path first. This will only block if the file is installed.
if (OpenURLFast(program_url, &nexe_downloader_)) {
NexeFileDidOpen(PP_OK);
@@ -845,48 +811,34 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) {
void Plugin::RequestNaClManifest(const nacl::string& url) {
PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str()));
- PLUGIN_PRINTF(("Plugin::RequestNaClManifest (plugin base url='%s')\n",
- plugin_base_url().c_str()));
- // The full URL of the manifest file is relative to the base url.
- CHECK(url_util_ != NULL);
- pp::Var nmf_resolved_url =
- url_util_->ResolveRelativeToURL(plugin_base_url(), pp::Var(url));
- if (!nmf_resolved_url.is_string()) {
- ErrorInfo error_info;
- error_info.SetReport(
- PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
- nacl::string("could not resolve URL \"") + url.c_str() +
- "\" relative to \"" + plugin_base_url().c_str() + "\".");
- ReportLoadError(error_info);
+ PP_Bool is_data_uri;
+ ErrorInfo error_info;
+ if (!nacl_interface_->RequestNaClManifest(pp_instance(), url.c_str(),
+ &is_data_uri))
return;
- }
- PLUGIN_PRINTF(("Plugin::RequestNaClManifest (resolved url='%s')\n",
- nmf_resolved_url.AsString().c_str()));
- nacl_interface_->SetIsInstalled(
- pp_instance(),
- PP_FromBool(
- nacl_interface_->GetUrlScheme(nmf_resolved_url.pp_var()) ==
- PP_SCHEME_CHROME_EXTENSION));
- set_manifest_base_url(nmf_resolved_url.AsString());
- // Inform JavaScript that a load is starting.
- nacl_interface_->SetNaClReadyState(pp_instance(), PP_NACL_READY_STATE_OPENED);
- EnqueueProgressEvent(PP_NACL_EVENT_LOADSTART);
- bool is_data_uri =
- (nacl_interface_->GetUrlScheme(nmf_resolved_url.pp_var()) ==
- PP_SCHEME_DATA);
- HistogramEnumerateManifestIsDataURI(static_cast<int>(is_data_uri));
+ pp::Var nmf_resolved_url =
+ pp::Var(pp::PASS_REF, nacl_interface_->GetManifestBaseURL(pp_instance()));
if (is_data_uri) {
- pp::CompletionCallback open_callback =
- callback_factory_.NewCallback(&Plugin::NaClManifestBufferReady);
- // Will always call the callback on success or failure.
- CHECK(nexe_downloader_.Open(nmf_resolved_url.AsString(),
- DOWNLOAD_TO_BUFFER,
- open_callback,
- false,
- NULL));
+ std::string string_nmf_resolved_url = nmf_resolved_url.AsString();
+ pp::Var nmf_data = pp::Var(
+ pp::PASS_REF,
+ nacl_interface_->ParseDataURL(string_nmf_resolved_url.c_str()));
+ if (!nmf_data.is_string()) {
+ error_info.SetReport(PP_NACL_ERROR_MANIFEST_LOAD_URL,
+ "could not load manifest url.");
+ ReportLoadError(error_info);
+ } else if (nmf_data.AsString().size() > kNaClManifestMaxFileBytes) {
+ error_info.SetReport(PP_NACL_ERROR_MANIFEST_TOO_LARGE,
+ "manifest file too large.");
+ ReportLoadError(error_info);
+ } else {
+ // TODO(teravest): Does this have to be async for any reason?
+ ProcessNaClManifest(nmf_data.AsString());
+ }
} else {
pp::CompletionCallback open_callback =
callback_factory_.NewCallback(&Plugin::NaClManifestFileDidOpen);
+ manifest_open_time_ = NaClGetTimeOfDayMicroseconds();
// Will always call the callback on success or failure.
CHECK(nexe_downloader_.Open(nmf_resolved_url.AsString(),
DOWNLOAD_TO_FILE,
@@ -908,12 +860,15 @@ bool Plugin::SetManifestObject(const nacl::string& manifest_json,
bool is_pnacl = (mime_type() == kPnaclMIMEType);
bool nonsfi_mode_enabled =
PP_ToBool(nacl_interface_->IsNonSFIModeEnabled());
+ pp::Var manifest_base_url =
+ pp::Var(pp::PASS_REF, nacl_interface_->GetManifestBaseURL(pp_instance()));
+ std::string manifest_base_url_str = manifest_base_url.AsString();
bool pnacl_debug = GetNaClInterface()->NaClDebugEnabledForURL(
- manifest_base_url().c_str());
+ manifest_base_url_str.c_str());
const char* sandbox_isa = nacl_interface_->GetSandboxArch();
nacl::scoped_ptr<JsonManifest> json_manifest(
new JsonManifest(url_util_,
- manifest_base_url(),
+ manifest_base_url_str,
(is_pnacl ? kPortableArch : sandbox_isa),
nonsfi_mode_enabled,
pnacl_debug));
@@ -973,17 +928,11 @@ bool Plugin::StreamAsFile(const nacl::string& url,
FileDownloader* downloader = new FileDownloader();
downloader->Initialize(this);
url_downloaders_.insert(downloader);
+
// Untrusted loads are always relative to the page's origin.
- CHECK(url_util_ != NULL);
- pp::Var resolved_url =
- url_util_->ResolveRelativeToURL(pp::Var(plugin_base_url()), url);
- if (!resolved_url.is_string()) {
- PLUGIN_PRINTF(("Plugin::StreamAsFile: "
- "could not resolve url \"%s\" relative to plugin \"%s\".",
- url.c_str(),
- plugin_base_url().c_str()));
+ if (!GetNaClInterface()->ResolvesRelativeToPluginBaseUrl(pp_instance(),
+ url.c_str()))
return false;
- }
// Try the fast path first. This will only block if the file is installed.
if (OpenURLFast(url, downloader)) {
@@ -1081,14 +1030,6 @@ void Plugin::ReportSelLdrLoadStatus(int status) {
HistogramEnumerateSelLdrLoadStatus(static_cast<NaClErrorCode>(status));
}
-void Plugin::EnqueueProgressEvent(PP_NaClEventType event_type) {
- EnqueueProgressEvent(event_type,
- NACL_NO_URL,
- Plugin::LENGTH_IS_NOT_COMPUTABLE,
- Plugin::kUnknownBytes,
- Plugin::kUnknownBytes);
-}
-
void Plugin::EnqueueProgressEvent(PP_NaClEventType event_type,
const nacl::string& url,
LengthComputable length_computable,
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi
index f8c8b8a57e..d9de561d39 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.gypi
+++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi
@@ -13,7 +13,6 @@
'nacl_subprocess.cc',
'plugin.cc',
'pnacl_coordinator.cc',
- 'pnacl_options.cc',
'pnacl_resources.cc',
'pnacl_translate_thread.cc',
'sel_ldr_launcher_chrome.cc',
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h
index f7864218cb..a1e12c3537 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.h
+++ b/ppapi/native_client/src/trusted/plugin/plugin.h
@@ -134,7 +134,6 @@ class Plugin : public pp::Instance {
// event (loadstart, progress, error, abort, load, loadend). Events are
// enqueued on the JavaScript event loop, which then calls back through
// DispatchProgressEvent.
- void EnqueueProgressEvent(PP_NaClEventType event_type);
void EnqueueProgressEvent(PP_NaClEventType event_type,
const nacl::string& url,
LengthComputable length_computable,
@@ -144,18 +143,6 @@ class Plugin : public pp::Instance {
// Report the error code that sel_ldr produces when starting a nexe.
void ReportSelLdrLoadStatus(int status);
- // URL resolution support.
- // plugin_base_url is the URL used for resolving relative URLs used in
- // src="...".
- nacl::string plugin_base_url() const { return plugin_base_url_; }
- void set_plugin_base_url(const nacl::string& url) { plugin_base_url_ = url; }
- // manifest_base_url is the URL used for resolving relative URLs mentioned
- // in manifest files. If the manifest is a data URI, this is an empty string.
- nacl::string manifest_base_url() const { return manifest_base_url_; }
- void set_manifest_base_url(const nacl::string& url) {
- manifest_base_url_ = url;
- }
-
nacl::DescWrapperFactory* wrapper_factory() const { return wrapper_factory_; }
// Requests a NaCl manifest download from a |url| relative to the page origin.
@@ -297,9 +284,6 @@ class Plugin : public pp::Instance {
// chosen for the sandbox ISA, any current service runtime is shut down, the
// .nexe is loaded and run.
- // Callback used when getting the manifest file as a buffer (e.g., data URIs)
- void NaClManifestBufferReady(int32_t pp_error);
-
// Callback used when getting the manifest file as a local file descriptor.
void NaClManifestFileDidOpen(int32_t pp_error);
@@ -413,6 +397,10 @@ class Plugin : public pp::Instance {
int64_t time_of_last_progress_event_;
int exit_status_;
+ // Open times are in microseconds.
+ int64_t manifest_open_time_;
+ int64_t nexe_open_time_;
+
const PPB_NaCl_Private* nacl_interface_;
pp::UMAPrivate uma_interface_;
};
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
index 74e84eb14c..7c04043418 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
@@ -42,7 +42,7 @@ class PnaclManifest : public Manifest {
virtual ~PnaclManifest() { }
virtual bool GetProgramURL(nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
bool* uses_nonsfi_mode,
ErrorInfo* error_info) const {
// Does not contain program urls.
@@ -65,10 +65,10 @@ class PnaclManifest : public Manifest {
virtual bool ResolveKey(const nacl::string& key,
nacl::string* full_url,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
ErrorInfo* error_info) const {
// All of the component files are native (do not require pnacl translate).
- pnacl_options->set_translate(false);
+ pnacl_options->translate = PP_FALSE;
// We can only resolve keys in the files/ namespace.
const nacl::string kFilesPrefix = "files/";
size_t files_prefix_pos = key.find(kFilesPrefix);
@@ -181,7 +181,7 @@ CallbackSource<FileStreamData>::~CallbackSource() {}
PnaclCoordinator* PnaclCoordinator::BitcodeToNative(
Plugin* plugin,
const nacl::string& pexe_url,
- const PnaclOptions& pnacl_options,
+ const PP_PNaClOptions& pnacl_options,
const pp::CompletionCallback& translate_notify_callback) {
PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n",
static_cast<void*>(plugin), pexe_url.c_str()));
@@ -207,7 +207,7 @@ PnaclCoordinator* PnaclCoordinator::BitcodeToNative(
PnaclCoordinator::PnaclCoordinator(
Plugin* plugin,
const nacl::string& pexe_url,
- const PnaclOptions& pnacl_options,
+ const PP_PNaClOptions& pnacl_options,
const pp::CompletionCallback& translate_notify_callback)
: translate_finish_error_(PP_OK),
plugin_(plugin),
@@ -325,7 +325,7 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) {
}
// If there are no errors, report stats from this thread (the main thread).
- HistogramOptLevel(plugin_->uma_interface(), pnacl_options_.opt_level());
+ HistogramOptLevel(plugin_->uma_interface(), pnacl_options_.opt_level);
HistogramKBPerSec(plugin_->uma_interface(),
"NaCl.Perf.PNaClLoadTime.CompileKBPerSec",
pexe_size_ / 1024.0,
@@ -483,7 +483,7 @@ void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) {
// TODO(dschuff): Get this value from the pnacl json file after it
// rolls in from NaCl.
1,
- pnacl_options_.opt_level(),
+ pnacl_options_.opt_level,
headers.c_str(),
"", // No extra compile flags yet.
&is_cache_hit_,
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
index 20b3d85ff0..99d6e7052b 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
@@ -21,9 +21,9 @@
#include "ppapi/native_client/src/trusted/plugin/file_downloader.h"
#include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
#include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
-#include "ppapi/native_client/src/trusted/plugin/pnacl_options.h"
#include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h"
+struct PP_PNaClOptions;
namespace plugin {
@@ -86,7 +86,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
static PnaclCoordinator* BitcodeToNative(
Plugin* plugin,
const nacl::string& pexe_url,
- const PnaclOptions& pnacl_options,
+ const PP_PNaClOptions& pnacl_options,
const pp::CompletionCallback& translate_notify_callback);
// Call this to take ownership of the FD of the translated nexe after
@@ -144,7 +144,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
// Therefore the constructor is private.
PnaclCoordinator(Plugin* plugin,
const nacl::string& pexe_url,
- const PnaclOptions& pnacl_options,
+ const PP_PNaClOptions& pnacl_options,
const pp::CompletionCallback& translate_notify_callback);
// Invoke to issue a GET request for bitcode.
@@ -211,7 +211,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
// The URL for the pexe file.
nacl::string pexe_url_;
// Options for translation.
- PnaclOptions pnacl_options_;
+ PP_PNaClOptions pnacl_options_;
// Object file, produced by the translator and consumed by the linker.
std::vector<TempFile*> obj_files_;
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_options.cc b/ppapi/native_client/src/trusted/plugin/pnacl_options.cc
deleted file mode 100644
index 46d7c24730..0000000000
--- a/ppapi/native_client/src/trusted/plugin/pnacl_options.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ppapi/native_client/src/trusted/plugin/pnacl_options.h"
-
-#include <iterator>
-#include <vector>
-
-#include "native_client/src/include/nacl_string.h"
-
-namespace plugin {
-
-PnaclOptions::PnaclOptions()
- : translate_(false),
- is_debug_(false),
- opt_level_(2) {
-}
-
-PnaclOptions::~PnaclOptions() {
-}
-
-void PnaclOptions::set_opt_level(int32_t l) {
- if (l <= 0) {
- opt_level_ = 0;
- return;
- }
- // Currently only allow 0 or 2, since that is what we test.
- opt_level_ = 2;
-}
-
-std::vector<char> PnaclOptions::GetOptCommandline() const {
- std::vector<char> result;
- nacl::string str;
-
- nacl::stringstream ss;
- ss << "-O" << opt_level_;
- str = ss.str();
- std::copy(str.begin(), str.end(), std::back_inserter(result));
- result.push_back('\x00');
- // Debug info is only available in LLVM format pexes,
- // not in PNaCl format pexes.
- if (is_debug_) {
- str = "-bitcode-format=llvm";
- std::copy(str.begin(), str.end(), std::back_inserter(result));
- result.push_back('\x00');
- }
-
- return result;
-}
-
-} // namespace plugin
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_options.h b/ppapi/native_client/src/trusted/plugin/pnacl_options.h
deleted file mode 100644
index 2d30c3b327..0000000000
--- a/ppapi/native_client/src/trusted/plugin/pnacl_options.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_OPTIONS_H_
-#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_OPTIONS_H_
-
-#include <vector>
-
-#include "native_client/src/include/nacl_string.h"
-#include "native_client/src/include/portability.h"
-
-namespace plugin {
-
-// Options for PNaCl translation.
-class PnaclOptions {
-
- public:
- PnaclOptions();
- ~PnaclOptions();
-
- // Return a character array of \x00 delimited commandline options.
- std::vector<char> GetOptCommandline() const;
-
- bool translate() const { return translate_; }
- void set_translate(bool t) { translate_ = t; }
-
- bool is_debug() const { return is_debug_; }
- void set_debug(bool t) { is_debug_ = t; }
-
- int32_t opt_level() const { return opt_level_; }
- void set_opt_level(int32_t l);
-
- private:
- // NOTE: There are users of this class that use the copy constructor.
- // Currently the default copy constructor is good enough, but
- // double-check that it is the case when more fields are added.
- bool translate_;
- bool is_debug_;
- int32_t opt_level_;
-};
-
-} // namespace plugin;
-#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_OPTIONS_H_
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
index 7cb98b8398..10f01bb31e 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
@@ -15,6 +15,25 @@
#include "ppapi/native_client/src/trusted/plugin/utility.h"
namespace plugin {
+namespace {
+
+nacl::string GetOptCommandLine(int32_t opt_level, bool is_debug) {
+ nacl::string str;
+ nacl::stringstream ss;
+ ss << "-O" << opt_level;
+ str = ss.str();
+ str += '\x00';
+
+ // Debug info is only available in LLVM format pexes,
+ // not in PNaCl format pexes.
+ if (is_debug) {
+ str += "-bitcode-format=llvm";
+ str += '\x00';
+ }
+ return str;
+}
+
+} // namespace
PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false),
ld_subprocess_active_(false),
@@ -40,7 +59,7 @@ void PnaclTranslateThread::RunTranslate(
nacl::DescWrapper* invalid_desc_wrapper,
ErrorInfo* error_info,
PnaclResources* resources,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
PnaclCoordinator* coordinator,
Plugin* plugin) {
PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n"));
@@ -187,7 +206,8 @@ void PnaclTranslateThread::DoTranslate() {
nacl::string split_arg = ss.str();
std::copy(split_arg.begin(), split_arg.end(), std::back_inserter(split_args));
split_args.push_back('\x00');
- std::vector<char> options = pnacl_options_->GetOptCommandline();
+ nacl::string options = GetOptCommandLine(pnacl_options_->opt_level,
+ pnacl_options_->is_debug);
std::copy(options.begin(), options.end(), std::back_inserter(split_args));
init_success = llc_subprocess_->InvokeSrpcMethod(
"StreamInitWithSplit",
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
index 4de0963383..db1dbf03a9 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
@@ -19,6 +19,8 @@
#include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
#include "ppapi/native_client/src/trusted/plugin/service_runtime.h"
+struct PP_PNaClOptions;
+
namespace nacl {
class DescWrapper;
}
@@ -30,7 +32,6 @@ class Manifest;
class NaClSubprocess;
class Plugin;
class PnaclCoordinator;
-class PnaclOptions;
class PnaclResources;
class TempFile;
@@ -48,7 +49,7 @@ class PnaclTranslateThread {
nacl::DescWrapper* invalid_desc_wrapper,
ErrorInfo* error_info,
PnaclResources* resources,
- PnaclOptions* pnacl_options,
+ PP_PNaClOptions* pnacl_options,
PnaclCoordinator* coordinator,
Plugin* plugin);
@@ -119,7 +120,7 @@ class PnaclTranslateThread {
nacl::DescWrapper* invalid_desc_wrapper_;
ErrorInfo* coordinator_error_info_;
PnaclResources* resources_;
- PnaclOptions* pnacl_options_;
+ PP_PNaClOptions* pnacl_options_;
PnaclCoordinator* coordinator_;
Plugin* plugin_;
private:
diff --git a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
index ce7b566b86..bd8ee9eb51 100644
--- a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
+++ b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
@@ -17,17 +17,20 @@ bool SelLdrLauncherChrome::Start(const char* url) {
return false;
}
-void SelLdrLauncherChrome::Start(PP_Instance instance,
- const char* url,
- bool uses_irt,
- bool uses_ppapi,
- bool uses_nonsfi_mode,
- bool enable_ppapi_dev,
- bool enable_dyncode_syscalls,
- bool enable_exception_handling,
- bool enable_crash_throttling,
- PP_Var* error_message,
- pp::CompletionCallback callback) {
+void SelLdrLauncherChrome::Start(
+ PP_Instance instance,
+ const char* url,
+ bool uses_irt,
+ bool uses_ppapi,
+ bool uses_nonsfi_mode,
+ bool enable_ppapi_dev,
+ bool enable_dyncode_syscalls,
+ bool enable_exception_handling,
+ bool enable_crash_throttling,
+ const PP_ManifestService* manifest_service_interface,
+ void* manifest_service_user_data,
+ PP_Var* error_message,
+ pp::CompletionCallback callback) {
if (!launch_nacl_process) {
pp::Module::Get()->core()->CallOnMainThread(0, callback, PP_ERROR_FAILED);
return;
@@ -41,6 +44,8 @@ void SelLdrLauncherChrome::Start(PP_Instance instance,
PP_FromBool(enable_dyncode_syscalls),
PP_FromBool(enable_exception_handling),
PP_FromBool(enable_crash_throttling),
+ manifest_service_interface,
+ manifest_service_user_data,
&channel_,
error_message,
callback.pp_completion_callback());
diff --git a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
index f512535c6f..50e884836c 100644
--- a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
+++ b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
@@ -8,6 +8,7 @@
#include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_var.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
#include "ppapi/cpp/completion_callback.h"
namespace plugin {
@@ -24,6 +25,8 @@ class SelLdrLauncherChrome : public nacl::SelLdrLauncherBase {
bool enable_dyncode_syscalls,
bool enable_exception_handling,
bool enable_crash_throttling,
+ const PP_ManifestService* manifest_service_interface,
+ void* manifest_service_user_data,
PP_Var* error_message,
pp::CompletionCallback callback);
};
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
index 2a3048e701..e9eba18348 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
@@ -50,12 +50,12 @@
#include "ppapi/native_client/src/trusted/plugin/manifest.h"
#include "ppapi/native_client/src/trusted/plugin/plugin.h"
#include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
-#include "ppapi/native_client/src/trusted/plugin/pnacl_options.h"
#include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h"
#include "ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h"
#include "ppapi/native_client/src/trusted/plugin/srpc_client.h"
#include "ppapi/native_client/src/trusted/weak_ref/call_on_main_thread.h"
+namespace plugin {
namespace {
// For doing crude quota enforcement on writes to temp files.
@@ -64,9 +64,58 @@ namespace {
// should be plenty for static data
const int64_t kMaxTempQuota = 0x8000000;
-} // namespace
+class ManifestService {
+ public:
+ ManifestService(nacl::WeakRefAnchor* anchor,
+ PluginReverseInterface* plugin_reverse)
+ : anchor_(anchor),
+ plugin_reverse_(plugin_reverse) {
+ }
-namespace plugin {
+ ~ManifestService() {
+ anchor_->Unref();
+ }
+
+ bool Quit() {
+ delete this;
+ return false;
+ }
+
+ bool StartupInitializationComplete() {
+ // Release this instance if the ServiceRuntime is already destructed.
+ if (anchor_->is_abandoned()) {
+ delete this;
+ return false;
+ }
+
+ plugin_reverse_->StartupInitializationComplete();
+ return true;
+ }
+
+ static PP_Bool QuitTrampoline(void* user_data) {
+ return PP_FromBool(static_cast<ManifestService*>(user_data)->Quit());
+ }
+
+ static PP_Bool StartupInitializationCompleteTrampoline(void* user_data) {
+ return PP_FromBool(static_cast<ManifestService*>(user_data)->
+ StartupInitializationComplete());
+ }
+
+ private:
+ // Weak reference to check if plugin_reverse is legally accessible or not.
+ nacl::WeakRefAnchor* anchor_;
+ PluginReverseInterface* plugin_reverse_;
+
+ DISALLOW_COPY_AND_ASSIGN(ManifestService);
+};
+
+// Vtable to pass functions to LaunchSelLdr.
+const PP_ManifestService kManifestServiceVTable = {
+ &ManifestService::QuitTrampoline,
+ &ManifestService::StartupInitializationCompleteTrampoline,
+};
+
+} // namespace
PluginReverseInterface::PluginReverseInterface(
nacl::WeakRefAnchor* anchor,
@@ -216,7 +265,7 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n");
std::string mapped_url;
- PnaclOptions pnacl_options;
+ PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2};
ErrorInfo error_info;
if (!manifest_->ResolveKey(p->url, &mapped_url,
&pnacl_options, &error_info)) {
@@ -236,9 +285,9 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
NaClLog(4,
"OpenManifestEntry_MainThreadContinuation: "
"ResolveKey: %s -> %s (pnacl_translate(%d))\n",
- p->url.c_str(), mapped_url.c_str(), pnacl_options.translate());
+ p->url.c_str(), mapped_url.c_str(), pnacl_options.translate);
- if (pnacl_options.translate()) {
+ if (pnacl_options.translate) {
// Requires PNaCl translation, but that's not supported.
NaClLog(4,
"OpenManifestEntry_MainThreadContinuation: "
@@ -469,14 +518,7 @@ bool ServiceRuntime::LoadModule(nacl::DescWrapper* nacl_desc,
bool ServiceRuntime::InitReverseService(ErrorInfo* error_info) {
if (uses_nonsfi_mode_) {
- // In non-SFI mode, open_resource() is not yet supported, so we do not
- // need the reverse service. So, skip the initialization (with calling
- // the completion callback).
- // Note that there is on going work to replace SRPC by Chrome IPC (not only
- // for non-SFI mode, but also for SFI mode) (crbug.com/333950),
- // and non-SFI mode will use Chrome IPC for open_resource() after the
- // refactoring is done.
- rev_interface_->StartupInitializationComplete();
+ // In non-SFI mode, no reverse service is set up. Just returns success.
return true;
}
@@ -572,6 +614,8 @@ void ServiceRuntime::StartSelLdr(const SelLdrStartParams& params,
callback_factory_.NewCallback(&ServiceRuntime::StartSelLdrContinuation,
callback);
+ ManifestService* manifest_service =
+ new ManifestService(anchor_->Ref(), rev_interface_);
tmp_subprocess->Start(plugin_->pp_instance(),
params.url.c_str(),
params.uses_irt,
@@ -581,6 +625,8 @@ void ServiceRuntime::StartSelLdr(const SelLdrStartParams& params,
params.enable_dyncode_syscalls,
params.enable_exception_handling,
params.enable_crash_throttling,
+ &kManifestServiceVTable,
+ manifest_service,
&start_sel_ldr_error_message_,
internal_callback);
subprocess_.reset(tmp_subprocess.release());
diff --git a/ppapi/native_client/src/untrusted/irt_stub/thread_creator.h b/ppapi/native_client/src/untrusted/irt_stub/thread_creator.h
index ac4258f996..7adbabe780 100644
--- a/ppapi/native_client/src/untrusted/irt_stub/thread_creator.h
+++ b/ppapi/native_client/src/untrusted/irt_stub/thread_creator.h
@@ -10,6 +10,14 @@
#include "native_client/src/untrusted/irt/irt.h"
#include "ppapi/nacl_irt/public/irt_ppapi.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void __nacl_register_thread_creator(const struct nacl_irt_ppapihook *hooks);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
#endif
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index 162e00528d..b085cfbbeb 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -3085,11 +3085,13 @@ static int32_t Pnacl_M33_PPB_IsolatedFileSystem_Private_Open(PP_Instance instanc
/* End wrapper methods for PPB_IsolatedFileSystem_Private_0_2 */
+/* Not generating wrapper methods for PP_ManifestService_1_0 */
+
/* Begin wrapper methods for PPB_NaCl_Private_1_0 */
-static void Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback* callback) {
+static void Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback* callback) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
- iface->LaunchSelLdr(instance, alleged_url, uses_irt, uses_ppapi, uses_nonsfi_mode, enable_ppapi_dev, enable_dyncode_syscalls, enable_exception_handling, enable_crash_throttling, imc_handle, error_message, *callback);
+ iface->LaunchSelLdr(instance, alleged_url, uses_irt, uses_ppapi, uses_nonsfi_mode, enable_ppapi_dev, enable_dyncode_syscalls, enable_exception_handling, enable_crash_throttling, manifest_service_interface, manifest_service_user_data, imc_handle, error_message, *callback);
}
static PP_Bool Pnacl_M25_PPB_NaCl_Private_StartPpapiProxy(PP_Instance instance) {
@@ -3212,21 +3214,11 @@ static PP_NaClReadyState Pnacl_M25_PPB_NaCl_Private_GetNaClReadyState(PP_Instanc
return iface->GetNaClReadyState(instance);
}
-static void Pnacl_M25_PPB_NaCl_Private_SetNaClReadyState(PP_Instance instance, PP_NaClReadyState ready_state) {
- const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
- iface->SetNaClReadyState(instance, ready_state);
-}
-
static PP_Bool Pnacl_M25_PPB_NaCl_Private_GetIsInstalled(PP_Instance instance) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
return iface->GetIsInstalled(instance);
}
-static void Pnacl_M25_PPB_NaCl_Private_SetIsInstalled(PP_Instance instance, PP_Bool is_installed) {
- const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
- iface->SetIsInstalled(instance, is_installed);
-}
-
static int32_t Pnacl_M25_PPB_NaCl_Private_GetExitStatus(PP_Instance instance) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
return iface->GetExitStatus(instance);
@@ -3242,9 +3234,9 @@ static void Pnacl_M25_PPB_NaCl_Private_Vlog(const char* message) {
iface->Vlog(message);
}
-static void Pnacl_M25_PPB_NaCl_Private_SetInitTime(PP_Instance instance) {
+static void Pnacl_M25_PPB_NaCl_Private_InitializePlugin(PP_Instance instance) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
- iface->SetInitTime(instance);
+ iface->InitializePlugin(instance);
}
static int64_t Pnacl_M25_PPB_NaCl_Private_GetNexeSize(PP_Instance instance) {
@@ -3252,9 +3244,29 @@ static int64_t Pnacl_M25_PPB_NaCl_Private_GetNexeSize(PP_Instance instance) {
return iface->GetNexeSize(instance);
}
-static void Pnacl_M25_PPB_NaCl_Private_SetNexeSize(PP_Instance instance, int64_t nexe_size) {
+static PP_Bool Pnacl_M25_PPB_NaCl_Private_RequestNaClManifest(PP_Instance instance, const char* manifest_url, PP_Bool* is_data_uri) {
+ const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+ return iface->RequestNaClManifest(instance, manifest_url, is_data_uri);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_GetManifestBaseURL(struct PP_Var* _struct_result, PP_Instance instance) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
- iface->SetNexeSize(instance, nexe_size);
+ *_struct_result = iface->GetManifestBaseURL(instance);
+}
+
+static PP_Bool Pnacl_M25_PPB_NaCl_Private_ResolvesRelativeToPluginBaseUrl(PP_Instance instance, const char* url) {
+ const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+ return iface->ResolvesRelativeToPluginBaseUrl(instance, url);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_ParseDataURL(struct PP_Var* _struct_result, const char* data_url) {
+ const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+ *_struct_result = iface->ParseDataURL(data_url);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_ProcessNaClManifest(PP_Instance instance, const char* program_url) {
+ const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+ iface->ProcessNaClManifest(instance, program_url);
}
/* End wrapper methods for PPB_NaCl_Private_1_0 */
@@ -5130,8 +5142,10 @@ static const struct PPB_IsolatedFileSystem_Private_0_2 Pnacl_Wrappers_PPB_Isolat
.Open = (int32_t (*)(PP_Instance instance, PP_IsolatedFileSystemType_Private type, PP_Resource* file_system, struct PP_CompletionCallback callback))&Pnacl_M33_PPB_IsolatedFileSystem_Private_Open
};
+/* Not generating wrapper interface for PP_ManifestService_1_0 */
+
static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = {
- .LaunchSelLdr = (void (*)(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr,
+ .LaunchSelLdr = (void (*)(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr,
.StartPpapiProxy = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_StartPpapiProxy,
.UrandomFD = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_UrandomFD,
.Are3DInterfacesDisabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_Are3DInterfacesDisabled,
@@ -5156,15 +5170,17 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = {
.GetUrlScheme = (PP_UrlSchemeType (*)(struct PP_Var url))&Pnacl_M25_PPB_NaCl_Private_GetUrlScheme,
.LogToConsole = (void (*)(PP_Instance instance, const char* message))&Pnacl_M25_PPB_NaCl_Private_LogToConsole,
.GetNaClReadyState = (PP_NaClReadyState (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetNaClReadyState,
- .SetNaClReadyState = (void (*)(PP_Instance instance, PP_NaClReadyState ready_state))&Pnacl_M25_PPB_NaCl_Private_SetNaClReadyState,
.GetIsInstalled = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetIsInstalled,
- .SetIsInstalled = (void (*)(PP_Instance instance, PP_Bool is_installed))&Pnacl_M25_PPB_NaCl_Private_SetIsInstalled,
.GetExitStatus = (int32_t (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetExitStatus,
.SetExitStatus = (void (*)(PP_Instance instance, int32_t exit_status))&Pnacl_M25_PPB_NaCl_Private_SetExitStatus,
.Vlog = (void (*)(const char* message))&Pnacl_M25_PPB_NaCl_Private_Vlog,
- .SetInitTime = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_SetInitTime,
+ .InitializePlugin = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_InitializePlugin,
.GetNexeSize = (int64_t (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetNexeSize,
- .SetNexeSize = (void (*)(PP_Instance instance, int64_t nexe_size))&Pnacl_M25_PPB_NaCl_Private_SetNexeSize
+ .RequestNaClManifest = (PP_Bool (*)(PP_Instance instance, const char* manifest_url, PP_Bool* is_data_uri))&Pnacl_M25_PPB_NaCl_Private_RequestNaClManifest,
+ .GetManifestBaseURL = (struct PP_Var (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetManifestBaseURL,
+ .ResolvesRelativeToPluginBaseUrl = (PP_Bool (*)(PP_Instance instance, const char* url))&Pnacl_M25_PPB_NaCl_Private_ResolvesRelativeToPluginBaseUrl,
+ .ParseDataURL = (struct PP_Var (*)(const char* data_url))&Pnacl_M25_PPB_NaCl_Private_ParseDataURL,
+ .ProcessNaClManifest = (void (*)(PP_Instance instance, const char* program_url))&Pnacl_M25_PPB_NaCl_Private_ProcessNaClManifest
};
static const struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = {
diff --git a/ppapi/native_client/tests/nacl_browser/fault_injection/fault_pm_nameservice_test.cc b/ppapi/native_client/tests/nacl_browser/fault_injection/fault_pm_nameservice_test.cc
index 61ed0f36e5..72ae9286ee 100644
--- a/ppapi/native_client/tests/nacl_browser/fault_injection/fault_pm_nameservice_test.cc
+++ b/ppapi/native_client/tests/nacl_browser/fault_injection/fault_pm_nameservice_test.cc
@@ -74,31 +74,6 @@ void dump_output(nacl::StringBuffer *sb, int d, size_t nbytes) {
sb->Printf("\n");
}
-void EnumerateNames(NaClSrpcChannel *nschan, nacl::StringBuffer *sb) {
- char buffer[1024];
- uint32_t nbytes = sizeof buffer;
-
- if (NACL_SRPC_RESULT_OK != NaClSrpcInvokeBySignature(nschan,
- NACL_NAME_SERVICE_LIST,
- &nbytes, buffer)) {
- sb->Printf("NaClSrpcInvokeBySignature failed\n");
- return;
- }
- sb->Printf("nbytes = %u\n", (size_t) nbytes);
- if (nbytes == sizeof buffer) {
- sb->Printf("Insufficent space for namespace enumeration\n");
- return;
- }
-
- size_t name_len;
- for (char *p = buffer;
- static_cast<size_t>(p - buffer) < nbytes;
- p += name_len) {
- name_len = strlen(p) + 1;
- sb->Printf("%s\n", p);
- }
-}
-
void Initialize(const pp::Var& message_data, nacl::StringBuffer* sb) {
if (g_ns_channel_initialized) {
return;
@@ -119,14 +94,6 @@ void Initialize(const pp::Var& message_data, nacl::StringBuffer* sb) {
}
//
-// Return name service output
-//
-void NameServiceDump(const pp::Var& message_data, nacl::StringBuffer* sb) {
- Initialize(message_data, sb);
- EnumerateNames(&g_ns_channel, sb);
-}
-
-//
// Dump RNG output into a string.
//
void RngDump(const pp::Var& message_data, nacl::StringBuffer* sb) {
@@ -203,7 +170,6 @@ class MyInstance : public pp::Instance {
void MyInstance::HandleMessage(const pp::Var& message_data) {
static struct PostMessageHandlerDesc kMsgHandlers[] = {
{ "init", Initialize },
- { "nameservice", NameServiceDump },
{ "rng", RngDump },
{ "manifest_test", ManifestTest },
{ reinterpret_cast<char const *>(NULL),
diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi
index 11eb697655..f8605db61b 100644
--- a/ppapi/ppapi_proxy.gypi
+++ b/ppapi/ppapi_proxy.gypi
@@ -247,6 +247,8 @@
'nacl_irt/irt_ppapi.cc',
'nacl_irt/irt_ppapi.h',
'nacl_irt/irt_start.cc',
+ 'nacl_irt/manifest_service.cc',
+ 'nacl_irt/manifest_service.h',
'nacl_irt/plugin_main.cc',
'nacl_irt/plugin_main.h',
'nacl_irt/plugin_startup.cc',
diff --git a/ppapi/proxy/file_system_resource_unittest.cc b/ppapi/proxy/file_system_resource_unittest.cc
index f93695439c..9b5d981242 100644
--- a/ppapi/proxy/file_system_resource_unittest.cc
+++ b/ppapi/proxy/file_system_resource_unittest.cc
@@ -74,7 +74,15 @@ class MockRequestQuotaCallback {
class FileSystemResourceTest : public PluginProxyTest {
public:
- FileSystemResourceTest() {}
+ const PPB_FileSystem_1_0* file_system_iface;
+ const PPB_FileRef_1_1* file_ref_iface;
+ const PPB_FileIO_1_1* file_io_iface;
+
+ FileSystemResourceTest()
+ : file_system_iface(thunk::GetPPB_FileSystem_1_0_Thunk()),
+ file_ref_iface(thunk::GetPPB_FileRef_1_1_Thunk()),
+ file_io_iface(thunk::GetPPB_FileIO_1_1_Thunk()) {
+ }
void SendReply(const ResourceMessageCallParams& params,
int32_t result,
@@ -93,7 +101,7 @@ class FileSystemResourceTest : public PluginProxyTest {
// Opens the given file system.
void OpenFileSystem(PP_Resource file_system) {
MockCompletionCallback cb;
- int32_t result = thunk::GetPPB_FileSystem_1_0_Thunk()->Open(
+ int32_t result = file_system_iface->Open(
file_system,
kExpectedFileSystemSize,
PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &cb));
@@ -119,7 +127,7 @@ class FileSystemResourceTest : public PluginProxyTest {
PP_Resource file_ref,
PP_Resource file_system) {
MockCompletionCallback cb;
- int32_t result = thunk::GetPPB_FileIO_1_1_Thunk()->Open(
+ int32_t result = file_io_iface->Open(
file_io,
file_ref,
PP_FILEOPENFLAG_WRITE,
@@ -149,14 +157,14 @@ class FileSystemResourceTest : public PluginProxyTest {
// Test that Open fails if either host returns failure. The other tests exercise
// the case where both hosts return PP_OK.
TEST_F(FileSystemResourceTest, OpenFailure) {
- const PPB_FileSystem_1_0* fs_iface = thunk::GetPPB_FileSystem_1_0_Thunk();
// Fail if the first reply doesn't return PP_OK.
{
LockingResourceReleaser file_system(
- fs_iface->Create(pp_instance(), PP_FILESYSTEMTYPE_LOCALTEMPORARY));
+ file_system_iface->Create(pp_instance(),
+ PP_FILESYSTEMTYPE_LOCALTEMPORARY));
MockCompletionCallback cb;
- int32_t result = thunk::GetPPB_FileSystem_1_0_Thunk()->Open(
+ int32_t result = file_system_iface->Open(
file_system.get(),
kExpectedFileSystemSize,
PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &cb));
@@ -176,10 +184,11 @@ TEST_F(FileSystemResourceTest, OpenFailure) {
// Fail if the second reply doesn't return PP_OK.
{
LockingResourceReleaser file_system(
- fs_iface->Create(pp_instance(), PP_FILESYSTEMTYPE_LOCALTEMPORARY));
+ file_system_iface->Create(pp_instance(),
+ PP_FILESYSTEMTYPE_LOCALTEMPORARY));
MockCompletionCallback cb;
- int32_t result = thunk::GetPPB_FileSystem_1_0_Thunk()->Open(
+ int32_t result = file_system_iface->Open(
file_system.get(),
kExpectedFileSystemSize,
PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &cb));
@@ -199,24 +208,21 @@ TEST_F(FileSystemResourceTest, OpenFailure) {
}
TEST_F(FileSystemResourceTest, RequestQuota) {
- const PPB_FileSystem_1_0* fs_iface = thunk::GetPPB_FileSystem_1_0_Thunk();
- const PPB_FileRef_1_1* fref_iface = thunk::GetPPB_FileRef_1_1_Thunk();
- const PPB_FileIO_1_1* fio_iface = thunk::GetPPB_FileIO_1_1_Thunk();
-
LockingResourceReleaser file_system(
- fs_iface->Create(pp_instance(), PP_FILESYSTEMTYPE_LOCALTEMPORARY));
+ file_system_iface->Create(pp_instance(),
+ PP_FILESYSTEMTYPE_LOCALTEMPORARY));
OpenFileSystem(file_system.get());
// Create and open two files in the file system. FileIOResource calls
// FileSystemResource::OpenQuotaFile on success.
LockingResourceReleaser file_ref1(
- fref_iface->Create(file_system.get(), "/file1"));
- LockingResourceReleaser file_io1(fio_iface->Create(pp_instance()));
+ file_ref_iface->Create(file_system.get(), "/file1"));
+ LockingResourceReleaser file_io1(file_io_iface->Create(pp_instance()));
OpenFile(file_io1.get(), file_ref1.get(), file_system.get());
LockingResourceReleaser file_ref2(
- fref_iface->Create(file_system.get(), "/file2"));
- LockingResourceReleaser file_io2(fio_iface->Create(pp_instance()));
+ file_ref_iface->Create(file_system.get(), "/file2"));
+ LockingResourceReleaser file_io2(file_io_iface->Create(pp_instance()));
OpenFile(file_io2.get(), file_ref2.get(), file_system.get());
EnterResource<PPB_FileSystem_API> enter(file_system.get(), true);
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc
index 1e4820d5ec..d747019158 100644
--- a/ppapi/proxy/ppapi_command_buffer_proxy.cc
+++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc
@@ -132,6 +132,7 @@ scoped_refptr<gpu::Buffer> PpapiCommandBufferProxy::CreateTransferBuffer(
// Map the shared memory on demand.
if (!shared_memory->memory()) {
if (!shared_memory->Map(handle.size())) {
+ *id = -1;
return NULL;
}
}
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index e54dae72ef..e099b36709 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -753,6 +753,9 @@ IPC_MESSAGE_CONTROL0(PpapiHostMsg_Keepalive)
IPC_MESSAGE_CONTROL1(PpapiHostMsg_ChannelCreated,
IPC::ChannelHandle /* handle */)
+// Notify the renderer that the PPAPI channel gets ready in the plugin.
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_StartupInitializationComplete);
+
// Logs the given message to the console of all instances.
IPC_MESSAGE_CONTROL4(PpapiHostMsg_LogWithSource,
PP_Instance /* instance */,
diff --git a/ppapi/proxy/ppb_audio_proxy.cc b/ppapi/proxy/ppb_audio_proxy.cc
index 58f5abc0d4..d84c3cb699 100644
--- a/ppapi/proxy/ppb_audio_proxy.cc
+++ b/ppapi/proxy/ppb_audio_proxy.cc
@@ -95,6 +95,8 @@ PP_Resource Audio::GetCurrentConfig() {
PP_Bool Audio::StartPlayback() {
if (playing())
return PP_TRUE;
+ if (!PPB_Audio_Shared::IsThreadFunctionReady())
+ return PP_FALSE;
SetStartPlaybackState();
PluginDispatcher::GetForResource(this)->Send(
new PpapiHostMsg_PPBAudio_StartOrStop(
diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc
index be0cc34751..85f1f16210 100644
--- a/ppapi/proxy/ppb_instance_proxy.cc
+++ b/ppapi/proxy/ppb_instance_proxy.cc
@@ -959,12 +959,11 @@ void PPB_Instance_Proxy::OnHostMsgSetTickmarks(
const std::vector<PP_Rect>& tickmarks) {
if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE))
return;
- if (tickmarks.empty())
- return;
+ const PP_Rect* array = tickmarks.empty() ? NULL : &tickmarks[0];
EnterInstanceNoLock enter(instance);
if (enter.succeeded()) {
enter.functions()->SetTickmarks(instance,
- &tickmarks[0],
+ array,
static_cast<uint32_t>(tickmarks.size()));
}
}
diff --git a/ppapi/shared_impl/ppb_audio_shared.cc b/ppapi/shared_impl/ppb_audio_shared.cc
index ced1146697..741a86f99b 100644
--- a/ppapi/shared_impl/ppb_audio_shared.cc
+++ b/ppapi/shared_impl/ppb_audio_shared.cc
@@ -5,18 +5,18 @@
#include "ppapi/shared_impl/ppb_audio_shared.h"
#include "base/logging.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/ppb_audio_config_shared.h"
#include "ppapi/shared_impl/proxy_lock.h"
namespace ppapi {
-#if defined(OS_NACL)
namespace {
+bool g_nacl_mode = false;
// Because this is static, the function pointers will be NULL initially.
-PP_ThreadFunctions thread_functions;
+PP_ThreadFunctions g_thread_functions;
}
-#endif // defined(OS_NACL)
AudioCallbackCombined::AudioCallbackCombined()
: callback_1_0_(NULL), callback_(NULL) {}
@@ -50,10 +50,7 @@ void AudioCallbackCombined::Run(void* sample_buffer,
PPB_Audio_Shared::PPB_Audio_Shared()
: playing_(false),
shared_memory_size_(0),
-#if defined(OS_NACL)
- thread_id_(0),
- thread_active_(false),
-#endif
+ nacl_thread_active_(false),
user_data_(NULL),
client_buffer_size_bytes_(0),
bytes_per_second_(0),
@@ -75,11 +72,8 @@ void PPB_Audio_Shared::SetCallback(const AudioCallbackCombined& callback,
void PPB_Audio_Shared::SetStartPlaybackState() {
DCHECK(!playing_);
-#if !defined(OS_NACL)
DCHECK(!audio_thread_.get());
-#else
- DCHECK(!thread_active_);
-#endif
+ DCHECK(!nacl_thread_active_);
// If the socket doesn't exist, that means that the plugin has started before
// the browser has had a chance to create all the shared memory info and
// notify us. This is a common case. In this case, we just set the playing_
@@ -138,54 +132,68 @@ void PPB_Audio_Shared::StartThread() {
// start up quickly enough.
memset(shared_memory_->memory(), 0, shared_memory_size_);
memset(client_buffer_.get(), 0, client_buffer_size_bytes_);
-#if !defined(OS_NACL)
- DCHECK(!audio_thread_.get());
- audio_thread_.reset(
- new base::DelegateSimpleThread(this, "plugin_audio_thread"));
- audio_thread_->Start();
-#else
- // Use NaCl's special API for IRT code that creates threads that call back
- // into user code.
- if (NULL == thread_functions.thread_create ||
- NULL == thread_functions.thread_join)
- return;
- int result = thread_functions.thread_create(&thread_id_, CallRun, this);
- DCHECK_EQ(result, 0);
- thread_active_ = true;
-#endif
+ if (g_nacl_mode) {
+ // Use NaCl's special API for IRT code that creates threads that call back
+ // into user code.
+ if (!IsThreadFunctionReady())
+ return;
+
+ DCHECK(!nacl_thread_active_);
+ int result =
+ g_thread_functions.thread_create(&nacl_thread_id_, CallRun, this);
+ DCHECK_EQ(0, result);
+ nacl_thread_active_ = true;
+ } else {
+ DCHECK(!audio_thread_.get());
+ audio_thread_.reset(
+ new base::DelegateSimpleThread(this, "plugin_audio_thread"));
+ audio_thread_->Start();
+ }
}
void PPB_Audio_Shared::StopThread() {
-#if !defined(OS_NACL)
- if (audio_thread_.get()) {
- // In general, the audio thread should not do Pepper calls, but it might
- // anyway (for example, our Audio test does CallOnMainThread). If it did
- // a pepper call which acquires the lock (most of them do), and we try to
- // shut down the thread and Join it while holding the lock, we would
- // deadlock. So we give up the lock here so that the thread at least _can_
- // make Pepper calls without causing deadlock.
- CallWhileUnlocked(base::Bind(&base::DelegateSimpleThread::Join,
- base::Unretained(audio_thread_.get())));
- audio_thread_.reset();
- }
-#else
- if (thread_active_) {
- // See comment above about why we unlock here.
- int result = CallWhileUnlocked(thread_functions.thread_join, thread_id_);
- DCHECK_EQ(0, result);
- thread_active_ = false;
+ // In general, the audio thread should not do Pepper calls, but it might
+ // anyway (for example, our Audio test does CallOnMainThread). If it did a
+ // pepper call which acquires the lock (most of them do), and we try to shut
+ // down the thread and Join it while holding the lock, we would deadlock. So
+ // we give up the lock here so that the thread at least _can_ make Pepper
+ // calls without causing deadlock.
+ if (g_nacl_mode) {
+ if (nacl_thread_active_) {
+ int result =
+ CallWhileUnlocked(g_thread_functions.thread_join, nacl_thread_id_);
+ DCHECK_EQ(0, result);
+ nacl_thread_active_ = false;
+ }
+ } else {
+ if (audio_thread_.get()) {
+ CallWhileUnlocked(base::Bind(&base::DelegateSimpleThread::Join,
+ base::Unretained(audio_thread_.get())));
+ audio_thread_.reset();
+ }
}
-#endif
}
-#if defined(OS_NACL)
+// static
+bool PPB_Audio_Shared::IsThreadFunctionReady() {
+ if (!g_nacl_mode)
+ return true;
+
+ return (g_thread_functions.thread_create != NULL &&
+ g_thread_functions.thread_join != NULL);
+}
+
+// static
+void PPB_Audio_Shared::SetNaClMode() {
+ g_nacl_mode = true;
+}
+
// static
void PPB_Audio_Shared::SetThreadFunctions(
const struct PP_ThreadFunctions* functions) {
- DCHECK(thread_functions.thread_create == NULL);
- DCHECK(thread_functions.thread_join == NULL);
- thread_functions = *functions;
+ DCHECK(g_nacl_mode);
+ g_thread_functions = *functions;
}
// static
@@ -193,7 +201,6 @@ void PPB_Audio_Shared::CallRun(void* self) {
PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self);
audio->Run();
}
-#endif
void PPB_Audio_Shared::Run() {
int pending_data = 0;
diff --git a/ppapi/shared_impl/ppb_audio_shared.h b/ppapi/shared_impl/ppb_audio_shared.h
index 6ba8cac2e6..31888c8826 100644
--- a/ppapi/shared_impl/ppb_audio_shared.h
+++ b/ppapi/shared_impl/ppb_audio_shared.h
@@ -15,9 +15,7 @@
#include "ppapi/shared_impl/resource.h"
#include "ppapi/thunk/ppb_audio_api.h"
-#if defined(OS_NACL)
-#include "ppapi/nacl_irt/public/irt_ppapi.h"
-#endif
+struct PP_ThreadFunctions;
namespace ppapi {
@@ -79,11 +77,20 @@ class PPAPI_SHARED_EXPORT PPB_Audio_Shared
PP_AudioSampleRate sample_rate,
int sample_frame_count);
-#if defined(OS_NACL)
+ // Returns whether a thread can be created on the client context.
+ // In trusted plugin, this should always return true, as it uses Chrome's
+ // thread library. In NaCl plugin, this returns whether SetThreadFunctions
+ // was invoked properly.
+ static bool IsThreadFunctionReady();
+
+ // Configures this class to run in a NaCl plugin.
+ // If called, SetThreadFunctions() must be called before calling
+ // SetStartPlaybackState() on any instance of this class.
+ static void SetNaClMode();
+
// NaCl has a special API for IRT code to create threads that can call back
// into user code.
static void SetThreadFunctions(const struct PP_ThreadFunctions* functions);
-#endif
private:
// Starts execution of the audio thread.
@@ -110,15 +117,12 @@ class PPAPI_SHARED_EXPORT PPB_Audio_Shared
// The size of the sample buffer in bytes.
size_t shared_memory_size_;
-#if !defined(OS_NACL)
// When the callback is set, this thread is spawned for calling it.
scoped_ptr<base::DelegateSimpleThread> audio_thread_;
-#else
- uintptr_t thread_id_;
- bool thread_active_;
+ uintptr_t nacl_thread_id_;
+ bool nacl_thread_active_;
static void CallRun(void* self);
-#endif
// Callback to call when audio is ready to accept new samples.
AudioCallbackCombined callback_;
diff --git a/ppapi/tests/DEPS b/ppapi/tests/DEPS
index 4f757144fc..06b64ab19b 100644
--- a/ppapi/tests/DEPS
+++ b/ppapi/tests/DEPS
@@ -12,6 +12,11 @@ include_rules = [
"+ppapi/lib",
"+ppapi/tests",
"+ppapi/utility",
+
+ # Test to confirm whether PPB_Audio_Shared works properly in NaCl needs to
+ # call nacl_irt_ppapihook internally to emulate some erroneous situation.
+ "+native_client/src/untrusted/irt/irt.h",
+ "+ppapi/native_client/src/untrusted/irt_stub/thread_creator.h",
]
# checkdeps.py shouldn't check include paths for files in clang, which aren't
# part of the chrome build.
diff --git a/ppapi/tests/test_audio.cc b/ppapi/tests/test_audio.cc
index 4fea6e8646..1c1c9b594a 100644
--- a/ppapi/tests/test_audio.cc
+++ b/ppapi/tests/test_audio.cc
@@ -12,10 +12,87 @@
#include "ppapi/tests/testing_instance.h"
#include "ppapi/tests/test_utils.h"
+#if defined(__native_client__)
+#include "native_client/src/untrusted/irt/irt.h"
+#include "ppapi/native_client/src/untrusted/irt_stub/thread_creator.h"
+#endif
+
#define ARRAYSIZE_UNSAFE(a) \
((sizeof(a) / sizeof(*(a))) / \
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+#if defined(__native_client__)
+namespace {
+
+void GetNaClIrtPpapiHook(struct nacl_irt_ppapihook* hooks) {
+ nacl_interface_query(NACL_IRT_PPAPIHOOK_v0_1, hooks, sizeof(*hooks));
+}
+
+struct PP_ThreadFunctions g_thread_funcs = {};
+
+void ThreadFunctionsGetter(const struct PP_ThreadFunctions* thread_funcs) {
+ g_thread_funcs = *thread_funcs;
+}
+
+// In order to check if the thread_create is called, CountingThreadCreate()
+// increments this variable. Callers can check if the function is actually
+// called by looking at this value.
+int g_num_thread_create_called = 0;
+int g_num_thread_join_called = 0;
+
+int CountingThreadCreate(uintptr_t* tid,
+ void (*func)(void* thread_argument),
+ void* thread_argument) {
+ ++g_num_thread_create_called;
+ return g_thread_funcs.thread_create(tid, func, thread_argument);
+}
+
+int CountingThreadJoin(uintptr_t tid) {
+ ++g_num_thread_join_called;
+ return g_thread_funcs.thread_join(tid);
+}
+
+// Sets NULL for PP_ThreadFunctions to emulate the situation that
+// ppapi_register_thread_creator() is not yet called.
+void SetNullThreadFunctions() {
+ nacl_irt_ppapihook hooks;
+ GetNaClIrtPpapiHook(&hooks);
+ PP_ThreadFunctions thread_functions = {};
+ hooks.ppapi_register_thread_creator(&thread_functions);
+}
+
+void InjectCountingThreadFunctions() {
+ // First of all, we extract the system default thread functions.
+ // Internally, __nacl_register_thread_creator calls
+ // hooks.ppapi_register_thread_creator with default PP_ThreadFunctions
+ // instance. ThreadFunctionGetter stores it to g_thread_funcs.
+ nacl_irt_ppapihook hooks = { NULL, ThreadFunctionsGetter };
+ __nacl_register_thread_creator(&hooks);
+
+ // Here g_thread_funcs stores the thread functions.
+ // Inject the CountingThreadCreate.
+ PP_ThreadFunctions thread_functions = {
+ CountingThreadCreate,
+ CountingThreadJoin,
+ };
+ GetNaClIrtPpapiHook(&hooks);
+ hooks.ppapi_register_thread_creator(&thread_functions);
+}
+
+// Resets the PP_ThreadFunctions on exit from the scope.
+class ScopedThreadFunctionsResetter {
+ public:
+ ScopedThreadFunctionsResetter() {}
+ ~ScopedThreadFunctionsResetter() {
+ nacl_irt_ppapihook hooks;
+ GetNaClIrtPpapiHook(&hooks);
+ __nacl_register_thread_creator(&hooks);
+ }
+};
+
+} // namespace
+#endif // __native_client__
+
REGISTER_TEST_CASE(Audio);
TestAudio::TestAudio(TestingInstance* instance)
@@ -53,6 +130,11 @@ void TestAudio::RunTests(const std::string& filter) {
RUN_TEST(AudioCallback2, filter);
RUN_TEST(AudioCallback3, filter);
RUN_TEST(AudioCallback4, filter);
+
+#if defined(__native_client__)
+ RUN_TEST(AudioThreadCreatorIsRequired, filter);
+ RUN_TEST(AudioThreadCreatorIsCalled, filter);
+#endif
}
// Test creating audio resources for all guaranteed sample rates and various
@@ -319,6 +401,91 @@ std::string TestAudio::TestAudioCallback4() {
PASS();
}
+#if defined(__native_client__)
+// Tests the behavior of the thread_create functions.
+// For PPB_Audio_Shared to work properly, the user code must call
+// ppapi_register_thread_creator(). This test checks the error handling for the
+// case when user code doesn't call ppapi_register_thread_creator().
+std::string TestAudio::TestAudioThreadCreatorIsRequired() {
+ // We'll inject some thread functions in this test case.
+ // Reset them at the end of this case.
+ ScopedThreadFunctionsResetter thread_resetter;
+
+ // Set the thread functions to NULLs to emulate the situation where
+ // ppapi_register_thread_creator() is not called by user code.
+ SetNullThreadFunctions();
+
+ PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 1024);
+ ASSERT_TRUE(ac);
+ audio_callback_method_ = NULL;
+ PP_Resource audio = audio_interface_->Create(
+ instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
+ core_interface_->ReleaseResource(ac);
+ ac = 0;
+
+ // StartPlayback() fails, because no thread creating function
+ // is available.
+ ASSERT_FALSE(audio_interface_->StartPlayback(audio));
+
+ // If any more audio callbacks are generated,
+ // we should crash (which is good).
+ audio_callback_method_ = NULL;
+
+ core_interface_->ReleaseResource(audio);
+
+ PASS();
+}
+
+// Tests whether the thread functions passed from the user code are actually
+// called.
+std::string TestAudio::TestAudioThreadCreatorIsCalled() {
+ // We'll inject some thread functions in this test case.
+ // Reset them at the end of this case.
+ ScopedThreadFunctionsResetter thread_resetter;
+
+ // Inject the thread counting function. In the injected function,
+ // when called, g_num_thread_create_called is incremented.
+ g_num_thread_create_called = 0;
+ g_num_thread_join_called = 0;
+ InjectCountingThreadFunctions();
+
+ PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 1024);
+ ASSERT_TRUE(ac);
+ audio_callback_method_ = NULL;
+ PP_Resource audio = audio_interface_->Create(
+ instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
+ core_interface_->ReleaseResource(ac);
+ ac = 0;
+
+ audio_callback_event_.Reset();
+ test_done_ = false;
+
+ audio_callback_method_ = &TestAudio::AudioCallbackTest;
+ ASSERT_TRUE(audio_interface_->StartPlayback(audio));
+
+ // Wait for the audio callback to be called.
+ audio_callback_event_.Wait();
+ // Here, the injected thread_create is called, but thread_join is not yet.
+ ASSERT_EQ(1, g_num_thread_create_called);
+ ASSERT_EQ(0, g_num_thread_join_called);
+
+ ASSERT_TRUE(audio_interface_->StopPlayback(audio));
+
+ test_done_ = true;
+
+ // Here, the injected thread_join is called.
+ ASSERT_EQ(1, g_num_thread_join_called);
+
+ // If any more audio callbacks are generated,
+ // we should crash (which is good).
+ audio_callback_method_ = NULL;
+
+ core_interface_->ReleaseResource(audio);
+
+ PASS();
+}
+#endif
+
// TODO(raymes): Test that actually playback happens correctly, etc.
static void Crash() {
diff --git a/ppapi/tests/test_audio.h b/ppapi/tests/test_audio.h
index 56e6254e18..63e06f48e2 100644
--- a/ppapi/tests/test_audio.h
+++ b/ppapi/tests/test_audio.h
@@ -30,6 +30,11 @@ class TestAudio : public TestCase {
std::string TestAudioCallback3();
std::string TestAudioCallback4();
+#if defined(__native_client__)
+ std::string TestAudioThreadCreatorIsRequired();
+ std::string TestAudioThreadCreatorIsCalled();
+#endif
+
// Calls |audio_callback_method_| (where |user_data| is "this").
static void AudioCallbackTrampoline(void* sample_buffer,
uint32_t buffer_size_in_bytes,