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