aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/audio_device/android/audio_manager.h
blob: 5f23147b8a6fa8bc767d15f74e4dc91d56a90f6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_MANAGER_H_
#define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_MANAGER_H_

#include <jni.h>

#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/modules/audio_device/android/audio_common.h"
#include "webrtc/modules/audio_device/audio_device_config.h"
#include "webrtc/modules/audio_device/include/audio_device_defines.h"
#include "webrtc/modules/audio_device/audio_device_generic.h"
#include "webrtc/modules/utility/interface/helpers_android.h"
#include "webrtc/modules/utility/interface/jvm_android.h"

namespace webrtc {

// Implements support for functions in the WebRTC audio stack for Android that
// relies on the AudioManager in android.media. It also populates an
// AudioParameter structure with native audio parameters detected at
// construction. This class does not make any audio-related modifications
// unless Init() is called. Caching audio parameters makes no changes but only
// reads data from the Java side.
class AudioManager {
 public:
  // Wraps the Java specific parts of the AudioManager into one helper class.
  // Stores method IDs for all supported methods at construction and then
  // allows calls like JavaAudioManager::Close() while hiding the Java/JNI
  // parts that are associated with this call.
  class JavaAudioManager {
   public:
    JavaAudioManager(NativeRegistration* native_registration,
                     rtc::scoped_ptr<GlobalRef> audio_manager);
    ~JavaAudioManager();

    bool Init();
    void Close();
    bool IsCommunicationModeEnabled();
    bool IsDeviceBlacklistedForOpenSLESUsage();

   private:
    rtc::scoped_ptr<GlobalRef> audio_manager_;
    jmethodID init_;
    jmethodID dispose_;
    jmethodID is_communication_mode_enabled_;
    jmethodID is_device_blacklisted_for_open_sles_usage_;
  };

  AudioManager();
  ~AudioManager();

  // Sets the currently active audio layer combination. Must be called before
  // Init().
  void SetActiveAudioLayer(AudioDeviceModule::AudioLayer audio_layer);

  // Initializes the audio manager and stores the current audio mode.
  bool Init();
  // Revert any setting done by Init().
  bool Close();

  // Returns true if current audio mode is AudioManager.MODE_IN_COMMUNICATION.
  bool IsCommunicationModeEnabled() const;

  // Native audio parameters stored during construction.
  const AudioParameters& GetPlayoutAudioParameters();
  const AudioParameters& GetRecordAudioParameters();

  // Returns true if the device supports built-in audio effects for AEC, AGC
  // and NS. Some devices can also be blacklisted for use in combination with
  // platform effects and these devices will return false.
  // Can currently only be used in combination with a Java based audio backend
  // for the recoring side (i.e. using the android.media.AudioRecord API).
  bool IsAcousticEchoCancelerSupported() const;
  bool IsAutomaticGainControlSupported() const;
  bool IsNoiseSuppressorSupported() const;

  // Returns true if the device supports the low-latency audio paths in
  // combination with OpenSL ES.
  bool IsLowLatencyPlayoutSupported() const;

  // Returns the estimated total delay of this device. Unit is in milliseconds.
  // The vaule is set once at construction and never changes after that.
  // Possible values are webrtc::kLowLatencyModeDelayEstimateInMilliseconds and
  // webrtc::kHighLatencyModeDelayEstimateInMilliseconds.
  int GetDelayEstimateInMilliseconds() const;

  int OutputStreamType() const { return output_stream_type_; }

 private:
  // Called from Java side so we can cache the native audio parameters.
  // This method will be called by the WebRtcAudioManager constructor, i.e.
  // on the same thread that this object is created on.
  static void JNICALL CacheAudioParameters(JNIEnv* env,
                                           jobject obj,
                                           jint sample_rate,
                                           jint channels,
                                           jboolean hardware_aec,
                                           jboolean hardware_agc,
                                           jboolean hardware_ns,
                                           jboolean low_latency_output,
                                           jint output_buffer_size,
                                           jint input_buffer_size,
                                           jint output_stream_type,
                                           jlong native_audio_manager);
  void OnCacheAudioParameters(JNIEnv* env,
                              jint sample_rate,
                              jint channels,
                              jboolean hardware_aec,
                              jboolean hardware_agc,
                              jboolean hardware_ns,
                              jboolean low_latency_output,
                              jint output_buffer_size,
                              jint input_buffer_size,
                              jint output_stream_type);

  // Stores thread ID in the constructor.
  // We can then use ThreadChecker::CalledOnValidThread() to ensure that
  // other methods are called from the same thread.
  rtc::ThreadChecker thread_checker_;

  // Calls AttachCurrentThread() if this thread is not attached at construction.
  // Also ensures that DetachCurrentThread() is called at destruction.
  AttachCurrentThreadIfNeeded attach_thread_if_needed_;

  // Wraps the JNI interface pointer and methods associated with it.
  rtc::scoped_ptr<JNIEnvironment> j_environment_;

  // Contains factory method for creating the Java object.
  rtc::scoped_ptr<NativeRegistration> j_native_registration_;

  // Wraps the Java specific parts of the AudioManager.
  rtc::scoped_ptr<AudioManager::JavaAudioManager> j_audio_manager_;

  AudioDeviceModule::AudioLayer audio_layer_;

  // Set to true by Init() and false by Close().
  bool initialized_;

  // True if device supports hardware (or built-in) AEC.
  bool hardware_aec_;
  // True if device supports hardware (or built-in) AGC.
  bool hardware_agc_;
  // True if device supports hardware (or built-in) NS.
  bool hardware_ns_;

  // True if device supports the low-latency OpenSL ES audio path.
  bool low_latency_playout_;

  // The delay estimate can take one of two fixed values depending on if the
  // device supports low-latency output or not.
  int delay_estimate_in_milliseconds_;

  // Contains the output stream type provided to this class at construction by
  // the AudioManager in Java land. Possible values are:
  //  - AudioManager.STREAM_VOICE_CALL = 0
  //  - AudioManager.STREAM_RING = 2
  //  - AudioManager.STREAM_MUSIC = 3
  int output_stream_type_;

  // Contains native parameters (e.g. sample rate, channel configuration).
  // Set at construction in OnCacheAudioParameters() which is called from
  // Java on the same thread as this object is created on.
  AudioParameters playout_parameters_;
  AudioParameters record_parameters_;
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_MANAGER_H_