1 /******************************************************************************
2  *
3  *  Copyright (C) 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 <gtest/gtest.h>
20 
21 #include "AlarmTestHarness.h"
22 
23 extern "C" {
24 #include <stdint.h>
25 
26 #include "low_power_manager.h"
27 #include "osi.h"
28 #include "semaphore.h"
29 #include "test_stubs.h"
30 #include "thread.h"
31 #include "vendor.h"
32 }
33 
34 DECLARE_TEST_MODES(
35   init,
36   cleanup,
37   enable_disable
38 );
39 
40 static const low_power_manager_t *manager;
41 static thread_t *thread;
42 static semaphore_t *done;
43 
44 static vendor_cb low_power_state_callback;
45 
flush_work_queue_item(UNUSED_ATTR void * context)46 static void flush_work_queue_item(UNUSED_ATTR void *context) {
47   semaphore_post(done);
48 }
49 
50 STUB_FUNCTION(int, vendor_send_command, (vendor_opcode_t opcode, void *param))
DURING(init)51   DURING(init) AT_CALL(0) {
52     EXPECT_EQ(VENDOR_GET_LPM_IDLE_TIMEOUT, opcode);
53     *((uint32_t *)param) = 100;
54     return 0;
55   }
56 
57   UNEXPECTED_CALL;
58   return 0;
59 }
60 
61 STUB_FUNCTION(int, vendor_send_async_command, (vendor_async_opcode_t opcode, void *param))
62   DURING(enable_disable) {
63     AT_CALL(0) {
64       EXPECT_EQ(VENDOR_SET_LPM_MODE, opcode);
65       EXPECT_EQ(BT_VND_LPM_ENABLE, *(uint8_t *)param);
66       low_power_state_callback(true);
67       thread_post(thread, flush_work_queue_item, NULL);
68       return 0;
69     }
70     AT_CALL(1) {
71       EXPECT_EQ(VENDOR_SET_LPM_MODE, opcode);
72       EXPECT_EQ(BT_VND_LPM_DISABLE, *(uint8_t *)param);
73       low_power_state_callback(true);
74       thread_post(thread, flush_work_queue_item, NULL);
75       return 0;
76     }
77   }
78 
79   UNEXPECTED_CALL;
80   return 0;
81 }
82 
83 STUB_FUNCTION(void, vendor_set_callback, (vendor_async_opcode_t opcode, vendor_cb callback))
84   DURING(init) AT_CALL(0) {
85     EXPECT_EQ(VENDOR_SET_LPM_MODE, opcode);
86     low_power_state_callback = callback;
87     return;
88   }
89 
90   UNEXPECTED_CALL;
91 }
92 
93 static void reset_for(TEST_MODES_T next) {
94   RESET_CALL_COUNT(vendor_send_command);
95   RESET_CALL_COUNT(vendor_send_async_command);
96   RESET_CALL_COUNT(vendor_set_callback);
97   CURRENT_TEST_MODE = next;
98 }
99 
100 class LowPowerManagerTest : public AlarmTestHarness {
101   protected:
102     virtual void SetUp() {
103       AlarmTestHarness::SetUp();
104       low_power_state_callback = NULL;
105       vendor.send_command = vendor_send_command;
106       vendor.send_async_command = vendor_send_async_command;
107       vendor.set_callback = vendor_set_callback;
108       manager = low_power_manager_get_test_interface(&vendor);
109       thread = thread_new("test_thread");
110       done = semaphore_new(0);
111 
112       reset_for(init);
113       manager->init(thread);
114 
115       EXPECT_CALL_COUNT(vendor_send_command, 1);
116       EXPECT_CALL_COUNT(vendor_set_callback, 1);
117     }
118 
119     virtual void TearDown() {
120       reset_for(cleanup);
121       manager->cleanup();
122 
123       semaphore_free(done);
124       thread_free(thread);
125       AlarmTestHarness::TearDown();
126     }
127 
128     vendor_t vendor;
129 };
130 
131 TEST_F(LowPowerManagerTest, test_enable_disable) {
132   reset_for(enable_disable);
133   manager->post_command(LPM_ENABLE);
134   semaphore_wait(done);
135 
136   manager->post_command(LPM_DISABLE);
137   semaphore_wait(done);
138 
139   EXPECT_CALL_COUNT(vendor_send_async_command, 2);
140 }
141