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
3 // found in the LICENSE file.
8 #include "base/message_loop.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/threading/thread.h"
11 #include "dbus/exported_object.h"
12 #include "dbus/object_path.h"
13 #include "dbus/object_proxy.h"
15 #include "testing/gtest/include/gtest/gtest.h"
19 // Used to test AddFilterFunction().
20 DBusHandlerResult
DummyHandler(DBusConnection
* connection
,
21 DBusMessage
* raw_message
,
23 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
28 TEST(BusTest
, GetObjectProxy
) {
29 dbus::Bus::Options options
;
30 scoped_refptr
<dbus::Bus
> bus
= new dbus::Bus(options
);
32 dbus::ObjectProxy
* object_proxy1
=
33 bus
->GetObjectProxy("org.chromium.TestService",
34 dbus::ObjectPath("/org/chromium/TestObject"));
35 ASSERT_TRUE(object_proxy1
);
37 // This should return the same object.
38 dbus::ObjectProxy
* object_proxy2
=
39 bus
->GetObjectProxy("org.chromium.TestService",
40 dbus::ObjectPath("/org/chromium/TestObject"));
41 ASSERT_TRUE(object_proxy2
);
42 EXPECT_EQ(object_proxy1
, object_proxy2
);
45 dbus::ObjectProxy
* object_proxy3
=
47 "org.chromium.TestService",
48 dbus::ObjectPath("/org/chromium/DifferentTestObject"));
49 ASSERT_TRUE(object_proxy3
);
50 EXPECT_NE(object_proxy1
, object_proxy3
);
52 bus
->ShutdownAndBlock();
55 TEST(BusTest
, GetObjectProxyIgnoreUnknownService
) {
56 dbus::Bus::Options options
;
57 scoped_refptr
<dbus::Bus
> bus
= new dbus::Bus(options
);
59 dbus::ObjectProxy
* object_proxy1
=
60 bus
->GetObjectProxyWithOptions(
61 "org.chromium.TestService",
62 dbus::ObjectPath("/org/chromium/TestObject"),
63 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS
);
64 ASSERT_TRUE(object_proxy1
);
66 // This should return the same object.
67 dbus::ObjectProxy
* object_proxy2
=
68 bus
->GetObjectProxyWithOptions(
69 "org.chromium.TestService",
70 dbus::ObjectPath("/org/chromium/TestObject"),
71 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS
);
72 ASSERT_TRUE(object_proxy2
);
73 EXPECT_EQ(object_proxy1
, object_proxy2
);
76 dbus::ObjectProxy
* object_proxy3
=
77 bus
->GetObjectProxyWithOptions(
78 "org.chromium.TestService",
79 dbus::ObjectPath("/org/chromium/DifferentTestObject"),
80 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS
);
81 ASSERT_TRUE(object_proxy3
);
82 EXPECT_NE(object_proxy1
, object_proxy3
);
84 bus
->ShutdownAndBlock();
87 TEST(BusTest
, GetExportedObject
) {
88 dbus::Bus::Options options
;
89 scoped_refptr
<dbus::Bus
> bus
= new dbus::Bus(options
);
91 dbus::ExportedObject
* object_proxy1
=
92 bus
->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
93 ASSERT_TRUE(object_proxy1
);
95 // This should return the same object.
96 dbus::ExportedObject
* object_proxy2
=
97 bus
->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
98 ASSERT_TRUE(object_proxy2
);
99 EXPECT_EQ(object_proxy1
, object_proxy2
);
102 dbus::ExportedObject
* object_proxy3
=
103 bus
->GetExportedObject(
104 dbus::ObjectPath("/org/chromium/DifferentTestObject"));
105 ASSERT_TRUE(object_proxy3
);
106 EXPECT_NE(object_proxy1
, object_proxy3
);
108 bus
->ShutdownAndBlock();
111 TEST(BusTest
, UnregisterExportedObject
) {
112 // Start the D-Bus thread.
113 base::Thread::Options thread_options
;
114 thread_options
.message_loop_type
= MessageLoop::TYPE_IO
;
115 base::Thread
dbus_thread("D-Bus thread");
116 dbus_thread
.StartWithOptions(thread_options
);
119 dbus::Bus::Options options
;
120 options
.dbus_thread_message_loop_proxy
= dbus_thread
.message_loop_proxy();
121 scoped_refptr
<dbus::Bus
> bus
= new dbus::Bus(options
);
122 ASSERT_FALSE(bus
->shutdown_completed());
124 dbus::ExportedObject
* object_proxy1
=
125 bus
->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
126 ASSERT_TRUE(object_proxy1
);
128 // Increment the reference count to the object proxy to avoid destroying it
129 // calling UnregisterExportedObject. This ensures the dbus::ExportedObject is
130 // not freed from memory. See http://crbug.com/137846 for details.
131 object_proxy1
->AddRef();
133 bus
->UnregisterExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
135 // This should return a new object because the object_proxy1 is still in
137 dbus::ExportedObject
* object_proxy2
=
138 bus
->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
139 ASSERT_TRUE(object_proxy2
);
140 EXPECT_NE(object_proxy1
, object_proxy2
);
142 // Release the incremented reference.
143 object_proxy1
->Release();
145 // Shut down synchronously.
146 bus
->ShutdownOnDBusThreadAndBlock();
147 EXPECT_TRUE(bus
->shutdown_completed());
151 TEST(BusTest
, ShutdownAndBlock
) {
152 dbus::Bus::Options options
;
153 scoped_refptr
<dbus::Bus
> bus
= new dbus::Bus(options
);
154 ASSERT_FALSE(bus
->shutdown_completed());
156 // Shut down synchronously.
157 bus
->ShutdownAndBlock();
158 EXPECT_TRUE(bus
->shutdown_completed());
161 TEST(BusTest
, ShutdownAndBlockWithDBusThread
) {
162 // Start the D-Bus thread.
163 base::Thread::Options thread_options
;
164 thread_options
.message_loop_type
= MessageLoop::TYPE_IO
;
165 base::Thread
dbus_thread("D-Bus thread");
166 dbus_thread
.StartWithOptions(thread_options
);
169 dbus::Bus::Options options
;
170 options
.dbus_thread_message_loop_proxy
= dbus_thread
.message_loop_proxy();
171 scoped_refptr
<dbus::Bus
> bus
= new dbus::Bus(options
);
172 ASSERT_FALSE(bus
->shutdown_completed());
174 // Shut down synchronously.
175 bus
->ShutdownOnDBusThreadAndBlock();
176 EXPECT_TRUE(bus
->shutdown_completed());
180 TEST(BusTest
, AddFilterFunction
) {
181 dbus::Bus::Options options
;
182 scoped_refptr
<dbus::Bus
> bus
= new dbus::Bus(options
);
183 // Should connect before calling AddFilterFunction().
188 ASSERT_TRUE(bus
->AddFilterFunction(&DummyHandler
, &data1
));
189 // Cannot add the same function with the same data.
190 ASSERT_FALSE(bus
->AddFilterFunction(&DummyHandler
, &data1
));
191 // Can add the same function with different data.
192 ASSERT_TRUE(bus
->AddFilterFunction(&DummyHandler
, &data2
));
194 ASSERT_TRUE(bus
->RemoveFilterFunction(&DummyHandler
, &data1
));
195 ASSERT_FALSE(bus
->RemoveFilterFunction(&DummyHandler
, &data1
));
196 ASSERT_TRUE(bus
->RemoveFilterFunction(&DummyHandler
, &data2
));
198 bus
->ShutdownAndBlock();