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
PipeControlMessageHandler(PipeControlMessageHandlerDelegate * delegate)18 PipeControlMessageHandler::PipeControlMessageHandler(
19 PipeControlMessageHandlerDelegate* delegate)
20 : delegate_(delegate) {}
21
~PipeControlMessageHandler()22 PipeControlMessageHandler::~PipeControlMessageHandler() {}
23
SetDescription(const std::string & description)24 void PipeControlMessageHandler::SetDescription(const std::string& description) {
25 description_ = description;
26 }
27
28 // static
IsPipeControlMessage(const Message * message)29 bool PipeControlMessageHandler::IsPipeControlMessage(const Message* message) {
30 return !IsValidInterfaceId(message->interface_id());
31 }
32
Accept(Message * message)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
Validate(Message * message)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
RunOrClosePipe(Message * message)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