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