1 /******************************************************************************
2 *
3 * Copyright 2020 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include <optional>
19 #include <unordered_map>
20
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23
24 #include "flatbuffers/flatbuffers.h"
25
26 #include "common/bind.h"
27 #include "os/handler.h"
28 #include "os/thread.h"
29 #include "os/wakelock_manager.h"
30 #include "wakelock_manager_generated.h"
31
32 namespace testing {
33
34 using bluetooth::os::FinishWakelockManagerDataBuffer;
35 using bluetooth::os::GetWakelockManagerData;
36 using bluetooth::os::Handler;
37 using bluetooth::os::Thread;
38 using bluetooth::os::WakelockManager;
39 using bluetooth::os::WakelockManagerData;
40 using bluetooth::os::WakelockManagerDataBuilder;
41
42 class TestOsCallouts : public WakelockManager::OsCallouts {
43 public:
AcquireCallout(const std::string & lock_name)44 void AcquireCallout(const std::string& lock_name) override {
45 auto iter = acquired_lock_counts.find(lock_name);
46 if (iter == acquired_lock_counts.end()) {
47 acquired_lock_counts[lock_name] = 0;
48 }
49 acquired_lock_counts[lock_name] += 1;
50 }
51
ReleaseCallout(const std::string & lock_name)52 void ReleaseCallout(const std::string& lock_name) override {
53 auto iter = acquired_lock_counts.find(lock_name);
54 if (iter == acquired_lock_counts.end()) {
55 acquired_lock_counts[lock_name] = 0;
56 }
57 acquired_lock_counts[lock_name] -= 1;
58 }
59
GetNetAcquiredCount(const std::string & lock_name) const60 std::optional<int> GetNetAcquiredCount(const std::string& lock_name) const {
61 auto iter = acquired_lock_counts.find(lock_name);
62 if (iter == acquired_lock_counts.end()) {
63 return std::nullopt;
64 }
65 return iter->second;
66 }
67
68 // how many times each lock is acquired, net, can go negative
69 std::unordered_map<std::string, int> acquired_lock_counts;
70 };
71
72 class WakelockManagerTest : public Test {
73 protected:
SetUp()74 void SetUp() override {
75 thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
76 handler_ = new Handler(thread_);
77 }
TearDown()78 void TearDown() override {
79 handler_->Clear();
80 delete handler_;
81 delete thread_;
82 }
83
SyncHandler()84 void SyncHandler() {
85 std::promise<void> promise;
86 auto future = promise.get_future();
87 handler_->Post(
88 bluetooth::common::BindOnce(&std::promise<void>::set_value, bluetooth::common::Unretained(&promise)));
89 auto future_status = future.wait_for(std::chrono::seconds(1));
90 ASSERT_EQ(future_status, std::future_status::ready);
91 }
92
93 Handler* handler_;
94 Thread* thread_;
95 };
96
TEST_F(WakelockManagerTest,test_set_os_callouts_repeated_acquire)97 TEST_F(WakelockManagerTest, test_set_os_callouts_repeated_acquire) {
98 TestOsCallouts os_callouts;
99 WakelockManager::Get().SetOsCallouts(&os_callouts, handler_);
100
101 // Initially, no wakelock is acquired
102 ASSERT_TRUE(os_callouts.acquired_lock_counts.empty());
103 ASSERT_FALSE(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId));
104
105 WakelockManager::Get().Acquire();
106 SyncHandler();
107 ASSERT_EQ(os_callouts.acquired_lock_counts.size(), 1);
108 ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(1)));
109
110 WakelockManager::Get().Acquire();
111 SyncHandler();
112 ASSERT_EQ(os_callouts.acquired_lock_counts.size(), 1);
113 ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(2)));
114
115 WakelockManager::Get().Release();
116 SyncHandler();
117 ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(1)));
118
119 WakelockManager::Get().CleanUp();
120 SyncHandler();
121 }
122
TEST_F(WakelockManagerTest,test_set_os_callouts_repeated_release)123 TEST_F(WakelockManagerTest, test_set_os_callouts_repeated_release) {
124 TestOsCallouts os_callouts;
125 WakelockManager::Get().SetOsCallouts(&os_callouts, handler_);
126
127 // Initially, no wakelock is acquired
128 ASSERT_TRUE(os_callouts.acquired_lock_counts.empty());
129 ASSERT_FALSE(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId));
130
131 WakelockManager::Get().Acquire();
132 SyncHandler();
133 ASSERT_EQ(os_callouts.acquired_lock_counts.size(), 1);
134 ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(1)));
135
136 WakelockManager::Get().Release();
137 SyncHandler();
138 ASSERT_EQ(os_callouts.acquired_lock_counts.size(), 1);
139 ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(0)));
140
141 // OS callouts allow pass through for repeated release calls
142 WakelockManager::Get().Release();
143 SyncHandler();
144 ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(-1)));
145
146 WakelockManager::Get().CleanUp();
147 SyncHandler();
148 }
149
TEST_F(WakelockManagerTest,test_with_os_callouts_in_a_loop_and_dump)150 TEST_F(WakelockManagerTest, test_with_os_callouts_in_a_loop_and_dump) {
151 TestOsCallouts os_callouts;
152 WakelockManager::Get().SetOsCallouts(&os_callouts, handler_);
153
154 // Initially, no wakelock is acquired
155 ASSERT_TRUE(os_callouts.acquired_lock_counts.empty());
156 ASSERT_FALSE(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId));
157
158 for (size_t i = 0; i < 1000; i++) {
159 WakelockManager::Get().Acquire();
160 SyncHandler();
161 ASSERT_EQ(os_callouts.acquired_lock_counts.size(), 1);
162 ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(1)));
163 WakelockManager::Get().Release();
164 SyncHandler();
165 ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(0)));
166 }
167
168 {
169 flatbuffers::FlatBufferBuilder builder(1024);
170 auto offset = WakelockManager::Get().GetDumpsysData(&builder);
171 FinishWakelockManagerDataBuffer(builder, offset);
172 auto data = GetWakelockManagerData(builder.GetBufferPointer());
173
174 ASSERT_EQ(data->acquired_count(), 1000);
175 ASSERT_EQ(data->released_count(), 1000);
176 }
177
178 WakelockManager::Get().CleanUp();
179 SyncHandler();
180
181 {
182 flatbuffers::FlatBufferBuilder builder(1024);
183 auto offset = WakelockManager::Get().GetDumpsysData(&builder);
184 FinishWakelockManagerDataBuffer(builder, offset);
185 auto data = GetWakelockManagerData(builder.GetBufferPointer());
186
187 ASSERT_EQ(data->acquired_count(), 0);
188 ASSERT_EQ(data->released_count(), 0);
189 }
190 }
191
192 } // namespace testing
193