summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorraymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-04 00:07:44 +0000
committerraymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-04 00:07:44 +0000
commite1f5c9beb4952df82815be228e71fa46c219b0b0 (patch)
tree9d09a28bbe3ade14197e243d81c1e040ff1870ed /ppapi
parente64eef241cdf4b096e0e1976ccb11ab0f070d2ea (diff)
downloadchromium_src-e1f5c9beb4952df82815be228e71fa46c219b0b0.zip
chromium_src-e1f5c9beb4952df82815be228e71fa46c219b0b0.tar.gz
chromium_src-e1f5c9beb4952df82815be228e71fa46c219b0b0.tar.bz2
Converted PluginResource reply message handling to use base::Callback
Previously each PluginResource had to write a reply handler (|OnReplyReceived|) for any replies to resource messages. This approach had several problems including the fact that the PluginResource had to track the state of any outstanding calls. This change allows you to register a base::Callback when calling CallToBrowser/CallToRenderer. The callback will be run when a reply message is received with a sequence number matching the call. The parameters of the reply will be passed to the callback. An example of usage: CallBrowser<PpapiPluginMsg_MyResourceType_MyReplyMessage>( PpapiHostMsg_MyResourceType_MyRequestMessage(), base::Bind(&MyPluginResource::ReplyHandler, this)); If a reply message to this call is received whose type does not match the expected reply message (for example, in the case of an error), the callback will still be invoked but with the default values of the message parameters. BUG= Review URL: https://chromiumcodereview.appspot.com/11022005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@160015 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/proxy/dispatch_reply_message.h84
-rw-r--r--ppapi/proxy/file_chooser_resource.cc22
-rw-r--r--ppapi/proxy/file_chooser_resource.h4
-rw-r--r--ppapi/proxy/flash_device_id_resource.cc15
-rw-r--r--ppapi/proxy/flash_device_id_resource.h4
-rw-r--r--ppapi/proxy/gamepad_resource.cc13
-rw-r--r--ppapi/proxy/gamepad_resource.h4
-rw-r--r--ppapi/proxy/plugin_resource.cc37
-rw-r--r--ppapi/proxy/plugin_resource.h76
-rw-r--r--ppapi/proxy/plugin_resource_callback.h52
-rw-r--r--ppapi/proxy/printing_resource.cc36
-rw-r--r--ppapi/proxy/printing_resource.h12
12 files changed, 239 insertions, 120 deletions
diff --git a/ppapi/proxy/dispatch_reply_message.h b/ppapi/proxy/dispatch_reply_message.h
index 609240f..3c12b1d 100644
--- a/ppapi/proxy/dispatch_reply_message.h
+++ b/ppapi/proxy/dispatch_reply_message.h
@@ -16,7 +16,6 @@
namespace ppapi {
namespace proxy {
-struct Context;
class ResourceMessageReplyParams;
template <class ObjT, class Method>
@@ -61,25 +60,72 @@ inline void DispatchResourceReply(ObjT* obj, Method method,
return (obj->*method)(params, arg.a, arg.b, arg.c, arg.d, arg.e);
}
-#define PPAPI_DISPATCH_RESOURCE_REPLY(msg_class, member_func) \
- case msg_class::ID: { \
- TRACK_RUN_IN_IPC_HANDLER(member_func); \
- msg_class::Schema::Param p; \
- if (msg_class::Read(&ipc_message__, &p)) { \
- ppapi::proxy::DispatchResourceReply( \
- this, \
- &_IpcMessageHandlerClass::member_func, \
- params, p); \
- } \
- break; \
- }
+// Used to dispatch resource replies. In most cases, you should not call this
+// function to dispatch a resource reply manually, but instead use
+// |PluginResource::CallBrowser|/|PluginResource::CallRenderer| with a
+// |base::Callback| which will be called when a reply message is received
+// (see plugin_resource.h).
+//
+// This function will call your callback with the nested reply message's
+// parameters on success. On failure, your callback will be called with each
+// parameter having its default constructed value.
+//
+// Resource replies are a bit weird in that the host will automatically
+// generate a reply in error cases (when the call handler returns error rather
+// than returning "completion pending"). This makes it more convenient to write
+// the call message handlers. But this also means that the reply handler has to
+// handle both the success case (when all of the reply message paramaters are
+// specified) and the error case (when the nested reply message is empty).
+// In both cases the resource will want to issue completion callbacks to the
+// plugin.
+//
+// This function handles the error case by calling your reply handler with the
+// default value for each paramater in the error case. In most situations this
+// will be the right thing. You should always dispatch completion callbacks
+// using the result code present in the ResourceMessageReplyParams.
+template<class MsgClass, class ObjT, class Method>
+void DispatchResourceReplyOrDefaultParams(
+ ObjT* obj,
+ Method method,
+ const ResourceMessageReplyParams& reply_params,
+ const IPC::Message& msg) {
+ typename MsgClass::Schema::Param msg_params;
+ // We either expect the nested message type to match, or that there is no
+ // nested message. No nested message indicates a default reply sent from
+ // the host: when the resource message handler returns an error, a reply
+ // is implicitly sent with no nested message.
+ DCHECK(msg.type() == MsgClass::ID || msg.type() == 0)
+ << "Resource reply message of unexpected type.";
+ if (msg.type() == MsgClass::ID && MsgClass::Read(&msg, &msg_params)) {
+ // Message type matches and the parameters were successfully read.
+ DispatchResourceReply(obj, method, reply_params, msg_params);
+ } else {
+ // The nested message is empty because the host handler didn't explicitly
+ // send a reply (likely), or you screwed up and didn't use the correct
+ // message type when calling this function (you should have hit the
+ // assertion above, Einstein).
+ //
+ // Dispatch the reply function with the default parameters. We explicitly
+ // use a new Params() structure since if the Read failed due to an invalid
+ // message, the params could have been partially filled in.
+ DispatchResourceReply(obj, method, reply_params,
+ typename MsgClass::Schema::Param());
+ }
+}
-#define PPAPI_DISPATCH_RESOURCE_REPLY_0(msg_class, member_func) \
- case msg_class::ID: { \
- TRACK_RUN_IN_IPC_HANDLER(member_func); \
- member_func(params); \
- break; \
- }
+// Template specialization for |Callback|s that only accept a
+// |ResourceMessageReplyParams|. In this case |msg| shouldn't contain any
+// arguments, so just call the |method| with the |reply_params|.
+template<class MsgClass, class Method>
+void DispatchResourceReplyOrDefaultParams(
+ base::Callback<void(const ResourceMessageReplyParams&)>* obj,
+ Method method,
+ const ResourceMessageReplyParams& reply_params,
+ const IPC::Message& msg) {
+ DCHECK(msg.type() == MsgClass::ID || msg.type() == 0)
+ << "Resource reply message of unexpected type.";
+ return (obj->*method)(reply_params);
+}
} // namespace proxy
} // namespace ppapi
diff --git a/ppapi/proxy/file_chooser_resource.cc b/ppapi/proxy/file_chooser_resource.cc
index 87d1128..f41ade5 100644
--- a/ppapi/proxy/file_chooser_resource.cc
+++ b/ppapi/proxy/file_chooser_resource.cc
@@ -4,6 +4,7 @@
#include "ppapi/proxy/file_chooser_resource.h"
+#include "base/bind.h"
#include "base/string_split.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/pp_errors.h"
@@ -97,15 +98,6 @@ void FileChooserResource::PopulateAcceptTypes(
}
}
-void FileChooserResource::OnReplyReceived(
- const ResourceMessageReplyParams& params,
- const IPC::Message& msg) {
- IPC_BEGIN_MESSAGE_MAP(FileChooserResource, msg)
- PPAPI_DISPATCH_RESOURCE_REPLY(PpapiPluginMsg_FileChooser_ShowReply,
- OnPluginMsgShowReply)
- IPC_END_MESSAGE_MAP()
-}
-
void FileChooserResource::OnPluginMsgShowReply(
const ResourceMessageReplyParams& params,
const std::vector<PPB_FileRef_CreateInfo>& chosen_files) {
@@ -143,11 +135,13 @@ int32_t FileChooserResource::ShowInternal(
callback_ = callback;
StringVar* sugg_str = StringVar::FromPPVar(suggested_file_name);
- CallRenderer(PpapiHostMsg_FileChooser_Show(
- PP_ToBool(save_as),
- mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE,
- sugg_str ? sugg_str->value() : std::string(),
- accept_types_));
+ PpapiHostMsg_FileChooser_Show msg(
+ PP_ToBool(save_as),
+ mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE,
+ sugg_str ? sugg_str->value() : std::string(),
+ accept_types_);
+ CallRenderer<PpapiPluginMsg_FileChooser_ShowReply>(msg,
+ base::Bind(&FileChooserResource::OnPluginMsgShowReply, this));
return PP_OK_COMPLETIONPENDING;
}
diff --git a/ppapi/proxy/file_chooser_resource.h b/ppapi/proxy/file_chooser_resource.h
index ecf4e87..58331db 100644
--- a/ppapi/proxy/file_chooser_resource.h
+++ b/ppapi/proxy/file_chooser_resource.h
@@ -54,10 +54,6 @@ class PPAPI_PROXY_EXPORT FileChooserResource
std::vector<std::string>* output);
private:
- // PluginResource override.
- virtual void OnReplyReceived(const ResourceMessageReplyParams& params,
- const IPC::Message& msg) OVERRIDE;
-
void OnPluginMsgShowReply(
const ResourceMessageReplyParams& params,
const std::vector<PPB_FileRef_CreateInfo>& chosen_files);
diff --git a/ppapi/proxy/flash_device_id_resource.cc b/ppapi/proxy/flash_device_id_resource.cc
index 39ff63b..1698b49 100644
--- a/ppapi/proxy/flash_device_id_resource.cc
+++ b/ppapi/proxy/flash_device_id_resource.cc
@@ -4,6 +4,7 @@
#include "ppapi/proxy/flash_device_id_resource.h"
+#include "base/bind.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/proxy/dispatch_reply_message.h"
#include "ppapi/proxy/ppapi_messages.h"
@@ -38,20 +39,12 @@ int32_t FlashDeviceIDResource::GetDeviceID(
dest_ = id;
callback_ = callback;
- CallBrowser(PpapiHostMsg_FlashDeviceID_GetDeviceID());
+ CallBrowser<PpapiPluginMsg_FlashDeviceID_GetDeviceIDReply>(
+ PpapiHostMsg_FlashDeviceID_GetDeviceID(),
+ base::Bind(&FlashDeviceIDResource::OnPluginMsgGetDeviceIDReply, this));
return PP_OK_COMPLETIONPENDING;
}
-void FlashDeviceIDResource::OnReplyReceived(
- const ResourceMessageReplyParams& params,
- const IPC::Message& msg) {
- IPC_BEGIN_MESSAGE_MAP(FlashDeviceIDResource, msg)
- PPAPI_DISPATCH_RESOURCE_REPLY(
- PpapiPluginMsg_FlashDeviceID_GetDeviceIDReply,
- OnPluginMsgGetDeviceIDReply)
- IPC_END_MESSAGE_MAP()
-}
-
void FlashDeviceIDResource::OnPluginMsgGetDeviceIDReply(
const ResourceMessageReplyParams& params,
const std::string& id) {
diff --git a/ppapi/proxy/flash_device_id_resource.h b/ppapi/proxy/flash_device_id_resource.h
index b563c80..19c9e63 100644
--- a/ppapi/proxy/flash_device_id_resource.h
+++ b/ppapi/proxy/flash_device_id_resource.h
@@ -29,10 +29,6 @@ class FlashDeviceIDResource
scoped_refptr<TrackedCallback> callback) OVERRIDE;
private:
- // PluginResource override;
- virtual void OnReplyReceived(const ResourceMessageReplyParams& params,
- const IPC::Message& msg);
-
// IPC message handler.
void OnPluginMsgGetDeviceIDReply(const ResourceMessageReplyParams& params,
const std::string& id);
diff --git a/ppapi/proxy/gamepad_resource.cc b/ppapi/proxy/gamepad_resource.cc
index 446c11c..fa028e4 100644
--- a/ppapi/proxy/gamepad_resource.cc
+++ b/ppapi/proxy/gamepad_resource.cc
@@ -6,6 +6,7 @@
#include <string.h>
+#include "base/bind.h"
#include "base/threading/platform_thread.h"
#include "ppapi/proxy/dispatch_reply_message.h"
#include "ppapi/proxy/ppapi_messages.h"
@@ -48,7 +49,9 @@ GamepadResource::GamepadResource(Connection connection, PP_Instance instance)
memset(&last_read_, 0, sizeof(last_read_));
SendCreateToBrowser(PpapiHostMsg_Gamepad_Create());
- CallBrowser(PpapiHostMsg_Gamepad_RequestMemory());
+ CallBrowser<PpapiPluginMsg_Gamepad_SendMemory>(
+ PpapiHostMsg_Gamepad_RequestMemory(),
+ base::Bind(&GamepadResource::OnPluginMsgSendMemory, this));
}
GamepadResource::~GamepadResource() {
@@ -91,14 +94,6 @@ void GamepadResource::Sample(PP_GamepadsSampleData* data) {
memcpy(data, &last_read_, sizeof(PP_GamepadsSampleData));
}
-void GamepadResource::OnReplyReceived(const ResourceMessageReplyParams& params,
- const IPC::Message& msg) {
- IPC_BEGIN_MESSAGE_MAP(GamepadResource, msg)
- PPAPI_DISPATCH_RESOURCE_REPLY_0(PpapiPluginMsg_Gamepad_SendMemory,
- OnPluginMsgSendMemory)
- IPC_END_MESSAGE_MAP()
-}
-
void GamepadResource::OnPluginMsgSendMemory(
const ResourceMessageReplyParams& params) {
// On failure, the handle will be null and the CHECK below will be tripped.
diff --git a/ppapi/proxy/gamepad_resource.h b/ppapi/proxy/gamepad_resource.h
index f2398ff..1eaa547f 100644
--- a/ppapi/proxy/gamepad_resource.h
+++ b/ppapi/proxy/gamepad_resource.h
@@ -39,10 +39,6 @@ class PPAPI_PROXY_EXPORT GamepadResource
virtual void Sample(PP_GamepadsSampleData* data) OVERRIDE;
private:
- // PluginResource override.
- virtual void OnReplyReceived(const ResourceMessageReplyParams& params,
- const IPC::Message& msg) OVERRIDE;
-
void OnPluginMsgSendMemory(const ResourceMessageReplyParams& params);
scoped_ptr<base::SharedMemory> shared_memory_;
diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc
index f86bc3d..1cfc3f1 100644
--- a/ppapi/proxy/plugin_resource.cc
+++ b/ppapi/proxy/plugin_resource.cc
@@ -30,6 +30,20 @@ PluginResource::~PluginResource() {
}
}
+void PluginResource::OnReplyReceived(
+ const proxy::ResourceMessageReplyParams& params,
+ const IPC::Message& msg) {
+ // Grab the callback for the reply sequence number and run it with |msg|.
+ CallbackMap::iterator it = callbacks_.find(params.sequence());
+ if (it == callbacks_.end()) {
+ DCHECK(false) << "Callback does not exist for an expected sequence number.";
+ } else {
+ scoped_refptr<PluginResourceCallbackBase> callback = it->second;
+ callbacks_.erase(it);
+ callback->Run(params, msg);
+ }
+}
+
void PluginResource::SendCreateToBrowser(const IPC::Message& msg) {
DCHECK(!sent_create_to_browser_);
sent_create_to_browser_ = true;
@@ -51,29 +65,20 @@ void PluginResource::SendCreateToRenderer(const IPC::Message& msg) {
void PluginResource::PostToBrowser(const IPC::Message& msg) {
ResourceMessageCallParams params(pp_resource(),
next_sequence_number_++);
- connection_.browser_sender->Send(new PpapiHostMsg_ResourceCall(params, msg));
+ SendResourceCall(connection_.browser_sender, params, msg);
}
void PluginResource::PostToRenderer(const IPC::Message& msg) {
ResourceMessageCallParams params(pp_resource(),
next_sequence_number_++);
- connection_.renderer_sender->Send(new PpapiHostMsg_ResourceCall(params, msg));
+ SendResourceCall(connection_.renderer_sender, params, msg);
}
-int32_t PluginResource::CallBrowser(const IPC::Message& msg) {
- ResourceMessageCallParams params(pp_resource(),
- next_sequence_number_++);
- params.set_has_callback();
- connection_.browser_sender->Send(new PpapiHostMsg_ResourceCall(params, msg));
- return params.sequence();
-}
-
-int32_t PluginResource::CallRenderer(const IPC::Message& msg) {
- ResourceMessageCallParams params(pp_resource(),
- next_sequence_number_++);
- params.set_has_callback();
- connection_.renderer_sender->Send(new PpapiHostMsg_ResourceCall(params, msg));
- return params.sequence();
+bool PluginResource::SendResourceCall(
+ IPC::Sender* sender,
+ const ResourceMessageCallParams& call_params,
+ const IPC::Message& nested_msg) {
+ return sender->Send(new PpapiHostMsg_ResourceCall(call_params, nested_msg));
}
int32_t PluginResource::CallBrowserSync(const IPC::Message& msg,
diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h
index 3bde7cb..00c29a1 100644
--- a/ppapi/proxy/plugin_resource.h
+++ b/ppapi/proxy/plugin_resource.h
@@ -5,9 +5,12 @@
#ifndef PPAPI_PROXY_PLUGIN_RESOURCE_H_
#define PPAPI_PROXY_PLUGIN_RESOURCE_H_
+#include <map>
+
#include "base/compiler_specific.h"
#include "ipc/ipc_sender.h"
#include "ppapi/proxy/connection.h"
+#include "ppapi/proxy/plugin_resource_callback.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/shared_impl/resource.h"
@@ -31,6 +34,11 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource {
bool sent_create_to_browser() const { return sent_create_to_browser_; }
bool sent_create_to_renderer() const { return sent_create_to_renderer_; }
+ // This handles a reply to a resource call. It works by looking up the
+ // callback that was registered when CallBrowser/CallRenderer was called
+ // and calling it with |params| and |msg|.
+ virtual void OnReplyReceived(const proxy::ResourceMessageReplyParams& params,
+ const IPC::Message& msg) OVERRIDE;
protected:
// Sends a create message to the browser or renderer for the current resource.
void SendCreateToBrowser(const IPC::Message& msg);
@@ -41,15 +49,27 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource {
void PostToBrowser(const IPC::Message& msg);
void PostToRenderer(const IPC::Message& msg);
- // Like PostToBrowser/Renderer but expects a response.
+ // Like PostToBrowser/Renderer but expects a response. |callback| is
+ // a |base::Callback| that will be run when a reply message with a sequence
+ // number matching that of the call is received. |ReplyMsgClass| is the type
+ // of the reply message that is expected. An example of usage:
+ //
+ // CallBrowser<PpapiPluginMsg_MyResourceType_MyReplyMessage>(
+ // PpapiHostMsg_MyResourceType_MyRequestMessage(),
+ // base::Bind(&MyPluginResource::ReplyHandler, this));
+ //
+ // If a reply message to this call is received whose type does not match
+ // |ReplyMsgClass| (for example, in the case of an error), the callback will
+ // still be invoked but with the default values of the message parameters.
//
// Returns the new request's sequence number which can be used to identify
- // the callback. The host will reply and ppapi::Resource::OnReplyReceived
- // will be called.
+ // the callback.
//
// Note that all integers (including 0 and -1) are valid request IDs.
- int32_t CallBrowser(const IPC::Message& msg);
- int32_t CallRenderer(const IPC::Message& msg);
+ template<typename ReplyMsgClass, typename CallbackType>
+ int32_t CallBrowser(const IPC::Message& msg, const CallbackType& callback);
+ template<typename ReplyMsgClass, typename CallbackType>
+ int32_t CallRenderer(const IPC::Message& msg, const CallbackType& callback);
// Call the browser/renderer with sync messages. The pepper error code from
// the call is returned and the reply message is stored in |reply_msg|.
@@ -57,6 +77,18 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource {
int32_t CallRendererSync(const IPC::Message& msg, IPC::Message* reply_msg);
private:
+ // Helper function to send a |PpapiHostMsg_ResourceCall| to the given sender
+ // with |nested_msg| and |call_params|.
+ bool SendResourceCall(IPC::Sender* sender,
+ const ResourceMessageCallParams& call_params,
+ const IPC::Message& nested_msg);
+
+ // Helper function to make a Resource Call to a host with a callback.
+ template<typename ReplyMsgClass, typename CallbackType>
+ int32_t CallHost(IPC::Sender* sender,
+ const IPC::Message& msg,
+ const CallbackType& callback);
+
Connection connection_;
int32_t next_sequence_number_;
@@ -64,9 +96,43 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource {
bool sent_create_to_browser_;
bool sent_create_to_renderer_;
+ typedef std::map<int32_t, scoped_refptr<PluginResourceCallbackBase> >
+ CallbackMap;
+ CallbackMap callbacks_;
+
DISALLOW_COPY_AND_ASSIGN(PluginResource);
};
+template<typename ReplyMsgClass, typename CallbackType>
+int32_t PluginResource::CallBrowser(const IPC::Message& msg,
+ const CallbackType& callback) {
+ return CallHost<ReplyMsgClass, CallbackType>(
+ connection_.browser_sender, msg, callback);
+}
+
+template<typename ReplyMsgClass, typename CallbackType>
+int32_t PluginResource::CallRenderer(const IPC::Message& msg,
+ const CallbackType& callback) {
+ return CallHost<ReplyMsgClass, CallbackType>(
+ connection_.renderer_sender, msg, callback);
+}
+
+template<typename ReplyMsgClass, typename CallbackType>
+int32_t PluginResource::CallHost(IPC::Sender* sender,
+ const IPC::Message& msg,
+ const CallbackType& callback) {
+ ResourceMessageCallParams params(pp_resource(),
+ next_sequence_number_++);
+ // Stash the |callback| in |callbacks_| identified by the sequence number of
+ // the call.
+ scoped_refptr<PluginResourceCallbackBase> plugin_callback(
+ new PluginResourceCallback<ReplyMsgClass, CallbackType>(callback));
+ callbacks_.insert(std::make_pair(params.sequence(), plugin_callback));
+ params.set_has_callback();
+ SendResourceCall(sender, params, msg);
+ return params.sequence();
+}
+
} // namespace proxy
} // namespace ppapi
diff --git a/ppapi/proxy/plugin_resource_callback.h b/ppapi/proxy/plugin_resource_callback.h
new file mode 100644
index 0000000..a306c26
--- /dev/null
+++ b/ppapi/proxy/plugin_resource_callback.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 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_PROXY_PLUGIN_RESOURCE_CALLBACK_H_
+#define PPAPI_PROXY_PLUGIN_RESOURCE_CALLBACK_H_
+
+#include "base/memory/ref_counted.h"
+#include "ipc/ipc_message.h"
+#include "ppapi/proxy/dispatch_reply_message.h"
+#include "ppapi/proxy/resource_message_params.h"
+
+namespace ppapi {
+namespace proxy {
+
+// |PluginResourceCallback| wraps a |base::Callback| on the plugin side which
+// will be triggered in response to a particular message type being received.
+// |MsgClass| is the reply message type that the callback will be called with
+// and |CallbackType| is the type of the |base::Callback| that will be called.
+class PluginResourceCallbackBase
+ : public base::RefCounted<PluginResourceCallbackBase> {
+ public:
+ virtual void Run(const ResourceMessageReplyParams& params,
+ const IPC::Message& msg) = 0;
+ protected:
+ friend class base::RefCounted<PluginResourceCallbackBase>;
+ virtual ~PluginResourceCallbackBase() {}
+};
+
+template<typename MsgClass, typename CallbackType>
+class PluginResourceCallback : public PluginResourceCallbackBase {
+ public:
+ explicit PluginResourceCallback(const CallbackType& callback)
+ : callback_(callback) {}
+
+ virtual void Run(
+ const ResourceMessageReplyParams& reply_params,
+ const IPC::Message& msg) OVERRIDE {
+ DispatchResourceReplyOrDefaultParams<MsgClass>(
+ &callback_, &CallbackType::Run, reply_params, msg);
+ }
+
+ private:
+ virtual ~PluginResourceCallback() {}
+
+ CallbackType callback_;
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_PLUGIN_RESOURCE_CALLBACK_H_
diff --git a/ppapi/proxy/printing_resource.cc b/ppapi/proxy/printing_resource.cc
index 9fd8fde..22950c2 100644
--- a/ppapi/proxy/printing_resource.cc
+++ b/ppapi/proxy/printing_resource.cc
@@ -4,6 +4,7 @@
#include "ppapi/proxy/printing_resource.h"
+#include "base/bind.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/proxy/dispatch_reply_message.h"
@@ -12,10 +13,8 @@
namespace ppapi {
namespace proxy {
-PrintingResource::PrintingResource(Connection connection,
- PP_Instance instance)
- : PluginResource(connection, instance),
- print_settings_(NULL) {
+PrintingResource::PrintingResource(Connection connection, PP_Instance instance)
+ : PluginResource(connection, instance) {
}
PrintingResource::~PrintingResource() {
@@ -31,39 +30,26 @@ int32_t PrintingResource::GetDefaultPrintSettings(
if (!print_settings)
return PP_ERROR_BADARGUMENT;
- if (TrackedCallback::IsPending(callback_))
- return PP_ERROR_INPROGRESS;
-
if (!sent_create_to_browser())
SendCreateToBrowser(PpapiHostMsg_Printing_Create());
- DCHECK(!print_settings_);
- print_settings_ = print_settings;
- callback_ = callback;
-
- CallBrowser(PpapiHostMsg_Printing_GetDefaultPrintSettings());
+ CallBrowser<PpapiPluginMsg_Printing_GetDefaultPrintSettingsReply>(
+ PpapiHostMsg_Printing_GetDefaultPrintSettings(),
+ base::Bind(&PrintingResource::OnPluginMsgGetDefaultPrintSettingsReply,
+ this, print_settings, callback));
return PP_OK_COMPLETIONPENDING;
}
-void PrintingResource::OnReplyReceived(
- const ResourceMessageReplyParams& params,
- const IPC::Message& msg) {
- IPC_BEGIN_MESSAGE_MAP(PrintingResource, msg)
- PPAPI_DISPATCH_RESOURCE_REPLY(
- PpapiPluginMsg_Printing_GetDefaultPrintSettingsReply,
- OnPluginMsgGetDefaultPrintSettingsReply)
- IPC_END_MESSAGE_MAP()
-}
-
void PrintingResource::OnPluginMsgGetDefaultPrintSettingsReply(
+ PP_PrintSettings_Dev* settings_out,
+ scoped_refptr<TrackedCallback> callback,
const ResourceMessageReplyParams& params,
const PP_PrintSettings_Dev& settings) {
if (params.result() == PP_OK)
- *print_settings_ = settings;
- print_settings_ = NULL;
+ *settings_out = settings;
// Notify the plugin of the new data.
- TrackedCallback::ClearAndRun(&callback_, params.result());
+ TrackedCallback::ClearAndRun(&callback, params.result());
// DANGER: May delete |this|!
}
diff --git a/ppapi/proxy/printing_resource.h b/ppapi/proxy/printing_resource.h
index d99b459..1f9216b 100644
--- a/ppapi/proxy/printing_resource.h
+++ b/ppapi/proxy/printing_resource.h
@@ -31,17 +31,11 @@ class PPAPI_PROXY_EXPORT PrintingResource
scoped_refptr<TrackedCallback> callback) OVERRIDE;
private:
- // PluginResource override.
- virtual void OnReplyReceived(const ResourceMessageReplyParams& params,
- const IPC::Message& msg) OVERRIDE;
-
void OnPluginMsgGetDefaultPrintSettingsReply(
+ PP_PrintSettings_Dev* settings_out,
+ scoped_refptr<TrackedCallback> callback,
const ResourceMessageReplyParams& params,
- const PP_PrintSettings_Dev& print_settings);
-
- PP_PrintSettings_Dev* print_settings_;
-
- scoped_refptr<TrackedCallback> callback_;
+ const PP_PrintSettings_Dev& settings);
DISALLOW_COPY_AND_ASSIGN(PrintingResource);
};