1 /* Copyright 2019 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
6 #include <gtest/gtest.h>
7
8 extern "C" {
9 #include "cras_bt_log.h"
10 #include "cras_bt_profile.h"
11 #include "cras_hfp_ag_profile.h"
12 #include "cras_iodev.h"
13 }
14
15 static int with_sco_pcm;
16 static struct cras_iodev fake_sco_out, fake_sco_in;
17 static struct cras_bt_device* fake_device;
18 static struct cras_bt_profile* internal_bt_profile;
19
20 static size_t hfp_alsa_iodev_create_called;
21 static size_t hfp_alsa_iodev_destroy_called;
22 static size_t hfp_iodev_create_called;
23 static size_t hfp_iodev_destroy_called;
24 static size_t cras_bt_device_notify_profile_dropped_called;
25 static struct cras_bt_device* cras_bt_device_notify_profile_dropped_dev;
26 static enum cras_bt_device_profile
27 cras_bt_device_notify_profile_dropped_profile;
28
ResetStubData()29 static void ResetStubData() {
30 hfp_alsa_iodev_create_called = 0;
31 hfp_alsa_iodev_destroy_called = 0;
32 hfp_iodev_create_called = 0;
33 hfp_iodev_destroy_called = 0;
34 cras_bt_device_notify_profile_dropped_called = 0;
35 }
36
37 namespace {
38
39 class HfpAgProfile : public testing::Test {
40 protected:
SetUp()41 virtual void SetUp() {
42 btlog = cras_bt_event_log_init();
43 ResetStubData();
44 }
45
TearDown()46 virtual void TearDown() { cras_bt_event_log_deinit(btlog); }
47 };
48
TEST_F(HfpAgProfile,StartWithoutScoPCM)49 TEST_F(HfpAgProfile, StartWithoutScoPCM) {
50 int ret;
51 struct cras_bt_profile* bt_profile;
52
53 with_sco_pcm = 0;
54 fake_device = (struct cras_bt_device*)0xdeadbeef;
55 /* to get the cras_hfp_ag_profile */
56 cras_hfp_ag_profile_create(NULL);
57 bt_profile = internal_bt_profile;
58 bt_profile->new_connection(NULL, bt_profile, fake_device, 0);
59
60 ret = cras_hfp_ag_start(fake_device);
61
62 EXPECT_EQ(0, ret);
63 EXPECT_EQ(2, hfp_iodev_create_called);
64
65 /* Start ag twice won't create more iodev. */
66 ret = cras_hfp_ag_start(fake_device);
67 EXPECT_EQ(0, ret);
68 EXPECT_EQ(2, hfp_iodev_create_called);
69
70 bt_profile->release(bt_profile);
71
72 EXPECT_EQ(2, hfp_iodev_destroy_called);
73 }
74
TEST_F(HfpAgProfile,StartWithScoPCM)75 TEST_F(HfpAgProfile, StartWithScoPCM) {
76 int ret;
77 struct cras_bt_profile* bt_profile;
78
79 with_sco_pcm = 1;
80 fake_device = (struct cras_bt_device*)0xdeadbeef;
81 /* to get the cras_hfp_ag_profile */
82 cras_hfp_ag_profile_create(NULL);
83 bt_profile = internal_bt_profile;
84 bt_profile->new_connection(NULL, bt_profile, fake_device, 0);
85
86 ret = cras_hfp_ag_start(fake_device);
87
88 EXPECT_EQ(0, ret);
89 EXPECT_EQ(2, hfp_alsa_iodev_create_called);
90
91 bt_profile->release(bt_profile);
92
93 EXPECT_EQ(2, hfp_alsa_iodev_destroy_called);
94 }
95
TEST_F(HfpAgProfile,RemoveConflictAG)96 TEST_F(HfpAgProfile, RemoveConflictAG) {
97 struct cras_bt_profile* bt_profile;
98 struct cras_bt_device* new_dev =
99 reinterpret_cast<struct cras_bt_device*>(0x123);
100 ;
101
102 with_sco_pcm = 0;
103 fake_device = (struct cras_bt_device*)0xdeadbeef;
104 /* to get the cras_hfp_ag_profile */
105 cras_hfp_ag_profile_create(NULL);
106 bt_profile = internal_bt_profile;
107 bt_profile->new_connection(NULL, bt_profile, fake_device, 0);
108
109 bt_profile->new_connection(NULL, bt_profile, new_dev, 0);
110
111 /* Expect removing conflict of new_dev triggers profile drop on
112 * fake_device. */
113 cras_hfp_ag_remove_conflict(new_dev);
114 EXPECT_EQ(1, cras_bt_device_notify_profile_dropped_called);
115 EXPECT_EQ(fake_device, cras_bt_device_notify_profile_dropped_dev);
116 EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE,
117 cras_bt_device_notify_profile_dropped_profile);
118
119 bt_profile->release(bt_profile);
120 }
121
122 } // namespace
123
124 extern "C" {
125
126 struct cras_bt_event_log* btlog;
127
cras_iodev_list_get_sco_pcm_iodev(enum CRAS_STREAM_DIRECTION direction)128 struct cras_iodev* cras_iodev_list_get_sco_pcm_iodev(
129 enum CRAS_STREAM_DIRECTION direction) {
130 if (with_sco_pcm) {
131 if (direction == CRAS_STREAM_OUTPUT)
132 return &fake_sco_out;
133 else
134 return &fake_sco_in;
135 }
136
137 return NULL;
138 }
139
hfp_alsa_iodev_create(enum CRAS_STREAM_DIRECTION dir,struct cras_bt_device * device,struct hfp_slc_handle * slc,enum cras_bt_device_profile profile)140 struct cras_iodev* hfp_alsa_iodev_create(enum CRAS_STREAM_DIRECTION dir,
141 struct cras_bt_device* device,
142 struct hfp_slc_handle* slc,
143 enum cras_bt_device_profile profile) {
144 hfp_alsa_iodev_create_called++;
145 return (struct cras_iodev*)0xdeadbeef;
146 }
147
hfp_alsa_iodev_destroy(struct cras_iodev * iodev)148 void hfp_alsa_iodev_destroy(struct cras_iodev* iodev) {
149 hfp_alsa_iodev_destroy_called++;
150 }
151
hfp_iodev_create(enum CRAS_STREAM_DIRECTION dir,struct cras_bt_device * device,struct hfp_slc_handle * slc,enum cras_bt_device_profile profile,struct hfp_info * info)152 struct cras_iodev* hfp_iodev_create(enum CRAS_STREAM_DIRECTION dir,
153 struct cras_bt_device* device,
154 struct hfp_slc_handle* slc,
155 enum cras_bt_device_profile profile,
156 struct hfp_info* info) {
157 hfp_iodev_create_called++;
158 return (struct cras_iodev*)0xdeadbeef;
159 }
160
hfp_iodev_destroy(struct cras_iodev * iodev)161 void hfp_iodev_destroy(struct cras_iodev* iodev) {
162 hfp_iodev_destroy_called++;
163 }
164
cras_bt_add_profile(DBusConnection * conn,struct cras_bt_profile * profile)165 int cras_bt_add_profile(DBusConnection* conn, struct cras_bt_profile* profile) {
166 internal_bt_profile = profile;
167 return 0;
168 }
169
cras_bt_rm_profile(DBusConnection * conn,struct cras_bt_profile * profile)170 int cras_bt_rm_profile(DBusConnection* conn, struct cras_bt_profile* profile) {
171 internal_bt_profile = NULL;
172 return 0;
173 }
174
cras_bt_register_profile(DBusConnection * conn,struct cras_bt_profile * profile)175 int cras_bt_register_profile(DBusConnection* conn,
176 struct cras_bt_profile* profile) {
177 return 0;
178 }
179
cras_bt_register_profiles(DBusConnection * conn)180 int cras_bt_register_profiles(DBusConnection* conn) {
181 return 0;
182 }
183
cras_bt_unregister_profile(DBusConnection * conn,struct cras_bt_profile * profile)184 int cras_bt_unregister_profile(DBusConnection* conn,
185 struct cras_bt_profile* profile) {
186 return 0;
187 }
188
hfp_info_create()189 struct hfp_info* hfp_info_create() {
190 return NULL;
191 }
192
hfp_info_running(struct hfp_info * info)193 int hfp_info_running(struct hfp_info* info) {
194 return 0;
195 }
196
hfp_info_stop(struct hfp_info * info)197 int hfp_info_stop(struct hfp_info* info) {
198 return 0;
199 }
200
hfp_info_destroy(struct hfp_info * info)201 void hfp_info_destroy(struct hfp_info* info) {}
202
hfp_slc_destroy(struct hfp_slc_handle * slc_handle)203 void hfp_slc_destroy(struct hfp_slc_handle* slc_handle) {}
204
cras_bt_device_has_a2dp(struct cras_bt_device * device)205 int cras_bt_device_has_a2dp(struct cras_bt_device* device) {
206 return 0;
207 }
208
cras_bt_device_disconnect(DBusConnection * conn,struct cras_bt_device * device)209 int cras_bt_device_disconnect(DBusConnection* conn,
210 struct cras_bt_device* device) {
211 return 0;
212 }
213
cras_bt_device_name(const struct cras_bt_device * device)214 const char* cras_bt_device_name(const struct cras_bt_device* device) {
215 return NULL;
216 }
217
cras_bt_device_set_append_iodev_cb(struct cras_bt_device * device,void (* cb)(void * data))218 void cras_bt_device_set_append_iodev_cb(struct cras_bt_device* device,
219 void (*cb)(void* data)) {}
220
cras_bt_device_profile_from_uuid(const char * uuid)221 enum cras_bt_device_profile cras_bt_device_profile_from_uuid(const char* uuid) {
222 return CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
223 }
224
cras_bt_device_adapter(const struct cras_bt_device * device)225 struct cras_bt_adapter* cras_bt_device_adapter(
226 const struct cras_bt_device* device) {
227 return reinterpret_cast<struct cras_bt_adapter*>(0x123);
228 }
229
cras_bt_adapter_wbs_supported(struct cras_bt_adapter * adapter)230 int cras_bt_adapter_wbs_supported(struct cras_bt_adapter* adapter) {
231 return 1;
232 }
233
hfp_slc_create(int fd,int is_hsp,int ag_supported_features,struct cras_bt_device * device,hfp_slc_init_cb init_cb,hfp_slc_disconnect_cb disconnect_cb)234 struct hfp_slc_handle* hfp_slc_create(int fd,
235 int is_hsp,
236 int ag_supported_features,
237 struct cras_bt_device* device,
238 hfp_slc_init_cb init_cb,
239 hfp_slc_disconnect_cb disconnect_cb) {
240 return NULL;
241 }
242
hfp_slc_get_selected_codec(struct hfp_slc_handle * handle)243 int hfp_slc_get_selected_codec(struct hfp_slc_handle* handle) {
244 return HFP_CODEC_ID_CVSD;
245 }
hfp_slc_get_ag_codec_negotiation_supported(struct hfp_slc_handle * handle)246 int hfp_slc_get_ag_codec_negotiation_supported(struct hfp_slc_handle* handle) {
247 return 1;
248 }
249
hfp_slc_get_hf_codec_negotiation_supported(struct hfp_slc_handle * handle)250 int hfp_slc_get_hf_codec_negotiation_supported(struct hfp_slc_handle* handle) {
251 return 1;
252 }
253
hfp_slc_get_hf_supports_battery_indicator(struct hfp_slc_handle * handle)254 int hfp_slc_get_hf_supports_battery_indicator(struct hfp_slc_handle* handle) {
255 return 0;
256 }
257
hfp_slc_get_hf_battery_level(struct hfp_slc_handle * handle)258 int hfp_slc_get_hf_battery_level(struct hfp_slc_handle* handle) {
259 return -1;
260 }
261
cras_a2dp_connected_device()262 struct cras_bt_device* cras_a2dp_connected_device() {
263 return NULL;
264 }
265
cras_bt_device_supports_profile(const struct cras_bt_device * device,enum cras_bt_device_profile profile)266 int cras_bt_device_supports_profile(const struct cras_bt_device* device,
267 enum cras_bt_device_profile profile) {
268 return 0;
269 }
270
cras_a2dp_suspend_connected_device(struct cras_bt_device * device)271 void cras_a2dp_suspend_connected_device(struct cras_bt_device* device) {}
272
cras_bt_device_address(const struct cras_bt_device * device)273 const char* cras_bt_device_address(const struct cras_bt_device* device) {
274 return "";
275 }
276
cras_bt_device_audio_gateway_initialized(struct cras_bt_device * device)277 int cras_bt_device_audio_gateway_initialized(struct cras_bt_device* device) {
278 return 0;
279 }
280
cras_bt_device_notify_profile_dropped(struct cras_bt_device * device,enum cras_bt_device_profile profile)281 void cras_bt_device_notify_profile_dropped(
282 struct cras_bt_device* device,
283 enum cras_bt_device_profile profile) {
284 cras_bt_device_notify_profile_dropped_called++;
285 cras_bt_device_notify_profile_dropped_dev = device;
286 cras_bt_device_notify_profile_dropped_profile = profile;
287 }
288
hfp_info_set_wbs_logger(struct hfp_info * info,struct packet_status_logger * wbs_logger)289 void hfp_info_set_wbs_logger(struct hfp_info* info,
290 struct packet_status_logger* wbs_logger) {}
291
cras_observer_notify_bt_battery_changed(const char * address,uint32_t level)292 void cras_observer_notify_bt_battery_changed(const char* address,
293 uint32_t level) {
294 return;
295 }
296
cras_system_get_bt_wbs_enabled()297 bool cras_system_get_bt_wbs_enabled() {
298 return true;
299 }
300
cras_server_metrics_hfp_wideband_selected_codec(int codec)301 int cras_server_metrics_hfp_wideband_selected_codec(int codec) {
302 return HFP_CODEC_ID_MSBC;
303 }
304
305 } // extern "C"
306
main(int argc,char ** argv)307 int main(int argc, char** argv) {
308 ::testing::InitGoogleTest(&argc, argv);
309 return RUN_ALL_TESTS();
310 }
311