Home | History | Annotate | Download | only in proxy
      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