| Index: mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
|
| diff --git a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
|
| index 8f2eb08d9fc3008d33eb09a3ae0887c207111b1e..b1148c73689a824f5176df17ab90b2f3761f6059 100644
|
| --- a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
|
| +++ b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
|
| @@ -9,6 +9,7 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/callback.h"
|
| +#include "base/callback_helpers.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| #include "base/single_thread_task_runner.h"
|
| @@ -21,6 +22,7 @@
|
| #include "mojo/public/cpp/bindings/associated_interface_request.h"
|
| #include "mojo/public/cpp/bindings/binding.h"
|
| #include "mojo/public/cpp/bindings/lib/multiplex_router.h"
|
| +#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h"
|
| #include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| @@ -589,6 +591,155 @@ TEST_F(AssociatedInterfaceTest, BindingWaitAndPauseWhenNoAssociatedInterfaces) {
|
| EXPECT_TRUE(connection.binding()->HasAssociatedInterfaces());
|
| }
|
|
|
| +class PingServiceImpl : public PingService {
|
| + public:
|
| + explicit PingServiceImpl(PingServiceAssociatedRequest request)
|
| + : binding_(this, std::move(request)) {}
|
| + ~PingServiceImpl() override {}
|
| +
|
| + AssociatedBinding<PingService>& binding() { return binding_; }
|
| +
|
| + void set_ping_handler(const base::Closure& handler) {
|
| + ping_handler_ = handler;
|
| + }
|
| +
|
| + // PingService:
|
| + void Ping(const PingCallback& callback) override {
|
| + if (!ping_handler_.is_null())
|
| + ping_handler_.Run();
|
| + callback.Run();
|
| + }
|
| +
|
| + private:
|
| + AssociatedBinding<PingService> binding_;
|
| + base::Closure ping_handler_;
|
| +};
|
| +
|
| +class PingProviderImpl : public AssociatedPingProvider {
|
| + public:
|
| + explicit PingProviderImpl(AssociatedPingProviderRequest request)
|
| + : binding_(this, std::move(request)) {}
|
| + ~PingProviderImpl() override {}
|
| +
|
| + // AssociatedPingProvider:
|
| + void GetPing(PingServiceAssociatedRequest request) override {
|
| + ping_services_.emplace_back(new PingServiceImpl(std::move(request)));
|
| +
|
| + if (expected_bindings_count_ > 0 &&
|
| + ping_services_.size() == expected_bindings_count_ &&
|
| + !quit_waiting_.is_null()) {
|
| + expected_bindings_count_ = 0;
|
| + base::ResetAndReturn(&quit_waiting_).Run();
|
| + }
|
| + }
|
| +
|
| + std::vector<std::unique_ptr<PingServiceImpl>>& ping_services() {
|
| + return ping_services_;
|
| + }
|
| +
|
| + void WaitForBindings(size_t count) {
|
| + DCHECK(quit_waiting_.is_null());
|
| +
|
| + expected_bindings_count_ = count;
|
| + base::RunLoop loop;
|
| + quit_waiting_ = loop.QuitClosure();
|
| + loop.Run();
|
| + }
|
| +
|
| + private:
|
| + Binding<AssociatedPingProvider> binding_;
|
| + std::vector<std::unique_ptr<PingServiceImpl>> ping_services_;
|
| + size_t expected_bindings_count_ = 0;
|
| + base::Closure quit_waiting_;
|
| +};
|
| +
|
| +class CallbackFilter : public MessageReceiver {
|
| + public:
|
| + explicit CallbackFilter(const base::Closure& callback)
|
| + : callback_(callback) {}
|
| + ~CallbackFilter() override {}
|
| +
|
| + static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) {
|
| + return base::MakeUnique<CallbackFilter>(callback);
|
| + }
|
| +
|
| + // MessageReceiver:
|
| + bool Accept(Message* message) override {
|
| + callback_.Run();
|
| + return true;
|
| + }
|
| +
|
| + private:
|
| + const base::Closure callback_;
|
| +};
|
| +
|
| +// Verifies that filters work as expected on associated bindings, i.e. that
|
| +// they're notified in order, before dispatch; and that each associated
|
| +// binding in a group operates with its own set of filters.
|
| +TEST_F(AssociatedInterfaceTest, BindingWithFilters) {
|
| + AssociatedPingProviderPtr provider;
|
| + PingProviderImpl provider_impl(GetProxy(&provider));
|
| +
|
| + PingServiceAssociatedPtr ping_a, ping_b;
|
| + provider->GetPing(GetProxy(&ping_a, provider.associated_group()));
|
| + provider->GetPing(GetProxy(&ping_b, provider.associated_group()));
|
| + provider_impl.WaitForBindings(2);
|
| +
|
| + ASSERT_EQ(2u, provider_impl.ping_services().size());
|
| + PingServiceImpl& ping_a_impl = *provider_impl.ping_services()[0];
|
| + PingServiceImpl& ping_b_impl = *provider_impl.ping_services()[1];
|
| +
|
| + int a_status, b_status;
|
| + auto handler_helper = [] (int* a_status, int* b_status, int expected_a_status,
|
| + int new_a_status, int expected_b_status,
|
| + int new_b_status) {
|
| + EXPECT_EQ(expected_a_status, *a_status);
|
| + EXPECT_EQ(expected_b_status, *b_status);
|
| + *a_status = new_a_status;
|
| + *b_status = new_b_status;
|
| + };
|
| + auto create_handler = [&] (int expected_a_status, int new_a_status,
|
| + int expected_b_status, int new_b_status) {
|
| + return base::Bind(handler_helper, &a_status, &b_status, expected_a_status,
|
| + new_a_status, expected_b_status, new_b_status);
|
| + };
|
| +
|
| + ping_a_impl.binding().AddFilter(
|
| + CallbackFilter::Wrap(create_handler(0, 1, 0, 0)));
|
| + ping_a_impl.binding().AddFilter(
|
| + CallbackFilter::Wrap(create_handler(1, 2, 0, 0)));
|
| + ping_a_impl.set_ping_handler(create_handler(2, 3, 0, 0));
|
| +
|
| + ping_b_impl.binding().AddFilter(
|
| + CallbackFilter::Wrap(create_handler(3, 3, 0, 1)));
|
| + ping_b_impl.binding().AddFilter(
|
| + CallbackFilter::Wrap(create_handler(3, 3, 1, 2)));
|
| + ping_b_impl.set_ping_handler(create_handler(3, 3, 2, 3));
|
| +
|
| + for (int i = 0; i < 10; ++i) {
|
| + a_status = 0;
|
| + b_status = 0;
|
| +
|
| + {
|
| + base::RunLoop loop;
|
| + ping_a->Ping(loop.QuitClosure());
|
| + loop.Run();
|
| + }
|
| +
|
| + EXPECT_EQ(3, a_status);
|
| + EXPECT_EQ(0, b_status);
|
| +
|
| + {
|
| + base::RunLoop loop;
|
| + ping_b->Ping(loop.QuitClosure());
|
| + loop.Run();
|
| + }
|
| +
|
| + EXPECT_EQ(3, a_status);
|
| + EXPECT_EQ(3, b_status);
|
| + }
|
| +}
|
| +
|
| } // namespace
|
| } // namespace test
|
| } // namespace mojo
|
|
|