Home | History | Annotate | Download | only in tests
      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 
     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. */
    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. */
    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. */
    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. */
    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. */
    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. */
    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. */
    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. */
    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. */
    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. */
    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:
    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 
    249   virtual void TearDown() {
    250     cras_observer_server_free();
    251     EXPECT_EQ(15, cras_alert_destroy_called);
    252     ResetStubData();
    253   }
    254 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    606 void cras_alert_destroy(struct cras_alert *alert) {
    607   cras_alert_destroy_called++;
    608 }
    609 
    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 
    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 
    628 void cras_alert_pending(struct cras_alert *alert) {
    629   cras_alert_pending_alert_value = alert;
    630 }
    631 
    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 
    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 
    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