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
23extern "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
34DECLARE_TEST_MODES(
35  init,
36  cleanup,
37  enable_disable
38);
39
40static const low_power_manager_t *manager;
41static thread_t *thread;
42static semaphore_t *done;
43
44static vendor_cb low_power_state_callback;
45
46static void flush_work_queue_item(UNUSED_ATTR void *context) {
47  semaphore_post(done);
48}
49
50STUB_FUNCTION(int, vendor_send_command, (vendor_opcode_t opcode, void *param))
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
61STUB_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
83STUB_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
93static 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
100class 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
131TEST_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