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