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