Commit 79d23c7e authored by brettw@chromium.org's avatar brettw@chromium.org

Reland 95309. Add a template to handle properly issuing completion callbacks.

This fixes some bugs where we forgot to issue completion callbacks in some
error cases in the proxy, and cleans up the cases that were already doing this
properly.

This removes the PPB_AudioTrusted_API and folds those functions into the
regular Audio API. I'm trying to merge more things to have a smaller explosion
of APIs and the boilerplate associated with them.
Original review URL: http://codereview.chromium.org/7551032
Review URL: http://codereview.chromium.org/7585025

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95859 0039d316-1c4b-4281-b951-d872f2087c98
parent 3e15fdfe
...@@ -72,7 +72,6 @@ ...@@ -72,7 +72,6 @@
'thunk/ppb_audio_config_api.h', 'thunk/ppb_audio_config_api.h',
'thunk/ppb_audio_config_thunk.cc', 'thunk/ppb_audio_config_thunk.cc',
'thunk/ppb_audio_thunk.cc', 'thunk/ppb_audio_thunk.cc',
'thunk/ppb_audio_trusted_api.h',
'thunk/ppb_audio_trusted_thunk.cc', 'thunk/ppb_audio_trusted_thunk.cc',
'thunk/ppb_broker_api.h', 'thunk/ppb_broker_api.h',
'thunk/ppb_broker_thunk.cc', 'thunk/ppb_broker_thunk.cc',
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define PPAPI_PROXY_ENTER_PROXY_H_ #define PPAPI_PROXY_ENTER_PROXY_H_
#include "base/logging.h" #include "base/logging.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/proxy/host_dispatcher.h" #include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/plugin_resource_tracker.h"
...@@ -52,6 +53,96 @@ class EnterHostFromHostResource ...@@ -52,6 +53,96 @@ class EnterHostFromHostResource
} }
}; };
// Enters a resource and forces a completion callback to be issued.
//
// This is used when implementing the host (renderer) side of a resource
// function that issues a completion callback. In all cases, we need to issue
// the callback to avoid hanging the plugin.
//
// This class automatically constructs a callback with the given factory
// calling the given method. The method will generally be the one that sends
// the message to trigger the completion callback in the plugin process.
//
// It will automatically issue the callback with PP_ERROR_NOINTERFACE if the
// host resource is invalid (i.e. failed() is set). In all other cases you
// should call SetResult(), which will issue the callback immediately if the
// result value isn't PP_OK_COMPLETIONPENDING. In the "completion pending"
// case, it's assumed the function the proxy is calling will take responsibility
// of executing the callback (returned by callback()).
//
// Example:
// EnterHostFromHostResourceForceCallback<PPB_Foo_API> enter(
// resource, callback_factory_, &MyClass::SendResult, resource);
// if (enter.failed())
// return; // SendResult automatically called with PP_ERROR_BADRESOURCE.
// enter.SetResult(enter.object()->DoFoo(enter.callback()));
//
// Where DoFoo's signature looks like this:
// int32_t DoFoo(PP_CompletionCallback callback);
// And SendResult's implementation looks like this:
// void MyClass::SendResult(int32_t result, const HostResource& res) {
// Send(new FooMsg_FooComplete(..., result, res));
// }
template<typename ResourceT>
class EnterHostFromHostResourceForceCallback
: public EnterHostFromHostResource<ResourceT> {
public:
// For callbacks that take no parameters except the "int32_t result". Most
// implementations will use the 1-extra-argument constructor below.
template<class CallbackFactory, typename Method>
EnterHostFromHostResourceForceCallback(const HostResource& host_resource,
CallbackFactory& factory,
Method method)
: EnterHostFromHostResource<ResourceT>(host_resource),
needs_running_(true),
callback_(factory.NewOptionalCallback(method)) {
if (this->failed())
RunCallback(PP_ERROR_BADRESOURCE);
}
// For callbacks that take an extra parameter as a closure.
template<class CallbackFactory, typename Method, typename A>
EnterHostFromHostResourceForceCallback(const HostResource& host_resource,
CallbackFactory& factory,
Method method,
const A& a)
: EnterHostFromHostResource<ResourceT>(host_resource),
needs_running_(true),
callback_(factory.NewOptionalCallback(method, a)) {
if (this->failed())
RunCallback(PP_ERROR_BADRESOURCE);
}
~EnterHostFromHostResourceForceCallback() {
if (needs_running_) {
NOTREACHED() << "Should always call SetResult except in the "
"initialization failed case.";
RunCallback(PP_ERROR_FAILED);
}
}
void SetResult(int32_t result) {
DCHECK(needs_running_) << "Don't call SetResult when there already is one.";
needs_running_ = false;
if (result != PP_OK_COMPLETIONPENDING)
callback_.Run(result);
}
PP_CompletionCallback callback() {
return callback_.pp_completion_callback();
}
private:
void RunCallback(int32_t result) {
DCHECK(needs_running_);
needs_running_ = false;
callback_.Run(result);
}
bool needs_running_;
pp::CompletionCallback callback_;
};
} // namespace proxy } // namespace proxy
} // namespace pp } // namespace pp
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ppapi/proxy/ppb_audio_proxy.h" #include "ppapi/proxy/ppb_audio_proxy.h"
#include "base/compiler_specific.h"
#include "base/threading/simple_thread.h" #include "base/threading/simple_thread.h"
#include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_audio.h" #include "ppapi/c/ppb_audio.h"
...@@ -17,12 +18,13 @@ ...@@ -17,12 +18,13 @@
#include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/audio_impl.h" #include "ppapi/shared_impl/audio_impl.h"
#include "ppapi/thunk/ppb_audio_config_api.h" #include "ppapi/thunk/ppb_audio_config_api.h"
#include "ppapi/thunk/ppb_audio_trusted_api.h"
#include "ppapi/thunk/enter.h" #include "ppapi/thunk/enter.h"
#include "ppapi/thunk/resource_creation_api.h" #include "ppapi/thunk/resource_creation_api.h"
#include "ppapi/thunk/thunk.h" #include "ppapi/thunk/thunk.h"
using ::ppapi::thunk::PPB_Audio_API; using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_Audio_API;
using ppapi::thunk::PPB_AudioConfig_API;
namespace pp { namespace pp {
namespace proxy { namespace proxy {
...@@ -42,6 +44,10 @@ class Audio : public PluginResource, public ppapi::AudioImpl { ...@@ -42,6 +44,10 @@ class Audio : public PluginResource, public ppapi::AudioImpl {
virtual PP_Resource GetCurrentConfig() OVERRIDE; virtual PP_Resource GetCurrentConfig() OVERRIDE;
virtual PP_Bool StartPlayback() OVERRIDE; virtual PP_Bool StartPlayback() OVERRIDE;
virtual PP_Bool StopPlayback() OVERRIDE; virtual PP_Bool StopPlayback() OVERRIDE;
virtual int32_t OpenTrusted(PP_Resource config_id,
PP_CompletionCallback create_callback) OVERRIDE;
virtual int32_t GetSyncSocket(int* sync_socket) OVERRIDE;
virtual int32_t GetSharedMemory(int* shm_handle, uint32_t* shm_size) OVERRIDE;
private: private:
// Owning reference to the current config object. This isn't actually used, // Owning reference to the current config object. This isn't actually used,
...@@ -95,6 +101,19 @@ PP_Bool Audio::StopPlayback() { ...@@ -95,6 +101,19 @@ PP_Bool Audio::StopPlayback() {
return PP_TRUE; return PP_TRUE;
} }
int32_t Audio::OpenTrusted(PP_Resource config_id,
PP_CompletionCallback create_callback) {
return PP_ERROR_NOTSUPPORTED; // Don't proxy the trusted interface.
}
int32_t Audio::GetSyncSocket(int* sync_socket) {
return PP_ERROR_NOTSUPPORTED; // Don't proxy the trusted interface.
}
int32_t Audio::GetSharedMemory(int* shm_handle, uint32_t* shm_size) {
return PP_ERROR_NOTSUPPORTED; // Don't proxy the trusted interface.
}
namespace { namespace {
InterfaceProxy* CreateAudioProxy(Dispatcher* dispatcher, InterfaceProxy* CreateAudioProxy(Dispatcher* dispatcher,
...@@ -147,8 +166,7 @@ PP_Resource PPB_Audio_Proxy::CreateProxyResource( ...@@ -147,8 +166,7 @@ PP_Resource PPB_Audio_Proxy::CreateProxyResource(
if (!dispatcher) if (!dispatcher)
return 0; return 0;
::ppapi::thunk::EnterResourceNoLock< ::ppapi::thunk::PPB_AudioConfig_API> EnterResourceNoLock<PPB_AudioConfig_API> config(config_id, true);
config(config_id, true);
if (config.failed()) if (config.failed())
return 0; return 0;
...@@ -193,26 +211,35 @@ void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id, ...@@ -193,26 +211,35 @@ void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id,
resource_creation.functions()->CreateAudioTrusted(instance_id)); resource_creation.functions()->CreateAudioTrusted(instance_id));
if (result->is_null()) if (result->is_null())
return; return;
::ppapi::thunk::EnterResourceNoLock< ::ppapi::thunk::PPB_AudioTrusted_API>
trusted_audio(result->host_resource(), false); // At this point, we've set the result resource, and this is a sync request.
if (trusted_audio.failed()) // Anything below this point must issue the AudioChannelConnected callback
return; // to the browser. Since that's an async message, it will be issued back to
// the plugin after the Create function returns (which is good because it
// would be weird to get a connected message with a failure code for a
// resource you haven't finished creating yet).
//
// The ...ForceCallback class will help ensure the callback is always called.
// All error cases must call SetResult on this class.
EnterHostFromHostResourceForceCallback<PPB_Audio_API> enter(
*result, callback_factory_,
&PPB_Audio_Proxy::AudioChannelConnected, *result);
if (enter.failed())
return; // When enter fails, it will internally schedule the callback.
// Make an audio config object. // Make an audio config object.
PP_Resource audio_config_res = PP_Resource audio_config_res =
resource_creation.functions()->CreateAudioConfig( resource_creation.functions()->CreateAudioConfig(
instance_id, static_cast<PP_AudioSampleRate>(sample_rate), instance_id, static_cast<PP_AudioSampleRate>(sample_rate),
sample_frame_count); sample_frame_count);
if (!audio_config_res) if (!audio_config_res) {
enter.SetResult(PP_ERROR_FAILED);
return; return;
}
// Initiate opening the audio object. // Initiate opening the audio object.
CompletionCallback callback = callback_factory_.NewOptionalCallback( enter.SetResult(enter.object()->OpenTrusted(audio_config_res,
&PPB_Audio_Proxy::AudioChannelConnected, *result); enter.callback()));
int32_t open_error = trusted_audio.object()->OpenTrusted(
audio_config_res, callback.pp_completion_callback());
if (open_error != PP_OK_COMPLETIONPENDING)
callback.Run(open_error);
// Clean up the temporary audio config resource we made. // Clean up the temporary audio config resource we made.
const PPB_Core* core = static_cast<const PPB_Core*>( const PPB_Core* core = static_cast<const PPB_Core*>(
...@@ -280,15 +307,14 @@ int32_t PPB_Audio_Proxy::GetAudioConnectedHandles( ...@@ -280,15 +307,14 @@ int32_t PPB_Audio_Proxy::GetAudioConnectedHandles(
IPC::PlatformFileForTransit* foreign_socket_handle, IPC::PlatformFileForTransit* foreign_socket_handle,
base::SharedMemoryHandle* foreign_shared_memory_handle, base::SharedMemoryHandle* foreign_shared_memory_handle,
uint32_t* shared_memory_length) { uint32_t* shared_memory_length) {
// Get the trusted audio interface which will give us the handles. // Get the audio interface which will give us the handles.
::ppapi::thunk::EnterResourceNoLock< ::ppapi::thunk::PPB_AudioTrusted_API> EnterResourceNoLock<PPB_Audio_API> enter(resource.host_resource(), false);
trusted_audio(resource.host_resource(), false); if (enter.failed())
if (trusted_audio.failed())
return PP_ERROR_NOINTERFACE; return PP_ERROR_NOINTERFACE;
// Get the socket handle for signaling. // Get the socket handle for signaling.
int32_t socket_handle; int32_t socket_handle;
int32_t result = trusted_audio.object()->GetSyncSocket(&socket_handle); int32_t result = enter.object()->GetSyncSocket(&socket_handle);
if (result != PP_OK) if (result != PP_OK)
return result; return result;
...@@ -300,8 +326,8 @@ int32_t PPB_Audio_Proxy::GetAudioConnectedHandles( ...@@ -300,8 +326,8 @@ int32_t PPB_Audio_Proxy::GetAudioConnectedHandles(
// Get the shared memory for the buffer. // Get the shared memory for the buffer.
int shared_memory_handle; int shared_memory_handle;
result = trusted_audio.object()->GetSharedMemory(&shared_memory_handle, result = enter.object()->GetSharedMemory(&shared_memory_handle,
shared_memory_length); shared_memory_length);
if (result != PP_OK) if (result != PP_OK)
return result; return result;
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include "ppapi/thunk/enter.h" #include "ppapi/thunk/enter.h"
#include "ppapi/thunk/thunk.h" #include "ppapi/thunk/thunk.h"
using ppapi::thunk::PPB_Broker_API;
namespace pp { namespace pp {
namespace proxy { namespace proxy {
...@@ -46,14 +48,13 @@ InterfaceProxy* CreateBrokerProxy(Dispatcher* dispatcher, ...@@ -46,14 +48,13 @@ InterfaceProxy* CreateBrokerProxy(Dispatcher* dispatcher,
} // namespace } // namespace
class Broker : public ppapi::thunk::PPB_Broker_API, class Broker : public PPB_Broker_API, public PluginResource {
public PluginResource {
public: public:
explicit Broker(const HostResource& resource); explicit Broker(const HostResource& resource);
virtual ~Broker(); virtual ~Broker();
// ResourceObjectBase overries. // ResourceObjectBase overries.
virtual ppapi::thunk::PPB_Broker_API* AsPPB_Broker_API() OVERRIDE; virtual PPB_Broker_API* AsPPB_Broker_API() OVERRIDE;
// PPB_Broker_API implementation. // PPB_Broker_API implementation.
virtual int32_t Connect(PP_CompletionCallback connect_callback) OVERRIDE; virtual int32_t Connect(PP_CompletionCallback connect_callback) OVERRIDE;
...@@ -96,7 +97,7 @@ Broker::~Broker() { ...@@ -96,7 +97,7 @@ Broker::~Broker() {
socket_handle_ = base::kInvalidPlatformFileValue; socket_handle_ = base::kInvalidPlatformFileValue;
} }
ppapi::thunk::PPB_Broker_API* Broker::AsPPB_Broker_API() { PPB_Broker_API* Broker::AsPPB_Broker_API() {
return this; return this;
} }
...@@ -204,14 +205,11 @@ void PPB_Broker_Proxy::OnMsgCreate(PP_Instance instance, ...@@ -204,14 +205,11 @@ void PPB_Broker_Proxy::OnMsgCreate(PP_Instance instance,
} }
void PPB_Broker_Proxy::OnMsgConnect(const HostResource& broker) { void PPB_Broker_Proxy::OnMsgConnect(const HostResource& broker) {
CompletionCallback callback = callback_factory_.NewOptionalCallback( EnterHostFromHostResourceForceCallback<PPB_Broker_API> enter(
broker, callback_factory_,
&PPB_Broker_Proxy::ConnectCompleteInHost, broker); &PPB_Broker_Proxy::ConnectCompleteInHost, broker);
if (enter.succeeded())
int32_t result = ppb_broker_target()->Connect( enter.SetResult(enter.object()->Connect(enter.callback()));
broker.host_resource(),
callback.pp_completion_callback());
if (result != PP_OK_COMPLETIONPENDING)
callback.Run(result);
} }
// Called in the plugin to handle the connect callback. // Called in the plugin to handle the connect callback.
...@@ -225,7 +223,7 @@ void PPB_Broker_Proxy::OnMsgConnectComplete( ...@@ -225,7 +223,7 @@ void PPB_Broker_Proxy::OnMsgConnectComplete(
DCHECK(result == PP_OK || DCHECK(result == PP_OK ||
socket_handle == IPC::InvalidPlatformFileForTransit()); socket_handle == IPC::InvalidPlatformFileForTransit());
EnterPluginFromHostResource<ppapi::thunk::PPB_Broker_API> enter(resource); EnterPluginFromHostResource<PPB_Broker_API> enter(resource);
if (enter.failed()) { if (enter.failed()) {
// As in Broker::ConnectComplete, we need to close the resource on error. // As in Broker::ConnectComplete, we need to close the resource on error.
base::SyncSocket temp_socket( base::SyncSocket temp_socket(
......
...@@ -194,13 +194,11 @@ void PPB_FileChooser_Proxy::OnMsgCreate(PP_Instance instance, ...@@ -194,13 +194,11 @@ void PPB_FileChooser_Proxy::OnMsgCreate(PP_Instance instance,
} }
void PPB_FileChooser_Proxy::OnMsgShow(const HostResource& chooser) { void PPB_FileChooser_Proxy::OnMsgShow(const HostResource& chooser) {
CompletionCallback callback = callback_factory_.NewOptionalCallback( EnterHostFromHostResourceForceCallback<PPB_FileChooser_API> enter(
&PPB_FileChooser_Proxy::OnShowCallback, chooser); chooser, callback_factory_, &PPB_FileChooser_Proxy::OnShowCallback,
chooser);
int32_t result = ppb_file_chooser_target()->Show( if (enter.succeeded())
chooser.host_resource(), callback.pp_completion_callback()); enter.SetResult(enter.object()->Show(enter.callback()));
if (result != PP_OK_COMPLETIONPENDING)
callback.Run(result);
} }
void PPB_FileChooser_Proxy::OnMsgChooseComplete( void PPB_FileChooser_Proxy::OnMsgChooseComplete(
......
...@@ -174,16 +174,11 @@ void PPB_FileSystem_Proxy::OnMsgCreate(PP_Instance instance, ...@@ -174,16 +174,11 @@ void PPB_FileSystem_Proxy::OnMsgCreate(PP_Instance instance,
void PPB_FileSystem_Proxy::OnMsgOpen(const HostResource& host_resource, void PPB_FileSystem_Proxy::OnMsgOpen(const HostResource& host_resource,
int64_t expected_size) { int64_t expected_size) {
EnterHostFromHostResource<PPB_FileSystem_API> enter(host_resource); EnterHostFromHostResourceForceCallback<PPB_FileSystem_API> enter(
if (enter.failed()) host_resource, callback_factory_,
return;
CompletionCallback callback = callback_factory_.NewOptionalCallback(
&PPB_FileSystem_Proxy::OpenCompleteInHost, host_resource); &PPB_FileSystem_Proxy::OpenCompleteInHost, host_resource);
int32_t result = enter.object()->Open(expected_size, if (enter.succeeded())
callback.pp_completion_callback()); enter.SetResult(enter.object()->Open(expected_size, enter.callback()));
if (result != PP_OK_COMPLETIONPENDING)
callback.Run(result);
} }
// Called in the plugin to handle the open callback. // Called in the plugin to handle the open callback.
......
...@@ -162,21 +162,13 @@ void PPB_Flash_Menu_Proxy::OnMsgShow(const HostResource& menu, ...@@ -162,21 +162,13 @@ void PPB_Flash_Menu_Proxy::OnMsgShow(const HostResource& menu,
const PP_Point& location) { const PP_Point& location) {
ShowRequest* request = new ShowRequest; ShowRequest* request = new ShowRequest;
request->menu = menu; request->menu = menu;
CompletionCallback callback = callback_factory_.NewOptionalCallback(
&PPB_Flash_Menu_Proxy::SendShowACKToPlugin, request);
EnterHostFromHostResource<PPB_Flash_Menu_API> enter(menu); EnterHostFromHostResourceForceCallback<PPB_Flash_Menu_API> enter(
int32_t result = PP_ERROR_BADRESOURCE; menu, callback_factory_, &PPB_Flash_Menu_Proxy::SendShowACKToPlugin,
request);
if (enter.succeeded()) { if (enter.succeeded()) {
result = enter.object()->Show(&location, enter.SetResult(enter.object()->Show(&location, &request->selected_id,
&request->selected_id, enter.callback()));
callback.pp_completion_callback());
}
if (result != PP_OK_COMPLETIONPENDING) {
// There was some error, so we won't get a callback. We need to now issue
// the ACK to the plugin so that it hears about the error. This will also
// clean up the data associated with the callback.
callback.Run(result);
} }
} }
......
...@@ -240,16 +240,12 @@ void PPB_Graphics2D_Proxy::OnMsgReplaceContents( ...@@ -240,16 +240,12 @@ void PPB_Graphics2D_Proxy::OnMsgReplaceContents(
} }
void PPB_Graphics2D_Proxy::OnMsgFlush(const HostResource& graphics_2d) { void PPB_Graphics2D_Proxy::OnMsgFlush(const HostResource& graphics_2d) {
CompletionCallback callback = callback_factory_.NewOptionalCallback( EnterHostFromHostResourceForceCallback<PPB_Graphics2D_API> enter(
graphics_2d, callback_factory_,
&PPB_Graphics2D_Proxy::SendFlushACKToPlugin, graphics_2d); &PPB_Graphics2D_Proxy::SendFlushACKToPlugin, graphics_2d);
int32_t result = ppb_graphics_2d_target()->Flush( if (enter.failed())
graphics_2d.host_resource(), callback.pp_completion_callback()); return;
if (result != PP_OK_COMPLETIONPENDING) { enter.SetResult(enter.object()->Flush(enter.callback()));
// There was some error, so we won't get a flush callback. We need to now
// issue the ACK to the plugin hears about the error. This will also clean
// up the data associated with the callback.
callback.Run(result);
}
} }
void PPB_Graphics2D_Proxy::OnMsgFlushACK(const HostResource& host_resource, void PPB_Graphics2D_Proxy::OnMsgFlushACK(const HostResource& host_resource,
......
...@@ -587,19 +587,11 @@ void PPB_Graphics3D_Proxy::OnMsgGetTransferBuffer( ...@@ -587,19 +587,11 @@ void PPB_Graphics3D_Proxy::OnMsgGetTransferBuffer(
} }
void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) { void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
CompletionCallback callback = callback_factory_.NewOptionalCallback( EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
context, callback_factory_,
&PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context); &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
int32_t result = PP_ERROR_BADRESOURCE;
if (enter.succeeded()) if (enter.succeeded())
result = enter.object()->SwapBuffers(callback.pp_completion_callback()); enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
if (result != PP_OK_COMPLETIONPENDING) {
// There was some error, so we won't get a flush callback. We need to now
// issue the ACK to the plugin hears about the error. This will also clean
// up the data associated with the callback.
callback.Run(result);
}
} }
void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource, void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
......
...@@ -177,19 +177,11 @@ void PPB_Surface3D_Proxy::OnMsgCreate(PP_Instance instance, ...@@ -177,19 +177,11 @@ void PPB_Surface3D_Proxy::OnMsgCreate(PP_Instance instance,
} }
void PPB_Surface3D_Proxy::OnMsgSwapBuffers(const HostResource& surface_3d) { void PPB_Surface3D_Proxy::OnMsgSwapBuffers(const HostResource& surface_3d) {
CompletionCallback callback = callback_factory_.NewOptionalCallback( EnterHostFromHostResourceForceCallback<PPB_Surface3D_API> enter(
surface_3d, callback_factory_,
&PPB_Surface3D_Proxy::SendSwapBuffersACKToPlugin, surface_3d); &PPB_Surface3D_Proxy::SendSwapBuffersACKToPlugin, surface_3d);
EnterHostFromHostResource<PPB_Surface3D_API> enter(surface_3d);
int32_t result = PP_ERROR_BADRESOURCE;
if (enter.succeeded()) if (enter.succeeded())
result = enter.object()->SwapBuffers(callback.pp_completion_callback()); enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
if (result != PP_OK_COMPLETIONPENDING) {
// There was some error, so we won't get a flush callback. We need to now
// issue the ACK to the plugin hears about the error. This will also clean
// up the data associated with the callback.
callback.Run(result);
}
} }
void PPB_Surface3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource, void PPB_Surface3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
......
...@@ -517,21 +517,12 @@ void PPB_URLLoader_Proxy::OnMsgReadResponseBody( ...@@ -517,21 +517,12 @@ void PPB_URLLoader_Proxy::OnMsgReadResponseBody(
// TODO(brettw) have a way to check for out-of-memory. // TODO(brettw) have a way to check for out-of-memory.
info->read_buffer.resize(bytes_to_read); info->read_buffer.resize(bytes_to_read);
CompletionCallback callback = callback_factory_.NewOptionalCallback( EnterHostFromHostResourceForceCallback<PPB_URLLoader_API> enter(
&PPB_URLLoader_Proxy::OnReadCallback, info); loader, callback_factory_, &PPB_URLLoader_Proxy::OnReadCallback, info);
EnterHostFromHostResource<PPB_URLLoader_API> enter(loader);
int32_t result = PP_ERROR_BADRESOURCE;
if (enter.succeeded()) { if (enter.succeeded()) {
result = enter.object()->ReadResponseBody( enter.SetResult(enter.object()->ReadResponseBody(
const_cast<char*>(info->read_buffer.c_str()), const_cast<char*>(info->read_buffer.c_str()),
bytes_to_read, callback.pp_completion_callback()); bytes_to_read, enter.callback()));
}
if (result != PP_OK_COMPLETIONPENDING) {
// Send error (or perhaps success for synchronous reads) back to plugin.
// The callback function is already set up to do this and also delete the
// callback info.
callback.Run(result);
} }
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef PPAPI_THUNK_AUDIO_API_H_ #ifndef PPAPI_THUNK_AUDIO_API_H_
#define PPAPI_THUNK_AUDIO_API_H_ #define PPAPI_THUNK_AUDIO_API_H_
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/ppb_audio.h" #include "ppapi/c/ppb_audio.h"
namespace ppapi { namespace ppapi {
...@@ -17,6 +18,12 @@ class PPB_Audio_API { ...@@ -17,6 +18,12 @@ class PPB_Audio_API {
virtual PP_Resource GetCurrentConfig() = 0; virtual PP_Resource GetCurrentConfig() = 0;
virtual PP_Bool StartPlayback() = 0; virtual PP_Bool StartPlayback() = 0;
virtual PP_Bool StopPlayback() = 0; virtual PP_Bool StopPlayback() = 0;
// Trusted API.
virtual int32_t OpenTrusted(PP_Resource config_id,
PP_CompletionCallback create_callback) = 0;
virtual int32_t GetSyncSocket(int* sync_socket) = 0;
virtual int32_t GetSharedMemory(int* shm_handle, uint32_t* shm_size) = 0;
}; };
} // namespace thunk } // namespace thunk
......
...@@ -12,6 +12,8 @@ namespace thunk { ...@@ -12,6 +12,8 @@ namespace thunk {
namespace { namespace {
typedef EnterResource<PPB_Audio_API> EnterAudio;
PP_Resource Create(PP_Instance instance, PP_Resource Create(PP_Instance instance,
PP_Resource config_id, PP_Resource config_id,
PPB_Audio_Callback callback, PPB_Audio_Callback callback,
...@@ -24,26 +26,26 @@ PP_Resource Create(PP_Instance instance, ...@@ -24,26 +26,26 @@ PP_Resource Create(PP_Instance instance,
} }
PP_Bool IsAudio(PP_Resource resource) { PP_Bool IsAudio(PP_Resource resource) {
EnterResource<PPB_Audio_API> enter(resource, false); EnterAudio enter(resource, false);
return enter.succeeded() ? PP_TRUE : PP_FALSE; return enter.succeeded() ? PP_TRUE : PP_FALSE;
} }
PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { PP_Resource GetCurrentConfiguration(PP_Resource audio_id) {
EnterResource<PPB_Audio_API> enter(audio_id, true); EnterAudio enter(audio_id, true);
if (enter.failed()) if (enter.failed())
return 0; return 0;
return enter.object()->GetCurrentConfig(); return enter.object()->GetCurrentConfig();
} }
PP_Bool StartPlayback(PP_Resource audio_id) { PP_Bool StartPlayback(PP_Resource audio_id) {
EnterResource<PPB_Audio_API> enter(audio_id, true); EnterAudio enter(audio_id, true);
if (enter.failed()) if (enter.failed())
return PP_FALSE; return PP_FALSE;
return enter.object()->StartPlayback(); return enter.object()->StartPlayback();
} }
PP_Bool StopPlayback(PP_Resource audio_id) { PP_Bool StopPlayback(PP_Resource audio_id) {
EnterResource<PPB_Audio_API> enter(audio_id, true); EnterAudio enter(audio_id, true);
if (enter.failed()) if (enter.failed())
return PP_FALSE; return PP_FALSE;
return enter.object()->StopPlayback(); return enter.object()->StopPlayback();
......
// Copyright (c) 2011 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_THUNK_AUDIO_TRUSTED_API_H_
#define PPAPI_THUNK_AUDIO_TRUSTED_API_H_
#include "ppapi/c/trusted/ppb_audio_trusted.h"
#include "ppapi/c/ppb_audio.h"
namespace ppapi {
namespace thunk {
class PPB_AudioTrusted_API {
public:
virtual ~PPB_AudioTrusted_API() {}
virtual int32_t OpenTrusted(PP_Resource config_id,
PP_CompletionCallback create_callback) = 0;
virtual int32_t GetSyncSocket(int* sync_socket) = 0;
virtual int32_t GetSharedMemory(int* shm_handle, uint32_t* shm_size) = 0;
};
} // namespace thunk
} // namespace ppapi
#endif // PPAPI_THUNK_AUDIO_TRUSTED_API_H_
...@@ -3,10 +3,11 @@ ...@@ -3,10 +3,11 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_errors.h"
#include "ppapi/c/trusted/ppb_audio_trusted.h"
#include "ppapi/thunk/common.h" #include "ppapi/thunk/common.h"
#include "ppapi/thunk/enter.h" #include "ppapi/thunk/enter.h"
#include "ppapi/thunk/thunk.h" #include "ppapi/thunk/thunk.h"
#include "ppapi/thunk/ppb_audio_trusted_api.h" #include "ppapi/thunk/ppb_audio_api.h"
#include "ppapi/thunk/resource_creation_api.h" #include "ppapi/thunk/resource_creation_api.h"
namespace ppapi { namespace ppapi {
...@@ -14,6 +15,8 @@ namespace thunk { ...@@ -14,6 +15,8 @@ namespace thunk {
namespace { namespace {
typedef EnterResource<PPB_Audio_API> EnterAudio;
PP_Resource Create(PP_Instance instance_id) { PP_Resource Create(PP_Instance instance_id) {
EnterFunction<ResourceCreationAPI> enter(instance_id, true); EnterFunction<ResourceCreationAPI> enter(instance_id, true);
if (enter.failed()) if (enter.failed())
...@@ -24,7 +27,7 @@ PP_Resource Create(PP_Instance instance_id) { ...@@ -24,7 +27,7 @@ PP_Resource Create(PP_Instance instance_id) {
int32_t Open(PP_Resource audio_id, int32_t Open(PP_Resource audio_id,
PP_Resource config_id, PP_Resource config_id,
PP_CompletionCallback create_callback) { PP_CompletionCallback create_callback) {
EnterResource<PPB_AudioTrusted_API> enter(audio_id, true); EnterAudio enter(audio_id, true);
if (enter.failed()) if (enter.failed())
return MayForceCallback(create_callback, PP_ERROR_BADRESOURCE); return MayForceCallback(create_callback, PP_ERROR_BADRESOURCE);
int32_t result = enter.object()->OpenTrusted(config_id, create_callback); int32_t result = enter.object()->OpenTrusted(config_id, create_callback);
...@@ -32,7 +35,7 @@ int32_t Open(PP_Resource audio_id, ...@@ -32,7 +35,7 @@ int32_t Open(PP_Resource audio_id,
} }
int32_t GetSyncSocket(PP_Resource audio_id, int* sync_socket) { int32_t GetSyncSocket(PP_Resource audio_id, int* sync_socket) {
EnterResource<PPB_AudioTrusted_API> enter(audio_id, true); EnterAudio enter(audio_id, true);
if (enter.failed()) if (enter.failed())
return PP_ERROR_BADRESOURCE; return PP_ERROR_BADRESOURCE;
return enter.object()->GetSyncSocket(sync_socket); return enter.object()->GetSyncSocket(sync_socket);
...@@ -41,7 +44,7 @@ int32_t GetSyncSocket(PP_Resource audio_id, int* sync_socket) { ...@@ -41,7 +44,7 @@ int32_t GetSyncSocket(PP_Resource audio_id, int* sync_socket) {
int32_t GetSharedMemory(PP_Resource audio_id, int32_t GetSharedMemory(PP_Resource audio_id,
int* shm_handle, int* shm_handle,
uint32_t* shm_size) { uint32_t* shm_size) {
EnterResource<PPB_AudioTrusted_API> enter(audio_id, true); EnterAudio enter(audio_id, true);
if (enter.failed()) if (enter.failed())
return PP_ERROR_BADRESOURCE; return PP_ERROR_BADRESOURCE;
return enter.object()->GetSharedMemory(shm_handle, shm_size); return enter.object()->GetSharedMemory(shm_handle, shm_size);
......
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
#include "ppapi/thunk/thunk.h" #include "ppapi/thunk/thunk.h"
#include "webkit/plugins/ppapi/common.h" #include "webkit/plugins/ppapi/common.h"
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_Audio_API;
using ppapi::thunk::PPB_AudioConfig_API;
namespace webkit { namespace webkit {
namespace ppapi { namespace ppapi {
...@@ -37,8 +41,7 @@ PP_Resource PPB_AudioConfig_Impl::Create(PluginInstance* instance, ...@@ -37,8 +41,7 @@ PP_Resource PPB_AudioConfig_Impl::Create(PluginInstance* instance,
return config->GetReference(); return config->GetReference();
} }
::ppapi::thunk::PPB_AudioConfig_API* PPB_AudioConfig_API* PPB_AudioConfig_Impl::AsPPB_AudioConfig_API() {
PPB_AudioConfig_Impl::AsPPB_AudioConfig_API() {
return this; return this;
} }
...@@ -86,19 +89,14 @@ PP_Resource PPB_Audio_Impl::Create(PluginInstance* instance, ...@@ -86,19 +89,14 @@ PP_Resource PPB_Audio_Impl::Create(PluginInstance* instance,
return audio->GetReference(); return audio->GetReference();
} }
::ppapi::thunk::PPB_Audio_API* PPB_Audio_Impl::AsPPB_Audio_API() { PPB_Audio_API* PPB_Audio_Impl::AsPPB_Audio_API() {
return this;
}
::ppapi::thunk::PPB_AudioTrusted_API* PPB_Audio_Impl::AsPPB_AudioTrusted_API() {
return this; return this;
} }
bool PPB_Audio_Impl::Init(PP_Resource config_id, bool PPB_Audio_Impl::Init(PP_Resource config_id,
PPB_Audio_Callback callback, void* user_data) { PPB_Audio_Callback callback, void* user_data) {
// Validate the config and keep a reference to it. // Validate the config and keep a reference to it.
::ppapi::thunk::EnterResourceNoLock< ::ppapi::thunk::PPB_AudioConfig_API> EnterResourceNoLock<PPB_AudioConfig_API> enter(config_id, true);
enter(config_id, true);
if (enter.failed()) if (enter.failed())
return false; return false;
config_id_ = config_id; config_id_ = config_id;
...@@ -147,8 +145,7 @@ int32_t PPB_Audio_Impl::OpenTrusted(PP_Resource config_id, ...@@ -147,8 +145,7 @@ int32_t PPB_Audio_Impl::OpenTrusted(PP_Resource config_id,
PP_CompletionCallback create_callback) { PP_CompletionCallback create_callback) {
// Validate the config and keep a reference to it. // Validate the config and keep a reference to it.
::ppapi::thunk::EnterResourceNoLock< ::ppapi::thunk::PPB_AudioConfig_API> EnterResourceNoLock<PPB_AudioConfig_API> enter(config_id, true);
enter(config_id, true);
if (enter.failed()) if (enter.failed())
return false; return false;
config_id_ = config_id; config_id_ = config_id;
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "ppapi/c/trusted/ppb_audio_trusted.h" #include "ppapi/c/trusted/ppb_audio_trusted.h"
#include "ppapi/shared_impl/audio_config_impl.h" #include "ppapi/shared_impl/audio_config_impl.h"
#include "ppapi/shared_impl/audio_impl.h" #include "ppapi/shared_impl/audio_impl.h"
#include "ppapi/thunk/ppb_audio_trusted_api.h"
#include "webkit/plugins/ppapi/plugin_delegate.h" #include "webkit/plugins/ppapi/plugin_delegate.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/resource.h" #include "webkit/plugins/ppapi/resource.h"
...@@ -49,7 +48,6 @@ class PPB_AudioConfig_Impl : public Resource, ...@@ -49,7 +48,6 @@ class PPB_AudioConfig_Impl : public Resource,
// AudioImpl so it can be shared with the proxy. // AudioImpl so it can be shared with the proxy.
class PPB_Audio_Impl : public Resource, class PPB_Audio_Impl : public Resource,
public ::ppapi::AudioImpl, public ::ppapi::AudioImpl,
public ::ppapi::thunk::PPB_AudioTrusted_API,
public PluginDelegate::PlatformAudio::Client { public PluginDelegate::PlatformAudio::Client {
public: public:
// Trusted initialization. You must call Init after this. // Trusted initialization. You must call Init after this.
...@@ -73,14 +71,11 @@ class PPB_Audio_Impl : public Resource, ...@@ -73,14 +71,11 @@ class PPB_Audio_Impl : public Resource,
// ResourceObjectBase overrides. // ResourceObjectBase overrides.
virtual ::ppapi::thunk::PPB_Audio_API* AsPPB_Audio_API(); virtual ::ppapi::thunk::PPB_Audio_API* AsPPB_Audio_API();
virtual ::ppapi::thunk::PPB_AudioTrusted_API* AsPPB_AudioTrusted_API();
// PPB_Audio_API implementation. // PPB_Audio_API implementation.
virtual PP_Resource GetCurrentConfig() OVERRIDE; virtual PP_Resource GetCurrentConfig() OVERRIDE;
virtual PP_Bool StartPlayback() OVERRIDE; virtual PP_Bool StartPlayback() OVERRIDE;
virtual PP_Bool StopPlayback() OVERRIDE; virtual PP_Bool StopPlayback() OVERRIDE;
// PPB_AudioTrusted_API implementation.
virtual int32_t OpenTrusted(PP_Resource config_id, virtual int32_t OpenTrusted(PP_Resource config_id,
PP_CompletionCallback create_callback) OVERRIDE; PP_CompletionCallback create_callback) OVERRIDE;
virtual int32_t GetSyncSocket(int* sync_socket) OVERRIDE; virtual int32_t GetSyncSocket(int* sync_socket) OVERRIDE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment