Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: mojo/public/cpp/bindings/lib/interface_endpoint_client.cc

Issue 2064903002: Mojo: Report bindings validation errors via MojoNotifyBadMessage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h" 5 #include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 : endpoint_client_(endpoint_client), 43 : endpoint_client_(endpoint_client),
44 accept_was_invoked_(false), 44 accept_was_invoked_(false),
45 task_runner_(std::move(runner)) {} 45 task_runner_(std::move(runner)) {}
46 ~ResponderThunk() override { 46 ~ResponderThunk() override {
47 if (!accept_was_invoked_) { 47 if (!accept_was_invoked_) {
48 // The Mojo application handled a message that was expecting a response 48 // The Mojo application handled a message that was expecting a response
49 // but did not send a response. 49 // but did not send a response.
50 // We raise an error to signal the calling application that an error 50 // We raise an error to signal the calling application that an error
51 // condition occurred. Without this the calling application would have no 51 // condition occurred. Without this the calling application would have no
52 // way of knowing it should stop waiting for a response. 52 // way of knowing it should stop waiting for a response.
53 Result error(Result::Type::RESPONSE_DROPPED);
53 if (task_runner_->RunsTasksOnCurrentThread()) { 54 if (task_runner_->RunsTasksOnCurrentThread()) {
54 // Please note that even if this code is run from a different task 55 // Please note that even if this code is run from a different task
55 // runner on the same thread as |task_runner_|, it is okay to directly 56 // runner on the same thread as |task_runner_|, it is okay to directly
56 // call InterfaceEndpointClient::RaiseError(), because it will raise 57 // call InterfaceEndpointClient::RaiseError(), because it will raise
57 // error from the correct task runner asynchronously. 58 // error from the correct task runner asynchronously.
58 if (endpoint_client_) { 59 if (endpoint_client_)
59 endpoint_client_->RaiseError(); 60 endpoint_client_->RaiseError(std::move(error));
60 }
61 } else { 61 } else {
62 task_runner_->PostTask( 62 task_runner_->PostTask(
63 FROM_HERE, 63 FROM_HERE,
64 base::Bind(&InterfaceEndpointClient::RaiseError, endpoint_client_)); 64 base::Bind(&InterfaceEndpointClient::RaiseError, endpoint_client_,
65 base::Passed(&error)));
65 } 66 }
66 } 67 }
67 } 68 }
68 69
69 // MessageReceiver implementation: 70 // MessageReceiver implementation:
70 bool Accept(Message* message) override { 71 Result Accept(Message* message) override {
71 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 72 DCHECK(task_runner_->RunsTasksOnCurrentThread());
72 accept_was_invoked_ = true; 73 accept_was_invoked_ = true;
73 DCHECK(message->has_flag(kMessageIsResponse)); 74 DCHECK(message->has_flag(kMessageIsResponse));
74 75
75 bool result = false; 76 if (!endpoint_client_)
76 77 return Result(Result::Type::RESPONSE_DROPPED);
77 if (endpoint_client_) 78 return endpoint_client_->Accept(message);
78 result = endpoint_client_->Accept(message);
79
80 return result;
81 } 79 }
82 80
83 // MessageReceiverWithStatus implementation: 81 // MessageReceiverWithStatus implementation:
84 bool IsValid() override { 82 bool IsValid() override {
85 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 83 DCHECK(task_runner_->RunsTasksOnCurrentThread());
86 return endpoint_client_ && !endpoint_client_->encountered_error(); 84 return endpoint_client_ && !endpoint_client_->encountered_error();
87 } 85 }
88 86
89 void DCheckInvalid(const std::string& message) override { 87 void DCheckInvalid(const std::string& message) override {
90 if (task_runner_->RunsTasksOnCurrentThread()) { 88 if (task_runner_->RunsTasksOnCurrentThread()) {
(...skipping 24 matching lines...) Expand all
115 113
116 // ---------------------------------------------------------------------------- 114 // ----------------------------------------------------------------------------
117 115
118 InterfaceEndpointClient::HandleIncomingMessageThunk::HandleIncomingMessageThunk( 116 InterfaceEndpointClient::HandleIncomingMessageThunk::HandleIncomingMessageThunk(
119 InterfaceEndpointClient* owner) 117 InterfaceEndpointClient* owner)
120 : owner_(owner) {} 118 : owner_(owner) {}
121 119
122 InterfaceEndpointClient::HandleIncomingMessageThunk:: 120 InterfaceEndpointClient::HandleIncomingMessageThunk::
123 ~HandleIncomingMessageThunk() {} 121 ~HandleIncomingMessageThunk() {}
124 122
125 bool InterfaceEndpointClient::HandleIncomingMessageThunk::Accept( 123 MessageReceiver::Result
126 Message* message) { 124 InterfaceEndpointClient::HandleIncomingMessageThunk::Accept(Message* message) {
127 return owner_->HandleValidatedMessage(message); 125 return owner_->HandleValidatedMessage(message);
128 } 126 }
129 127
130 // ---------------------------------------------------------------------------- 128 // ----------------------------------------------------------------------------
131 129
132 InterfaceEndpointClient::InterfaceEndpointClient( 130 InterfaceEndpointClient::InterfaceEndpointClient(
133 ScopedInterfaceEndpointHandle handle, 131 ScopedInterfaceEndpointHandle handle,
134 MessageReceiverWithResponderStatus* receiver, 132 MessageReceiverWithResponderStatus* receiver,
135 std::unique_ptr<MessageFilter> payload_validator, 133 std::unique_ptr<MessageFilter> payload_validator,
136 bool expect_sync_requests, 134 bool expect_sync_requests,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 177
180 if (!handle_.is_valid()) 178 if (!handle_.is_valid())
181 return ScopedInterfaceEndpointHandle(); 179 return ScopedInterfaceEndpointHandle();
182 180
183 controller_ = nullptr; 181 controller_ = nullptr;
184 handle_.router()->DetachEndpointClient(handle_); 182 handle_.router()->DetachEndpointClient(handle_);
185 183
186 return std::move(handle_); 184 return std::move(handle_);
187 } 185 }
188 186
189 void InterfaceEndpointClient::RaiseError() { 187 void InterfaceEndpointClient::RaiseError(Result error) {
190 DCHECK(thread_checker_.CalledOnValidThread()); 188 DCHECK(thread_checker_.CalledOnValidThread());
191 189
192 handle_.router()->RaiseError(); 190 handle_.router()->RaiseError(std::move(error));
193 } 191 }
194 192
195 bool InterfaceEndpointClient::Accept(Message* message) { 193 MessageReceiver::Result InterfaceEndpointClient::Accept(Message* message) {
196 DCHECK(thread_checker_.CalledOnValidThread()); 194 DCHECK(thread_checker_.CalledOnValidThread());
197 DCHECK(controller_); 195 DCHECK(controller_);
198 DCHECK(!message->has_flag(kMessageExpectsResponse)); 196 DCHECK(!message->has_flag(kMessageExpectsResponse));
199 197
200 if (encountered_error_) 198 if (encountered_error_ || !controller_->SendMessage(message))
201 return false; 199 return Result(Result::Type::SEND_FAILED);
202 200
203 return controller_->SendMessage(message); 201 return Result::ForSuccess();
204 } 202 }
205 203
206 bool InterfaceEndpointClient::AcceptWithResponder(Message* message, 204 MessageReceiver::Result InterfaceEndpointClient::AcceptWithResponder(
207 MessageReceiver* responder) { 205 Message* message,
206 MessageReceiver* responder) {
208 DCHECK(thread_checker_.CalledOnValidThread()); 207 DCHECK(thread_checker_.CalledOnValidThread());
209 DCHECK(controller_); 208 DCHECK(controller_);
210 DCHECK(message->has_flag(kMessageExpectsResponse)); 209 DCHECK(message->has_flag(kMessageExpectsResponse));
211 210
212 if (encountered_error_) 211 if (encountered_error_)
213 return false; 212 return Result(Result::Type::SEND_FAILED);
214 213
215 // Reserve 0 in case we want it to convey special meaning in the future. 214 // Reserve 0 in case we want it to convey special meaning in the future.
216 uint64_t request_id = next_request_id_++; 215 uint64_t request_id = next_request_id_++;
217 if (request_id == 0) 216 if (request_id == 0)
218 request_id = next_request_id_++; 217 request_id = next_request_id_++;
219 218
220 message->set_request_id(request_id); 219 message->set_request_id(request_id);
221 220
222 bool is_sync = message->has_flag(kMessageIsSync); 221 bool is_sync = message->has_flag(kMessageIsSync);
223 if (!controller_->SendMessage(message)) 222 if (!controller_->SendMessage(message))
224 return false; 223 return Result(Result::Type::SEND_FAILED);
225 224
226 if (!is_sync) { 225 if (!is_sync) {
227 // We assume ownership of |responder|. 226 // We assume ownership of |responder|.
228 async_responders_[request_id] = base::WrapUnique(responder); 227 async_responders_[request_id] = base::WrapUnique(responder);
229 return true; 228 return Result::ForSuccess();
230 } 229 }
231 230
232 bool response_received = false; 231 bool response_received = false;
233 std::unique_ptr<MessageReceiver> sync_responder(responder); 232 std::unique_ptr<MessageReceiver> sync_responder(responder);
234 sync_responses_.insert(std::make_pair( 233 sync_responses_.insert(std::make_pair(
235 request_id, base::WrapUnique(new SyncResponseInfo(&response_received)))); 234 request_id, base::WrapUnique(new SyncResponseInfo(&response_received))));
236 235
237 base::WeakPtr<InterfaceEndpointClient> weak_self = 236 base::WeakPtr<InterfaceEndpointClient> weak_self =
238 weak_ptr_factory_.GetWeakPtr(); 237 weak_ptr_factory_.GetWeakPtr();
239 controller_->SyncWatch(&response_received); 238 controller_->SyncWatch(&response_received);
240 // Make sure that this instance hasn't been destroyed. 239 // Make sure that this instance hasn't been destroyed.
241 if (weak_self) { 240 if (weak_self) {
242 DCHECK(ContainsKey(sync_responses_, request_id)); 241 DCHECK(ContainsKey(sync_responses_, request_id));
243 auto iter = sync_responses_.find(request_id); 242 auto iter = sync_responses_.find(request_id);
244 DCHECK_EQ(&response_received, iter->second->response_received); 243 DCHECK_EQ(&response_received, iter->second->response_received);
245 if (response_received) { 244 if (response_received) {
246 std::unique_ptr<Message> response = std::move(iter->second->response); 245 std::unique_ptr<Message> response = std::move(iter->second->response);
247 ignore_result(sync_responder->Accept(response.get())); 246 ignore_result(sync_responder->Accept(response.get()));
248 } 247 }
249 sync_responses_.erase(iter); 248 sync_responses_.erase(iter);
250 } 249 }
251 250
252 // Return true means that we take ownership of |responder|. 251 // Return true means that we take ownership of |responder|.
253 return true; 252 return Result::ForSuccess();
254 } 253 }
255 254
256 bool InterfaceEndpointClient::HandleIncomingMessage(Message* message) { 255 MessageReceiver::Result InterfaceEndpointClient::HandleIncomingMessage(
256 Message* message) {
257 DCHECK(thread_checker_.CalledOnValidThread()); 257 DCHECK(thread_checker_.CalledOnValidThread());
258 258
259 return payload_validator_->Accept(message); 259 return payload_validator_->Accept(message);
260 } 260 }
261 261
262 void InterfaceEndpointClient::NotifyError() { 262 void InterfaceEndpointClient::NotifyError() {
263 DCHECK(thread_checker_.CalledOnValidThread()); 263 DCHECK(thread_checker_.CalledOnValidThread());
264 264
265 if (encountered_error_) 265 if (encountered_error_)
266 return; 266 return;
267 encountered_error_ = true; 267 encountered_error_ = true;
268 error_handler_.Run(); 268 error_handler_.Run();
269 } 269 }
270 270
271 bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) { 271 MessageReceiver::Result InterfaceEndpointClient::HandleValidatedMessage(
272 Message* message) {
272 DCHECK_EQ(handle_.id(), message->interface_id()); 273 DCHECK_EQ(handle_.id(), message->interface_id());
273 274
274 if (message->has_flag(kMessageExpectsResponse)) { 275 if (message->has_flag(kMessageExpectsResponse)) {
275 if (!incoming_receiver_) 276 if (!incoming_receiver_)
276 return false; 277 return Result(Result::Type::REQUEST_DROPPED);
277 278
278 MessageReceiverWithStatus* responder = 279 MessageReceiverWithStatus* responder =
279 new ResponderThunk(weak_ptr_factory_.GetWeakPtr(), task_runner_); 280 new ResponderThunk(weak_ptr_factory_.GetWeakPtr(), task_runner_);
280 bool ok = incoming_receiver_->AcceptWithResponder(message, responder); 281 Result result = incoming_receiver_->AcceptWithResponder(message, responder);
281 if (!ok) 282 if (!result.Succeeded())
282 delete responder; 283 delete responder;
283 return ok; 284 return result;
284 } else if (message->has_flag(kMessageIsResponse)) { 285 } else if (message->has_flag(kMessageIsResponse)) {
285 uint64_t request_id = message->request_id(); 286 uint64_t request_id = message->request_id();
286 287
287 if (message->has_flag(kMessageIsSync)) { 288 if (message->has_flag(kMessageIsSync)) {
288 auto it = sync_responses_.find(request_id); 289 auto it = sync_responses_.find(request_id);
289 if (it == sync_responses_.end()) 290 if (it == sync_responses_.end())
290 return false; 291 return Result::ForUnexpectedResponse(interface_name_, message);
291 it->second->response.reset(new Message()); 292 it->second->response.reset(new Message());
292 message->MoveTo(it->second->response.get()); 293 message->MoveTo(it->second->response.get());
293 *it->second->response_received = true; 294 *it->second->response_received = true;
294 return true; 295 return Result::ForSuccess();
295 } 296 }
296 297
297 auto it = async_responders_.find(request_id); 298 auto it = async_responders_.find(request_id);
298 if (it == async_responders_.end()) 299 if (it == async_responders_.end())
299 return false; 300 return Result::ForUnexpectedResponse(interface_name_, message);
301
300 std::unique_ptr<MessageReceiver> responder = std::move(it->second); 302 std::unique_ptr<MessageReceiver> responder = std::move(it->second);
301 async_responders_.erase(it); 303 async_responders_.erase(it);
302 return responder->Accept(message); 304 return responder->Accept(message);
303 } else { 305 } else {
304 if (!incoming_receiver_) 306 if (!incoming_receiver_)
305 return false; 307 return Result(Result::Type::REQUEST_DROPPED);
306
307 return incoming_receiver_->Accept(message); 308 return incoming_receiver_->Accept(message);
308 } 309 }
309 } 310 }
310 311
311 } // namespace internal 312 } // namespace internal
312 } // namespace mojo 313 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698