blob: f8dfa33d065087def6618b3ffde278e474c3dbc5 [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"
fdorayc4aba522017-04-18 22:40:21 +09008#include "base/files/file_descriptor_watcher_posix.h"
avi0ad0ce02015-12-23 03:12:45 +09009#include "base/macros.h"
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090010#include "base/memory/ref_counted.h"
avi@chromium.orga29af562013-07-18 08:00:30 +090011#include "base/message_loop/message_loop.h"
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090012#include "base/run_loop.h"
satorux@chromium.orgd336d452011-09-02 15:56:23 +090013#include "base/threading/thread.h"
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090014#include "dbus/exported_object.h"
keybuk@google.combf4649a2012-02-15 06:29:06 +090015#include "dbus/object_path.h"
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090016#include "dbus/object_proxy.h"
deymo@chromium.org7894ebf2013-01-31 15:08:02 +090017#include "dbus/scoped_dbus_error.h"
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090018#include "dbus/test_service.h"
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090019
20#include "testing/gtest/include/gtest/gtest.h"
21
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090022namespace dbus {
23
satorux@chromium.org66bc4c22011-10-06 09:20:53 +090024namespace {
25
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090026// Test helper for BusTest.ListenForServiceOwnerChange that wraps a
27// base::RunLoop. At Run() time, the caller pass in the expected number of
28// quit calls, and at QuitIfConditionIsSatisified() time, only quit the RunLoop
29// if the expected number of quit calls have been reached.
30class RunLoopWithExpectedCount {
31 public:
32 RunLoopWithExpectedCount() : expected_quit_calls_(0), actual_quit_calls_(0) {}
Chris Watkins635e8902017-11-29 16:44:11 +090033 ~RunLoopWithExpectedCount() = default;
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090034
35 void Run(int expected_quit_calls) {
36 DCHECK_EQ(0, expected_quit_calls_);
37 DCHECK_EQ(0, actual_quit_calls_);
38 expected_quit_calls_ = expected_quit_calls;
39 run_loop_.reset(new base::RunLoop());
40 run_loop_->Run();
41 }
42
43 void QuitIfConditionIsSatisified() {
44 if (++actual_quit_calls_ != expected_quit_calls_)
45 return;
46 run_loop_->Quit();
47 expected_quit_calls_ = 0;
48 actual_quit_calls_ = 0;
49 }
50
51 private:
dcheng30c5a172016-04-09 07:55:04 +090052 std::unique_ptr<base::RunLoop> run_loop_;
thestig@chromium.orgc2482f12013-06-11 07:52:34 +090053 int expected_quit_calls_;
54 int actual_quit_calls_;
55
56 DISALLOW_COPY_AND_ASSIGN(RunLoopWithExpectedCount);
57};
58
59// Test helper for BusTest.ListenForServiceOwnerChange.
60void OnServiceOwnerChanged(RunLoopWithExpectedCount* run_loop_state,
61 std::string* service_owner,
62 int* num_of_owner_changes,
63 const std::string& new_service_owner) {
64 *service_owner = new_service_owner;
65 ++(*num_of_owner_changes);
66 run_loop_state->QuitIfConditionIsSatisified();
67}
68
satorux@chromium.org66bc4c22011-10-06 09:20:53 +090069} // namespace
70
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090071TEST(BusTest, GetObjectProxy) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090072 Bus::Options options;
73 scoped_refptr<Bus> bus = new Bus(options);
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090074
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090075 ObjectProxy* object_proxy1 =
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090076 bus->GetObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090077 ObjectPath("/org/chromium/TestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090078 ASSERT_TRUE(object_proxy1);
79
80 // This should return the same object.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090081 ObjectProxy* object_proxy2 =
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090082 bus->GetObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090083 ObjectPath("/org/chromium/TestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090084 ASSERT_TRUE(object_proxy2);
85 EXPECT_EQ(object_proxy1, object_proxy2);
86
87 // This should not.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090088 ObjectProxy* object_proxy3 =
keybuk@google.combf4649a2012-02-15 06:29:06 +090089 bus->GetObjectProxy(
90 "org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090091 ObjectPath("/org/chromium/DifferentTestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090092 ASSERT_TRUE(object_proxy3);
93 EXPECT_NE(object_proxy1, object_proxy3);
satorux@chromium.orgf06eb892011-10-13 09:45:26 +090094
95 bus->ShutdownAndBlock();
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +090096}
97
adamk@chromium.org35c0eef2012-02-11 06:45:23 +090098TEST(BusTest, GetObjectProxyIgnoreUnknownService) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +090099 Bus::Options options;
100 scoped_refptr<Bus> bus = new Bus(options);
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900101
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900102 ObjectProxy* object_proxy1 =
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900103 bus->GetObjectProxyWithOptions(
104 "org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900105 ObjectPath("/org/chromium/TestObject"),
106 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900107 ASSERT_TRUE(object_proxy1);
108
109 // This should return the same object.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900110 ObjectProxy* object_proxy2 =
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900111 bus->GetObjectProxyWithOptions(
112 "org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900113 ObjectPath("/org/chromium/TestObject"),
114 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900115 ASSERT_TRUE(object_proxy2);
116 EXPECT_EQ(object_proxy1, object_proxy2);
117
118 // This should not.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900119 ObjectProxy* object_proxy3 =
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900120 bus->GetObjectProxyWithOptions(
121 "org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900122 ObjectPath("/org/chromium/DifferentTestObject"),
123 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
adamk@chromium.org35c0eef2012-02-11 06:45:23 +0900124 ASSERT_TRUE(object_proxy3);
125 EXPECT_NE(object_proxy1, object_proxy3);
126
127 bus->ShutdownAndBlock();
128}
129
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900130TEST(BusTest, RemoveObjectProxy) {
131 // Setup the current thread's MessageLoop.
xhwang@chromium.orgdff6b132013-05-02 01:10:30 +0900132 base::MessageLoop message_loop;
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900133
134 // Start the D-Bus thread.
135 base::Thread::Options thread_options;
xhwang@chromium.orgdff6b132013-05-02 01:10:30 +0900136 thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900137 base::Thread dbus_thread("D-Bus thread");
138 dbus_thread.StartWithOptions(thread_options);
139
140 // Create the bus.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900141 Bus::Options options;
skyostile5a8dc42015-06-18 00:46:04 +0900142 options.dbus_task_runner = dbus_thread.task_runner();
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900143 scoped_refptr<Bus> bus = new Bus(options);
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900144 ASSERT_FALSE(bus->shutdown_completed());
145
146 // Try to remove a non existant object proxy should return false.
147 ASSERT_FALSE(
148 bus->RemoveObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900149 ObjectPath("/org/chromium/TestObject"),
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900150 base::Bind(&base::DoNothing)));
151
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.
164 ASSERT_TRUE(
165 bus->RemoveObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900166 ObjectPath("/org/chromium/TestObject"),
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900167 base::Bind(&base::DoNothing)));
168
169 // This should return a different object because the first object was removed
170 // from the bus, but not deleted from memory.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900171 ObjectProxy* object_proxy2 =
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900172 bus->GetObjectProxy("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900173 ObjectPath("/org/chromium/TestObject"));
deymo@chromium.org6d168a72013-01-30 05:29:12 +0900174 ASSERT_TRUE(object_proxy2);
175
176 // Compare the new object with the first object. The first object still exists
177 // thanks to the increased reference.
178 EXPECT_NE(object_proxy1, object_proxy2);
179
180 // Release object_proxy1.
181 object_proxy1->Release();
182
183 // Shut down synchronously.
184 bus->ShutdownOnDBusThreadAndBlock();
185 EXPECT_TRUE(bus->shutdown_completed());
186 dbus_thread.Stop();
187}
188
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900189TEST(BusTest, GetExportedObject) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900190 Bus::Options options;
191 scoped_refptr<Bus> bus = new Bus(options);
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900192
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900193 ExportedObject* object_proxy1 =
194 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900195 ASSERT_TRUE(object_proxy1);
196
197 // This should return the same object.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900198 ExportedObject* object_proxy2 =
199 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900200 ASSERT_TRUE(object_proxy2);
201 EXPECT_EQ(object_proxy1, object_proxy2);
202
203 // This should not.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900204 ExportedObject* object_proxy3 =
keybuk@google.combf4649a2012-02-15 06:29:06 +0900205 bus->GetExportedObject(
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900206 ObjectPath("/org/chromium/DifferentTestObject"));
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900207 ASSERT_TRUE(object_proxy3);
208 EXPECT_NE(object_proxy1, object_proxy3);
satorux@chromium.orgf06eb892011-10-13 09:45:26 +0900209
210 bus->ShutdownAndBlock();
satorux@chromium.orgdccbb7b2011-08-24 04:25:20 +0900211}
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900212
deymo@chromium.org03ec2482013-01-24 09:58:35 +0900213TEST(BusTest, UnregisterExportedObject) {
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900214 // Start the D-Bus thread.
215 base::Thread::Options thread_options;
xhwang@chromium.orgdff6b132013-05-02 01:10:30 +0900216 thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900217 base::Thread dbus_thread("D-Bus thread");
218 dbus_thread.StartWithOptions(thread_options);
219
220 // Create the bus.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900221 Bus::Options options;
skyostile5a8dc42015-06-18 00:46:04 +0900222 options.dbus_task_runner = dbus_thread.task_runner();
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900223 scoped_refptr<Bus> bus = new Bus(options);
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900224 ASSERT_FALSE(bus->shutdown_completed());
225
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900226 ExportedObject* object_proxy1 =
227 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900228 ASSERT_TRUE(object_proxy1);
229
deymo@chromium.org03ec2482013-01-24 09:58:35 +0900230 // Increment the reference count to the object proxy to avoid destroying it
231 // calling UnregisterExportedObject. This ensures the dbus::ExportedObject is
232 // not freed from memory. See http://crbug.com/137846 for details.
233 object_proxy1->AddRef();
234
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900235 bus->UnregisterExportedObject(ObjectPath("/org/chromium/TestObject"));
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900236
deymo@chromium.org03ec2482013-01-24 09:58:35 +0900237 // This should return a new object because the object_proxy1 is still in
238 // alloc'ed memory.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900239 ExportedObject* object_proxy2 =
240 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900241 ASSERT_TRUE(object_proxy2);
242 EXPECT_NE(object_proxy1, object_proxy2);
243
deymo@chromium.org03ec2482013-01-24 09:58:35 +0900244 // Release the incremented reference.
245 object_proxy1->Release();
246
keybuk@chromium.orgd2ca8f32012-03-14 10:18:35 +0900247 // Shut down synchronously.
248 bus->ShutdownOnDBusThreadAndBlock();
249 EXPECT_TRUE(bus->shutdown_completed());
250 dbus_thread.Stop();
251}
252
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900253TEST(BusTest, ShutdownAndBlock) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900254 Bus::Options options;
255 scoped_refptr<Bus> bus = new Bus(options);
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900256 ASSERT_FALSE(bus->shutdown_completed());
257
258 // Shut down synchronously.
259 bus->ShutdownAndBlock();
260 EXPECT_TRUE(bus->shutdown_completed());
261}
262
263TEST(BusTest, ShutdownAndBlockWithDBusThread) {
264 // Start the D-Bus thread.
265 base::Thread::Options thread_options;
xhwang@chromium.orgdff6b132013-05-02 01:10:30 +0900266 thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900267 base::Thread dbus_thread("D-Bus thread");
268 dbus_thread.StartWithOptions(thread_options);
269
270 // Create the bus.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900271 Bus::Options options;
skyostile5a8dc42015-06-18 00:46:04 +0900272 options.dbus_task_runner = dbus_thread.task_runner();
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900273 scoped_refptr<Bus> bus = new Bus(options);
satorux@chromium.orgd336d452011-09-02 15:56:23 +0900274 ASSERT_FALSE(bus->shutdown_completed());
275
276 // Shut down synchronously.
277 bus->ShutdownOnDBusThreadAndBlock();
278 EXPECT_TRUE(bus->shutdown_completed());
279 dbus_thread.Stop();
280}
satorux@chromium.org66bc4c22011-10-06 09:20:53 +0900281
deymo@chromium.org7894ebf2013-01-31 15:08:02 +0900282TEST(BusTest, DoubleAddAndRemoveMatch) {
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900283 Bus::Options options;
284 scoped_refptr<Bus> bus = new Bus(options);
285 ScopedDBusError error;
deymo@chromium.org7894ebf2013-01-31 15:08:02 +0900286
287 bus->Connect();
288
289 // Adds the same rule twice.
290 bus->AddMatch(
291 "type='signal',interface='org.chromium.TestService',path='/'",
292 error.get());
293 ASSERT_FALSE(error.is_set());
294
295 bus->AddMatch(
296 "type='signal',interface='org.chromium.TestService',path='/'",
297 error.get());
298 ASSERT_FALSE(error.is_set());
299
300 // Removes the same rule twice.
301 ASSERT_TRUE(bus->RemoveMatch(
302 "type='signal',interface='org.chromium.TestService',path='/'",
303 error.get()));
304 ASSERT_FALSE(error.is_set());
305
306 // The rule should be still in the bus since it was removed only once.
307 // A second removal shouldn't give an error.
308 ASSERT_TRUE(bus->RemoveMatch(
309 "type='signal',interface='org.chromium.TestService',path='/'",
310 error.get()));
311 ASSERT_FALSE(error.is_set());
312
313 // A third attemp to remove the same rule should fail.
314 ASSERT_FALSE(bus->RemoveMatch(
315 "type='signal',interface='org.chromium.TestService',path='/'",
316 error.get()));
317
318 bus->ShutdownAndBlock();
319}
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900320
321TEST(BusTest, ListenForServiceOwnerChange) {
fdorayc4aba522017-04-18 22:40:21 +0900322 base::MessageLoopForIO message_loop;
323
324 // This enables FileDescriptorWatcher, which is required by dbus::Watch.
325 base::FileDescriptorWatcher file_descriptor_watcher(&message_loop);
326
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900327 RunLoopWithExpectedCount run_loop_state;
328
329 // Create the bus.
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900330 Bus::Options bus_options;
331 scoped_refptr<Bus> bus = new Bus(bus_options);
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900332
333 // Add a listener.
334 std::string service_owner1;
335 int num_of_owner_changes1 = 0;
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900336 Bus::GetServiceOwnerCallback callback1 =
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900337 base::Bind(&OnServiceOwnerChanged,
338 &run_loop_state,
339 &service_owner1,
340 &num_of_owner_changes1);
341 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1);
342 // This should be a no-op.
343 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1);
344 base::RunLoop().RunUntilIdle();
345
346 // Nothing has happened yet. Check initial state.
347 EXPECT_TRUE(service_owner1.empty());
348 EXPECT_EQ(0, num_of_owner_changes1);
349
350 // Make an ownership change.
cmasone@chromium.org989857e2013-07-31 15:34:59 +0900351 ASSERT_TRUE(bus->RequestOwnershipAndBlock("org.chromium.TestService",
352 Bus::REQUIRE_PRIMARY));
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900353 run_loop_state.Run(1);
354
355 {
356 // Get the current service owner and check to make sure the listener got
357 // the right value.
358 std::string current_service_owner =
359 bus->GetServiceOwnerAndBlock("org.chromium.TestService",
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900360 Bus::REPORT_ERRORS);
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900361 ASSERT_FALSE(current_service_owner.empty());
362
363 // Make sure the listener heard about the new owner.
364 EXPECT_EQ(current_service_owner, service_owner1);
365
366 // Test the second ListenForServiceOwnerChange() above is indeed a no-op.
367 EXPECT_EQ(1, num_of_owner_changes1);
368 }
369
370 // Add a second listener.
371 std::string service_owner2;
372 int num_of_owner_changes2 = 0;
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900373 Bus::GetServiceOwnerCallback callback2 =
thestig@chromium.orgc2482f12013-06-11 07:52:34 +0900374 base::Bind(&OnServiceOwnerChanged,
375 &run_loop_state,
376 &service_owner2,
377 &num_of_owner_changes2);
378 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback2);
379 base::RunLoop().RunUntilIdle();
380
381 // Release the ownership and make sure the service owner listeners fire with
382 // the right values and the right number of times.
383 ASSERT_TRUE(bus->ReleaseOwnership("org.chromium.TestService"));
384 run_loop_state.Run(2);
385
386 EXPECT_TRUE(service_owner1.empty());
387 EXPECT_TRUE(service_owner2.empty());
388 EXPECT_EQ(2, num_of_owner_changes1);
389 EXPECT_EQ(1, num_of_owner_changes2);
390
391 // Unlisten so shutdown can proceed correctly.
392 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback1);
393 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback2);
394 base::RunLoop().RunUntilIdle();
395
396 // Shut down synchronously.
397 bus->ShutdownAndBlock();
398 EXPECT_TRUE(bus->shutdown_completed());
399}
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900400
zqiua84d25f2015-07-08 11:08:30 +0900401TEST(BusTest, GetConnectionName) {
402 Bus::Options options;
403 scoped_refptr<Bus> bus = new Bus(options);
404
405 // Connection name is empty since bus is not connected.
406 EXPECT_FALSE(bus->is_connected());
407 EXPECT_TRUE(bus->GetConnectionName().empty());
408
409 // Connect bus to D-Bus.
410 bus->Connect();
411
412 // Connection name is not empty after connection is established.
413 EXPECT_TRUE(bus->is_connected());
414 EXPECT_FALSE(bus->GetConnectionName().empty());
415
416 // Shut down synchronously.
417 bus->ShutdownAndBlock();
418 EXPECT_TRUE(bus->shutdown_completed());
419}
420
thestig@chromium.orgf0b7eac2013-06-13 15:37:19 +0900421} // namespace dbus