1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ppapi/proxy/resource_message_test_sink.h" 6 7 #include "ppapi/proxy/ppapi_messages.h" 8 #include "ppapi/proxy/resource_message_params.h" 9 #include "ppapi/proxy/serialized_handle.h" 10 11 namespace ppapi { 12 namespace proxy { 13 14 namespace { 15 16 // Backend for GetFirstResource[Call|Reply]Matching. 17 template<class WrapperMessage, class Params> 18 bool GetFirstResourceMessageMatching(const ResourceMessageTestSink& sink, 19 uint32 id, 20 Params* params, 21 IPC::Message* nested_msg) { 22 for (size_t i = 0; i < sink.message_count(); i++) { 23 const IPC::Message* msg = sink.GetMessageAt(i); 24 if (msg->type() == WrapperMessage::ID) { 25 Params cur_params; 26 IPC::Message cur_msg; 27 WrapperMessage::Read(msg, &cur_params, &cur_msg); 28 if (cur_msg.type() == id) { 29 *params = cur_params; 30 *nested_msg = cur_msg; 31 return true; 32 } 33 } 34 } 35 return false; 36 } 37 38 } // namespace 39 40 ResourceMessageTestSink::ResourceMessageTestSink() { 41 } 42 43 ResourceMessageTestSink::~ResourceMessageTestSink() { 44 } 45 46 bool ResourceMessageTestSink::Send(IPC::Message* msg) { 47 int message_id = 0; 48 scoped_ptr<IPC::MessageReplyDeserializer> reply_deserializer; 49 if (msg->is_sync()) { 50 reply_deserializer.reset( 51 static_cast<IPC::SyncMessage*>(msg)->GetReplyDeserializer()); 52 message_id = IPC::SyncMessage::GetMessageId(*msg); 53 } 54 bool result = IPC::TestSink::Send(msg); // Deletes |msg|. 55 if (sync_reply_msg_.get()) { 56 // |sync_reply_msg_| should always be a reply to the pending sync message. 57 DCHECK(IPC::SyncMessage::IsMessageReplyTo(*sync_reply_msg_.get(), 58 message_id)); 59 reply_deserializer->SerializeOutputParameters(*sync_reply_msg_.get()); 60 sync_reply_msg_.reset(NULL); 61 } 62 return result; 63 } 64 65 void ResourceMessageTestSink::SetSyncReplyMessage(IPC::Message* reply_msg) { 66 DCHECK(!sync_reply_msg_.get()); 67 sync_reply_msg_.reset(reply_msg); 68 } 69 70 bool ResourceMessageTestSink::GetFirstResourceCallMatching( 71 uint32 id, 72 ResourceMessageCallParams* params, 73 IPC::Message* nested_msg) const { 74 return GetFirstResourceMessageMatching<PpapiHostMsg_ResourceCall, 75 ResourceMessageCallParams>( 76 *this, id, params, nested_msg); 77 } 78 79 bool ResourceMessageTestSink::GetFirstResourceReplyMatching( 80 uint32 id, 81 ResourceMessageReplyParams* params, 82 IPC::Message* nested_msg) { 83 return GetFirstResourceMessageMatching<PpapiPluginMsg_ResourceReply, 84 ResourceMessageReplyParams>( 85 *this, id, params, nested_msg); 86 } 87 88 ResourceSyncCallHandler::ResourceSyncCallHandler( 89 ResourceMessageTestSink* test_sink, 90 uint32 incoming_type, 91 int32_t result, 92 const IPC::Message& reply_msg) 93 : test_sink_(test_sink), 94 incoming_type_(incoming_type), 95 result_(result), 96 serialized_handle_(NULL), 97 reply_msg_(reply_msg) { 98 } 99 100 ResourceSyncCallHandler::~ResourceSyncCallHandler() { 101 } 102 103 bool ResourceSyncCallHandler::OnMessageReceived(const IPC::Message& msg) { 104 if (msg.type() != PpapiHostMsg_ResourceSyncCall::ID) 105 return false; 106 PpapiHostMsg_ResourceSyncCall::Schema::SendParam send_params; 107 bool success = PpapiHostMsg_ResourceSyncCall::ReadSendParam( 108 &msg, &send_params); 109 DCHECK(success); 110 ResourceMessageCallParams call_params = send_params.a; 111 IPC::Message call_msg = send_params.b; 112 if (call_msg.type() != incoming_type_) 113 return false; 114 IPC::Message* wrapper_reply_msg = IPC::SyncMessage::GenerateReply(&msg); 115 ResourceMessageReplyParams reply_params(call_params.pp_resource(), 116 call_params.sequence()); 117 reply_params.set_result(result_); 118 if (serialized_handle_) 119 reply_params.AppendHandle(*serialized_handle_); 120 PpapiHostMsg_ResourceSyncCall::WriteReplyParams( 121 wrapper_reply_msg, reply_params, reply_msg_); 122 test_sink_->SetSyncReplyMessage(wrapper_reply_msg); 123 124 // Stash a copy of the message for inspection later. 125 last_handled_msg_ = call_msg; 126 return true; 127 } 128 129 } // namespace proxy 130 } // namespace ppapi 131