15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/run_loop.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/exported_object.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/scoped_dbus_error.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "dbus/test_service.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace dbus { 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to test AddFilterFunction(). 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DBusHandlerResult DummyHandler(DBusConnection* connection, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* raw_message, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* user_data) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test helper for BusTest.ListenForServiceOwnerChange that wraps a 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// base::RunLoop. At Run() time, the caller pass in the expected number of 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// quit calls, and at QuitIfConditionIsSatisified() time, only quit the RunLoop 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// if the expected number of quit calls have been reached. 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class RunLoopWithExpectedCount { 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RunLoopWithExpectedCount() : expected_quit_calls_(0), actual_quit_calls_(0) {} 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ~RunLoopWithExpectedCount() {} 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void Run(int expected_quit_calls) { 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(0, expected_quit_calls_); 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(0, actual_quit_calls_); 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) expected_quit_calls_ = expected_quit_calls; 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop_.reset(new base::RunLoop()); 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop_->Run(); 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void QuitIfConditionIsSatisified() { 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (++actual_quit_calls_ != expected_quit_calls_) 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop_->Quit(); 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) expected_quit_calls_ = 0; 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) actual_quit_calls_ = 0; 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::RunLoop> run_loop_; 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int expected_quit_calls_; 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int actual_quit_calls_; 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RunLoopWithExpectedCount); 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test helper for BusTest.ListenForServiceOwnerChange. 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void OnServiceOwnerChanged(RunLoopWithExpectedCount* run_loop_state, 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string* service_owner, 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int* num_of_owner_changes, 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& new_service_owner) { 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *service_owner = new_service_owner; 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++(*num_of_owner_changes); 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop_state->QuitIfConditionIsSatisified(); 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BusTest, GetObjectProxy) { 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy* object_proxy1 = 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->GetObjectProxy("org.chromium.TestService", 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/TestObject")); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy1); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should return the same object. 867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy* object_proxy2 = 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->GetObjectProxy("org.chromium.TestService", 887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/TestObject")); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy2); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(object_proxy1, object_proxy2); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should not. 937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy* object_proxy3 = 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->GetObjectProxy( 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "org.chromium.TestService", 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/DifferentTestObject")); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy3); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(object_proxy1, object_proxy3); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->ShutdownAndBlock(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BusTest, GetObjectProxyIgnoreUnknownService) { 1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy* object_proxy1 = 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->GetObjectProxyWithOptions( 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "org.chromium.TestService", 1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/TestObject"), 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy1); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should return the same object. 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy* object_proxy2 = 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->GetObjectProxyWithOptions( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "org.chromium.TestService", 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/TestObject"), 1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy2); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(object_proxy1, object_proxy2); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should not. 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy* object_proxy3 = 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->GetObjectProxyWithOptions( 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "org.chromium.TestService", 1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/DifferentTestObject"), 1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy3); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(object_proxy1, object_proxy3); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->ShutdownAndBlock(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BusTest, RemoveObjectProxy) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setup the current thread's MessageLoop. 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop message_loop; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start the D-Bus thread. 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Thread::Options thread_options; 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) thread_options.message_loop_type = base::MessageLoop::TYPE_IO; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Thread dbus_thread("D-Bus thread"); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus_thread.StartWithOptions(thread_options); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create the bus. 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options.dbus_task_runner = dbus_thread.message_loop_proxy(); 1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(bus->shutdown_completed()); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Try to remove a non existant object proxy should return false. 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE( 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->RemoveObjectProxy("org.chromium.TestService", 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/TestObject"), 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&base::DoNothing))); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy* object_proxy1 = 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->GetObjectProxy("org.chromium.TestService", 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/TestObject")); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(object_proxy1); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Increment the reference count to the object proxy to avoid destroying it 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // while removing the object. 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_proxy1->AddRef(); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Remove the object from the bus. This will invalidate any other usage of 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // object_proxy1 other than destroy it. We keep this object for a comparison 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // at a later time. 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE( 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->RemoveObjectProxy("org.chromium.TestService", 1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/TestObject"), 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&base::DoNothing))); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should return a different object because the first object was removed 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from the bus, but not deleted from memory. 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectProxy* object_proxy2 = 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->GetObjectProxy("org.chromium.TestService", 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/TestObject")); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(object_proxy2); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compare the new object with the first object. The first object still exists 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // thanks to the increased reference. 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_NE(object_proxy1, object_proxy2); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release object_proxy1. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_proxy1->Release(); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Shut down synchronously. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->ShutdownOnDBusThreadAndBlock(); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(bus->shutdown_completed()); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus_thread.Stop(); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BusTest, GetExportedObject) { 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExportedObject* object_proxy1 = 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bus->GetExportedObject(ObjectPath("/org/chromium/TestObject")); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy1); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should return the same object. 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExportedObject* object_proxy2 = 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bus->GetExportedObject(ObjectPath("/org/chromium/TestObject")); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy2); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(object_proxy1, object_proxy2); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should not. 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExportedObject* object_proxy3 = 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->GetExportedObject( 2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ObjectPath("/org/chromium/DifferentTestObject")); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy3); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(object_proxy1, object_proxy3); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->ShutdownAndBlock(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BusTest, UnregisterExportedObject) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the D-Bus thread. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options thread_options; 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) thread_options.message_loop_type = base::MessageLoop::TYPE_IO; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread dbus_thread("D-Bus thread"); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_thread.StartWithOptions(thread_options); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the bus. 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options.dbus_task_runner = dbus_thread.message_loop_proxy(); 2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bus->shutdown_completed()); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExportedObject* object_proxy1 = 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bus->GetExportedObject(ObjectPath("/org/chromium/TestObject")); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy1); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Increment the reference count to the object proxy to avoid destroying it 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // calling UnregisterExportedObject. This ensures the dbus::ExportedObject is 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not freed from memory. See http://crbug.com/137846 for details. 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_proxy1->AddRef(); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bus->UnregisterExportedObject(ObjectPath("/org/chromium/TestObject")); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should return a new object because the object_proxy1 is still in 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // alloc'ed memory. 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExportedObject* object_proxy2 = 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bus->GetExportedObject(ObjectPath("/org/chromium/TestObject")); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_proxy2); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(object_proxy1, object_proxy2); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release the incremented reference. 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_proxy1->Release(); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shut down synchronously. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->ShutdownOnDBusThreadAndBlock(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(bus->shutdown_completed()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_thread.Stop(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BusTest, ShutdownAndBlock) { 2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bus->shutdown_completed()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shut down synchronously. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->ShutdownAndBlock(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(bus->shutdown_completed()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BusTest, ShutdownAndBlockWithDBusThread) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the D-Bus thread. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options thread_options; 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) thread_options.message_loop_type = base::MessageLoop::TYPE_IO; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread dbus_thread("D-Bus thread"); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_thread.StartWithOptions(thread_options); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the bus. 2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options.dbus_task_runner = dbus_thread.message_loop_proxy(); 2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bus->shutdown_completed()); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shut down synchronously. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->ShutdownOnDBusThreadAndBlock(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(bus->shutdown_completed()); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_thread.Stop(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BusTest, AddFilterFunction) { 2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should connect before calling AddFilterFunction(). 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->Connect(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data1 = 100; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data2 = 200; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data1)); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cannot add the same function with the same data. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bus->AddFilterFunction(&DummyHandler, &data1)); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Can add the same function with different data. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data2)); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data1)); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bus->RemoveFilterFunction(&DummyHandler, &data1)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data2)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->ShutdownAndBlock(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BusTest, DoubleAddAndRemoveMatch) { 3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options options; 3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(options); 3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ScopedDBusError error; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->Connect(); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Adds the same rule twice. 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->AddMatch( 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "type='signal',interface='org.chromium.TestService',path='/'", 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error.get()); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(error.is_set()); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->AddMatch( 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "type='signal',interface='org.chromium.TestService',path='/'", 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error.get()); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(error.is_set()); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Removes the same rule twice. 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(bus->RemoveMatch( 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "type='signal',interface='org.chromium.TestService',path='/'", 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error.get())); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(error.is_set()); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The rule should be still in the bus since it was removed only once. 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A second removal shouldn't give an error. 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(bus->RemoveMatch( 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "type='signal',interface='org.chromium.TestService',path='/'", 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error.get())); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(error.is_set()); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A third attemp to remove the same rule should fail. 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(bus->RemoveMatch( 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "type='signal',interface='org.chromium.TestService',path='/'", 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error.get())); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus->ShutdownAndBlock(); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(BusTest, ListenForServiceOwnerChange) { 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Setup the current thread's MessageLoop. Must be of TYPE_IO for the 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // listeners to work. 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RunLoopWithExpectedCount run_loop_state; 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Create the bus. 3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::Options bus_options; 3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<Bus> bus = new Bus(bus_options); 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Add a listener. 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string service_owner1; 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int num_of_owner_changes1 = 0; 3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::GetServiceOwnerCallback callback1 = 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&OnServiceOwnerChanged, 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &run_loop_state, 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &service_owner1, 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &num_of_owner_changes1); 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1); 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This should be a no-op. 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1); 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Nothing has happened yet. Check initial state. 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(service_owner1.empty()); 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(0, num_of_owner_changes1); 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Make an ownership change. 375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(bus->RequestOwnershipAndBlock("org.chromium.TestService", 376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Bus::REQUIRE_PRIMARY)); 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop_state.Run(1); 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { 380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Get the current service owner and check to make sure the listener got 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the right value. 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string current_service_owner = 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bus->GetServiceOwnerAndBlock("org.chromium.TestService", 3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::REPORT_ERRORS); 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_FALSE(current_service_owner.empty()); 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Make sure the listener heard about the new owner. 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(current_service_owner, service_owner1); 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Test the second ListenForServiceOwnerChange() above is indeed a no-op. 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(1, num_of_owner_changes1); 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Add a second listener. 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string service_owner2; 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int num_of_owner_changes2 = 0; 3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Bus::GetServiceOwnerCallback callback2 = 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&OnServiceOwnerChanged, 399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &run_loop_state, 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &service_owner2, 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &num_of_owner_changes2); 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bus->ListenForServiceOwnerChange("org.chromium.TestService", callback2); 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Release the ownership and make sure the service owner listeners fire with 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the right values and the right number of times. 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(bus->ReleaseOwnership("org.chromium.TestService")); 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) run_loop_state.Run(2); 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(service_owner1.empty()); 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(service_owner2.empty()); 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(2, num_of_owner_changes1); 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(1, num_of_owner_changes2); 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Unlisten so shutdown can proceed correctly. 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback1); 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback2); 418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Shut down synchronously. 421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bus->ShutdownAndBlock(); 422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(bus->shutdown_completed()); 423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace dbus 426