• 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_proxy.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <utility>
10 
11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
13 #include "base/macros.h"
14 #include "base/run_loop.h"
15 #include "mojo/public/cpp/bindings/lib/message_builder.h"
16 #include "mojo/public/cpp/bindings/lib/serialization.h"
17 #include "mojo/public/cpp/bindings/lib/validation_util.h"
18 #include "mojo/public/cpp/bindings/message.h"
19 #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
20 
21 namespace mojo {
22 namespace internal {
23 
24 namespace {
25 
ValidateControlResponse(Message * message)26 bool ValidateControlResponse(Message* message) {
27   ValidationContext validation_context(message->payload(),
28                                        message->payload_num_bytes(), 0, 0,
29                                        message, "ControlResponseValidator");
30   if (!ValidateMessageIsResponse(message, &validation_context))
31     return false;
32 
33   switch (message->header()->name) {
34     case interface_control::kRunMessageId:
35       return ValidateMessagePayload<
36           interface_control::internal::RunResponseMessageParams_Data>(
37           message, &validation_context);
38   }
39   return false;
40 }
41 
42 using RunCallback =
43     base::Callback<void(interface_control::RunResponseMessageParamsPtr)>;
44 
45 class RunResponseForwardToCallback : public MessageReceiver {
46  public:
RunResponseForwardToCallback(const RunCallback & callback)47   explicit RunResponseForwardToCallback(const RunCallback& callback)
48       : callback_(callback) {}
49   bool Accept(Message* message) override;
50 
51  private:
52   RunCallback callback_;
53   DISALLOW_COPY_AND_ASSIGN(RunResponseForwardToCallback);
54 };
55 
Accept(Message * message)56 bool RunResponseForwardToCallback::Accept(Message* message) {
57   if (!ValidateControlResponse(message))
58     return false;
59 
60   interface_control::internal::RunResponseMessageParams_Data* params =
61       reinterpret_cast<
62           interface_control::internal::RunResponseMessageParams_Data*>(
63           message->mutable_payload());
64   interface_control::RunResponseMessageParamsPtr params_ptr;
65   SerializationContext context;
66   Deserialize<interface_control::RunResponseMessageParamsDataView>(
67       params, &params_ptr, &context);
68 
69   callback_.Run(std::move(params_ptr));
70   return true;
71 }
72 
SendRunMessage(MessageReceiverWithResponder * receiver,interface_control::RunInputPtr input_ptr,const RunCallback & callback)73 void SendRunMessage(MessageReceiverWithResponder* receiver,
74                     interface_control::RunInputPtr input_ptr,
75                     const RunCallback& callback) {
76   SerializationContext context;
77 
78   auto params_ptr = interface_control::RunMessageParams::New();
79   params_ptr->input = std::move(input_ptr);
80   size_t size = PrepareToSerialize<interface_control::RunMessageParamsDataView>(
81       params_ptr, &context);
82   MessageBuilder builder(interface_control::kRunMessageId,
83                          Message::kFlagExpectsResponse, size, 0);
84 
85   interface_control::internal::RunMessageParams_Data* params = nullptr;
86   Serialize<interface_control::RunMessageParamsDataView>(
87       params_ptr, builder.buffer(), &params, &context);
88   MessageReceiver* responder = new RunResponseForwardToCallback(callback);
89   if (!receiver->AcceptWithResponder(builder.message(), responder))
90     delete responder;
91 }
92 
ConstructRunOrClosePipeMessage(interface_control::RunOrClosePipeInputPtr input_ptr)93 Message ConstructRunOrClosePipeMessage(
94     interface_control::RunOrClosePipeInputPtr input_ptr) {
95   SerializationContext context;
96 
97   auto params_ptr = interface_control::RunOrClosePipeMessageParams::New();
98   params_ptr->input = std::move(input_ptr);
99 
100   size_t size = PrepareToSerialize<
101       interface_control::RunOrClosePipeMessageParamsDataView>(params_ptr,
102                                                               &context);
103   MessageBuilder builder(interface_control::kRunOrClosePipeMessageId, 0, size,
104                          0);
105 
106   interface_control::internal::RunOrClosePipeMessageParams_Data* params =
107       nullptr;
108   Serialize<interface_control::RunOrClosePipeMessageParamsDataView>(
109       params_ptr, builder.buffer(), &params, &context);
110   return std::move(*builder.message());
111 }
112 
SendRunOrClosePipeMessage(MessageReceiverWithResponder * receiver,interface_control::RunOrClosePipeInputPtr input_ptr)113 void SendRunOrClosePipeMessage(
114     MessageReceiverWithResponder* receiver,
115     interface_control::RunOrClosePipeInputPtr input_ptr) {
116   Message message(ConstructRunOrClosePipeMessage(std::move(input_ptr)));
117 
118   bool ok = receiver->Accept(&message);
119   ALLOW_UNUSED_LOCAL(ok);
120 }
121 
RunVersionCallback(const base::Callback<void (uint32_t)> & callback,interface_control::RunResponseMessageParamsPtr run_response)122 void RunVersionCallback(
123     const base::Callback<void(uint32_t)>& callback,
124     interface_control::RunResponseMessageParamsPtr run_response) {
125   uint32_t version = 0u;
126   if (run_response->output && run_response->output->is_query_version_result())
127     version = run_response->output->get_query_version_result()->version;
128   callback.Run(version);
129 }
130 
RunClosure(const base::Closure & callback,interface_control::RunResponseMessageParamsPtr run_response)131 void RunClosure(const base::Closure& callback,
132                 interface_control::RunResponseMessageParamsPtr run_response) {
133   callback.Run();
134 }
135 
136 }  // namespace
137 
ControlMessageProxy(MessageReceiverWithResponder * receiver)138 ControlMessageProxy::ControlMessageProxy(MessageReceiverWithResponder* receiver)
139     : receiver_(receiver) {
140 }
141 
142 ControlMessageProxy::~ControlMessageProxy() = default;
143 
QueryVersion(const base::Callback<void (uint32_t)> & callback)144 void ControlMessageProxy::QueryVersion(
145     const base::Callback<void(uint32_t)>& callback) {
146   auto input_ptr = interface_control::RunInput::New();
147   input_ptr->set_query_version(interface_control::QueryVersion::New());
148   SendRunMessage(receiver_, std::move(input_ptr),
149                  base::Bind(&RunVersionCallback, callback));
150 }
151 
RequireVersion(uint32_t version)152 void ControlMessageProxy::RequireVersion(uint32_t version) {
153   auto require_version = interface_control::RequireVersion::New();
154   require_version->version = version;
155   auto input_ptr = interface_control::RunOrClosePipeInput::New();
156   input_ptr->set_require_version(std::move(require_version));
157   SendRunOrClosePipeMessage(receiver_, std::move(input_ptr));
158 }
159 
FlushForTesting()160 void ControlMessageProxy::FlushForTesting() {
161   if (encountered_error_)
162     return;
163 
164   auto input_ptr = interface_control::RunInput::New();
165   input_ptr->set_flush_for_testing(interface_control::FlushForTesting::New());
166   base::RunLoop run_loop;
167   run_loop_quit_closure_ = run_loop.QuitClosure();
168   SendRunMessage(
169       receiver_, std::move(input_ptr),
170       base::Bind(&RunClosure,
171                  base::Bind(&ControlMessageProxy::RunFlushForTestingClosure,
172                             base::Unretained(this))));
173   run_loop.Run();
174 }
175 
RunFlushForTestingClosure()176 void ControlMessageProxy::RunFlushForTestingClosure() {
177   DCHECK(!run_loop_quit_closure_.is_null());
178   base::ResetAndReturn(&run_loop_quit_closure_).Run();
179 }
180 
OnConnectionError()181 void ControlMessageProxy::OnConnectionError() {
182   encountered_error_ = true;
183   if (!run_loop_quit_closure_.is_null())
184     RunFlushForTestingClosure();
185 }
186 
187 }  // namespace internal
188 }  // namespace mojo
189