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, ¶ms_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