• 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_constants.h"
9 #include "cras_bt_device.h"
10 #include "cras_bt_io.h"
11 #include "cras_bt_log.h"
12 #include "cras_iodev.h"
13 #include "cras_main_message.h"
14 
15 #define FAKE_OBJ_PATH "/obj/path"
16 }
17 
18 static struct cras_iodev* cras_bt_io_create_profile_ret;
19 static struct cras_iodev* cras_bt_io_append_btio_val;
20 static struct cras_ionode* cras_bt_io_get_profile_ret;
21 static unsigned int cras_bt_io_create_called;
22 static unsigned int cras_bt_io_append_called;
23 static unsigned int cras_bt_io_remove_called;
24 static unsigned int cras_bt_io_destroy_called;
25 static enum cras_bt_device_profile cras_bt_io_create_profile_val;
26 static enum cras_bt_device_profile cras_bt_io_append_profile_val;
27 static unsigned int cras_bt_io_try_remove_ret;
28 
29 static cras_main_message* cras_main_message_send_msg;
30 static cras_message_callback cras_main_message_add_handler_callback;
31 static void* cras_main_message_add_handler_callback_data;
32 static int cras_tm_create_timer_called;
33 static int cras_a2dp_start_called;
34 static int cras_a2dp_suspend_connected_device_called;
35 static int cras_hfp_ag_remove_conflict_called;
36 static int cras_hfp_ag_start_called;
37 static int cras_hfp_ag_suspend_connected_device_called;
38 static void (*cras_tm_create_timer_cb)(struct cras_timer* t, void* data);
39 static void* cras_tm_create_timer_cb_data;
40 static int dbus_message_new_method_call_called;
41 static const char* dbus_message_new_method_call_method;
42 static struct cras_bt_device* cras_a2dp_connected_device_ret;
43 static struct cras_bt_device* cras_a2dp_suspend_connected_device_dev;
44 
45 struct MockDBusMessage {
46   int type;
47   void* value;
48   MockDBusMessage* next;
49   MockDBusMessage* recurse;
50 };
51 
ResetStubData()52 void ResetStubData() {
53   cras_bt_io_get_profile_ret = NULL;
54   cras_bt_io_create_called = 0;
55   cras_bt_io_append_called = 0;
56   cras_bt_io_remove_called = 0;
57   cras_bt_io_destroy_called = 0;
58   cras_bt_io_try_remove_ret = 0;
59   cras_main_message_send_msg = NULL;
60   cras_tm_create_timer_called = 0;
61   cras_a2dp_start_called = 0;
62   cras_a2dp_suspend_connected_device_called = 0;
63   cras_hfp_ag_remove_conflict_called = 0;
64   cras_hfp_ag_start_called = 0;
65   cras_hfp_ag_suspend_connected_device_called = 0;
66   dbus_message_new_method_call_method = NULL;
67   dbus_message_new_method_call_called = 0;
68   cras_a2dp_connected_device_ret = NULL;
69 }
70 
FreeMockDBusMessage(MockDBusMessage * head)71 static void FreeMockDBusMessage(MockDBusMessage* head) {
72   if (head->next != NULL)
73     FreeMockDBusMessage(head->next);
74   if (head->recurse != NULL)
75     FreeMockDBusMessage(head->recurse);
76   if (head->type == DBUS_TYPE_STRING)
77     free((char*)head->value);
78   delete head;
79 }
80 
NewMockDBusConnectedMessage()81 static struct MockDBusMessage* NewMockDBusConnectedMessage() {
82   MockDBusMessage* msg = new MockDBusMessage{DBUS_TYPE_ARRAY, NULL};
83   MockDBusMessage* dict =
84       new MockDBusMessage{DBUS_TYPE_STRING, (void*)strdup("Connected")};
85   MockDBusMessage* variant = new MockDBusMessage{DBUS_TYPE_BOOLEAN, (void*)1};
86 
87   msg->recurse = dict;
88   dict->next = new MockDBusMessage{DBUS_TYPE_INVALID, NULL};
89   dict->next->recurse = variant;
90   return msg;
91 }
92 
93 namespace {
94 
95 class BtDeviceTestSuite : public testing::Test {
96  protected:
SetUp()97   virtual void SetUp() {
98     ResetStubData();
99     bt_iodev1.direction = CRAS_STREAM_OUTPUT;
100     bt_iodev1.update_active_node = update_active_node;
101     bt_iodev2.direction = CRAS_STREAM_INPUT;
102     bt_iodev2.update_active_node = update_active_node;
103     d1_.direction = CRAS_STREAM_OUTPUT;
104     d1_.update_active_node = update_active_node;
105     d2_.direction = CRAS_STREAM_OUTPUT;
106     d2_.update_active_node = update_active_node;
107     d3_.direction = CRAS_STREAM_INPUT;
108     d3_.update_active_node = update_active_node;
109     btlog = cras_bt_event_log_init();
110   }
111 
TearDown()112   virtual void TearDown() {
113     if (cras_main_message_send_msg)
114       free(cras_main_message_send_msg);
115     cras_bt_event_log_deinit(btlog);
116   }
117 
update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)118   static void update_active_node(struct cras_iodev* iodev,
119                                  unsigned node_idx,
120                                  unsigned dev_enabled) {}
121 
122   struct cras_iodev bt_iodev1;
123   struct cras_iodev bt_iodev2;
124   struct cras_iodev d3_;
125   struct cras_iodev d2_;
126   struct cras_iodev d1_;
127 };
128 
TEST(BtDeviceSuite,CreateBtDevice)129 TEST(BtDeviceSuite, CreateBtDevice) {
130   struct cras_bt_device* device;
131 
132   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
133   EXPECT_NE((void*)NULL, device);
134 
135   device = cras_bt_device_get(FAKE_OBJ_PATH);
136   EXPECT_NE((void*)NULL, device);
137 
138   cras_bt_device_remove(device);
139   device = cras_bt_device_get(FAKE_OBJ_PATH);
140   EXPECT_EQ((void*)NULL, device);
141 }
142 
TEST_F(BtDeviceTestSuite,AppendRmIodev)143 TEST_F(BtDeviceTestSuite, AppendRmIodev) {
144   struct cras_bt_device* device;
145   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
146   bt_iodev1.nodes = reinterpret_cast<struct cras_ionode*>(0x123);
147   cras_bt_io_create_profile_ret = &bt_iodev1;
148   cras_bt_device_append_iodev(device, &d1_, CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
149   EXPECT_EQ(1, cras_bt_io_create_called);
150   EXPECT_EQ(0, cras_bt_io_append_called);
151   EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE, cras_bt_io_create_profile_val);
152   cras_bt_device_set_active_profile(device, CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
153 
154   cras_bt_device_append_iodev(device, &d2_,
155                               CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
156   EXPECT_EQ(1, cras_bt_io_create_called);
157   EXPECT_EQ(1, cras_bt_io_append_called);
158   EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY,
159             cras_bt_io_append_profile_val);
160   EXPECT_EQ(&bt_iodev1, cras_bt_io_append_btio_val);
161 
162   /* Test HFP disconnected and switch to A2DP. */
163   cras_bt_io_get_profile_ret = bt_iodev1.nodes;
164   cras_bt_io_try_remove_ret = CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
165   cras_bt_device_set_active_profile(device,
166                                     CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
167   cras_bt_device_rm_iodev(device, &d2_);
168   EXPECT_EQ(1, cras_bt_io_remove_called);
169 
170   /* Test A2DP disconnection will cause bt_io destroy. */
171   cras_bt_io_try_remove_ret = 0;
172   cras_bt_device_rm_iodev(device, &d1_);
173   EXPECT_EQ(1, cras_bt_io_remove_called);
174   EXPECT_EQ(1, cras_bt_io_destroy_called);
175   EXPECT_EQ(0, cras_bt_device_get_active_profile(device));
176   cras_bt_device_remove(device);
177 }
178 
TEST_F(BtDeviceTestSuite,SwitchProfile)179 TEST_F(BtDeviceTestSuite, SwitchProfile) {
180   struct cras_bt_device* device;
181 
182   ResetStubData();
183   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
184   cras_bt_io_create_profile_ret = &bt_iodev1;
185   cras_bt_device_append_iodev(device, &d1_, CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
186   cras_bt_io_create_profile_ret = &bt_iodev2;
187   cras_bt_device_append_iodev(device, &d3_,
188                               CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
189 
190   cras_bt_device_start_monitor();
191   cras_bt_device_switch_profile_enable_dev(device, &bt_iodev1);
192 
193   /* Two bt iodevs were all active. */
194   cras_main_message_add_handler_callback(
195       cras_main_message_send_msg, cras_main_message_add_handler_callback_data);
196 
197   /* One bt iodev was active, the other was not. */
198   cras_bt_device_switch_profile_enable_dev(device, &bt_iodev2);
199   cras_main_message_add_handler_callback(
200       cras_main_message_send_msg, cras_main_message_add_handler_callback_data);
201 
202   /* Output bt iodev wasn't active, close the active input iodev. */
203   cras_bt_device_switch_profile(device, &bt_iodev2);
204   cras_main_message_add_handler_callback(
205       cras_main_message_send_msg, cras_main_message_add_handler_callback_data);
206   cras_bt_device_remove(device);
207 }
208 
TEST_F(BtDeviceTestSuite,SetDeviceConnectedA2dpOnly)209 TEST_F(BtDeviceTestSuite, SetDeviceConnectedA2dpOnly) {
210   struct cras_bt_device* device;
211   struct MockDBusMessage *msg_root, *cur;
212   ResetStubData();
213 
214   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
215   EXPECT_NE((void*)NULL, device);
216 
217   cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
218 
219   cur = msg_root = NewMockDBusConnectedMessage();
220   cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
221   EXPECT_EQ(1, cras_tm_create_timer_called);
222   EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
223 
224   /* Schedule another timer, if A2DP not yet configured. */
225   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
226   EXPECT_EQ(2, cras_tm_create_timer_called);
227   EXPECT_EQ(1, dbus_message_new_method_call_called);
228   EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
229 
230   cras_bt_device_a2dp_configured(device);
231   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
232   EXPECT_EQ(2, cras_tm_create_timer_called);
233   EXPECT_EQ(1, cras_hfp_ag_remove_conflict_called);
234   EXPECT_EQ(1, cras_a2dp_start_called);
235 
236   cras_bt_device_remove(device);
237   FreeMockDBusMessage(msg_root);
238 }
239 
TEST_F(BtDeviceTestSuite,SetDeviceConnectedHfpHspOnly)240 TEST_F(BtDeviceTestSuite, SetDeviceConnectedHfpHspOnly) {
241   struct cras_bt_device* device;
242   struct MockDBusMessage *msg_root, *cur;
243 
244   ResetStubData();
245 
246   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
247   EXPECT_NE((void*)NULL, device);
248 
249   cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
250   cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
251 
252   cur = msg_root = NewMockDBusConnectedMessage();
253   cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
254   EXPECT_EQ(1, cras_tm_create_timer_called);
255   EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
256 
257   /* Schedule another timer, if HFP AG not yet intialized. */
258   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
259   EXPECT_EQ(2, cras_tm_create_timer_called);
260   EXPECT_EQ(1, dbus_message_new_method_call_called);
261   EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
262 
263   cras_bt_device_audio_gateway_initialized(device);
264 
265   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
266   EXPECT_EQ(2, cras_tm_create_timer_called);
267   EXPECT_EQ(1, cras_hfp_ag_remove_conflict_called);
268   EXPECT_EQ(1, cras_hfp_ag_start_called);
269 
270   cras_bt_device_remove(device);
271   FreeMockDBusMessage(msg_root);
272 }
273 
TEST_F(BtDeviceTestSuite,SetDeviceConnectedA2dpHfpHsp)274 TEST_F(BtDeviceTestSuite, SetDeviceConnectedA2dpHfpHsp) {
275   struct cras_bt_device* device;
276   struct MockDBusMessage *msg_root, *cur;
277 
278   ResetStubData();
279 
280   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
281   EXPECT_NE((void*)NULL, device);
282 
283   cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
284   cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
285   cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
286 
287   cur = msg_root = NewMockDBusConnectedMessage();
288   cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
289   EXPECT_EQ(1, cras_tm_create_timer_called);
290   EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
291 
292   /* Schedule another timer, if not HFP nor A2DP is ready. */
293   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
294   EXPECT_EQ(2, cras_tm_create_timer_called);
295 
296   cras_bt_device_audio_gateway_initialized(device);
297 
298   /* Schedule another timer, because A2DP is not ready. */
299   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
300   EXPECT_EQ(3, cras_tm_create_timer_called);
301   EXPECT_EQ(0, cras_hfp_ag_start_called);
302   EXPECT_EQ(1, dbus_message_new_method_call_called);
303   EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
304 
305   cras_bt_device_a2dp_configured(device);
306 
307   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
308   EXPECT_EQ(3, cras_tm_create_timer_called);
309   EXPECT_EQ(1, cras_hfp_ag_remove_conflict_called);
310   EXPECT_EQ(1, cras_a2dp_start_called);
311   EXPECT_EQ(1, cras_hfp_ag_start_called);
312 
313   cras_bt_device_remove(device);
314   FreeMockDBusMessage(msg_root);
315 }
316 
TEST_F(BtDeviceTestSuite,DevConnectedConflictCheck)317 TEST_F(BtDeviceTestSuite, DevConnectedConflictCheck) {
318   struct cras_bt_device* device;
319   struct MockDBusMessage *msg_root, *cur;
320 
321   ResetStubData();
322 
323   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
324   EXPECT_NE((void*)NULL, device);
325 
326   cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
327   cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
328   cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
329 
330   cur = msg_root = NewMockDBusConnectedMessage();
331   cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
332   cras_bt_device_audio_gateway_initialized(device);
333   cras_bt_device_a2dp_configured(device);
334   EXPECT_EQ(1, cras_tm_create_timer_called);
335 
336   /* Fake that a different device already connected with A2DP */
337   cras_a2dp_connected_device_ret =
338       reinterpret_cast<struct cras_bt_device*>(0x99);
339   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
340   EXPECT_EQ(1, cras_tm_create_timer_called);
341 
342   /* Expect check conflict in HFP AG and A2DP. */
343   EXPECT_EQ(1, cras_hfp_ag_remove_conflict_called);
344   EXPECT_EQ(1, cras_a2dp_suspend_connected_device_called);
345   EXPECT_EQ(cras_a2dp_suspend_connected_device_dev,
346             cras_a2dp_connected_device_ret);
347 
348   EXPECT_EQ(1, cras_a2dp_start_called);
349   EXPECT_EQ(1, cras_hfp_ag_start_called);
350 
351   cras_bt_device_remove(device);
352   FreeMockDBusMessage(msg_root);
353 }
354 
TEST_F(BtDeviceTestSuite,A2dpDropped)355 TEST_F(BtDeviceTestSuite, A2dpDropped) {
356   struct cras_bt_device* device;
357   struct MockDBusMessage *msg_root, *cur;
358 
359   ResetStubData();
360 
361   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
362   EXPECT_NE((void*)NULL, device);
363 
364   cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
365   cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
366   cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
367 
368   cur = msg_root = NewMockDBusConnectedMessage();
369   cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
370   EXPECT_EQ(1, cras_tm_create_timer_called);
371   EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
372 
373   /* Schedule another timer, if HFP AG not yet intialized. */
374   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
375   EXPECT_EQ(2, cras_tm_create_timer_called);
376   EXPECT_EQ(1, dbus_message_new_method_call_called);
377   EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
378 
379   cras_bt_device_a2dp_configured(device);
380 
381   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
382   EXPECT_EQ(3, cras_tm_create_timer_called);
383 
384   cras_bt_device_notify_profile_dropped(device,
385                                         CRAS_BT_DEVICE_PROFILE_A2DP_SINK);
386   EXPECT_EQ(4, cras_tm_create_timer_called);
387 
388   /* Expect suspend timer is scheduled. */
389   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
390   EXPECT_EQ(1, cras_a2dp_suspend_connected_device_called);
391   EXPECT_EQ(1, cras_hfp_ag_suspend_connected_device_called);
392   EXPECT_EQ(2, dbus_message_new_method_call_called);
393   EXPECT_STREQ("Disconnect", dbus_message_new_method_call_method);
394 
395   cras_bt_device_remove(device);
396   FreeMockDBusMessage(msg_root);
397 }
398 
TEST_F(BtDeviceTestSuite,ConnectionWatchTimeout)399 TEST_F(BtDeviceTestSuite, ConnectionWatchTimeout) {
400   struct cras_bt_device* device;
401   struct MockDBusMessage *msg_root, *cur;
402 
403   ResetStubData();
404 
405   device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
406   EXPECT_NE((void*)NULL, device);
407 
408   cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
409   cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
410   cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
411 
412   cur = msg_root = NewMockDBusConnectedMessage();
413   cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
414   EXPECT_EQ(1, cras_tm_create_timer_called);
415   EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
416 
417   /* Schedule another timer, if HFP AG not yet intialized. */
418   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
419   EXPECT_EQ(2, cras_tm_create_timer_called);
420   EXPECT_EQ(1, dbus_message_new_method_call_called);
421   EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
422 
423   cras_bt_device_a2dp_configured(device);
424 
425   for (int i = 0; i < 29; i++) {
426     cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
427     EXPECT_EQ(i + 3, cras_tm_create_timer_called);
428     EXPECT_EQ(0, cras_a2dp_start_called);
429     EXPECT_EQ(0, cras_hfp_ag_start_called);
430     EXPECT_EQ(0, cras_hfp_ag_remove_conflict_called);
431   }
432 
433   dbus_message_new_method_call_called = 0;
434 
435   /* Expect suspend timer is scheduled. */
436   cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
437   EXPECT_EQ(1, cras_a2dp_suspend_connected_device_called);
438   EXPECT_EQ(1, cras_hfp_ag_suspend_connected_device_called);
439   EXPECT_EQ(1, dbus_message_new_method_call_called);
440   EXPECT_STREQ("Disconnect", dbus_message_new_method_call_method);
441 
442   cras_bt_device_remove(device);
443   FreeMockDBusMessage(msg_root);
444 }
445 
446 /* Stubs */
447 extern "C" {
448 
449 struct cras_bt_event_log* btlog;
450 
451 /* From bt_io */
cras_bt_io_create(struct cras_bt_device * device,struct cras_iodev * dev,enum cras_bt_device_profile profile)452 struct cras_iodev* cras_bt_io_create(struct cras_bt_device* device,
453                                      struct cras_iodev* dev,
454                                      enum cras_bt_device_profile profile) {
455   cras_bt_io_create_called++;
456   cras_bt_io_create_profile_val = profile;
457   return cras_bt_io_create_profile_ret;
458 }
cras_bt_io_destroy(struct cras_iodev * bt_iodev)459 void cras_bt_io_destroy(struct cras_iodev* bt_iodev) {
460   cras_bt_io_destroy_called++;
461 }
cras_bt_io_get_profile(struct cras_iodev * bt_iodev,enum cras_bt_device_profile profile)462 struct cras_ionode* cras_bt_io_get_profile(
463     struct cras_iodev* bt_iodev,
464     enum cras_bt_device_profile profile) {
465   return cras_bt_io_get_profile_ret;
466 }
cras_bt_io_append(struct cras_iodev * bt_iodev,struct cras_iodev * dev,enum cras_bt_device_profile profile)467 int cras_bt_io_append(struct cras_iodev* bt_iodev,
468                       struct cras_iodev* dev,
469                       enum cras_bt_device_profile profile) {
470   cras_bt_io_append_called++;
471   cras_bt_io_append_profile_val = profile;
472   cras_bt_io_append_btio_val = bt_iodev;
473   return 0;
474 }
cras_bt_io_on_profile(struct cras_iodev * bt_iodev,enum cras_bt_device_profile profile)475 int cras_bt_io_on_profile(struct cras_iodev* bt_iodev,
476                           enum cras_bt_device_profile profile) {
477   return 0;
478 }
cras_bt_io_try_remove(struct cras_iodev * bt_iodev,struct cras_iodev * dev)479 unsigned int cras_bt_io_try_remove(struct cras_iodev* bt_iodev,
480                                    struct cras_iodev* dev) {
481   return cras_bt_io_try_remove_ret;
482 }
cras_bt_io_remove(struct cras_iodev * bt_iodev,struct cras_iodev * dev)483 int cras_bt_io_remove(struct cras_iodev* bt_iodev, struct cras_iodev* dev) {
484   cras_bt_io_remove_called++;
485   return 0;
486 }
487 
488 /* From bt_adapter */
cras_bt_adapter_get(const char * object_path)489 struct cras_bt_adapter* cras_bt_adapter_get(const char* object_path) {
490   return NULL;
491 }
cras_bt_adapter_address(const struct cras_bt_adapter * adapter)492 const char* cras_bt_adapter_address(const struct cras_bt_adapter* adapter) {
493   return NULL;
494 }
495 
cras_bt_adapter_on_usb(struct cras_bt_adapter * adapter)496 int cras_bt_adapter_on_usb(struct cras_bt_adapter* adapter) {
497   return 1;
498 }
499 
500 /* From bt_profile */
cras_bt_profile_on_device_disconnected(struct cras_bt_device * device)501 void cras_bt_profile_on_device_disconnected(struct cras_bt_device* device) {}
502 
503 /* From hfp_ag_profile */
cras_hfp_ag_get_slc(struct cras_bt_device * device)504 struct hfp_slc_handle* cras_hfp_ag_get_slc(struct cras_bt_device* device) {
505   return NULL;
506 }
507 
cras_hfp_ag_suspend_connected_device(struct cras_bt_device * device)508 void cras_hfp_ag_suspend_connected_device(struct cras_bt_device* device) {
509   cras_hfp_ag_suspend_connected_device_called++;
510 }
511 
cras_a2dp_suspend_connected_device(struct cras_bt_device * device)512 void cras_a2dp_suspend_connected_device(struct cras_bt_device* device) {
513   cras_a2dp_suspend_connected_device_called++;
514   cras_a2dp_suspend_connected_device_dev = device;
515 }
516 
cras_a2dp_start(struct cras_bt_device * device)517 void cras_a2dp_start(struct cras_bt_device* device) {
518   cras_a2dp_start_called++;
519 }
520 
cras_a2dp_connected_device()521 struct cras_bt_device* cras_a2dp_connected_device() {
522   return cras_a2dp_connected_device_ret;
523 }
524 
cras_hfp_ag_remove_conflict(struct cras_bt_device * device)525 int cras_hfp_ag_remove_conflict(struct cras_bt_device* device) {
526   cras_hfp_ag_remove_conflict_called++;
527   return 0;
528 }
529 
cras_hfp_ag_start(struct cras_bt_device * device)530 int cras_hfp_ag_start(struct cras_bt_device* device) {
531   cras_hfp_ag_start_called++;
532   return 0;
533 }
534 
cras_hfp_ag_suspend()535 void cras_hfp_ag_suspend() {}
536 
537 /* From hfp_slc */
hfp_event_speaker_gain(struct hfp_slc_handle * handle,int gain)538 int hfp_event_speaker_gain(struct hfp_slc_handle* handle, int gain) {
539   return 0;
540 }
541 
542 /* From iodev_list */
543 
cras_iodev_open(struct cras_iodev * dev,unsigned int cb_level,const struct cras_audio_format * fmt)544 int cras_iodev_open(struct cras_iodev* dev,
545                     unsigned int cb_level,
546                     const struct cras_audio_format* fmt) {
547   return 0;
548 }
549 
cras_iodev_close(struct cras_iodev * dev)550 int cras_iodev_close(struct cras_iodev* dev) {
551   return 0;
552 }
553 
cras_iodev_list_dev_is_enabled(const struct cras_iodev * dev)554 int cras_iodev_list_dev_is_enabled(const struct cras_iodev* dev) {
555   return 0;
556 }
557 
cras_iodev_list_suspend_dev(struct cras_iodev * dev)558 void cras_iodev_list_suspend_dev(struct cras_iodev* dev) {}
559 
cras_iodev_list_resume_dev(struct cras_iodev * dev)560 void cras_iodev_list_resume_dev(struct cras_iodev* dev) {}
561 
cras_iodev_list_notify_node_volume(struct cras_ionode * node)562 void cras_iodev_list_notify_node_volume(struct cras_ionode* node) {}
563 
cras_main_message_send(struct cras_main_message * msg)564 int cras_main_message_send(struct cras_main_message* msg) {
565   // cras_main_message is a local variable from caller, we should allocate
566   // memory from heap and copy its data
567   if (cras_main_message_send_msg)
568     free(cras_main_message_send_msg);
569   cras_main_message_send_msg =
570       (struct cras_main_message*)calloc(1, msg->length);
571   memcpy((void*)cras_main_message_send_msg, (void*)msg, msg->length);
572   return 0;
573 }
574 
cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,cras_message_callback callback,void * callback_data)575 int cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,
576                                   cras_message_callback callback,
577                                   void* callback_data) {
578   cras_main_message_add_handler_callback = callback;
579   cras_main_message_add_handler_callback_data = callback_data;
580   return 0;
581 }
582 
583 /* From cras_system_state */
cras_system_state_get_tm()584 struct cras_tm* cras_system_state_get_tm() {
585   return NULL;
586 }
587 
588 /* 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)589 struct cras_timer* cras_tm_create_timer(struct cras_tm* tm,
590                                         unsigned int ms,
591                                         void (*cb)(struct cras_timer* t,
592                                                    void* data),
593                                         void* cb_data) {
594   cras_tm_create_timer_called++;
595   cras_tm_create_timer_cb = cb;
596   cras_tm_create_timer_cb_data = cb_data;
597   return NULL;
598 }
599 
cras_tm_cancel_timer(struct cras_tm * tm,struct cras_timer * t)600 void cras_tm_cancel_timer(struct cras_tm* tm, struct cras_timer* t) {}
601 
dbus_message_new_method_call(const char * destination,const char * path,const char * iface,const char * method)602 DBusMessage* dbus_message_new_method_call(const char* destination,
603                                           const char* path,
604                                           const char* iface,
605                                           const char* method) {
606   dbus_message_new_method_call_called++;
607   dbus_message_new_method_call_method = method;
608   return reinterpret_cast<DBusMessage*>(0x456);
609 }
610 
dbus_message_unref(DBusMessage * message)611 void dbus_message_unref(DBusMessage* message) {}
612 
dbus_message_append_args(DBusMessage * message,int first_arg_type,...)613 dbus_bool_t dbus_message_append_args(DBusMessage* message,
614                                      int first_arg_type,
615                                      ...) {
616   return true;
617 }
618 
dbus_connection_send_with_reply(DBusConnection * connection,DBusMessage * message,DBusPendingCall ** pending_return,int timeout_milliseconds)619 dbus_bool_t dbus_connection_send_with_reply(DBusConnection* connection,
620                                             DBusMessage* message,
621                                             DBusPendingCall** pending_return,
622                                             int timeout_milliseconds) {
623   return true;
624 }
625 
dbus_pending_call_set_notify(DBusPendingCall * pending,DBusPendingCallNotifyFunction function,void * user_data,DBusFreeFunction free_user_data)626 dbus_bool_t dbus_pending_call_set_notify(DBusPendingCall* pending,
627                                          DBusPendingCallNotifyFunction function,
628                                          void* user_data,
629                                          DBusFreeFunction free_user_data) {
630   return true;
631 }
632 
dbus_message_iter_recurse(DBusMessageIter * iter,DBusMessageIter * sub)633 void dbus_message_iter_recurse(DBusMessageIter* iter, DBusMessageIter* sub) {
634   MockDBusMessage* msg = *(MockDBusMessage**)iter;
635   MockDBusMessage** cur = (MockDBusMessage**)sub;
636   *cur = msg->recurse;
637 }
638 
dbus_message_iter_next(DBusMessageIter * iter)639 dbus_bool_t dbus_message_iter_next(DBusMessageIter* iter) {
640   MockDBusMessage** cur = (MockDBusMessage**)iter;
641   MockDBusMessage* msg = *cur;
642   *cur = msg->next;
643   return true;
644 }
645 
dbus_message_iter_get_arg_type(DBusMessageIter * iter)646 int dbus_message_iter_get_arg_type(DBusMessageIter* iter) {
647   MockDBusMessage* msg;
648 
649   if (iter == NULL)
650     return DBUS_TYPE_INVALID;
651 
652   msg = *(MockDBusMessage**)iter;
653   if (msg == NULL)
654     return DBUS_TYPE_INVALID;
655 
656   return msg->type;
657 }
658 
dbus_message_iter_get_basic(DBusMessageIter * iter,void * value)659 void dbus_message_iter_get_basic(DBusMessageIter* iter, void* value) {
660   MockDBusMessage* msg = *(MockDBusMessage**)iter;
661   switch (msg->type) {
662     case DBUS_TYPE_BOOLEAN:
663       memcpy(value, &msg->value, sizeof(int));
664       break;
665     case DBUS_TYPE_STRING:
666       memcpy(value, &msg->value, sizeof(char*));
667       break;
668   }
669 }
670 
671 }  // extern "C"
672 }  // namespace
673 
main(int argc,char ** argv)674 int main(int argc, char** argv) {
675   ::testing::InitGoogleTest(&argc, argv);
676   return RUN_ALL_TESTS();
677 }
678