• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/task_queue/default_task_queue_factory.h"
17 #include "api/task_queue/task_queue_factory.h"
18 #include "modules/audio_device/audio_device_buffer.h"
19 #include "rtc_base/checks.h"
20 #include "rtc_base/logging.h"
21 #include "rtc_base/ref_counted_object.h"
22 #include "rtc_base/thread_checker.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_LOG(INFO) << __FUNCTION__;
74     thread_checker_.Detach();
75   }
76 
~AndroidAudioDeviceModule()77   ~AndroidAudioDeviceModule() override { RTC_LOG(INFO) << __FUNCTION__; }
78 
ActiveAudioLayer(AudioDeviceModule::AudioLayer * audioLayer) const79   int32_t ActiveAudioLayer(
80       AudioDeviceModule::AudioLayer* audioLayer) const override {
81     RTC_LOG(INFO) << __FUNCTION__;
82     *audioLayer = audio_layer_;
83     return 0;
84   }
85 
RegisterAudioCallback(AudioTransport * audioCallback)86   int32_t RegisterAudioCallback(AudioTransport* audioCallback) override {
87     RTC_LOG(INFO) << __FUNCTION__;
88     return audio_device_buffer_->RegisterAudioCallback(audioCallback);
89   }
90 
Init()91   int32_t Init() override {
92     RTC_LOG(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_LOG(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_LOG(INFO) << __FUNCTION__ << ":" << initialized_;
136     return initialized_;
137   }
138 
PlayoutDevices()139   int16_t PlayoutDevices() override {
140     RTC_LOG(INFO) << __FUNCTION__;
141     RTC_LOG(INFO) << "output: " << 1;
142     return 1;
143   }
144 
RecordingDevices()145   int16_t RecordingDevices() override {
146     RTC_LOG(INFO) << __FUNCTION__;
147     RTC_LOG(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     FATAL() << "Should never be called";
155     return -1;
156   }
157 
RecordingDeviceName(uint16_t index,char name[kAdmMaxDeviceNameSize],char guid[kAdmMaxGuidSize])158   int32_t RecordingDeviceName(uint16_t index,
159                               char name[kAdmMaxDeviceNameSize],
160                               char guid[kAdmMaxGuidSize]) override {
161     FATAL() << "Should never be called";
162     return -1;
163   }
164 
SetPlayoutDevice(uint16_t index)165   int32_t SetPlayoutDevice(uint16_t index) override {
166     // OK to use but it has no effect currently since device selection is
167     // done using Andoid APIs instead.
168     RTC_LOG(INFO) << __FUNCTION__ << "(" << index << ")";
169     return 0;
170   }
171 
SetPlayoutDevice(AudioDeviceModule::WindowsDeviceType device)172   int32_t SetPlayoutDevice(
173       AudioDeviceModule::WindowsDeviceType device) override {
174     FATAL() << "Should never be called";
175     return -1;
176   }
177 
SetRecordingDevice(uint16_t index)178   int32_t SetRecordingDevice(uint16_t index) override {
179     // OK to use but it has no effect currently since device selection is
180     // done using Andoid APIs instead.
181     RTC_LOG(INFO) << __FUNCTION__ << "(" << index << ")";
182     return 0;
183   }
184 
SetRecordingDevice(AudioDeviceModule::WindowsDeviceType device)185   int32_t SetRecordingDevice(
186       AudioDeviceModule::WindowsDeviceType device) override {
187     FATAL() << "Should never be called";
188     return -1;
189   }
190 
PlayoutIsAvailable(bool * available)191   int32_t PlayoutIsAvailable(bool* available) override {
192     RTC_LOG(INFO) << __FUNCTION__;
193     *available = true;
194     RTC_LOG(INFO) << "output: " << *available;
195     return 0;
196   }
197 
InitPlayout()198   int32_t InitPlayout() override {
199     RTC_LOG(INFO) << __FUNCTION__;
200     if (!initialized_)
201       return -1;
202     if (PlayoutIsInitialized()) {
203       return 0;
204     }
205     int32_t result = output_->InitPlayout();
206     RTC_LOG(INFO) << "output: " << result;
207     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitPlayoutSuccess",
208                           static_cast<int>(result == 0));
209     return result;
210   }
211 
PlayoutIsInitialized() const212   bool PlayoutIsInitialized() const override {
213     RTC_LOG(INFO) << __FUNCTION__;
214     return output_->PlayoutIsInitialized();
215   }
216 
RecordingIsAvailable(bool * available)217   int32_t RecordingIsAvailable(bool* available) override {
218     RTC_LOG(INFO) << __FUNCTION__;
219     *available = true;
220     RTC_LOG(INFO) << "output: " << *available;
221     return 0;
222   }
223 
InitRecording()224   int32_t InitRecording() override {
225     RTC_LOG(INFO) << __FUNCTION__;
226     if (!initialized_)
227       return -1;
228     if (RecordingIsInitialized()) {
229       return 0;
230     }
231     int32_t result = input_->InitRecording();
232     RTC_LOG(INFO) << "output: " << result;
233     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitRecordingSuccess",
234                           static_cast<int>(result == 0));
235     return result;
236   }
237 
RecordingIsInitialized() const238   bool RecordingIsInitialized() const override {
239     RTC_LOG(INFO) << __FUNCTION__;
240     return input_->RecordingIsInitialized();
241   }
242 
StartPlayout()243   int32_t StartPlayout() override {
244     RTC_LOG(INFO) << __FUNCTION__;
245     if (!initialized_)
246       return -1;
247     if (Playing()) {
248       return 0;
249     }
250     int32_t result = output_->StartPlayout();
251     RTC_LOG(INFO) << "output: " << result;
252     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartPlayoutSuccess",
253                           static_cast<int>(result == 0));
254     if (result == 0) {
255       // Only start playing the audio device buffer if starting the audio
256       // output succeeded.
257       audio_device_buffer_->StartPlayout();
258     }
259     return result;
260   }
261 
StopPlayout()262   int32_t StopPlayout() override {
263     RTC_LOG(INFO) << __FUNCTION__;
264     if (!initialized_)
265       return -1;
266     if (!Playing())
267       return 0;
268     RTC_LOG(INFO) << __FUNCTION__;
269     audio_device_buffer_->StopPlayout();
270     int32_t result = output_->StopPlayout();
271     RTC_LOG(INFO) << "output: " << result;
272     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopPlayoutSuccess",
273                           static_cast<int>(result == 0));
274     return result;
275   }
276 
Playing() const277   bool Playing() const override {
278     RTC_LOG(INFO) << __FUNCTION__;
279     return output_->Playing();
280   }
281 
StartRecording()282   int32_t StartRecording() override {
283     RTC_LOG(INFO) << __FUNCTION__;
284     if (!initialized_)
285       return -1;
286     if (Recording()) {
287       return 0;
288     }
289     int32_t result = input_->StartRecording();
290     RTC_LOG(INFO) << "output: " << result;
291     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartRecordingSuccess",
292                           static_cast<int>(result == 0));
293     if (result == 0) {
294       // Only start recording the audio device buffer if starting the audio
295       // input succeeded.
296       audio_device_buffer_->StartRecording();
297     }
298     return result;
299   }
300 
StopRecording()301   int32_t StopRecording() override {
302     RTC_LOG(INFO) << __FUNCTION__;
303     if (!initialized_)
304       return -1;
305     if (!Recording())
306       return 0;
307     audio_device_buffer_->StopRecording();
308     int32_t result = input_->StopRecording();
309     RTC_LOG(INFO) << "output: " << result;
310     RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopRecordingSuccess",
311                           static_cast<int>(result == 0));
312     return result;
313   }
314 
Recording() const315   bool Recording() const override {
316     RTC_LOG(INFO) << __FUNCTION__;
317     return input_->Recording();
318   }
319 
InitSpeaker()320   int32_t InitSpeaker() override {
321     RTC_LOG(INFO) << __FUNCTION__;
322     return initialized_ ? 0 : -1;
323   }
324 
SpeakerIsInitialized() const325   bool SpeakerIsInitialized() const override {
326     RTC_LOG(INFO) << __FUNCTION__;
327     return initialized_;
328   }
329 
InitMicrophone()330   int32_t InitMicrophone() override {
331     RTC_LOG(INFO) << __FUNCTION__;
332     return initialized_ ? 0 : -1;
333   }
334 
MicrophoneIsInitialized() const335   bool MicrophoneIsInitialized() const override {
336     RTC_LOG(INFO) << __FUNCTION__;
337     return initialized_;
338   }
339 
SpeakerVolumeIsAvailable(bool * available)340   int32_t SpeakerVolumeIsAvailable(bool* available) override {
341     RTC_LOG(INFO) << __FUNCTION__;
342     if (!initialized_)
343       return -1;
344     *available = output_->SpeakerVolumeIsAvailable();
345     RTC_LOG(INFO) << "output: " << *available;
346     return 0;
347   }
348 
SetSpeakerVolume(uint32_t volume)349   int32_t SetSpeakerVolume(uint32_t volume) override {
350     RTC_LOG(INFO) << __FUNCTION__;
351     if (!initialized_)
352       return -1;
353     return output_->SetSpeakerVolume(volume);
354   }
355 
SpeakerVolume(uint32_t * output_volume) const356   int32_t SpeakerVolume(uint32_t* output_volume) const override {
357     RTC_LOG(INFO) << __FUNCTION__;
358     if (!initialized_)
359       return -1;
360     absl::optional<uint32_t> volume = output_->SpeakerVolume();
361     if (!volume)
362       return -1;
363     *output_volume = *volume;
364     RTC_LOG(INFO) << "output: " << *volume;
365     return 0;
366   }
367 
MaxSpeakerVolume(uint32_t * output_max_volume) const368   int32_t MaxSpeakerVolume(uint32_t* output_max_volume) const override {
369     RTC_LOG(INFO) << __FUNCTION__;
370     if (!initialized_)
371       return -1;
372     absl::optional<uint32_t> max_volume = output_->MaxSpeakerVolume();
373     if (!max_volume)
374       return -1;
375     *output_max_volume = *max_volume;
376     return 0;
377   }
378 
MinSpeakerVolume(uint32_t * output_min_volume) const379   int32_t MinSpeakerVolume(uint32_t* output_min_volume) const override {
380     RTC_LOG(INFO) << __FUNCTION__;
381     if (!initialized_)
382       return -1;
383     absl::optional<uint32_t> min_volume = output_->MinSpeakerVolume();
384     if (!min_volume)
385       return -1;
386     *output_min_volume = *min_volume;
387     return 0;
388   }
389 
MicrophoneVolumeIsAvailable(bool * available)390   int32_t MicrophoneVolumeIsAvailable(bool* available) override {
391     RTC_LOG(INFO) << __FUNCTION__;
392     *available = false;
393     RTC_LOG(INFO) << "output: " << *available;
394     return -1;
395   }
396 
SetMicrophoneVolume(uint32_t volume)397   int32_t SetMicrophoneVolume(uint32_t volume) override {
398     RTC_LOG(INFO) << __FUNCTION__ << "(" << volume << ")";
399     FATAL() << "Should never be called";
400     return -1;
401   }
402 
MicrophoneVolume(uint32_t * volume) const403   int32_t MicrophoneVolume(uint32_t* volume) const override {
404     RTC_LOG(INFO) << __FUNCTION__;
405     FATAL() << "Should never be called";
406     return -1;
407   }
408 
MaxMicrophoneVolume(uint32_t * maxVolume) const409   int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override {
410     RTC_LOG(INFO) << __FUNCTION__;
411     FATAL() << "Should never be called";
412     return -1;
413   }
414 
MinMicrophoneVolume(uint32_t * minVolume) const415   int32_t MinMicrophoneVolume(uint32_t* minVolume) const override {
416     RTC_LOG(INFO) << __FUNCTION__;
417     FATAL() << "Should never be called";
418     return -1;
419   }
420 
SpeakerMuteIsAvailable(bool * available)421   int32_t SpeakerMuteIsAvailable(bool* available) override {
422     RTC_LOG(INFO) << __FUNCTION__;
423     FATAL() << "Should never be called";
424     return -1;
425   }
426 
SetSpeakerMute(bool enable)427   int32_t SetSpeakerMute(bool enable) override {
428     RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
429     FATAL() << "Should never be called";
430     return -1;
431   }
432 
SpeakerMute(bool * enabled) const433   int32_t SpeakerMute(bool* enabled) const override {
434     RTC_LOG(INFO) << __FUNCTION__;
435     FATAL() << "Should never be called";
436     return -1;
437   }
438 
MicrophoneMuteIsAvailable(bool * available)439   int32_t MicrophoneMuteIsAvailable(bool* available) override {
440     RTC_LOG(INFO) << __FUNCTION__;
441     FATAL() << "Not implemented";
442     return -1;
443   }
444 
SetMicrophoneMute(bool enable)445   int32_t SetMicrophoneMute(bool enable) override {
446     RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
447     FATAL() << "Not implemented";
448     return -1;
449   }
450 
MicrophoneMute(bool * enabled) const451   int32_t MicrophoneMute(bool* enabled) const override {
452     RTC_LOG(INFO) << __FUNCTION__;
453     FATAL() << "Not implemented";
454     return -1;
455   }
456 
StereoPlayoutIsAvailable(bool * available) const457   int32_t StereoPlayoutIsAvailable(bool* available) const override {
458     RTC_LOG(INFO) << __FUNCTION__;
459     *available = is_stereo_playout_supported_;
460     RTC_LOG(INFO) << "output: " << *available;
461     return 0;
462   }
463 
SetStereoPlayout(bool enable)464   int32_t SetStereoPlayout(bool enable) override {
465     RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
466     // Android does not support changes between mono and stero on the fly. The
467     // use of stereo or mono is determined by the audio layer. It is allowed
468     // to call this method if that same state is not modified.
469     bool available = is_stereo_playout_supported_;
470     if (enable != available) {
471       RTC_LOG(WARNING) << "changing stereo playout not supported";
472       return -1;
473     }
474     return 0;
475   }
476 
StereoPlayout(bool * enabled) const477   int32_t StereoPlayout(bool* enabled) const override {
478     RTC_LOG(INFO) << __FUNCTION__;
479     *enabled = is_stereo_playout_supported_;
480     RTC_LOG(INFO) << "output: " << *enabled;
481     return 0;
482   }
483 
StereoRecordingIsAvailable(bool * available) const484   int32_t StereoRecordingIsAvailable(bool* available) const override {
485     RTC_LOG(INFO) << __FUNCTION__;
486     *available = is_stereo_record_supported_;
487     RTC_LOG(INFO) << "output: " << *available;
488     return 0;
489   }
490 
SetStereoRecording(bool enable)491   int32_t SetStereoRecording(bool enable) override {
492     RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
493     // Android does not support changes between mono and stero on the fly. The
494     // use of stereo or mono is determined by the audio layer. It is allowed
495     // to call this method if that same state is not modified.
496     bool available = is_stereo_record_supported_;
497     if (enable != available) {
498       RTC_LOG(WARNING) << "changing stereo recording not supported";
499       return -1;
500     }
501     return 0;
502   }
503 
StereoRecording(bool * enabled) const504   int32_t StereoRecording(bool* enabled) const override {
505     RTC_LOG(INFO) << __FUNCTION__;
506     *enabled = is_stereo_record_supported_;
507     RTC_LOG(INFO) << "output: " << *enabled;
508     return 0;
509   }
510 
PlayoutDelay(uint16_t * delay_ms) const511   int32_t PlayoutDelay(uint16_t* delay_ms) const override {
512     // Best guess we can do is to use half of the estimated total delay.
513     *delay_ms = playout_delay_ms_ / 2;
514     RTC_DCHECK_GT(*delay_ms, 0);
515     return 0;
516   }
517 
518   // Returns true if the device both supports built in AEC and the device
519   // is not blocklisted.
520   // Currently, if OpenSL ES is used in both directions, this method will still
521   // report the correct value and it has the correct effect. As an example:
522   // a device supports built in AEC and this method returns true. Libjingle
523   // will then disable the WebRTC based AEC and that will work for all devices
524   // (mainly Nexus) even when OpenSL ES is used for input since our current
525   // implementation will enable built-in AEC by default also for OpenSL ES.
526   // The only "bad" thing that happens today is that when Libjingle calls
527   // OpenSLESRecorder::EnableBuiltInAEC() it will not have any real effect and
528   // a "Not Implemented" log will be filed. This non-perfect state will remain
529   // until I have added full support for audio effects based on OpenSL ES APIs.
BuiltInAECIsAvailable() const530   bool BuiltInAECIsAvailable() const override {
531     RTC_LOG(INFO) << __FUNCTION__;
532     if (!initialized_)
533       return false;
534     bool isAvailable = input_->IsAcousticEchoCancelerSupported();
535     RTC_LOG(INFO) << "output: " << isAvailable;
536     return isAvailable;
537   }
538 
539   // Not implemented for any input device on Android.
BuiltInAGCIsAvailable() const540   bool BuiltInAGCIsAvailable() const override {
541     RTC_LOG(INFO) << __FUNCTION__;
542     RTC_LOG(INFO) << "output: " << false;
543     return false;
544   }
545 
546   // Returns true if the device both supports built in NS and the device
547   // is not blocklisted.
548   // TODO(henrika): add implementation for OpenSL ES based audio as well.
549   // In addition, see comments for BuiltInAECIsAvailable().
BuiltInNSIsAvailable() const550   bool BuiltInNSIsAvailable() const override {
551     RTC_LOG(INFO) << __FUNCTION__;
552     if (!initialized_)
553       return false;
554     bool isAvailable = input_->IsNoiseSuppressorSupported();
555     RTC_LOG(INFO) << "output: " << isAvailable;
556     return isAvailable;
557   }
558 
559   // TODO(henrika): add implementation for OpenSL ES based audio as well.
EnableBuiltInAEC(bool enable)560   int32_t EnableBuiltInAEC(bool enable) override {
561     RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
562     if (!initialized_)
563       return -1;
564     RTC_CHECK(BuiltInAECIsAvailable()) << "HW AEC is not available";
565     int32_t result = input_->EnableBuiltInAEC(enable);
566     RTC_LOG(INFO) << "output: " << result;
567     return result;
568   }
569 
EnableBuiltInAGC(bool enable)570   int32_t EnableBuiltInAGC(bool enable) override {
571     RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
572     FATAL() << "HW AGC is not available";
573     return -1;
574   }
575 
576   // TODO(henrika): add implementation for OpenSL ES based audio as well.
EnableBuiltInNS(bool enable)577   int32_t EnableBuiltInNS(bool enable) override {
578     RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
579     if (!initialized_)
580       return -1;
581     RTC_CHECK(BuiltInNSIsAvailable()) << "HW NS is not available";
582     int32_t result = input_->EnableBuiltInNS(enable);
583     RTC_LOG(INFO) << "output: " << result;
584     return result;
585   }
586 
GetPlayoutUnderrunCount() const587   int32_t GetPlayoutUnderrunCount() const override {
588     if (!initialized_)
589       return -1;
590     return output_->GetPlayoutUnderrunCount();
591   }
592 
AttachAudioBuffer()593   int32_t AttachAudioBuffer() {
594     RTC_LOG(INFO) << __FUNCTION__;
595     output_->AttachAudioBuffer(audio_device_buffer_.get());
596     input_->AttachAudioBuffer(audio_device_buffer_.get());
597     return 0;
598   }
599 
600  private:
601   rtc::ThreadChecker thread_checker_;
602 
603   const AudioDeviceModule::AudioLayer audio_layer_;
604   const bool is_stereo_playout_supported_;
605   const bool is_stereo_record_supported_;
606   const uint16_t playout_delay_ms_;
607   const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
608   const std::unique_ptr<AudioInput> input_;
609   const std::unique_ptr<AudioOutput> output_;
610   std::unique_ptr<AudioDeviceBuffer> audio_device_buffer_;
611 
612   bool initialized_;
613 };
614 
615 }  // namespace
616 
GetAudioManager(JNIEnv * env,const JavaRef<jobject> & j_context)617 ScopedJavaLocalRef<jobject> GetAudioManager(JNIEnv* env,
618                                             const JavaRef<jobject>& j_context) {
619   return Java_WebRtcAudioManager_getAudioManager(env, j_context);
620 }
621 
GetDefaultSampleRate(JNIEnv * env,const JavaRef<jobject> & j_audio_manager)622 int GetDefaultSampleRate(JNIEnv* env, const JavaRef<jobject>& j_audio_manager) {
623   return Java_WebRtcAudioManager_getSampleRate(env, j_audio_manager);
624 }
625 
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)626 void GetAudioParameters(JNIEnv* env,
627                         const JavaRef<jobject>& j_context,
628                         const JavaRef<jobject>& j_audio_manager,
629                         int input_sample_rate,
630                         int output_sample_rate,
631                         bool use_stereo_input,
632                         bool use_stereo_output,
633                         AudioParameters* input_parameters,
634                         AudioParameters* output_parameters) {
635   const int output_channels = use_stereo_output ? 2 : 1;
636   const int input_channels = use_stereo_input ? 2 : 1;
637   const size_t output_buffer_size = Java_WebRtcAudioManager_getOutputBufferSize(
638       env, j_context, j_audio_manager, output_sample_rate, output_channels);
639   const size_t input_buffer_size = Java_WebRtcAudioManager_getInputBufferSize(
640       env, j_context, j_audio_manager, input_sample_rate, input_channels);
641   output_parameters->reset(output_sample_rate,
642                            static_cast<size_t>(output_channels),
643                            static_cast<size_t>(output_buffer_size));
644   input_parameters->reset(input_sample_rate,
645                           static_cast<size_t>(input_channels),
646                           static_cast<size_t>(input_buffer_size));
647   RTC_CHECK(input_parameters->is_valid());
648   RTC_CHECK(output_parameters->is_valid());
649 }
650 
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)651 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDeviceModuleFromInputAndOutput(
652     AudioDeviceModule::AudioLayer audio_layer,
653     bool is_stereo_playout_supported,
654     bool is_stereo_record_supported,
655     uint16_t playout_delay_ms,
656     std::unique_ptr<AudioInput> audio_input,
657     std::unique_ptr<AudioOutput> audio_output) {
658   RTC_LOG(INFO) << __FUNCTION__;
659   return new rtc::RefCountedObject<AndroidAudioDeviceModule>(
660       audio_layer, is_stereo_playout_supported, is_stereo_record_supported,
661       playout_delay_ms, std::move(audio_input), std::move(audio_output));
662 }
663 
664 }  // namespace jni
665 }  // namespace webrtc
666