• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 extern "C" {
13 #include "cras_observer.c"
14 }
15 
16 namespace {
17 
18 static size_t cras_alert_destroy_called;
19 static size_t cras_alert_create_called;
20 static std::vector<struct cras_alert *> cras_alert_create_return_values;
21 typedef std::map<struct cras_alert *, void *> alert_callback_map;
22 static alert_callback_map cras_alert_create_prepare_map;
23 static alert_callback_map cras_alert_add_callback_map;
24 typedef std::map<struct cras_alert *, unsigned int> alert_flags_map;
25 static alert_flags_map cras_alert_create_flags_map;
26 static struct cras_alert *cras_alert_pending_alert_value;
27 static void *cras_alert_pending_data_value = NULL;
28 static size_t cras_alert_pending_data_size_value;
29 static size_t cras_iodev_list_update_device_list_called;
30 static std::vector<void *> cb_context;
31 static size_t cb_output_volume_changed_called;
32 static std::vector<int32_t> cb_output_volume_changed_volume;
33 static size_t cb_output_mute_changed_called;
34 static std::vector<int> cb_output_mute_changed_muted;
35 static std::vector<int> cb_output_mute_changed_user_muted;
36 static std::vector<int> cb_output_mute_changed_mute_locked;
37 static size_t cb_capture_gain_changed_called;
38 static std::vector<int32_t> cb_capture_gain_changed_gain;
39 static size_t cb_capture_mute_changed_called;
40 static std::vector<int> cb_capture_mute_changed_muted;
41 static std::vector<int> cb_capture_mute_changed_mute_locked;
42 static size_t cb_nodes_changed_called;
43 static size_t cb_active_node_changed_called;
44 static std::vector<enum CRAS_STREAM_DIRECTION> cb_active_node_changed_dir;
45 static std::vector<cras_node_id_t> cb_active_node_changed_node_id;
46 static size_t cb_output_node_volume_changed_called;
47 static std::vector<cras_node_id_t> cb_output_node_volume_changed_node_id;
48 static std::vector<int32_t> cb_output_node_volume_changed_volume;
49 static size_t cb_node_left_right_swapped_changed_called;
50 static std::vector<cras_node_id_t> cb_node_left_right_swapped_changed_node_id;
51 static std::vector<int> cb_node_left_right_swapped_changed_swapped;
52 static size_t cb_input_node_gain_changed_called;
53 static std::vector<cras_node_id_t> cb_input_node_gain_changed_node_id;
54 static std::vector<int32_t> cb_input_node_gain_changed_gain;
55 static size_t cb_num_active_streams_changed_called;
56 static std::vector<enum CRAS_STREAM_DIRECTION>
57     cb_num_active_streams_changed_dir;
58 static std::vector<uint32_t> cb_num_active_streams_changed_num;
59 
ResetStubData()60 static 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. */
cb_output_volume_changed(void * context,int32_t volume)105 void 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. */
cb_output_mute_changed(void * context,int muted,int user_muted,int mute_locked)111 void 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. */
cb_capture_gain_changed(void * context,int32_t gain)120 void 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. */
cb_capture_mute_changed(void * context,int muted,int mute_locked)127 void 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. */
cb_nodes_changed(void * context)135 void 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. */
cb_active_node_changed(void * context,enum CRAS_STREAM_DIRECTION dir,cras_node_id_t node_id)142 void 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. */
cb_output_node_volume_changed(void * context,cras_node_id_t node_id,int32_t volume)152 void 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. */
cb_node_left_right_swapped_changed(void * context,cras_node_id_t node_id,int swapped)162 void 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. */
cb_input_node_gain_changed(void * context,cras_node_id_t node_id,int32_t gain)172 void 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. */
cb_num_active_streams_changed(void * context,enum CRAS_STREAM_DIRECTION dir,uint32_t num_active_streams)182 void 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 
191 class ObserverTest : public testing::Test {
192  protected:
SetUp()193   virtual void SetUp() {
194     int rc;
195 
196     ResetStubData();
197     rc = cras_observer_server_init();
198     ASSERT_EQ(0, rc);
199     EXPECT_EQ(15, 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     EXPECT_EQ(reinterpret_cast<void *>(hotword_triggered_alert),
234         cras_alert_add_callback_map[g_observer->alerts.hotword_triggered]);
235     EXPECT_EQ(reinterpret_cast<void *>(non_empty_audio_state_changed_alert),
236         cras_alert_add_callback_map[
237                 g_observer->alerts.non_empty_audio_state_changed]);
238 
239     cras_observer_get_ops(NULL, &ops1_);
240     EXPECT_NE(0, cras_observer_ops_are_empty(&ops1_));
241 
242     cras_observer_get_ops(NULL, &ops2_);
243     EXPECT_NE(0, cras_observer_ops_are_empty(&ops2_));
244 
245     context1_ = reinterpret_cast<void *>(1);
246     context2_ = reinterpret_cast<void *>(2);
247   }
248 
TearDown()249   virtual void TearDown() {
250     cras_observer_server_free();
251     EXPECT_EQ(15, cras_alert_destroy_called);
252     ResetStubData();
253   }
254 
DoObserverAlert(cras_alert_cb alert,void * data)255   void DoObserverAlert(cras_alert_cb alert, void *data) {
256     client1_ = cras_observer_add(&ops1_, context1_);
257     client2_ = cras_observer_add(&ops2_, context2_);
258     ASSERT_NE(client1_, reinterpret_cast<struct cras_observer_client *>(NULL));
259     ASSERT_NE(client2_, reinterpret_cast<struct cras_observer_client *>(NULL));
260 
261     ASSERT_NE(alert, reinterpret_cast<cras_alert_cb>(NULL));
262     alert(NULL, data);
263 
264     EXPECT_EQ(cb_context[0], context1_);
265     EXPECT_EQ(cb_context[1], context2_);
266   }
267 
DoObserverRemoveClear(cras_alert_cb alert,void * data)268   void DoObserverRemoveClear(cras_alert_cb alert, void *data) {
269     ASSERT_NE(alert, reinterpret_cast<cras_alert_cb>(NULL));
270     ASSERT_NE(client1_, reinterpret_cast<struct cras_observer_client *>(NULL));
271     ASSERT_NE(client2_, reinterpret_cast<struct cras_observer_client *>(NULL));
272 
273     // Test observer removal.
274     cras_observer_remove(client1_);
275     cb_context.clear();
276     alert(NULL, data);
277     EXPECT_EQ(cb_context[0], context2_);
278     EXPECT_EQ(cb_context.size(), 1);
279 
280     // Clear out ops1_.
281     cras_observer_get_ops(NULL, &ops1_);
282     EXPECT_NE(0, cras_observer_ops_are_empty(&ops1_));
283 
284     // Get the current value of ops2_ into ops1_.
285     cras_observer_get_ops(client2_, &ops1_);
286     EXPECT_EQ(0, memcmp((void *)&ops1_, (void *)&ops2_, sizeof(ops1_)));
287 
288     // Clear out opts for client2.
289     cras_observer_get_ops(NULL, &ops2_);
290     EXPECT_NE(0, cras_observer_ops_are_empty(&ops2_));
291     cras_observer_set_ops(client2_, &ops2_);
292 
293     cras_observer_remove(client2_);
294     cb_context.clear();
295     alert(NULL, data);
296     // No callbacks executed.
297     EXPECT_EQ(cb_context.size(), 0);
298   }
299 
300   struct cras_observer_client *client1_;
301   struct cras_observer_client *client2_;
302   struct cras_observer_ops ops1_;
303   struct cras_observer_ops ops2_;
304   void *context1_;
305   void *context2_;
306 };
307 
TEST_F(ObserverTest,NotifyOutputVolume)308 TEST_F(ObserverTest, NotifyOutputVolume) {
309   struct cras_observer_alert_data_volume *data;
310   const int32_t volume = 100;
311 
312   cras_observer_notify_output_volume(volume);
313   EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.output_volume);
314   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
315   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
316   data = reinterpret_cast<struct cras_observer_alert_data_volume *>(
317              cras_alert_pending_data_value);
318   EXPECT_EQ(data->volume, volume);
319 
320   ops1_.output_volume_changed = cb_output_volume_changed;
321   ops2_.output_volume_changed = cb_output_volume_changed;
322   DoObserverAlert(output_volume_alert, data);
323   ASSERT_EQ(2, cb_output_volume_changed_called);
324   EXPECT_EQ(cb_output_volume_changed_volume[0], volume);
325   EXPECT_EQ(cb_output_volume_changed_volume[1], volume);
326 
327   DoObserverRemoveClear(output_volume_alert, data);
328 };
329 
TEST_F(ObserverTest,NotifyOutputMute)330 TEST_F(ObserverTest, NotifyOutputMute) {
331   struct cras_observer_alert_data_mute *data;
332   const int muted = 1;
333   const int user_muted = 0;
334   const int mute_locked = 0;
335 
336   cras_observer_notify_output_mute(muted, user_muted, mute_locked);
337   EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.output_mute);
338   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
339   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
340   data = reinterpret_cast<struct cras_observer_alert_data_mute *>(
341              cras_alert_pending_data_value);
342   EXPECT_EQ(data->muted, muted);
343   EXPECT_EQ(data->user_muted, user_muted);
344   EXPECT_EQ(data->mute_locked, mute_locked);
345 
346   ops1_.output_mute_changed = cb_output_mute_changed;
347   ops2_.output_mute_changed = cb_output_mute_changed;
348   DoObserverAlert(output_mute_alert, data);
349   ASSERT_EQ(2, cb_output_mute_changed_called);
350   EXPECT_EQ(cb_output_mute_changed_muted[0], muted);
351   EXPECT_EQ(cb_output_mute_changed_muted[1], muted);
352   EXPECT_EQ(cb_output_mute_changed_user_muted[0], user_muted);
353   EXPECT_EQ(cb_output_mute_changed_user_muted[1], user_muted);
354   EXPECT_EQ(cb_output_mute_changed_mute_locked[0], mute_locked);
355   EXPECT_EQ(cb_output_mute_changed_mute_locked[1], mute_locked);
356 
357   DoObserverRemoveClear(output_mute_alert, data);
358 };
359 
TEST_F(ObserverTest,NotifyCaptureGain)360 TEST_F(ObserverTest, NotifyCaptureGain) {
361   struct cras_observer_alert_data_volume *data;
362   const int32_t gain = -20;
363 
364   cras_observer_notify_capture_gain(gain);
365   EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.capture_gain);
366   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
367   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
368   data = reinterpret_cast<struct cras_observer_alert_data_volume *>(
369              cras_alert_pending_data_value);
370   EXPECT_EQ(data->volume, gain);
371 
372   ops1_.capture_gain_changed = cb_capture_gain_changed;
373   ops2_.capture_gain_changed = cb_capture_gain_changed;
374   DoObserverAlert(capture_gain_alert, data);
375   ASSERT_EQ(2, cb_capture_gain_changed_called);
376   EXPECT_EQ(cb_capture_gain_changed_gain[0], gain);
377   EXPECT_EQ(cb_capture_gain_changed_gain[1], gain);
378 
379   DoObserverRemoveClear(capture_gain_alert, data);
380 };
381 
TEST_F(ObserverTest,NotifyCaptureMute)382 TEST_F(ObserverTest, NotifyCaptureMute) {
383   struct cras_observer_alert_data_mute *data;
384   const int muted = 1;
385   const int mute_locked = 0;
386 
387   cras_observer_notify_capture_mute(muted, mute_locked);
388   EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.capture_mute);
389   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
390   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
391   data = reinterpret_cast<struct cras_observer_alert_data_mute *>(
392              cras_alert_pending_data_value);
393   EXPECT_EQ(data->muted, muted);
394   EXPECT_EQ(data->mute_locked, mute_locked);
395 
396   ops1_.capture_mute_changed = cb_capture_mute_changed;
397   ops2_.capture_mute_changed = cb_capture_mute_changed;
398   DoObserverAlert(capture_mute_alert, data);
399   ASSERT_EQ(2, cb_capture_mute_changed_called);
400   EXPECT_EQ(cb_capture_mute_changed_muted[0], muted);
401   EXPECT_EQ(cb_capture_mute_changed_muted[1], muted);
402   EXPECT_EQ(cb_capture_mute_changed_mute_locked[0], mute_locked);
403   EXPECT_EQ(cb_capture_mute_changed_mute_locked[1], mute_locked);
404 
405   DoObserverRemoveClear(capture_mute_alert, data);
406 };
407 
TEST_F(ObserverTest,NotifyNodes)408 TEST_F(ObserverTest, NotifyNodes) {
409   cras_observer_notify_nodes();
410   EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.nodes);
411 
412   ops1_.nodes_changed = cb_nodes_changed;
413   ops2_.nodes_changed = cb_nodes_changed;
414   DoObserverAlert(nodes_alert, NULL);
415   ASSERT_EQ(2, cb_nodes_changed_called);
416 
417   DoObserverRemoveClear(nodes_alert, NULL);
418 };
419 
TEST_F(ObserverTest,NotifyActiveNode)420 TEST_F(ObserverTest, NotifyActiveNode) {
421   struct cras_observer_alert_data_active_node *data;
422   const enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_INPUT;
423   const cras_node_id_t node_id = 0x0001000100020002;
424 
425   cras_observer_notify_active_node(dir, node_id);
426   EXPECT_EQ(cras_alert_pending_alert_value, g_observer->alerts.active_node);
427   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
428   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
429   data = reinterpret_cast<struct cras_observer_alert_data_active_node *>(
430              cras_alert_pending_data_value);
431   EXPECT_EQ(data->node_id, node_id);
432   EXPECT_EQ(data->direction, dir);
433 
434   ops1_.active_node_changed = cb_active_node_changed;
435   ops2_.active_node_changed = cb_active_node_changed;
436   DoObserverAlert(active_node_alert, data);
437   ASSERT_EQ(2, cb_active_node_changed_called);
438   EXPECT_EQ(cb_active_node_changed_dir[0], dir);
439   EXPECT_EQ(cb_active_node_changed_dir[1], dir);
440   EXPECT_EQ(cb_active_node_changed_node_id[0], node_id);
441   EXPECT_EQ(cb_active_node_changed_node_id[1], node_id);
442 
443   DoObserverRemoveClear(active_node_alert, data);
444 };
445 
TEST_F(ObserverTest,NotifyOutputNodeVolume)446 TEST_F(ObserverTest, NotifyOutputNodeVolume) {
447   struct cras_observer_alert_data_node_volume *data;
448   const cras_node_id_t node_id = 0x0001000100020002;
449   const int32_t volume = 100;
450 
451   cras_observer_notify_output_node_volume(node_id, volume);
452   EXPECT_EQ(cras_alert_pending_alert_value,
453             g_observer->alerts.output_node_volume);
454   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
455   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
456   data = reinterpret_cast<struct cras_observer_alert_data_node_volume *>(
457              cras_alert_pending_data_value);
458   EXPECT_EQ(data->node_id, node_id);
459   EXPECT_EQ(data->volume, volume);
460 
461   ops1_.output_node_volume_changed = cb_output_node_volume_changed;
462   ops2_.output_node_volume_changed = cb_output_node_volume_changed;
463   DoObserverAlert(output_node_volume_alert, data);
464   ASSERT_EQ(2, cb_output_node_volume_changed_called);
465   EXPECT_EQ(cb_output_node_volume_changed_volume[0], volume);
466   EXPECT_EQ(cb_output_node_volume_changed_volume[1], volume);
467   EXPECT_EQ(cb_output_node_volume_changed_node_id[0], node_id);
468   EXPECT_EQ(cb_output_node_volume_changed_node_id[1], node_id);
469 
470   DoObserverRemoveClear(output_node_volume_alert, data);
471 };
472 
TEST_F(ObserverTest,NotifyNodeLeftRightSwapped)473 TEST_F(ObserverTest, NotifyNodeLeftRightSwapped) {
474   struct cras_observer_alert_data_node_lr_swapped *data;
475   const cras_node_id_t node_id = 0x0001000100020002;
476   const int swapped = 1;
477 
478   cras_observer_notify_node_left_right_swapped(node_id, swapped);
479   EXPECT_EQ(cras_alert_pending_alert_value,
480             g_observer->alerts.node_left_right_swapped);
481   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
482   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
483   data = reinterpret_cast<struct cras_observer_alert_data_node_lr_swapped *>(
484              cras_alert_pending_data_value);
485   EXPECT_EQ(data->node_id, node_id);
486   EXPECT_EQ(data->swapped, swapped);
487 
488   ops1_.node_left_right_swapped_changed = cb_node_left_right_swapped_changed;
489   ops2_.node_left_right_swapped_changed = cb_node_left_right_swapped_changed;
490   DoObserverAlert(node_left_right_swapped_alert, data);
491   ASSERT_EQ(2, cb_node_left_right_swapped_changed_called);
492   EXPECT_EQ(cb_node_left_right_swapped_changed_swapped[0], swapped);
493   EXPECT_EQ(cb_node_left_right_swapped_changed_swapped[1], swapped);
494   EXPECT_EQ(cb_node_left_right_swapped_changed_node_id[0], node_id);
495   EXPECT_EQ(cb_node_left_right_swapped_changed_node_id[1], node_id);
496 
497   DoObserverRemoveClear(node_left_right_swapped_alert, data);
498 };
499 
TEST_F(ObserverTest,NotifyInputNodeGain)500 TEST_F(ObserverTest, NotifyInputNodeGain) {
501   struct cras_observer_alert_data_node_volume *data;
502   const cras_node_id_t node_id = 0x0001000100020002;
503   const int32_t gain = -20;
504 
505   cras_observer_notify_input_node_gain(node_id, gain);
506   EXPECT_EQ(cras_alert_pending_alert_value,
507             g_observer->alerts.input_node_gain);
508   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
509   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
510   data = reinterpret_cast<struct cras_observer_alert_data_node_volume *>(
511              cras_alert_pending_data_value);
512   EXPECT_EQ(data->node_id, node_id);
513   EXPECT_EQ(data->volume, gain);
514 
515   ops1_.input_node_gain_changed = cb_input_node_gain_changed;
516   ops2_.input_node_gain_changed = cb_input_node_gain_changed;
517   DoObserverAlert(input_node_gain_alert, data);
518   ASSERT_EQ(2, cb_input_node_gain_changed_called);
519   EXPECT_EQ(cb_input_node_gain_changed_gain[0], gain);
520   EXPECT_EQ(cb_input_node_gain_changed_gain[1], gain);
521   EXPECT_EQ(cb_input_node_gain_changed_node_id[0], node_id);
522   EXPECT_EQ(cb_input_node_gain_changed_node_id[1], node_id);
523 
524   DoObserverRemoveClear(input_node_gain_alert, data);
525 };
526 
TEST_F(ObserverTest,NotifySuspendChanged)527 TEST_F(ObserverTest, NotifySuspendChanged) {
528   struct cras_observer_alert_data_suspend *data;
529 
530   cras_observer_notify_suspend_changed(1);
531   EXPECT_EQ(cras_alert_pending_alert_value,
532             g_observer->alerts.suspend_changed);
533   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
534   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
535   data = reinterpret_cast<struct cras_observer_alert_data_suspend *>(
536       cras_alert_pending_data_value);
537   EXPECT_EQ(data->suspended, 1);
538 
539   cras_observer_notify_suspend_changed(0);
540   EXPECT_EQ(cras_alert_pending_alert_value,
541             g_observer->alerts.suspend_changed);
542   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
543   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
544   data = reinterpret_cast<struct cras_observer_alert_data_suspend *>(
545       cras_alert_pending_data_value);
546   EXPECT_EQ(data->suspended, 0);
547 }
548 
TEST_F(ObserverTest,NotifyNumActiveStreams)549 TEST_F(ObserverTest, NotifyNumActiveStreams) {
550   struct cras_observer_alert_data_streams *data;
551   const enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_INPUT;
552   const uint32_t active_streams = 10;
553 
554   cras_observer_notify_num_active_streams(dir, active_streams);
555   EXPECT_EQ(cras_alert_pending_alert_value,
556             g_observer->alerts.num_active_streams[CRAS_STREAM_INPUT]);
557   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
558   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
559   data = reinterpret_cast<struct cras_observer_alert_data_streams *>(
560              cras_alert_pending_data_value);
561   EXPECT_EQ(data->num_active_streams, active_streams);
562   EXPECT_EQ(data->direction, dir);
563 
564   ops1_.num_active_streams_changed = cb_num_active_streams_changed;
565   ops2_.num_active_streams_changed = cb_num_active_streams_changed;
566   DoObserverAlert(num_active_streams_alert, data);
567   ASSERT_EQ(2, cb_num_active_streams_changed_called);
568   EXPECT_EQ(cb_num_active_streams_changed_dir[0], dir);
569   EXPECT_EQ(cb_num_active_streams_changed_dir[1], dir);
570   EXPECT_EQ(cb_num_active_streams_changed_num[0], active_streams);
571   EXPECT_EQ(cb_num_active_streams_changed_num[1], active_streams);
572 
573   DoObserverRemoveClear(num_active_streams_alert, data);
574 };
575 
TEST_F(ObserverTest,NotifyHotwordTriggered)576 TEST_F(ObserverTest, NotifyHotwordTriggered) {
577   struct cras_observer_alert_data_hotword_triggered *data;
578 
579   cras_observer_notify_hotword_triggered(100, 200);
580   EXPECT_EQ(cras_alert_pending_alert_value,
581       g_observer->alerts.hotword_triggered);
582   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
583   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
584   data = reinterpret_cast<struct cras_observer_alert_data_hotword_triggered *>(
585           cras_alert_pending_data_value);
586   EXPECT_EQ(data->tv_sec, 100);
587   EXPECT_EQ(data->tv_nsec, 200);
588 }
589 
TEST_F(ObserverTest,NonEmpyAudioStateChanged)590 TEST_F(ObserverTest, NonEmpyAudioStateChanged) {
591   struct cras_observer_non_empty_audio_state *data;
592 
593   cras_observer_notify_non_empty_audio_state_changed(1);
594   EXPECT_EQ(cras_alert_pending_alert_value,
595     g_observer->alerts.non_empty_audio_state_changed);
596   ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
597   ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void *>(NULL));
598   data = reinterpret_cast<struct cras_observer_non_empty_audio_state *>(
599     cras_alert_pending_data_value);
600   EXPECT_EQ(data->non_empty, 1);
601 }
602 
603 // Stubs
604 extern "C" {
605 
cras_alert_destroy(struct cras_alert * alert)606 void cras_alert_destroy(struct cras_alert *alert) {
607   cras_alert_destroy_called++;
608 }
609 
cras_alert_create(cras_alert_prepare prepare,unsigned int flags)610 struct cras_alert *cras_alert_create(cras_alert_prepare prepare,
611                                      unsigned int flags) {
612   struct cras_alert *alert = NULL;
613 
614   cras_alert_create_called++;
615   alert = reinterpret_cast<struct cras_alert*>(cras_alert_create_called);
616   cras_alert_create_return_values.push_back(alert);
617   cras_alert_create_flags_map[alert] = flags;
618   cras_alert_create_prepare_map[alert] = reinterpret_cast<void *>(prepare);
619   return alert;
620 }
621 
cras_alert_add_callback(struct cras_alert * alert,cras_alert_cb cb,void * arg)622 int cras_alert_add_callback(struct cras_alert *alert, cras_alert_cb cb,
623 			    void *arg) {
624   cras_alert_add_callback_map[alert] = reinterpret_cast<void *>(cb);
625   return 0;
626 }
627 
cras_alert_pending(struct cras_alert * alert)628 void cras_alert_pending(struct cras_alert *alert) {
629   cras_alert_pending_alert_value = alert;
630 }
631 
cras_alert_pending_data(struct cras_alert * alert,void * data,size_t data_size)632 void cras_alert_pending_data(struct cras_alert *alert,
633 			     void *data, size_t data_size) {
634   cras_alert_pending_alert_value = alert;
635   cras_alert_pending_data_size_value = data_size;
636   if (cras_alert_pending_data_value)
637     free(cras_alert_pending_data_value);
638   if (data) {
639     cras_alert_pending_data_value = malloc(data_size);
640     memcpy(cras_alert_pending_data_value, data, data_size);
641   }
642   else
643     cras_alert_pending_data_value = NULL;
644 }
645 
cras_iodev_list_update_device_list()646 void cras_iodev_list_update_device_list() {
647   cras_iodev_list_update_device_list_called++;
648 }
649 
650 }  // extern "C"
651 
652 }  // namespace
653 
main(int argc,char ** argv)654 int main(int argc, char **argv) {
655   ::testing::InitGoogleTest(&argc, argv);
656   openlog(NULL, LOG_PERROR, LOG_USER);
657   return RUN_ALL_TESTS();
658 }
659