| OLD | NEW |
| 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 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h | 5 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h |
| 6 // (mojo::StrongBinding). | 6 // (mojo::StrongBinding). |
| 7 | 7 |
| 8 #include "mojo/public/cpp/bindings/binding.h" | 8 #include "mojo/public/cpp/bindings/binding.h" |
| 9 | 9 |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 ~BindingTestBase() override {} | 29 ~BindingTestBase() override {} |
| 30 | 30 |
| 31 base::MessageLoop& loop() { return loop_; } | 31 base::MessageLoop& loop() { return loop_; } |
| 32 | 32 |
| 33 private: | 33 private: |
| 34 base::MessageLoop loop_; | 34 base::MessageLoop loop_; |
| 35 | 35 |
| 36 DISALLOW_COPY_AND_ASSIGN(BindingTestBase); | 36 DISALLOW_COPY_AND_ASSIGN(BindingTestBase); |
| 37 }; | 37 }; |
| 38 | 38 |
| 39 class ServiceImpl : public sample::Service { | 39 class ServiceImpl : public SupportsStrongBinding<sample::Service> { |
| 40 public: | 40 public: |
| 41 explicit ServiceImpl(bool* was_deleted = nullptr) | 41 explicit ServiceImpl( |
| 42 : was_deleted_(was_deleted) {} | 42 bool* was_deleted = nullptr, |
| 43 const base::Closure& destruction_callback = base::Closure()) |
| 44 : was_deleted_(was_deleted), |
| 45 destruction_callback_(destruction_callback) {} |
| 43 ~ServiceImpl() override { | 46 ~ServiceImpl() override { |
| 44 if (was_deleted_) | 47 if (was_deleted_) |
| 45 *was_deleted_ = true; | 48 *was_deleted_ = true; |
| 49 if (!destruction_callback_.is_null()) |
| 50 destruction_callback_.Run(); |
| 46 } | 51 } |
| 47 | 52 |
| 48 private: | 53 private: |
| 49 // sample::Service implementation | 54 // sample::Service implementation |
| 50 void Frobinate(sample::FooPtr foo, | 55 void Frobinate(sample::FooPtr foo, |
| 51 BazOptions options, | 56 BazOptions options, |
| 52 sample::PortPtr port, | 57 sample::PortPtr port, |
| 53 const FrobinateCallback& callback) override { | 58 const FrobinateCallback& callback) override { |
| 54 callback.Run(1); | 59 callback.Run(1); |
| 55 } | 60 } |
| 56 void GetPort(InterfaceRequest<sample::Port> port) override {} | 61 void GetPort(InterfaceRequest<sample::Port> port) override {} |
| 57 | 62 |
| 58 bool* const was_deleted_; | 63 bool* const was_deleted_; |
| 64 const base::Closure destruction_callback_; |
| 59 | 65 |
| 60 DISALLOW_COPY_AND_ASSIGN(ServiceImpl); | 66 DISALLOW_COPY_AND_ASSIGN(ServiceImpl); |
| 61 }; | 67 }; |
| 62 | 68 |
| 63 template <typename... Args> | 69 template <typename... Args> |
| 64 void DoSetFlagAndRunClosure(bool* flag, | 70 void DoSetFlagAndRunClosure(bool* flag, |
| 65 const base::Closure& closure, | 71 const base::Closure& closure, |
| 66 Args... args) { | 72 Args... args) { |
| 67 *flag = true; | 73 *flag = true; |
| 68 if (!closure.is_null()) | 74 if (!closure.is_null()) |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 // We can also close the other end, and the error handler still won't be | 172 // We can also close the other end, and the error handler still won't be |
| 167 // called. | 173 // called. |
| 168 ptr.reset(); | 174 ptr.reset(); |
| 169 base::RunLoop().RunUntilIdle(); | 175 base::RunLoop().RunUntilIdle(); |
| 170 EXPECT_FALSE(called); | 176 EXPECT_FALSE(called); |
| 171 } | 177 } |
| 172 | 178 |
| 173 class ServiceImplWithBinding : public ServiceImpl { | 179 class ServiceImplWithBinding : public ServiceImpl { |
| 174 public: | 180 public: |
| 175 ServiceImplWithBinding(bool* was_deleted, | 181 ServiceImplWithBinding(bool* was_deleted, |
| 176 const base::Closure& closure, | 182 const base::Closure& destruction_callback, |
| 177 InterfaceRequest<sample::Service> request) | 183 InterfaceRequest<sample::Service> request) |
| 178 : ServiceImpl(was_deleted), | 184 : ServiceImpl(was_deleted, destruction_callback), |
| 179 binding_(this, std::move(request)), | 185 binding_(this, std::move(request)) { |
| 180 closure_(closure) { | |
| 181 binding_.set_connection_error_handler( | 186 binding_.set_connection_error_handler( |
| 182 base::Bind(&ServiceImplWithBinding::OnConnectionError, | 187 base::Bind(&ServiceImplWithBinding::OnConnectionError, |
| 183 base::Unretained(this))); | 188 base::Unretained(this))); |
| 184 } | 189 } |
| 185 | 190 |
| 186 private: | 191 private: |
| 187 ~ServiceImplWithBinding() override{ | |
| 188 closure_.Run(); | |
| 189 } | |
| 190 | |
| 191 void OnConnectionError() { delete this; } | 192 void OnConnectionError() { delete this; } |
| 192 | 193 |
| 193 Binding<sample::Service> binding_; | 194 Binding<sample::Service> binding_; |
| 194 base::Closure closure_; | |
| 195 | 195 |
| 196 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); | 196 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); |
| 197 }; | 197 }; |
| 198 | 198 |
| 199 // Tests that the binding may be deleted in the connection error handler. | 199 // Tests that the binding may be deleted in the connection error handler. |
| 200 TEST_F(BindingTest, SelfDeleteOnConnectionError) { | 200 TEST_F(BindingTest, SelfDeleteOnConnectionError) { |
| 201 bool was_deleted = false; | 201 bool was_deleted = false; |
| 202 sample::ServicePtr ptr; | 202 sample::ServicePtr ptr; |
| 203 // This should delete itself on connection error. | 203 // This should delete itself on connection error. |
| 204 base::RunLoop run_loop; | 204 base::RunLoop run_loop; |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 proxy.set_connection_error_handler(run_loop.QuitClosure()); | 481 proxy.set_connection_error_handler(run_loop.QuitClosure()); |
| 482 weak_factory.InvalidateWeakPtrs(); | 482 weak_factory.InvalidateWeakPtrs(); |
| 483 run_loop.Run(); | 483 run_loop.Run(); |
| 484 } | 484 } |
| 485 } | 485 } |
| 486 | 486 |
| 487 // StrongBindingTest ----------------------------------------------------------- | 487 // StrongBindingTest ----------------------------------------------------------- |
| 488 | 488 |
| 489 using StrongBindingTest = BindingTestBase; | 489 using StrongBindingTest = BindingTestBase; |
| 490 | 490 |
| 491 // Tests that destroying a mojo::StrongBinding closes the bound message pipe | |
| 492 // handle but does *not* destroy the implementation object. | |
| 493 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { | |
| 494 base::RunLoop run_loop; | |
| 495 bool encountered_error = false; | |
| 496 bool was_deleted = false; | |
| 497 sample::ServicePtr ptr; | |
| 498 auto request = GetProxy(&ptr); | |
| 499 ptr.set_connection_error_handler( | |
| 500 SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure())); | |
| 501 bool called = false; | |
| 502 base::RunLoop run_loop2; | |
| 503 | |
| 504 auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted), | |
| 505 std::move(request)); | |
| 506 ptr->Frobinate( | |
| 507 nullptr, sample::Service::BazOptions::REGULAR, nullptr, | |
| 508 SetFlagAndRunClosure<int32_t>(&called, run_loop2.QuitClosure())); | |
| 509 run_loop2.Run(); | |
| 510 EXPECT_TRUE(called); | |
| 511 EXPECT_FALSE(encountered_error); | |
| 512 binding->Close(); | |
| 513 | |
| 514 // Now that the StrongBinding is closed we should detect an error on the other | |
| 515 // end of the pipe. | |
| 516 run_loop.Run(); | |
| 517 EXPECT_TRUE(encountered_error); | |
| 518 | |
| 519 // Destroying the StrongBinding also destroys the impl. | |
| 520 ASSERT_TRUE(was_deleted); | |
| 521 } | |
| 522 | |
| 523 // Tests the typical case, where the implementation object owns the | |
| 524 // StrongBinding (and should be destroyed on connection error). | |
| 525 TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) { | 491 TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) { |
| 526 sample::ServicePtr ptr; | 492 sample::ServicePtr ptr; |
| 527 bool was_deleted = false; | 493 bool was_deleted = false; |
| 528 // Will delete itself. | 494 |
| 529 base::RunLoop run_loop; | 495 base::RunLoop run_loop; |
| 530 new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), | 496 StrongBindingPtr<sample::Service> weak_binding = mojo::MakeStrongBinding( |
| 531 GetProxy(&ptr)); | 497 base::MakeUnique<ServiceImpl>(&was_deleted, run_loop.QuitClosure()), |
| 532 | 498 GetProxy(&ptr)); |
| 533 base::RunLoop().RunUntilIdle(); | |
| 534 EXPECT_FALSE(was_deleted); | |
| 535 | |
| 536 ptr.reset(); | 499 ptr.reset(); |
| 537 EXPECT_FALSE(was_deleted); | 500 EXPECT_FALSE(was_deleted); |
| 538 run_loop.Run(); | 501 run_loop.Run(); |
| 539 EXPECT_TRUE(was_deleted); | 502 EXPECT_TRUE(was_deleted); |
| 503 EXPECT_FALSE(weak_binding); |
| 504 } |
| 505 |
| 506 TEST_F(StrongBindingTest, ExplicitImplDeletionIsSafe) { |
| 507 sample::ServicePtr ptr; |
| 508 bool was_deleted = false; |
| 509 |
| 510 base::Closure close_callback; |
| 511 |
| 512 std::unique_ptr<ServiceImpl> impl = |
| 513 base::MakeUnique<ServiceImpl>(&was_deleted); |
| 514 ServiceImpl* raw_impl = impl.get(); |
| 515 StrongBindingPtr<sample::Service> weak_binding = |
| 516 mojo::MakeStrongBinding(std::move(impl), GetProxy(&ptr)); |
| 517 |
| 518 EXPECT_FALSE(was_deleted); |
| 519 |
| 520 base::RunLoop run_loop; |
| 521 ptr.set_connection_error_handler(run_loop.QuitClosure()); |
| 522 |
| 523 EXPECT_TRUE(weak_binding); |
| 524 |
| 525 delete raw_impl; |
| 526 |
| 527 EXPECT_TRUE(was_deleted); |
| 528 EXPECT_FALSE(weak_binding); |
| 529 |
| 530 run_loop.Run(); |
| 540 } | 531 } |
| 541 | 532 |
| 542 TEST_F(StrongBindingTest, FlushForTesting) { | 533 TEST_F(StrongBindingTest, FlushForTesting) { |
| 543 bool called = false; | 534 bool called = false; |
| 544 bool was_deleted = false; | 535 bool was_deleted = false; |
| 545 sample::ServicePtr ptr; | 536 sample::ServicePtr ptr; |
| 546 auto request = GetProxy(&ptr); | 537 auto request = GetProxy(&ptr); |
| 547 auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted), | 538 auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted), |
| 548 std::move(request)); | 539 std::move(request)); |
| 549 binding->set_connection_error_handler(base::Bind(&Fail)); | 540 binding->set_connection_error_handler(base::Bind(&Fail)); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 }, | 592 }, |
| 602 run_loop.QuitClosure())); | 593 run_loop.QuitClosure())); |
| 603 | 594 |
| 604 ptr.ResetWithReason(5678u, "hello"); | 595 ptr.ResetWithReason(5678u, "hello"); |
| 605 | 596 |
| 606 run_loop.Run(); | 597 run_loop.Run(); |
| 607 } | 598 } |
| 608 | 599 |
| 609 } // namespace | 600 } // namespace |
| 610 } // mojo | 601 } // mojo |
| OLD | NEW |