Home | History | Annotate | Download | only in android
      1 // Copyright 2013 The Chromium 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 "base/android/build_info.h"
      6 #include "base/basictypes.h"
      7 #include "base/file_util.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/path_service.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "base/synchronization/lock.h"
     13 #include "base/synchronization/waitable_event.h"
     14 #include "base/test/test_timeouts.h"
     15 #include "base/time/time.h"
     16 #include "build/build_config.h"
     17 #include "media/audio/android/audio_manager_android.h"
     18 #include "media/audio/audio_io.h"
     19 #include "media/audio/audio_manager_base.h"
     20 #include "media/base/decoder_buffer.h"
     21 #include "media/base/seekable_buffer.h"
     22 #include "media/base/test_data_util.h"
     23 #include "testing/gmock/include/gmock/gmock.h"
     24 #include "testing/gtest/include/gtest/gtest.h"
     25 
     26 using ::testing::_;
     27 using ::testing::AtLeast;
     28 using ::testing::DoAll;
     29 using ::testing::Invoke;
     30 using ::testing::NotNull;
     31 using ::testing::Return;
     32 
     33 namespace media {
     34 
     35 ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop) {
     36   if (++*count >= limit) {
     37     loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
     38   }
     39 }
     40 
     41 static const char kSpeechFile_16b_s_48k[] = "speech_16b_stereo_48kHz.raw";
     42 static const char kSpeechFile_16b_m_48k[] = "speech_16b_mono_48kHz.raw";
     43 static const char kSpeechFile_16b_s_44k[] = "speech_16b_stereo_44kHz.raw";
     44 static const char kSpeechFile_16b_m_44k[] = "speech_16b_mono_44kHz.raw";
     45 
     46 static const float kCallbackTestTimeMs = 2000.0;
     47 static const int kBitsPerSample = 16;
     48 static const int kBytesPerSample = kBitsPerSample / 8;
     49 
     50 // Converts AudioParameters::Format enumerator to readable string.
     51 static std::string FormatToString(AudioParameters::Format format) {
     52   switch (format) {
     53     case AudioParameters::AUDIO_PCM_LINEAR:
     54       return std::string("AUDIO_PCM_LINEAR");
     55     case AudioParameters::AUDIO_PCM_LOW_LATENCY:
     56       return std::string("AUDIO_PCM_LOW_LATENCY");
     57     case AudioParameters::AUDIO_FAKE:
     58       return std::string("AUDIO_FAKE");
     59     case AudioParameters::AUDIO_LAST_FORMAT:
     60       return std::string("AUDIO_LAST_FORMAT");
     61     default:
     62       return std::string();
     63   }
     64 }
     65 
     66 // Converts ChannelLayout enumerator to readable string. Does not include
     67 // multi-channel cases since these layouts are not supported on Android.
     68 static std::string LayoutToString(ChannelLayout channel_layout) {
     69   switch (channel_layout) {
     70     case CHANNEL_LAYOUT_NONE:
     71       return std::string("CHANNEL_LAYOUT_NONE");
     72     case CHANNEL_LAYOUT_MONO:
     73       return std::string("CHANNEL_LAYOUT_MONO");
     74     case CHANNEL_LAYOUT_STEREO:
     75       return std::string("CHANNEL_LAYOUT_STEREO");
     76     case CHANNEL_LAYOUT_UNSUPPORTED:
     77     default:
     78       return std::string("CHANNEL_LAYOUT_UNSUPPORTED");
     79   }
     80 }
     81 
     82 static double ExpectedTimeBetweenCallbacks(AudioParameters params) {
     83   return (base::TimeDelta::FromMicroseconds(
     84               params.frames_per_buffer() * base::Time::kMicrosecondsPerSecond /
     85               static_cast<double>(params.sample_rate()))).InMillisecondsF();
     86 }
     87 
     88 std::ostream& operator<<(std::ostream& os, const AudioParameters& params) {
     89   using namespace std;
     90   os << endl << "format: " << FormatToString(params.format()) << endl
     91      << "channel layout: " << LayoutToString(params.channel_layout()) << endl
     92      << "sample rate: " << params.sample_rate() << endl
     93      << "bits per sample: " << params.bits_per_sample() << endl
     94      << "frames per buffer: " << params.frames_per_buffer() << endl
     95      << "channels: " << params.channels() << endl
     96      << "bytes per buffer: " << params.GetBytesPerBuffer() << endl
     97      << "bytes per second: " << params.GetBytesPerSecond() << endl
     98      << "bytes per frame: " << params.GetBytesPerFrame() << endl
     99      << "chunk size in ms: " << ExpectedTimeBetweenCallbacks(params) << endl
    100      << "echo_canceller: "
    101      << (params.effects() & AudioParameters::ECHO_CANCELLER);
    102   return os;
    103 }
    104 
    105 // Gmock implementation of AudioInputStream::AudioInputCallback.
    106 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
    107  public:
    108   MOCK_METHOD5(OnData,
    109                void(AudioInputStream* stream,
    110                     const uint8* src,
    111                     uint32 size,
    112                     uint32 hardware_delay_bytes,
    113                     double volume));
    114   MOCK_METHOD1(OnClose, void(AudioInputStream* stream));
    115   MOCK_METHOD1(OnError, void(AudioInputStream* stream));
    116 };
    117 
    118 // Gmock implementation of AudioOutputStream::AudioSourceCallback.
    119 class MockAudioOutputCallback : public AudioOutputStream::AudioSourceCallback {
    120  public:
    121   MOCK_METHOD2(OnMoreData,
    122                int(AudioBus* dest, AudioBuffersState buffers_state));
    123   MOCK_METHOD3(OnMoreIOData,
    124                int(AudioBus* source,
    125                    AudioBus* dest,
    126                    AudioBuffersState buffers_state));
    127   MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
    128 
    129   // We clear the data bus to ensure that the test does not cause noise.
    130   int RealOnMoreData(AudioBus* dest, AudioBuffersState buffers_state) {
    131     dest->Zero();
    132     return dest->frames();
    133   }
    134 };
    135 
    136 // Implements AudioOutputStream::AudioSourceCallback and provides audio data
    137 // by reading from a data file.
    138 class FileAudioSource : public AudioOutputStream::AudioSourceCallback {
    139  public:
    140   explicit FileAudioSource(base::WaitableEvent* event, const std::string& name)
    141       : event_(event), pos_(0) {
    142     // Reads a test file from media/test/data directory and stores it in
    143     // a DecoderBuffer.
    144     file_ = ReadTestDataFile(name);
    145 
    146     // Log the name of the file which is used as input for this test.
    147     base::FilePath file_path = GetTestDataFilePath(name);
    148     VLOG(0) << "Reading from file: " << file_path.value().c_str();
    149   }
    150 
    151   virtual ~FileAudioSource() {}
    152 
    153   // AudioOutputStream::AudioSourceCallback implementation.
    154 
    155   // Use samples read from a data file and fill up the audio buffer
    156   // provided to us in the callback.
    157   virtual int OnMoreData(AudioBus* audio_bus,
    158                          AudioBuffersState buffers_state) OVERRIDE {
    159     bool stop_playing = false;
    160     int max_size =
    161         audio_bus->frames() * audio_bus->channels() * kBytesPerSample;
    162 
    163     // Adjust data size and prepare for end signal if file has ended.
    164     if (pos_ + max_size > file_size()) {
    165       stop_playing = true;
    166       max_size = file_size() - pos_;
    167     }
    168 
    169     // File data is stored as interleaved 16-bit values. Copy data samples from
    170     // the file and deinterleave to match the audio bus format.
    171     // FromInterleaved() will zero out any unfilled frames when there is not
    172     // sufficient data remaining in the file to fill up the complete frame.
    173     int frames = max_size / (audio_bus->channels() * kBytesPerSample);
    174     if (max_size) {
    175       audio_bus->FromInterleaved(file_->data() + pos_, frames, kBytesPerSample);
    176       pos_ += max_size;
    177     }
    178 
    179     // Set event to ensure that the test can stop when the file has ended.
    180     if (stop_playing)
    181       event_->Signal();
    182 
    183     return frames;
    184   }
    185 
    186   virtual int OnMoreIOData(AudioBus* source,
    187                            AudioBus* dest,
    188                            AudioBuffersState buffers_state) OVERRIDE {
    189     NOTREACHED();
    190     return 0;
    191   }
    192 
    193   virtual void OnError(AudioOutputStream* stream) OVERRIDE {}
    194 
    195   int file_size() { return file_->data_size(); }
    196 
    197  private:
    198   base::WaitableEvent* event_;
    199   int pos_;
    200   scoped_refptr<DecoderBuffer> file_;
    201 
    202   DISALLOW_COPY_AND_ASSIGN(FileAudioSource);
    203 };
    204 
    205 // Implements AudioInputStream::AudioInputCallback and writes the recorded
    206 // audio data to a local output file. Note that this implementation should
    207 // only be used for manually invoked and evaluated tests, hence the created
    208 // file will not be destroyed after the test is done since the intention is
    209 // that it shall be available for off-line analysis.
    210 class FileAudioSink : public AudioInputStream::AudioInputCallback {
    211  public:
    212   explicit FileAudioSink(base::WaitableEvent* event,
    213                          const AudioParameters& params,
    214                          const std::string& file_name)
    215       : event_(event), params_(params) {
    216     // Allocate space for ~10 seconds of data.
    217     const int kMaxBufferSize = 10 * params.GetBytesPerSecond();
    218     buffer_.reset(new media::SeekableBuffer(0, kMaxBufferSize));
    219 
    220     // Open up the binary file which will be written to in the destructor.
    221     base::FilePath file_path;
    222     EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
    223     file_path = file_path.AppendASCII(file_name.c_str());
    224     binary_file_ = base::OpenFile(file_path, "wb");
    225     DLOG_IF(ERROR, !binary_file_) << "Failed to open binary PCM data file.";
    226     VLOG(0) << "Writing to file: " << file_path.value().c_str();
    227   }
    228 
    229   virtual ~FileAudioSink() {
    230     int bytes_written = 0;
    231     while (bytes_written < buffer_->forward_capacity()) {
    232       const uint8* chunk;
    233       int chunk_size;
    234 
    235       // Stop writing if no more data is available.
    236       if (!buffer_->GetCurrentChunk(&chunk, &chunk_size))
    237         break;
    238 
    239       // Write recorded data chunk to the file and prepare for next chunk.
    240       // TODO(henrika): use file_util:: instead.
    241       fwrite(chunk, 1, chunk_size, binary_file_);
    242       buffer_->Seek(chunk_size);
    243       bytes_written += chunk_size;
    244     }
    245     base::CloseFile(binary_file_);
    246   }
    247 
    248   // AudioInputStream::AudioInputCallback implementation.
    249   virtual void OnData(AudioInputStream* stream,
    250                       const uint8* src,
    251                       uint32 size,
    252                       uint32 hardware_delay_bytes,
    253                       double volume) OVERRIDE {
    254     // Store data data in a temporary buffer to avoid making blocking
    255     // fwrite() calls in the audio callback. The complete buffer will be
    256     // written to file in the destructor.
    257     if (!buffer_->Append(src, size))
    258       event_->Signal();
    259   }
    260 
    261   virtual void OnClose(AudioInputStream* stream) OVERRIDE {}
    262   virtual void OnError(AudioInputStream* stream) OVERRIDE {}
    263 
    264  private:
    265   base::WaitableEvent* event_;
    266   AudioParameters params_;
    267   scoped_ptr<media::SeekableBuffer> buffer_;
    268   FILE* binary_file_;
    269 
    270   DISALLOW_COPY_AND_ASSIGN(FileAudioSink);
    271 };
    272 
    273 // Implements AudioInputCallback and AudioSourceCallback to support full
    274 // duplex audio where captured samples are played out in loopback after
    275 // reading from a temporary FIFO storage.
    276 class FullDuplexAudioSinkSource
    277     : public AudioInputStream::AudioInputCallback,
    278       public AudioOutputStream::AudioSourceCallback {
    279  public:
    280   explicit FullDuplexAudioSinkSource(const AudioParameters& params)
    281       : params_(params),
    282         previous_time_(base::TimeTicks::Now()),
    283         started_(false) {
    284     // Start with a reasonably small FIFO size. It will be increased
    285     // dynamically during the test if required.
    286     fifo_.reset(new media::SeekableBuffer(0, 2 * params.GetBytesPerBuffer()));
    287     buffer_.reset(new uint8[params_.GetBytesPerBuffer()]);
    288   }
    289 
    290   virtual ~FullDuplexAudioSinkSource() {}
    291 
    292   // AudioInputStream::AudioInputCallback implementation
    293   virtual void OnData(AudioInputStream* stream,
    294                       const uint8* src,
    295                       uint32 size,
    296                       uint32 hardware_delay_bytes,
    297                       double volume) OVERRIDE {
    298     const base::TimeTicks now_time = base::TimeTicks::Now();
    299     const int diff = (now_time - previous_time_).InMilliseconds();
    300 
    301     base::AutoLock lock(lock_);
    302     if (diff > 1000) {
    303       started_ = true;
    304       previous_time_ = now_time;
    305 
    306       // Log out the extra delay added by the FIFO. This is a best effort
    307       // estimate. We might be +- 10ms off here.
    308       int extra_fifo_delay =
    309           static_cast<int>(BytesToMilliseconds(fifo_->forward_bytes() + size));
    310       DVLOG(1) << extra_fifo_delay;
    311     }
    312 
    313     // We add an initial delay of ~1 second before loopback starts to ensure
    314     // a stable callback sequence and to avoid initial bursts which might add
    315     // to the extra FIFO delay.
    316     if (!started_)
    317       return;
    318 
    319     // Append new data to the FIFO and extend the size if the max capacity
    320     // was exceeded. Flush the FIFO when extended just in case.
    321     if (!fifo_->Append(src, size)) {
    322       fifo_->set_forward_capacity(2 * fifo_->forward_capacity());
    323       fifo_->Clear();
    324     }
    325   }
    326 
    327   virtual void OnClose(AudioInputStream* stream) OVERRIDE {}
    328   virtual void OnError(AudioInputStream* stream) OVERRIDE {}
    329 
    330   // AudioOutputStream::AudioSourceCallback implementation
    331   virtual int OnMoreData(AudioBus* dest,
    332                          AudioBuffersState buffers_state) OVERRIDE {
    333     const int size_in_bytes =
    334         (params_.bits_per_sample() / 8) * dest->frames() * dest->channels();
    335     EXPECT_EQ(size_in_bytes, params_.GetBytesPerBuffer());
    336 
    337     base::AutoLock lock(lock_);
    338 
    339     // We add an initial delay of ~1 second before loopback starts to ensure
    340     // a stable callback sequences and to avoid initial bursts which might add
    341     // to the extra FIFO delay.
    342     if (!started_) {
    343       dest->Zero();
    344       return dest->frames();
    345     }
    346 
    347     // Fill up destination with zeros if the FIFO does not contain enough
    348     // data to fulfill the request.
    349     if (fifo_->forward_bytes() < size_in_bytes) {
    350       dest->Zero();
    351     } else {
    352       fifo_->Read(buffer_.get(), size_in_bytes);
    353       dest->FromInterleaved(
    354           buffer_.get(), dest->frames(), params_.bits_per_sample() / 8);
    355     }
    356 
    357     return dest->frames();
    358   }
    359 
    360   virtual int OnMoreIOData(AudioBus* source,
    361                            AudioBus* dest,
    362                            AudioBuffersState buffers_state) OVERRIDE {
    363     NOTREACHED();
    364     return 0;
    365   }
    366 
    367   virtual void OnError(AudioOutputStream* stream) OVERRIDE {}
    368 
    369  private:
    370   // Converts from bytes to milliseconds given number of bytes and existing
    371   // audio parameters.
    372   double BytesToMilliseconds(int bytes) const {
    373     const int frames = bytes / params_.GetBytesPerFrame();
    374     return (base::TimeDelta::FromMicroseconds(
    375                 frames * base::Time::kMicrosecondsPerSecond /
    376                 static_cast<double>(params_.sample_rate()))).InMillisecondsF();
    377   }
    378 
    379   AudioParameters params_;
    380   base::TimeTicks previous_time_;
    381   base::Lock lock_;
    382   scoped_ptr<media::SeekableBuffer> fifo_;
    383   scoped_ptr<uint8[]> buffer_;
    384   bool started_;
    385 
    386   DISALLOW_COPY_AND_ASSIGN(FullDuplexAudioSinkSource);
    387 };
    388 
    389 // Test fixture class for tests which only exercise the output path.
    390 class AudioAndroidOutputTest : public testing::Test {
    391  public:
    392   AudioAndroidOutputTest() {}
    393 
    394  protected:
    395   virtual void SetUp() {
    396     audio_manager_.reset(AudioManager::CreateForTesting());
    397     loop_.reset(new base::MessageLoopForUI());
    398   }
    399 
    400   virtual void TearDown() {}
    401 
    402   AudioManager* audio_manager() { return audio_manager_.get(); }
    403   base::MessageLoopForUI* loop() { return loop_.get(); }
    404 
    405   AudioParameters GetDefaultOutputStreamParameters() {
    406     return audio_manager()->GetDefaultOutputStreamParameters();
    407   }
    408 
    409   double AverageTimeBetweenCallbacks(int num_callbacks) const {
    410     return ((end_time_ - start_time_) / static_cast<double>(num_callbacks - 1))
    411         .InMillisecondsF();
    412   }
    413 
    414   void StartOutputStreamCallbacks(const AudioParameters& params) {
    415     double expected_time_between_callbacks_ms =
    416         ExpectedTimeBetweenCallbacks(params);
    417     const int num_callbacks =
    418         (kCallbackTestTimeMs / expected_time_between_callbacks_ms);
    419     AudioOutputStream* stream = audio_manager()->MakeAudioOutputStream(
    420         params, std::string(), std::string());
    421     EXPECT_TRUE(stream);
    422 
    423     int count = 0;
    424     MockAudioOutputCallback source;
    425 
    426     EXPECT_CALL(source, OnMoreData(NotNull(), _))
    427         .Times(AtLeast(num_callbacks))
    428         .WillRepeatedly(
    429              DoAll(CheckCountAndPostQuitTask(&count, num_callbacks, loop()),
    430                    Invoke(&source, &MockAudioOutputCallback::RealOnMoreData)));
    431     EXPECT_CALL(source, OnError(stream)).Times(0);
    432     EXPECT_CALL(source, OnMoreIOData(_, _, _)).Times(0);
    433 
    434     EXPECT_TRUE(stream->Open());
    435     stream->Start(&source);
    436     start_time_ = base::TimeTicks::Now();
    437     loop()->Run();
    438     end_time_ = base::TimeTicks::Now();
    439     stream->Stop();
    440     stream->Close();
    441 
    442     double average_time_between_callbacks_ms =
    443         AverageTimeBetweenCallbacks(num_callbacks);
    444     VLOG(0) << "expected time between callbacks: "
    445             << expected_time_between_callbacks_ms << " ms";
    446     VLOG(0) << "average time between callbacks: "
    447             << average_time_between_callbacks_ms << " ms";
    448     EXPECT_GE(average_time_between_callbacks_ms,
    449               0.70 * expected_time_between_callbacks_ms);
    450     EXPECT_LE(average_time_between_callbacks_ms,
    451               1.30 * expected_time_between_callbacks_ms);
    452   }
    453 
    454   scoped_ptr<base::MessageLoopForUI> loop_;
    455   scoped_ptr<AudioManager> audio_manager_;
    456   base::TimeTicks start_time_;
    457   base::TimeTicks end_time_;
    458 
    459  private:
    460   DISALLOW_COPY_AND_ASSIGN(AudioAndroidOutputTest);
    461 };
    462 
    463 // AudioRecordInputStream should only be created on Jelly Bean and higher. This
    464 // ensures we only test against the AudioRecord path when that is satisfied.
    465 std::vector<bool> RunAudioRecordInputPathTests() {
    466   std::vector<bool> tests;
    467   tests.push_back(false);
    468   if (base::android::BuildInfo::GetInstance()->sdk_int() >= 16)
    469     tests.push_back(true);
    470   return tests;
    471 }
    472 
    473 // Test fixture class for tests which exercise the input path, or both input and
    474 // output paths. It is value-parameterized to test against both the Java
    475 // AudioRecord (when true) and native OpenSLES (when false) input paths.
    476 class AudioAndroidInputTest : public AudioAndroidOutputTest,
    477                               public testing::WithParamInterface<bool> {
    478  public:
    479   AudioAndroidInputTest() {}
    480 
    481  protected:
    482   AudioParameters GetInputStreamParameters() {
    483     AudioParameters input_params = audio_manager()->GetInputStreamParameters(
    484         AudioManagerBase::kDefaultDeviceId);
    485     // Override the platform effects setting to use the AudioRecord or OpenSLES
    486     // path as requested.
    487     int effects = GetParam() ? AudioParameters::ECHO_CANCELLER :
    488                                AudioParameters::NO_EFFECTS;
    489     AudioParameters params(input_params.format(),
    490                            input_params.channel_layout(),
    491                            input_params.input_channels(),
    492                            input_params.sample_rate(),
    493                            input_params.bits_per_sample(),
    494                            input_params.frames_per_buffer(),
    495                            effects);
    496     return params;
    497   }
    498 
    499   void StartInputStreamCallbacks(const AudioParameters& params) {
    500     double expected_time_between_callbacks_ms =
    501         ExpectedTimeBetweenCallbacks(params);
    502     const int num_callbacks =
    503         (kCallbackTestTimeMs / expected_time_between_callbacks_ms);
    504     AudioInputStream* stream = audio_manager()->MakeAudioInputStream(
    505         params, AudioManagerBase::kDefaultDeviceId);
    506     EXPECT_TRUE(stream);
    507 
    508     int count = 0;
    509     MockAudioInputCallback sink;
    510 
    511     EXPECT_CALL(sink,
    512                 OnData(stream, NotNull(), params.GetBytesPerBuffer(), _, _))
    513         .Times(AtLeast(num_callbacks))
    514         .WillRepeatedly(
    515              CheckCountAndPostQuitTask(&count, num_callbacks, loop()));
    516     EXPECT_CALL(sink, OnError(stream)).Times(0);
    517     EXPECT_CALL(sink, OnClose(stream)).Times(1);
    518 
    519     EXPECT_TRUE(stream->Open());
    520     stream->Start(&sink);
    521     start_time_ = base::TimeTicks::Now();
    522     loop()->Run();
    523     end_time_ = base::TimeTicks::Now();
    524     stream->Stop();
    525     stream->Close();
    526 
    527     double average_time_between_callbacks_ms =
    528         AverageTimeBetweenCallbacks(num_callbacks);
    529     VLOG(0) << "expected time between callbacks: "
    530             << expected_time_between_callbacks_ms << " ms";
    531     VLOG(0) << "average time between callbacks: "
    532             << average_time_between_callbacks_ms << " ms";
    533     EXPECT_GE(average_time_between_callbacks_ms,
    534               0.70 * expected_time_between_callbacks_ms);
    535     EXPECT_LE(average_time_between_callbacks_ms,
    536               1.30 * expected_time_between_callbacks_ms);
    537   }
    538 
    539 
    540  private:
    541   DISALLOW_COPY_AND_ASSIGN(AudioAndroidInputTest);
    542 };
    543 
    544 // Get the default audio input parameters and log the result.
    545 TEST_P(AudioAndroidInputTest, GetDefaultInputStreamParameters) {
    546   // We don't go through AudioAndroidInputTest::GetInputStreamParameters() here
    547   // so that we can log the real (non-overridden) values of the effects.
    548   AudioParameters params = audio_manager()->GetInputStreamParameters(
    549       AudioManagerBase::kDefaultDeviceId);
    550   EXPECT_TRUE(params.IsValid());
    551   VLOG(1) << params;
    552 }
    553 
    554 // Get the default audio output parameters and log the result.
    555 TEST_F(AudioAndroidOutputTest, GetDefaultOutputStreamParameters) {
    556   AudioParameters params = GetDefaultOutputStreamParameters();
    557   EXPECT_TRUE(params.IsValid());
    558   VLOG(1) << params;
    559 }
    560 
    561 // Check if low-latency output is supported and log the result as output.
    562 TEST_F(AudioAndroidOutputTest, IsAudioLowLatencySupported) {
    563   AudioManagerAndroid* manager =
    564       static_cast<AudioManagerAndroid*>(audio_manager());
    565   bool low_latency = manager->IsAudioLowLatencySupported();
    566   low_latency ? VLOG(0) << "Low latency output is supported"
    567               : VLOG(0) << "Low latency output is *not* supported";
    568 }
    569 
    570 // Ensure that a default input stream can be created and closed.
    571 TEST_P(AudioAndroidInputTest, CreateAndCloseInputStream) {
    572   AudioParameters params = GetInputStreamParameters();
    573   AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
    574       params, AudioManagerBase::kDefaultDeviceId);
    575   EXPECT_TRUE(ais);
    576   ais->Close();
    577 }
    578 
    579 // Ensure that a default output stream can be created and closed.
    580 // TODO(henrika): should we also verify that this API changes the audio mode
    581 // to communication mode, and calls RegisterHeadsetReceiver, the first time
    582 // it is called?
    583 TEST_F(AudioAndroidOutputTest, CreateAndCloseOutputStream) {
    584   AudioParameters params = GetDefaultOutputStreamParameters();
    585   AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
    586       params, std::string(), std::string());
    587   EXPECT_TRUE(aos);
    588   aos->Close();
    589 }
    590 
    591 // Ensure that a default input stream can be opened and closed.
    592 TEST_P(AudioAndroidInputTest, OpenAndCloseInputStream) {
    593   AudioParameters params = GetInputStreamParameters();
    594   AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
    595       params, AudioManagerBase::kDefaultDeviceId);
    596   EXPECT_TRUE(ais);
    597   EXPECT_TRUE(ais->Open());
    598   ais->Close();
    599 }
    600 
    601 // Ensure that a default output stream can be opened and closed.
    602 TEST_F(AudioAndroidOutputTest, OpenAndCloseOutputStream) {
    603   AudioParameters params = GetDefaultOutputStreamParameters();
    604   AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
    605       params, std::string(), std::string());
    606   EXPECT_TRUE(aos);
    607   EXPECT_TRUE(aos->Open());
    608   aos->Close();
    609 }
    610 
    611 // Start input streaming using default input parameters and ensure that the
    612 // callback sequence is sane.
    613 TEST_P(AudioAndroidInputTest, StartInputStreamCallbacks) {
    614   AudioParameters params = GetInputStreamParameters();
    615   StartInputStreamCallbacks(params);
    616 }
    617 
    618 // Start input streaming using non default input parameters and ensure that the
    619 // callback sequence is sane. The only change we make in this test is to select
    620 // a 10ms buffer size instead of the default size.
    621 // TODO(henrika): possibly add support for more variations.
    622 TEST_P(AudioAndroidInputTest, StartInputStreamCallbacksNonDefaultParameters) {
    623   AudioParameters native_params = GetInputStreamParameters();
    624   AudioParameters params(native_params.format(),
    625                          native_params.channel_layout(),
    626                          native_params.input_channels(),
    627                          native_params.sample_rate(),
    628                          native_params.bits_per_sample(),
    629                          native_params.sample_rate() / 100,
    630                          native_params.effects());
    631   StartInputStreamCallbacks(params);
    632 }
    633 
    634 // Start output streaming using default output parameters and ensure that the
    635 // callback sequence is sane.
    636 TEST_F(AudioAndroidOutputTest, StartOutputStreamCallbacks) {
    637   AudioParameters params = GetDefaultOutputStreamParameters();
    638   StartOutputStreamCallbacks(params);
    639 }
    640 
    641 // Start output streaming using non default output parameters and ensure that
    642 // the callback sequence is sane. The only change we make in this test is to
    643 // select a 10ms buffer size instead of the default size and to open up the
    644 // device in mono.
    645 // TODO(henrika): possibly add support for more variations.
    646 TEST_F(AudioAndroidOutputTest, StartOutputStreamCallbacksNonDefaultParameters) {
    647   AudioParameters native_params = GetDefaultOutputStreamParameters();
    648   AudioParameters params(native_params.format(),
    649                          CHANNEL_LAYOUT_MONO,
    650                          native_params.sample_rate(),
    651                          native_params.bits_per_sample(),
    652                          native_params.sample_rate() / 100);
    653   StartOutputStreamCallbacks(params);
    654 }
    655 
    656 // Play out a PCM file segment in real time and allow the user to verify that
    657 // the rendered audio sounds OK.
    658 // NOTE: this test requires user interaction and is not designed to run as an
    659 // automatized test on bots.
    660 TEST_F(AudioAndroidOutputTest, DISABLED_RunOutputStreamWithFileAsSource) {
    661   AudioParameters params = GetDefaultOutputStreamParameters();
    662   VLOG(1) << params;
    663   AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
    664       params, std::string(), std::string());
    665   EXPECT_TRUE(aos);
    666 
    667   std::string file_name;
    668   if (params.sample_rate() == 48000 && params.channels() == 2) {
    669     file_name = kSpeechFile_16b_s_48k;
    670   } else if (params.sample_rate() == 48000 && params.channels() == 1) {
    671     file_name = kSpeechFile_16b_m_48k;
    672   } else if (params.sample_rate() == 44100 && params.channels() == 2) {
    673     file_name = kSpeechFile_16b_s_44k;
    674   } else if (params.sample_rate() == 44100 && params.channels() == 1) {
    675     file_name = kSpeechFile_16b_m_44k;
    676   } else {
    677     FAIL() << "This test supports 44.1kHz and 48kHz mono/stereo only.";
    678     return;
    679   }
    680 
    681   base::WaitableEvent event(false, false);
    682   FileAudioSource source(&event, file_name);
    683 
    684   EXPECT_TRUE(aos->Open());
    685   aos->SetVolume(1.0);
    686   aos->Start(&source);
    687   VLOG(0) << ">> Verify that the file is played out correctly...";
    688   EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
    689   aos->Stop();
    690   aos->Close();
    691 }
    692 
    693 // Start input streaming and run it for ten seconds while recording to a
    694 // local audio file.
    695 // NOTE: this test requires user interaction and is not designed to run as an
    696 // automatized test on bots.
    697 TEST_P(AudioAndroidInputTest, DISABLED_RunSimplexInputStreamWithFileAsSink) {
    698   AudioParameters params = GetInputStreamParameters();
    699   VLOG(1) << params;
    700   AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
    701       params, AudioManagerBase::kDefaultDeviceId);
    702   EXPECT_TRUE(ais);
    703 
    704   std::string file_name = base::StringPrintf("out_simplex_%d_%d_%d.pcm",
    705                                              params.sample_rate(),
    706                                              params.frames_per_buffer(),
    707                                              params.channels());
    708 
    709   base::WaitableEvent event(false, false);
    710   FileAudioSink sink(&event, params, file_name);
    711 
    712   EXPECT_TRUE(ais->Open());
    713   ais->Start(&sink);
    714   VLOG(0) << ">> Speak into the microphone to record audio...";
    715   EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
    716   ais->Stop();
    717   ais->Close();
    718 }
    719 
    720 // Same test as RunSimplexInputStreamWithFileAsSink but this time output
    721 // streaming is active as well (reads zeros only).
    722 // NOTE: this test requires user interaction and is not designed to run as an
    723 // automatized test on bots.
    724 TEST_P(AudioAndroidInputTest, DISABLED_RunDuplexInputStreamWithFileAsSink) {
    725   AudioParameters in_params = GetInputStreamParameters();
    726   AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
    727       in_params, AudioManagerBase::kDefaultDeviceId);
    728   EXPECT_TRUE(ais);
    729 
    730   AudioParameters out_params =
    731       audio_manager()->GetDefaultOutputStreamParameters();
    732   AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
    733       out_params, std::string(), std::string());
    734   EXPECT_TRUE(aos);
    735 
    736   std::string file_name = base::StringPrintf("out_duplex_%d_%d_%d.pcm",
    737                                              in_params.sample_rate(),
    738                                              in_params.frames_per_buffer(),
    739                                              in_params.channels());
    740 
    741   base::WaitableEvent event(false, false);
    742   FileAudioSink sink(&event, in_params, file_name);
    743   MockAudioOutputCallback source;
    744 
    745   EXPECT_CALL(source, OnMoreData(NotNull(), _)).WillRepeatedly(
    746       Invoke(&source, &MockAudioOutputCallback::RealOnMoreData));
    747   EXPECT_CALL(source, OnError(aos)).Times(0);
    748   EXPECT_CALL(source, OnMoreIOData(_, _, _)).Times(0);
    749 
    750   EXPECT_TRUE(ais->Open());
    751   EXPECT_TRUE(aos->Open());
    752   ais->Start(&sink);
    753   aos->Start(&source);
    754   VLOG(0) << ">> Speak into the microphone to record audio";
    755   EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
    756   aos->Stop();
    757   ais->Stop();
    758   aos->Close();
    759   ais->Close();
    760 }
    761 
    762 // Start audio in both directions while feeding captured data into a FIFO so
    763 // it can be read directly (in loopback) by the render side. A small extra
    764 // delay will be added by the FIFO and an estimate of this delay will be
    765 // printed out during the test.
    766 // NOTE: this test requires user interaction and is not designed to run as an
    767 // automatized test on bots.
    768 TEST_P(AudioAndroidInputTest,
    769        DISABLED_RunSymmetricInputAndOutputStreamsInFullDuplex) {
    770   // Get native audio parameters for the input side.
    771   AudioParameters default_input_params = GetInputStreamParameters();
    772 
    773   // Modify the parameters so that both input and output can use the same
    774   // parameters by selecting 10ms as buffer size. This will also ensure that
    775   // the output stream will be a mono stream since mono is default for input
    776   // audio on Android.
    777   AudioParameters io_params(default_input_params.format(),
    778                             default_input_params.channel_layout(),
    779                             default_input_params.sample_rate(),
    780                             default_input_params.bits_per_sample(),
    781                             default_input_params.sample_rate() / 100);
    782   VLOG(1) << io_params;
    783 
    784   // Create input and output streams using the common audio parameters.
    785   AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
    786       io_params, AudioManagerBase::kDefaultDeviceId);
    787   EXPECT_TRUE(ais);
    788   AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
    789       io_params, std::string(), std::string());
    790   EXPECT_TRUE(aos);
    791 
    792   FullDuplexAudioSinkSource full_duplex(io_params);
    793 
    794   // Start a full duplex audio session and print out estimates of the extra
    795   // delay we should expect from the FIFO. If real-time delay measurements are
    796   // performed, the result should be reduced by this extra delay since it is
    797   // something that has been added by the test.
    798   EXPECT_TRUE(ais->Open());
    799   EXPECT_TRUE(aos->Open());
    800   ais->Start(&full_duplex);
    801   aos->Start(&full_duplex);
    802   VLOG(1) << "HINT: an estimate of the extra FIFO delay will be updated "
    803           << "once per second during this test.";
    804   VLOG(0) << ">> Speak into the mic and listen to the audio in loopback...";
    805   fflush(stdout);
    806   base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20));
    807   printf("\n");
    808   aos->Stop();
    809   ais->Stop();
    810   aos->Close();
    811   ais->Close();
    812 }
    813 
    814 INSTANTIATE_TEST_CASE_P(AudioAndroidInputTest, AudioAndroidInputTest,
    815     testing::ValuesIn(RunAudioRecordInputPathTests()));
    816 
    817 }  // namespace media
    818