• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 #include <stdio.h>
7 #include <unistd.h>
8 
9 extern "C" {
10 #include "audio_thread.h"
11 #include "cras_bt_log.h"
12 #include "cras_main_thread_log.h"
13 #include "cras_messages.h"
14 #include "cras_rclient.h"
15 #include "cras_rstream.h"
16 #include "cras_system_state.h"
17 
18 // Access to data structures and static functions.
19 #include "cras_control_rclient.c"
20 #include "cras_rclient_util.c"
21 }
22 
23 //  Stub data.
24 static int audio_thread_config_global_remix_called;
25 static float audio_thread_config_global_remix_copy[CRAS_MAX_REMIX_CHANNELS *
26                                                    CRAS_MAX_REMIX_CHANNELS];
27 static int cras_rstream_create_return;
28 static struct cras_rstream* cras_rstream_create_stream_out;
29 static int cras_iodev_attach_stream_retval;
30 static size_t cras_system_set_volume_value;
31 static int cras_system_set_volume_called;
32 static size_t cras_system_set_mute_value;
33 static int cras_system_set_mute_called;
34 static size_t cras_system_set_user_mute_value;
35 static int cras_system_set_user_mute_called;
36 static size_t cras_system_set_mute_locked_value;
37 static int cras_system_set_mute_locked_called;
38 static size_t cras_system_set_capture_mute_value;
39 static int cras_system_set_capture_mute_called;
40 static size_t cras_system_set_capture_mute_locked_value;
41 static int cras_system_set_capture_mute_locked_called;
42 static int cras_system_state_dump_snapshots_called;
43 static size_t cras_make_fd_nonblocking_called;
44 static audio_thread* iodev_get_thread_return;
45 static int stream_list_add_stream_return;
46 static unsigned int stream_list_add_stream_called;
47 static unsigned int stream_list_disconnect_stream_called;
48 static unsigned int cras_iodev_list_rm_input_called;
49 static unsigned int cras_iodev_list_rm_output_called;
50 static struct cras_audio_shm mock_shm;
51 static struct cras_rstream mock_rstream;
52 static size_t cras_observer_num_ops_registered;
53 static size_t cras_observer_register_notify_called;
54 static size_t cras_observer_add_called;
55 static void* cras_observer_add_context_value;
56 static struct cras_observer_client* cras_observer_add_return_value;
57 static size_t cras_observer_get_ops_called;
58 static struct cras_observer_ops cras_observer_ops_value;
59 static size_t cras_observer_set_ops_called;
60 static size_t cras_observer_ops_are_empty_called;
61 static struct cras_observer_ops cras_observer_ops_are_empty_empty_ops;
62 static size_t cras_observer_remove_called;
63 
ResetStubData()64 void ResetStubData() {
65   audio_thread_config_global_remix_called = 0;
66   memset(audio_thread_config_global_remix_copy, 0,
67          sizeof(audio_thread_config_global_remix_copy));
68   cras_rstream_create_return = 0;
69   cras_rstream_create_stream_out = (struct cras_rstream*)NULL;
70   cras_iodev_attach_stream_retval = 0;
71   cras_system_set_volume_value = 0;
72   cras_system_set_volume_called = 0;
73   cras_system_set_mute_value = 0;
74   cras_system_set_mute_called = 0;
75   cras_system_set_user_mute_value = 0;
76   cras_system_set_user_mute_called = 0;
77   cras_system_set_mute_locked_value = 0;
78   cras_system_set_mute_locked_called = 0;
79   cras_system_set_capture_mute_value = 0;
80   cras_system_set_capture_mute_called = 0;
81   cras_system_set_capture_mute_locked_value = 0;
82   cras_system_set_capture_mute_locked_called = 0;
83   cras_system_state_dump_snapshots_called = 0;
84   cras_make_fd_nonblocking_called = 0;
85   iodev_get_thread_return = reinterpret_cast<audio_thread*>(0xad);
86   stream_list_add_stream_return = 0;
87   stream_list_add_stream_called = 0;
88   stream_list_disconnect_stream_called = 0;
89   cras_iodev_list_rm_output_called = 0;
90   cras_iodev_list_rm_input_called = 0;
91   cras_observer_num_ops_registered = 0;
92   cras_observer_register_notify_called = 0;
93   cras_observer_add_called = 0;
94   cras_observer_add_return_value =
95       reinterpret_cast<struct cras_observer_client*>(1);
96   cras_observer_add_context_value = NULL;
97   cras_observer_get_ops_called = 0;
98   memset(&cras_observer_ops_value, 0, sizeof(cras_observer_ops_value));
99   cras_observer_set_ops_called = 0;
100   cras_observer_ops_are_empty_called = 0;
101   memset(&cras_observer_ops_are_empty_empty_ops, 0,
102          sizeof(cras_observer_ops_are_empty_empty_ops));
103   cras_observer_remove_called = 0;
104 }
105 
106 namespace {
107 
TEST(RClientSuite,CreateSendMessage)108 TEST(RClientSuite, CreateSendMessage) {
109   struct cras_rclient* rclient;
110   int rc;
111   struct cras_client_connected msg;
112   int pipe_fds[2];
113 
114   ResetStubData();
115 
116   rc = pipe(pipe_fds);
117   ASSERT_EQ(0, rc);
118 
119   rclient = cras_control_rclient_create(pipe_fds[1], 800);
120   ASSERT_NE((void*)NULL, rclient);
121 
122   rc = read(pipe_fds[0], &msg, sizeof(msg));
123   EXPECT_EQ(sizeof(msg), rc);
124   EXPECT_EQ(CRAS_CLIENT_CONNECTED, msg.header.id);
125 
126   rclient->ops->destroy(rclient);
127   close(pipe_fds[0]);
128   close(pipe_fds[1]);
129 }
130 
131 class RClientMessagesSuite : public testing::Test {
132  protected:
SetUp()133   virtual void SetUp() {
134     int rc;
135     struct cras_client_connected msg;
136 
137     rc = pipe(pipe_fds_);
138     if (rc < 0)
139       return;
140     rclient_ = cras_control_rclient_create(pipe_fds_[1], 1);
141     rc = read(pipe_fds_[0], &msg, sizeof(msg));
142     if (rc < 0)
143       return;
144 
145     rstream_ = (struct cras_rstream*)calloc(1, sizeof(*rstream_));
146 
147     stream_id_ = 0x10002;
148     connect_msg_.header.id = CRAS_SERVER_CONNECT_STREAM;
149     connect_msg_.header.length = sizeof(connect_msg_);
150     connect_msg_.proto_version = CRAS_PROTO_VER;
151     connect_msg_.stream_type = CRAS_STREAM_TYPE_DEFAULT;
152     connect_msg_.direction = CRAS_STREAM_OUTPUT;
153     connect_msg_.stream_id = stream_id_;
154     connect_msg_.buffer_frames = 480;
155     connect_msg_.cb_threshold = 240;
156     connect_msg_.flags = 0;
157     connect_msg_.format.num_channels = 2;
158     connect_msg_.format.frame_rate = 48000;
159     connect_msg_.format.format = SND_PCM_FORMAT_S16_LE;
160     connect_msg_.dev_idx = NO_DEVICE;
161     connect_msg_.client_shm_size = 0;
162     btlog = cras_bt_event_log_init();
163     main_log = main_thread_event_log_init();
164     ResetStubData();
165   }
166 
TearDown()167   virtual void TearDown() {
168     rclient_->ops->destroy(rclient_);
169     free(rstream_);
170     close(pipe_fds_[0]);
171     close(pipe_fds_[1]);
172     cras_bt_event_log_deinit(btlog);
173     main_thread_event_log_deinit(main_log);
174   }
175 
176   void RegisterNotification(enum CRAS_CLIENT_MESSAGE_ID msg_id,
177                             void* callback,
178                             void** ops_address);
179 
180   struct cras_connect_message connect_msg_;
181   struct cras_rclient* rclient_;
182   struct cras_rstream* rstream_;
183   size_t stream_id_;
184   int pipe_fds_[2];
185   int fd_;
186 };
187 
TEST_F(RClientMessagesSuite,AudThreadAttachFail)188 TEST_F(RClientMessagesSuite, AudThreadAttachFail) {
189   struct cras_client_stream_connected out_msg;
190   int rc;
191 
192   cras_rstream_create_stream_out = rstream_;
193   stream_list_add_stream_return = -EINVAL;
194 
195   fd_ = 100;
196   rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
197                                                  &fd_, 1);
198   EXPECT_EQ(0, rc);
199 
200   rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
201   EXPECT_EQ(sizeof(out_msg), rc);
202   EXPECT_EQ(stream_id_, out_msg.stream_id);
203   EXPECT_NE(0, out_msg.err);
204   EXPECT_EQ(0, cras_iodev_list_rm_output_called);
205   EXPECT_EQ(1, stream_list_add_stream_called);
206   EXPECT_EQ(0, stream_list_disconnect_stream_called);
207 }
208 
TEST_F(RClientMessagesSuite,ConnectMsgWithBadFd)209 TEST_F(RClientMessagesSuite, ConnectMsgWithBadFd) {
210   struct cras_client_stream_connected out_msg;
211   int rc;
212 
213   rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
214                                                  NULL, 0);
215   EXPECT_EQ(0, rc);
216 
217   rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
218   EXPECT_EQ(sizeof(out_msg), rc);
219   EXPECT_EQ(stream_id_, out_msg.stream_id);
220   EXPECT_NE(0, out_msg.err);
221   EXPECT_EQ(stream_list_add_stream_called,
222             stream_list_disconnect_stream_called);
223 }
224 
TEST_F(RClientMessagesSuite,StreamConnectMessageValidDirection)225 TEST_F(RClientMessagesSuite, StreamConnectMessageValidDirection) {
226   struct cras_client_stream_connected out_msg;
227   int rc;
228   int called = 0;
229 
230   for (int i = 0; i < CRAS_NUM_DIRECTIONS; i++) {
231     connect_msg_.direction = static_cast<CRAS_STREAM_DIRECTION>(i);
232     if (connect_msg_.direction == CRAS_STREAM_UNDEFINED)
233       continue;
234     called++;
235     cras_rstream_create_stream_out = rstream_;
236     cras_iodev_attach_stream_retval = 0;
237 
238     fd_ = 100;
239     rc = rclient_->ops->handle_message_from_client(
240         rclient_, &connect_msg_.header, &fd_, 1);
241     EXPECT_EQ(0, rc);
242     EXPECT_EQ(called, cras_make_fd_nonblocking_called);
243 
244     rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
245     EXPECT_EQ(sizeof(out_msg), rc);
246     EXPECT_EQ(stream_id_, out_msg.stream_id);
247     EXPECT_EQ(0, out_msg.err);
248     EXPECT_EQ(called, stream_list_add_stream_called);
249     EXPECT_EQ(0, stream_list_disconnect_stream_called);
250   }
251 }
252 
TEST_F(RClientMessagesSuite,StreamConnectMessageInvalidDirection)253 TEST_F(RClientMessagesSuite, StreamConnectMessageInvalidDirection) {
254   struct cras_client_stream_connected out_msg;
255   int rc;
256 
257   connect_msg_.direction = CRAS_STREAM_UNDEFINED;
258   cras_rstream_create_stream_out = rstream_;
259   cras_iodev_attach_stream_retval = 0;
260 
261   fd_ = 100;
262   rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
263                                                  &fd_, 1);
264   EXPECT_EQ(0, rc);
265   EXPECT_EQ(0, cras_make_fd_nonblocking_called);
266 
267   rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
268   EXPECT_EQ(sizeof(out_msg), rc);
269   EXPECT_EQ(stream_id_, out_msg.stream_id);
270   EXPECT_EQ(-EINVAL, out_msg.err);
271   EXPECT_EQ(0, stream_list_add_stream_called);
272   EXPECT_EQ(0, stream_list_disconnect_stream_called);
273 }
274 
TEST_F(RClientMessagesSuite,StreamConnectMessageInvalidClientId)275 TEST_F(RClientMessagesSuite, StreamConnectMessageInvalidClientId) {
276   struct cras_client_stream_connected out_msg;
277   int rc;
278 
279   connect_msg_.stream_id = 0x20002;  // stream_id with invalid client_id
280 
281   fd_ = 100;
282   rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
283                                                  &fd_, 1);
284   EXPECT_EQ(0, rc);
285   EXPECT_EQ(0, cras_make_fd_nonblocking_called);
286   EXPECT_EQ(0, stream_list_add_stream_called);
287   EXPECT_EQ(0, stream_list_disconnect_stream_called);
288 
289   rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
290   EXPECT_EQ(sizeof(out_msg), rc);
291   EXPECT_EQ(-EINVAL, out_msg.err);
292   EXPECT_EQ(connect_msg_.stream_id, out_msg.stream_id);
293 }
294 
TEST_F(RClientMessagesSuite,SuccessReply)295 TEST_F(RClientMessagesSuite, SuccessReply) {
296   struct cras_client_stream_connected out_msg;
297   int rc;
298 
299   cras_rstream_create_stream_out = rstream_;
300   cras_iodev_attach_stream_retval = 0;
301 
302   fd_ = 100;
303   rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
304                                                  &fd_, 1);
305   EXPECT_EQ(0, rc);
306   EXPECT_EQ(1, cras_make_fd_nonblocking_called);
307 
308   rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
309   EXPECT_EQ(sizeof(out_msg), rc);
310   EXPECT_EQ(stream_id_, out_msg.stream_id);
311   EXPECT_EQ(0, out_msg.err);
312   EXPECT_EQ(1, stream_list_add_stream_called);
313   EXPECT_EQ(0, stream_list_disconnect_stream_called);
314 }
315 
TEST_F(RClientMessagesSuite,SuccessCreateThreadReply)316 TEST_F(RClientMessagesSuite, SuccessCreateThreadReply) {
317   struct cras_client_stream_connected out_msg;
318   int rc;
319 
320   cras_rstream_create_stream_out = rstream_;
321   cras_iodev_attach_stream_retval = 0;
322 
323   fd_ = 100;
324   rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
325                                                  &fd_, 1);
326   EXPECT_EQ(0, rc);
327   EXPECT_EQ(1, cras_make_fd_nonblocking_called);
328 
329   rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
330   EXPECT_EQ(sizeof(out_msg), rc);
331   EXPECT_EQ(stream_id_, out_msg.stream_id);
332   EXPECT_EQ(0, out_msg.err);
333   EXPECT_EQ(1, stream_list_add_stream_called);
334   EXPECT_EQ(0, stream_list_disconnect_stream_called);
335 }
336 
TEST_F(RClientMessagesSuite,SetVolume)337 TEST_F(RClientMessagesSuite, SetVolume) {
338   struct cras_set_system_volume msg;
339   int rc;
340 
341   msg.header.id = CRAS_SERVER_SET_SYSTEM_VOLUME;
342   msg.header.length = sizeof(msg);
343   msg.volume = 66;
344 
345   rc =
346       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
347   EXPECT_EQ(0, rc);
348   EXPECT_EQ(1, cras_system_set_volume_called);
349   EXPECT_EQ(66, cras_system_set_volume_value);
350 }
351 
TEST_F(RClientMessagesSuite,SetMute)352 TEST_F(RClientMessagesSuite, SetMute) {
353   struct cras_set_system_mute msg;
354   int rc;
355 
356   msg.header.id = CRAS_SERVER_SET_SYSTEM_MUTE;
357   msg.header.length = sizeof(msg);
358   msg.mute = 1;
359 
360   rc =
361       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
362   EXPECT_EQ(0, rc);
363   EXPECT_EQ(1, cras_system_set_mute_called);
364   EXPECT_EQ(1, cras_system_set_mute_value);
365 
366   msg.header.id = CRAS_SERVER_SET_SYSTEM_MUTE_LOCKED;
367   rc =
368       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
369   EXPECT_EQ(0, rc);
370   EXPECT_EQ(1, cras_system_set_mute_locked_called);
371   EXPECT_EQ(1, cras_system_set_mute_locked_value);
372 }
373 
TEST_F(RClientMessagesSuite,SetUserMute)374 TEST_F(RClientMessagesSuite, SetUserMute) {
375   struct cras_set_system_mute msg;
376   int rc;
377 
378   msg.header.id = CRAS_SERVER_SET_USER_MUTE;
379   msg.header.length = sizeof(msg);
380   msg.mute = 1;
381 
382   rc =
383       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
384   EXPECT_EQ(0, rc);
385   EXPECT_EQ(1, cras_system_set_user_mute_called);
386   EXPECT_EQ(1, cras_system_set_user_mute_value);
387 }
388 
TEST_F(RClientMessagesSuite,SetCaptureMute)389 TEST_F(RClientMessagesSuite, SetCaptureMute) {
390   struct cras_set_system_mute msg;
391   int rc;
392 
393   msg.header.id = CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE;
394   msg.header.length = sizeof(msg);
395   msg.mute = 1;
396 
397   rc =
398       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
399   EXPECT_EQ(0, rc);
400   EXPECT_EQ(1, cras_system_set_capture_mute_called);
401   EXPECT_EQ(1, cras_system_set_capture_mute_value);
402 
403   msg.header.id = CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE_LOCKED;
404   rc =
405       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
406   EXPECT_EQ(0, rc);
407   EXPECT_EQ(1, cras_system_set_capture_mute_locked_called);
408   EXPECT_EQ(1, cras_system_set_capture_mute_locked_value);
409 }
410 
TEST_F(RClientMessagesSuite,DumpSnapshots)411 TEST_F(RClientMessagesSuite, DumpSnapshots) {
412   struct cras_dump_snapshots msg;
413   int rc;
414   cras_fill_dump_snapshots(&msg);
415   rc =
416       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
417   EXPECT_EQ(0, rc);
418   EXPECT_EQ(1, cras_system_state_dump_snapshots_called);
419 }
420 
TEST_F(RClientMessagesSuite,ConfigGlobalRemix)421 TEST_F(RClientMessagesSuite, ConfigGlobalRemix) {
422   int rc;
423   struct cras_config_global_remix msg;
424   const int num_channels = 2;
425   float coefficient[4] = {0.1, 0.2, 0.3, 0.4};
426   cras_fill_config_global_remix_command(&msg, num_channels, coefficient,
427                                         num_channels * num_channels);
428 
429   rc =
430       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
431   EXPECT_EQ(0, rc);
432   EXPECT_EQ(1, audio_thread_config_global_remix_called);
433   for (unsigned i = 0; i < (unsigned)num_channels * num_channels; i++) {
434     EXPECT_EQ(audio_thread_config_global_remix_copy[i], coefficient[i]);
435   }
436 }
437 
RegisterNotification(enum CRAS_CLIENT_MESSAGE_ID msg_id,void * callback,void ** ops_address)438 void RClientMessagesSuite::RegisterNotification(
439     enum CRAS_CLIENT_MESSAGE_ID msg_id,
440     void* callback,
441     void** ops_address) {
442   struct cras_register_notification msg;
443   int do_register = callback != NULL ? 1 : 0;
444   int rc;
445 
446   cras_observer_register_notify_called++;
447 
448   cras_fill_register_notification_message(&msg, msg_id, do_register);
449   EXPECT_EQ(msg.header.length, sizeof(msg));
450   EXPECT_EQ(msg.header.id, CRAS_SERVER_REGISTER_NOTIFICATION);
451   EXPECT_EQ(msg.do_register, do_register);
452   EXPECT_EQ(msg.msg_id, msg_id);
453 
454   rc =
455       rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
456   EXPECT_EQ(0, rc);
457   EXPECT_EQ(cras_observer_register_notify_called, cras_observer_get_ops_called);
458   EXPECT_EQ(cras_observer_register_notify_called,
459             cras_observer_ops_are_empty_called);
460   if (msg.do_register)
461     cras_observer_num_ops_registered++;
462   if (cras_observer_num_ops_registered == 1) {
463     if (msg.do_register) {
464       EXPECT_EQ(1, cras_observer_add_called);
465       EXPECT_EQ(rclient_, cras_observer_add_context_value);
466       EXPECT_EQ(rclient_->observer, cras_observer_add_return_value);
467     } else {
468       EXPECT_EQ(1, cras_observer_remove_called);
469       EXPECT_EQ(rclient_->observer, (struct cras_observer_client*)NULL);
470     }
471   } else {
472     EXPECT_EQ(cras_observer_register_notify_called - 1,
473               cras_observer_set_ops_called);
474   }
475   if (!msg.do_register)
476     cras_observer_num_ops_registered--;
477   if (cras_observer_num_ops_registered) {
478     EXPECT_EQ(callback, *ops_address);
479   }
480 }
481 
TEST_F(RClientMessagesSuite,RegisterStatusNotification)482 TEST_F(RClientMessagesSuite, RegisterStatusNotification) {
483   /* First registration for this client. */
484   RegisterNotification(CRAS_CLIENT_OUTPUT_VOLUME_CHANGED,
485                        (void*)send_output_volume_changed,
486                        (void**)&cras_observer_ops_value.output_volume_changed);
487 
488   /* Second registration for this client. */
489   RegisterNotification(CRAS_CLIENT_CAPTURE_GAIN_CHANGED,
490                        (void*)send_capture_gain_changed,
491                        (void**)&cras_observer_ops_value.capture_gain_changed);
492 
493   /* Deregister output_volume. */
494   RegisterNotification(CRAS_CLIENT_OUTPUT_VOLUME_CHANGED, NULL,
495                        (void**)&cras_observer_ops_value.output_volume_changed);
496 
497   /* Register/deregister all msg_ids. */
498 
499   RegisterNotification(CRAS_CLIENT_OUTPUT_MUTE_CHANGED,
500                        (void*)send_output_mute_changed,
501                        (void**)&cras_observer_ops_value.output_mute_changed);
502   RegisterNotification(CRAS_CLIENT_OUTPUT_MUTE_CHANGED, NULL,
503                        (void**)&cras_observer_ops_value.output_mute_changed);
504 
505   RegisterNotification(CRAS_CLIENT_CAPTURE_MUTE_CHANGED,
506                        (void*)send_capture_mute_changed,
507                        (void**)&cras_observer_ops_value.capture_mute_changed);
508   RegisterNotification(CRAS_CLIENT_CAPTURE_MUTE_CHANGED, NULL,
509                        (void**)&cras_observer_ops_value.capture_mute_changed);
510 
511   RegisterNotification(CRAS_CLIENT_NODES_CHANGED, (void*)send_nodes_changed,
512                        (void**)&cras_observer_ops_value.nodes_changed);
513   RegisterNotification(CRAS_CLIENT_NODES_CHANGED, NULL,
514                        (void**)&cras_observer_ops_value.nodes_changed);
515 
516   RegisterNotification(CRAS_CLIENT_ACTIVE_NODE_CHANGED,
517                        (void*)send_active_node_changed,
518                        (void**)&cras_observer_ops_value.active_node_changed);
519   RegisterNotification(CRAS_CLIENT_ACTIVE_NODE_CHANGED, NULL,
520                        (void**)&cras_observer_ops_value.active_node_changed);
521 
522   RegisterNotification(
523       CRAS_CLIENT_OUTPUT_NODE_VOLUME_CHANGED,
524       (void*)send_output_node_volume_changed,
525       (void**)&cras_observer_ops_value.output_node_volume_changed);
526   RegisterNotification(
527       CRAS_CLIENT_OUTPUT_NODE_VOLUME_CHANGED, NULL,
528       (void**)&cras_observer_ops_value.output_node_volume_changed);
529 
530   RegisterNotification(
531       CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED,
532       (void*)send_node_left_right_swapped_changed,
533       (void**)&cras_observer_ops_value.node_left_right_swapped_changed);
534   RegisterNotification(
535       CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED, NULL,
536       (void**)&cras_observer_ops_value.node_left_right_swapped_changed);
537 
538   RegisterNotification(
539       CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED, (void*)send_input_node_gain_changed,
540       (void**)&cras_observer_ops_value.input_node_gain_changed);
541   RegisterNotification(
542       CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED, NULL,
543       (void**)&cras_observer_ops_value.input_node_gain_changed);
544 
545   RegisterNotification(
546       CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED,
547       (void*)send_num_active_streams_changed,
548       (void**)&cras_observer_ops_value.num_active_streams_changed);
549   RegisterNotification(
550       CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED, NULL,
551       (void**)&cras_observer_ops_value.num_active_streams_changed);
552 
553   /* Deregister last. */
554   RegisterNotification(CRAS_CLIENT_CAPTURE_GAIN_CHANGED, NULL,
555                        (void**)&cras_observer_ops_value.capture_gain_changed);
556 }
557 
TEST_F(RClientMessagesSuite,SendOutputVolumeChanged)558 TEST_F(RClientMessagesSuite, SendOutputVolumeChanged) {
559   void* void_client = reinterpret_cast<void*>(rclient_);
560   char buf[1024];
561   ssize_t rc;
562   struct cras_client_volume_changed* msg =
563       (struct cras_client_volume_changed*)buf;
564   const int32_t volume = 90;
565 
566   send_output_volume_changed(void_client, volume);
567   rc = read(pipe_fds_[0], buf, sizeof(buf));
568   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
569   EXPECT_EQ(msg->header.id, CRAS_CLIENT_OUTPUT_VOLUME_CHANGED);
570   EXPECT_EQ(msg->volume, volume);
571 }
572 
TEST_F(RClientMessagesSuite,SendOutputMuteChanged)573 TEST_F(RClientMessagesSuite, SendOutputMuteChanged) {
574   void* void_client = reinterpret_cast<void*>(rclient_);
575   char buf[1024];
576   ssize_t rc;
577   struct cras_client_mute_changed* msg = (struct cras_client_mute_changed*)buf;
578   const int muted = 1;
579   const int user_muted = 0;
580   const int mute_locked = 1;
581 
582   send_output_mute_changed(void_client, muted, user_muted, mute_locked);
583   rc = read(pipe_fds_[0], buf, sizeof(buf));
584   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
585   EXPECT_EQ(msg->header.id, CRAS_CLIENT_OUTPUT_MUTE_CHANGED);
586   EXPECT_EQ(msg->muted, muted);
587   EXPECT_EQ(msg->user_muted, user_muted);
588   EXPECT_EQ(msg->mute_locked, mute_locked);
589 }
590 
TEST_F(RClientMessagesSuite,SendCaptureMuteChanged)591 TEST_F(RClientMessagesSuite, SendCaptureMuteChanged) {
592   void* void_client = reinterpret_cast<void*>(rclient_);
593   char buf[1024];
594   ssize_t rc;
595   struct cras_client_mute_changed* msg = (struct cras_client_mute_changed*)buf;
596   const int muted = 1;
597   const int mute_locked = 0;
598 
599   send_capture_mute_changed(void_client, muted, mute_locked);
600   rc = read(pipe_fds_[0], buf, sizeof(buf));
601   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
602   EXPECT_EQ(msg->header.id, CRAS_CLIENT_CAPTURE_MUTE_CHANGED);
603   EXPECT_EQ(msg->muted, muted);
604   EXPECT_EQ(msg->mute_locked, mute_locked);
605 }
606 
TEST_F(RClientMessagesSuite,SendNodesChanged)607 TEST_F(RClientMessagesSuite, SendNodesChanged) {
608   void* void_client = reinterpret_cast<void*>(rclient_);
609   char buf[1024];
610   ssize_t rc;
611   struct cras_client_nodes_changed* msg =
612       (struct cras_client_nodes_changed*)buf;
613 
614   send_nodes_changed(void_client);
615   rc = read(pipe_fds_[0], buf, sizeof(buf));
616   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
617   EXPECT_EQ(msg->header.id, CRAS_CLIENT_NODES_CHANGED);
618 }
619 
TEST_F(RClientMessagesSuite,SendActiveNodeChanged)620 TEST_F(RClientMessagesSuite, SendActiveNodeChanged) {
621   void* void_client = reinterpret_cast<void*>(rclient_);
622   char buf[1024];
623   ssize_t rc;
624   struct cras_client_active_node_changed* msg =
625       (struct cras_client_active_node_changed*)buf;
626   const enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_INPUT;
627   const cras_node_id_t node_id = 0x0001000200030004;
628 
629   send_active_node_changed(void_client, dir, node_id);
630   rc = read(pipe_fds_[0], buf, sizeof(buf));
631   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
632   EXPECT_EQ(msg->header.id, CRAS_CLIENT_ACTIVE_NODE_CHANGED);
633   EXPECT_EQ(msg->direction, (int32_t)dir);
634   EXPECT_EQ((uint64_t)msg->node_id, node_id);
635 }
636 
TEST_F(RClientMessagesSuite,SendOutputNodeVolumeChanged)637 TEST_F(RClientMessagesSuite, SendOutputNodeVolumeChanged) {
638   void* void_client = reinterpret_cast<void*>(rclient_);
639   char buf[1024];
640   ssize_t rc;
641   struct cras_client_node_value_changed* msg =
642       (struct cras_client_node_value_changed*)buf;
643   const cras_node_id_t node_id = 0x0001000200030004;
644   const int32_t value = 90;
645 
646   send_output_node_volume_changed(void_client, node_id, value);
647   rc = read(pipe_fds_[0], buf, sizeof(buf));
648   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
649   EXPECT_EQ(msg->header.id, CRAS_CLIENT_OUTPUT_NODE_VOLUME_CHANGED);
650   EXPECT_EQ(msg->node_id, node_id);
651   EXPECT_EQ(msg->value, value);
652 }
653 
TEST_F(RClientMessagesSuite,SendNodeLeftRightSwappedChanged)654 TEST_F(RClientMessagesSuite, SendNodeLeftRightSwappedChanged) {
655   void* void_client = reinterpret_cast<void*>(rclient_);
656   char buf[1024];
657   ssize_t rc;
658   struct cras_client_node_value_changed* msg =
659       (struct cras_client_node_value_changed*)buf;
660   const cras_node_id_t node_id = 0x0001000200030004;
661   const int32_t value = 0;
662 
663   send_node_left_right_swapped_changed(void_client, node_id, value);
664   rc = read(pipe_fds_[0], buf, sizeof(buf));
665   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
666   EXPECT_EQ(msg->header.id, CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED);
667   EXPECT_EQ(msg->node_id, node_id);
668   EXPECT_EQ(msg->value, value);
669 }
670 
TEST_F(RClientMessagesSuite,SendNodeInputNodeGainChanged)671 TEST_F(RClientMessagesSuite, SendNodeInputNodeGainChanged) {
672   void* void_client = reinterpret_cast<void*>(rclient_);
673   char buf[1024];
674   ssize_t rc;
675   struct cras_client_node_value_changed* msg =
676       (struct cras_client_node_value_changed*)buf;
677   const cras_node_id_t node_id = 0x0001000200030004;
678   const int32_t value = -19;
679 
680   send_input_node_gain_changed(void_client, node_id, value);
681   rc = read(pipe_fds_[0], buf, sizeof(buf));
682   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
683   EXPECT_EQ(msg->header.id, CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED);
684   EXPECT_EQ(msg->node_id, node_id);
685   EXPECT_EQ(msg->value, value);
686 }
687 
TEST_F(RClientMessagesSuite,SendNumActiveStreamsChanged)688 TEST_F(RClientMessagesSuite, SendNumActiveStreamsChanged) {
689   void* void_client = reinterpret_cast<void*>(rclient_);
690   char buf[1024];
691   ssize_t rc;
692   struct cras_client_num_active_streams_changed* msg =
693       (struct cras_client_num_active_streams_changed*)buf;
694   const enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_INPUT;
695   const uint32_t num_active_streams = 3;
696 
697   send_num_active_streams_changed(void_client, dir, num_active_streams);
698   rc = read(pipe_fds_[0], buf, sizeof(buf));
699   ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
700   EXPECT_EQ(msg->header.id, CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED);
701   EXPECT_EQ(msg->direction, (int32_t)dir);
702   EXPECT_EQ(msg->num_active_streams, num_active_streams);
703 }
704 
705 }  //  namespace
706 
main(int argc,char ** argv)707 int main(int argc, char** argv) {
708   ::testing::InitGoogleTest(&argc, argv);
709   return RUN_ALL_TESTS();
710 }
711 
712 /* stubs */
713 extern "C" {
714 
715 struct cras_bt_event_log* btlog;
716 struct main_thread_event_log* main_log;
717 
cras_iodev_list_get_audio_thread()718 struct audio_thread* cras_iodev_list_get_audio_thread() {
719   return iodev_get_thread_return;
720 }
721 
cras_iodev_list_add_active_node(enum CRAS_STREAM_DIRECTION dir,cras_node_id_t node_id)722 void cras_iodev_list_add_active_node(enum CRAS_STREAM_DIRECTION dir,
723                                      cras_node_id_t node_id) {}
724 
cras_iodev_list_rm_active_node(enum CRAS_STREAM_DIRECTION dir,cras_node_id_t node_id)725 void cras_iodev_list_rm_active_node(enum CRAS_STREAM_DIRECTION dir,
726                                     cras_node_id_t node_id) {}
727 
audio_thread_rm_stream(audio_thread * thread,cras_rstream * stream)728 int audio_thread_rm_stream(audio_thread* thread, cras_rstream* stream) {
729   return 0;
730 }
731 
audio_thread_add_output_dev(struct audio_thread * thread,struct cras_iodev * odev)732 void audio_thread_add_output_dev(struct audio_thread* thread,
733                                  struct cras_iodev* odev) {}
734 
audio_thread_dump_thread_info(struct audio_thread * thread,struct audio_debug_info * info)735 int audio_thread_dump_thread_info(struct audio_thread* thread,
736                                   struct audio_debug_info* info) {
737   return 0;
738 }
739 
audio_thread_suspend(struct audio_thread * thread)740 int audio_thread_suspend(struct audio_thread* thread) {
741   return 0;
742 }
743 
audio_thread_resume(struct audio_thread * thread)744 int audio_thread_resume(struct audio_thread* thread) {
745   return 0;
746 }
747 
audio_thread_config_global_remix(struct audio_thread * thread,unsigned int num_channels,const float * coefficient)748 int audio_thread_config_global_remix(struct audio_thread* thread,
749                                      unsigned int num_channels,
750                                      const float* coefficient) {
751   audio_thread_config_global_remix_called++;
752   memcpy(audio_thread_config_global_remix_copy, coefficient,
753          num_channels * num_channels * sizeof(coefficient));
754   return 0;
755 }
756 
audio_thread_set_aec_dump(struct audio_thread * thread,cras_stream_id_t stream_id,unsigned int start,int fd)757 int audio_thread_set_aec_dump(struct audio_thread* thread,
758                               cras_stream_id_t stream_id,
759                               unsigned int start,
760                               int fd) {
761   return 0;
762 }
763 
audio_thread_event_log_shm_fd()764 int audio_thread_event_log_shm_fd() {
765   return -1;
766 }
767 
768 #ifdef HAVE_WEBRTC_APM
cras_apm_list_reload_aec_config()769 void cras_apm_list_reload_aec_config() {}
770 #endif
771 
cras_system_set_bt_wbs_enabled(bool enabled)772 void cras_system_set_bt_wbs_enabled(bool enabled) {}
773 
cras_config_get_socket_file_dir()774 const char* cras_config_get_socket_file_dir() {
775   return CRAS_UT_TMPDIR;
776 }
777 
cras_rstream_create(struct cras_rstream_config * stream_config,struct cras_rstream ** stream_out)778 int cras_rstream_create(struct cras_rstream_config* stream_config,
779                         struct cras_rstream** stream_out) {
780   *stream_out = cras_rstream_create_stream_out;
781   return cras_rstream_create_return;
782 }
783 
cras_rstream_get_effects(const struct cras_rstream * stream)784 unsigned int cras_rstream_get_effects(const struct cras_rstream* stream) {
785   return 0;
786 }
787 
cras_iodev_move_stream_type(uint32_t type,uint32_t index)788 int cras_iodev_move_stream_type(uint32_t type, uint32_t index) {
789   return 0;
790 }
791 
cras_iodev_list_rm_output(struct cras_iodev * output)792 int cras_iodev_list_rm_output(struct cras_iodev* output) {
793   cras_iodev_list_rm_output_called++;
794   return 0;
795 }
796 
cras_iodev_list_rm_input(struct cras_iodev * input)797 int cras_iodev_list_rm_input(struct cras_iodev* input) {
798   cras_iodev_list_rm_input_called++;
799   return 0;
800 }
801 
cras_server_disconnect_from_client_socket(int socket_fd)802 int cras_server_disconnect_from_client_socket(int socket_fd) {
803   return 0;
804 }
805 
cras_make_fd_nonblocking(int fd)806 int cras_make_fd_nonblocking(int fd) {
807   cras_make_fd_nonblocking_called++;
808   return 0;
809 }
810 
cras_system_state_dump_snapshots()811 void cras_system_state_dump_snapshots() {
812   cras_system_state_dump_snapshots_called++;
813 }
814 
cras_system_set_volume(size_t volume)815 void cras_system_set_volume(size_t volume) {
816   cras_system_set_volume_value = volume;
817   cras_system_set_volume_called++;
818 }
819 
820 //  From system_state.
cras_system_set_mute(int mute)821 void cras_system_set_mute(int mute) {
822   cras_system_set_mute_value = mute;
823   cras_system_set_mute_called++;
824 }
cras_system_set_user_mute(int mute)825 void cras_system_set_user_mute(int mute) {
826   cras_system_set_user_mute_value = mute;
827   cras_system_set_user_mute_called++;
828 }
cras_system_set_mute_locked(int mute)829 void cras_system_set_mute_locked(int mute) {
830   cras_system_set_mute_locked_value = mute;
831   cras_system_set_mute_locked_called++;
832 }
cras_system_set_capture_mute(int mute)833 void cras_system_set_capture_mute(int mute) {
834   cras_system_set_capture_mute_value = mute;
835   cras_system_set_capture_mute_called++;
836 }
cras_system_set_capture_mute_locked(int mute)837 void cras_system_set_capture_mute_locked(int mute) {
838   cras_system_set_capture_mute_locked_value = mute;
839   cras_system_set_capture_mute_locked_called++;
840 }
841 
cras_system_remove_alsa_card(size_t alsa_card_index)842 int cras_system_remove_alsa_card(size_t alsa_card_index) {
843   return -1;
844 }
845 
cras_system_set_suspended(int suspended)846 void cras_system_set_suspended(int suspended) {}
847 
cras_system_state_get_no_lock()848 struct cras_server_state* cras_system_state_get_no_lock() {
849   return NULL;
850 }
851 
cras_sys_state_shm_fd()852 key_t cras_sys_state_shm_fd() {
853   return 1;
854 }
855 
cras_dsp_reload_ini()856 void cras_dsp_reload_ini() {}
857 
cras_dsp_dump_info()858 void cras_dsp_dump_info() {}
859 
cras_iodev_list_set_node_attr(cras_node_id_t id,enum ionode_attr attr,int value)860 int cras_iodev_list_set_node_attr(cras_node_id_t id,
861                                   enum ionode_attr attr,
862                                   int value) {
863   return 0;
864 }
865 
cras_iodev_list_select_node(enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)866 void cras_iodev_list_select_node(enum CRAS_STREAM_DIRECTION direction,
867                                  cras_node_id_t node_id) {}
868 
cras_iodev_list_add_test_dev(enum TEST_IODEV_TYPE type)869 void cras_iodev_list_add_test_dev(enum TEST_IODEV_TYPE type) {}
870 
cras_iodev_list_get_stream_list()871 struct stream_list* cras_iodev_list_get_stream_list() {
872   return NULL;
873 }
874 
875 /* Handles sending a command to a test iodev. */
cras_iodev_list_test_dev_command(unsigned int iodev_idx,enum CRAS_TEST_IODEV_CMD command,unsigned int data_len,const uint8_t * data)876 void cras_iodev_list_test_dev_command(unsigned int iodev_idx,
877                                       enum CRAS_TEST_IODEV_CMD command,
878                                       unsigned int data_len,
879                                       const uint8_t* data) {}
880 
cras_iodev_list_configure_global_remix_converter(unsigned int num_channels,const float * coefficient)881 void cras_iodev_list_configure_global_remix_converter(
882     unsigned int num_channels,
883     const float* coefficient) {}
884 
stream_list_add(struct stream_list * list,struct cras_rstream_config * config,struct cras_rstream ** stream)885 int stream_list_add(struct stream_list* list,
886                     struct cras_rstream_config* config,
887                     struct cras_rstream** stream) {
888   int ret;
889 
890   *stream = &mock_rstream;
891 
892   stream_list_add_stream_called++;
893   ret = stream_list_add_stream_return;
894   if (ret)
895     stream_list_add_stream_return = -EINVAL;
896 
897   mock_rstream.shm = &mock_shm;
898   mock_rstream.direction = config->direction;
899   mock_rstream.stream_id = config->stream_id;
900 
901   return ret;
902 }
903 
stream_list_rm(struct stream_list * list,cras_stream_id_t id)904 int stream_list_rm(struct stream_list* list, cras_stream_id_t id) {
905   stream_list_disconnect_stream_called++;
906   return 0;
907 }
908 
stream_list_rm_all_client_streams(struct stream_list * list,struct cras_rclient * rclient)909 int stream_list_rm_all_client_streams(struct stream_list* list,
910                                       struct cras_rclient* rclient) {
911   return 0;
912 }
913 
cras_send_with_fds(int sockfd,const void * buf,size_t len,int * fd,unsigned int num_fds)914 int cras_send_with_fds(int sockfd,
915                        const void* buf,
916                        size_t len,
917                        int* fd,
918                        unsigned int num_fds) {
919   return write(sockfd, buf, len);
920 }
921 
cras_iodev_list_get_hotword_models(cras_node_id_t node_id)922 char* cras_iodev_list_get_hotword_models(cras_node_id_t node_id) {
923   return NULL;
924 }
925 
cras_iodev_list_set_hotword_model(cras_node_id_t id,const char * model_name)926 int cras_iodev_list_set_hotword_model(cras_node_id_t id,
927                                       const char* model_name) {
928   return 0;
929 }
930 
cras_observer_add(const struct cras_observer_ops * ops,void * context)931 struct cras_observer_client* cras_observer_add(
932     const struct cras_observer_ops* ops,
933     void* context) {
934   cras_observer_add_called++;
935   cras_observer_add_context_value = context;
936   memcpy(&cras_observer_ops_value, ops, sizeof(cras_observer_ops_value));
937   return cras_observer_add_return_value;
938 }
939 
cras_observer_get_ops(const struct cras_observer_client * client,struct cras_observer_ops * ops)940 void cras_observer_get_ops(const struct cras_observer_client* client,
941                            struct cras_observer_ops* ops) {
942   cras_observer_get_ops_called++;
943   memcpy(ops, &cras_observer_ops_value, sizeof(*ops));
944 }
945 
cras_observer_set_ops(struct cras_observer_client * client,const struct cras_observer_ops * ops)946 void cras_observer_set_ops(struct cras_observer_client* client,
947                            const struct cras_observer_ops* ops) {
948   cras_observer_set_ops_called++;
949   memcpy(&cras_observer_ops_value, ops, sizeof(cras_observer_ops_value));
950 }
951 
cras_observer_ops_are_empty(const struct cras_observer_ops * ops)952 int cras_observer_ops_are_empty(const struct cras_observer_ops* ops) {
953   cras_observer_ops_are_empty_called++;
954   return memcmp(&cras_observer_ops_are_empty_empty_ops, ops,
955                 sizeof(cras_observer_ops_are_empty_empty_ops)) == 0;
956 }
957 
cras_observer_remove(struct cras_observer_client * client)958 void cras_observer_remove(struct cras_observer_client* client) {
959   cras_observer_remove_called++;
960 }
961 
cras_audio_format_valid(const struct cras_audio_format * fmt)962 bool cras_audio_format_valid(const struct cras_audio_format* fmt) {
963   return true;
964 }
965 
cras_hfp_ag_get_wbs_logger()966 struct packet_status_logger* cras_hfp_ag_get_wbs_logger() {
967   return NULL;
968 }
969 
detect_rtc_stream_pair(struct stream_list * list,struct cras_rstream * stream)970 void detect_rtc_stream_pair(struct stream_list* list,
971                             struct cras_rstream* stream) {
972   return;
973 }
974 
cras_system_set_hotword_pause_at_suspend(bool pause)975 void cras_system_set_hotword_pause_at_suspend(bool pause) {}
976 
977 }  // extern "C"
978