• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/lib/control_message_handler.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <utility>
10 
11 #include "base/logging.h"
12 #include "mojo/public/cpp/bindings/lib/message_builder.h"
13 #include "mojo/public/cpp/bindings/lib/serialization.h"
14 #include "mojo/public/cpp/bindings/lib/validation_util.h"
15 #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
16 
17 namespace mojo {
18 namespace internal {
19 namespace {
20 
ValidateControlRequestWithResponse(Message * message)21 bool ValidateControlRequestWithResponse(Message* message) {
22   ValidationContext validation_context(message->payload(),
23                                        message->payload_num_bytes(), 0, 0,
24                                        message, "ControlRequestValidator");
25   if (!ValidateMessageIsRequestExpectingResponse(message, &validation_context))
26     return false;
27 
28   switch (message->header()->name) {
29     case interface_control::kRunMessageId:
30       return ValidateMessagePayload<
31           interface_control::internal::RunMessageParams_Data>(
32           message, &validation_context);
33   }
34   return false;
35 }
36 
ValidateControlRequestWithoutResponse(Message * message)37 bool ValidateControlRequestWithoutResponse(Message* message) {
38   ValidationContext validation_context(message->payload(),
39                                        message->payload_num_bytes(), 0, 0,
40                                        message, "ControlRequestValidator");
41   if (!ValidateMessageIsRequestWithoutResponse(message, &validation_context))
42     return false;
43 
44   switch (message->header()->name) {
45     case interface_control::kRunOrClosePipeMessageId:
46       return ValidateMessageIsRequestWithoutResponse(message,
47                                                      &validation_context) &&
48              ValidateMessagePayload<
49                  interface_control::internal::RunOrClosePipeMessageParams_Data>(
50                  message, &validation_context);
51   }
52   return false;
53 }
54 
55 }  // namespace
56 
57 // static
IsControlMessage(const Message * message)58 bool ControlMessageHandler::IsControlMessage(const Message* message) {
59   return message->header()->name == interface_control::kRunMessageId ||
60          message->header()->name == interface_control::kRunOrClosePipeMessageId;
61 }
62 
ControlMessageHandler(uint32_t interface_version)63 ControlMessageHandler::ControlMessageHandler(uint32_t interface_version)
64     : interface_version_(interface_version) {
65 }
66 
~ControlMessageHandler()67 ControlMessageHandler::~ControlMessageHandler() {
68 }
69 
Accept(Message * message)70 bool ControlMessageHandler::Accept(Message* message) {
71   if (!ValidateControlRequestWithoutResponse(message))
72     return false;
73 
74   if (message->header()->name == interface_control::kRunOrClosePipeMessageId)
75     return RunOrClosePipe(message);
76 
77   NOTREACHED();
78   return false;
79 }
80 
AcceptWithResponder(Message * message,MessageReceiverWithStatus * responder)81 bool ControlMessageHandler::AcceptWithResponder(
82     Message* message,
83     MessageReceiverWithStatus* responder) {
84   if (!ValidateControlRequestWithResponse(message))
85     return false;
86 
87   if (message->header()->name == interface_control::kRunMessageId)
88     return Run(message, responder);
89 
90   NOTREACHED();
91   return false;
92 }
93 
Run(Message * message,MessageReceiverWithStatus * responder)94 bool ControlMessageHandler::Run(Message* message,
95                                 MessageReceiverWithStatus* responder) {
96   interface_control::internal::RunMessageParams_Data* params =
97       reinterpret_cast<interface_control::internal::RunMessageParams_Data*>(
98           message->mutable_payload());
99   interface_control::RunMessageParamsPtr params_ptr;
100   Deserialize<interface_control::RunMessageParamsDataView>(params, &params_ptr,
101                                                            &context_);
102   auto& input = *params_ptr->input;
103   interface_control::RunOutputPtr output = interface_control::RunOutput::New();
104   if (input.is_query_version()) {
105     output->set_query_version_result(
106         interface_control::QueryVersionResult::New());
107     output->get_query_version_result()->version = interface_version_;
108   } else if (input.is_flush_for_testing()) {
109     output.reset();
110   } else {
111     output.reset();
112   }
113 
114   auto response_params_ptr = interface_control::RunResponseMessageParams::New();
115   response_params_ptr->output = std::move(output);
116   size_t size =
117       PrepareToSerialize<interface_control::RunResponseMessageParamsDataView>(
118           response_params_ptr, &context_);
119   MessageBuilder builder(interface_control::kRunMessageId,
120                          Message::kFlagIsResponse, size, 0);
121   builder.message()->set_request_id(message->request_id());
122 
123   interface_control::internal::RunResponseMessageParams_Data* response_params =
124       nullptr;
125   Serialize<interface_control::RunResponseMessageParamsDataView>(
126       response_params_ptr, builder.buffer(), &response_params, &context_);
127   bool ok = responder->Accept(builder.message());
128   ALLOW_UNUSED_LOCAL(ok);
129   delete responder;
130 
131   return true;
132 }
133 
RunOrClosePipe(Message * message)134 bool ControlMessageHandler::RunOrClosePipe(Message* message) {
135   interface_control::internal::RunOrClosePipeMessageParams_Data* params =
136       reinterpret_cast<
137           interface_control::internal::RunOrClosePipeMessageParams_Data*>(
138           message->mutable_payload());
139   interface_control::RunOrClosePipeMessageParamsPtr params_ptr;
140   Deserialize<interface_control::RunOrClosePipeMessageParamsDataView>(
141       params, &params_ptr, &context_);
142   auto& input = *params_ptr->input;
143   if (input.is_require_version())
144     return interface_version_ >= input.get_require_version()->version;
145 
146   return false;
147 }
148 
149 }  // namespace internal
150 }  // namespace mojo
151