| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 const FrobinateCallback& callback) override { | 51 const FrobinateCallback& callback) override { |
| 52 callback.Run(1); | 52 callback.Run(1); |
| 53 } | 53 } |
| 54 void GetPort(InterfaceRequest<sample::Port> port) override {} | 54 void GetPort(InterfaceRequest<sample::Port> port) override {} |
| 55 | 55 |
| 56 bool* const was_deleted_; | 56 bool* const was_deleted_; |
| 57 | 57 |
| 58 DISALLOW_COPY_AND_ASSIGN(ServiceImpl); | 58 DISALLOW_COPY_AND_ASSIGN(ServiceImpl); |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 template <typename... Args> |
| 62 void DoSetFlagAndRunClosure(bool* flag, |
| 63 const base::Closure& closure, |
| 64 Args... args) { |
| 65 *flag = true; |
| 66 closure.Run(); |
| 67 } |
| 68 |
| 69 template <typename... Args> |
| 70 base::Callback<void(Args...)> SetFlagAndRunClosure( |
| 71 bool* flag, |
| 72 const base::Closure& callback = base::Closure()) { |
| 73 return base::Bind(&DoSetFlagAndRunClosure<Args...>, flag, callback); |
| 74 } |
| 75 |
| 61 // BindingTest ----------------------------------------------------------------- | 76 // BindingTest ----------------------------------------------------------------- |
| 62 | 77 |
| 63 using BindingTest = BindingTestBase; | 78 using BindingTest = BindingTestBase; |
| 64 | 79 |
| 65 TEST_F(BindingTest, Close) { | 80 TEST_F(BindingTest, Close) { |
| 66 bool called = false; | 81 bool called = false; |
| 67 sample::ServicePtr ptr; | 82 sample::ServicePtr ptr; |
| 68 auto request = GetProxy(&ptr); | 83 auto request = GetProxy(&ptr); |
| 69 base::RunLoop run_loop; | 84 base::RunLoop run_loop; |
| 70 ptr.set_connection_error_handler([&called, &run_loop]() { | 85 ptr.set_connection_error_handler( |
| 71 called = true; | 86 SetFlagAndRunClosure(&called, run_loop.QuitClosure())); |
| 72 run_loop.Quit(); | |
| 73 }); | |
| 74 ServiceImpl impl; | 87 ServiceImpl impl; |
| 75 Binding<sample::Service> binding(&impl, std::move(request)); | 88 Binding<sample::Service> binding(&impl, std::move(request)); |
| 76 | 89 |
| 77 binding.Close(); | 90 binding.Close(); |
| 78 EXPECT_FALSE(called); | 91 EXPECT_FALSE(called); |
| 79 run_loop.Run(); | 92 run_loop.Run(); |
| 80 EXPECT_TRUE(called); | 93 EXPECT_TRUE(called); |
| 81 } | 94 } |
| 82 | 95 |
| 83 // Tests that destroying a mojo::Binding closes the bound message pipe handle. | 96 // Tests that destroying a mojo::Binding closes the bound message pipe handle. |
| 84 TEST_F(BindingTest, DestroyClosesMessagePipe) { | 97 TEST_F(BindingTest, DestroyClosesMessagePipe) { |
| 85 bool encountered_error = false; | 98 bool encountered_error = false; |
| 86 ServiceImpl impl; | 99 ServiceImpl impl; |
| 87 sample::ServicePtr ptr; | 100 sample::ServicePtr ptr; |
| 88 auto request = GetProxy(&ptr); | 101 auto request = GetProxy(&ptr); |
| 89 base::RunLoop run_loop; | 102 base::RunLoop run_loop; |
| 90 ptr.set_connection_error_handler( | 103 ptr.set_connection_error_handler( |
| 91 [&encountered_error, &run_loop]() { | 104 SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure())); |
| 92 encountered_error = true; | |
| 93 run_loop.Quit(); | |
| 94 }); | |
| 95 bool called = false; | 105 bool called = false; |
| 96 base::RunLoop run_loop2; | 106 base::RunLoop run_loop2; |
| 97 auto called_cb = [&called, &run_loop2](int32_t result) { | |
| 98 called = true; | |
| 99 run_loop2.Quit(); | |
| 100 }; | |
| 101 { | 107 { |
| 102 Binding<sample::Service> binding(&impl, std::move(request)); | 108 Binding<sample::Service> binding(&impl, std::move(request)); |
| 103 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 109 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
| 104 called_cb); | 110 SetFlagAndRunClosure<int32_t>(&called, |
| 111 run_loop2.QuitClosure())); |
| 105 run_loop2.Run(); | 112 run_loop2.Run(); |
| 106 EXPECT_TRUE(called); | 113 EXPECT_TRUE(called); |
| 107 EXPECT_FALSE(encountered_error); | 114 EXPECT_FALSE(encountered_error); |
| 108 } | 115 } |
| 109 // Now that the Binding is out of scope we should detect an error on the other | 116 // Now that the Binding is out of scope we should detect an error on the other |
| 110 // end of the pipe. | 117 // end of the pipe. |
| 111 run_loop.Run(); | 118 run_loop.Run(); |
| 112 EXPECT_TRUE(encountered_error); | 119 EXPECT_TRUE(encountered_error); |
| 113 | 120 |
| 114 // And calls should fail. | 121 // And calls should fail. |
| 115 called = false; | 122 called = false; |
| 116 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 123 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
| 117 called_cb); | 124 SetFlagAndRunClosure<int32_t>(&called, |
| 125 run_loop2.QuitClosure())); |
| 118 loop().RunUntilIdle(); | 126 loop().RunUntilIdle(); |
| 119 EXPECT_FALSE(called); | 127 EXPECT_FALSE(called); |
| 120 } | 128 } |
| 121 | 129 |
| 122 // Tests that the binding's connection error handler gets called when the other | 130 // Tests that the binding's connection error handler gets called when the other |
| 123 // end is closed. | 131 // end is closed. |
| 124 TEST_F(BindingTest, ConnectionError) { | 132 TEST_F(BindingTest, ConnectionError) { |
| 125 bool called = false; | 133 bool called = false; |
| 126 { | 134 { |
| 127 ServiceImpl impl; | 135 ServiceImpl impl; |
| 128 sample::ServicePtr ptr; | 136 sample::ServicePtr ptr; |
| 129 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); | 137 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); |
| 130 base::RunLoop run_loop; | 138 base::RunLoop run_loop; |
| 131 binding.set_connection_error_handler([&called, &run_loop]() { | 139 binding.set_connection_error_handler( |
| 132 called = true; | 140 SetFlagAndRunClosure(&called, run_loop.QuitClosure())); |
| 133 run_loop.Quit(); | |
| 134 }); | |
| 135 ptr.reset(); | 141 ptr.reset(); |
| 136 EXPECT_FALSE(called); | 142 EXPECT_FALSE(called); |
| 137 run_loop.Run(); | 143 run_loop.Run(); |
| 138 EXPECT_TRUE(called); | 144 EXPECT_TRUE(called); |
| 139 // We want to make sure that it isn't called again during destruction. | 145 // We want to make sure that it isn't called again during destruction. |
| 140 called = false; | 146 called = false; |
| 141 } | 147 } |
| 142 EXPECT_FALSE(called); | 148 EXPECT_FALSE(called); |
| 143 } | 149 } |
| 144 | 150 |
| 145 // Tests that calling Close doesn't result in the connection error handler being | 151 // Tests that calling Close doesn't result in the connection error handler being |
| 146 // called. | 152 // called. |
| 147 TEST_F(BindingTest, CloseDoesntCallConnectionErrorHandler) { | 153 TEST_F(BindingTest, CloseDoesntCallConnectionErrorHandler) { |
| 148 ServiceImpl impl; | 154 ServiceImpl impl; |
| 149 sample::ServicePtr ptr; | 155 sample::ServicePtr ptr; |
| 150 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); | 156 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); |
| 151 bool called = false; | 157 bool called = false; |
| 152 binding.set_connection_error_handler([&called]() { called = true; }); | 158 binding.set_connection_error_handler(SetFlagAndRunClosure(&called)); |
| 153 binding.Close(); | 159 binding.Close(); |
| 154 loop().RunUntilIdle(); | 160 loop().RunUntilIdle(); |
| 155 EXPECT_FALSE(called); | 161 EXPECT_FALSE(called); |
| 156 | 162 |
| 157 // We can also close the other end, and the error handler still won't be | 163 // We can also close the other end, and the error handler still won't be |
| 158 // called. | 164 // called. |
| 159 ptr.reset(); | 165 ptr.reset(); |
| 160 loop().RunUntilIdle(); | 166 loop().RunUntilIdle(); |
| 161 EXPECT_FALSE(called); | 167 EXPECT_FALSE(called); |
| 162 } | 168 } |
| 163 | 169 |
| 164 class ServiceImplWithBinding : public ServiceImpl { | 170 class ServiceImplWithBinding : public ServiceImpl { |
| 165 public: | 171 public: |
| 166 ServiceImplWithBinding(bool* was_deleted, | 172 ServiceImplWithBinding(bool* was_deleted, |
| 167 const base::Closure& closure, | 173 const base::Closure& closure, |
| 168 InterfaceRequest<sample::Service> request) | 174 InterfaceRequest<sample::Service> request) |
| 169 : ServiceImpl(was_deleted), | 175 : ServiceImpl(was_deleted), |
| 170 binding_(this, std::move(request)), | 176 binding_(this, std::move(request)), |
| 171 closure_(closure) { | 177 closure_(closure) { |
| 172 binding_.set_connection_error_handler([this]() { delete this; }); | 178 binding_.set_connection_error_handler( |
| 179 base::Bind(&ServiceImplWithBinding::OnConnectionError, |
| 180 base::Unretained(this))); |
| 173 } | 181 } |
| 174 | 182 |
| 175 private: | 183 private: |
| 176 ~ServiceImplWithBinding() override{ | 184 ~ServiceImplWithBinding() override{ |
| 177 closure_.Run(); | 185 closure_.Run(); |
| 178 } | 186 } |
| 179 | 187 |
| 188 void OnConnectionError() { delete this; } |
| 189 |
| 180 Binding<sample::Service> binding_; | 190 Binding<sample::Service> binding_; |
| 181 base::Closure closure_; | 191 base::Closure closure_; |
| 182 | 192 |
| 183 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); | 193 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); |
| 184 }; | 194 }; |
| 185 | 195 |
| 186 // Tests that the binding may be deleted in the connection error handler. | 196 // Tests that the binding may be deleted in the connection error handler. |
| 187 TEST_F(BindingTest, SelfDeleteOnConnectionError) { | 197 TEST_F(BindingTest, SelfDeleteOnConnectionError) { |
| 188 bool was_deleted = false; | 198 bool was_deleted = false; |
| 189 sample::ServicePtr ptr; | 199 sample::ServicePtr ptr; |
| 190 // This should delete itself on connection error. | 200 // This should delete itself on connection error. |
| 191 base::RunLoop run_loop; | 201 base::RunLoop run_loop; |
| 192 new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), | 202 new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), |
| 193 GetProxy(&ptr)); | 203 GetProxy(&ptr)); |
| 194 ptr.reset(); | 204 ptr.reset(); |
| 195 EXPECT_FALSE(was_deleted); | 205 EXPECT_FALSE(was_deleted); |
| 196 run_loop.Run(); | 206 run_loop.Run(); |
| 197 EXPECT_TRUE(was_deleted); | 207 EXPECT_TRUE(was_deleted); |
| 198 } | 208 } |
| 199 | 209 |
| 200 // Tests that explicitly calling Unbind followed by rebinding works. | 210 // Tests that explicitly calling Unbind followed by rebinding works. |
| 201 TEST_F(BindingTest, Unbind) { | 211 TEST_F(BindingTest, Unbind) { |
| 202 ServiceImpl impl; | 212 ServiceImpl impl; |
| 203 sample::ServicePtr ptr; | 213 sample::ServicePtr ptr; |
| 204 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); | 214 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); |
| 205 | 215 |
| 206 bool called = false; | 216 bool called = false; |
| 207 base::RunLoop run_loop; | 217 base::RunLoop run_loop; |
| 208 auto called_cb = [&called, &run_loop](int32_t result) { | |
| 209 called = true; | |
| 210 run_loop.Quit(); | |
| 211 }; | |
| 212 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 218 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
| 213 called_cb); | 219 SetFlagAndRunClosure<int32_t>(&called, |
| 220 run_loop.QuitClosure())); |
| 214 run_loop.Run(); | 221 run_loop.Run(); |
| 215 EXPECT_TRUE(called); | 222 EXPECT_TRUE(called); |
| 216 | 223 |
| 217 called = false; | 224 called = false; |
| 218 auto request = binding.Unbind(); | 225 auto request = binding.Unbind(); |
| 219 EXPECT_FALSE(binding.is_bound()); | 226 EXPECT_FALSE(binding.is_bound()); |
| 220 // All calls should fail when not bound... | 227 // All calls should fail when not bound... |
| 221 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 228 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
| 222 called_cb); | 229 SetFlagAndRunClosure<int32_t>(&called, |
| 230 run_loop.QuitClosure())); |
| 223 loop().RunUntilIdle(); | 231 loop().RunUntilIdle(); |
| 224 EXPECT_FALSE(called); | 232 EXPECT_FALSE(called); |
| 225 | 233 |
| 226 called = false; | 234 called = false; |
| 227 binding.Bind(std::move(request)); | 235 binding.Bind(std::move(request)); |
| 228 EXPECT_TRUE(binding.is_bound()); | 236 EXPECT_TRUE(binding.is_bound()); |
| 229 // ...and should succeed again when the rebound. | 237 // ...and should succeed again when the rebound. |
| 230 base::RunLoop run_loop2; | 238 base::RunLoop run_loop2; |
| 231 auto called_cb2 = [&called, &run_loop2](int32_t result) { | |
| 232 called = true; | |
| 233 run_loop2.Quit(); | |
| 234 }; | |
| 235 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 239 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
| 236 called_cb2); | 240 SetFlagAndRunClosure<int32_t>(&called, |
| 241 run_loop2.QuitClosure())); |
| 237 run_loop2.Run(); | 242 run_loop2.Run(); |
| 238 EXPECT_TRUE(called); | 243 EXPECT_TRUE(called); |
| 239 } | 244 } |
| 240 | 245 |
| 241 class IntegerAccessorImpl : public sample::IntegerAccessor { | 246 class IntegerAccessorImpl : public sample::IntegerAccessor { |
| 242 public: | 247 public: |
| 243 IntegerAccessorImpl() {} | 248 IntegerAccessorImpl() {} |
| 244 ~IntegerAccessorImpl() override {} | 249 ~IntegerAccessorImpl() override {} |
| 245 | 250 |
| 246 private: | 251 private: |
| 247 // sample::IntegerAccessor implementation. | 252 // sample::IntegerAccessor implementation. |
| 248 void GetInteger(const GetIntegerCallback& callback) override { | 253 void GetInteger(const GetIntegerCallback& callback) override { |
| 249 callback.Run(1, sample::Enum::VALUE); | 254 callback.Run(1, sample::Enum::VALUE); |
| 250 } | 255 } |
| 251 void SetInteger(int64_t data, sample::Enum type) override {} | 256 void SetInteger(int64_t data, sample::Enum type) override {} |
| 252 | 257 |
| 253 DISALLOW_COPY_AND_ASSIGN(IntegerAccessorImpl); | 258 DISALLOW_COPY_AND_ASSIGN(IntegerAccessorImpl); |
| 254 }; | 259 }; |
| 255 | 260 |
| 256 TEST_F(BindingTest, SetInterfacePtrVersion) { | 261 TEST_F(BindingTest, SetInterfacePtrVersion) { |
| 257 IntegerAccessorImpl impl; | 262 IntegerAccessorImpl impl; |
| 258 sample::IntegerAccessorPtr ptr; | 263 sample::IntegerAccessorPtr ptr; |
| 259 Binding<sample::IntegerAccessor> binding(&impl, &ptr); | 264 Binding<sample::IntegerAccessor> binding(&impl, &ptr); |
| 260 EXPECT_EQ(3u, ptr.version()); | 265 EXPECT_EQ(3u, ptr.version()); |
| 261 } | 266 } |
| 262 | 267 |
| 263 TEST_F(BindingTest, PauseResume) { | 268 TEST_F(BindingTest, PauseResume) { |
| 264 bool called = false; | 269 bool called = false; |
| 265 base::RunLoop run_loop; | 270 base::RunLoop run_loop; |
| 266 auto called_cb = [&called, &run_loop](int32_t result) { | |
| 267 called = true; | |
| 268 run_loop.Quit(); | |
| 269 }; | |
| 270 sample::ServicePtr ptr; | 271 sample::ServicePtr ptr; |
| 271 auto request = GetProxy(&ptr); | 272 auto request = GetProxy(&ptr); |
| 272 ServiceImpl impl; | 273 ServiceImpl impl; |
| 273 Binding<sample::Service> binding(&impl, std::move(request)); | 274 Binding<sample::Service> binding(&impl, std::move(request)); |
| 274 binding.PauseIncomingMethodCallProcessing(); | 275 binding.PauseIncomingMethodCallProcessing(); |
| 275 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 276 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
| 276 called_cb); | 277 SetFlagAndRunClosure<int32_t>(&called, |
| 278 run_loop.QuitClosure())); |
| 277 EXPECT_FALSE(called); | 279 EXPECT_FALSE(called); |
| 278 loop().RunUntilIdle(); | 280 loop().RunUntilIdle(); |
| 279 // Frobinate() should not be called as the binding is paused. | 281 // Frobinate() should not be called as the binding is paused. |
| 280 EXPECT_FALSE(called); | 282 EXPECT_FALSE(called); |
| 281 | 283 |
| 282 // Resume the binding, which should trigger processing. | 284 // Resume the binding, which should trigger processing. |
| 283 binding.ResumeIncomingMethodCallProcessing(); | 285 binding.ResumeIncomingMethodCallProcessing(); |
| 284 run_loop.Run(); | 286 run_loop.Run(); |
| 285 EXPECT_TRUE(called); | 287 EXPECT_TRUE(called); |
| 286 } | 288 } |
| 287 | 289 |
| 288 // Verifies the connection error handler is not run while a binding is paused. | 290 // Verifies the connection error handler is not run while a binding is paused. |
| 289 TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) { | 291 TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) { |
| 290 bool called = false; | 292 bool called = false; |
| 291 base::RunLoop run_loop; | 293 base::RunLoop run_loop; |
| 292 sample::ServicePtr ptr; | 294 sample::ServicePtr ptr; |
| 293 auto request = GetProxy(&ptr); | 295 auto request = GetProxy(&ptr); |
| 294 ServiceImpl impl; | 296 ServiceImpl impl; |
| 295 Binding<sample::Service> binding(&impl, std::move(request)); | 297 Binding<sample::Service> binding(&impl, std::move(request)); |
| 296 binding.set_connection_error_handler([&called, &run_loop]() { | 298 binding.set_connection_error_handler( |
| 297 called = true; | 299 SetFlagAndRunClosure(&called, run_loop.QuitClosure())); |
| 298 run_loop.Quit(); | |
| 299 }); | |
| 300 binding.PauseIncomingMethodCallProcessing(); | 300 binding.PauseIncomingMethodCallProcessing(); |
| 301 | 301 |
| 302 ptr.reset(); | 302 ptr.reset(); |
| 303 loop().RunUntilIdle(); | 303 loop().RunUntilIdle(); |
| 304 // The connection error handle should not be called as the binding is paused. | 304 // The connection error handle should not be called as the binding is paused. |
| 305 EXPECT_FALSE(called); | 305 EXPECT_FALSE(called); |
| 306 | 306 |
| 307 // Resume the binding, which should trigger the error handler. | 307 // Resume the binding, which should trigger the error handler. |
| 308 binding.ResumeIncomingMethodCallProcessing(); | 308 binding.ResumeIncomingMethodCallProcessing(); |
| 309 run_loop.Run(); | 309 run_loop.Run(); |
| 310 EXPECT_TRUE(called); | 310 EXPECT_TRUE(called); |
| 311 } | 311 } |
| 312 | 312 |
| 313 // StrongBindingTest ----------------------------------------------------------- | 313 // StrongBindingTest ----------------------------------------------------------- |
| 314 | 314 |
| 315 using StrongBindingTest = BindingTestBase; | 315 using StrongBindingTest = BindingTestBase; |
| 316 | 316 |
| 317 // Tests that destroying a mojo::StrongBinding closes the bound message pipe | 317 // Tests that destroying a mojo::StrongBinding closes the bound message pipe |
| 318 // handle but does *not* destroy the implementation object. | 318 // handle but does *not* destroy the implementation object. |
| 319 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { | 319 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { |
| 320 base::RunLoop run_loop; | 320 base::RunLoop run_loop; |
| 321 bool encountered_error = false; | 321 bool encountered_error = false; |
| 322 bool was_deleted = false; | 322 bool was_deleted = false; |
| 323 ServiceImpl impl(&was_deleted); | 323 ServiceImpl impl(&was_deleted); |
| 324 sample::ServicePtr ptr; | 324 sample::ServicePtr ptr; |
| 325 auto request = GetProxy(&ptr); | 325 auto request = GetProxy(&ptr); |
| 326 ptr.set_connection_error_handler( | 326 ptr.set_connection_error_handler( |
| 327 [&encountered_error, &run_loop]() { | 327 SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure())); |
| 328 encountered_error = true; | |
| 329 run_loop.Quit(); | |
| 330 }); | |
| 331 bool called = false; | 328 bool called = false; |
| 332 base::RunLoop run_loop2; | 329 base::RunLoop run_loop2; |
| 333 auto called_cb = [&called, &run_loop2](int32_t result) { | |
| 334 called = true; | |
| 335 run_loop2.Quit(); | |
| 336 }; | |
| 337 { | 330 { |
| 338 StrongBinding<sample::Service> binding(&impl, std::move(request)); | 331 StrongBinding<sample::Service> binding(&impl, std::move(request)); |
| 339 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 332 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
| 340 called_cb); | 333 SetFlagAndRunClosure<int32_t>(&called, |
| 334 run_loop2.QuitClosure())); |
| 341 run_loop2.Run(); | 335 run_loop2.Run(); |
| 342 EXPECT_TRUE(called); | 336 EXPECT_TRUE(called); |
| 343 EXPECT_FALSE(encountered_error); | 337 EXPECT_FALSE(encountered_error); |
| 344 } | 338 } |
| 345 // Now that the StrongBinding is out of scope we should detect an error on the | 339 // Now that the StrongBinding is out of scope we should detect an error on the |
| 346 // other end of the pipe. | 340 // other end of the pipe. |
| 347 run_loop.Run(); | 341 run_loop.Run(); |
| 348 EXPECT_TRUE(encountered_error); | 342 EXPECT_TRUE(encountered_error); |
| 349 // But destroying the StrongBinding doesn't destroy the object. | 343 // But destroying the StrongBinding doesn't destroy the object. |
| 350 ASSERT_FALSE(was_deleted); | 344 ASSERT_FALSE(was_deleted); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 // Tests that even when the implementation object owns the StrongBinding, that | 380 // Tests that even when the implementation object owns the StrongBinding, that |
| 387 // the implementation can still be deleted (which should result in the message | 381 // the implementation can still be deleted (which should result in the message |
| 388 // pipe being closed). Also checks that the connection error handler doesn't get | 382 // pipe being closed). Also checks that the connection error handler doesn't get |
| 389 // called. | 383 // called. |
| 390 TEST_F(StrongBindingTest, ExplicitDeleteImpl) { | 384 TEST_F(StrongBindingTest, ExplicitDeleteImpl) { |
| 391 bool ptr_error_handler_called = false; | 385 bool ptr_error_handler_called = false; |
| 392 sample::ServicePtr ptr; | 386 sample::ServicePtr ptr; |
| 393 auto request = GetProxy(&ptr); | 387 auto request = GetProxy(&ptr); |
| 394 base::RunLoop run_loop; | 388 base::RunLoop run_loop; |
| 395 ptr.set_connection_error_handler( | 389 ptr.set_connection_error_handler( |
| 396 [&ptr_error_handler_called, &run_loop]() { | 390 SetFlagAndRunClosure(&ptr_error_handler_called, run_loop.QuitClosure())); |
| 397 ptr_error_handler_called = true; | |
| 398 run_loop.Quit(); | |
| 399 }); | |
| 400 bool was_deleted = false; | 391 bool was_deleted = false; |
| 401 ServiceImplWithStrongBinding* impl = | 392 ServiceImplWithStrongBinding* impl = |
| 402 new ServiceImplWithStrongBinding(&was_deleted, std::move(request)); | 393 new ServiceImplWithStrongBinding(&was_deleted, std::move(request)); |
| 403 bool binding_error_handler_called = false; | 394 bool binding_error_handler_called = false; |
| 404 impl->binding().set_connection_error_handler( | 395 impl->binding().set_connection_error_handler( |
| 405 [&binding_error_handler_called]() { | 396 SetFlagAndRunClosure(&binding_error_handler_called)); |
| 406 binding_error_handler_called = true; | |
| 407 }); | |
| 408 | 397 |
| 409 loop().RunUntilIdle(); | 398 loop().RunUntilIdle(); |
| 410 EXPECT_FALSE(ptr_error_handler_called); | 399 EXPECT_FALSE(ptr_error_handler_called); |
| 411 EXPECT_FALSE(was_deleted); | 400 EXPECT_FALSE(was_deleted); |
| 412 | 401 |
| 413 delete impl; | 402 delete impl; |
| 414 EXPECT_FALSE(ptr_error_handler_called); | 403 EXPECT_FALSE(ptr_error_handler_called); |
| 415 EXPECT_TRUE(was_deleted); | 404 EXPECT_TRUE(was_deleted); |
| 416 was_deleted = false; // It shouldn't be double-deleted! | 405 was_deleted = false; // It shouldn't be double-deleted! |
| 417 run_loop.Run(); | 406 run_loop.Run(); |
| 418 EXPECT_TRUE(ptr_error_handler_called); | 407 EXPECT_TRUE(ptr_error_handler_called); |
| 419 EXPECT_FALSE(was_deleted); | 408 EXPECT_FALSE(was_deleted); |
| 420 | 409 |
| 421 EXPECT_FALSE(binding_error_handler_called); | 410 EXPECT_FALSE(binding_error_handler_called); |
| 422 } | 411 } |
| 423 | 412 |
| 424 } // namespace | 413 } // namespace |
| 425 } // mojo | 414 } // mojo |
| OLD | NEW |