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