1 // Copyright 2013 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.
5 #include "dbus/object_proxy.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/run_loop.h"
10 #include "base/test/task_environment.h"
12 #include "dbus/test_service.h"
13 #include "testing/gtest/include/gtest/gtest.h"
18 class ObjectProxyTest : public testing::Test {
22 void SetUp() override {
23 Bus::Options bus_options;
24 bus_options.bus_type = Bus::SESSION;
25 bus_options.connection_type = Bus::PRIVATE;
26 bus_ = new Bus(bus_options);
29 void TearDown() override { bus_->ShutdownAndBlock(); }
31 base::test::TaskEnvironment task_environment_{
32 base::test::TaskEnvironment::MainThreadType::IO};
34 scoped_refptr<Bus> bus_;
37 // Used as a WaitForServiceToBeAvailableCallback.
38 void OnServiceIsAvailable(bool* dest_service_is_available,
40 bool src_service_is_available) {
41 *dest_service_is_available = src_service_is_available;
45 // Used as a callback for TestService::RequestOwnership().
46 void OnOwnershipRequestDone(bool success) {
50 // Used as a callback for TestService::ReleaseOwnership().
51 void OnOwnershipReleased() {}
53 TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableRunOnce) {
54 TestService::Options options;
55 TestService test_service(options);
56 ObjectProxy* object_proxy = bus_->GetObjectProxy(
57 test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
59 // The callback is not yet called because the service is not available.
61 bool service_is_available = false;
62 object_proxy->WaitForServiceToBeAvailable(
63 base::BindOnce(&OnServiceIsAvailable, &service_is_available, &num_calls));
64 base::RunLoop().RunUntilIdle();
65 EXPECT_EQ(0, num_calls);
67 // Start the service. The callback should be called asynchronously.
68 ASSERT_TRUE(test_service.StartService());
69 test_service.WaitUntilServiceIsStarted();
70 ASSERT_TRUE(test_service.has_ownership());
72 base::RunLoop().RunUntilIdle();
73 EXPECT_EQ(1, num_calls);
74 EXPECT_TRUE(service_is_available);
76 // Release the service's ownership of its name. The callback should not be
78 test_service.ReleaseOwnership(base::BindOnce(&OnOwnershipReleased));
80 base::RunLoop().RunUntilIdle();
81 EXPECT_EQ(0, num_calls);
83 // Take ownership of the name and check that the callback is not called.
84 test_service.RequestOwnership(base::BindOnce(&OnOwnershipRequestDone));
86 base::RunLoop().RunUntilIdle();
87 EXPECT_EQ(0, num_calls);
90 TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableAlreadyRunning) {
91 TestService::Options options;
92 TestService test_service(options);
93 ObjectProxy* object_proxy = bus_->GetObjectProxy(
94 test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
96 ASSERT_TRUE(test_service.StartService());
97 test_service.WaitUntilServiceIsStarted();
98 ASSERT_TRUE(test_service.has_ownership());
100 // Since the service is already running, the callback should be invoked
101 // immediately (but asynchronously, rather than the callback being invoked
102 // directly within WaitForServiceToBeAvailable()).
104 bool service_is_available = false;
105 object_proxy->WaitForServiceToBeAvailable(
106 base::BindOnce(&OnServiceIsAvailable, &service_is_available, &num_calls));
107 EXPECT_EQ(0, num_calls);
109 base::RunLoop().RunUntilIdle();
110 EXPECT_EQ(1, num_calls);
111 EXPECT_TRUE(service_is_available);
114 TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableMultipleCallbacks) {
115 TestService::Options options;
116 TestService test_service(options);
117 ObjectProxy* object_proxy = bus_->GetObjectProxy(
118 test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
120 // Register two callbacks.
121 int num_calls_1 = 0, num_calls_2 = 0;
122 bool service_is_available_1 = false, service_is_available_2 = false;
123 object_proxy->WaitForServiceToBeAvailable(base::BindOnce(
124 &OnServiceIsAvailable, &service_is_available_1, &num_calls_1));
125 object_proxy->WaitForServiceToBeAvailable(base::BindOnce(
126 &OnServiceIsAvailable, &service_is_available_2, &num_calls_2));
127 base::RunLoop().RunUntilIdle();
128 EXPECT_EQ(0, num_calls_1);
129 EXPECT_EQ(0, num_calls_2);
131 // Start the service and confirm that both callbacks are invoked.
132 ASSERT_TRUE(test_service.StartService());
133 test_service.WaitUntilServiceIsStarted();
134 ASSERT_TRUE(test_service.has_ownership());
137 base::RunLoop().RunUntilIdle();
138 EXPECT_EQ(1, num_calls_1);
139 EXPECT_EQ(1, num_calls_2);
140 EXPECT_TRUE(service_is_available_1);
141 EXPECT_TRUE(service_is_available_2);