Home | History | Annotate | Download | only in lib
      1 // Copyright 2015 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 "mojo/public/cpp/bindings/pipe_control_message_handler.h"
      6 
      7 #include "base/logging.h"
      8 #include "mojo/public/cpp/bindings/interface_id.h"
      9 #include "mojo/public/cpp/bindings/lib/message_builder.h"
     10 #include "mojo/public/cpp/bindings/lib/serialization.h"
     11 #include "mojo/public/cpp/bindings/lib/serialization_context.h"
     12 #include "mojo/public/cpp/bindings/lib/validation_context.h"
     13 #include "mojo/public/cpp/bindings/lib/validation_util.h"
     14 #include "mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h"
     15 #include "mojo/public/interfaces/bindings/pipe_control_messages.mojom.h"
     16 
     17 namespace mojo {
     18 
     19 PipeControlMessageHandler::PipeControlMessageHandler(
     20     PipeControlMessageHandlerDelegate* delegate)
     21     : delegate_(delegate) {}
     22 
     23 PipeControlMessageHandler::~PipeControlMessageHandler() {}
     24 
     25 void PipeControlMessageHandler::SetDescription(const std::string& description) {
     26   description_ = description;
     27 }
     28 
     29 // static
     30 bool PipeControlMessageHandler::IsPipeControlMessage(const Message* message) {
     31   return !IsValidInterfaceId(message->interface_id());
     32 }
     33 
     34 bool PipeControlMessageHandler::Accept(Message* message) {
     35   if (!Validate(message))
     36     return false;
     37 
     38   if (message->name() == pipe_control::kRunOrClosePipeMessageId)
     39     return RunOrClosePipe(message);
     40 
     41   NOTREACHED();
     42   return false;
     43 }
     44 
     45 bool PipeControlMessageHandler::Validate(Message* message) {
     46   internal::ValidationContext validation_context(message->payload(),
     47                                                  message->payload_num_bytes(),
     48                                                  0, 0, message, description_);
     49 
     50   if (message->name() == pipe_control::kRunOrClosePipeMessageId) {
     51     if (!internal::ValidateMessageIsRequestWithoutResponse(
     52             message, &validation_context)) {
     53       return false;
     54     }
     55     return internal::ValidateMessagePayload<
     56         pipe_control::internal::RunOrClosePipeMessageParams_Data>(
     57             message, &validation_context);
     58   }
     59 
     60   return false;
     61 }
     62 
     63 bool PipeControlMessageHandler::RunOrClosePipe(Message* message) {
     64   internal::SerializationContext context;
     65   pipe_control::internal::RunOrClosePipeMessageParams_Data* params =
     66       reinterpret_cast<
     67           pipe_control::internal::RunOrClosePipeMessageParams_Data*>(
     68           message->mutable_payload());
     69   pipe_control::RunOrClosePipeMessageParamsPtr params_ptr;
     70   internal::Deserialize<pipe_control::RunOrClosePipeMessageParamsDataView>(
     71       params, &params_ptr, &context);
     72 
     73   if (params_ptr->input->is_peer_associated_endpoint_closed_event()) {
     74     const auto& event =
     75         params_ptr->input->get_peer_associated_endpoint_closed_event();
     76 
     77     base::Optional<DisconnectReason> reason;
     78     if (event->disconnect_reason) {
     79       reason.emplace(event->disconnect_reason->custom_reason,
     80                      event->disconnect_reason->description);
     81     }
     82     return delegate_->OnPeerAssociatedEndpointClosed(event->id, reason);
     83   }
     84 
     85   DVLOG(1) << "Unsupported command in a RunOrClosePipe message pipe control "
     86            << "message. Closing the pipe.";
     87   return false;
     88 }
     89 
     90 }  // namespace mojo
     91