bt_device_unittest.cc revision 50cf4aec95391fb7768d9a98e35e618edc7443f3
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
7extern "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
16static struct cras_iodev *cras_bt_io_create_profile_ret;
17static struct cras_iodev *cras_bt_io_append_btio_val;
18static struct cras_ionode* cras_bt_io_get_profile_ret;
19static unsigned int cras_bt_io_create_called;
20static unsigned int cras_bt_io_append_called;
21static unsigned int cras_bt_io_remove_called;
22static unsigned int cras_bt_io_destroy_called;
23static enum cras_bt_device_profile cras_bt_io_create_profile_val;
24static enum cras_bt_device_profile cras_bt_io_append_profile_val;
25static unsigned int cras_bt_io_try_remove_ret;
26
27static cras_main_message *cras_main_message_send_msg;
28static cras_message_callback cras_main_message_add_handler_callback;
29static void *cras_main_message_add_handler_callback_data;
30
31void 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
40namespace {
41
42class BtDeviceTestSuite : public testing::Test {
43  protected:
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
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
70TEST(BtDeviceSuite, CreateBtDevice) {
71  struct cras_bt_device *device;
72
73  device = cras_bt_device_create(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
84TEST_F(BtDeviceTestSuite, AppendRmIodev) {
85  struct cras_bt_device *device;
86  device = cras_bt_device_create(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
122TEST_F(BtDeviceTestSuite, SwitchProfile) {
123  struct cras_bt_device *device;
124
125  ResetStubData();
126  device = cras_bt_device_create(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 */
156extern "C" {
157
158/* From bt_io */
159struct 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}
168void cras_bt_io_destroy(struct cras_iodev *bt_iodev)
169{
170  cras_bt_io_destroy_called++;
171}
172struct 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}
178int 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}
187int cras_bt_io_on_profile(struct cras_iodev *bt_iodev,
188                          enum cras_bt_device_profile profile)
189{
190  return 0;
191}
192int cras_bt_io_update_buffer_size(struct cras_iodev *bt_iodev)
193{
194  return 0;
195}
196unsigned 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}
201int 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 */
209struct cras_bt_adapter *cras_bt_adapter_get(const char *object_path)
210{
211  return NULL;
212}
213const char *cras_bt_adapter_address(const struct cras_bt_adapter *adapter)
214{
215  return NULL;
216}
217
218int cras_bt_adapter_on_usb(struct cras_bt_adapter *adapter)
219{
220  return 1;
221}
222
223/* From bt_profile */
224void cras_bt_profile_on_device_disconnected(struct cras_bt_device *device)
225{
226}
227
228/* From hfp_ag_profile */
229struct hfp_slc_handle *cras_hfp_ag_get_slc(struct cras_bt_device *device)
230{
231  return NULL;
232}
233
234/* From hfp_slc */
235int hfp_event_speaker_gain(struct hfp_slc_handle *handle, int gain)
236{
237  return 0;
238}
239
240/* From iodev_list */
241
242int cras_iodev_open(struct cras_iodev *dev, unsigned int cb_level) {
243  return 0;
244}
245
246int cras_iodev_close(struct cras_iodev *dev) {
247  return 0;
248}
249
250int cras_iodev_list_dev_is_enabled(struct cras_iodev *dev)
251{
252  return 0;
253}
254
255void cras_iodev_list_disable_dev(struct cras_iodev *dev)
256{
257}
258
259void cras_iodev_list_enable_dev(struct cras_iodev *dev)
260{
261}
262
263void cras_iodev_list_notify_node_volume(struct cras_ionode *node)
264{
265}
266
267int cras_main_message_send(struct cras_main_message *msg)
268{
269  cras_main_message_send_msg = msg;
270  return 0;
271}
272
273int cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,
274          cras_message_callback callback,
275          void *callback_data)
276{
277  cras_main_message_add_handler_callback = callback;
278  cras_main_message_add_handler_callback_data = callback_data;
279  return 0;
280}
281
282/* From cras_system_state */
283struct cras_tm *cras_system_state_get_tm()
284{
285  return NULL;
286}
287
288/* From cras_tm */
289struct cras_timer *cras_tm_create_timer(
290    struct cras_tm *tm,
291    unsigned int ms,
292    void (*cb)(struct cras_timer *t, void *data),
293    void *cb_data)
294{
295  return NULL;
296}
297
298void cras_tm_cancel_timer(struct cras_tm *tm, struct cras_timer *t)
299{
300}
301
302} // extern "C"
303} // namespace
304
305int main(int argc, char **argv) {
306  ::testing::InitGoogleTest(&argc, argv);
307  return RUN_ALL_TESTS();
308}
309
310
311