xref: /aosp_15_r20/external/webrtc/modules/audio_device/audio_device_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_device/include/audio_device.h"
12 
13 #include <algorithm>
14 #include <cstring>
15 #include <list>
16 #include <memory>
17 #include <numeric>
18 
19 #include "absl/types/optional.h"
20 #include "api/array_view.h"
21 #include "api/scoped_refptr.h"
22 #include "api/sequence_checker.h"
23 #include "api/task_queue/default_task_queue_factory.h"
24 #include "api/task_queue/task_queue_factory.h"
25 #include "modules/audio_device/audio_device_impl.h"
26 #include "modules/audio_device/include/mock_audio_transport.h"
27 #include "rtc_base/arraysize.h"
28 #include "rtc_base/buffer.h"
29 #include "rtc_base/event.h"
30 #include "rtc_base/logging.h"
31 #include "rtc_base/numerics/safe_conversions.h"
32 #include "rtc_base/race_checker.h"
33 #include "rtc_base/synchronization/mutex.h"
34 #include "rtc_base/thread_annotations.h"
35 #include "rtc_base/time_utils.h"
36 #include "test/gmock.h"
37 #include "test/gtest.h"
38 #ifdef WEBRTC_WIN
39 #include "modules/audio_device/include/audio_device_factory.h"
40 #include "modules/audio_device/win/core_audio_utility_win.h"
41 #include "rtc_base/win/scoped_com_initializer.h"
42 #endif  // WEBRTC_WIN
43 
44 using ::testing::_;
45 using ::testing::AtLeast;
46 using ::testing::Ge;
47 using ::testing::Invoke;
48 using ::testing::Mock;
49 using ::testing::NiceMock;
50 using ::testing::NotNull;
51 
52 namespace webrtc {
53 namespace {
54 
55 // Using a #define for AUDIO_DEVICE since we will call *different* versions of
56 // the ADM functions, depending on the ID type.
57 #if defined(WEBRTC_WIN)
58 #define AUDIO_DEVICE_ID (AudioDeviceModule::WindowsDeviceType::kDefaultDevice)
59 #else
60 #define AUDIO_DEVICE_ID (0u)
61 #endif  // defined(WEBRTC_WIN)
62 
63 // #define ENABLE_DEBUG_PRINTF
64 #ifdef ENABLE_DEBUG_PRINTF
65 #define PRINTD(...) fprintf(stderr, __VA_ARGS__);
66 #else
67 #define PRINTD(...) ((void)0)
68 #endif
69 #define PRINT(...) fprintf(stderr, __VA_ARGS__);
70 
71 // Don't run these tests if audio-related requirements are not met.
72 #define SKIP_TEST_IF_NOT(requirements_satisfied)         \
73   do {                                                   \
74     if (!requirements_satisfied) {                       \
75       GTEST_SKIP() << "Skipped. No audio device found."; \
76     }                                                    \
77   } while (false)
78 
79 // Number of callbacks (input or output) the tests waits for before we set
80 // an event indicating that the test was OK.
81 static constexpr size_t kNumCallbacks = 10;
82 // Max amount of time we wait for an event to be set while counting callbacks.
83 static constexpr TimeDelta kTestTimeOut = TimeDelta::Seconds(10);
84 // Average number of audio callbacks per second assuming 10ms packet size.
85 static constexpr size_t kNumCallbacksPerSecond = 100;
86 // Run the full-duplex test during this time (unit is in seconds).
87 static constexpr TimeDelta kFullDuplexTime = TimeDelta::Seconds(5);
88 // Length of round-trip latency measurements. Number of deteced impulses
89 // shall be kImpulseFrequencyInHz * kMeasureLatencyTime - 1 since the
90 // last transmitted pulse is not used.
91 static constexpr TimeDelta kMeasureLatencyTime = TimeDelta::Seconds(10);
92 // Sets the number of impulses per second in the latency test.
93 static constexpr size_t kImpulseFrequencyInHz = 1;
94 // Utilized in round-trip latency measurements to avoid capturing noise samples.
95 static constexpr int kImpulseThreshold = 1000;
96 
97 enum class TransportType {
98   kInvalid,
99   kPlay,
100   kRecord,
101   kPlayAndRecord,
102 };
103 
104 // Interface for processing the audio stream. Real implementations can e.g.
105 // run audio in loopback, read audio from a file or perform latency
106 // measurements.
107 class AudioStream {
108  public:
109   virtual void Write(rtc::ArrayView<const int16_t> source) = 0;
110   virtual void Read(rtc::ArrayView<int16_t> destination) = 0;
111 
112   virtual ~AudioStream() = default;
113 };
114 
115 // Converts index corresponding to position within a 10ms buffer into a
116 // delay value in milliseconds.
117 // Example: index=240, frames_per_10ms_buffer=480 => 5ms as output.
IndexToMilliseconds(size_t index,size_t frames_per_10ms_buffer)118 int IndexToMilliseconds(size_t index, size_t frames_per_10ms_buffer) {
119   return rtc::checked_cast<int>(
120       10.0 * (static_cast<double>(index) / frames_per_10ms_buffer) + 0.5);
121 }
122 
123 }  // namespace
124 
125 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio
126 // buffers of fixed size and allows Write and Read operations. The idea is to
127 // store recorded audio buffers (using Write) and then read (using Read) these
128 // stored buffers with as short delay as possible when the audio layer needs
129 // data to play out. The number of buffers in the FIFO will stabilize under
130 // normal conditions since there will be a balance between Write and Read calls.
131 // The container is a std::list container and access is protected with a lock
132 // since both sides (playout and recording) are driven by its own thread.
133 // Note that, we know by design that the size of the audio buffer will not
134 // change over time and that both sides will in most cases use the same size.
135 class FifoAudioStream : public AudioStream {
136  public:
Write(rtc::ArrayView<const int16_t> source)137   void Write(rtc::ArrayView<const int16_t> source) override {
138     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
139     const size_t size = [&] {
140       MutexLock lock(&lock_);
141       fifo_.push_back(Buffer16(source.data(), source.size()));
142       return fifo_.size();
143     }();
144     if (size > max_size_) {
145       max_size_ = size;
146     }
147     // Add marker once per second to signal that audio is active.
148     if (write_count_++ % 100 == 0) {
149       PRINTD(".");
150     }
151     written_elements_ += size;
152   }
153 
Read(rtc::ArrayView<int16_t> destination)154   void Read(rtc::ArrayView<int16_t> destination) override {
155     MutexLock lock(&lock_);
156     if (fifo_.empty()) {
157       std::fill(destination.begin(), destination.end(), 0);
158     } else {
159       const Buffer16& buffer = fifo_.front();
160       if (buffer.size() == destination.size()) {
161         // Default case where input and output uses same sample rate and
162         // channel configuration. No conversion is needed.
163         std::copy(buffer.begin(), buffer.end(), destination.begin());
164       } else if (destination.size() == 2 * buffer.size()) {
165         // Recorded input signal in `buffer` is in mono. Do channel upmix to
166         // match stereo output (1 -> 2).
167         for (size_t i = 0; i < buffer.size(); ++i) {
168           destination[2 * i] = buffer[i];
169           destination[2 * i + 1] = buffer[i];
170         }
171       } else if (buffer.size() == 2 * destination.size()) {
172         // Recorded input signal in `buffer` is in stereo. Do channel downmix
173         // to match mono output (2 -> 1).
174         for (size_t i = 0; i < destination.size(); ++i) {
175           destination[i] =
176               (static_cast<int32_t>(buffer[2 * i]) + buffer[2 * i + 1]) / 2;
177         }
178       } else {
179         RTC_DCHECK_NOTREACHED() << "Required conversion is not support";
180       }
181       fifo_.pop_front();
182     }
183   }
184 
size() const185   size_t size() const {
186     MutexLock lock(&lock_);
187     return fifo_.size();
188   }
189 
max_size() const190   size_t max_size() const {
191     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
192     return max_size_;
193   }
194 
average_size() const195   size_t average_size() const {
196     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
197     return 0.5 + static_cast<float>(written_elements_ / write_count_);
198   }
199 
200   using Buffer16 = rtc::BufferT<int16_t>;
201 
202   mutable Mutex lock_;
203   rtc::RaceChecker race_checker_;
204 
205   std::list<Buffer16> fifo_ RTC_GUARDED_BY(lock_);
206   size_t write_count_ RTC_GUARDED_BY(race_checker_) = 0;
207   size_t max_size_ RTC_GUARDED_BY(race_checker_) = 0;
208   size_t written_elements_ RTC_GUARDED_BY(race_checker_) = 0;
209 };
210 
211 // Inserts periodic impulses and measures the latency between the time of
212 // transmission and time of receiving the same impulse.
213 class LatencyAudioStream : public AudioStream {
214  public:
LatencyAudioStream()215   LatencyAudioStream() {
216     // Delay thread checkers from being initialized until first callback from
217     // respective thread.
218     read_thread_checker_.Detach();
219     write_thread_checker_.Detach();
220   }
221 
222   // Insert periodic impulses in first two samples of `destination`.
Read(rtc::ArrayView<int16_t> destination)223   void Read(rtc::ArrayView<int16_t> destination) override {
224     RTC_DCHECK_RUN_ON(&read_thread_checker_);
225     if (read_count_ == 0) {
226       PRINT("[");
227     }
228     read_count_++;
229     std::fill(destination.begin(), destination.end(), 0);
230     if (read_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) {
231       PRINT(".");
232       {
233         MutexLock lock(&lock_);
234         if (!pulse_time_) {
235           pulse_time_ = rtc::TimeMillis();
236         }
237       }
238       constexpr int16_t impulse = std::numeric_limits<int16_t>::max();
239       std::fill_n(destination.begin(), 2, impulse);
240     }
241   }
242 
243   // Detect received impulses in `source`, derive time between transmission and
244   // detection and add the calculated delay to list of latencies.
Write(rtc::ArrayView<const int16_t> source)245   void Write(rtc::ArrayView<const int16_t> source) override {
246     RTC_DCHECK_RUN_ON(&write_thread_checker_);
247     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
248     MutexLock lock(&lock_);
249     write_count_++;
250     if (!pulse_time_) {
251       // Avoid detection of new impulse response until a new impulse has
252       // been transmitted (sets `pulse_time_` to value larger than zero).
253       return;
254     }
255     // Find index (element position in vector) of the max element.
256     const size_t index_of_max =
257         std::max_element(source.begin(), source.end()) - source.begin();
258     // Derive time between transmitted pulse and received pulse if the level
259     // is high enough (removes noise).
260     const size_t max = source[index_of_max];
261     if (max > kImpulseThreshold) {
262       PRINTD("(%zu, %zu)", max, index_of_max);
263       int64_t now_time = rtc::TimeMillis();
264       int extra_delay = IndexToMilliseconds(index_of_max, source.size());
265       PRINTD("[%d]", rtc::checked_cast<int>(now_time - pulse_time_));
266       PRINTD("[%d]", extra_delay);
267       // Total latency is the difference between transmit time and detection
268       // tome plus the extra delay within the buffer in which we detected the
269       // received impulse. It is transmitted at sample 0 but can be received
270       // at sample N where N > 0. The term `extra_delay` accounts for N and it
271       // is a value between 0 and 10ms.
272       latencies_.push_back(now_time - *pulse_time_ + extra_delay);
273       pulse_time_.reset();
274     } else {
275       PRINTD("-");
276     }
277   }
278 
num_latency_values() const279   size_t num_latency_values() const {
280     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
281     return latencies_.size();
282   }
283 
min_latency() const284   int min_latency() const {
285     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
286     if (latencies_.empty())
287       return 0;
288     return *std::min_element(latencies_.begin(), latencies_.end());
289   }
290 
max_latency() const291   int max_latency() const {
292     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
293     if (latencies_.empty())
294       return 0;
295     return *std::max_element(latencies_.begin(), latencies_.end());
296   }
297 
average_latency() const298   int average_latency() const {
299     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
300     if (latencies_.empty())
301       return 0;
302     return 0.5 + static_cast<double>(
303                      std::accumulate(latencies_.begin(), latencies_.end(), 0)) /
304                      latencies_.size();
305   }
306 
PrintResults() const307   void PrintResults() const {
308     RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
309     PRINT("] ");
310     for (auto it = latencies_.begin(); it != latencies_.end(); ++it) {
311       PRINTD("%d ", *it);
312     }
313     PRINT("\n");
314     PRINT("[..........] [min, max, avg]=[%d, %d, %d] ms\n", min_latency(),
315           max_latency(), average_latency());
316   }
317 
318   Mutex lock_;
319   rtc::RaceChecker race_checker_;
320   SequenceChecker read_thread_checker_;
321   SequenceChecker write_thread_checker_;
322 
323   absl::optional<int64_t> pulse_time_ RTC_GUARDED_BY(lock_);
324   std::vector<int> latencies_ RTC_GUARDED_BY(race_checker_);
325   size_t read_count_ RTC_GUARDED_BY(read_thread_checker_) = 0;
326   size_t write_count_ RTC_GUARDED_BY(write_thread_checker_) = 0;
327 };
328 
329 // Mocks the AudioTransport object and proxies actions for the two callbacks
330 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations
331 // of AudioStreamInterface.
332 class MockAudioTransport : public test::MockAudioTransport {
333  public:
MockAudioTransport(TransportType type)334   explicit MockAudioTransport(TransportType type) : type_(type) {}
~MockAudioTransport()335   ~MockAudioTransport() {}
336 
337   // Set default actions of the mock object. We are delegating to fake
338   // implementation where the number of callbacks is counted and an event
339   // is set after a certain number of callbacks. Audio parameters are also
340   // checked.
HandleCallbacks(rtc::Event * event,AudioStream * audio_stream,int num_callbacks)341   void HandleCallbacks(rtc::Event* event,
342                        AudioStream* audio_stream,
343                        int num_callbacks) {
344     event_ = event;
345     audio_stream_ = audio_stream;
346     num_callbacks_ = num_callbacks;
347     if (play_mode()) {
348       ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _))
349           .WillByDefault(
350               Invoke(this, &MockAudioTransport::RealNeedMorePlayData));
351     }
352     if (rec_mode()) {
353       ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _))
354           .WillByDefault(
355               Invoke(this, &MockAudioTransport::RealRecordedDataIsAvailable));
356     }
357   }
358 
359   // Special constructor used in manual tests where the user wants to run audio
360   // until e.g. a keyboard key is pressed. The event flag is set to nullptr by
361   // default since it is up to the user to stop the test. See e.g.
362   // DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey().
HandleCallbacks(AudioStream * audio_stream)363   void HandleCallbacks(AudioStream* audio_stream) {
364     HandleCallbacks(nullptr, audio_stream, 0);
365   }
366 
RealRecordedDataIsAvailable(const void * audio_buffer,const size_t samples_per_channel,const size_t bytes_per_frame,const size_t channels,const uint32_t sample_rate,const uint32_t total_delay_ms,const int32_t clock_drift,const uint32_t current_mic_level,const bool typing_status,uint32_t & new_mic_level)367   int32_t RealRecordedDataIsAvailable(const void* audio_buffer,
368                                       const size_t samples_per_channel,
369                                       const size_t bytes_per_frame,
370                                       const size_t channels,
371                                       const uint32_t sample_rate,
372                                       const uint32_t total_delay_ms,
373                                       const int32_t clock_drift,
374                                       const uint32_t current_mic_level,
375                                       const bool typing_status,
376                                       uint32_t& new_mic_level) {
377     EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks.";
378     // Store audio parameters once in the first callback. For all other
379     // callbacks, verify that the provided audio parameters are maintained and
380     // that each callback corresponds to 10ms for any given sample rate.
381     if (!record_parameters_.is_complete()) {
382       record_parameters_.reset(sample_rate, channels, samples_per_channel);
383     } else {
384       EXPECT_EQ(samples_per_channel, record_parameters_.frames_per_buffer());
385       EXPECT_EQ(bytes_per_frame, record_parameters_.GetBytesPerFrame());
386       EXPECT_EQ(channels, record_parameters_.channels());
387       EXPECT_EQ(static_cast<int>(sample_rate),
388                 record_parameters_.sample_rate());
389       EXPECT_EQ(samples_per_channel,
390                 record_parameters_.frames_per_10ms_buffer());
391     }
392     {
393       MutexLock lock(&lock_);
394       rec_count_++;
395     }
396     // Write audio data to audio stream object if one has been injected.
397     if (audio_stream_) {
398       audio_stream_->Write(
399           rtc::MakeArrayView(static_cast<const int16_t*>(audio_buffer),
400                              samples_per_channel * channels));
401     }
402     // Signal the event after given amount of callbacks.
403     if (event_ && ReceivedEnoughCallbacks()) {
404       event_->Set();
405     }
406     return 0;
407   }
408 
RealNeedMorePlayData(const size_t samples_per_channel,const size_t bytes_per_frame,const size_t channels,const uint32_t sample_rate,void * audio_buffer,size_t & samples_out,int64_t * elapsed_time_ms,int64_t * ntp_time_ms)409   int32_t RealNeedMorePlayData(const size_t samples_per_channel,
410                                const size_t bytes_per_frame,
411                                const size_t channels,
412                                const uint32_t sample_rate,
413                                void* audio_buffer,
414                                size_t& samples_out,
415                                int64_t* elapsed_time_ms,
416                                int64_t* ntp_time_ms) {
417     EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks.";
418     // Store audio parameters once in the first callback. For all other
419     // callbacks, verify that the provided audio parameters are maintained and
420     // that each callback corresponds to 10ms for any given sample rate.
421     if (!playout_parameters_.is_complete()) {
422       playout_parameters_.reset(sample_rate, channels, samples_per_channel);
423     } else {
424       EXPECT_EQ(samples_per_channel, playout_parameters_.frames_per_buffer());
425       EXPECT_EQ(bytes_per_frame, playout_parameters_.GetBytesPerFrame());
426       EXPECT_EQ(channels, playout_parameters_.channels());
427       EXPECT_EQ(static_cast<int>(sample_rate),
428                 playout_parameters_.sample_rate());
429       EXPECT_EQ(samples_per_channel,
430                 playout_parameters_.frames_per_10ms_buffer());
431     }
432     {
433       MutexLock lock(&lock_);
434       play_count_++;
435     }
436     samples_out = samples_per_channel * channels;
437     // Read audio data from audio stream object if one has been injected.
438     if (audio_stream_) {
439       audio_stream_->Read(rtc::MakeArrayView(
440           static_cast<int16_t*>(audio_buffer), samples_per_channel * channels));
441     } else {
442       // Fill the audio buffer with zeros to avoid disturbing audio.
443       const size_t num_bytes = samples_per_channel * bytes_per_frame;
444       std::memset(audio_buffer, 0, num_bytes);
445     }
446     // Signal the event after given amount of callbacks.
447     if (event_ && ReceivedEnoughCallbacks()) {
448       event_->Set();
449     }
450     return 0;
451   }
452 
ReceivedEnoughCallbacks()453   bool ReceivedEnoughCallbacks() {
454     bool recording_done = false;
455     if (rec_mode()) {
456       MutexLock lock(&lock_);
457       recording_done = rec_count_ >= num_callbacks_;
458     } else {
459       recording_done = true;
460     }
461     bool playout_done = false;
462     if (play_mode()) {
463       MutexLock lock(&lock_);
464       playout_done = play_count_ >= num_callbacks_;
465     } else {
466       playout_done = true;
467     }
468     return recording_done && playout_done;
469   }
470 
play_mode() const471   bool play_mode() const {
472     return type_ == TransportType::kPlay ||
473            type_ == TransportType::kPlayAndRecord;
474   }
475 
rec_mode() const476   bool rec_mode() const {
477     return type_ == TransportType::kRecord ||
478            type_ == TransportType::kPlayAndRecord;
479   }
480 
ResetCallbackCounters()481   void ResetCallbackCounters() {
482     MutexLock lock(&lock_);
483     if (play_mode()) {
484       play_count_ = 0;
485     }
486     if (rec_mode()) {
487       rec_count_ = 0;
488     }
489   }
490 
491  private:
492   Mutex lock_;
493   TransportType type_ = TransportType::kInvalid;
494   rtc::Event* event_ = nullptr;
495   AudioStream* audio_stream_ = nullptr;
496   size_t num_callbacks_ = 0;
497   size_t play_count_ RTC_GUARDED_BY(lock_) = 0;
498   size_t rec_count_ RTC_GUARDED_BY(lock_) = 0;
499   AudioParameters playout_parameters_;
500   AudioParameters record_parameters_;
501 };
502 
503 // AudioDeviceTest test fixture.
504 
505 // bugs.webrtc.org/9808
506 // Both the tests and the code under test are very old, unstaffed and not
507 // a part of webRTC stack.
508 // Here sanitizers make the tests hang, without providing usefull report.
509 // So we are just disabling them, without intention to re-enable them.
510 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
511     defined(THREAD_SANITIZER) || defined(UNDEFINED_SANITIZER)
512 #define MAYBE_AudioDeviceTest DISABLED_AudioDeviceTest
513 #else
514 #define MAYBE_AudioDeviceTest AudioDeviceTest
515 #endif
516 
517 class MAYBE_AudioDeviceTest
518     : public ::testing::TestWithParam<webrtc::AudioDeviceModule::AudioLayer> {
519  protected:
MAYBE_AudioDeviceTest()520   MAYBE_AudioDeviceTest()
521       : audio_layer_(GetParam()),
522         task_queue_factory_(CreateDefaultTaskQueueFactory()) {
523     rtc::LogMessage::LogToDebug(rtc::LS_INFO);
524     // Add extra logging fields here if needed for debugging.
525     rtc::LogMessage::LogTimestamps();
526     rtc::LogMessage::LogThreads();
527     audio_device_ = CreateAudioDevice();
528     EXPECT_NE(audio_device_.get(), nullptr);
529     AudioDeviceModule::AudioLayer audio_layer;
530     int got_platform_audio_layer =
531         audio_device_->ActiveAudioLayer(&audio_layer);
532     // First, ensure that a valid audio layer can be activated.
533     if (got_platform_audio_layer != 0) {
534       requirements_satisfied_ = false;
535     }
536     // Next, verify that the ADM can be initialized.
537     if (requirements_satisfied_) {
538       requirements_satisfied_ = (audio_device_->Init() == 0);
539     }
540     // Finally, ensure that at least one valid device exists in each direction.
541     if (requirements_satisfied_) {
542       const int16_t num_playout_devices = audio_device_->PlayoutDevices();
543       const int16_t num_record_devices = audio_device_->RecordingDevices();
544       requirements_satisfied_ =
545           num_playout_devices > 0 && num_record_devices > 0;
546     }
547     if (requirements_satisfied_) {
548       EXPECT_EQ(0, audio_device_->SetPlayoutDevice(AUDIO_DEVICE_ID));
549       EXPECT_EQ(0, audio_device_->InitSpeaker());
550       EXPECT_EQ(0, audio_device_->StereoPlayoutIsAvailable(&stereo_playout_));
551       EXPECT_EQ(0, audio_device_->SetStereoPlayout(stereo_playout_));
552       EXPECT_EQ(0, audio_device_->SetRecordingDevice(AUDIO_DEVICE_ID));
553       EXPECT_EQ(0, audio_device_->InitMicrophone());
554       // Avoid asking for input stereo support and always record in mono
555       // since asking can cause issues in combination with remote desktop.
556       // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7397 for
557       // details.
558       EXPECT_EQ(0, audio_device_->SetStereoRecording(false));
559     }
560   }
561 
562   // This is needed by all tests using MockAudioTransport,
563   // since there is no way to unregister it.
564   // Without Terminate(), audio_device would still accesses
565   // the destructed mock via "webrtc_audio_module_rec_thread".
566   // An alternative would be for the mock to outlive audio_device.
PreTearDown()567   void PreTearDown() { EXPECT_EQ(0, audio_device_->Terminate()); }
568 
~MAYBE_AudioDeviceTest()569   virtual ~MAYBE_AudioDeviceTest() {
570     if (audio_device_) {
571       EXPECT_EQ(0, audio_device_->Terminate());
572     }
573   }
574 
requirements_satisfied() const575   bool requirements_satisfied() const { return requirements_satisfied_; }
event()576   rtc::Event* event() { return &event_; }
audio_layer() const577   AudioDeviceModule::AudioLayer audio_layer() const { return audio_layer_; }
578 
579   // AudioDeviceModuleForTest extends the default ADM interface with some extra
580   // test methods. Intended for usage in tests only and requires a unique
581   // factory method. See CreateAudioDevice() for details.
audio_device() const582   const rtc::scoped_refptr<AudioDeviceModuleForTest>& audio_device() const {
583     return audio_device_;
584   }
585 
CreateAudioDevice()586   rtc::scoped_refptr<AudioDeviceModuleForTest> CreateAudioDevice() {
587     // Use the default factory for kPlatformDefaultAudio and a special factory
588     // CreateWindowsCoreAudioAudioDeviceModuleForTest() for kWindowsCoreAudio2.
589     // The value of `audio_layer_` is set at construction by GetParam() and two
590     // different layers are tested on Windows only.
591     if (audio_layer_ == AudioDeviceModule::kPlatformDefaultAudio) {
592       return AudioDeviceModule::CreateForTest(audio_layer_,
593                                               task_queue_factory_.get());
594     } else if (audio_layer_ == AudioDeviceModule::kWindowsCoreAudio2) {
595 #ifdef WEBRTC_WIN
596       // We must initialize the COM library on a thread before we calling any of
597       // the library functions. All COM functions in the ADM will return
598       // CO_E_NOTINITIALIZED otherwise.
599       com_initializer_ =
600           std::make_unique<ScopedCOMInitializer>(ScopedCOMInitializer::kMTA);
601       EXPECT_TRUE(com_initializer_->Succeeded());
602       EXPECT_TRUE(webrtc_win::core_audio_utility::IsSupported());
603       EXPECT_TRUE(webrtc_win::core_audio_utility::IsMMCSSSupported());
604       return CreateWindowsCoreAudioAudioDeviceModuleForTest(
605           task_queue_factory_.get(), true);
606 #else
607       return nullptr;
608 #endif
609     } else {
610       return nullptr;
611     }
612   }
613 
StartPlayout()614   void StartPlayout() {
615     EXPECT_FALSE(audio_device()->Playing());
616     EXPECT_EQ(0, audio_device()->InitPlayout());
617     EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
618     EXPECT_EQ(0, audio_device()->StartPlayout());
619     EXPECT_TRUE(audio_device()->Playing());
620   }
621 
StopPlayout()622   void StopPlayout() {
623     EXPECT_EQ(0, audio_device()->StopPlayout());
624     EXPECT_FALSE(audio_device()->Playing());
625     EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
626   }
627 
StartRecording()628   void StartRecording() {
629     EXPECT_FALSE(audio_device()->Recording());
630     EXPECT_EQ(0, audio_device()->InitRecording());
631     EXPECT_TRUE(audio_device()->RecordingIsInitialized());
632     EXPECT_EQ(0, audio_device()->StartRecording());
633     EXPECT_TRUE(audio_device()->Recording());
634   }
635 
StopRecording()636   void StopRecording() {
637     EXPECT_EQ(0, audio_device()->StopRecording());
638     EXPECT_FALSE(audio_device()->Recording());
639     EXPECT_FALSE(audio_device()->RecordingIsInitialized());
640   }
641 
NewWindowsAudioDeviceModuleIsUsed()642   bool NewWindowsAudioDeviceModuleIsUsed() {
643 #ifdef WEBRTC_WIN
644     AudioDeviceModule::AudioLayer audio_layer;
645     EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer));
646     if (audio_layer == AudioDeviceModule::kWindowsCoreAudio2) {
647       // Default device is always added as first element in the list and the
648       // default communication device as the second element. Hence, the list
649       // contains two extra elements in this case.
650       return true;
651     }
652 #endif
653     return false;
654   }
655 
656  private:
657 #ifdef WEBRTC_WIN
658   // Windows Core Audio based ADM needs to run on a COM initialized thread.
659   std::unique_ptr<ScopedCOMInitializer> com_initializer_;
660 #endif
661   AudioDeviceModule::AudioLayer audio_layer_;
662   std::unique_ptr<TaskQueueFactory> task_queue_factory_;
663   bool requirements_satisfied_ = true;
664   rtc::Event event_;
665   rtc::scoped_refptr<AudioDeviceModuleForTest> audio_device_;
666   bool stereo_playout_ = false;
667 };
668 
669 // Instead of using the test fixture, verify that the different factory methods
670 // work as intended.
TEST(MAYBE_AudioDeviceTestWin,ConstructDestructWithFactory)671 TEST(MAYBE_AudioDeviceTestWin, ConstructDestructWithFactory) {
672   std::unique_ptr<TaskQueueFactory> task_queue_factory =
673       CreateDefaultTaskQueueFactory();
674   rtc::scoped_refptr<AudioDeviceModule> audio_device;
675   // The default factory should work for all platforms when a default ADM is
676   // requested.
677   audio_device = AudioDeviceModule::Create(
678       AudioDeviceModule::kPlatformDefaultAudio, task_queue_factory.get());
679   EXPECT_TRUE(audio_device);
680   audio_device = nullptr;
681 #ifdef WEBRTC_WIN
682   // For Windows, the old factory method creates an ADM where the platform-
683   // specific parts are implemented by an AudioDeviceGeneric object. Verify
684   // that the old factory can't be used in combination with the latest audio
685   // layer AudioDeviceModule::kWindowsCoreAudio2.
686   audio_device = AudioDeviceModule::Create(
687       AudioDeviceModule::kWindowsCoreAudio2, task_queue_factory.get());
688   EXPECT_FALSE(audio_device);
689   audio_device = nullptr;
690   // Instead, ensure that the new dedicated factory method called
691   // CreateWindowsCoreAudioAudioDeviceModule() can be used on Windows and that
692   // it sets the audio layer to kWindowsCoreAudio2 implicitly. Note that, the
693   // new ADM for Windows must be created on a COM thread.
694   ScopedCOMInitializer com_initializer(ScopedCOMInitializer::kMTA);
695   EXPECT_TRUE(com_initializer.Succeeded());
696   audio_device =
697       CreateWindowsCoreAudioAudioDeviceModule(task_queue_factory.get());
698   EXPECT_TRUE(audio_device);
699   AudioDeviceModule::AudioLayer audio_layer;
700   EXPECT_EQ(0, audio_device->ActiveAudioLayer(&audio_layer));
701   EXPECT_EQ(audio_layer, AudioDeviceModule::kWindowsCoreAudio2);
702 #endif
703 }
704 
705 // Uses the test fixture to create, initialize and destruct the ADM.
TEST_P(MAYBE_AudioDeviceTest,ConstructDestructDefault)706 TEST_P(MAYBE_AudioDeviceTest, ConstructDestructDefault) {}
707 
TEST_P(MAYBE_AudioDeviceTest,InitTerminate)708 TEST_P(MAYBE_AudioDeviceTest, InitTerminate) {
709   SKIP_TEST_IF_NOT(requirements_satisfied());
710   // Initialization is part of the test fixture.
711   EXPECT_TRUE(audio_device()->Initialized());
712   EXPECT_EQ(0, audio_device()->Terminate());
713   EXPECT_FALSE(audio_device()->Initialized());
714 }
715 
716 // Enumerate all available and active output devices.
TEST_P(MAYBE_AudioDeviceTest,PlayoutDeviceNames)717 TEST_P(MAYBE_AudioDeviceTest, PlayoutDeviceNames) {
718   SKIP_TEST_IF_NOT(requirements_satisfied());
719   char device_name[kAdmMaxDeviceNameSize];
720   char unique_id[kAdmMaxGuidSize];
721   int num_devices = audio_device()->PlayoutDevices();
722   if (NewWindowsAudioDeviceModuleIsUsed()) {
723     num_devices += 2;
724   }
725   EXPECT_GT(num_devices, 0);
726   for (int i = 0; i < num_devices; ++i) {
727     EXPECT_EQ(0, audio_device()->PlayoutDeviceName(i, device_name, unique_id));
728   }
729   EXPECT_EQ(-1, audio_device()->PlayoutDeviceName(num_devices, device_name,
730                                                   unique_id));
731 }
732 
733 // Enumerate all available and active input devices.
TEST_P(MAYBE_AudioDeviceTest,RecordingDeviceNames)734 TEST_P(MAYBE_AudioDeviceTest, RecordingDeviceNames) {
735   SKIP_TEST_IF_NOT(requirements_satisfied());
736   char device_name[kAdmMaxDeviceNameSize];
737   char unique_id[kAdmMaxGuidSize];
738   int num_devices = audio_device()->RecordingDevices();
739   if (NewWindowsAudioDeviceModuleIsUsed()) {
740     num_devices += 2;
741   }
742   EXPECT_GT(num_devices, 0);
743   for (int i = 0; i < num_devices; ++i) {
744     EXPECT_EQ(0,
745               audio_device()->RecordingDeviceName(i, device_name, unique_id));
746   }
747   EXPECT_EQ(-1, audio_device()->RecordingDeviceName(num_devices, device_name,
748                                                     unique_id));
749 }
750 
751 // Counts number of active output devices and ensure that all can be selected.
TEST_P(MAYBE_AudioDeviceTest,SetPlayoutDevice)752 TEST_P(MAYBE_AudioDeviceTest, SetPlayoutDevice) {
753   SKIP_TEST_IF_NOT(requirements_satisfied());
754   int num_devices = audio_device()->PlayoutDevices();
755   if (NewWindowsAudioDeviceModuleIsUsed()) {
756     num_devices += 2;
757   }
758   EXPECT_GT(num_devices, 0);
759   // Verify that all available playout devices can be set (not enabled yet).
760   for (int i = 0; i < num_devices; ++i) {
761     EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i));
762   }
763   EXPECT_EQ(-1, audio_device()->SetPlayoutDevice(num_devices));
764 #ifdef WEBRTC_WIN
765   // On Windows, verify the alternative method where the user can select device
766   // by role.
767   EXPECT_EQ(
768       0, audio_device()->SetPlayoutDevice(AudioDeviceModule::kDefaultDevice));
769   EXPECT_EQ(0, audio_device()->SetPlayoutDevice(
770                    AudioDeviceModule::kDefaultCommunicationDevice));
771 #endif
772 }
773 
774 // Counts number of active input devices and ensure that all can be selected.
TEST_P(MAYBE_AudioDeviceTest,SetRecordingDevice)775 TEST_P(MAYBE_AudioDeviceTest, SetRecordingDevice) {
776   SKIP_TEST_IF_NOT(requirements_satisfied());
777   int num_devices = audio_device()->RecordingDevices();
778   if (NewWindowsAudioDeviceModuleIsUsed()) {
779     num_devices += 2;
780   }
781   EXPECT_GT(num_devices, 0);
782   // Verify that all available recording devices can be set (not enabled yet).
783   for (int i = 0; i < num_devices; ++i) {
784     EXPECT_EQ(0, audio_device()->SetRecordingDevice(i));
785   }
786   EXPECT_EQ(-1, audio_device()->SetRecordingDevice(num_devices));
787 #ifdef WEBRTC_WIN
788   // On Windows, verify the alternative method where the user can select device
789   // by role.
790   EXPECT_EQ(
791       0, audio_device()->SetRecordingDevice(AudioDeviceModule::kDefaultDevice));
792   EXPECT_EQ(0, audio_device()->SetRecordingDevice(
793                    AudioDeviceModule::kDefaultCommunicationDevice));
794 #endif
795 }
796 
797 // Tests Start/Stop playout without any registered audio callback.
TEST_P(MAYBE_AudioDeviceTest,StartStopPlayout)798 TEST_P(MAYBE_AudioDeviceTest, StartStopPlayout) {
799   SKIP_TEST_IF_NOT(requirements_satisfied());
800   StartPlayout();
801   StopPlayout();
802 }
803 
804 // Tests Start/Stop recording without any registered audio callback.
TEST_P(MAYBE_AudioDeviceTest,StartStopRecording)805 TEST_P(MAYBE_AudioDeviceTest, StartStopRecording) {
806   SKIP_TEST_IF_NOT(requirements_satisfied());
807   StartRecording();
808   StopRecording();
809 }
810 
811 // Tests Start/Stop playout for all available input devices to ensure that
812 // the selected device can be created and used as intended.
TEST_P(MAYBE_AudioDeviceTest,StartStopPlayoutWithRealDevice)813 TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithRealDevice) {
814   SKIP_TEST_IF_NOT(requirements_satisfied());
815   int num_devices = audio_device()->PlayoutDevices();
816   if (NewWindowsAudioDeviceModuleIsUsed()) {
817     num_devices += 2;
818   }
819   EXPECT_GT(num_devices, 0);
820   // Verify that all available playout devices can be set and used.
821   for (int i = 0; i < num_devices; ++i) {
822     EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i));
823     StartPlayout();
824     StopPlayout();
825   }
826 #ifdef WEBRTC_WIN
827   AudioDeviceModule::WindowsDeviceType device_role[] = {
828       AudioDeviceModule::kDefaultDevice,
829       AudioDeviceModule::kDefaultCommunicationDevice};
830   for (size_t i = 0; i < arraysize(device_role); ++i) {
831     EXPECT_EQ(0, audio_device()->SetPlayoutDevice(device_role[i]));
832     StartPlayout();
833     StopPlayout();
834   }
835 #endif
836 }
837 
838 // Tests Start/Stop recording for all available input devices to ensure that
839 // the selected device can be created and used as intended.
TEST_P(MAYBE_AudioDeviceTest,StartStopRecordingWithRealDevice)840 TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithRealDevice) {
841   SKIP_TEST_IF_NOT(requirements_satisfied());
842   int num_devices = audio_device()->RecordingDevices();
843   if (NewWindowsAudioDeviceModuleIsUsed()) {
844     num_devices += 2;
845   }
846   EXPECT_GT(num_devices, 0);
847   // Verify that all available recording devices can be set and used.
848   for (int i = 0; i < num_devices; ++i) {
849     EXPECT_EQ(0, audio_device()->SetRecordingDevice(i));
850     StartRecording();
851     StopRecording();
852   }
853 #ifdef WEBRTC_WIN
854   AudioDeviceModule::WindowsDeviceType device_role[] = {
855       AudioDeviceModule::kDefaultDevice,
856       AudioDeviceModule::kDefaultCommunicationDevice};
857   for (size_t i = 0; i < arraysize(device_role); ++i) {
858     EXPECT_EQ(0, audio_device()->SetRecordingDevice(device_role[i]));
859     StartRecording();
860     StopRecording();
861   }
862 #endif
863 }
864 
865 // Tests Init/Stop/Init recording without any registered audio callback.
866 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=8041 for details
867 // on why this test is useful.
TEST_P(MAYBE_AudioDeviceTest,InitStopInitRecording)868 TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecording) {
869   SKIP_TEST_IF_NOT(requirements_satisfied());
870   EXPECT_EQ(0, audio_device()->InitRecording());
871   EXPECT_TRUE(audio_device()->RecordingIsInitialized());
872   StopRecording();
873   EXPECT_EQ(0, audio_device()->InitRecording());
874   StopRecording();
875 }
876 
877 // Verify that additional attempts to initialize or start recording while
878 // already being active works. Additional calls should just be ignored.
TEST_P(MAYBE_AudioDeviceTest,StartInitRecording)879 TEST_P(MAYBE_AudioDeviceTest, StartInitRecording) {
880   SKIP_TEST_IF_NOT(requirements_satisfied());
881   StartRecording();
882   // An additional attempt to initialize at this stage should be ignored.
883   EXPECT_EQ(0, audio_device()->InitRecording());
884   // Same for additional request to start recording while already active.
885   EXPECT_EQ(0, audio_device()->StartRecording());
886   StopRecording();
887 }
888 
889 // Verify that additional attempts to initialize or start playou while
890 // already being active works. Additional calls should just be ignored.
TEST_P(MAYBE_AudioDeviceTest,StartInitPlayout)891 TEST_P(MAYBE_AudioDeviceTest, StartInitPlayout) {
892   SKIP_TEST_IF_NOT(requirements_satisfied());
893   StartPlayout();
894   // An additional attempt to initialize at this stage should be ignored.
895   EXPECT_EQ(0, audio_device()->InitPlayout());
896   // Same for additional request to start playout while already active.
897   EXPECT_EQ(0, audio_device()->StartPlayout());
898   StopPlayout();
899 }
900 
901 // Tests Init/Stop/Init recording while playout is active.
TEST_P(MAYBE_AudioDeviceTest,InitStopInitRecordingWhilePlaying)902 TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecordingWhilePlaying) {
903   SKIP_TEST_IF_NOT(requirements_satisfied());
904   StartPlayout();
905   EXPECT_EQ(0, audio_device()->InitRecording());
906   EXPECT_TRUE(audio_device()->RecordingIsInitialized());
907   StopRecording();
908   EXPECT_EQ(0, audio_device()->InitRecording());
909   StopRecording();
910   StopPlayout();
911 }
912 
913 // Tests Init/Stop/Init playout without any registered audio callback.
TEST_P(MAYBE_AudioDeviceTest,InitStopInitPlayout)914 TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayout) {
915   SKIP_TEST_IF_NOT(requirements_satisfied());
916   EXPECT_EQ(0, audio_device()->InitPlayout());
917   EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
918   StopPlayout();
919   EXPECT_EQ(0, audio_device()->InitPlayout());
920   StopPlayout();
921 }
922 
923 // Tests Init/Stop/Init playout while recording is active.
TEST_P(MAYBE_AudioDeviceTest,InitStopInitPlayoutWhileRecording)924 TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayoutWhileRecording) {
925   SKIP_TEST_IF_NOT(requirements_satisfied());
926   StartRecording();
927   EXPECT_EQ(0, audio_device()->InitPlayout());
928   EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
929   StopPlayout();
930   EXPECT_EQ(0, audio_device()->InitPlayout());
931   StopPlayout();
932   StopRecording();
933 }
934 
935 // TODO(henrika): restart without intermediate destruction is currently only
936 // supported on Windows.
937 #ifdef WEBRTC_WIN
938 // Tests Start/Stop playout followed by a second session (emulates a restart
939 // triggered by a user using public APIs).
TEST_P(MAYBE_AudioDeviceTest,StartStopPlayoutWithExternalRestart)940 TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithExternalRestart) {
941   SKIP_TEST_IF_NOT(requirements_satisfied());
942   StartPlayout();
943   StopPlayout();
944   // Restart playout without destroying the ADM in between. Ensures that we
945   // support: Init(), Start(), Stop(), Init(), Start(), Stop().
946   StartPlayout();
947   StopPlayout();
948 }
949 
950 // Tests Start/Stop recording followed by a second session (emulates a restart
951 // triggered by a user using public APIs).
TEST_P(MAYBE_AudioDeviceTest,StartStopRecordingWithExternalRestart)952 TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithExternalRestart) {
953   SKIP_TEST_IF_NOT(requirements_satisfied());
954   StartRecording();
955   StopRecording();
956   // Restart recording without destroying the ADM in between.  Ensures that we
957   // support: Init(), Start(), Stop(), Init(), Start(), Stop().
958   StartRecording();
959   StopRecording();
960 }
961 
962 // Tests Start/Stop playout followed by a second session (emulates a restart
963 // triggered by an internal callback e.g. corresponding to a device switch).
964 // Note that, internal restart is only supported in combination with the latest
965 // Windows ADM.
TEST_P(MAYBE_AudioDeviceTest,StartStopPlayoutWithInternalRestart)966 TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithInternalRestart) {
967   SKIP_TEST_IF_NOT(requirements_satisfied());
968   if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
969     return;
970   }
971   MockAudioTransport mock(TransportType::kPlay);
972   mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
973   EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
974       .Times(AtLeast(kNumCallbacks));
975   EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
976   StartPlayout();
977   event()->Wait(kTestTimeOut);
978   EXPECT_TRUE(audio_device()->Playing());
979   // Restart playout but without stopping the internal audio thread.
980   // This procedure uses a non-public test API and it emulates what happens
981   // inside the ADM when e.g. a device is removed.
982   EXPECT_EQ(0, audio_device()->RestartPlayoutInternally());
983 
984   // Run basic tests of public APIs while a restart attempt is active.
985   // These calls should now be very thin and not trigger any new actions.
986   EXPECT_EQ(-1, audio_device()->StopPlayout());
987   EXPECT_TRUE(audio_device()->Playing());
988   EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
989   EXPECT_EQ(0, audio_device()->InitPlayout());
990   EXPECT_EQ(0, audio_device()->StartPlayout());
991 
992   // Wait until audio has restarted and a new sequence of audio callbacks
993   // becomes active.
994   // TODO(henrika): is it possible to verify that the internal state transition
995   // is Stop->Init->Start?
996   ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock));
997   mock.ResetCallbackCounters();
998   EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
999       .Times(AtLeast(kNumCallbacks));
1000   event()->Wait(kTestTimeOut);
1001   EXPECT_TRUE(audio_device()->Playing());
1002   // Stop playout and the audio thread after successful internal restart.
1003   StopPlayout();
1004   PreTearDown();
1005 }
1006 
1007 // Tests Start/Stop recording followed by a second session (emulates a restart
1008 // triggered by an internal callback e.g. corresponding to a device switch).
1009 // Note that, internal restart is only supported in combination with the latest
1010 // Windows ADM.
TEST_P(MAYBE_AudioDeviceTest,StartStopRecordingWithInternalRestart)1011 TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithInternalRestart) {
1012   SKIP_TEST_IF_NOT(requirements_satisfied());
1013   if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
1014     return;
1015   }
1016   MockAudioTransport mock(TransportType::kRecord);
1017   mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
1018   EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1019                                             false, _))
1020       .Times(AtLeast(kNumCallbacks));
1021   EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1022   StartRecording();
1023   event()->Wait(kTestTimeOut);
1024   EXPECT_TRUE(audio_device()->Recording());
1025   // Restart recording but without stopping the internal audio thread.
1026   // This procedure uses a non-public test API and it emulates what happens
1027   // inside the ADM when e.g. a device is removed.
1028   EXPECT_EQ(0, audio_device()->RestartRecordingInternally());
1029 
1030   // Run basic tests of public APIs while a restart attempt is active.
1031   // These calls should now be very thin and not trigger any new actions.
1032   EXPECT_EQ(-1, audio_device()->StopRecording());
1033   EXPECT_TRUE(audio_device()->Recording());
1034   EXPECT_TRUE(audio_device()->RecordingIsInitialized());
1035   EXPECT_EQ(0, audio_device()->InitRecording());
1036   EXPECT_EQ(0, audio_device()->StartRecording());
1037 
1038   // Wait until audio has restarted and a new sequence of audio callbacks
1039   // becomes active.
1040   // TODO(henrika): is it possible to verify that the internal state transition
1041   // is Stop->Init->Start?
1042   ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock));
1043   mock.ResetCallbackCounters();
1044   EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1045                                             false, _))
1046       .Times(AtLeast(kNumCallbacks));
1047   event()->Wait(kTestTimeOut);
1048   EXPECT_TRUE(audio_device()->Recording());
1049   // Stop recording and the audio thread after successful internal restart.
1050   StopRecording();
1051   PreTearDown();
1052 }
1053 #endif  // #ifdef WEBRTC_WIN
1054 
1055 // Start playout and verify that the native audio layer starts asking for real
1056 // audio samples to play out using the NeedMorePlayData() callback.
1057 // Note that we can't add expectations on audio parameters in EXPECT_CALL
1058 // since parameter are not provided in the each callback. We therefore test and
1059 // verify the parameters in the fake audio transport implementation instead.
TEST_P(MAYBE_AudioDeviceTest,StartPlayoutVerifyCallbacks)1060 TEST_P(MAYBE_AudioDeviceTest, StartPlayoutVerifyCallbacks) {
1061   SKIP_TEST_IF_NOT(requirements_satisfied());
1062   MockAudioTransport mock(TransportType::kPlay);
1063   mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
1064   EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1065       .Times(AtLeast(kNumCallbacks));
1066   EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1067   StartPlayout();
1068   event()->Wait(kTestTimeOut);
1069   StopPlayout();
1070   PreTearDown();
1071 }
1072 
1073 // Don't run these tests in combination with sanitizers.
1074 // They are already flaky *without* sanitizers.
1075 // Sanitizers seem to increase flakiness (which brings noise),
1076 // without reporting anything.
1077 // TODO(webrtc:10867): Re-enable when flakiness fixed.
1078 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
1079     defined(THREAD_SANITIZER)
1080 #define MAYBE_StartRecordingVerifyCallbacks \
1081   DISABLED_StartRecordingVerifyCallbacks
1082 #define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \
1083   DISABLED_StartPlayoutAndRecordingVerifyCallbacks
1084 #else
1085 #define MAYBE_StartRecordingVerifyCallbacks StartRecordingVerifyCallbacks
1086 #define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \
1087   StartPlayoutAndRecordingVerifyCallbacks
1088 #endif
1089 
1090 // Start recording and verify that the native audio layer starts providing real
1091 // audio samples using the RecordedDataIsAvailable() callback.
TEST_P(MAYBE_AudioDeviceTest,MAYBE_StartRecordingVerifyCallbacks)1092 TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartRecordingVerifyCallbacks) {
1093   SKIP_TEST_IF_NOT(requirements_satisfied());
1094   MockAudioTransport mock(TransportType::kRecord);
1095   mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
1096   EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1097                                             false, _))
1098       .Times(AtLeast(kNumCallbacks));
1099   EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1100   StartRecording();
1101   event()->Wait(kTestTimeOut);
1102   StopRecording();
1103   PreTearDown();
1104 }
1105 
1106 // Start playout and recording (full-duplex audio) and verify that audio is
1107 // active in both directions.
TEST_P(MAYBE_AudioDeviceTest,MAYBE_StartPlayoutAndRecordingVerifyCallbacks)1108 TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartPlayoutAndRecordingVerifyCallbacks) {
1109   SKIP_TEST_IF_NOT(requirements_satisfied());
1110   MockAudioTransport mock(TransportType::kPlayAndRecord);
1111   mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
1112   EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1113       .Times(AtLeast(kNumCallbacks));
1114   EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1115                                             false, _))
1116       .Times(AtLeast(kNumCallbacks));
1117   EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1118   StartPlayout();
1119   StartRecording();
1120   event()->Wait(kTestTimeOut);
1121   StopRecording();
1122   StopPlayout();
1123   PreTearDown();
1124 }
1125 
1126 // Start playout and recording and store recorded data in an intermediate FIFO
1127 // buffer from which the playout side then reads its samples in the same order
1128 // as they were stored. Under ideal circumstances, a callback sequence would
1129 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-'
1130 // means 'packet played'. Under such conditions, the FIFO would contain max 1,
1131 // with an average somewhere in (0,1) depending on how long the packets are
1132 // buffered. However, under more realistic conditions, the size
1133 // of the FIFO will vary more due to an unbalance between the two sides.
1134 // This test tries to verify that the device maintains a balanced callback-
1135 // sequence by running in loopback for a few seconds while measuring the size
1136 // (max and average) of the FIFO. The size of the FIFO is increased by the
1137 // recording side and decreased by the playout side.
TEST_P(MAYBE_AudioDeviceTest,RunPlayoutAndRecordingInFullDuplex)1138 TEST_P(MAYBE_AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) {
1139   SKIP_TEST_IF_NOT(requirements_satisfied());
1140   NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1141   FifoAudioStream audio_stream;
1142   mock.HandleCallbacks(event(), &audio_stream,
1143                        kFullDuplexTime.seconds() * kNumCallbacksPerSecond);
1144   EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1145   // Run both sides using the same channel configuration to avoid conversions
1146   // between mono/stereo while running in full duplex mode. Also, some devices
1147   // (mainly on Windows) do not support mono.
1148   EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1149   EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
1150   // Mute speakers to prevent howling.
1151   EXPECT_EQ(0, audio_device()->SetSpeakerVolume(0));
1152   StartPlayout();
1153   StartRecording();
1154   event()->Wait(std::max(kTestTimeOut, kFullDuplexTime));
1155   StopRecording();
1156   StopPlayout();
1157   PreTearDown();
1158 }
1159 
1160 // Runs audio in full duplex until user hits Enter. Intended as a manual test
1161 // to ensure that the audio quality is good and that real device switches works
1162 // as intended.
TEST_P(MAYBE_AudioDeviceTest,DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey)1163 TEST_P(MAYBE_AudioDeviceTest,
1164        DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey) {
1165   SKIP_TEST_IF_NOT(requirements_satisfied());
1166   if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
1167     return;
1168   }
1169   NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1170   FifoAudioStream audio_stream;
1171   mock.HandleCallbacks(&audio_stream);
1172   EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1173   EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1174   EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
1175   // Ensure that the sample rate for both directions are identical so that we
1176   // always can listen to our own voice. Will lead to rate conversion (and
1177   // higher latency) if the native sample rate is not 48kHz.
1178   EXPECT_EQ(0, audio_device()->SetPlayoutSampleRate(48000));
1179   EXPECT_EQ(0, audio_device()->SetRecordingSampleRate(48000));
1180   StartPlayout();
1181   StartRecording();
1182   do {
1183     PRINT("Loopback audio is active at 48kHz. Press Enter to stop.\n");
1184   } while (getchar() != '\n');
1185   StopRecording();
1186   StopPlayout();
1187   PreTearDown();
1188 }
1189 
1190 // Measures loopback latency and reports the min, max and average values for
1191 // a full duplex audio session.
1192 // The latency is measured like so:
1193 // - Insert impulses periodically on the output side.
1194 // - Detect the impulses on the input side.
1195 // - Measure the time difference between the transmit time and receive time.
1196 // - Store time differences in a vector and calculate min, max and average.
1197 // This test needs the '--gtest_also_run_disabled_tests' flag to run and also
1198 // some sort of audio feedback loop. E.g. a headset where the mic is placed
1199 // close to the speaker to ensure highest possible echo. It is also recommended
1200 // to run the test at highest possible output volume.
TEST_P(MAYBE_AudioDeviceTest,DISABLED_MeasureLoopbackLatency)1201 TEST_P(MAYBE_AudioDeviceTest, DISABLED_MeasureLoopbackLatency) {
1202   SKIP_TEST_IF_NOT(requirements_satisfied());
1203   NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1204   LatencyAudioStream audio_stream;
1205   mock.HandleCallbacks(event(), &audio_stream,
1206                        kMeasureLatencyTime.seconds() * kNumCallbacksPerSecond);
1207   EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1208   EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1209   EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
1210   StartPlayout();
1211   StartRecording();
1212   event()->Wait(std::max(kTestTimeOut, kMeasureLatencyTime));
1213   StopRecording();
1214   StopPlayout();
1215   // Avoid concurrent access to audio_stream.
1216   PreTearDown();
1217   // Verify that a sufficient number of transmitted impulses are detected.
1218   EXPECT_GE(audio_stream.num_latency_values(),
1219             static_cast<size_t>(
1220                 kImpulseFrequencyInHz * kMeasureLatencyTime.seconds() - 2));
1221   // Print out min, max and average delay values for debugging purposes.
1222   audio_stream.PrintResults();
1223 }
1224 
1225 #ifdef WEBRTC_WIN
1226 // Test two different audio layers (or rather two different Core Audio
1227 // implementations) for Windows.
1228 INSTANTIATE_TEST_SUITE_P(
1229     AudioLayerWin,
1230     MAYBE_AudioDeviceTest,
1231     ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio,
1232                       AudioDeviceModule::kWindowsCoreAudio2));
1233 #else
1234 // For all platforms but Windows, only test the default audio layer.
1235 INSTANTIATE_TEST_SUITE_P(
1236     AudioLayer,
1237     MAYBE_AudioDeviceTest,
1238     ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio));
1239 #endif
1240 
1241 }  // namespace webrtc
1242