Index: mojo/public/cpp/bindings/lib/control_message_proxy.cc |
diff --git a/mojo/public/cpp/bindings/lib/control_message_proxy.cc b/mojo/public/cpp/bindings/lib/control_message_proxy.cc |
index 06d9815bc08ba8a6fcfb4741579d60b9a8cd81c8..e48f369735984d073aedcac2a406814953351ff4 100644 |
--- a/mojo/public/cpp/bindings/lib/control_message_proxy.cc |
+++ b/mojo/public/cpp/bindings/lib/control_message_proxy.cc |
@@ -10,8 +10,10 @@ |
#include "base/bind.h" |
#include "base/macros.h" |
+#include "base/run_loop.h" |
#include "mojo/public/cpp/bindings/lib/message_builder.h" |
#include "mojo/public/cpp/bindings/lib/serialization.h" |
+#include "mojo/public/cpp/bindings/lib/validation_util.h" |
#include "mojo/public/cpp/bindings/message.h" |
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h" |
@@ -20,6 +22,22 @@ namespace internal { |
namespace { |
+bool ValidateControlResponse(Message* message) { |
+ ValidationContext validation_context( |
+ message->data(), message->data_num_bytes(), message->handles()->size(), |
+ message, "ControlResponseValidator"); |
+ if (!ValidateMessageIsResponse(message, &validation_context)) |
+ return false; |
+ |
+ switch (message->header()->name) { |
+ case interface_control::kRunMessageId: |
+ return ValidateMessagePayload< |
+ interface_control::internal::RunResponseMessageParams_Data>( |
+ message, &validation_context); |
+ } |
+ return false; |
+} |
+ |
using RunCallback = |
base::Callback<void(interface_control::RunResponseMessageParamsPtr)>; |
@@ -35,6 +53,9 @@ class RunResponseForwardToCallback : public MessageReceiver { |
}; |
bool RunResponseForwardToCallback::Accept(Message* message) { |
+ if (!ValidateControlResponse(message)) |
+ return false; |
+ |
interface_control::internal::RunResponseMessageParams_Data* params = |
reinterpret_cast< |
interface_control::internal::RunResponseMessageParams_Data*>( |
@@ -95,12 +116,19 @@ void RunVersionCallback( |
callback.Run(version); |
} |
+void RunClosure(const base::Closure& callback, |
+ interface_control::RunResponseMessageParamsPtr run_response) { |
+ callback.Run(); |
+} |
+ |
} // namespace |
ControlMessageProxy::ControlMessageProxy(MessageReceiverWithResponder* receiver) |
: receiver_(receiver) { |
} |
+ControlMessageProxy::~ControlMessageProxy() = default; |
+ |
void ControlMessageProxy::QueryVersion( |
const base::Callback<void(uint32_t)>& callback) { |
auto input_ptr = interface_control::RunInput::New(); |
@@ -117,5 +145,34 @@ void ControlMessageProxy::RequireVersion(uint32_t version) { |
SendRunOrClosePipeMessage(receiver_, std::move(input_ptr), &context_); |
} |
+void ControlMessageProxy::FlushForTesting() { |
+ if (encountered_error_) |
+ return; |
+ |
+ auto input_ptr = interface_control::RunInput::New(); |
+ input_ptr->set_flush_for_testing(interface_control::FlushForTesting::New()); |
+ base::RunLoop run_loop; |
+ run_loop_quit_closure_ = run_loop.QuitClosure(); |
+ SendRunMessage( |
+ receiver_, std::move(input_ptr), |
+ base::Bind(&RunClosure, |
+ base::Bind(&ControlMessageProxy::RunFlushForTestingClosure, |
+ base::Unretained(this))), |
+ &context_); |
+ run_loop.Run(); |
+} |
+ |
+void ControlMessageProxy::RunFlushForTestingClosure() { |
+ DCHECK(!run_loop_quit_closure_.is_null()); |
+ run_loop_quit_closure_.Run(); |
dcheng
2016/09/01 08:19:00
This could use base::ResetAndReturn().Run()
Sam McNally
2016/09/01 08:35:34
Done.
|
+ run_loop_quit_closure_.Reset(); |
+} |
+ |
+void ControlMessageProxy::OnConnectionError() { |
+ encountered_error_ = true; |
+ if (!run_loop_quit_closure_.is_null()) |
+ RunFlushForTestingClosure(); |
+} |
+ |
} // namespace internal |
} // namespace mojo |