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