| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <string> | 6 #include <string> |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/run_loop.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 13 #include "base/test/test_timeouts.h" | 14 #include "base/test/test_timeouts.h" |
| 14 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 15 #include "base/threading/thread_restrictions.h" | 16 #include "base/threading/thread_restrictions.h" |
| 16 #include "dbus/bus.h" | 17 #include "dbus/bus.h" |
| 17 #include "dbus/message.h" | 18 #include "dbus/message.h" |
| 18 #include "dbus/object_path.h" | 19 #include "dbus/object_path.h" |
| 19 #include "dbus/object_proxy.h" | 20 #include "dbus/object_proxy.h" |
| 20 #include "dbus/test_service.h" | 21 #include "dbus/test_service.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 // Connect to the "Test" signal of "org.chromium.TestInterface" from | 71 // Connect to the "Test" signal of "org.chromium.TestInterface" from |
| 71 // the remote object. | 72 // the remote object. |
| 72 object_proxy_->ConnectToSignal( | 73 object_proxy_->ConnectToSignal( |
| 73 "org.chromium.TestInterface", | 74 "org.chromium.TestInterface", |
| 74 "Test", | 75 "Test", |
| 75 base::Bind(&EndToEndAsyncTest::OnTestSignal, | 76 base::Bind(&EndToEndAsyncTest::OnTestSignal, |
| 76 base::Unretained(this)), | 77 base::Unretained(this)), |
| 77 base::Bind(&EndToEndAsyncTest::OnConnected, | 78 base::Bind(&EndToEndAsyncTest::OnConnected, |
| 78 base::Unretained(this))); | 79 base::Unretained(this))); |
| 79 // Wait until the object proxy is connected to the signal. | 80 // Wait until the object proxy is connected to the signal. |
| 80 message_loop_.Run(); | 81 run_loop_.reset(new base::RunLoop()); |
| 82 run_loop_->Run(); |
| 81 | 83 |
| 82 // Connect to the "Test2" signal of "org.chromium.TestInterface" from | 84 // Connect to the "Test2" signal of "org.chromium.TestInterface" from |
| 83 // the remote object. There was a bug where we were emitting error | 85 // the remote object. There was a bug where we were emitting error |
| 84 // messages like "Requested to remove an unknown match rule: ..." at | 86 // messages like "Requested to remove an unknown match rule: ..." at |
| 85 // the shutdown of Bus when an object proxy is connected to more than | 87 // the shutdown of Bus when an object proxy is connected to more than |
| 86 // one signal of the same interface. See crosbug.com/23382 for details. | 88 // one signal of the same interface. See crosbug.com/23382 for details. |
| 87 object_proxy_->ConnectToSignal( | 89 object_proxy_->ConnectToSignal( |
| 88 "org.chromium.TestInterface", | 90 "org.chromium.TestInterface", |
| 89 "Test2", | 91 "Test2", |
| 90 base::Bind(&EndToEndAsyncTest::OnTest2Signal, | 92 base::Bind(&EndToEndAsyncTest::OnTest2Signal, |
| 91 base::Unretained(this)), | 93 base::Unretained(this)), |
| 92 base::Bind(&EndToEndAsyncTest::OnConnected, | 94 base::Bind(&EndToEndAsyncTest::OnConnected, |
| 93 base::Unretained(this))); | 95 base::Unretained(this))); |
| 94 // Wait until the object proxy is connected to the signal. | 96 // Wait until the object proxy is connected to the signal. |
| 95 message_loop_.Run(); | 97 run_loop_.reset(new base::RunLoop()); |
| 98 run_loop_->Run(); |
| 96 | 99 |
| 97 // Create a second object proxy for the root object. | 100 // Create a second object proxy for the root object. |
| 98 root_object_proxy_ = bus_->GetObjectProxy("org.chromium.TestService", | 101 root_object_proxy_ = bus_->GetObjectProxy("org.chromium.TestService", |
| 99 ObjectPath("/")); | 102 ObjectPath("/")); |
| 100 ASSERT_TRUE(bus_->HasDBusThread()); | 103 ASSERT_TRUE(bus_->HasDBusThread()); |
| 101 | 104 |
| 102 // Connect to the "Test" signal of "org.chromium.TestInterface" from | 105 // Connect to the "Test" signal of "org.chromium.TestInterface" from |
| 103 // the root remote object too. | 106 // the root remote object too. |
| 104 root_object_proxy_->ConnectToSignal( | 107 root_object_proxy_->ConnectToSignal( |
| 105 "org.chromium.TestInterface", | 108 "org.chromium.TestInterface", |
| 106 "Test", | 109 "Test", |
| 107 base::Bind(&EndToEndAsyncTest::OnRootTestSignal, | 110 base::Bind(&EndToEndAsyncTest::OnRootTestSignal, |
| 108 base::Unretained(this)), | 111 base::Unretained(this)), |
| 109 base::Bind(&EndToEndAsyncTest::OnConnected, | 112 base::Bind(&EndToEndAsyncTest::OnConnected, |
| 110 base::Unretained(this))); | 113 base::Unretained(this))); |
| 111 // Wait until the root object proxy is connected to the signal. | 114 // Wait until the root object proxy is connected to the signal. |
| 112 message_loop_.Run(); | 115 run_loop_.reset(new base::RunLoop()); |
| 116 run_loop_->Run(); |
| 113 } | 117 } |
| 114 | 118 |
| 115 virtual void TearDown() { | 119 virtual void TearDown() { |
| 116 bus_->ShutdownOnDBusThreadAndBlock(); | 120 bus_->ShutdownOnDBusThreadAndBlock(); |
| 117 | 121 |
| 118 // Shut down the service. | 122 // Shut down the service. |
| 119 test_service_->ShutdownAndBlock(); | 123 test_service_->ShutdownAndBlock(); |
| 120 | 124 |
| 121 // Reset to the default. | 125 // Reset to the default. |
| 122 base::ThreadRestrictions::SetIOAllowed(true); | 126 base::ThreadRestrictions::SetIOAllowed(true); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 object_proxy_->CallMethodWithErrorCallback( | 169 object_proxy_->CallMethodWithErrorCallback( |
| 166 method_call, | 170 method_call, |
| 167 timeout_ms, | 171 timeout_ms, |
| 168 base::Bind(&EndToEndAsyncTest::OnResponse, base::Unretained(this)), | 172 base::Bind(&EndToEndAsyncTest::OnResponse, base::Unretained(this)), |
| 169 base::Bind(&EndToEndAsyncTest::OnError, base::Unretained(this))); | 173 base::Bind(&EndToEndAsyncTest::OnError, base::Unretained(this))); |
| 170 } | 174 } |
| 171 | 175 |
| 172 // Wait for the give number of responses. | 176 // Wait for the give number of responses. |
| 173 void WaitForResponses(size_t num_responses) { | 177 void WaitForResponses(size_t num_responses) { |
| 174 while (response_strings_.size() < num_responses) { | 178 while (response_strings_.size() < num_responses) { |
| 175 message_loop_.Run(); | 179 run_loop_.reset(new base::RunLoop); |
| 180 run_loop_->Run(); |
| 176 } | 181 } |
| 177 } | 182 } |
| 178 | 183 |
| 179 // Called when the response is received. | 184 // Called when the response is received. |
| 180 void OnResponse(Response* response) { | 185 void OnResponse(Response* response) { |
| 181 // |response| will be deleted on exit of the function. Copy the | 186 // |response| will be deleted on exit of the function. Copy the |
| 182 // payload to |response_strings_|. | 187 // payload to |response_strings_|. |
| 183 if (response) { | 188 if (response) { |
| 184 MessageReader reader(response); | 189 MessageReader reader(response); |
| 185 std::string response_string; | 190 std::string response_string; |
| 186 ASSERT_TRUE(reader.PopString(&response_string)); | 191 ASSERT_TRUE(reader.PopString(&response_string)); |
| 187 response_strings_.push_back(response_string); | 192 response_strings_.push_back(response_string); |
| 188 } else { | 193 } else { |
| 189 response_strings_.push_back(std::string()); | 194 response_strings_.push_back(std::string()); |
| 190 } | 195 } |
| 191 message_loop_.Quit(); | 196 run_loop_->Quit(); |
| 192 }; | 197 }; |
| 193 | 198 |
| 194 // Wait for the given number of errors. | 199 // Wait for the given number of errors. |
| 195 void WaitForErrors(size_t num_errors) { | 200 void WaitForErrors(size_t num_errors) { |
| 196 while (error_names_.size() < num_errors) { | 201 while (error_names_.size() < num_errors) { |
| 197 message_loop_.Run(); | 202 run_loop_.reset(new base::RunLoop); |
| 203 run_loop_->Run(); |
| 198 } | 204 } |
| 199 } | 205 } |
| 200 | 206 |
| 201 // Called when an error is received. | 207 // Called when an error is received. |
| 202 void OnError(ErrorResponse* error) { | 208 void OnError(ErrorResponse* error) { |
| 203 // |error| will be deleted on exit of the function. Copy the payload to | 209 // |error| will be deleted on exit of the function. Copy the payload to |
| 204 // |error_names_|. | 210 // |error_names_|. |
| 205 if (error) { | 211 if (error) { |
| 206 ASSERT_NE("", error->GetErrorName()); | 212 ASSERT_NE("", error->GetErrorName()); |
| 207 error_names_.push_back(error->GetErrorName()); | 213 error_names_.push_back(error->GetErrorName()); |
| 208 } else { | 214 } else { |
| 209 error_names_.push_back(std::string()); | 215 error_names_.push_back(std::string()); |
| 210 } | 216 } |
| 211 message_loop_.Quit(); | 217 run_loop_->Quit(); |
| 212 } | 218 } |
| 213 | 219 |
| 214 // Called when the "Test" signal is received, in the main thread. | 220 // Called when the "Test" signal is received, in the main thread. |
| 215 // Copy the string payload to |test_signal_string_|. | 221 // Copy the string payload to |test_signal_string_|. |
| 216 void OnTestSignal(Signal* signal) { | 222 void OnTestSignal(Signal* signal) { |
| 217 MessageReader reader(signal); | 223 MessageReader reader(signal); |
| 218 ASSERT_TRUE(reader.PopString(&test_signal_string_)); | 224 ASSERT_TRUE(reader.PopString(&test_signal_string_)); |
| 219 message_loop_.Quit(); | 225 run_loop_->Quit(); |
| 220 } | 226 } |
| 221 | 227 |
| 222 // Called when the "Test" signal is received, in the main thread, by | 228 // Called when the "Test" signal is received, in the main thread, by |
| 223 // the root object proxy. Copy the string payload to | 229 // the root object proxy. Copy the string payload to |
| 224 // |root_test_signal_string_|. | 230 // |root_test_signal_string_|. |
| 225 void OnRootTestSignal(Signal* signal) { | 231 void OnRootTestSignal(Signal* signal) { |
| 226 MessageReader reader(signal); | 232 MessageReader reader(signal); |
| 227 ASSERT_TRUE(reader.PopString(&root_test_signal_string_)); | 233 ASSERT_TRUE(reader.PopString(&root_test_signal_string_)); |
| 228 message_loop_.Quit(); | 234 run_loop_->Quit(); |
| 229 } | 235 } |
| 230 | 236 |
| 231 // Called when the "Test2" signal is received, in the main thread. | 237 // Called when the "Test2" signal is received, in the main thread. |
| 232 void OnTest2Signal(Signal* signal) { | 238 void OnTest2Signal(Signal* signal) { |
| 233 MessageReader reader(signal); | 239 MessageReader reader(signal); |
| 234 message_loop_.Quit(); | 240 run_loop_->Quit(); |
| 235 } | 241 } |
| 236 | 242 |
| 237 // Called when connected to the signal. | 243 // Called when connected to the signal. |
| 238 void OnConnected(const std::string& interface_name, | 244 void OnConnected(const std::string& interface_name, |
| 239 const std::string& signal_name, | 245 const std::string& signal_name, |
| 240 bool success) { | 246 bool success) { |
| 241 ASSERT_TRUE(success); | 247 ASSERT_TRUE(success); |
| 242 message_loop_.Quit(); | 248 run_loop_->Quit(); |
| 243 } | 249 } |
| 244 | 250 |
| 245 // Called when the connection with dbus-daemon is disconnected. | 251 // Called when the connection with dbus-daemon is disconnected. |
| 246 void OnDisconnected() { | 252 void OnDisconnected() { |
| 247 message_loop_.Quit(); | 253 run_loop_->Quit(); |
| 248 ++on_disconnected_call_count_; | 254 ++on_disconnected_call_count_; |
| 249 } | 255 } |
| 250 | 256 |
| 251 // Wait for the hey signal to be received. | 257 // Wait for the hey signal to be received. |
| 252 void WaitForTestSignal() { | 258 void WaitForTestSignal() { |
| 253 // OnTestSignal() will quit the message loop. | 259 // OnTestSignal() will quit the message loop. |
| 254 message_loop_.Run(); | 260 run_loop_.reset(new base::RunLoop); |
| 261 run_loop_->Run(); |
| 255 } | 262 } |
| 256 | 263 |
| 257 base::MessageLoop message_loop_; | 264 base::MessageLoop message_loop_; |
| 265 scoped_ptr<base::RunLoop> run_loop_; |
| 258 std::vector<std::string> response_strings_; | 266 std::vector<std::string> response_strings_; |
| 259 std::vector<std::string> error_names_; | 267 std::vector<std::string> error_names_; |
| 260 scoped_ptr<base::Thread> dbus_thread_; | 268 scoped_ptr<base::Thread> dbus_thread_; |
| 261 scoped_refptr<Bus> bus_; | 269 scoped_refptr<Bus> bus_; |
| 262 ObjectProxy* object_proxy_; | 270 ObjectProxy* object_proxy_; |
| 263 ObjectProxy* root_object_proxy_; | 271 ObjectProxy* root_object_proxy_; |
| 264 scoped_ptr<TestService> test_service_; | 272 scoped_ptr<TestService> test_service_; |
| 265 // Text message from "Test" signal. | 273 // Text message from "Test" signal. |
| 266 std::string test_signal_string_; | 274 std::string test_signal_string_; |
| 267 // Text message from "Test" signal delivered to root. | 275 // Text message from "Test" signal delivered to root. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 MethodCall method_call("org.chromium.TestInterface", "Echo"); | 538 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
| 531 MessageWriter writer(&method_call); | 539 MessageWriter writer(&method_call); |
| 532 writer.AppendString(kHello); | 540 writer.AppendString(kHello); |
| 533 | 541 |
| 534 // Call the method with an empty callback. | 542 // Call the method with an empty callback. |
| 535 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; | 543 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
| 536 object_proxy_->CallMethod(&method_call, | 544 object_proxy_->CallMethod(&method_call, |
| 537 timeout_ms, | 545 timeout_ms, |
| 538 ObjectProxy::EmptyResponseCallback()); | 546 ObjectProxy::EmptyResponseCallback()); |
| 539 // Post a delayed task to quit the message loop. | 547 // Post a delayed task to quit the message loop. |
| 548 run_loop_.reset(new base::RunLoop); |
| 540 message_loop_.PostDelayedTask(FROM_HERE, | 549 message_loop_.PostDelayedTask(FROM_HERE, |
| 541 base::MessageLoop::QuitClosure(), | 550 run_loop_->QuitClosure(), |
| 542 TestTimeouts::tiny_timeout()); | 551 TestTimeouts::tiny_timeout()); |
| 543 message_loop_.Run(); | 552 run_loop_->Run(); |
| 544 // We cannot tell if the empty callback is called, but at least we can | 553 // We cannot tell if the empty callback is called, but at least we can |
| 545 // check if the test does not crash. | 554 // check if the test does not crash. |
| 546 } | 555 } |
| 547 | 556 |
| 548 TEST_F(EndToEndAsyncTest, TestSignal) { | 557 TEST_F(EndToEndAsyncTest, TestSignal) { |
| 549 const char kMessage[] = "hello, world"; | 558 const char kMessage[] = "hello, world"; |
| 550 // Send the test signal from the exported object. | 559 // Send the test signal from the exported object. |
| 551 test_service_->SendTestSignal(kMessage); | 560 test_service_->SendTestSignal(kMessage); |
| 552 // Receive the signal with the object proxy. The signal is handled in | 561 // Receive the signal with the object proxy. The signal is handled in |
| 553 // EndToEndAsyncTest::OnTestSignal() in the main thread. | 562 // EndToEndAsyncTest::OnTestSignal() in the main thread. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 577 // This caused a DCHECK failure before. Ensure that the issue is fixed. | 586 // This caused a DCHECK failure before. Ensure that the issue is fixed. |
| 578 WaitForTestSignal(); | 587 WaitForTestSignal(); |
| 579 ASSERT_EQ(kHugeMessage, test_signal_string_); | 588 ASSERT_EQ(kHugeMessage, test_signal_string_); |
| 580 } | 589 } |
| 581 | 590 |
| 582 TEST_F(EndToEndAsyncTest, DisconnectedSignal) { | 591 TEST_F(EndToEndAsyncTest, DisconnectedSignal) { |
| 583 bus_->GetDBusTaskRunner()->PostTask(FROM_HERE, | 592 bus_->GetDBusTaskRunner()->PostTask(FROM_HERE, |
| 584 base::Bind(&Bus::ClosePrivateConnection, | 593 base::Bind(&Bus::ClosePrivateConnection, |
| 585 base::Unretained(bus_.get()))); | 594 base::Unretained(bus_.get()))); |
| 586 // OnDisconnected callback quits message loop. | 595 // OnDisconnected callback quits message loop. |
| 587 message_loop_.Run(); | 596 run_loop_.reset(new base::RunLoop); |
| 597 run_loop_->Run(); |
| 588 EXPECT_EQ(1, on_disconnected_call_count_); | 598 EXPECT_EQ(1, on_disconnected_call_count_); |
| 589 } | 599 } |
| 590 | 600 |
| 591 class SignalMultipleHandlerTest : public EndToEndAsyncTest { | 601 class SignalMultipleHandlerTest : public EndToEndAsyncTest { |
| 592 public: | 602 public: |
| 593 SignalMultipleHandlerTest() { | 603 SignalMultipleHandlerTest() { |
| 594 } | 604 } |
| 595 | 605 |
| 596 virtual void SetUp() { | 606 virtual void SetUp() { |
| 597 // Set up base class. | 607 // Set up base class. |
| 598 EndToEndAsyncTest::SetUp(); | 608 EndToEndAsyncTest::SetUp(); |
| 599 | 609 |
| 600 // Connect the root object proxy's signal handler to a new handler | 610 // Connect the root object proxy's signal handler to a new handler |
| 601 // so that we can verify that a second call to ConnectSignal() delivers | 611 // so that we can verify that a second call to ConnectSignal() delivers |
| 602 // to both our new handler and the old. | 612 // to both our new handler and the old. |
| 603 object_proxy_->ConnectToSignal( | 613 object_proxy_->ConnectToSignal( |
| 604 "org.chromium.TestInterface", | 614 "org.chromium.TestInterface", |
| 605 "Test", | 615 "Test", |
| 606 base::Bind(&SignalMultipleHandlerTest::OnAdditionalTestSignal, | 616 base::Bind(&SignalMultipleHandlerTest::OnAdditionalTestSignal, |
| 607 base::Unretained(this)), | 617 base::Unretained(this)), |
| 608 base::Bind(&SignalMultipleHandlerTest::OnAdditionalConnected, | 618 base::Bind(&SignalMultipleHandlerTest::OnAdditionalConnected, |
| 609 base::Unretained(this))); | 619 base::Unretained(this))); |
| 610 // Wait until the object proxy is connected to the signal. | 620 // Wait until the object proxy is connected to the signal. |
| 611 message_loop_.Run(); | 621 run_loop_.reset(new base::RunLoop); |
| 622 run_loop_->Run(); |
| 612 } | 623 } |
| 613 | 624 |
| 614 protected: | 625 protected: |
| 615 // Called when the "Test" signal is received, in the main thread. | 626 // Called when the "Test" signal is received, in the main thread. |
| 616 // Copy the string payload to |additional_test_signal_string_|. | 627 // Copy the string payload to |additional_test_signal_string_|. |
| 617 void OnAdditionalTestSignal(Signal* signal) { | 628 void OnAdditionalTestSignal(Signal* signal) { |
| 618 MessageReader reader(signal); | 629 MessageReader reader(signal); |
| 619 ASSERT_TRUE(reader.PopString(&additional_test_signal_string_)); | 630 ASSERT_TRUE(reader.PopString(&additional_test_signal_string_)); |
| 620 message_loop_.Quit(); | 631 run_loop_->Quit(); |
| 621 } | 632 } |
| 622 | 633 |
| 623 // Called when connected to the signal. | 634 // Called when connected to the signal. |
| 624 void OnAdditionalConnected(const std::string& interface_name, | 635 void OnAdditionalConnected(const std::string& interface_name, |
| 625 const std::string& signal_name, | 636 const std::string& signal_name, |
| 626 bool success) { | 637 bool success) { |
| 627 ASSERT_TRUE(success); | 638 ASSERT_TRUE(success); |
| 628 message_loop_.Quit(); | 639 run_loop_->Quit(); |
| 629 } | 640 } |
| 630 | 641 |
| 631 // Text message from "Test" signal delivered to additional handler. | 642 // Text message from "Test" signal delivered to additional handler. |
| 632 std::string additional_test_signal_string_; | 643 std::string additional_test_signal_string_; |
| 633 }; | 644 }; |
| 634 | 645 |
| 635 TEST_F(SignalMultipleHandlerTest, TestMultipleHandlers) { | 646 TEST_F(SignalMultipleHandlerTest, TestMultipleHandlers) { |
| 636 const char kMessage[] = "hello, world"; | 647 const char kMessage[] = "hello, world"; |
| 637 // Send the test signal from the exported object. | 648 // Send the test signal from the exported object. |
| 638 test_service_->SendTestSignal(kMessage); | 649 test_service_->SendTestSignal(kMessage); |
| 639 // Receive the signal with the object proxy. | 650 // Receive the signal with the object proxy. |
| 640 WaitForTestSignal(); | 651 WaitForTestSignal(); |
| 641 // Verify the string WAS received by the original handler. | 652 // Verify the string WAS received by the original handler. |
| 642 ASSERT_EQ(kMessage, test_signal_string_); | 653 ASSERT_EQ(kMessage, test_signal_string_); |
| 643 // Verify the signal WAS ALSO received by the additional handler. | 654 // Verify the signal WAS ALSO received by the additional handler. |
| 644 ASSERT_EQ(kMessage, additional_test_signal_string_); | 655 ASSERT_EQ(kMessage, additional_test_signal_string_); |
| 645 } | 656 } |
| 646 | 657 |
| 647 } // namespace dbus | 658 } // namespace dbus |
| OLD | NEW |