1// Copyright 2016 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 <syslog.h>
8
9#include <vector>
10#include <map>
11
12extern "C" {
13#include "cras_observer.c"
14}
15
16namespace {
17
18static size_t cras_alert_destroy_called;
19static size_t cras_alert_create_called;
20static std::vector<struct cras_alert *> cras_alert_create_return_values;
21typedef std::map<struct cras_alert *, void *> alert_callback_map;
22static alert_callback_map cras_alert_create_prepare_map;
23static alert_callback_map cras_alert_add_callback_map;
24typedef std::map<struct cras_alert *, unsigned int> alert_flags_map;
25static alert_flags_map cras_alert_create_flags_map;
26static struct cras_alert *cras_alert_pending_alert_value;
27static void *cras_alert_pending_data_value = NULL;
28static size_t cras_alert_pending_data_size_value;
29static size_t cras_iodev_list_update_device_list_called;
30static std::vector<void *> cb_context;
31static size_t cb_output_volume_changed_called;
32static std::vector<int32_t> cb_output_volume_changed_volume;
33static size_t cb_output_mute_changed_called;
34static std::vector<int> cb_output_mute_changed_muted;
35static std::vector<int> cb_output_mute_changed_user_muted;
36static std::vector<int> cb_output_mute_changed_mute_locked;
37static size_t cb_capture_gain_changed_called;
38static std::vector<int32_t> cb_capture_gain_changed_gain;
39static size_t cb_capture_mute_changed_called;
40static std::vector<int> cb_capture_mute_changed_muted;
41static std::vector<int> cb_capture_mute_changed_mute_locked;
42static size_t cb_nodes_changed_called;
43static size_t cb_active_node_changed_called;
44static std::vector<enum CRAS_STREAM_DIRECTION> cb_active_node_changed_dir;
45static std::vector<cras_node_id_t> cb_active_node_changed_node_id;
46static size_t cb_output_node_volume_changed_called;
47static std::vector<cras_node_id_t> cb_output_node_volume_changed_node_id;
48static std::vector<int32_t> cb_output_node_volume_changed_volume;
49static size_t cb_node_left_right_swapped_changed_called;
50static std::vector<cras_node_id_t> cb_node_left_right_swapped_changed_node_id;
51static std::vector<int> cb_node_left_right_swapped_changed_swapped;
52static size_t cb_input_node_gain_changed_called;
53static std::vector<cras_node_id_t> cb_input_node_gain_changed_node_id;
54static std::vector<int32_t> cb_input_node_gain_changed_gain;
55static size_t cb_num_active_streams_changed_called;
56static std::vector<enum CRAS_STREAM_DIRECTION>
57    cb_num_active_streams_changed_dir;
58static std::vector<uint32_t> cb_num_active_streams_changed_num;
59
60static void ResetStubData() {
61  cras_alert_destroy_called = 0;
62  cras_alert_create_called = 0;
63  cras_alert_create_return_values.clear();
64  cras_alert_create_prepare_map.clear();
65  cras_alert_create_flags_map.clear();
66  cras_alert_add_callback_map.clear();
67  cras_alert_pending_alert_value = NULL;
68  cras_alert_pending_data_size_value = 0;
69  if (cras_alert_pending_data_value) {
70    free(cras_alert_pending_data_value);
71    cras_alert_pending_data_value = NULL;
72  }
73  cras_iodev_list_update_device_list_called = 0;
74  cb_context.clear();
75  cb_output_volume_changed_called = 0;
76  cb_output_volume_changed_volume.clear();
77  cb_output_mute_changed_called = 0;
78  cb_output_mute_changed_muted.clear();
79  cb_output_mute_changed_user_muted.clear();
80  cb_output_mute_changed_mute_locked.clear();
81  cb_capture_gain_changed_called = 0;
82  cb_capture_gain_changed_gain.clear();
83  cb_capture_mute_changed_called = 0;
84  cb_capture_mute_changed_muted.clear();
85  cb_capture_mute_changed_mute_locked.clear();
86  cb_nodes_changed_called = 0;
87  cb_active_node_changed_called = 0;
88  cb_active_node_changed_dir.clear();
89  cb_active_node_changed_node_id.clear();
90  cb_output_node_volume_changed_called = 0;
91  cb_output_node_volume_changed_node_id.clear();
92  cb_output_node_volume_changed_volume.clear();
93  cb_node_left_right_swapped_changed_called = 0;
94  cb_node_left_right_swapped_changed_node_id.clear();
95  cb_node_left_right_swapped_changed_swapped.clear();
96  cb_input_node_gain_changed_called = 0;
97  cb_input_node_gain_changed_node_id.clear();
98  cb_input_node_gain_changed_gain.clear();
99  cb_num_active_streams_changed_called = 0;
100  cb_num_active_streams_changed_dir.clear();
101  cb_num_active_streams_changed_num.clear();
102}
103
104/* System output volume changed. */
105void cb_output_volume_changed(void *context, int32_t volume) {
106  cb_output_volume_changed_called++;
107  cb_context.push_back(context);
108  cb_output_volume_changed_volume.push_back(volume);
109}
110/* System output mute changed. */
111void cb_output_mute_changed(void *context,
112                            int muted, int user_muted, int mute_locked) {
113  cb_output_mute_changed_called++;
114  cb_context.push_back(context);
115  cb_output_mute_changed_muted.push_back(muted);
116  cb_output_mute_changed_user_muted.push_back(user_muted);
117  cb_output_mute_changed_mute_locked.push_back(mute_locked);
118}
119/* System input/capture gain changed. */
120void cb_capture_gain_changed(void *context, int32_t gain) {
121  cb_capture_gain_changed_called++;
122  cb_context.push_back(context);
123  cb_capture_gain_changed_gain.push_back(gain);
124}
125
126/* System input/capture mute changed. */
127void cb_capture_mute_changed(void *context, int muted, int mute_locked) {
128  cb_capture_mute_changed_called++;
129  cb_context.push_back(context);
130  cb_capture_mute_changed_muted.push_back(muted);
131  cb_capture_mute_changed_mute_locked.push_back(mute_locked);
132}
133
134/* Device or node topology changed. */
135void cb_nodes_changed(void *context) {
136  cb_nodes_changed_called++;
137  cb_context.push_back(context);
138}
139
140/* Active node changed. A notification is sent for every change.
141 * When there is no active node, node_id is 0. */
142void cb_active_node_changed(void *context,
143                            enum CRAS_STREAM_DIRECTION dir,
144                            cras_node_id_t node_id) {
145  cb_active_node_changed_called++;
146  cb_context.push_back(context);
147  cb_active_node_changed_dir.push_back(dir);
148  cb_active_node_changed_node_id.push_back(node_id);
149}
150
151/* Output node volume changed. */
152void cb_output_node_volume_changed(void *context,
153                                   cras_node_id_t node_id,
154                                   int32_t volume) {
155  cb_output_node_volume_changed_called++;
156  cb_context.push_back(context);
157  cb_output_node_volume_changed_node_id.push_back(node_id);
158  cb_output_node_volume_changed_volume.push_back(volume);
159}
160
161/* Node left/right swapped state change. */
162void cb_node_left_right_swapped_changed(void *context,
163                                        cras_node_id_t node_id,
164                                        int swapped) {
165  cb_node_left_right_swapped_changed_called++;
166  cb_context.push_back(context);
167  cb_node_left_right_swapped_changed_node_id.push_back(node_id);
168  cb_node_left_right_swapped_changed_swapped.push_back(swapped);
169}
170
171/* Input gain changed. */
172void cb_input_node_gain_changed(void *context,
173                                cras_node_id_t node_id,
174                                int32_t gain) {
175  cb_input_node_gain_changed_called++;
176  cb_context.push_back(context);
177  cb_input_node_gain_changed_node_id.push_back(node_id);
178  cb_input_node_gain_changed_gain.push_back(gain);
179}
180
181/* Number of active streams changed. */
182void cb_num_active_streams_changed(void *context,
183                                         enum CRAS_STREAM_DIRECTION dir,
184                                         uint32_t num_active_streams) {
185  cb_num_active_streams_changed_called++;
186  cb_context.push_back(context);
187  cb_num_active_streams_changed_dir.push_back(dir);
188  cb_num_active_streams_changed_num.push_back(num_active_streams);
189}
190
191class ObserverTest : public testing::Test {
192 protected:
193  virtual void SetUp() {
194    int rc;
195
196    ResetStubData();
197    rc = cras_observer_server_init();
198    ASSERT_EQ(0, rc);
199    EXPECT_EQ(13, cras_alert_create_called);
200    EXPECT_EQ(reinterpret_cast<void *>(output_volume_alert),
201              cras_alert_add_callback_map[g_observer->alerts.output_volume]);
202    EXPECT_EQ(reinterpret_cast<void *>(output_mute_alert),
203              cras_alert_add_callback_map[g_observer->alerts.output_mute]);
204    EXPECT_EQ(reinterpret_cast<void *>(capture_gain_alert),
205              cras_alert_add_callback_map[g_observer->alerts.capture_gain]);
206    EXPECT_EQ(reinterpret_cast<void *>(capture_mute_alert),
207              cras_alert_add_callback_map[g_observer->alerts.capture_mute]);
208    EXPECT_EQ(reinterpret_cast<void *>(nodes_alert),
209              cras_alert_add_callback_map[g_observer->alerts.nodes]);
210    EXPECT_EQ(reinterpret_cast<void *>(nodes_prepare),
211              cras_alert_create_prepare_map[g_observer->alerts.nodes]);
212    EXPECT_EQ(reinterpret_cast<void *>(active_node_alert),
213              cras_alert_add_callback_map[g_observer->alerts.active_node]);
214    EXPECT_EQ(CRAS_ALERT_FLAG_KEEP_ALL_DATA,
215              cras_alert_create_flags_map[g_observer->alerts.active_node]);
216    EXPECT_EQ(reinterpret_cast<void *>(output_node_volume_alert),
217            cras_alert_add_callback_map[g_observer->alerts.output_node_volume]);
218    EXPECT_EQ(reinterpret_cast<void *>(node_left_right_swapped_alert),
219       cras_alert_add_callback_map[g_observer->alerts.node_left_right_swapped]);
220    EXPECT_EQ(reinterpret_cast<void *>(input_node_gain_alert),
221            cras_alert_add_callback_map[g_observer->alerts.input_node_gain]);
222    EXPECT_EQ(reinterpret_cast<void *>(num_active_streams_alert),
223       cras_alert_add_callback_map[g_observer->alerts.num_active_streams[
224                                               CRAS_STREAM_OUTPUT]]);
225    EXPECT_EQ(reinterpret_cast<void *>(num_active_streams_alert),
226       cras_alert_add_callback_map[g_observer->alerts.num_active_streams[
227                                               CRAS_STREAM_INPUT]]);
228    EXPECT_EQ(reinterpret_cast<void *>(num_active_streams_alert),
229       cras_alert_add_callback_map[g_observer->alerts.num_active_streams[
230                                               CRAS_STREAM_POST_MIX_PRE_DSP]]);
231    EXPECT_EQ(reinterpret_cast<void *>(suspend_changed_alert),
232       cras_alert_add_callback_map[g_observer->alerts.suspend_changed]);
233
234    cras_observer_get_ops(NULL, &ops1_);
235    EXPECT_NE(0, cras_observer_ops_are_empty(&ops1_));
236
237    cras_observer_get_ops(NULL, &ops2_);
238    EXPECT_NE(0, cras_observer_ops_are_empty(&ops2_));
239
240    context1_ = reinterpret_cast<void *>(1);
241    context2_ = reinterpret_cast<void *>(2);
242  }
243
244  virtual void TearDown() {
245    cras_observer_server_free();
246    EXPECT_EQ(13, cras_alert_destroy_called);
247    ResetStubData();
248  }
249
250  void DoObserverAlert(cras_alert_cb alert, void *data) {
251    client1_ = cras_observer_add(&ops1_, context1_);
252    client2_ = cras_observer_add(&ops2_, context2_);
253    ASSERT_NE(client1_, reinterpret_cast<struct cras_observer_client *>(NULL));
254    ASSERT_NE(client2_, reinterpret_cast<struct cras_observer_client *>(NULL));
255
256    ASSERT_NE(alert, reinterpret_cast<cras_alert_cb>(NULL));
257    alert(NULL, data);
258
259    EXPECT_EQ(cb_context[0], context1_);
260    EXPECT_EQ(cb_context[1], context2_);
261  }
262
263  void DoObserverRemoveClear(cras_alert_cb alert, void *data) {
264    ASSERT_NE(alert, reinterpret_cast<cras_alert_cb>(NULL));
265    ASSERT_NE(client1_, reinterpret_cast<struct cras_observer_client *>(NULL));
266    ASSERT_NE(client2_, reinterpret_cast<struct cras_observer_client *>(NULL));
267
268    // Test observer removal.
269    cras_observer_remove(client1_);
270    cb_context.clear();
271    alert(NULL, data);
272    EXPECT_EQ(cb_context[0], context2_);
273    EXPECT_EQ(cb_context.size(), 1);
274
275    // Clear out ops1_.
276    cras_observer_get_ops(NULL, &ops1_);
277    EXPECT_NE(0, cras_observer_ops_are_empty(&ops1_));
278
279    // Get the current value of ops2_ into ops1_.
280    cras_observer_get_ops(client2_, &ops1_);
281    EXPECT_EQ(0, memcmp((void *)&ops1_, (void *)&ops2_, sizeof(ops1_)));
282
283    // Clear out opts for client2.
284    cras_observer_get_ops(NULL, &ops2_);
285    EXPECT_NE(0, cras_observer_ops_are_empty(&ops2_));
286    cras_observer_set_ops(client2_, &ops2_);
287
288    cb_context.clear();
289    alert(NULL, data);
290    // No callbacks executed.
291    EXPECT_EQ(cb_context.size(), 0);
292  }
293
294  struct cras_observer_client *client1_;
295  struct cras_observer_client *client2_;
296  struct cras_observer_ops ops1_;
297  struct cras_observer_ops ops2_;
298  void *context1_;
299  void *context2_;
300};
301
302TEST_F(ObserverTest, NotifyOutputVolume) {
303  struct cras_observer_alert_data_volume *data;
304  const int32_t volume = 100;
305
306  cras_observer_notify_output_volume(volume);
307  EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.output_volume);
308  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
309  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
310  data = reinterpret_cast<struct cras_observer_alert_data_volume *>(
311             cras_alert_pending_data_value);
312  EXPECT_EQ(data->volume, volume);
313
314  ops1_.output_volume_changed = cb_output_volume_changed;
315  ops2_.output_volume_changed = cb_output_volume_changed;
316  DoObserverAlert(output_volume_alert, data);
317  ASSERT_EQ(2, cb_output_volume_changed_called);
318  EXPECT_EQ(cb_output_volume_changed_volume[0], volume);
319  EXPECT_EQ(cb_output_volume_changed_volume[1], volume);
320
321  DoObserverRemoveClear(output_volume_alert, data);
322};
323
324TEST_F(ObserverTest, NotifyOutputMute) {
325  struct cras_observer_alert_data_mute *data;
326  const int muted = 1;
327  const int user_muted = 0;
328  const int mute_locked = 0;
329
330  cras_observer_notify_output_mute(muted, user_muted, mute_locked);
331  EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.output_mute);
332  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
333  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
334  data = reinterpret_cast<struct cras_observer_alert_data_mute *>(
335             cras_alert_pending_data_value);
336  EXPECT_EQ(data->muted, muted);
337  EXPECT_EQ(data->user_muted, user_muted);
338  EXPECT_EQ(data->mute_locked, mute_locked);
339
340  ops1_.output_mute_changed = cb_output_mute_changed;
341  ops2_.output_mute_changed = cb_output_mute_changed;
342  DoObserverAlert(output_mute_alert, data);
343  ASSERT_EQ(2, cb_output_mute_changed_called);
344  EXPECT_EQ(cb_output_mute_changed_muted[0], muted);
345  EXPECT_EQ(cb_output_mute_changed_muted[1], muted);
346  EXPECT_EQ(cb_output_mute_changed_user_muted[0], user_muted);
347  EXPECT_EQ(cb_output_mute_changed_user_muted[1], user_muted);
348  EXPECT_EQ(cb_output_mute_changed_mute_locked[0], mute_locked);
349  EXPECT_EQ(cb_output_mute_changed_mute_locked[1], mute_locked);
350
351  DoObserverRemoveClear(output_mute_alert, data);
352};
353
354TEST_F(ObserverTest, NotifyCaptureGain) {
355  struct cras_observer_alert_data_volume *data;
356  const int32_t gain = -20;
357
358  cras_observer_notify_capture_gain(gain);
359  EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.capture_gain);
360  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
361  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
362  data = reinterpret_cast<struct cras_observer_alert_data_volume *>(
363             cras_alert_pending_data_value);
364  EXPECT_EQ(data->volume, gain);
365
366  ops1_.capture_gain_changed = cb_capture_gain_changed;
367  ops2_.capture_gain_changed = cb_capture_gain_changed;
368  DoObserverAlert(capture_gain_alert, data);
369  ASSERT_EQ(2, cb_capture_gain_changed_called);
370  EXPECT_EQ(cb_capture_gain_changed_gain[0], gain);
371  EXPECT_EQ(cb_capture_gain_changed_gain[1], gain);
372
373  DoObserverRemoveClear(capture_gain_alert, data);
374};
375
376TEST_F(ObserverTest, NotifyCaptureMute) {
377  struct cras_observer_alert_data_mute *data;
378  const int muted = 1;
379  const int mute_locked = 0;
380
381  cras_observer_notify_capture_mute(muted, mute_locked);
382  EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.capture_mute);
383  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
384  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
385  data = reinterpret_cast<struct cras_observer_alert_data_mute *>(
386             cras_alert_pending_data_value);
387  EXPECT_EQ(data->muted, muted);
388  EXPECT_EQ(data->mute_locked, mute_locked);
389
390  ops1_.capture_mute_changed = cb_capture_mute_changed;
391  ops2_.capture_mute_changed = cb_capture_mute_changed;
392  DoObserverAlert(capture_mute_alert, data);
393  ASSERT_EQ(2, cb_capture_mute_changed_called);
394  EXPECT_EQ(cb_capture_mute_changed_muted[0], muted);
395  EXPECT_EQ(cb_capture_mute_changed_muted[1], muted);
396  EXPECT_EQ(cb_capture_mute_changed_mute_locked[0], mute_locked);
397  EXPECT_EQ(cb_capture_mute_changed_mute_locked[1], mute_locked);
398
399  DoObserverRemoveClear(capture_mute_alert, data);
400};
401
402TEST_F(ObserverTest, NotifyNodes) {
403  cras_observer_notify_nodes();
404  EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.nodes);
405
406  ops1_.nodes_changed = cb_nodes_changed;
407  ops2_.nodes_changed = cb_nodes_changed;
408  DoObserverAlert(nodes_alert, NULL);
409  ASSERT_EQ(2, cb_nodes_changed_called);
410
411  DoObserverRemoveClear(nodes_alert, NULL);
412};
413
414TEST_F(ObserverTest, NotifyActiveNode) {
415  struct cras_observer_alert_data_active_node *data;
416  const enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_INPUT;
417  const cras_node_id_t node_id = 0x0001000100020002;
418
419  cras_observer_notify_active_node(dir, node_id);
420  EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.active_node);
421  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
422  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
423  data = reinterpret_cast<struct cras_observer_alert_data_active_node *>(
424             cras_alert_pending_data_value);
425  EXPECT_EQ(data->node_id, node_id);
426  EXPECT_EQ(data->direction, dir);
427
428  ops1_.active_node_changed = cb_active_node_changed;
429  ops2_.active_node_changed = cb_active_node_changed;
430  DoObserverAlert(active_node_alert, data);
431  ASSERT_EQ(2, cb_active_node_changed_called);
432  EXPECT_EQ(cb_active_node_changed_dir[0], dir);
433  EXPECT_EQ(cb_active_node_changed_dir[1], dir);
434  EXPECT_EQ(cb_active_node_changed_node_id[0], node_id);
435  EXPECT_EQ(cb_active_node_changed_node_id[1], node_id);
436
437  DoObserverRemoveClear(active_node_alert, data);
438};
439
440TEST_F(ObserverTest, NotifyOutputNodeVolume) {
441  struct cras_observer_alert_data_node_volume *data;
442  const cras_node_id_t node_id = 0x0001000100020002;
443  const int32_t volume = 100;
444
445  cras_observer_notify_output_node_volume(node_id, volume);
446  EXPECT_EQ(cras_alert_pending_alert_value,
447            g_observer->alerts.output_node_volume);
448  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
449  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
450  data = reinterpret_cast<struct cras_observer_alert_data_node_volume *>(
451             cras_alert_pending_data_value);
452  EXPECT_EQ(data->node_id, node_id);
453  EXPECT_EQ(data->volume, volume);
454
455  ops1_.output_node_volume_changed = cb_output_node_volume_changed;
456  ops2_.output_node_volume_changed = cb_output_node_volume_changed;
457  DoObserverAlert(output_node_volume_alert, data);
458  ASSERT_EQ(2, cb_output_node_volume_changed_called);
459  EXPECT_EQ(cb_output_node_volume_changed_volume[0], volume);
460  EXPECT_EQ(cb_output_node_volume_changed_volume[1], volume);
461  EXPECT_EQ(cb_output_node_volume_changed_node_id[0], node_id);
462  EXPECT_EQ(cb_output_node_volume_changed_node_id[1], node_id);
463
464  DoObserverRemoveClear(output_node_volume_alert, data);
465};
466
467TEST_F(ObserverTest, NotifyNodeLeftRightSwapped) {
468  struct cras_observer_alert_data_node_lr_swapped *data;
469  const cras_node_id_t node_id = 0x0001000100020002;
470  const int swapped = 1;
471
472  cras_observer_notify_node_left_right_swapped(node_id, swapped);
473  EXPECT_EQ(cras_alert_pending_alert_value,
474            g_observer->alerts.node_left_right_swapped);
475  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
476  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
477  data = reinterpret_cast<struct cras_observer_alert_data_node_lr_swapped *>(
478             cras_alert_pending_data_value);
479  EXPECT_EQ(data->node_id, node_id);
480  EXPECT_EQ(data->swapped, swapped);
481
482  ops1_.node_left_right_swapped_changed = cb_node_left_right_swapped_changed;
483  ops2_.node_left_right_swapped_changed = cb_node_left_right_swapped_changed;
484  DoObserverAlert(node_left_right_swapped_alert, data);
485  ASSERT_EQ(2, cb_node_left_right_swapped_changed_called);
486  EXPECT_EQ(cb_node_left_right_swapped_changed_swapped[0], swapped);
487  EXPECT_EQ(cb_node_left_right_swapped_changed_swapped[1], swapped);
488  EXPECT_EQ(cb_node_left_right_swapped_changed_node_id[0], node_id);
489  EXPECT_EQ(cb_node_left_right_swapped_changed_node_id[1], node_id);
490
491  DoObserverRemoveClear(node_left_right_swapped_alert, data);
492};
493
494TEST_F(ObserverTest, NotifyInputNodeGain) {
495  struct cras_observer_alert_data_node_volume *data;
496  const cras_node_id_t node_id = 0x0001000100020002;
497  const int32_t gain = -20;
498
499  cras_observer_notify_input_node_gain(node_id, gain);
500  EXPECT_EQ(cras_alert_pending_alert_value,
501            g_observer->alerts.input_node_gain);
502  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
503  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
504  data = reinterpret_cast<struct cras_observer_alert_data_node_volume *>(
505             cras_alert_pending_data_value);
506  EXPECT_EQ(data->node_id, node_id);
507  EXPECT_EQ(data->volume, gain);
508
509  ops1_.input_node_gain_changed = cb_input_node_gain_changed;
510  ops2_.input_node_gain_changed = cb_input_node_gain_changed;
511  DoObserverAlert(input_node_gain_alert, data);
512  ASSERT_EQ(2, cb_input_node_gain_changed_called);
513  EXPECT_EQ(cb_input_node_gain_changed_gain[0], gain);
514  EXPECT_EQ(cb_input_node_gain_changed_gain[1], gain);
515  EXPECT_EQ(cb_input_node_gain_changed_node_id[0], node_id);
516  EXPECT_EQ(cb_input_node_gain_changed_node_id[1], node_id);
517
518  DoObserverRemoveClear(input_node_gain_alert, data);
519};
520
521TEST_F(ObserverTest, NotifySuspendChanged) {
522  struct cras_observer_alert_data_suspend *data;
523
524  cras_observer_notify_suspend_changed(1);
525  EXPECT_EQ(cras_alert_pending_alert_value,
526            g_observer->alerts.suspend_changed);
527  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
528  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
529  data = reinterpret_cast<struct cras_observer_alert_data_suspend *>(
530      cras_alert_pending_data_value);
531  EXPECT_EQ(data->suspended, 1);
532
533  cras_observer_notify_suspend_changed(0);
534  EXPECT_EQ(cras_alert_pending_alert_value,
535            g_observer->alerts.suspend_changed);
536  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
537  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
538  data = reinterpret_cast<struct cras_observer_alert_data_suspend *>(
539      cras_alert_pending_data_value);
540  EXPECT_EQ(data->suspended, 0);
541}
542
543TEST_F(ObserverTest, NotifyNumActiveStreams) {
544  struct cras_observer_alert_data_streams *data;
545  const enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_INPUT;
546  const uint32_t active_streams = 10;
547
548  cras_observer_notify_num_active_streams(dir, active_streams);
549  EXPECT_EQ(cras_alert_pending_alert_value,
550            g_observer->alerts.num_active_streams[CRAS_STREAM_INPUT]);
551  ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
552  ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
553  data = reinterpret_cast<struct cras_observer_alert_data_streams *>(
554             cras_alert_pending_data_value);
555  EXPECT_EQ(data->num_active_streams, active_streams);
556  EXPECT_EQ(data->direction, dir);
557
558  ops1_.num_active_streams_changed = cb_num_active_streams_changed;
559  ops2_.num_active_streams_changed = cb_num_active_streams_changed;
560  DoObserverAlert(num_active_streams_alert, data);
561  ASSERT_EQ(2, cb_num_active_streams_changed_called);
562  EXPECT_EQ(cb_num_active_streams_changed_dir[0], dir);
563  EXPECT_EQ(cb_num_active_streams_changed_dir[1], dir);
564  EXPECT_EQ(cb_num_active_streams_changed_num[0], active_streams);
565  EXPECT_EQ(cb_num_active_streams_changed_num[1], active_streams);
566
567  DoObserverRemoveClear(num_active_streams_alert, data);
568};
569
570// Stubs
571extern "C" {
572
573void cras_alert_destroy(struct cras_alert *alert) {
574  cras_alert_destroy_called++;
575}
576
577struct cras_alert *cras_alert_create(cras_alert_prepare prepare,
578                                     unsigned int flags) {
579  struct cras_alert *alert = NULL;
580
581  cras_alert_create_called++;
582  alert = reinterpret_cast<struct cras_alert*>(cras_alert_create_called);
583  cras_alert_create_return_values.push_back(alert);
584  cras_alert_create_flags_map[alert] = flags;
585  cras_alert_create_prepare_map[alert] = reinterpret_cast<void *>(prepare);
586  return alert;
587}
588
589int cras_alert_add_callback(struct cras_alert *alert, cras_alert_cb cb,
590			    void *arg) {
591  cras_alert_add_callback_map[alert] = reinterpret_cast<void *>(cb);
592  return 0;
593}
594
595void cras_alert_pending(struct cras_alert *alert) {
596  cras_alert_pending_alert_value = alert;
597}
598
599void cras_alert_pending_data(struct cras_alert *alert,
600			     void *data, size_t data_size) {
601  cras_alert_pending_alert_value = alert;
602  cras_alert_pending_data_size_value = data_size;
603  if (cras_alert_pending_data_value)
604    free(cras_alert_pending_data_value);
605  if (data) {
606    cras_alert_pending_data_value = malloc(data_size);
607    memcpy(cras_alert_pending_data_value, data, data_size);
608  }
609  else
610    cras_alert_pending_data_value = NULL;
611}
612
613void cras_iodev_list_update_device_list() {
614  cras_iodev_list_update_device_list_called++;
615}
616
617}  // extern "C"
618
619}  // namespace
620
621int main(int argc, char **argv) {
622  ::testing::InitGoogleTest(&argc, argv);
623  openlog(NULL, LOG_PERROR, LOG_USER);
624  return RUN_ALL_TESTS();
625}
626