• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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