1 /******************************************************************************
2  *
3  *  Copyright 2014 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 
19 #include "osi/include/alarm.h"
20 
21 #include <base/run_loop.h>
22 #include <gtest/gtest.h>
23 #include <hardware/bluetooth.h>
24 
25 #include "common/message_loop_thread.h"
26 #include "osi/include/fixed_queue.h"
27 #include "osi/include/osi.h"
28 #include "osi/include/wakelock.h"
29 #include "osi/semaphore.h"
30 
31 // TODO(b/369381361) Enfore -Wmissing-prototypes
32 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
33 
34 using base::Closure;
35 using bluetooth::common::MessageLoopThread;
36 
37 static semaphore_t* semaphore;
38 static int cb_counter;
39 static int cb_misordered_counter;
40 
41 static const uint64_t EPSILON_MS = 50;
42 
msleep(uint64_t ms)43 static void msleep(uint64_t ms) { usleep(ms * 1000); }
44 
45 static MessageLoopThread* thread_;
46 
get_main_thread()47 bluetooth::common::MessageLoopThread* get_main_thread() { return thread_; }
48 
49 extern int64_t TIMER_INTERVAL_FOR_WAKELOCK_IN_MS;
50 
51 static bool is_wake_lock_acquired = false;
52 
acquire_wake_lock_cb(const char *)53 static int acquire_wake_lock_cb(const char* /*lock_name*/) {
54   is_wake_lock_acquired = true;
55   return BT_STATUS_SUCCESS;
56 }
57 
release_wake_lock_cb(const char *)58 static int release_wake_lock_cb(const char* /*lock_name*/) {
59   is_wake_lock_acquired = false;
60   return BT_STATUS_SUCCESS;
61 }
62 
63 static bt_os_callouts_t bt_wakelock_callouts = {sizeof(bt_os_callouts_t), acquire_wake_lock_cb,
64                                                 release_wake_lock_cb};
65 
66 class AlarmTest : public ::testing::Test {
67 protected:
SetUp()68   void SetUp() override {
69     TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 500;
70 
71     wakelock_set_os_callouts(&bt_wakelock_callouts);
72 
73     cb_counter = 0;
74     cb_misordered_counter = 0;
75 
76     semaphore = semaphore_new(0);
77   }
78 
TearDown()79   void TearDown() override {
80     semaphore_free(semaphore);
81     alarm_cleanup();
82     wakelock_cleanup();
83     wakelock_set_os_callouts(NULL);
84   }
85 };
86 
cb(void *)87 static void cb(void* /* data */) {
88   ++cb_counter;
89   semaphore_post(semaphore);
90 }
91 
ordered_cb(void * data)92 static void ordered_cb(void* data) {
93   int i = PTR_TO_INT(data);
94   if (i != cb_counter) {
95     cb_misordered_counter++;
96   }
97   ++cb_counter;
98   semaphore_post(semaphore);
99 }
100 
TEST_F(AlarmTest,test_new_free_simple)101 TEST_F(AlarmTest, test_new_free_simple) {
102   alarm_t* alarm = alarm_new("alarm_test.test_new_free_simple");
103   ASSERT_TRUE(alarm != NULL);
104   alarm_free(alarm);
105 }
106 
TEST_F(AlarmTest,test_free_null)107 TEST_F(AlarmTest, test_free_null) { alarm_free(NULL); }
108 
TEST_F(AlarmTest,test_simple_cancel)109 TEST_F(AlarmTest, test_simple_cancel) {
110   alarm_t* alarm = alarm_new("alarm_test.test_simple_cancel");
111   alarm_cancel(alarm);
112   alarm_free(alarm);
113 }
114 
TEST_F(AlarmTest,test_cancel)115 TEST_F(AlarmTest, test_cancel) {
116   alarm_t* alarm = alarm_new("alarm_test.test_cancel");
117   alarm_set(alarm, 10, cb, NULL);
118   alarm_cancel(alarm);
119 
120   msleep(10 + EPSILON_MS);
121 
122   EXPECT_EQ(cb_counter, 0);
123   EXPECT_FALSE(is_wake_lock_acquired);
124   alarm_free(alarm);
125 }
126 
TEST_F(AlarmTest,test_cancel_idempotent)127 TEST_F(AlarmTest, test_cancel_idempotent) {
128   alarm_t* alarm = alarm_new("alarm_test.test_cancel_idempotent");
129   alarm_set(alarm, 10, cb, NULL);
130   alarm_cancel(alarm);
131   alarm_cancel(alarm);
132   alarm_cancel(alarm);
133   alarm_free(alarm);
134 }
135 
TEST_F(AlarmTest,test_set_short)136 TEST_F(AlarmTest, test_set_short) {
137   alarm_t* alarm = alarm_new("alarm_test.test_set_short");
138 
139   alarm_set(alarm, 10, cb, NULL);
140 
141   EXPECT_EQ(cb_counter, 0);
142   EXPECT_TRUE(is_wake_lock_acquired);
143 
144   semaphore_wait(semaphore);
145 
146   EXPECT_EQ(cb_counter, 1);
147   EXPECT_FALSE(is_wake_lock_acquired);
148 
149   alarm_free(alarm);
150 }
151 
TEST_F(AlarmTest,test_set_short_periodic)152 TEST_F(AlarmTest, test_set_short_periodic) {
153   alarm_t* alarm = alarm_new_periodic("alarm_test.test_set_short_periodic");
154 
155   alarm_set(alarm, 10, cb, NULL);
156 
157   EXPECT_EQ(cb_counter, 0);
158   EXPECT_TRUE(is_wake_lock_acquired);
159 
160   for (int i = 1; i <= 10; i++) {
161     semaphore_wait(semaphore);
162 
163     EXPECT_GE(cb_counter, i);
164     EXPECT_TRUE(is_wake_lock_acquired);
165   }
166   alarm_cancel(alarm);
167   EXPECT_FALSE(is_wake_lock_acquired);
168 
169   alarm_free(alarm);
170 }
171 
TEST_F(AlarmTest,test_set_zero_periodic)172 TEST_F(AlarmTest, test_set_zero_periodic) {
173   alarm_t* alarm = alarm_new_periodic("alarm_test.test_set_zero_periodic");
174 
175   alarm_set(alarm, 0, cb, NULL);
176 
177   EXPECT_TRUE(is_wake_lock_acquired);
178 
179   for (int i = 1; i <= 10; i++) {
180     semaphore_wait(semaphore);
181 
182     EXPECT_GE(cb_counter, i);
183     EXPECT_TRUE(is_wake_lock_acquired);
184   }
185   alarm_cancel(alarm);
186   EXPECT_FALSE(is_wake_lock_acquired);
187 
188   alarm_free(alarm);
189 }
190 
TEST_F(AlarmTest,test_set_long)191 TEST_F(AlarmTest, test_set_long) {
192   alarm_t* alarm = alarm_new("alarm_test.test_set_long");
193   alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
194 
195   EXPECT_EQ(cb_counter, 0);
196   EXPECT_FALSE(is_wake_lock_acquired);
197 
198   semaphore_wait(semaphore);
199 
200   EXPECT_EQ(cb_counter, 1);
201   EXPECT_FALSE(is_wake_lock_acquired);
202 
203   alarm_free(alarm);
204 }
205 
TEST_F(AlarmTest,test_set_short_short)206 TEST_F(AlarmTest, test_set_short_short) {
207   alarm_t* alarm[2] = {alarm_new("alarm_test.test_set_short_short_0"),
208                        alarm_new("alarm_test.test_set_short_short_1")};
209 
210   alarm_set(alarm[0], 10, cb, NULL);
211   alarm_set(alarm[1], 200, cb, NULL);
212 
213   EXPECT_EQ(cb_counter, 0);
214   EXPECT_TRUE(is_wake_lock_acquired);
215 
216   semaphore_wait(semaphore);
217 
218   EXPECT_EQ(cb_counter, 1);
219   EXPECT_TRUE(is_wake_lock_acquired);
220 
221   semaphore_wait(semaphore);
222 
223   EXPECT_EQ(cb_counter, 2);
224   EXPECT_FALSE(is_wake_lock_acquired);
225 
226   alarm_free(alarm[0]);
227   alarm_free(alarm[1]);
228 }
229 
TEST_F(AlarmTest,test_set_short_long)230 TEST_F(AlarmTest, test_set_short_long) {
231   alarm_t* alarm[2] = {alarm_new("alarm_test.test_set_short_long_0"),
232                        alarm_new("alarm_test.test_set_short_long_1")};
233 
234   alarm_set(alarm[0], 10, cb, NULL);
235   alarm_set(alarm[1], 10 + TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
236 
237   EXPECT_EQ(cb_counter, 0);
238   EXPECT_TRUE(is_wake_lock_acquired);
239 
240   semaphore_wait(semaphore);
241 
242   EXPECT_EQ(cb_counter, 1);
243   EXPECT_FALSE(is_wake_lock_acquired);
244 
245   semaphore_wait(semaphore);
246 
247   EXPECT_EQ(cb_counter, 2);
248   EXPECT_FALSE(is_wake_lock_acquired);
249 
250   alarm_free(alarm[0]);
251   alarm_free(alarm[1]);
252 }
253 
TEST_F(AlarmTest,test_set_long_long)254 TEST_F(AlarmTest, test_set_long_long) {
255   alarm_t* alarm[2] = {alarm_new("alarm_test.test_set_long_long_0"),
256                        alarm_new("alarm_test.test_set_long_long_1")};
257 
258   alarm_set(alarm[0], TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
259   alarm_set(alarm[1], 2 * (TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS), cb, NULL);
260 
261   EXPECT_EQ(cb_counter, 0);
262   EXPECT_FALSE(is_wake_lock_acquired);
263 
264   semaphore_wait(semaphore);
265 
266   EXPECT_EQ(cb_counter, 1);
267   EXPECT_FALSE(is_wake_lock_acquired);
268 
269   semaphore_wait(semaphore);
270 
271   EXPECT_EQ(cb_counter, 2);
272   EXPECT_FALSE(is_wake_lock_acquired);
273 
274   alarm_free(alarm[0]);
275   alarm_free(alarm[1]);
276 }
277 
TEST_F(AlarmTest,test_is_scheduled)278 TEST_F(AlarmTest, test_is_scheduled) {
279   alarm_t* alarm = alarm_new("alarm_test.test_is_scheduled");
280 
281   EXPECT_FALSE(alarm_is_scheduled((alarm_t*)NULL));
282   EXPECT_FALSE(alarm_is_scheduled(alarm));
283   alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
284   EXPECT_TRUE(alarm_is_scheduled(alarm));
285 
286   EXPECT_EQ(cb_counter, 0);
287   EXPECT_FALSE(is_wake_lock_acquired);
288 
289   semaphore_wait(semaphore);
290 
291   EXPECT_FALSE(alarm_is_scheduled(alarm));
292   EXPECT_EQ(cb_counter, 1);
293   EXPECT_FALSE(is_wake_lock_acquired);
294 
295   alarm_free(alarm);
296 }
297 
298 // Test whether the callbacks are invoked in the expected order
TEST_F(AlarmTest,test_callback_ordering)299 TEST_F(AlarmTest, test_callback_ordering) {
300   alarm_t* alarms[100];
301 
302   for (int i = 0; i < 100; i++) {
303     const std::string alarm_name = "alarm_test.test_callback_ordering[" + std::to_string(i) + "]";
304     alarms[i] = alarm_new(alarm_name.c_str());
305   }
306 
307   for (int i = 0; i < 100; i++) {
308     alarm_set(alarms[i], 100, ordered_cb, INT_TO_PTR(i));
309   }
310 
311   for (int i = 1; i <= 100; i++) {
312     semaphore_wait(semaphore);
313     EXPECT_GE(cb_counter, i);
314   }
315   EXPECT_EQ(cb_counter, 100);
316   EXPECT_EQ(cb_misordered_counter, 0);
317 
318   for (int i = 0; i < 100; i++) {
319     alarm_free(alarms[i]);
320   }
321 
322   EXPECT_FALSE(is_wake_lock_acquired);
323 }
324 
325 // Test whether the callbacks are involed in the expected order on a
326 // message loop.
TEST_F(AlarmTest,test_callback_ordering_on_mloop)327 TEST_F(AlarmTest, test_callback_ordering_on_mloop) {
328   alarm_t* alarms[100];
329 
330   // Initialize MesageLoop, and wait till it's initialized.
331   MessageLoopThread message_loop_thread("btu message loop");
332   message_loop_thread.StartUp();
333   if (!message_loop_thread.IsRunning()) {
334     FAIL() << "unable to create btu message loop thread.";
335   }
336   thread_ = &message_loop_thread;
337 
338   for (int i = 0; i < 100; i++) {
339     const std::string alarm_name =
340             "alarm_test.test_callback_ordering_on_mloop[" + std::to_string(i) + "]";
341     alarms[i] = alarm_new(alarm_name.c_str());
342   }
343 
344   for (int i = 0; i < 100; i++) {
345     alarm_set_on_mloop(alarms[i], 100, ordered_cb, INT_TO_PTR(i));
346   }
347 
348   for (int i = 1; i <= 100; i++) {
349     semaphore_wait(semaphore);
350     EXPECT_GE(cb_counter, i);
351   }
352   EXPECT_EQ(cb_counter, 100);
353   EXPECT_EQ(cb_misordered_counter, 0);
354 
355   for (int i = 0; i < 100; i++) {
356     alarm_free(alarms[i]);
357   }
358 
359   message_loop_thread.ShutDown();
360   EXPECT_FALSE(is_wake_lock_acquired);
361 }
362 
363 // Try to catch any race conditions between the timer callback and |alarm_free|.
TEST_F(AlarmTest,test_callback_free_race)364 TEST_F(AlarmTest, test_callback_free_race) {
365   for (int i = 0; i < 1000; ++i) {
366     const std::string alarm_name = "alarm_test.test_callback_free_race[" + std::to_string(i) + "]";
367     alarm_t* alarm = alarm_new(alarm_name.c_str());
368     alarm_set(alarm, 0, cb, NULL);
369     alarm_free(alarm);
370   }
371   alarm_cleanup();
372 }
373 
remove_cb(void * data)374 static void remove_cb(void* data) {
375   alarm_free((alarm_t*)data);
376   semaphore_post(semaphore);
377 }
378 
TEST_F(AlarmTest,test_delete_during_callback)379 TEST_F(AlarmTest, test_delete_during_callback) {
380   for (int i = 0; i < 1000; ++i) {
381     alarm_t* alarm = alarm_new("alarm_test.test_delete_during_callback");
382     alarm_set(alarm, 0, remove_cb, alarm);
383     semaphore_wait(semaphore);
384   }
385   alarm_cleanup();
386 }
387