blob: f00d1e9374014c252c1d4b1a72879a1743d51216 [file] [log] [blame]
adamk@chromium.org35c0eef2012-02-11 06:45:23 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "dbus/bus.h"
6
satorux@chromium.orgd336d452011-09-02 15:56:23 +09007#include "base/bind.h"
Peter Kasting88430fa2018-02-13 15:22:40 +09008#include "base/bind_helpers.h"
fdorayc4aba522017-04-18 22:40:21 +09009#include "base/files/file_descriptor_watcher_posix.h"
avi0ad0ce02015-12-23 03:12:45 +090010#include "base/macros.h"
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090011#include "base/memory/ref_counted.h"
avi@chromium.orga29af562013-07-18 08:00:30 +090012#include "base/message_loop/message_loop.h"
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090013#include "base/run_loop.h"
satorux@chromium.orgd336d452011-09-02 15:56:23 +090014#include "base/threading/thread.h"
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090015#include "dbus/exported_object.h"
keybuk@google.combf4649a2012-02-15 06:29:06 +090016#include "dbus/object_path.h"
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090017#include "dbus/object_proxy.h"
deymo@chromium.org7894ebf2013-01-31 15:08:02 +090018#include "dbus/scoped_dbus_error.h"
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090019#include "dbus/test_service.h"
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090020
21#include "testing/gtest/include/gtest/gtest.h"
22
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090023namespace dbus {
24
satorux@chromium.org66bc4c22011-10-06 09:20:53 +090025namespace {
26
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090027// Test helper for BusTest.ListenForServiceOwnerChange that wraps a
28// base::RunLoop. At Run() time, the caller pass in the expected number of
29// quit calls, and at QuitIfConditionIsSatisified() time, only quit the RunLoop
30// if the expected number of quit calls have been reached.
31class RunLoopWithExpectedCount {
32 public:
33 RunLoopWithExpectedCount() : expected_quit_calls_(0), actual_quit_calls_(0) {}
Chris Watkins635e8902017-11-29 16:44:11 +090034 ~RunLoopWithExpectedCount() = default;
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090035
36 void Run(int expected_quit_calls) {
37 DCHECK_EQ(0, expected_quit_calls_);
38 DCHECK_EQ(0, actual_quit_calls_);
39 expected_quit_calls_ = expected_quit_calls;
40 run_loop_.reset(new base::RunLoop());
41 run_loop_->Run();
42 }
43
44 void QuitIfConditionIsSatisified() {
45 if (++actual_quit_calls_ != expected_quit_calls_)
46 return;
47 run_loop_->Quit();
48 expected_quit_calls_ = 0;
49 actual_quit_calls_ = 0;
50 }
51
52 private:
dcheng30c5a172016-04-09 07:55:04 +090053 std::unique_ptr<base::RunLoop> run_loop_;
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090054 int expected_quit_calls_;
55 int actual_quit_calls_;
56
57 DISALLOW_COPY_AND_ASSIGN(RunLoopWithExpectedCount);
58};
59
60// Test helper for BusTest.ListenForServiceOwnerChange.
61void OnServiceOwnerChanged(RunLoopWithExpectedCount* run_loop_state,
62 std::string* service_owner,
63 int* num_of_owner_changes,
64 const std::string& new_service_owner) {
65 *service_owner = new_service_owner;
66 ++(*num_of_owner_changes);
67 run_loop_state->QuitIfConditionIsSatisified();
68}
69
satorux@chromium.org66bc4c22011-10-06 09:20:53 +090070} // namespace
71
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090072TEST(BusTest, GetObjectProxy) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090073 Bus::Options options;
74 scoped_refptr<Bus> bus = new Bus(options);
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090075
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090076 ObjectProxy* object_proxy1 =
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090077 bus->GetObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090078 ObjectPath("/org/chromium/TestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090079 ASSERT_TRUE(object_proxy1);
80
81 // This should return the same object.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090082 ObjectProxy* object_proxy2 =
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090083 bus->GetObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090084 ObjectPath("/org/chromium/TestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090085 ASSERT_TRUE(object_proxy2);
86 EXPECT_EQ(object_proxy1, object_proxy2);
87
88 // This should not.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090089 ObjectProxy* object_proxy3 =
keybuk@google.combf4649a2012-02-15 06:29:06 +090090 bus->GetObjectProxy(
91 "org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090092 ObjectPath("/org/chromium/DifferentTestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090093 ASSERT_TRUE(object_proxy3);
94 EXPECT_NE(object_proxy1, object_proxy3);
satorux@chromium.orgf06eb892011-10-13 09:45:26 +090095
96 bus->ShutdownAndBlock();
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090097}
98
adamk@chromium.org35c0eef2012-02-11 06:45:23 +090099TEST(BusTest, GetObjectProxyIgnoreUnknownService) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900100 Bus::Options options;
101 scoped_refptr<Bus> bus = new Bus(options);
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900102
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900103 ObjectProxy* object_proxy1 =
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900104 bus->GetObjectProxyWithOptions(
105 "org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900106 ObjectPath("/org/chromium/TestObject"),
107 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900108 ASSERT_TRUE(object_proxy1);
109
110 // This should return the same object.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900111 ObjectProxy* object_proxy2 =
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900112 bus->GetObjectProxyWithOptions(
113 "org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900114 ObjectPath("/org/chromium/TestObject"),
115 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900116 ASSERT_TRUE(object_proxy2);
117 EXPECT_EQ(object_proxy1, object_proxy2);
118
119 // This should not.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900120 ObjectProxy* object_proxy3 =
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900121 bus->GetObjectProxyWithOptions(
122 "org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900123 ObjectPath("/org/chromium/DifferentTestObject"),
124 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900125 ASSERT_TRUE(object_proxy3);
126 EXPECT_NE(object_proxy1, object_proxy3);
127
128 bus->ShutdownAndBlock();
129}
130
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900131TEST(BusTest, RemoveObjectProxy) {
132 // Setup the current thread's MessageLoop.
xhwang@chromium.orgdff6b132013-05-02 01:10:30 +0900133 base::MessageLoop message_loop;
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900134
135 // Start the D-Bus thread.
136 base::Thread::Options thread_options;
xhwang@chromium.orgdff6b132013-05-02 01:10:30 +0900137 thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900138 base::Thread dbus_thread("D-Bus thread");
139 dbus_thread.StartWithOptions(thread_options);
140
141 // Create the bus.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900142 Bus::Options options;
skyostile5a8dc42015-06-18 00:46:04 +0900143 options.dbus_task_runner = dbus_thread.task_runner();
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900144 scoped_refptr<Bus> bus = new Bus(options);
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900145 ASSERT_FALSE(bus->shutdown_completed());
146
147 // Try to remove a non existant object proxy should return false.
Peter Kasting24efe5e2018-02-24 09:03:01 +0900148 ASSERT_FALSE(bus->RemoveObjectProxy("org.chromium.TestService",
149 ObjectPath("/org/chromium/TestObject"),
150 base::DoNothing()));
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900151
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900152 ObjectProxy* object_proxy1 =
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900153 bus->GetObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900154 ObjectPath("/org/chromium/TestObject"));
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900155 ASSERT_TRUE(object_proxy1);
156
157 // Increment the reference count to the object proxy to avoid destroying it
158 // while removing the object.
159 object_proxy1->AddRef();
160
161 // Remove the object from the bus. This will invalidate any other usage of
162 // object_proxy1 other than destroy it. We keep this object for a comparison
163 // at a later time.
Peter Kasting24efe5e2018-02-24 09:03:01 +0900164 ASSERT_TRUE(bus->RemoveObjectProxy("org.chromium.TestService",
165 ObjectPath("/org/chromium/TestObject"),
166 base::DoNothing()));
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900167
168 // This should return a different object because the first object was removed
169 // from the bus, but not deleted from memory.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900170 ObjectProxy* object_proxy2 =
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900171 bus->GetObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900172 ObjectPath("/org/chromium/TestObject"));
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900173 ASSERT_TRUE(object_proxy2);
174
175 // Compare the new object with the first object. The first object still exists
176 // thanks to the increased reference.
177 EXPECT_NE(object_proxy1, object_proxy2);
178
179 // Release object_proxy1.
180 object_proxy1->Release();
181
182 // Shut down synchronously.
183 bus->ShutdownOnDBusThreadAndBlock();
184 EXPECT_TRUE(bus->shutdown_completed());
185 dbus_thread.Stop();
186}
187
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900188TEST(BusTest, GetExportedObject) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900189 Bus::Options options;
190 scoped_refptr<Bus> bus = new Bus(options);
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900191
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900192 ExportedObject* object_proxy1 =
193 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900194 ASSERT_TRUE(object_proxy1);
195
196 // This should return the same object.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900197 ExportedObject* object_proxy2 =
198 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900199 ASSERT_TRUE(object_proxy2);
200 EXPECT_EQ(object_proxy1, object_proxy2);
201
202 // This should not.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900203 ExportedObject* object_proxy3 =
keybuk@google.combf4649a2012-02-15 06:29:06 +0900204 bus->GetExportedObject(
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900205 ObjectPath("/org/chromium/DifferentTestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900206 ASSERT_TRUE(object_proxy3);
207 EXPECT_NE(object_proxy1, object_proxy3);
satorux@chromium.orgf06eb892011-10-13 09:45:26 +0900208
209 bus->ShutdownAndBlock();
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900210}
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900211
deymo@chromium.org03ec2482013-01-24 09:58:35 +0900212TEST(BusTest, UnregisterExportedObject) {
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900213 // Start the D-Bus thread.
214 base::Thread::Options thread_options;
xhwang@chromium.orgdff6b132013-05-02 01:10:30 +0900215 thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900216 base::Thread dbus_thread("D-Bus thread");
217 dbus_thread.StartWithOptions(thread_options);
218
219 // Create the bus.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900220 Bus::Options options;
skyostile5a8dc42015-06-18 00:46:04 +0900221 options.dbus_task_runner = dbus_thread.task_runner();
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900222 scoped_refptr<Bus> bus = new Bus(options);
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900223 ASSERT_FALSE(bus->shutdown_completed());
224
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900225 ExportedObject* object_proxy1 =
226 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900227 ASSERT_TRUE(object_proxy1);
228
deymo@chromium.org03ec2482013-01-24 09:58:35 +0900229 // Increment the reference count to the object proxy to avoid destroying it
230 // calling UnregisterExportedObject. This ensures the dbus::ExportedObject is
231 // not freed from memory. See http://crbug.com/137846 for details.
232 object_proxy1->AddRef();
233
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900234 bus->UnregisterExportedObject(ObjectPath("/org/chromium/TestObject"));
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900235
deymo@chromium.org03ec2482013-01-24 09:58:35 +0900236 // This should return a new object because the object_proxy1 is still in
237 // alloc'ed memory.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900238 ExportedObject* object_proxy2 =
239 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900240 ASSERT_TRUE(object_proxy2);
241 EXPECT_NE(object_proxy1, object_proxy2);
242
deymo@chromium.org03ec2482013-01-24 09:58:35 +0900243 // Release the incremented reference.
244 object_proxy1->Release();
245
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900246 // Shut down synchronously.
247 bus->ShutdownOnDBusThreadAndBlock();
248 EXPECT_TRUE(bus->shutdown_completed());
249 dbus_thread.Stop();
250}
251
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900252TEST(BusTest, ShutdownAndBlock) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900253 Bus::Options options;
254 scoped_refptr<Bus> bus = new Bus(options);
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900255 ASSERT_FALSE(bus->shutdown_completed());
256
257 // Shut down synchronously.
258 bus->ShutdownAndBlock();
259 EXPECT_TRUE(bus->shutdown_completed());
260}
261
262TEST(BusTest, ShutdownAndBlockWithDBusThread) {
263 // Start the D-Bus thread.
264 base::Thread::Options thread_options;
xhwang@chromium.orgdff6b132013-05-02 01:10:30 +0900265 thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900266 base::Thread dbus_thread("D-Bus thread");
267 dbus_thread.StartWithOptions(thread_options);
268
269 // Create the bus.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900270 Bus::Options options;
skyostile5a8dc42015-06-18 00:46:04 +0900271 options.dbus_task_runner = dbus_thread.task_runner();
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900272 scoped_refptr<Bus> bus = new Bus(options);
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900273 ASSERT_FALSE(bus->shutdown_completed());
274
275 // Shut down synchronously.
276 bus->ShutdownOnDBusThreadAndBlock();
277 EXPECT_TRUE(bus->shutdown_completed());
278 dbus_thread.Stop();
279}
satorux@chromium.org66bc4c22011-10-06 09:20:53 +0900280
deymo@chromium.org7894ebf2013-01-31 15:08:02 +0900281TEST(BusTest, DoubleAddAndRemoveMatch) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900282 Bus::Options options;
283 scoped_refptr<Bus> bus = new Bus(options);
284 ScopedDBusError error;
deymo@chromium.org7894ebf2013-01-31 15:08:02 +0900285
286 bus->Connect();
287
288 // Adds the same rule twice.
289 bus->AddMatch(
290 "type='signal',interface='org.chromium.TestService',path='/'",
291 error.get());
292 ASSERT_FALSE(error.is_set());
293
294 bus->AddMatch(
295 "type='signal',interface='org.chromium.TestService',path='/'",
296 error.get());
297 ASSERT_FALSE(error.is_set());
298
299 // Removes the same rule twice.
300 ASSERT_TRUE(bus->RemoveMatch(
301 "type='signal',interface='org.chromium.TestService',path='/'",
302 error.get()));
303 ASSERT_FALSE(error.is_set());
304
305 // The rule should be still in the bus since it was removed only once.
306 // A second removal shouldn't give an error.
307 ASSERT_TRUE(bus->RemoveMatch(
308 "type='signal',interface='org.chromium.TestService',path='/'",
309 error.get()));
310 ASSERT_FALSE(error.is_set());
311
312 // A third attemp to remove the same rule should fail.
313 ASSERT_FALSE(bus->RemoveMatch(
314 "type='signal',interface='org.chromium.TestService',path='/'",
315 error.get()));
316
317 bus->ShutdownAndBlock();
318}
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900319
320TEST(BusTest, ListenForServiceOwnerChange) {
fdorayc4aba522017-04-18 22:40:21 +0900321 base::MessageLoopForIO message_loop;
322
323 // This enables FileDescriptorWatcher, which is required by dbus::Watch.
324 base::FileDescriptorWatcher file_descriptor_watcher(&message_loop);
325
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900326 RunLoopWithExpectedCount run_loop_state;
327
328 // Create the bus.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900329 Bus::Options bus_options;
330 scoped_refptr<Bus> bus = new Bus(bus_options);
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900331
332 // Add a listener.
333 std::string service_owner1;
334 int num_of_owner_changes1 = 0;
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900335 Bus::GetServiceOwnerCallback callback1 =
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900336 base::Bind(&OnServiceOwnerChanged,
337 &run_loop_state,
338 &service_owner1,
339 &num_of_owner_changes1);
340 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1);
341 // This should be a no-op.
342 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1);
343 base::RunLoop().RunUntilIdle();
344
345 // Nothing has happened yet. Check initial state.
346 EXPECT_TRUE(service_owner1.empty());
347 EXPECT_EQ(0, num_of_owner_changes1);
348
349 // Make an ownership change.
cmasone@chromium.org989857e2013-07-31 15:34:59 +0900350 ASSERT_TRUE(bus->RequestOwnershipAndBlock("org.chromium.TestService",
351 Bus::REQUIRE_PRIMARY));
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900352 run_loop_state.Run(1);
353
354 {
355 // Get the current service owner and check to make sure the listener got
356 // the right value.
357 std::string current_service_owner =
358 bus->GetServiceOwnerAndBlock("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900359 Bus::REPORT_ERRORS);
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900360 ASSERT_FALSE(current_service_owner.empty());
361
362 // Make sure the listener heard about the new owner.
363 EXPECT_EQ(current_service_owner, service_owner1);
364
365 // Test the second ListenForServiceOwnerChange() above is indeed a no-op.
366 EXPECT_EQ(1, num_of_owner_changes1);
367 }
368
369 // Add a second listener.
370 std::string service_owner2;
371 int num_of_owner_changes2 = 0;
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900372 Bus::GetServiceOwnerCallback callback2 =
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900373 base::Bind(&OnServiceOwnerChanged,
374 &run_loop_state,
375 &service_owner2,
376 &num_of_owner_changes2);
377 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback2);
378 base::RunLoop().RunUntilIdle();
379
380 // Release the ownership and make sure the service owner listeners fire with
381 // the right values and the right number of times.
382 ASSERT_TRUE(bus->ReleaseOwnership("org.chromium.TestService"));
383 run_loop_state.Run(2);
384
385 EXPECT_TRUE(service_owner1.empty());
386 EXPECT_TRUE(service_owner2.empty());
387 EXPECT_EQ(2, num_of_owner_changes1);
388 EXPECT_EQ(1, num_of_owner_changes2);
389
390 // Unlisten so shutdown can proceed correctly.
391 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback1);
392 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback2);
393 base::RunLoop().RunUntilIdle();
394
395 // Shut down synchronously.
396 bus->ShutdownAndBlock();
397 EXPECT_TRUE(bus->shutdown_completed());
398}
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900399
zqiua84d25f2015-07-08 11:08:30 +0900400TEST(BusTest, GetConnectionName) {
401 Bus::Options options;
402 scoped_refptr<Bus> bus = new Bus(options);
403
404 // Connection name is empty since bus is not connected.
405 EXPECT_FALSE(bus->is_connected());
406 EXPECT_TRUE(bus->GetConnectionName().empty());
407
408 // Connect bus to D-Bus.
409 bus->Connect();
410
411 // Connection name is not empty after connection is established.
412 EXPECT_TRUE(bus->is_connected());
413 EXPECT_FALSE(bus->GetConnectionName().empty());
414
415 // Shut down synchronously.
416 bus->ShutdownAndBlock();
417 EXPECT_TRUE(bus->shutdown_completed());
418}
419
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900420} // namespace dbus