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/threading/thread.h" | 11 #include "base/threading/thread.h" |
11 #include "dbus/exported_object.h" | 12 #include "dbus/exported_object.h" |
12 #include "dbus/object_path.h" | 13 #include "dbus/object_path.h" |
13 #include "dbus/object_proxy.h" | 14 #include "dbus/object_proxy.h" |
14 #include "dbus/scoped_dbus_error.h" | 15 #include "dbus/scoped_dbus_error.h" |
16 #include "dbus/test_service.h" | |
15 | 17 |
16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
17 | 19 |
18 namespace { | 20 namespace { |
19 | 21 |
20 // Used to test AddFilterFunction(). | 22 // Used to test AddFilterFunction(). |
21 DBusHandlerResult DummyHandler(DBusConnection* connection, | 23 DBusHandlerResult DummyHandler(DBusConnection* connection, |
22 DBusMessage* raw_message, | 24 DBusMessage* raw_message, |
23 void* user_data) { | 25 void* user_data) { |
24 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 26 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
25 } | 27 } |
26 | 28 |
29 // The test helpers below are for BusTest.ListenForServiceOwnerChange. | |
30 | |
31 class OwnershipChangeListener { | |
32 public: | |
33 OwnershipChangeListener() : owner_changes_(0) {} | |
34 ~OwnershipChangeListener() {} | |
35 | |
36 void OnServiceOwnerChanged(const std::string& new_service_owner) { | |
37 current_owner_ = new_service_owner; | |
38 ++owner_changes_; | |
39 } | |
40 | |
41 void set_current_owner(const std::string& owner) { current_owner_ = owner; } | |
42 const std::string& current_owner() const { return current_owner_; } | |
43 | |
44 int owner_changes() const { return owner_changes_; } | |
45 | |
46 private: | |
47 std::string current_owner_; | |
48 int owner_changes_; | |
49 | |
50 DISALLOW_COPY_AND_ASSIGN(OwnershipChangeListener); | |
51 }; | |
52 | |
53 void RequestOwnershipHelper(const base::Closure& quit_closure, | |
54 std::string* service_name, | |
55 bool* is_owner, | |
56 const std::string& actual_service_name, | |
57 bool actual_is_owner) { | |
58 *service_name = actual_service_name; | |
59 *is_owner = actual_is_owner; | |
60 quit_closure.Run(); | |
61 } | |
62 | |
63 void RequestOwnership(dbus::Bus* bus, const std::string& service_name) { | |
64 base::RunLoop run_loop; | |
65 std::string requested_service_name; | |
66 bool got_owner = false; | |
67 bus->RequestOwnership(service_name, | |
68 base::Bind(&RequestOwnershipHelper, | |
69 run_loop.QuitClosure(), | |
70 &requested_service_name, | |
71 &got_owner)); | |
72 run_loop.Run(); | |
73 ASSERT_TRUE(got_owner); | |
74 ASSERT_EQ(service_name, requested_service_name); | |
75 } | |
76 | |
77 void ReleaseOwnershipHelper(const base::Closure& quit_closure, | |
78 dbus::Bus* bus, | |
79 const std::string& service_name, | |
80 bool* released) { | |
81 *released = bus->ReleaseOwnership(service_name); | |
82 bus->PostTaskToOriginThread(FROM_HERE, quit_closure); | |
83 } | |
84 | |
85 void ReleaseOwnership(dbus::Bus* bus, const std::string& service_name) { | |
86 base::RunLoop run_loop; | |
87 bool released = false; | |
88 bus->PostTaskToDBusThread( | |
89 FROM_HERE, | |
90 base::Bind(&ReleaseOwnershipHelper, | |
91 run_loop.QuitClosure(), | |
92 make_scoped_refptr(bus), | |
93 service_name, | |
94 &released)); | |
95 run_loop.Run(); | |
96 ASSERT_TRUE(released); | |
97 } | |
98 | |
99 void GetServiceOwnerHelper(const base::Closure& quit_closure, | |
100 std::string* service_owner, | |
101 const std::string& actual_service_owner) { | |
102 *service_owner = actual_service_owner; | |
103 quit_closure.Run(); | |
104 } | |
105 | |
106 std::string GetServiceOwner(dbus::Bus* bus, const std::string& service_name) { | |
107 base::RunLoop run_loop; | |
108 std::string service_owner; | |
109 bus->GetServiceOwner(service_name, | |
110 base::Bind(&GetServiceOwnerHelper, | |
111 run_loop.QuitClosure(), | |
112 &service_owner)); | |
113 run_loop.Run(); | |
114 return service_owner; | |
115 } | |
116 | |
27 } // namespace | 117 } // namespace |
28 | 118 |
29 TEST(BusTest, GetObjectProxy) { | 119 TEST(BusTest, GetObjectProxy) { |
30 dbus::Bus::Options options; | 120 dbus::Bus::Options options; |
31 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); | 121 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options); |
32 | 122 |
33 dbus::ObjectProxy* object_proxy1 = | 123 dbus::ObjectProxy* object_proxy1 = |
34 bus->GetObjectProxy("org.chromium.TestService", | 124 bus->GetObjectProxy("org.chromium.TestService", |
35 dbus::ObjectPath("/org/chromium/TestObject")); | 125 dbus::ObjectPath("/org/chromium/TestObject")); |
36 ASSERT_TRUE(object_proxy1); | 126 ASSERT_TRUE(object_proxy1); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 error.get())); | 379 error.get())); |
290 ASSERT_FALSE(error.is_set()); | 380 ASSERT_FALSE(error.is_set()); |
291 | 381 |
292 // A third attemp to remove the same rule should fail. | 382 // A third attemp to remove the same rule should fail. |
293 ASSERT_FALSE(bus->RemoveMatch( | 383 ASSERT_FALSE(bus->RemoveMatch( |
294 "type='signal',interface='org.chromium.TestService',path='/'", | 384 "type='signal',interface='org.chromium.TestService',path='/'", |
295 error.get())); | 385 error.get())); |
296 | 386 |
297 bus->ShutdownAndBlock(); | 387 bus->ShutdownAndBlock(); |
298 } | 388 } |
389 | |
390 TEST(BusTest, ListenForServiceOwnerChange) { | |
391 // Setup the current thread's MessageLoop. | |
392 base::MessageLoop message_loop; | |
393 | |
394 // Start the D-Bus thread. | |
395 base::Thread::Options thread_options; | |
396 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | |
397 base::Thread dbus_thread("D-Bus thread"); | |
satorux1
2013/06/05 01:33:58
Do we need to create a D-Bus thread? Other test ca
Lei Zhang
2013/06/09 04:37:57
I copied it from the test right above this one and
| |
398 dbus_thread.StartWithOptions(thread_options); | |
399 | |
400 // Create the bus. | |
401 dbus::Bus::Options bus_options; | |
402 bus_options.dbus_task_runner = dbus_thread.message_loop_proxy(); | |
403 scoped_refptr<dbus::Bus> bus = new dbus::Bus(bus_options); | |
404 ASSERT_FALSE(bus->shutdown_completed()); | |
405 | |
406 // Add a listener. | |
407 OwnershipChangeListener ownership_change_listener_1; | |
satorux1
2013/06/05 01:33:58
nit: ownership_change_listener1 ? having _ before
Lei Zhang
2013/06/09 04:37:57
Done.
| |
408 ownership_change_listener_1.set_current_owner("dummy1"); | |
satorux1
2013/06/05 01:33:58
At first, I was confused about why a dummy value w
| |
409 dbus::Bus::GetServiceOwnerCallback callback1 = | |
410 base::Bind(&OwnershipChangeListener::OnServiceOwnerChanged, | |
satorux1
2013/06/05 01:33:58
This class seems to be unnecessary. Can we just pa
Lei Zhang
2013/06/09 04:37:57
Done
| |
411 base::Unretained(&ownership_change_listener_1)); | |
412 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1); | |
413 // This should be a no-op. | |
414 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1); | |
415 | |
416 // Nothing has happened yet. Check initial state. | |
417 // The blocking GetServiceOwner() call makes sure the | |
418 // ListenForServiceOwnerChange() calls happen first. | |
419 std::string service_owner = GetServiceOwner(bus, "org.chromium.TestService"); | |
420 ASSERT_TRUE(service_owner.empty()); | |
421 ASSERT_EQ("dummy1", ownership_change_listener_1.current_owner()); | |
422 EXPECT_EQ(0, ownership_change_listener_1.owner_changes()); | |
423 | |
424 // Make an ownership change. | |
425 RequestOwnership(bus, "org.chromium.TestService"); | |
426 service_owner = GetServiceOwner(bus, "org.chromium.TestService"); | |
satorux1
2013/06/05 01:33:58
How does the |service_owner_| look like? Could you
| |
427 ASSERT_FALSE(service_owner.empty()); | |
428 ASSERT_EQ(service_owner, ownership_change_listener_1.current_owner()); | |
429 | |
430 // Test the second ListenForServiceOwnerChange() above is indeed a no-op. | |
431 EXPECT_EQ(1, ownership_change_listener_1.owner_changes()); | |
432 | |
433 // Add a second listener. | |
434 OwnershipChangeListener ownership_change_listener_2; | |
435 ownership_change_listener_2.set_current_owner("dummy2"); | |
436 dbus::Bus::GetServiceOwnerCallback callback2 = | |
437 base::Bind(&OwnershipChangeListener::OnServiceOwnerChanged, | |
438 base::Unretained(&ownership_change_listener_2)); | |
439 bus->ListenForServiceOwnerChange("org.chromium.TestService", callback2); | |
440 bus->ListenForServiceOwnerChange("org.chromium.FakeService", callback2); | |
satorux1
2013/06/05 01:33:58
Why do we listen to "org.chromium.FakeService"? Co
Lei Zhang
2013/06/09 04:37:57
I guess it doesn't add too much value to the test,
| |
441 | |
442 // The blocking ReleaseOwnership() call makes sure the | |
443 // ListenForServiceOwnerChange() calls happen first. | |
444 ReleaseOwnership(bus, "org.chromium.TestService"); | |
445 service_owner = GetServiceOwner(bus, "org.chromium.TestService"); | |
446 ASSERT_TRUE(service_owner.empty()); | |
447 ASSERT_TRUE(ownership_change_listener_1.current_owner().empty()); | |
448 ASSERT_TRUE(ownership_change_listener_2.current_owner().empty()); | |
449 EXPECT_EQ(2, ownership_change_listener_1.owner_changes()); | |
450 EXPECT_EQ(1, ownership_change_listener_2.owner_changes()); | |
451 | |
452 bus->UnlistenForServiceOwnerChange("org.chromium.FakeService", callback2); | |
453 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback1); | |
454 bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback2); | |
455 | |
456 // Shut down synchronously. The pending UnlistenForServiceOwnerChange() | |
457 // calls will happen first. | |
458 bus->ShutdownOnDBusThreadAndBlock(); | |
459 EXPECT_TRUE(bus->shutdown_completed()); | |
460 dbus_thread.Stop(); | |
461 } | |
462 | |
OLD | NEW |