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 <stdio.h>
6 #include <gtest/gtest.h>
7
8 extern "C" {
9 #include "cras_alert.h"
10 #include "cras_shm.h"
11 #include "cras_system_state.h"
12 #include "cras_types.h"
13 }
14
15 namespace {
16 static struct cras_alsa_card* kFakeAlsaCard;
17 size_t cras_alsa_card_create_called;
18 size_t cras_alsa_card_destroy_called;
19 static size_t add_stub_called;
20 static size_t rm_stub_called;
21 static size_t add_task_stub_called;
22 static size_t callback_stub_called;
23 static void *select_data_value;
24 static void *task_data_value;
25 static size_t add_callback_called;
26 static cras_alert_cb add_callback_cb;
27 static void *add_callback_arg;
28 static size_t rm_callback_called;
29 static cras_alert_cb rm_callback_cb;
30 static void *rm_callback_arg;
31 static size_t alert_pending_called;
32 static char* device_config_dir;
33 static const char* cras_alsa_card_config_dir;
34 static size_t cras_observer_notify_output_volume_called;
35 static size_t cras_observer_notify_output_mute_called;
36 static size_t cras_observer_notify_capture_gain_called;
37 static size_t cras_observer_notify_capture_mute_called;
38 static size_t cras_observer_notify_suspend_changed_called;
39 static size_t cras_observer_notify_num_active_streams_called;
40
ResetStubData()41 static void ResetStubData() {
42 cras_alsa_card_create_called = 0;
43 cras_alsa_card_destroy_called = 0;
44 kFakeAlsaCard = reinterpret_cast<struct cras_alsa_card*>(0x33);
45 add_stub_called = 0;
46 rm_stub_called = 0;
47 add_task_stub_called = 0;
48 callback_stub_called = 0;
49 add_callback_called = 0;
50 rm_callback_called = 0;
51 alert_pending_called = 0;
52 device_config_dir = NULL;
53 cras_alsa_card_config_dir = NULL;
54 cras_observer_notify_output_volume_called = 0;
55 cras_observer_notify_output_mute_called = 0;
56 cras_observer_notify_capture_gain_called = 0;
57 cras_observer_notify_capture_mute_called = 0;
58 cras_observer_notify_suspend_changed_called = 0;
59 cras_observer_notify_num_active_streams_called = 0;
60 }
61
add_stub(int fd,void (* cb)(void * data),void * callback_data,void * select_data)62 static int add_stub(int fd, void (*cb)(void *data),
63 void *callback_data, void *select_data) {
64 add_stub_called++;
65 select_data_value = select_data;
66 return 0;
67 }
68
rm_stub(int fd,void * select_data)69 static void rm_stub(int fd, void *select_data) {
70 rm_stub_called++;
71 select_data_value = select_data;
72 }
73
add_task_stub(void (* cb)(void * data),void * callback_data,void * task_data)74 static int add_task_stub(void (*cb)(void *data),
75 void *callback_data,
76 void *task_data)
77 {
78 add_task_stub_called++;
79 task_data_value = task_data;
80 return 0;
81 }
82
callback_stub(void * data)83 static void callback_stub(void *data) {
84 callback_stub_called++;
85 }
86
do_sys_init()87 static void do_sys_init() {
88 char *shm_name;
89 ASSERT_GT(asprintf(&shm_name, "/cras-%d", getpid()), 0);
90 int rw_shm_fd;
91 int ro_shm_fd;
92 struct cras_server_state *exp_state = (struct cras_server_state *)
93 cras_shm_setup(shm_name,
94 sizeof(*exp_state),
95 &rw_shm_fd,
96 &ro_shm_fd);
97 if (!exp_state)
98 exit(-1);
99 cras_system_state_init(device_config_dir,
100 shm_name,
101 rw_shm_fd,
102 ro_shm_fd,
103 exp_state,
104 sizeof(*exp_state));
105 free(shm_name);
106 }
107
TEST(SystemStateSuite,DefaultVolume)108 TEST(SystemStateSuite, DefaultVolume) {
109 do_sys_init();
110 EXPECT_EQ(100, cras_system_get_volume());
111 EXPECT_EQ(2000, cras_system_get_capture_gain());
112 EXPECT_EQ(0, cras_system_get_mute());
113 EXPECT_EQ(0, cras_system_get_capture_mute());
114 cras_system_state_deinit();
115 }
116
TEST(SystemStateSuite,SetVolume)117 TEST(SystemStateSuite, SetVolume) {
118 do_sys_init();
119 cras_system_set_volume(0);
120 EXPECT_EQ(0, cras_system_get_volume());
121 cras_system_set_volume(50);
122 EXPECT_EQ(50, cras_system_get_volume());
123 cras_system_set_volume(CRAS_MAX_SYSTEM_VOLUME);
124 EXPECT_EQ(CRAS_MAX_SYSTEM_VOLUME, cras_system_get_volume());
125 cras_system_set_volume(CRAS_MAX_SYSTEM_VOLUME + 1);
126 EXPECT_EQ(CRAS_MAX_SYSTEM_VOLUME, cras_system_get_volume());
127 cras_system_state_deinit();
128 EXPECT_EQ(4, cras_observer_notify_output_volume_called);
129 }
130
TEST(SystemStateSuite,SetMinMaxVolume)131 TEST(SystemStateSuite, SetMinMaxVolume) {
132 do_sys_init();
133 cras_system_set_volume_limits(-10000, -600);
134 EXPECT_EQ(-10000, cras_system_get_min_volume());
135 EXPECT_EQ(-600, cras_system_get_max_volume());
136 cras_system_state_deinit();
137 }
138
TEST(SystemStateSuite,SetCaptureVolume)139 TEST(SystemStateSuite, SetCaptureVolume) {
140 do_sys_init();
141 cras_system_set_capture_gain(0);
142 EXPECT_EQ(0, cras_system_get_capture_gain());
143 cras_system_set_capture_gain(3000);
144 EXPECT_EQ(3000, cras_system_get_capture_gain());
145 // Check that it is limited to the minimum allowed gain.
146 cras_system_set_capture_gain(-10000);
147 EXPECT_EQ(-5000, cras_system_get_capture_gain());
148 cras_system_state_deinit();
149 EXPECT_EQ(3, cras_observer_notify_capture_gain_called);
150 }
151
TEST(SystemStateSuite,SetCaptureVolumeStoreTarget)152 TEST(SystemStateSuite, SetCaptureVolumeStoreTarget) {
153 do_sys_init();
154 cras_system_set_capture_gain_limits(-2000, 2000);
155 cras_system_set_capture_gain(3000);
156 // Gain is within the limit.
157 EXPECT_EQ(2000, cras_system_get_capture_gain());
158
159 // Assume the range is changed.
160 cras_system_set_capture_gain_limits(-4000, 4000);
161
162 // Gain is also changed because target gain is re-applied.
163 EXPECT_EQ(3000, cras_system_get_capture_gain());
164
165 cras_system_state_deinit();
166 }
167
TEST(SystemStateSuite,SetMinMaxCaptureGain)168 TEST(SystemStateSuite, SetMinMaxCaptureGain) {
169 do_sys_init();
170 cras_system_set_capture_gain(3000);
171 cras_system_set_capture_gain_limits(-2000, 2000);
172 EXPECT_EQ(-2000, cras_system_get_min_capture_gain());
173 EXPECT_EQ(2000, cras_system_get_max_capture_gain());
174 // Current gain is adjusted for range.
175 EXPECT_EQ(2000, cras_system_get_capture_gain());
176 cras_system_state_deinit();
177 }
178
TEST(SystemStateSuite,SetUserMute)179 TEST(SystemStateSuite, SetUserMute) {
180 ResetStubData();
181 do_sys_init();
182
183 EXPECT_EQ(0, cras_system_get_mute());
184
185 cras_system_set_user_mute(0);
186 EXPECT_EQ(0, cras_system_get_mute());
187 EXPECT_EQ(0, cras_observer_notify_output_mute_called);
188
189 cras_system_set_user_mute(1);
190 EXPECT_EQ(1, cras_system_get_mute());
191 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
192
193 cras_system_set_user_mute(22);
194 EXPECT_EQ(1, cras_system_get_mute());
195 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
196
197 cras_system_state_deinit();
198 }
199
TEST(SystemStateSuite,SetMute)200 TEST(SystemStateSuite, SetMute) {
201 ResetStubData();
202 do_sys_init();
203
204 EXPECT_EQ(0, cras_system_get_mute());
205
206 cras_system_set_mute(0);
207 EXPECT_EQ(0, cras_system_get_mute());
208 EXPECT_EQ(0, cras_observer_notify_output_mute_called);
209
210 cras_system_set_mute(1);
211 EXPECT_EQ(1, cras_system_get_mute());
212 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
213
214 cras_system_set_mute(22);
215 EXPECT_EQ(1, cras_system_get_mute());
216 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
217
218 cras_system_state_deinit();
219 }
220
TEST(SystemStateSuite,SetSystemMuteThenSwitchUserMute)221 TEST(SystemStateSuite, SetSystemMuteThenSwitchUserMute) {
222 ResetStubData();
223 do_sys_init();
224
225 EXPECT_EQ(0, cras_system_get_mute());
226
227 // Set system mute.
228 cras_system_set_mute(1);
229
230 // Switching user mute will not notify observer.
231 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
232 cras_system_set_user_mute(1);
233 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
234 cras_system_set_user_mute(0);
235 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
236
237 // Unset system mute.
238 cras_system_set_mute(0);
239 EXPECT_EQ(2, cras_observer_notify_output_mute_called);
240
241 cras_system_state_deinit();
242 }
243
TEST(SystemStateSuite,SetUserMuteThenSwitchSystemMute)244 TEST(SystemStateSuite, SetUserMuteThenSwitchSystemMute) {
245 ResetStubData();
246 do_sys_init();
247
248 EXPECT_EQ(0, cras_system_get_mute());
249
250 // Set user mute.
251 cras_system_set_user_mute(1);
252
253 // Switching system mute will not notify observer.
254 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
255 cras_system_set_mute(1);
256 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
257 cras_system_set_mute(0);
258 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
259
260 // Unset user mute.
261 cras_system_set_user_mute(0);
262 EXPECT_EQ(2, cras_observer_notify_output_mute_called);
263
264 cras_system_state_deinit();
265 }
266
TEST(SystemStateSuite,CaptureMuteChangedCallbackMultiple)267 TEST(SystemStateSuite, CaptureMuteChangedCallbackMultiple) {
268 do_sys_init();
269 ResetStubData();
270
271 cras_system_set_capture_mute(1);
272 EXPECT_EQ(1, cras_system_get_capture_mute());
273 EXPECT_EQ(1, cras_observer_notify_capture_mute_called);
274 cras_system_set_capture_mute(0);
275 EXPECT_EQ(0, cras_system_get_capture_mute());
276 EXPECT_EQ(2, cras_observer_notify_capture_mute_called);
277
278 cras_system_state_deinit();
279 }
280
TEST(SystemStateSuite,MuteLocked)281 TEST(SystemStateSuite, MuteLocked) {
282 do_sys_init();
283 ResetStubData();
284
285 cras_system_set_mute(1);
286 EXPECT_EQ(1, cras_system_get_mute());
287 EXPECT_EQ(0, cras_system_get_mute_locked());
288 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
289
290 cras_system_set_mute_locked(1);
291 cras_system_set_mute(0);
292 EXPECT_EQ(1, cras_system_get_mute());
293 EXPECT_EQ(1, cras_system_get_mute_locked());
294 EXPECT_EQ(1, cras_observer_notify_output_mute_called);
295
296 cras_system_set_capture_mute(1);
297 EXPECT_EQ(1, cras_system_get_capture_mute());
298 EXPECT_EQ(0, cras_system_get_capture_mute_locked());
299 EXPECT_EQ(1, cras_observer_notify_capture_mute_called);
300
301 cras_system_set_capture_mute_locked(1);
302 cras_system_set_capture_mute(0);
303 EXPECT_EQ(1, cras_system_get_capture_mute());
304 EXPECT_EQ(1, cras_system_get_capture_mute_locked());
305 cras_system_state_deinit();
306 EXPECT_EQ(2, cras_observer_notify_capture_mute_called);
307 }
308
TEST(SystemStateSuite,Suspend)309 TEST(SystemStateSuite, Suspend) {
310 do_sys_init();
311 ResetStubData();
312
313 cras_system_set_suspended(1);
314 EXPECT_EQ(1, cras_observer_notify_suspend_changed_called);
315 EXPECT_EQ(1, cras_system_get_suspended());
316
317 cras_system_set_suspended(0);
318 EXPECT_EQ(2, cras_observer_notify_suspend_changed_called);
319 EXPECT_EQ(0, cras_system_get_suspended());
320
321 cras_system_state_deinit();
322 }
323
TEST(SystemStateSuite,AddCardFailCreate)324 TEST(SystemStateSuite, AddCardFailCreate) {
325 ResetStubData();
326 kFakeAlsaCard = NULL;
327 cras_alsa_card_info info;
328
329 info.card_type = ALSA_CARD_TYPE_INTERNAL;
330 info.card_index = 0;
331 do_sys_init();
332 EXPECT_EQ(-ENOMEM, cras_system_add_alsa_card(&info));
333 EXPECT_EQ(1, cras_alsa_card_create_called);
334 EXPECT_EQ(cras_alsa_card_config_dir, device_config_dir);
335 cras_system_state_deinit();
336 }
337
TEST(SystemStateSuite,AddCard)338 TEST(SystemStateSuite, AddCard) {
339 ResetStubData();
340 cras_alsa_card_info info;
341
342 info.card_type = ALSA_CARD_TYPE_INTERNAL;
343 info.card_index = 0;
344 do_sys_init();
345 EXPECT_EQ(0, cras_system_add_alsa_card(&info));
346 EXPECT_EQ(1, cras_alsa_card_create_called);
347 EXPECT_EQ(cras_alsa_card_config_dir, device_config_dir);
348 // Adding the same card again should fail.
349 ResetStubData();
350 EXPECT_NE(0, cras_system_add_alsa_card(&info));
351 EXPECT_EQ(0, cras_alsa_card_create_called);
352 // Removing card should destroy it.
353 cras_system_remove_alsa_card(0);
354 EXPECT_EQ(1, cras_alsa_card_destroy_called);
355 cras_system_state_deinit();
356 }
357
TEST(SystemSettingsRegisterSelectDescriptor,AddSelectFd)358 TEST(SystemSettingsRegisterSelectDescriptor, AddSelectFd) {
359 void *stub_data = reinterpret_cast<void *>(44);
360 void *select_data = reinterpret_cast<void *>(33);
361 int rc;
362
363 ResetStubData();
364 do_sys_init();
365 rc = cras_system_add_select_fd(7, callback_stub, stub_data);
366 EXPECT_NE(0, rc);
367 EXPECT_EQ(0, add_stub_called);
368 EXPECT_EQ(0, rm_stub_called);
369 rc = cras_system_set_select_handler(add_stub, rm_stub, select_data);
370 EXPECT_EQ(0, rc);
371 EXPECT_EQ(0, add_stub_called);
372 EXPECT_EQ(0, rm_stub_called);
373 rc = cras_system_set_select_handler(add_stub, rm_stub, select_data);
374 EXPECT_EQ(-EEXIST, rc);
375 EXPECT_EQ(0, add_stub_called);
376 EXPECT_EQ(0, rm_stub_called);
377 rc = cras_system_add_select_fd(7, callback_stub, stub_data);
378 EXPECT_EQ(0, rc);
379 EXPECT_EQ(1, add_stub_called);
380 EXPECT_EQ(select_data, select_data_value);
381 cras_system_rm_select_fd(7);
382 EXPECT_EQ(1, rm_stub_called);
383 EXPECT_EQ(0, callback_stub_called);
384 EXPECT_EQ(select_data, select_data_value);
385 cras_system_state_deinit();
386 }
387
TEST(SystemSettingsAddTask,AddTask)388 TEST(SystemSettingsAddTask, AddTask) {
389 void *stub_data = reinterpret_cast<void *>(44);
390 void *task_data = reinterpret_cast<void *>(33);
391 int rc;
392
393 do_sys_init();
394 rc = cras_system_add_task(callback_stub, stub_data);
395 EXPECT_NE(0, rc);
396 EXPECT_EQ(0, add_task_stub_called);
397 rc = cras_system_set_add_task_handler(add_task_stub, task_data);
398 EXPECT_EQ(0, rc);
399 EXPECT_EQ(0, add_task_stub_called);
400 rc = cras_system_add_task(callback_stub, stub_data);
401 EXPECT_EQ(0, rc);
402 EXPECT_EQ(1, add_task_stub_called);
403 EXPECT_EQ(task_data, task_data_value);
404
405 cras_system_state_deinit();
406 }
407
TEST(SystemSettingsStreamCount,StreamCount)408 TEST(SystemSettingsStreamCount, StreamCount) {
409 ResetStubData();
410 do_sys_init();
411
412 EXPECT_EQ(0, cras_system_state_get_active_streams());
413 cras_system_state_stream_added(CRAS_STREAM_OUTPUT);
414 EXPECT_EQ(1, cras_system_state_get_active_streams());
415 struct cras_timespec ts1;
416 cras_system_state_get_last_stream_active_time(&ts1);
417 cras_system_state_stream_removed(CRAS_STREAM_OUTPUT);
418 EXPECT_EQ(0, cras_system_state_get_active_streams());
419 struct cras_timespec ts2;
420 cras_system_state_get_last_stream_active_time(&ts2);
421 EXPECT_NE(0, memcmp(&ts1, &ts2, sizeof(ts1)));
422 cras_system_state_deinit();
423 }
424
TEST(SystemSettingsStreamCount,StreamCountByDirection)425 TEST(SystemSettingsStreamCount, StreamCountByDirection) {
426 ResetStubData();
427 do_sys_init();
428
429 EXPECT_EQ(0, cras_system_state_get_active_streams());
430 cras_system_state_stream_added(CRAS_STREAM_OUTPUT);
431 cras_system_state_stream_added(CRAS_STREAM_INPUT);
432 cras_system_state_stream_added(CRAS_STREAM_POST_MIX_PRE_DSP);
433 EXPECT_EQ(1,
434 cras_system_state_get_active_streams_by_direction(
435 CRAS_STREAM_OUTPUT));
436 EXPECT_EQ(1,
437 cras_system_state_get_active_streams_by_direction(
438 CRAS_STREAM_INPUT));
439 EXPECT_EQ(1,
440 cras_system_state_get_active_streams_by_direction(
441 CRAS_STREAM_POST_MIX_PRE_DSP));
442 EXPECT_EQ(3, cras_system_state_get_active_streams());
443 EXPECT_EQ(3, cras_observer_notify_num_active_streams_called);
444 cras_system_state_stream_removed(CRAS_STREAM_OUTPUT);
445 cras_system_state_stream_removed(CRAS_STREAM_INPUT);
446 cras_system_state_stream_removed(CRAS_STREAM_POST_MIX_PRE_DSP);
447 EXPECT_EQ(0,
448 cras_system_state_get_active_streams_by_direction(
449 CRAS_STREAM_OUTPUT));
450 EXPECT_EQ(0,
451 cras_system_state_get_active_streams_by_direction(
452 CRAS_STREAM_INPUT));
453 EXPECT_EQ(0,
454 cras_system_state_get_active_streams_by_direction(
455 CRAS_STREAM_POST_MIX_PRE_DSP));
456 EXPECT_EQ(0, cras_system_state_get_active_streams());
457 EXPECT_EQ(6, cras_observer_notify_num_active_streams_called);
458
459 cras_system_state_deinit();
460 }
461
462 extern "C" {
463
464
cras_alsa_card_create(struct cras_alsa_card_info * info,const char * device_config_dir,struct cras_device_blacklist * blacklist)465 struct cras_alsa_card *cras_alsa_card_create(struct cras_alsa_card_info *info,
466 const char *device_config_dir,
467 struct cras_device_blacklist *blacklist) {
468 cras_alsa_card_create_called++;
469 cras_alsa_card_config_dir = device_config_dir;
470 return kFakeAlsaCard;
471 }
472
cras_alsa_card_destroy(struct cras_alsa_card * alsa_card)473 void cras_alsa_card_destroy(struct cras_alsa_card *alsa_card) {
474 cras_alsa_card_destroy_called++;
475 }
476
cras_alsa_card_get_index(const struct cras_alsa_card * alsa_card)477 size_t cras_alsa_card_get_index(const struct cras_alsa_card *alsa_card) {
478 return 0;
479 }
480
cras_device_blacklist_create(const char * config_path)481 struct cras_device_blacklist *cras_device_blacklist_create(
482 const char *config_path)
483 {
484 return NULL;
485 }
486
cras_device_blacklist_destroy(struct cras_device_blacklist * blacklist)487 void cras_device_blacklist_destroy(struct cras_device_blacklist *blacklist)
488 {
489 }
490
cras_alert_create(cras_alert_prepare prepare,unsigned int flags)491 struct cras_alert *cras_alert_create(cras_alert_prepare prepare,
492 unsigned int flags)
493 {
494 return NULL;
495 }
496
cras_alert_destroy(struct cras_alert * alert)497 void cras_alert_destroy(struct cras_alert *alert)
498 {
499 }
500
cras_alert_add_callback(struct cras_alert * alert,cras_alert_cb cb,void * arg)501 int cras_alert_add_callback(struct cras_alert *alert, cras_alert_cb cb,
502 void *arg)
503 {
504 add_callback_called++;
505 add_callback_cb = cb;
506 add_callback_arg = arg;
507 return 0;
508 }
509
cras_alert_rm_callback(struct cras_alert * alert,cras_alert_cb cb,void * arg)510 int cras_alert_rm_callback(struct cras_alert *alert, cras_alert_cb cb,
511 void *arg)
512 {
513 rm_callback_called++;
514 rm_callback_cb = cb;
515 rm_callback_arg = arg;
516 return 0;
517 }
518
cras_alert_pending(struct cras_alert * alert)519 void cras_alert_pending(struct cras_alert *alert)
520 {
521 alert_pending_called++;
522 }
523
cras_tm_init()524 cras_tm *cras_tm_init() {
525 return static_cast<cras_tm*>(malloc(sizeof(unsigned int)));
526 }
527
cras_tm_deinit(cras_tm * tm)528 void cras_tm_deinit(cras_tm *tm) {
529 free(tm);
530 }
531
cras_observer_notify_output_volume(int32_t volume)532 void cras_observer_notify_output_volume(int32_t volume)
533 {
534 cras_observer_notify_output_volume_called++;
535 }
536
cras_observer_notify_output_mute(int muted,int user_muted,int mute_locked)537 void cras_observer_notify_output_mute(int muted, int user_muted,
538 int mute_locked)
539 {
540 cras_observer_notify_output_mute_called++;
541 }
542
cras_observer_notify_capture_gain(int32_t gain)543 void cras_observer_notify_capture_gain(int32_t gain)
544 {
545 cras_observer_notify_capture_gain_called++;
546 }
547
cras_observer_notify_capture_mute(int muted,int mute_locked)548 void cras_observer_notify_capture_mute(int muted, int mute_locked)
549 {
550 cras_observer_notify_capture_mute_called++;
551 }
552
cras_observer_notify_suspend_changed(int suspended)553 void cras_observer_notify_suspend_changed(int suspended)
554 {
555 cras_observer_notify_suspend_changed_called++;
556 }
557
cras_observer_notify_num_active_streams(enum CRAS_STREAM_DIRECTION dir,uint32_t num_active_streams)558 void cras_observer_notify_num_active_streams(enum CRAS_STREAM_DIRECTION dir,
559 uint32_t num_active_streams)
560 {
561 cras_observer_notify_num_active_streams_called++;
562 }
563
564 } // extern "C"
565 } // namespace
566
main(int argc,char ** argv)567 int main(int argc, char **argv) {
568 ::testing::InitGoogleTest(&argc, argv);
569 return RUN_ALL_TESTS();
570 }
571