1 /*
2  *  Copyright (c) 2018 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 "sdk/android/src/jni/audio_device/audio_device_module.h"
12 
13 #include <memory>
14 #include <utility>
15 
16 #include "api/sequence_checker.h"
17 #include "api/task_queue/default_task_queue_factory.h"
18 #include "api/task_queue/task_queue_factory.h"
19 #include "modules/audio_device/audio_device_buffer.h"
20 #include "rtc_base/checks.h"
21 #include "rtc_base/logging.h"
22 #include "rtc_base/ref_counted_object.h"
23 #include "sdk/android/generated_audio_device_module_base_jni/WebRtcAudioManager_jni.h"
24 #include "system_wrappers/include/metrics.h"
25 
26 namespace webrtc {
27 namespace jni {
28 
29 namespace {
30 
31 // This class combines a generic instance of an AudioInput and a generic
32 // instance of an AudioOutput to create an AudioDeviceModule. This is mostly
33 // done by delegating to the audio input/output with some glue code. This class
34 // also directly implements some of the AudioDeviceModule methods with dummy
35 // implementations.
36 //
37 // An instance can be created on any thread, but must then be used on one and
38 // the same thread. All public methods must also be called on the same thread.
39 // A thread checker will RTC_DCHECK if any method is called on an invalid
40 // thread.
41 // TODO(henrika): it might be useful to also support a scenario where the ADM
42 // is constructed on thread T1, used on thread T2 and destructed on T2 or T3.
43 // If so, care must be taken to ensure that only T2 is a COM thread.
44 class AndroidAudioDeviceModule : public AudioDeviceModule {
45  public:
46   // For use with UMA logging. Must be kept in sync with histograms.xml in
47   // Chrome, located at
48   // https://cs.chromium.org/chromium/src/tools/metrics/histograms/histograms.xml
49   enum class InitStatus {
50     OK = 0,
51     PLAYOUT_ERROR = 1,
52     RECORDING_ERROR = 2,
53     OTHER_ERROR = 3,
54     NUM_STATUSES = 4
55   };
56 
AndroidAudioDeviceModule(AudioDeviceModule::AudioLayer audio_layer,bool is_stereo_playout_supported,bool is_stereo_record_supported,uint16_t playout_delay_ms,std::unique_ptr<AudioInput> audio_input,std::unique_ptr<AudioOutput> audio_output)57   AndroidAudioDeviceModule(AudioDeviceModule::AudioLayer audio_layer,
58                            bool is_stereo_playout_supported,
59                            bool is_stereo_record_supported,
60                            uint16_t playout_delay_ms,
61                            std::unique_ptr<AudioInput> audio_input,
62                            std::unique_ptr<AudioOutput> audio_output)
63       : audio_layer_(audio_layer),
64         is_stereo_playout_supported_(is_stereo_playout_supported),
65         is_stereo_record_supported_(is_stereo_record_supported),
66         playout_delay_ms_(playout_delay_ms),
67         task_queue_factory_(CreateDefaultTaskQueueFactory()),
68         input_(std::move(audio_input)),
69         output_(std::move(audio_output)),
70         initialized_(false) {
71     RTC_CHECK(input_);
72     RTC_CHECK(output_);
73     RTC_DLOG(INFO) << __FUNCTION__;
74     thread_checker_.Detach();
75   }
76 
~AndroidAudioDeviceModule()77   ~AndroidAudioDeviceModule() override { RTC_DLOG(INFO) << __FUNCTION__; }
78 
ActiveAudioLayer(AudioDeviceModule::AudioLayer * audioLayer) const79   int32_t ActiveAudioLayer(
80       AudioDeviceModule::AudioLayer* audioLayer) const override {
81     RTC_DLOG(INFO) << __FUNCTION__;
82     *audioLayer = audio_layer_;
83     return 0;
84   }
85 
RegisterAudioCallback(AudioTransport * audioCallback)86   int32_t RegisterAudioCallback(AudioTransport* audioCallback) override {
87     RTC_DLOG(INFO) << __FUNCTION__;
88     return audio_device_buffer_->RegisterAudioCallback(audioCallback);
89   }
90 
Init()91   int32_t Init() override {
92     RTC_DLOG(INFO) << __FUNCTION__;
93     RTC_DCHECK(thread_checker_.IsCurrent());
94     audio_device_buffer_ =
95         std::make_unique<AudioDeviceBuffer>(task_queue_factory_.get());
96     AttachAudioBuffer();
97     if (initialized_) {
98       return 0;
99     }
100     InitStatus status;
101     if (output_->Init() != 0) {
102       status = InitStatus::PLAYOUT_ERROR;
103     } else if (input_->Init() != 0) {
104       output_->Terminate();
105       status = InitStatus::RECORDING_ERROR;
106     } else {
107       initialized_ = true;
108       status = InitStatus::OK;
109     }
110     RTC_HISTOGRAM_ENUMERATION("WebRTC.Audio.InitializationResult",
111                               static_cast<int>(status),
112                               static_cast<int>(InitStatus::NUM_STATUSES));
113     if (status != InitStatus::OK) {
114       RTC_LOG(LS_ERROR) << "Audio device initialization failed.";
115       return -1;
116     }
117     return 0;
118   }
119 
Terminate()120   int32_t Terminate() override {
121     RTC_DLOG(INFO) << __FUNCTION__;
122     if (!initialized_)
123       return 0;
124     RTC_DCHECK(thread_checker_.IsCurrent());
125     int32_t err = input_->Terminate();
126     err |= output_->Terminate();
127     initialized_ = false;
128     thread_checker_.Detach();
129     audio_device_buffer_.reset(nullptr);
130     RTC_DCHECK_EQ(err, 0);
131     return err;
132   }
133 
Initialized() const134   bool Initialized() const override {
135     RTC_DLOG(INFO) << __FUNCTION__ << ":" << initialized_;
136     return initialized_;
137   }
138 
PlayoutDevices()139   int16_t PlayoutDevices() override {
140     RTC_DLOG(INFO) << __FUNCTION__;
141     RTC_LOG(INFO) << "output: " << 1;
142     return 1;
143   }
144 
RecordingDevices()145   int16_t RecordingDevices() override {
146     RTC_DLOG(INFO) << __FUNCTION__;
147     RTC_DLOG(INFO) << "output: " << 1;
148     return 1;
149   }
150 
PlayoutDeviceName(uint16_t index,char name[kAdmMaxDeviceNameSize],char guid[kAdmMaxGuidSize])151   int32_t PlayoutDeviceName(uint16_t index,
152                             char name[kAdmMaxDeviceNameSize],
153                             char guid[kAdmMaxGuidSize]) override {
154     RTC_CHECK_NOTREACHED();
155   }
156 
RecordingDeviceName(uint16_t index,char name[kAdmMaxDeviceNameSize],char guid[kAdmMaxGuidSize])157   int32_t RecordingDeviceName(uint16_t index,
158                               char name[kAdmMaxDeviceNameSize],
159                               char guid[kAdmMaxGuidSize]) override {
160     RTC_CHECK_NOTREACHED();
161   }
162 
SetPlayoutDevice(uint16_t index)163   int32_t SetPlayoutDevice(uint16_t index) override {
164     // OK to use but it has no effect currently since device selection is
165     // done using Andoid APIs instead.
166     RTC_DLOG(INFO) << __FUNCTION__ << "(" << index << ")";
167     return 0;
168   }
169 
SetPlayoutDevice(AudioDeviceModule::WindowsDeviceType device)170   int32_t SetPlayoutDevice(
171       AudioDeviceModule::WindowsDeviceType device) override {
172     RTC_CHECK_NOTREACHED();
173   }
174 
SetRecordingDevice(uint16_t index)175   int32_t SetRecordingDevice(uint16_t index) override {
176     // OK to use but it has no effect currently since device selection is
177     // done using Andoid APIs instead.
178     RTC_DLOG(INFO) << __FUNCTION__ << "(" << index << ")";
179     return 0;
180   }
181 
SetRecordingDevice(AudioDeviceModule::WindowsDeviceType device)182   int32_t SetRecordingDevice(
183       AudioDeviceModule::WindowsDeviceType device) override {
184     RTC_CHECK_NOTREACHED();
185   }
186 
PlayoutIsAvailable(bool * available)187   int32_t PlayoutIsAvailable(bool* available) override {
188     RTC_DLOG(INFO) << __FUNCTION__;
189     *available = true;
190     RTC_DLOG(INFO) << "output: " << *available;
191     return 0;
192   }
193 
InitPlayout()194   int32_t InitPlayout() override {
195     RTC_DLOG(INFO) << __FUNCTION__;
196     if (!initialized_)
197       return -1;
198     if (PlayoutIsInitialized()) {
199       return 0;
200     }
201     int32_t result = output_->InitPlayout();
202     RTC_DLOG(INFO) << "output: " << result;
203     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitPlayoutSuccess",
204                           static_cast<int>(result == 0));
205     return result;
206   }
207 
PlayoutIsInitialized() const208   bool PlayoutIsInitialized() const override {
209     RTC_DLOG(INFO) << __FUNCTION__;
210     return output_->PlayoutIsInitialized();
211   }
212 
RecordingIsAvailable(bool * available)213   int32_t RecordingIsAvailable(bool* available) override {
214     RTC_DLOG(INFO) << __FUNCTION__;
215     *available = true;
216     RTC_DLOG(INFO) << "output: " << *available;
217     return 0;
218   }
219 
InitRecording()220   int32_t InitRecording() override {
221     RTC_DLOG(INFO) << __FUNCTION__;
222     if (!initialized_)
223       return -1;
224     if (RecordingIsInitialized()) {
225       return 0;
226     }
227     int32_t result = input_->InitRecording();
228     RTC_DLOG(INFO) << "output: " << result;
229     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitRecordingSuccess",
230                           static_cast<int>(result == 0));
231     return result;
232   }
233 
RecordingIsInitialized() const234   bool RecordingIsInitialized() const override {
235     RTC_DLOG(INFO) << __FUNCTION__;
236     return input_->RecordingIsInitialized();
237   }
238 
StartPlayout()239   int32_t StartPlayout() override {
240     RTC_DLOG(INFO) << __FUNCTION__;
241     if (!initialized_)
242       return -1;
243     if (Playing()) {
244       return 0;
245     }
246     int32_t result = output_->StartPlayout();
247     RTC_DLOG(INFO) << "output: " << result;
248     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartPlayoutSuccess",
249                           static_cast<int>(result == 0));
250     if (result == 0) {
251       // Only start playing the audio device buffer if starting the audio
252       // output succeeded.
253       audio_device_buffer_->StartPlayout();
254     }
255     return result;
256   }
257 
StopPlayout()258   int32_t StopPlayout() override {
259     RTC_DLOG(INFO) << __FUNCTION__;
260     if (!initialized_)
261       return -1;
262     if (!Playing())
263       return 0;
264     RTC_LOG(INFO) << __FUNCTION__;
265     audio_device_buffer_->StopPlayout();
266     int32_t result = output_->StopPlayout();
267     RTC_DLOG(INFO) << "output: " << result;
268     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopPlayoutSuccess",
269                           static_cast<int>(result == 0));
270     return result;
271   }
272 
Playing() const273   bool Playing() const override {
274     RTC_DLOG(INFO) << __FUNCTION__;
275     return output_->Playing();
276   }
277 
StartRecording()278   int32_t StartRecording() override {
279     RTC_DLOG(INFO) << __FUNCTION__;
280     if (!initialized_)
281       return -1;
282     if (Recording()) {
283       return 0;
284     }
285     int32_t result = input_->StartRecording();
286     RTC_DLOG(INFO) << "output: " << result;
287     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartRecordingSuccess",
288                           static_cast<int>(result == 0));
289     if (result == 0) {
290       // Only start recording the audio device buffer if starting the audio
291       // input succeeded.
292       audio_device_buffer_->StartRecording();
293     }
294     return result;
295   }
296 
StopRecording()297   int32_t StopRecording() override {
298     RTC_DLOG(INFO) << __FUNCTION__;
299     if (!initialized_)
300       return -1;
301     if (!Recording())
302       return 0;
303     audio_device_buffer_->StopRecording();
304     int32_t result = input_->StopRecording();
305     RTC_DLOG(INFO) << "output: " << result;
306     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopRecordingSuccess",
307                           static_cast<int>(result == 0));
308     return result;
309   }
310 
Recording() const311   bool Recording() const override {
312     RTC_DLOG(INFO) << __FUNCTION__;
313     return input_->Recording();
314   }
315 
InitSpeaker()316   int32_t InitSpeaker() override {
317     RTC_DLOG(INFO) << __FUNCTION__;
318     return initialized_ ? 0 : -1;
319   }
320 
SpeakerIsInitialized() const321   bool SpeakerIsInitialized() const override {
322     RTC_DLOG(INFO) << __FUNCTION__;
323     return initialized_;
324   }
325 
InitMicrophone()326   int32_t InitMicrophone() override {
327     RTC_DLOG(INFO) << __FUNCTION__;
328     return initialized_ ? 0 : -1;
329   }
330 
MicrophoneIsInitialized() const331   bool MicrophoneIsInitialized() const override {
332     RTC_DLOG(INFO) << __FUNCTION__;
333     return initialized_;
334   }
335 
SpeakerVolumeIsAvailable(bool * available)336   int32_t SpeakerVolumeIsAvailable(bool* available) override {
337     RTC_DLOG(INFO) << __FUNCTION__;
338     if (!initialized_)
339       return -1;
340     *available = output_->SpeakerVolumeIsAvailable();
341     RTC_DLOG(INFO) << "output: " << *available;
342     return 0;
343   }
344 
SetSpeakerVolume(uint32_t volume)345   int32_t SetSpeakerVolume(uint32_t volume) override {
346     RTC_DLOG(INFO) << __FUNCTION__;
347     if (!initialized_)
348       return -1;
349     return output_->SetSpeakerVolume(volume);
350   }
351 
SpeakerVolume(uint32_t * output_volume) const352   int32_t SpeakerVolume(uint32_t* output_volume) const override {
353     RTC_DLOG(INFO) << __FUNCTION__;
354     if (!initialized_)
355       return -1;
356     absl::optional<uint32_t> volume = output_->SpeakerVolume();
357     if (!volume)
358       return -1;
359     *output_volume = *volume;
360     RTC_DLOG(INFO) << "output: " << *volume;
361     return 0;
362   }
363 
MaxSpeakerVolume(uint32_t * output_max_volume) const364   int32_t MaxSpeakerVolume(uint32_t* output_max_volume) const override {
365     RTC_DLOG(INFO) << __FUNCTION__;
366     if (!initialized_)
367       return -1;
368     absl::optional<uint32_t> max_volume = output_->MaxSpeakerVolume();
369     if (!max_volume)
370       return -1;
371     *output_max_volume = *max_volume;
372     return 0;
373   }
374 
MinSpeakerVolume(uint32_t * output_min_volume) const375   int32_t MinSpeakerVolume(uint32_t* output_min_volume) const override {
376     RTC_DLOG(INFO) << __FUNCTION__;
377     if (!initialized_)
378       return -1;
379     absl::optional<uint32_t> min_volume = output_->MinSpeakerVolume();
380     if (!min_volume)
381       return -1;
382     *output_min_volume = *min_volume;
383     return 0;
384   }
385 
MicrophoneVolumeIsAvailable(bool * available)386   int32_t MicrophoneVolumeIsAvailable(bool* available) override {
387     RTC_DLOG(INFO) << __FUNCTION__;
388     *available = false;
389     RTC_DLOG(INFO) << "output: " << *available;
390     return -1;
391   }
392 
SetMicrophoneVolume(uint32_t volume)393   int32_t SetMicrophoneVolume(uint32_t volume) override {
394     RTC_DLOG(INFO) << __FUNCTION__ << "(" << volume << ")";
395     RTC_CHECK_NOTREACHED();
396   }
397 
MicrophoneVolume(uint32_t * volume) const398   int32_t MicrophoneVolume(uint32_t* volume) const override {
399     RTC_DLOG(INFO) << __FUNCTION__;
400     RTC_CHECK_NOTREACHED();
401   }
402 
MaxMicrophoneVolume(uint32_t * maxVolume) const403   int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override {
404     RTC_DLOG(INFO) << __FUNCTION__;
405     RTC_CHECK_NOTREACHED();
406   }
407 
MinMicrophoneVolume(uint32_t * minVolume) const408   int32_t MinMicrophoneVolume(uint32_t* minVolume) const override {
409     RTC_DLOG(INFO) << __FUNCTION__;
410     RTC_CHECK_NOTREACHED();
411   }
412 
SpeakerMuteIsAvailable(bool * available)413   int32_t SpeakerMuteIsAvailable(bool* available) override {
414     RTC_DLOG(INFO) << __FUNCTION__;
415     RTC_CHECK_NOTREACHED();
416   }
417 
SetSpeakerMute(bool enable)418   int32_t SetSpeakerMute(bool enable) override {
419     RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
420     RTC_CHECK_NOTREACHED();
421   }
422 
SpeakerMute(bool * enabled) const423   int32_t SpeakerMute(bool* enabled) const override {
424     RTC_DLOG(INFO) << __FUNCTION__;
425     RTC_CHECK_NOTREACHED();
426   }
427 
MicrophoneMuteIsAvailable(bool * available)428   int32_t MicrophoneMuteIsAvailable(bool* available) override {
429     RTC_DLOG(INFO) << __FUNCTION__;
430     RTC_CHECK_NOTREACHED();
431   }
432 
SetMicrophoneMute(bool enable)433   int32_t SetMicrophoneMute(bool enable) override {
434     RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
435     RTC_CHECK_NOTREACHED();
436   }
437 
MicrophoneMute(bool * enabled) const438   int32_t MicrophoneMute(bool* enabled) const override {
439     RTC_DLOG(INFO) << __FUNCTION__;
440     RTC_CHECK_NOTREACHED();
441   }
442 
StereoPlayoutIsAvailable(bool * available) const443   int32_t StereoPlayoutIsAvailable(bool* available) const override {
444     RTC_DLOG(INFO) << __FUNCTION__;
445     *available = is_stereo_playout_supported_;
446     RTC_DLOG(INFO) << "output: " << *available;
447     return 0;
448   }
449 
SetStereoPlayout(bool enable)450   int32_t SetStereoPlayout(bool enable) override {
451     RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
452     // Android does not support changes between mono and stero on the fly. The
453     // use of stereo or mono is determined by the audio layer. It is allowed
454     // to call this method if that same state is not modified.
455     bool available = is_stereo_playout_supported_;
456     if (enable != available) {
457       RTC_LOG(WARNING) << "changing stereo playout not supported";
458       return -1;
459     }
460     return 0;
461   }
462 
StereoPlayout(bool * enabled) const463   int32_t StereoPlayout(bool* enabled) const override {
464     RTC_DLOG(INFO) << __FUNCTION__;
465     *enabled = is_stereo_playout_supported_;
466     RTC_DLOG(INFO) << "output: " << *enabled;
467     return 0;
468   }
469 
StereoRecordingIsAvailable(bool * available) const470   int32_t StereoRecordingIsAvailable(bool* available) const override {
471     RTC_DLOG(INFO) << __FUNCTION__;
472     *available = is_stereo_record_supported_;
473     RTC_DLOG(INFO) << "output: " << *available;
474     return 0;
475   }
476 
SetStereoRecording(bool enable)477   int32_t SetStereoRecording(bool enable) override {
478     RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
479     // Android does not support changes between mono and stero on the fly. The
480     // use of stereo or mono is determined by the audio layer. It is allowed
481     // to call this method if that same state is not modified.
482     bool available = is_stereo_record_supported_;
483     if (enable != available) {
484       RTC_LOG(WARNING) << "changing stereo recording not supported";
485       return -1;
486     }
487     return 0;
488   }
489 
StereoRecording(bool * enabled) const490   int32_t StereoRecording(bool* enabled) const override {
491     RTC_DLOG(INFO) << __FUNCTION__;
492     *enabled = is_stereo_record_supported_;
493     RTC_DLOG(INFO) << "output: " << *enabled;
494     return 0;
495   }
496 
PlayoutDelay(uint16_t * delay_ms) const497   int32_t PlayoutDelay(uint16_t* delay_ms) const override {
498     // Best guess we can do is to use half of the estimated total delay.
499     *delay_ms = playout_delay_ms_ / 2;
500     RTC_DCHECK_GT(*delay_ms, 0);
501     return 0;
502   }
503 
504   // Returns true if the device both supports built in AEC and the device
505   // is not blocklisted.
506   // Currently, if OpenSL ES is used in both directions, this method will still
507   // report the correct value and it has the correct effect. As an example:
508   // a device supports built in AEC and this method returns true. Libjingle
509   // will then disable the WebRTC based AEC and that will work for all devices
510   // (mainly Nexus) even when OpenSL ES is used for input since our current
511   // implementation will enable built-in AEC by default also for OpenSL ES.
512   // The only "bad" thing that happens today is that when Libjingle calls
513   // OpenSLESRecorder::EnableBuiltInAEC() it will not have any real effect and
514   // a "Not Implemented" log will be filed. This non-perfect state will remain
515   // until I have added full support for audio effects based on OpenSL ES APIs.
BuiltInAECIsAvailable() const516   bool BuiltInAECIsAvailable() const override {
517     RTC_DLOG(INFO) << __FUNCTION__;
518     if (!initialized_)
519       return false;
520     bool isAvailable = input_->IsAcousticEchoCancelerSupported();
521     RTC_DLOG(INFO) << "output: " << isAvailable;
522     return isAvailable;
523   }
524 
525   // Not implemented for any input device on Android.
BuiltInAGCIsAvailable() const526   bool BuiltInAGCIsAvailable() const override {
527     RTC_DLOG(INFO) << __FUNCTION__;
528     RTC_DLOG(INFO) << "output: " << false;
529     return false;
530   }
531 
532   // Returns true if the device both supports built in NS and the device
533   // is not blocklisted.
534   // TODO(henrika): add implementation for OpenSL ES based audio as well.
535   // In addition, see comments for BuiltInAECIsAvailable().
BuiltInNSIsAvailable() const536   bool BuiltInNSIsAvailable() const override {
537     RTC_DLOG(INFO) << __FUNCTION__;
538     if (!initialized_)
539       return false;
540     bool isAvailable = input_->IsNoiseSuppressorSupported();
541     RTC_DLOG(INFO) << "output: " << isAvailable;
542     return isAvailable;
543   }
544 
545   // TODO(henrika): add implementation for OpenSL ES based audio as well.
EnableBuiltInAEC(bool enable)546   int32_t EnableBuiltInAEC(bool enable) override {
547     RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
548     if (!initialized_)
549       return -1;
550     RTC_CHECK(BuiltInAECIsAvailable()) << "HW AEC is not available";
551     int32_t result = input_->EnableBuiltInAEC(enable);
552     RTC_DLOG(INFO) << "output: " << result;
553     return result;
554   }
555 
EnableBuiltInAGC(bool enable)556   int32_t EnableBuiltInAGC(bool enable) override {
557     RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
558     RTC_CHECK_NOTREACHED();
559   }
560 
561   // TODO(henrika): add implementation for OpenSL ES based audio as well.
EnableBuiltInNS(bool enable)562   int32_t EnableBuiltInNS(bool enable) override {
563     RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
564     if (!initialized_)
565       return -1;
566     RTC_CHECK(BuiltInNSIsAvailable()) << "HW NS is not available";
567     int32_t result = input_->EnableBuiltInNS(enable);
568     RTC_DLOG(INFO) << "output: " << result;
569     return result;
570   }
571 
GetPlayoutUnderrunCount() const572   int32_t GetPlayoutUnderrunCount() const override {
573     if (!initialized_)
574       return -1;
575     return output_->GetPlayoutUnderrunCount();
576   }
577 
AttachAudioBuffer()578   int32_t AttachAudioBuffer() {
579     RTC_DLOG(INFO) << __FUNCTION__;
580     output_->AttachAudioBuffer(audio_device_buffer_.get());
581     input_->AttachAudioBuffer(audio_device_buffer_.get());
582     return 0;
583   }
584 
585  private:
586   SequenceChecker thread_checker_;
587 
588   const AudioDeviceModule::AudioLayer audio_layer_;
589   const bool is_stereo_playout_supported_;
590   const bool is_stereo_record_supported_;
591   const uint16_t playout_delay_ms_;
592   const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
593   const std::unique_ptr<AudioInput> input_;
594   const std::unique_ptr<AudioOutput> output_;
595   std::unique_ptr<AudioDeviceBuffer> audio_device_buffer_;
596 
597   bool initialized_;
598 };
599 
600 }  // namespace
601 
GetAudioManager(JNIEnv * env,const JavaRef<jobject> & j_context)602 ScopedJavaLocalRef<jobject> GetAudioManager(JNIEnv* env,
603                                             const JavaRef<jobject>& j_context) {
604   return Java_WebRtcAudioManager_getAudioManager(env, j_context);
605 }
606 
GetDefaultSampleRate(JNIEnv * env,const JavaRef<jobject> & j_audio_manager)607 int GetDefaultSampleRate(JNIEnv* env, const JavaRef<jobject>& j_audio_manager) {
608   return Java_WebRtcAudioManager_getSampleRate(env, j_audio_manager);
609 }
610 
GetAudioParameters(JNIEnv * env,const JavaRef<jobject> & j_context,const JavaRef<jobject> & j_audio_manager,int input_sample_rate,int output_sample_rate,bool use_stereo_input,bool use_stereo_output,AudioParameters * input_parameters,AudioParameters * output_parameters)611 void GetAudioParameters(JNIEnv* env,
612                         const JavaRef<jobject>& j_context,
613                         const JavaRef<jobject>& j_audio_manager,
614                         int input_sample_rate,
615                         int output_sample_rate,
616                         bool use_stereo_input,
617                         bool use_stereo_output,
618                         AudioParameters* input_parameters,
619                         AudioParameters* output_parameters) {
620   const int output_channels = use_stereo_output ? 2 : 1;
621   const int input_channels = use_stereo_input ? 2 : 1;
622   const size_t output_buffer_size = Java_WebRtcAudioManager_getOutputBufferSize(
623       env, j_context, j_audio_manager, output_sample_rate, output_channels);
624   const size_t input_buffer_size = Java_WebRtcAudioManager_getInputBufferSize(
625       env, j_context, j_audio_manager, input_sample_rate, input_channels);
626   output_parameters->reset(output_sample_rate,
627                            static_cast<size_t>(output_channels),
628                            static_cast<size_t>(output_buffer_size));
629   input_parameters->reset(input_sample_rate,
630                           static_cast<size_t>(input_channels),
631                           static_cast<size_t>(input_buffer_size));
632   RTC_CHECK(input_parameters->is_valid());
633   RTC_CHECK(output_parameters->is_valid());
634 }
635 
CreateAudioDeviceModuleFromInputAndOutput(AudioDeviceModule::AudioLayer audio_layer,bool is_stereo_playout_supported,bool is_stereo_record_supported,uint16_t playout_delay_ms,std::unique_ptr<AudioInput> audio_input,std::unique_ptr<AudioOutput> audio_output)636 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDeviceModuleFromInputAndOutput(
637     AudioDeviceModule::AudioLayer audio_layer,
638     bool is_stereo_playout_supported,
639     bool is_stereo_record_supported,
640     uint16_t playout_delay_ms,
641     std::unique_ptr<AudioInput> audio_input,
642     std::unique_ptr<AudioOutput> audio_output) {
643   RTC_DLOG(INFO) << __FUNCTION__;
644   return new rtc::RefCountedObject<AndroidAudioDeviceModule>(
645       audio_layer, is_stereo_playout_supported, is_stereo_record_supported,
646       playout_delay_ms, std::move(audio_input), std::move(audio_output));
647 }
648 
649 }  // namespace jni
650 }  // namespace webrtc
651