Home | History | Annotate | Download | only in tests
      1 /* Copyright 2013 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 
      6 #include <gtest/gtest.h>
      7 #include <stdint.h>
      8 #include <time.h>
      9 
     10 extern "C" {
     11   #include "cras_hfp_info.c"
     12 }
     13 
     14 static struct hfp_info *info;
     15 static struct cras_iodev dev;
     16 static cras_audio_format format;
     17 
     18 static thread_callback thread_cb;
     19 static void *cb_data;
     20 static timespec ts;
     21 
     22 void ResetStubData() {
     23   format.format = SND_PCM_FORMAT_S16_LE;
     24   format.num_channels = 1;
     25   format.frame_rate = 8000;
     26   dev.format = &format;
     27 }
     28 
     29 namespace {
     30 
     31 TEST(HfpInfo, AddRmDev) {
     32   info = hfp_info_create();
     33   ASSERT_NE(info, (void *)NULL);
     34   dev.direction = CRAS_STREAM_OUTPUT;
     35 
     36   /* Test add dev */
     37   ASSERT_EQ(0, hfp_info_add_iodev(info, &dev));
     38   ASSERT_TRUE(hfp_info_has_iodev(info));
     39 
     40   /* Test remove dev */
     41   ASSERT_EQ(0, hfp_info_rm_iodev(info, &dev));
     42   ASSERT_FALSE(hfp_info_has_iodev(info));
     43 
     44   hfp_info_destroy(info);
     45 }
     46 
     47 TEST(HfpInfo, AddRmDevInvalid) {
     48   info = hfp_info_create();
     49   ASSERT_NE(info, (void *)NULL);
     50 
     51   dev.direction = CRAS_STREAM_OUTPUT;
     52 
     53   /* Remove an iodev which doesn't exist */
     54   ASSERT_NE(0, hfp_info_rm_iodev(info, &dev));
     55 
     56   /* Adding an iodev twice returns error code */
     57   ASSERT_EQ(0, hfp_info_add_iodev(info, &dev));
     58   ASSERT_NE(0, hfp_info_add_iodev(info, &dev));
     59 
     60   hfp_info_destroy(info);
     61 }
     62 
     63 TEST(HfpInfo, AcquirePlaybackBuffer) {
     64   unsigned buffer_frames, buffer_frames2, queued;
     65   uint8_t *samples;
     66 
     67   ResetStubData();
     68 
     69   info = hfp_info_create();
     70   ASSERT_NE(info, (void *)NULL);
     71 
     72   hfp_info_start(1, 48, info);
     73   dev.direction = CRAS_STREAM_OUTPUT;
     74   ASSERT_EQ(0, hfp_info_add_iodev(info, &dev));
     75 
     76   buffer_frames = 500;
     77   hfp_buf_acquire(info, &dev, &samples, &buffer_frames);
     78   ASSERT_EQ(500, buffer_frames);
     79 
     80   hfp_buf_release(info, &dev, 500);
     81   ASSERT_EQ(500, hfp_buf_queued(info, &dev));
     82 
     83   /* Assert the amount of frames of available buffer + queued buf is
     84    * greater than or equal to the buffer size, 2 bytes per frame
     85    */
     86   queued = hfp_buf_queued(info, &dev);
     87   buffer_frames = 500;
     88   hfp_buf_acquire(info, &dev, &samples, &buffer_frames);
     89   ASSERT_GE(info->playback_buf->used_size / 2, buffer_frames + queued);
     90 
     91   /* Consume all queued data from read buffer */
     92   buf_increment_read(info->playback_buf, queued * 2);
     93 
     94   queued = hfp_buf_queued(info, &dev);
     95   ASSERT_EQ(0, queued);
     96 
     97   /* Assert consecutive acquire buffer will acquire full used size of buffer */
     98   buffer_frames = 500;
     99   hfp_buf_acquire(info, &dev, &samples, &buffer_frames);
    100   hfp_buf_release(info, &dev, buffer_frames);
    101 
    102   buffer_frames2 = 500;
    103   hfp_buf_acquire(info, &dev, &samples, &buffer_frames2);
    104   hfp_buf_release(info, &dev, buffer_frames2);
    105 
    106   ASSERT_GE(info->playback_buf->used_size / 2, buffer_frames + buffer_frames2);
    107 
    108   hfp_info_destroy(info);
    109 }
    110 
    111 TEST(HfpInfo, AcquireCaptureBuffer) {
    112   unsigned buffer_frames, buffer_frames2;
    113   uint8_t *samples;
    114 
    115   ResetStubData();
    116 
    117   info = hfp_info_create();
    118   ASSERT_NE(info, (void *)NULL);
    119 
    120   hfp_info_start(1, 48, info);
    121   dev.direction = CRAS_STREAM_INPUT;
    122   ASSERT_EQ(0, hfp_info_add_iodev(info, &dev));
    123 
    124   /* Put fake data 100 bytes(50 frames) in capture buf for test */
    125   buf_increment_write(info->capture_buf, 100);
    126 
    127   /* Assert successfully acquire and release 100 bytes of data */
    128   buffer_frames = 50;
    129   hfp_buf_acquire(info, &dev, &samples, &buffer_frames);
    130   ASSERT_EQ(50, buffer_frames);
    131 
    132   hfp_buf_release(info, &dev, buffer_frames);
    133   ASSERT_EQ(0, hfp_buf_queued(info, &dev));
    134 
    135   /* Push fake data to capture buffer */
    136   buf_increment_write(info->capture_buf, info->capture_buf->used_size - 100);
    137   buf_increment_write(info->capture_buf, 100);
    138 
    139   /* Assert consecutive acquire call will consume the whole buffer */
    140   buffer_frames = 1000;
    141   hfp_buf_acquire(info, &dev, &samples, &buffer_frames);
    142   hfp_buf_release(info, &dev, buffer_frames);
    143   ASSERT_GE(1000, buffer_frames);
    144 
    145   buffer_frames2 = 1000;
    146   hfp_buf_acquire(info, &dev, &samples, &buffer_frames2);
    147   hfp_buf_release(info, &dev, buffer_frames2);
    148 
    149   ASSERT_GE(info->capture_buf->used_size / 2, buffer_frames + buffer_frames2);
    150 
    151   hfp_info_destroy(info);
    152 }
    153 
    154 TEST(HfpInfo, HfpReadWriteFD) {
    155   int rc;
    156   int sock[2];
    157   uint8_t sample[480];
    158   uint8_t *buf;
    159   unsigned buffer_count;
    160 
    161   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
    162 
    163   info = hfp_info_create();
    164   ASSERT_NE(info, (void *)NULL);
    165 
    166   dev.direction = CRAS_STREAM_INPUT;
    167   hfp_info_start(sock[1], 48, info);
    168   ASSERT_EQ(0, hfp_info_add_iodev(info, &dev));
    169 
    170   /* Mock the sco fd and send some fake data */
    171   send(sock[0], sample, 48, 0);
    172 
    173   rc = hfp_read(info);
    174   ASSERT_EQ(48, rc);
    175 
    176   rc = hfp_buf_queued(info, &dev);
    177   ASSERT_EQ(48 / 2, rc);
    178 
    179   /* Fill the write buffer*/
    180   buffer_count = info->capture_buf->used_size;
    181   buf = buf_write_pointer_size(info->capture_buf, &buffer_count);
    182   buf_increment_write(info->capture_buf, buffer_count);
    183   ASSERT_NE((void *)NULL, buf);
    184 
    185   rc = hfp_read(info);
    186   ASSERT_EQ(0, rc);
    187 
    188   ASSERT_EQ(0, hfp_info_rm_iodev(info, &dev));
    189   dev.direction = CRAS_STREAM_OUTPUT;
    190   ASSERT_EQ(0, hfp_info_add_iodev(info, &dev));
    191 
    192   /* Initial buffer is empty */
    193   rc = hfp_write(info);
    194   ASSERT_EQ(0, rc);
    195 
    196   buffer_count = 1024;
    197   buf = buf_write_pointer_size(info->playback_buf, &buffer_count);
    198   buf_increment_write(info->playback_buf, buffer_count);
    199 
    200   rc = hfp_write(info);
    201   ASSERT_EQ(48, rc);
    202 
    203   rc = recv(sock[0], sample, 48, 0);
    204   ASSERT_EQ(48, rc);
    205 
    206   hfp_info_destroy(info);
    207 }
    208 
    209 TEST(HfpInfo, StartHfpInfo) {
    210   int sock[2];
    211 
    212   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
    213 
    214   info = hfp_info_create();
    215   ASSERT_NE(info, (void *)NULL);
    216 
    217   hfp_info_start(sock[0], 48, info);
    218   ASSERT_EQ(1, hfp_info_running(info));
    219   ASSERT_EQ(cb_data, (void *)info);
    220 
    221   hfp_info_stop(info);
    222   ASSERT_EQ(0, hfp_info_running(info));
    223   ASSERT_EQ(NULL, cb_data);
    224 
    225   hfp_info_destroy(info);
    226 }
    227 
    228 TEST(HfpInfo, StartHfpInfoAndRead) {
    229   int rc;
    230   int sock[2];
    231   uint8_t sample[480];
    232 
    233   ResetStubData();
    234 
    235   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
    236 
    237   info = hfp_info_create();
    238   ASSERT_NE(info, (void *)NULL);
    239 
    240   /* Start and send two chunk of fake data */
    241   hfp_info_start(sock[1], 48, info);
    242   send(sock[0], sample ,48, 0);
    243   send(sock[0], sample ,48, 0);
    244 
    245   /* Trigger thread callback */
    246   thread_cb((struct hfp_info *)cb_data);
    247 
    248   dev.direction = CRAS_STREAM_INPUT;
    249   ASSERT_EQ(0, hfp_info_add_iodev(info, &dev));
    250 
    251   /* Expect no data read, since no idev present at previous thread callback */
    252   rc = hfp_buf_queued(info, &dev);
    253   ASSERT_EQ(0, rc);
    254 
    255   /* Trigger thread callback after idev added. */
    256   ts.tv_sec = 0;
    257   ts.tv_nsec = 5000000;
    258   thread_cb((struct hfp_info *)cb_data);
    259 
    260   rc = hfp_buf_queued(info, &dev);
    261   ASSERT_EQ(48 / 2, rc);
    262 
    263   /* Assert wait time is unchanged. */
    264   ASSERT_EQ(0, ts.tv_sec);
    265   ASSERT_EQ(5000000, ts.tv_nsec);
    266 
    267   hfp_info_stop(info);
    268   ASSERT_EQ(0, hfp_info_running(info));
    269 
    270   hfp_info_destroy(info);
    271 }
    272 
    273 TEST(HfpInfo, StartHfpInfoAndWrite) {
    274   int rc;
    275   int sock[2];
    276   uint8_t sample[480];
    277 
    278   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
    279 
    280   info = hfp_info_create();
    281   ASSERT_NE(info, (void *)NULL);
    282 
    283   hfp_info_start(sock[1], 48, info);
    284   send(sock[0], sample ,48, 0);
    285   send(sock[0], sample ,48, 0);
    286 
    287   /* Trigger thread callback */
    288   thread_cb((struct hfp_info *)cb_data);
    289 
    290   dev.direction = CRAS_STREAM_OUTPUT;
    291   ASSERT_EQ(0, hfp_info_add_iodev(info, &dev));
    292 
    293   /* Assert queued samples unchanged before output device added */
    294   ASSERT_EQ(0, hfp_buf_queued(info, &dev));
    295 
    296   /* Put some fake data and trigger thread callback again */
    297   buf_increment_write(info->playback_buf, 1008);
    298   thread_cb((struct hfp_info *)cb_data);
    299 
    300   /* Assert some samples written */
    301   rc = recv(sock[0], sample ,48, 0);
    302   ASSERT_EQ(48, rc);
    303   ASSERT_EQ(480, hfp_buf_queued(info, &dev));
    304 
    305   hfp_info_stop(info);
    306   hfp_info_destroy(info);
    307 }
    308 
    309 } // namespace
    310 
    311 extern "C" {
    312 
    313 struct audio_thread *cras_iodev_list_get_audio_thread()
    314 {
    315   return NULL;
    316 }
    317 
    318 void audio_thread_add_callback(int fd, thread_callback cb,
    319                                void *data)
    320 {
    321   thread_cb = cb;
    322   cb_data = data;
    323   return;
    324 }
    325 
    326 int audio_thread_rm_callback_sync(struct audio_thread *thread, int fd)
    327 {
    328   thread_cb = NULL;
    329   cb_data = NULL;
    330   return 0;
    331 }
    332 }
    333 
    334 int main(int argc, char **argv) {
    335   ::testing::InitGoogleTest(&argc, argv);
    336   return RUN_ALL_TESTS();
    337 }
    338