Implement plugin side of sync EnumerateVideoCaptureDevices

This implements the plugin side of PPB_Flash::EnumerateVideoCaptureDevices which is a synchronous version of PPB_VideoCapture::EnumerateVideoDevices. The result is output into a PP_ArrayOutput. This also adds a unittest which does some basic testing of the messages sent, but mainly demonstrates how to write PluginResource unittests when dealing with sync messages (and adds some infrastructure to make it easy to do this).

Once VideoCapture is implemented as a new-style resource, the code for this will simplify a lot.

Review URL: https://chromiumcodereview.appspot.com/11039012

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161265 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/ppapi/proxy/resource_message_test_sink.cc b/ppapi/proxy/resource_message_test_sink.cc
index 7daf435..a2920e3f 100644
--- a/ppapi/proxy/resource_message_test_sink.cc
+++ b/ppapi/proxy/resource_message_test_sink.cc
@@ -42,6 +42,30 @@
 ResourceMessageTestSink::~ResourceMessageTestSink() {
 }
 
+bool ResourceMessageTestSink::Send(IPC::Message* msg) {
+  int message_id = 0;
+  scoped_ptr<IPC::MessageReplyDeserializer> reply_deserializer;
+  if (msg->is_sync()) {
+    reply_deserializer.reset(
+        static_cast<IPC::SyncMessage*>(msg)->GetReplyDeserializer());
+    message_id = IPC::SyncMessage::GetMessageId(*msg);
+  }
+  bool result = IPC::TestSink::Send(msg);  // Deletes |msg|.
+  if (sync_reply_msg_.get()) {
+    // |sync_reply_msg_| should always be a reply to the pending sync message.
+    DCHECK(IPC::SyncMessage::IsMessageReplyTo(*sync_reply_msg_.get(),
+                                              message_id));
+    reply_deserializer->SerializeOutputParameters(*sync_reply_msg_.get());
+    sync_reply_msg_.reset(NULL);
+  }
+  return result;
+}
+
+void ResourceMessageTestSink::SetSyncReplyMessage(IPC::Message* reply_msg) {
+  DCHECK(!sync_reply_msg_.get());
+  sync_reply_msg_.reset(reply_msg);
+}
+
 bool ResourceMessageTestSink::GetFirstResourceCallMatching(
     uint32 id,
     ResourceMessageCallParams* params,
@@ -60,5 +84,43 @@
       *this, id, params, nested_msg);
 }
 
+ResourceSyncCallHandler::ResourceSyncCallHandler(
+    ResourceMessageTestSink* test_sink,
+    uint32 incoming_type,
+    int32_t result,
+    const IPC::Message& reply_msg)
+    : test_sink_(test_sink),
+      incoming_type_(incoming_type),
+      result_(result),
+      reply_msg_(reply_msg) {
+}
+
+ResourceSyncCallHandler::~ResourceSyncCallHandler() {
+}
+
+bool ResourceSyncCallHandler::OnMessageReceived(const IPC::Message& msg) {
+  if (msg.type() != PpapiHostMsg_ResourceSyncCall::ID)
+    return false;
+  PpapiHostMsg_ResourceSyncCall::Schema::SendParam send_params;
+  bool success = PpapiHostMsg_ResourceSyncCall::ReadSendParam(
+      &msg, &send_params);
+  DCHECK(success);
+  ResourceMessageCallParams call_params = send_params.a;
+  IPC::Message call_msg = send_params.b;
+  if (call_msg.type() != incoming_type_)
+    return false;
+  IPC::Message* wrapper_reply_msg = IPC::SyncMessage::GenerateReply(&msg);
+  ResourceMessageReplyParams reply_params(call_params.pp_resource(),
+                                          call_params.sequence());
+  reply_params.set_result(result_);
+  PpapiHostMsg_ResourceSyncCall::WriteReplyParams(
+      wrapper_reply_msg, reply_params, reply_msg_);
+  test_sink_->SetSyncReplyMessage(wrapper_reply_msg);
+
+  // Stash a copy of the message for inspection later.
+  last_handled_msg_ = call_msg;
+  return true;
+}
+
 }  // namespace proxy
 }  // namespace ppapi