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 "os/wakelock_manager.h"
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include <optional>
24 #include <unordered_map>
25 
26 #include "common/bind.h"
27 #include "os/handler.h"
28 #include "os/thread.h"
29 
30 namespace testing {
31 
32 using bluetooth::os::Handler;
33 using bluetooth::os::Thread;
34 using bluetooth::os::WakelockManager;
35 
36 class TestOsCallouts : public WakelockManager::OsCallouts {
37 public:
AcquireCallout(const std::string & lock_name)38   void AcquireCallout(const std::string& lock_name) override {
39     auto iter = acquired_lock_counts.find(lock_name);
40     if (iter == acquired_lock_counts.end()) {
41       acquired_lock_counts[lock_name] = 0;
42     }
43     acquired_lock_counts[lock_name] += 1;
44   }
45 
ReleaseCallout(const std::string & lock_name)46   void ReleaseCallout(const std::string& lock_name) override {
47     auto iter = acquired_lock_counts.find(lock_name);
48     if (iter == acquired_lock_counts.end()) {
49       acquired_lock_counts[lock_name] = 0;
50     }
51     acquired_lock_counts[lock_name] -= 1;
52   }
53 
GetNetAcquiredCount(const std::string & lock_name) const54   std::optional<int> GetNetAcquiredCount(const std::string& lock_name) const {
55     auto iter = acquired_lock_counts.find(lock_name);
56     if (iter == acquired_lock_counts.end()) {
57       return std::nullopt;
58     }
59     return iter->second;
60   }
61 
62   // how many times each lock is acquired, net, can go negative
63   std::unordered_map<std::string, int> acquired_lock_counts;
64 };
65 
66 class WakelockManagerTest : public Test {
67 protected:
SetUp()68   void SetUp() override {
69     thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
70     handler_ = new Handler(thread_);
71   }
TearDown()72   void TearDown() override {
73     handler_->Clear();
74     delete handler_;
75     delete thread_;
76   }
77 
SyncHandler()78   void SyncHandler() {
79     std::promise<void> promise;
80     auto future = promise.get_future();
81     handler_->Post(bluetooth::common::BindOnce(&std::promise<void>::set_value,
82                                                bluetooth::common::Unretained(&promise)));
83     auto future_status = future.wait_for(std::chrono::seconds(1));
84     ASSERT_EQ(future_status, std::future_status::ready);
85   }
86 
87   Handler* handler_;
88   Thread* thread_;
89 };
90 
TEST_F(WakelockManagerTest,test_set_os_callouts_repeated_acquire)91 TEST_F(WakelockManagerTest, test_set_os_callouts_repeated_acquire) {
92   TestOsCallouts os_callouts;
93   WakelockManager::Get().SetOsCallouts(&os_callouts, handler_);
94 
95   // Initially, no wakelock is acquired
96   ASSERT_TRUE(os_callouts.acquired_lock_counts.empty());
97   ASSERT_FALSE(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId));
98 
99   WakelockManager::Get().Acquire();
100   SyncHandler();
101   ASSERT_EQ(os_callouts.acquired_lock_counts.size(), (size_t)1);
102   ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(1)));
103 
104   WakelockManager::Get().Acquire();
105   SyncHandler();
106   ASSERT_EQ(os_callouts.acquired_lock_counts.size(), (size_t)1);
107   ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(2)));
108 
109   WakelockManager::Get().Release();
110   SyncHandler();
111   ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(1)));
112 
113   WakelockManager::Get().CleanUp();
114   SyncHandler();
115 }
116 
TEST_F(WakelockManagerTest,test_set_os_callouts_repeated_release)117 TEST_F(WakelockManagerTest, test_set_os_callouts_repeated_release) {
118   TestOsCallouts os_callouts;
119   WakelockManager::Get().SetOsCallouts(&os_callouts, handler_);
120 
121   // Initially, no wakelock is acquired
122   ASSERT_TRUE(os_callouts.acquired_lock_counts.empty());
123   ASSERT_FALSE(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId));
124 
125   WakelockManager::Get().Acquire();
126   SyncHandler();
127   ASSERT_EQ(os_callouts.acquired_lock_counts.size(), (size_t)1);
128   ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(1)));
129 
130   WakelockManager::Get().Release();
131   SyncHandler();
132   ASSERT_EQ(os_callouts.acquired_lock_counts.size(), (size_t)1);
133   ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(0)));
134 
135   // OS callouts allow pass through for repeated release calls
136   WakelockManager::Get().Release();
137   SyncHandler();
138   ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(-1)));
139 
140   WakelockManager::Get().CleanUp();
141   SyncHandler();
142 }
143 
TEST_F(WakelockManagerTest,test_with_os_callouts_in_a_loop_and_dump)144 TEST_F(WakelockManagerTest, test_with_os_callouts_in_a_loop_and_dump) {
145   TestOsCallouts os_callouts;
146   WakelockManager::Get().SetOsCallouts(&os_callouts, handler_);
147 
148   // Initially, no wakelock is acquired
149   ASSERT_TRUE(os_callouts.acquired_lock_counts.empty());
150   ASSERT_FALSE(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId));
151 
152   for (size_t i = 0; i < 1000; i++) {
153     WakelockManager::Get().Acquire();
154     SyncHandler();
155     ASSERT_EQ(os_callouts.acquired_lock_counts.size(), (size_t)1);
156     ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(1)));
157     WakelockManager::Get().Release();
158     SyncHandler();
159     ASSERT_THAT(os_callouts.GetNetAcquiredCount(WakelockManager::kBtWakelockId), Optional(Eq(0)));
160   }
161 
162   WakelockManager::Get().CleanUp();
163   SyncHandler();
164 }
165 
166 }  // namespace testing
167