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 "dbus/bus.h" | 5 #include "dbus/bus.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
11 #include "base/threading/thread.h" | 11 #include "base/threading/thread.h" |
12 #include "dbus/exported_object.h" | 12 #include "dbus/exported_object.h" |
13 #include "dbus/object_path.h" | 13 #include "dbus/object_path.h" |
14 #include "dbus/object_proxy.h" | 14 #include "dbus/object_proxy.h" |
15 #include "dbus/scoped_dbus_error.h" | 15 #include "dbus/scoped_dbus_error.h" |
16 #include "dbus/test_service.h" | 16 #include "dbus/test_service.h" |
17 | 17 |
18 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
19 | 19 |
| 20 namespace dbus { |
| 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 // Used to test AddFilterFunction(). | 24 // Used to test AddFilterFunction(). |
23 DBusHandlerResult DummyHandler(DBusConnection* connection, | 25 DBusHandlerResult DummyHandler(DBusConnection* connection, |
24 DBusMessage* raw_message, | 26 DBusMessage* raw_message, |
25 void* user_data) { | 27 void* user_data) { |
26 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 28 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
27 } | 29 } |
28 | 30 |
29 // Test helper for BusTest.ListenForServiceOwnerChange that wraps a | 31 // Test helper for BusTest.ListenForServiceOwnerChange that wraps a |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 int* num_of_owner_changes, | 67 int* num_of_owner_changes, |
66 const std::string& new_service_owner) { | 68 const std::string& new_service_owner) { |
67 *service_owner = new_service_owner; | 69 *service_owner = new_service_owner; |
68 ++(*num_of_owner_changes); | 70 ++(*num_of_owner_changes); |
69 run_loop_state->QuitIfConditionIsSatisified(); | 71 run_loop_state->QuitIfConditionIsSatisified(); |
70 } | 72 } |
71 | 73 |
72 } // namespace | 74 } // namespace |
73 | 75 |
74 TEST(BusTest, GetObjectProxy) { | 76 TEST(BusTest, GetObjectProxy) { |
75 dbus::Bus::Options options; | 77 Bus::Options options; |
76 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 78 scoped_refptr<Bus> bus = new Bus(options); |
77 | 79 |
78 dbus::ObjectProxy* object_proxy1 = | 80 ObjectProxy* object_proxy1 = |
79 bus->GetObjectProxy("org.chromium.TestService", | 81 bus->GetObjectProxy("org.chromium.TestService", |
80 dbus::ObjectPath("/org/chromium/TestObject")); | 82 ObjectPath("/org/chromium/TestObject")); |
81 ASSERT_TRUE(object_proxy1); | 83 ASSERT_TRUE(object_proxy1); |
82 | 84 |
83 // This should return the same object. | 85 // This should return the same object. |
84 dbus::ObjectProxy* object_proxy2 = | 86 ObjectProxy* object_proxy2 = |
85 bus->GetObjectProxy("org.chromium.TestService", | 87 bus->GetObjectProxy("org.chromium.TestService", |
86 dbus::ObjectPath("/org/chromium/TestObject")); | 88 ObjectPath("/org/chromium/TestObject")); |
87 ASSERT_TRUE(object_proxy2); | 89 ASSERT_TRUE(object_proxy2); |
88 EXPECT_EQ(object_proxy1, object_proxy2); | 90 EXPECT_EQ(object_proxy1, object_proxy2); |
89 | 91 |
90 // This should not. | 92 // This should not. |
91 dbus::ObjectProxy* object_proxy3 = | 93 ObjectProxy* object_proxy3 = |
92 bus->GetObjectProxy( | 94 bus->GetObjectProxy( |
93 "org.chromium.TestService", | 95 "org.chromium.TestService", |
94 dbus::ObjectPath("/org/chromium/DifferentTestObject")); | 96 ObjectPath("/org/chromium/DifferentTestObject")); |
95 ASSERT_TRUE(object_proxy3); | 97 ASSERT_TRUE(object_proxy3); |
96 EXPECT_NE(object_proxy1, object_proxy3); | 98 EXPECT_NE(object_proxy1, object_proxy3); |
97 | 99 |
98 bus->ShutdownAndBlock(); | 100 bus->ShutdownAndBlock(); |
99 } | 101 } |
100 | 102 |
101 TEST(BusTest, GetObjectProxyIgnoreUnknownService) { | 103 TEST(BusTest, GetObjectProxyIgnoreUnknownService) { |
102 dbus::Bus::Options options; | 104 Bus::Options options; |
103 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 105 scoped_refptr<Bus> bus = new Bus(options); |
104 | 106 |
105 dbus::ObjectProxy* object_proxy1 = | 107 ObjectProxy* object_proxy1 = |
106 bus->GetObjectProxyWithOptions( | 108 bus->GetObjectProxyWithOptions( |
107 "org.chromium.TestService", | 109 "org.chromium.TestService", |
108 dbus::ObjectPath("/org/chromium/TestObject"), | 110 ObjectPath("/org/chromium/TestObject"), |
109 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); | 111 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); |
110 ASSERT_TRUE(object_proxy1); | 112 ASSERT_TRUE(object_proxy1); |
111 | 113 |
112 // This should return the same object. | 114 // This should return the same object. |
113 dbus::ObjectProxy* object_proxy2 = | 115 ObjectProxy* object_proxy2 = |
114 bus->GetObjectProxyWithOptions( | 116 bus->GetObjectProxyWithOptions( |
115 "org.chromium.TestService", | 117 "org.chromium.TestService", |
116 dbus::ObjectPath("/org/chromium/TestObject"), | 118 ObjectPath("/org/chromium/TestObject"), |
117 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); | 119 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); |
118 ASSERT_TRUE(object_proxy2); | 120 ASSERT_TRUE(object_proxy2); |
119 EXPECT_EQ(object_proxy1, object_proxy2); | 121 EXPECT_EQ(object_proxy1, object_proxy2); |
120 | 122 |
121 // This should not. | 123 // This should not. |
122 dbus::ObjectProxy* object_proxy3 = | 124 ObjectProxy* object_proxy3 = |
123 bus->GetObjectProxyWithOptions( | 125 bus->GetObjectProxyWithOptions( |
124 "org.chromium.TestService", | 126 "org.chromium.TestService", |
125 dbus::ObjectPath("/org/chromium/DifferentTestObject"), | 127 ObjectPath("/org/chromium/DifferentTestObject"), |
126 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); | 128 ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS); |
127 ASSERT_TRUE(object_proxy3); | 129 ASSERT_TRUE(object_proxy3); |
128 EXPECT_NE(object_proxy1, object_proxy3); | 130 EXPECT_NE(object_proxy1, object_proxy3); |
129 | 131 |
130 bus->ShutdownAndBlock(); | 132 bus->ShutdownAndBlock(); |
131 } | 133 } |
132 | 134 |
133 TEST(BusTest, RemoveObjectProxy) { | 135 TEST(BusTest, RemoveObjectProxy) { |
134 // Setup the current thread's MessageLoop. | 136 // Setup the current thread's MessageLoop. |
135 base::MessageLoop message_loop; | 137 base::MessageLoop message_loop; |
136 | 138 |
137 // Start the D-Bus thread. | 139 // Start the D-Bus thread. |
138 base::Thread::Options thread_options; | 140 base::Thread::Options thread_options; |
139 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | 141 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; |
140 base::Thread dbus_thread("D-Bus thread"); | 142 base::Thread dbus_thread("D-Bus thread"); |
141 dbus_thread.StartWithOptions(thread_options); | 143 dbus_thread.StartWithOptions(thread_options); |
142 | 144 |
143 // Create the bus. | 145 // Create the bus. |
144 dbus::Bus::Options options; | 146 Bus::Options options; |
145 options.dbus_task_runner = dbus_thread.message_loop_proxy(); | 147 options.dbus_task_runner = dbus_thread.message_loop_proxy(); |
146 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 148 scoped_refptr<Bus> bus = new Bus(options); |
147 ASSERT_FALSE(bus->shutdown_completed()); | 149 ASSERT_FALSE(bus->shutdown_completed()); |
148 | 150 |
149 // Try to remove a non existant object proxy should return false. | 151 // Try to remove a non existant object proxy should return false. |
150 ASSERT_FALSE( | 152 ASSERT_FALSE( |
151 bus->RemoveObjectProxy("org.chromium.TestService", | 153 bus->RemoveObjectProxy("org.chromium.TestService", |
152 dbus::ObjectPath("/org/chromium/TestObject"), | 154 ObjectPath("/org/chromium/TestObject"), |
153 base::Bind(&base::DoNothing))); | 155 base::Bind(&base::DoNothing))); |
154 | 156 |
155 dbus::ObjectProxy* object_proxy1 = | 157 ObjectProxy* object_proxy1 = |
156 bus->GetObjectProxy("org.chromium.TestService", | 158 bus->GetObjectProxy("org.chromium.TestService", |
157 dbus::ObjectPath("/org/chromium/TestObject")); | 159 ObjectPath("/org/chromium/TestObject")); |
158 ASSERT_TRUE(object_proxy1); | 160 ASSERT_TRUE(object_proxy1); |
159 | 161 |
160 // Increment the reference count to the object proxy to avoid destroying it | 162 // Increment the reference count to the object proxy to avoid destroying it |
161 // while removing the object. | 163 // while removing the object. |
162 object_proxy1->AddRef(); | 164 object_proxy1->AddRef(); |
163 | 165 |
164 // Remove the object from the bus. This will invalidate any other usage of | 166 // Remove the object from the bus. This will invalidate any other usage of |
165 // object_proxy1 other than destroy it. We keep this object for a comparison | 167 // object_proxy1 other than destroy it. We keep this object for a comparison |
166 // at a later time. | 168 // at a later time. |
167 ASSERT_TRUE( | 169 ASSERT_TRUE( |
168 bus->RemoveObjectProxy("org.chromium.TestService", | 170 bus->RemoveObjectProxy("org.chromium.TestService", |
169 dbus::ObjectPath("/org/chromium/TestObject"), | 171 ObjectPath("/org/chromium/TestObject"), |
170 base::Bind(&base::DoNothing))); | 172 base::Bind(&base::DoNothing))); |
171 | 173 |
172 // This should return a different object because the first object was removed | 174 // This should return a different object because the first object was removed |
173 // from the bus, but not deleted from memory. | 175 // from the bus, but not deleted from memory. |
174 dbus::ObjectProxy* object_proxy2 = | 176 ObjectProxy* object_proxy2 = |
175 bus->GetObjectProxy("org.chromium.TestService", | 177 bus->GetObjectProxy("org.chromium.TestService", |
176 dbus::ObjectPath("/org/chromium/TestObject")); | 178 ObjectPath("/org/chromium/TestObject")); |
177 ASSERT_TRUE(object_proxy2); | 179 ASSERT_TRUE(object_proxy2); |
178 | 180 |
179 // Compare the new object with the first object. The first object still exists | 181 // Compare the new object with the first object. The first object still exists |
180 // thanks to the increased reference. | 182 // thanks to the increased reference. |
181 EXPECT_NE(object_proxy1, object_proxy2); | 183 EXPECT_NE(object_proxy1, object_proxy2); |
182 | 184 |
183 // Release object_proxy1. | 185 // Release object_proxy1. |
184 object_proxy1->Release(); | 186 object_proxy1->Release(); |
185 | 187 |
186 // Shut down synchronously. | 188 // Shut down synchronously. |
187 bus->ShutdownOnDBusThreadAndBlock(); | 189 bus->ShutdownOnDBusThreadAndBlock(); |
188 EXPECT_TRUE(bus->shutdown_completed()); | 190 EXPECT_TRUE(bus->shutdown_completed()); |
189 dbus_thread.Stop(); | 191 dbus_thread.Stop(); |
190 } | 192 } |
191 | 193 |
192 TEST(BusTest, GetExportedObject) { | 194 TEST(BusTest, GetExportedObject) { |
193 dbus::Bus::Options options; | 195 Bus::Options options; |
194 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 196 scoped_refptr<Bus> bus = new Bus(options); |
195 | 197 |
196 dbus::ExportedObject* object_proxy1 = | 198 ExportedObject* object_proxy1 = |
197 bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject")); | 199 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject")); |
198 ASSERT_TRUE(object_proxy1); | 200 ASSERT_TRUE(object_proxy1); |
199 | 201 |
200 // This should return the same object. | 202 // This should return the same object. |
201 dbus::ExportedObject* object_proxy2 = | 203 ExportedObject* object_proxy2 = |
202 bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject")); | 204 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject")); |
203 ASSERT_TRUE(object_proxy2); | 205 ASSERT_TRUE(object_proxy2); |
204 EXPECT_EQ(object_proxy1, object_proxy2); | 206 EXPECT_EQ(object_proxy1, object_proxy2); |
205 | 207 |
206 // This should not. | 208 // This should not. |
207 dbus::ExportedObject* object_proxy3 = | 209 ExportedObject* object_proxy3 = |
208 bus->GetExportedObject( | 210 bus->GetExportedObject( |
209 dbus::ObjectPath("/org/chromium/DifferentTestObject")); | 211 ObjectPath("/org/chromium/DifferentTestObject")); |
210 ASSERT_TRUE(object_proxy3); | 212 ASSERT_TRUE(object_proxy3); |
211 EXPECT_NE(object_proxy1, object_proxy3); | 213 EXPECT_NE(object_proxy1, object_proxy3); |
212 | 214 |
213 bus->ShutdownAndBlock(); | 215 bus->ShutdownAndBlock(); |
214 } | 216 } |
215 | 217 |
216 TEST(BusTest, UnregisterExportedObject) { | 218 TEST(BusTest, UnregisterExportedObject) { |
217 // Start the D-Bus thread. | 219 // Start the D-Bus thread. |
218 base::Thread::Options thread_options; | 220 base::Thread::Options thread_options; |
219 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | 221 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; |
220 base::Thread dbus_thread("D-Bus thread"); | 222 base::Thread dbus_thread("D-Bus thread"); |
221 dbus_thread.StartWithOptions(thread_options); | 223 dbus_thread.StartWithOptions(thread_options); |
222 | 224 |
223 // Create the bus. | 225 // Create the bus. |
224 dbus::Bus::Options options; | 226 Bus::Options options; |
225 options.dbus_task_runner = dbus_thread.message_loop_proxy(); | 227 options.dbus_task_runner = dbus_thread.message_loop_proxy(); |
226 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 228 scoped_refptr<Bus> bus = new Bus(options); |
227 ASSERT_FALSE(bus->shutdown_completed()); | 229 ASSERT_FALSE(bus->shutdown_completed()); |
228 | 230 |
229 dbus::ExportedObject* object_proxy1 = | 231 ExportedObject* object_proxy1 = |
230 bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject")); | 232 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject")); |
231 ASSERT_TRUE(object_proxy1); | 233 ASSERT_TRUE(object_proxy1); |
232 | 234 |
233 // Increment the reference count to the object proxy to avoid destroying it | 235 // Increment the reference count to the object proxy to avoid destroying it |
234 // calling UnregisterExportedObject. This ensures the dbus::ExportedObject is | 236 // calling UnregisterExportedObject. This ensures the dbus::ExportedObject is |
235 // not freed from memory. See http://crbug.com/137846 for details. | 237 // not freed from memory. See http://crbug.com/137846 for details. |
236 object_proxy1->AddRef(); | 238 object_proxy1->AddRef(); |
237 | 239 |
238 bus->UnregisterExportedObject(dbus::ObjectPath("/org/chromium/TestObject")); | 240 bus->UnregisterExportedObject(ObjectPath("/org/chromium/TestObject")); |
239 | 241 |
240 // This should return a new object because the object_proxy1 is still in | 242 // This should return a new object because the object_proxy1 is still in |
241 // alloc'ed memory. | 243 // alloc'ed memory. |
242 dbus::ExportedObject* object_proxy2 = | 244 ExportedObject* object_proxy2 = |
243 bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject")); | 245 bus->GetExportedObject(ObjectPath("/org/chromium/TestObject")); |
244 ASSERT_TRUE(object_proxy2); | 246 ASSERT_TRUE(object_proxy2); |
245 EXPECT_NE(object_proxy1, object_proxy2); | 247 EXPECT_NE(object_proxy1, object_proxy2); |
246 | 248 |
247 // Release the incremented reference. | 249 // Release the incremented reference. |
248 object_proxy1->Release(); | 250 object_proxy1->Release(); |
249 | 251 |
250 // Shut down synchronously. | 252 // Shut down synchronously. |
251 bus->ShutdownOnDBusThreadAndBlock(); | 253 bus->ShutdownOnDBusThreadAndBlock(); |
252 EXPECT_TRUE(bus->shutdown_completed()); | 254 EXPECT_TRUE(bus->shutdown_completed()); |
253 dbus_thread.Stop(); | 255 dbus_thread.Stop(); |
254 } | 256 } |
255 | 257 |
256 TEST(BusTest, ShutdownAndBlock) { | 258 TEST(BusTest, ShutdownAndBlock) { |
257 dbus::Bus::Options options; | 259 Bus::Options options; |
258 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 260 scoped_refptr<Bus> bus = new Bus(options); |
259 ASSERT_FALSE(bus->shutdown_completed()); | 261 ASSERT_FALSE(bus->shutdown_completed()); |
260 | 262 |
261 // Shut down synchronously. | 263 // Shut down synchronously. |
262 bus->ShutdownAndBlock(); | 264 bus->ShutdownAndBlock(); |
263 EXPECT_TRUE(bus->shutdown_completed()); | 265 EXPECT_TRUE(bus->shutdown_completed()); |
264 } | 266 } |
265 | 267 |
266 TEST(BusTest, ShutdownAndBlockWithDBusThread) { | 268 TEST(BusTest, ShutdownAndBlockWithDBusThread) { |
267 // Start the D-Bus thread. | 269 // Start the D-Bus thread. |
268 base::Thread::Options thread_options; | 270 base::Thread::Options thread_options; |
269 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | 271 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; |
270 base::Thread dbus_thread("D-Bus thread"); | 272 base::Thread dbus_thread("D-Bus thread"); |
271 dbus_thread.StartWithOptions(thread_options); | 273 dbus_thread.StartWithOptions(thread_options); |
272 | 274 |
273 // Create the bus. | 275 // Create the bus. |
274 dbus::Bus::Options options; | 276 Bus::Options options; |
275 options.dbus_task_runner = dbus_thread.message_loop_proxy(); | 277 options.dbus_task_runner = dbus_thread.message_loop_proxy(); |
276 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 278 scoped_refptr<Bus> bus = new Bus(options); |
277 ASSERT_FALSE(bus->shutdown_completed()); | 279 ASSERT_FALSE(bus->shutdown_completed()); |
278 | 280 |
279 // Shut down synchronously. | 281 // Shut down synchronously. |
280 bus->ShutdownOnDBusThreadAndBlock(); | 282 bus->ShutdownOnDBusThreadAndBlock(); |
281 EXPECT_TRUE(bus->shutdown_completed()); | 283 EXPECT_TRUE(bus->shutdown_completed()); |
282 dbus_thread.Stop(); | 284 dbus_thread.Stop(); |
283 } | 285 } |
284 | 286 |
285 TEST(BusTest, AddFilterFunction) { | 287 TEST(BusTest, AddFilterFunction) { |
286 dbus::Bus::Options options; | 288 Bus::Options options; |
287 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 289 scoped_refptr<Bus> bus = new Bus(options); |
288 // Should connect before calling AddFilterFunction(). | 290 // Should connect before calling AddFilterFunction(). |
289 bus->Connect(); | 291 bus->Connect(); |
290 | 292 |
291 int data1 = 100; | 293 int data1 = 100; |
292 int data2 = 200; | 294 int data2 = 200; |
293 ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data1)); | 295 ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data1)); |
294 // Cannot add the same function with the same data. | 296 // Cannot add the same function with the same data. |
295 ASSERT_FALSE(bus->AddFilterFunction(&DummyHandler, &data1)); | 297 ASSERT_FALSE(bus->AddFilterFunction(&DummyHandler, &data1)); |
296 // Can add the same function with different data. | 298 // Can add the same function with different data. |
297 ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data2)); | 299 ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data2)); |
298 | 300 |
299 ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data1)); | 301 ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data1)); |
300 ASSERT_FALSE(bus->RemoveFilterFunction(&DummyHandler, &data1)); | 302 ASSERT_FALSE(bus->RemoveFilterFunction(&DummyHandler, &data1)); |
301 ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data2)); | 303 ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data2)); |
302 | 304 |
303 bus->ShutdownAndBlock(); | 305 bus->ShutdownAndBlock(); |
304 } | 306 } |
305 | 307 |
306 TEST(BusTest, DoubleAddAndRemoveMatch) { | 308 TEST(BusTest, DoubleAddAndRemoveMatch) { |
307 dbus::Bus::Options options; | 309 Bus::Options options; |
308 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 310 scoped_refptr<Bus> bus = new Bus(options); |
309 dbus::ScopedDBusError error; | 311 ScopedDBusError error; |
310 | 312 |
311 bus->Connect(); | 313 bus->Connect(); |
312 | 314 |
313 // Adds the same rule twice. | 315 // Adds the same rule twice. |
314 bus->AddMatch( | 316 bus->AddMatch( |
315 "type='signal',interface='org.chromium.TestService',path='/'", | 317 "type='signal',interface='org.chromium.TestService',path='/'", |
316 error.get()); | 318 error.get()); |
317 ASSERT_FALSE(error.is_set()); | 319 ASSERT_FALSE(error.is_set()); |
318 | 320 |
319 bus->AddMatch( | 321 bus->AddMatch( |
(...skipping 22 matching lines...) Expand all Loading... |
342 bus->ShutdownAndBlock(); | 344 bus->ShutdownAndBlock(); |
343 } | 345 } |
344 | 346 |
345 TEST(BusTest, ListenForServiceOwnerChange) { | 347 TEST(BusTest, ListenForServiceOwnerChange) { |
346 // Setup the current thread's MessageLoop. Must be of TYPE_IO for the | 348 // Setup the current thread's MessageLoop. Must be of TYPE_IO for the |
347 // listeners to work. | 349 // listeners to work. |
348 base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); | 350 base::MessageLoop message_loop(base::MessageLoop::TYPE_IO); |
349 RunLoopWithExpectedCount run_loop_state; | 351 RunLoopWithExpectedCount run_loop_state; |
350 | 352 |
351 // Create the bus. | 353 // Create the bus. |
352 dbus::Bus::Options bus_options; | 354 Bus::Options bus_options; |
353 scoped_refptr<dbus::Bus> bus = new dbus::Bus(bus_options); | 355 scoped_refptr<Bus> bus = new Bus(bus_options); |
354 | 356 |
355 // Add a listener. | 357 // Add a listener. |
356 std::string service_owner1; | 358 std::string service_owner1; |
357 int num_of_owner_changes1 = 0; | 359 int num_of_owner_changes1 = 0; |
358 dbus::Bus::GetServiceOwnerCallback callback1 = | 360 Bus::GetServiceOwnerCallback callback1 = |
359 base::Bind(&OnServiceOwnerChanged, | 361 base::Bind(&OnServiceOwnerChanged, |
360 &run_loop_state, | 362 &run_loop_state, |
361 &service_owner1, | 363 &service_owner1, |
362 &num_of_owner_changes1); | 364 &num_of_owner_changes1); |
363 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1); | 365 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1); |
364 // This should be a no-op. | 366 // This should be a no-op. |
365 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1); | 367 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1); |
366 base::RunLoop().RunUntilIdle(); | 368 base::RunLoop().RunUntilIdle(); |
367 | 369 |
368 // Nothing has happened yet. Check initial state. | 370 // Nothing has happened yet. Check initial state. |
369 EXPECT_TRUE(service_owner1.empty()); | 371 EXPECT_TRUE(service_owner1.empty()); |
370 EXPECT_EQ(0, num_of_owner_changes1); | 372 EXPECT_EQ(0, num_of_owner_changes1); |
371 | 373 |
372 // Make an ownership change. | 374 // Make an ownership change. |
373 ASSERT_TRUE(bus->RequestOwnershipAndBlock("org.chromium.TestService")); | 375 ASSERT_TRUE(bus->RequestOwnershipAndBlock("org.chromium.TestService")); |
374 run_loop_state.Run(1); | 376 run_loop_state.Run(1); |
375 | 377 |
376 { | 378 { |
377 // Get the current service owner and check to make sure the listener got | 379 // Get the current service owner and check to make sure the listener got |
378 // the right value. | 380 // the right value. |
379 std::string current_service_owner = | 381 std::string current_service_owner = |
380 bus->GetServiceOwnerAndBlock("org.chromium.TestService", | 382 bus->GetServiceOwnerAndBlock("org.chromium.TestService", |
381 dbus::Bus::REPORT_ERRORS); | 383 Bus::REPORT_ERRORS); |
382 ASSERT_FALSE(current_service_owner.empty()); | 384 ASSERT_FALSE(current_service_owner.empty()); |
383 | 385 |
384 // Make sure the listener heard about the new owner. | 386 // Make sure the listener heard about the new owner. |
385 EXPECT_EQ(current_service_owner, service_owner1); | 387 EXPECT_EQ(current_service_owner, service_owner1); |
386 | 388 |
387 // Test the second ListenForServiceOwnerChange() above is indeed a no-op. | 389 // Test the second ListenForServiceOwnerChange() above is indeed a no-op. |
388 EXPECT_EQ(1, num_of_owner_changes1); | 390 EXPECT_EQ(1, num_of_owner_changes1); |
389 } | 391 } |
390 | 392 |
391 // Add a second listener. | 393 // Add a second listener. |
392 std::string service_owner2; | 394 std::string service_owner2; |
393 int num_of_owner_changes2 = 0; | 395 int num_of_owner_changes2 = 0; |
394 dbus::Bus::GetServiceOwnerCallback callback2 = | 396 Bus::GetServiceOwnerCallback callback2 = |
395 base::Bind(&OnServiceOwnerChanged, | 397 base::Bind(&OnServiceOwnerChanged, |
396 &run_loop_state, | 398 &run_loop_state, |
397 &service_owner2, | 399 &service_owner2, |
398 &num_of_owner_changes2); | 400 &num_of_owner_changes2); |
399 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback2); | 401 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback2); |
400 base::RunLoop().RunUntilIdle(); | 402 base::RunLoop().RunUntilIdle(); |
401 | 403 |
402 // Release the ownership and make sure the service owner listeners fire with | 404 // Release the ownership and make sure the service owner listeners fire with |
403 // the right values and the right number of times. | 405 // the right values and the right number of times. |
404 ASSERT_TRUE(bus->ReleaseOwnership("org.chromium.TestService")); | 406 ASSERT_TRUE(bus->ReleaseOwnership("org.chromium.TestService")); |
405 run_loop_state.Run(2); | 407 run_loop_state.Run(2); |
406 | 408 |
407 EXPECT_TRUE(service_owner1.empty()); | 409 EXPECT_TRUE(service_owner1.empty()); |
408 EXPECT_TRUE(service_owner2.empty()); | 410 EXPECT_TRUE(service_owner2.empty()); |
409 EXPECT_EQ(2, num_of_owner_changes1); | 411 EXPECT_EQ(2, num_of_owner_changes1); |
410 EXPECT_EQ(1, num_of_owner_changes2); | 412 EXPECT_EQ(1, num_of_owner_changes2); |
411 | 413 |
412 // Unlisten so shutdown can proceed correctly. | 414 // Unlisten so shutdown can proceed correctly. |
413 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback1); | 415 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback1); |
414 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback2); | 416 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback2); |
415 base::RunLoop().RunUntilIdle(); | 417 base::RunLoop().RunUntilIdle(); |
416 | 418 |
417 // Shut down synchronously. | 419 // Shut down synchronously. |
418 bus->ShutdownAndBlock(); | 420 bus->ShutdownAndBlock(); |
419 EXPECT_TRUE(bus->shutdown_completed()); | 421 EXPECT_TRUE(bus->shutdown_completed()); |
420 } | 422 } |
| 423 |
| 424 } // namespace dbus |
OLD | NEW |