[go: nahoru, domu]

Add support for passing an arbitrary parameter to an IPC message handler. The motivation is for WebContentsObserver to pass RenderFrameHost* to message handlers easily.

As an example, an observer would look like this:

bool FooWebContentsObserver::OnMessageReceived(
    const IPC::Message& message,
    RenderFrameHost* render_frame_host) {
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(FooWebContentsObserver, message, RenderFrameHost, render_frame_host)
  IPC_MESSAGE_HANDLER(FooHostMsg_Bar, OnBar)
.
.
.

void FooWebContentsObserver::OnBar(RenderFrameHost* render_frame_host, ...

You can of course still have dispatchers without the extra parameter as before.


This is generalizing the existing code that allows an IPC message handler to have a "const IPC::Message& message) first parameter to get access to the IPC.

Sync IPCs don't support this yet. It's a lot more work because for them we conveniently reuse tuple's DispatchToMethod. This isn't urgent yet, since sync IPCs aren't dispatched on the UI thread for the most part because of NPAPI and Windows, so punting on this for now.

BUG=304341
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/283623002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270237 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/ipc/ipc_message_unittest.cc b/ipc/ipc_message_unittest.cc
index 971314a..ceb92df3 100644
--- a/ipc/ipc_message_unittest.cc
+++ b/ipc/ipc_message_unittest.cc
@@ -11,6 +11,19 @@
 #include "ipc/ipc_message_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+// IPC messages for testing ----------------------------------------------------
+
+#define IPC_MESSAGE_IMPL
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START TestMsgStart
+
+IPC_MESSAGE_CONTROL0(TestMsgClassEmpty)
+
+IPC_MESSAGE_CONTROL1(TestMsgClassI, int)
+
+IPC_SYNC_MESSAGE_CONTROL1_1(TestMsgClassIS, int, std::string)
+
 namespace {
 
 TEST(IPCMessageTest, ListValue) {
@@ -70,4 +83,71 @@
   EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output));
 }
 
+class IPCMessageParameterTest : public testing::Test {
+ public:
+  IPCMessageParameterTest() : extra_param_("extra_param"), called_(false) {}
+
+  bool OnMessageReceived(const IPC::Message& message) {
+    bool msg_is_ok = true;
+    bool handled = true;
+    IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(IPCMessageParameterTest, message,
+                                     msg_is_ok, std::string, &extra_param_) 
+      IPC_MESSAGE_HANDLER(TestMsgClassEmpty, OnEmpty)
+      IPC_MESSAGE_HANDLER(TestMsgClassI, OnInt)
+      //IPC_MESSAGE_HANDLER(TestMsgClassIS, OnSync)
+      IPC_MESSAGE_UNHANDLED(handled = false)
+    IPC_END_MESSAGE_MAP()
+
+    return handled;
+  }
+
+  void OnEmpty(std::string* extra_param) {
+    EXPECT_EQ(extra_param, &extra_param_);
+    called_ = true;
+  }
+
+  void OnInt(std::string* extra_param, int foo) {
+    EXPECT_EQ(extra_param, &extra_param_);
+    EXPECT_EQ(foo, 42);
+    called_ = true;
+  }
+
+  /* TODO: handle sync IPCs
+    void OnSync(std::string* extra_param, int foo, std::string* out) {
+    EXPECT_EQ(extra_param, &extra_param_);
+    EXPECT_EQ(foo, 42);
+    called_ = true;
+    *out = std::string("out");
+  }
+
+  bool Send(IPC::Message* reply) {
+    delete reply;
+    return true;
+  }*/
+
+  std::string extra_param_;
+  bool called_;
+};
+
+TEST_F(IPCMessageParameterTest, EmptyDispatcherWithParam) {
+  TestMsgClassEmpty message;
+  EXPECT_TRUE(OnMessageReceived(message));
+  EXPECT_TRUE(called_);
+}
+
+TEST_F(IPCMessageParameterTest, OneIntegerWithParam) {
+  TestMsgClassI message(42);
+  EXPECT_TRUE(OnMessageReceived(message));
+  EXPECT_TRUE(called_);
+}
+
+/* TODO: handle sync IPCs
+TEST_F(IPCMessageParameterTest, Sync) {
+  std::string output;
+  TestMsgClassIS message(42, &output);
+  EXPECT_TRUE(OnMessageReceived(message));
+  EXPECT_TRUE(called_);
+  EXPECT_EQ(output, std::string("out"));
+}*/
+
 }  // namespace