1 // Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <gtest/gtest.h>
6
7 extern "C" {
8 #include "cras_bt_io.h"
9 #include "cras_bt_device.h"
10 #include "cras_iodev.h"
11 #include "cras_main_message.h"
12
13 #define FAKE_OBJ_PATH "/obj/path"
14 }
15
16 static struct cras_iodev *cras_bt_io_create_profile_ret;
17 static struct cras_iodev *cras_bt_io_append_btio_val;
18 static struct cras_ionode* cras_bt_io_get_profile_ret;
19 static unsigned int cras_bt_io_create_called;
20 static unsigned int cras_bt_io_append_called;
21 static unsigned int cras_bt_io_remove_called;
22 static unsigned int cras_bt_io_destroy_called;
23 static enum cras_bt_device_profile cras_bt_io_create_profile_val;
24 static enum cras_bt_device_profile cras_bt_io_append_profile_val;
25 static unsigned int cras_bt_io_try_remove_ret;
26
27 static cras_main_message *cras_main_message_send_msg;
28 static cras_message_callback cras_main_message_add_handler_callback;
29 static void *cras_main_message_add_handler_callback_data;
30
ResetStubData()31 void ResetStubData() {
32 cras_bt_io_get_profile_ret = NULL;
33 cras_bt_io_create_called = 0;
34 cras_bt_io_append_called = 0;
35 cras_bt_io_remove_called = 0;
36 cras_bt_io_destroy_called = 0;
37 cras_bt_io_try_remove_ret = 0;
38 }
39
40 namespace {
41
42 class BtDeviceTestSuite : public testing::Test {
43 protected:
SetUp()44 virtual void SetUp() {
45 ResetStubData();
46 bt_iodev1.direction = CRAS_STREAM_OUTPUT;
47 bt_iodev1.update_active_node = update_active_node;
48 bt_iodev2.direction = CRAS_STREAM_INPUT;
49 bt_iodev2.update_active_node = update_active_node;
50 d1_.direction = CRAS_STREAM_OUTPUT;
51 d1_.update_active_node = update_active_node;
52 d2_.direction = CRAS_STREAM_OUTPUT;
53 d2_.update_active_node = update_active_node;
54 d3_.direction = CRAS_STREAM_INPUT;
55 d3_.update_active_node = update_active_node;
56 }
57
update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)58 static void update_active_node(struct cras_iodev *iodev,
59 unsigned node_idx,
60 unsigned dev_enabled) {
61 }
62
63 struct cras_iodev bt_iodev1;
64 struct cras_iodev bt_iodev2;
65 struct cras_iodev d3_;
66 struct cras_iodev d2_;
67 struct cras_iodev d1_;
68 };
69
TEST(BtDeviceSuite,CreateBtDevice)70 TEST(BtDeviceSuite, CreateBtDevice) {
71 struct cras_bt_device *device;
72
73 device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
74 EXPECT_NE((void *)NULL, device);
75
76 device = cras_bt_device_get(FAKE_OBJ_PATH);
77 EXPECT_NE((void *)NULL, device);
78
79 cras_bt_device_destroy(device);
80 device = cras_bt_device_get(FAKE_OBJ_PATH);
81 EXPECT_EQ((void *)NULL, device);
82 }
83
TEST_F(BtDeviceTestSuite,AppendRmIodev)84 TEST_F(BtDeviceTestSuite, AppendRmIodev) {
85 struct cras_bt_device *device;
86 device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
87 bt_iodev1.nodes = reinterpret_cast<struct cras_ionode*>(0x123);
88 cras_bt_io_create_profile_ret = &bt_iodev1;
89 cras_bt_device_append_iodev(device, &d1_,
90 CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
91 EXPECT_EQ(1, cras_bt_io_create_called);
92 EXPECT_EQ(0, cras_bt_io_append_called);
93 EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE,
94 cras_bt_io_create_profile_val);
95 cras_bt_device_set_active_profile(device,
96 CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
97
98 cras_bt_device_append_iodev(device, &d2_,
99 CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
100 EXPECT_EQ(1, cras_bt_io_create_called);
101 EXPECT_EQ(1, cras_bt_io_append_called);
102 EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY,
103 cras_bt_io_append_profile_val);
104 EXPECT_EQ(&bt_iodev1, cras_bt_io_append_btio_val);
105
106 /* Test HFP disconnected and switch to A2DP. */
107 cras_bt_io_get_profile_ret = bt_iodev1.nodes;
108 cras_bt_io_try_remove_ret = CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
109 cras_bt_device_set_active_profile(
110 device, CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
111 cras_bt_device_rm_iodev(device, &d2_);
112 EXPECT_EQ(1, cras_bt_io_remove_called);
113
114 /* Test A2DP disconnection will cause bt_io destroy. */
115 cras_bt_io_try_remove_ret = 0;
116 cras_bt_device_rm_iodev(device, &d1_);
117 EXPECT_EQ(1, cras_bt_io_remove_called);
118 EXPECT_EQ(1, cras_bt_io_destroy_called);
119 EXPECT_EQ(0, cras_bt_device_get_active_profile(device));
120 }
121
TEST_F(BtDeviceTestSuite,SwitchProfile)122 TEST_F(BtDeviceTestSuite, SwitchProfile) {
123 struct cras_bt_device *device;
124
125 ResetStubData();
126 device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
127 cras_bt_io_create_profile_ret = &bt_iodev1;
128 cras_bt_device_append_iodev(device, &d1_,
129 CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
130 cras_bt_io_create_profile_ret = &bt_iodev2;
131 cras_bt_device_append_iodev(device, &d3_,
132 CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
133
134 cras_bt_device_start_monitor();
135 cras_bt_device_switch_profile_enable_dev(device, &bt_iodev1);
136
137 /* Two bt iodevs were all active. */
138 cras_main_message_add_handler_callback(
139 cras_main_message_send_msg,
140 cras_main_message_add_handler_callback_data);
141
142 /* One bt iodev was active, the other was not. */
143 cras_bt_device_switch_profile_enable_dev(device, &bt_iodev2);
144 cras_main_message_add_handler_callback(
145 cras_main_message_send_msg,
146 cras_main_message_add_handler_callback_data);
147
148 /* Output bt iodev wasn't active, close the active input iodev. */
149 cras_bt_device_switch_profile(device, &bt_iodev2);
150 cras_main_message_add_handler_callback(
151 cras_main_message_send_msg,
152 cras_main_message_add_handler_callback_data);
153 }
154
155 /* Stubs */
156 extern "C" {
157
158 /* From bt_io */
cras_bt_io_create(struct cras_bt_device * device,struct cras_iodev * dev,enum cras_bt_device_profile profile)159 struct cras_iodev *cras_bt_io_create(
160 struct cras_bt_device *device,
161 struct cras_iodev *dev,
162 enum cras_bt_device_profile profile)
163 {
164 cras_bt_io_create_called++;
165 cras_bt_io_create_profile_val = profile;
166 return cras_bt_io_create_profile_ret;
167 }
cras_bt_io_destroy(struct cras_iodev * bt_iodev)168 void cras_bt_io_destroy(struct cras_iodev *bt_iodev)
169 {
170 cras_bt_io_destroy_called++;
171 }
cras_bt_io_get_profile(struct cras_iodev * bt_iodev,enum cras_bt_device_profile profile)172 struct cras_ionode* cras_bt_io_get_profile(
173 struct cras_iodev *bt_iodev,
174 enum cras_bt_device_profile profile)
175 {
176 return cras_bt_io_get_profile_ret;
177 }
cras_bt_io_append(struct cras_iodev * bt_iodev,struct cras_iodev * dev,enum cras_bt_device_profile profile)178 int cras_bt_io_append(struct cras_iodev *bt_iodev,
179 struct cras_iodev *dev,
180 enum cras_bt_device_profile profile)
181 {
182 cras_bt_io_append_called++;
183 cras_bt_io_append_profile_val = profile;
184 cras_bt_io_append_btio_val = bt_iodev;
185 return 0;
186 }
cras_bt_io_on_profile(struct cras_iodev * bt_iodev,enum cras_bt_device_profile profile)187 int cras_bt_io_on_profile(struct cras_iodev *bt_iodev,
188 enum cras_bt_device_profile profile)
189 {
190 return 0;
191 }
cras_bt_io_update_buffer_size(struct cras_iodev * bt_iodev)192 int cras_bt_io_update_buffer_size(struct cras_iodev *bt_iodev)
193 {
194 return 0;
195 }
cras_bt_io_try_remove(struct cras_iodev * bt_iodev,struct cras_iodev * dev)196 unsigned int cras_bt_io_try_remove(struct cras_iodev *bt_iodev,
197 struct cras_iodev *dev)
198 {
199 return cras_bt_io_try_remove_ret;
200 }
cras_bt_io_remove(struct cras_iodev * bt_iodev,struct cras_iodev * dev)201 int cras_bt_io_remove(struct cras_iodev *bt_iodev,
202 struct cras_iodev *dev)
203 {
204 cras_bt_io_remove_called++;
205 return 0;
206 }
207
208 /* From bt_adapter */
cras_bt_adapter_get(const char * object_path)209 struct cras_bt_adapter *cras_bt_adapter_get(const char *object_path)
210 {
211 return NULL;
212 }
cras_bt_adapter_address(const struct cras_bt_adapter * adapter)213 const char *cras_bt_adapter_address(const struct cras_bt_adapter *adapter)
214 {
215 return NULL;
216 }
217
cras_bt_adapter_on_usb(struct cras_bt_adapter * adapter)218 int cras_bt_adapter_on_usb(struct cras_bt_adapter *adapter)
219 {
220 return 1;
221 }
222
223 /* From bt_profile */
cras_bt_profile_on_device_disconnected(struct cras_bt_device * device)224 void cras_bt_profile_on_device_disconnected(struct cras_bt_device *device)
225 {
226 }
227
228 /* From hfp_ag_profile */
cras_hfp_ag_get_slc(struct cras_bt_device * device)229 struct hfp_slc_handle *cras_hfp_ag_get_slc(struct cras_bt_device *device)
230 {
231 return NULL;
232 }
233
cras_hfp_ag_suspend_connected_device(struct cras_bt_device * device)234 void cras_hfp_ag_suspend_connected_device(struct cras_bt_device *device)
235 {
236 }
237
cras_a2dp_suspend_connected_device(struct cras_bt_device * device)238 void cras_a2dp_suspend_connected_device(struct cras_bt_device *device)
239 {
240 }
241
cras_a2dp_start(struct cras_bt_device * device)242 void cras_a2dp_start(struct cras_bt_device *device)
243 {
244 }
245
cras_hfp_ag_start(struct cras_bt_device * device)246 int cras_hfp_ag_start(struct cras_bt_device *device)
247 {
248 return 0;
249 }
250
cras_hfp_ag_suspend()251 void cras_hfp_ag_suspend()
252 {
253 }
254
255 /* From hfp_slc */
hfp_event_speaker_gain(struct hfp_slc_handle * handle,int gain)256 int hfp_event_speaker_gain(struct hfp_slc_handle *handle, int gain)
257 {
258 return 0;
259 }
260
261 /* From iodev_list */
262
cras_iodev_open(struct cras_iodev * dev,unsigned int cb_level)263 int cras_iodev_open(struct cras_iodev *dev, unsigned int cb_level) {
264 return 0;
265 }
266
cras_iodev_close(struct cras_iodev * dev)267 int cras_iodev_close(struct cras_iodev *dev) {
268 return 0;
269 }
270
cras_iodev_list_dev_is_enabled(const struct cras_iodev * dev)271 int cras_iodev_list_dev_is_enabled(const struct cras_iodev *dev)
272 {
273 return 0;
274 }
275
cras_iodev_list_disable_dev(struct cras_iodev * dev)276 void cras_iodev_list_disable_dev(struct cras_iodev *dev)
277 {
278 }
279
cras_iodev_list_enable_dev(struct cras_iodev * dev)280 void cras_iodev_list_enable_dev(struct cras_iodev *dev)
281 {
282 }
283
cras_iodev_list_notify_node_volume(struct cras_ionode * node)284 void cras_iodev_list_notify_node_volume(struct cras_ionode *node)
285 {
286 }
287
cras_main_message_send(struct cras_main_message * msg)288 int cras_main_message_send(struct cras_main_message *msg)
289 {
290 cras_main_message_send_msg = msg;
291 return 0;
292 }
293
cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,cras_message_callback callback,void * callback_data)294 int cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,
295 cras_message_callback callback,
296 void *callback_data)
297 {
298 cras_main_message_add_handler_callback = callback;
299 cras_main_message_add_handler_callback_data = callback_data;
300 return 0;
301 }
302
303 /* From cras_system_state */
cras_system_state_get_tm()304 struct cras_tm *cras_system_state_get_tm()
305 {
306 return NULL;
307 }
308
309 /* From cras_tm */
cras_tm_create_timer(struct cras_tm * tm,unsigned int ms,void (* cb)(struct cras_timer * t,void * data),void * cb_data)310 struct cras_timer *cras_tm_create_timer(
311 struct cras_tm *tm,
312 unsigned int ms,
313 void (*cb)(struct cras_timer *t, void *data),
314 void *cb_data)
315 {
316 return NULL;
317 }
318
cras_tm_cancel_timer(struct cras_tm * tm,struct cras_timer * t)319 void cras_tm_cancel_timer(struct cras_tm *tm, struct cras_timer *t)
320 {
321 }
322
323 } // extern "C"
324 } // namespace
325
main(int argc,char ** argv)326 int main(int argc, char **argv) {
327 ::testing::InitGoogleTest(&argc, argv);
328 return RUN_ALL_TESTS();
329 }
330
331
332