Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: media/audio/android/audio_manager_android.cc

Issue 131503006: Initialization of audio manager for Android is now done on the audio thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: now compiles Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/android/audio_manager_android.h ('k') | media/audio/audio_input_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/android/audio_manager_android.h" 5 #include "media/audio/android/audio_manager_android.h"
6 6
7 #include "base/android/build_info.h" 7 #include "base/android/build_info.h"
8 #include "base/android/jni_array.h" 8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h" 9 #include "base/android/jni_string.h"
10 #include "base/android/scoped_java_ref.h" 10 #include "base/android/scoped_java_ref.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
13 #include "jni/AudioManagerAndroid_jni.h" 14 #include "jni/AudioManagerAndroid_jni.h"
14 #include "media/audio/android/audio_record_input.h" 15 #include "media/audio/android/audio_record_input.h"
15 #include "media/audio/android/opensles_input.h" 16 #include "media/audio/android/opensles_input.h"
16 #include "media/audio/android/opensles_output.h" 17 #include "media/audio/android/opensles_output.h"
17 #include "media/audio/audio_manager.h" 18 #include "media/audio/audio_manager.h"
18 #include "media/audio/audio_parameters.h" 19 #include "media/audio/audio_parameters.h"
19 #include "media/audio/fake_audio_input_stream.h" 20 #include "media/audio/fake_audio_input_stream.h"
20 #include "media/base/channel_layout.h" 21 #include "media/base/channel_layout.h"
21 22
(...skipping 20 matching lines...) Expand all
42 43
43 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { 44 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
44 return new AudioManagerAndroid(audio_log_factory); 45 return new AudioManagerAndroid(audio_log_factory);
45 } 46 }
46 47
47 AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory) 48 AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory)
48 : AudioManagerBase(audio_log_factory), 49 : AudioManagerBase(audio_log_factory),
49 communication_mode_is_on_(false) { 50 communication_mode_is_on_(false) {
50 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 51 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
51 52
52 j_audio_manager_.Reset( 53 // WARNING: This is executed on the UI loop, do not add any code here which
53 Java_AudioManagerAndroid_createAudioManagerAndroid( 54 // loads libraries or attempts to call out into the OS. Instead add such code
54 base::android::AttachCurrentThread(), 55 // to the InitializeOnAudioThread() method below.
55 base::android::GetApplicationContext(), 56
56 reinterpret_cast<intptr_t>(this))); 57 // Task must be posted last to avoid races from handing out "this" to the
57 Init(); 58 // audio thread.
59 GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
60 &AudioManagerAndroid::InitializeOnAudioThread,
61 base::Unretained(this)));
58 } 62 }
59 63
60 AudioManagerAndroid::~AudioManagerAndroid() { 64 AudioManagerAndroid::~AudioManagerAndroid() {
61 Close(); 65 // It's safe to post a task here since Shutdown() will wait for all tasks to
66 // complete before returning.
67 GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
68 &AudioManagerAndroid::ShutdownOnAudioThread, base::Unretained(this)));
62 Shutdown(); 69 Shutdown();
63 } 70 }
64 71
65 bool AudioManagerAndroid::HasAudioOutputDevices() { 72 bool AudioManagerAndroid::HasAudioOutputDevices() {
66 return true; 73 return true;
67 } 74 }
68 75
69 bool AudioManagerAndroid::HasAudioInputDevices() { 76 bool AudioManagerAndroid::HasAudioInputDevices() {
70 return true; 77 return true;
71 } 78 }
72 79
73 void AudioManagerAndroid::GetAudioInputDeviceNames( 80 void AudioManagerAndroid::GetAudioInputDeviceNames(
74 AudioDeviceNames* device_names) { 81 AudioDeviceNames* device_names) {
82 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
83
75 // Always add default device parameters as first element. 84 // Always add default device parameters as first element.
76 DCHECK(device_names->empty()); 85 DCHECK(device_names->empty());
77 AddDefaultDevice(device_names); 86 AddDefaultDevice(device_names);
78 87
88 // Get list of available audio devices.
79 JNIEnv* env = AttachCurrentThread(); 89 JNIEnv* env = AttachCurrentThread();
80 ScopedJavaLocalRef<jobjectArray> j_device_array = 90 ScopedJavaLocalRef<jobjectArray> j_device_array =
81 Java_AudioManagerAndroid_getAudioInputDeviceNames( 91 Java_AudioManagerAndroid_getAudioInputDeviceNames(
82 env, j_audio_manager_.obj()); 92 env, j_audio_manager_.obj());
83 jsize len = env->GetArrayLength(j_device_array.obj()); 93 jsize len = env->GetArrayLength(j_device_array.obj());
84 AudioDeviceName device; 94 AudioDeviceName device;
85 for (jsize i = 0; i < len; ++i) { 95 for (jsize i = 0; i < len; ++i) {
86 ScopedJavaLocalRef<jobject> j_device( 96 ScopedJavaLocalRef<jobject> j_device(
87 env, env->GetObjectArrayElement(j_device_array.obj(), i)); 97 env, env->GetObjectArrayElement(j_device_array.obj(), i));
88 ScopedJavaLocalRef<jstring> j_device_name = 98 ScopedJavaLocalRef<jstring> j_device_name =
89 Java_AudioDeviceName_name(env, j_device.obj()); 99 Java_AudioDeviceName_name(env, j_device.obj());
90 ConvertJavaStringToUTF8(env, j_device_name.obj(), &device.device_name); 100 ConvertJavaStringToUTF8(env, j_device_name.obj(), &device.device_name);
91 ScopedJavaLocalRef<jstring> j_device_id = 101 ScopedJavaLocalRef<jstring> j_device_id =
92 Java_AudioDeviceName_id(env, j_device.obj()); 102 Java_AudioDeviceName_id(env, j_device.obj());
93 ConvertJavaStringToUTF8(env, j_device_id.obj(), &device.unique_id); 103 ConvertJavaStringToUTF8(env, j_device_id.obj(), &device.unique_id);
94 device_names->push_back(device); 104 device_names->push_back(device);
95 } 105 }
96 } 106 }
97 107
98 void AudioManagerAndroid::GetAudioOutputDeviceNames( 108 void AudioManagerAndroid::GetAudioOutputDeviceNames(
99 AudioDeviceNames* device_names) { 109 AudioDeviceNames* device_names) {
100 // TODO(henrika): enumerate using GetAudioInputDeviceNames(). 110 // TODO(henrika): enumerate using GetAudioInputDeviceNames().
101 AddDefaultDevice(device_names); 111 AddDefaultDevice(device_names);
102 } 112 }
103 113
104 AudioParameters AudioManagerAndroid::GetInputStreamParameters( 114 AudioParameters AudioManagerAndroid::GetInputStreamParameters(
105 const std::string& device_id) { 115 const std::string& device_id) {
106 JNIEnv* env = AttachCurrentThread(); 116 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
117
107 // Use mono as preferred number of input channels on Android to save 118 // Use mono as preferred number of input channels on Android to save
108 // resources. Using mono also avoids a driver issue seen on Samsung 119 // resources. Using mono also avoids a driver issue seen on Samsung
109 // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details. 120 // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details.
121 JNIEnv* env = AttachCurrentThread();
110 ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO; 122 ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
111 int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize( 123 int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize(
112 env, GetNativeOutputSampleRate(), 124 env, GetNativeOutputSampleRate(),
113 ChannelLayoutToChannelCount(channel_layout)); 125 ChannelLayoutToChannelCount(channel_layout));
114 int effects = AudioParameters::NO_EFFECTS; 126 int effects = AudioParameters::NO_EFFECTS;
115 effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ? 127 effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ?
116 AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS; 128 AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS;
117 AudioParameters params( 129 AudioParameters params(
118 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0, 130 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0,
119 GetNativeOutputSampleRate(), 16, 131 GetNativeOutputSampleRate(), 16,
120 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects); 132 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects);
121 return params; 133 return params;
122 } 134 }
123 135
124 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( 136 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream(
125 const AudioParameters& params, 137 const AudioParameters& params,
126 const std::string& device_id) { 138 const std::string& device_id) {
139 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
127 AudioOutputStream* stream = 140 AudioOutputStream* stream =
128 AudioManagerBase::MakeAudioOutputStream(params, std::string()); 141 AudioManagerBase::MakeAudioOutputStream(params, std::string());
129 { 142 streams_.insert(static_cast<OpenSLESOutputStream*>(stream));
130 base::AutoLock lock(streams_lock_);
131 streams_.insert(static_cast<OpenSLESOutputStream*>(stream));
132 }
133
134 return stream; 143 return stream;
135 } 144 }
136 145
137 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( 146 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream(
138 const AudioParameters& params, const std::string& device_id) { 147 const AudioParameters& params, const std::string& device_id) {
148 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
139 bool has_no_input_streams = HasNoAudioInputStreams(); 149 bool has_no_input_streams = HasNoAudioInputStreams();
140 AudioInputStream* stream = 150 AudioInputStream* stream =
141 AudioManagerBase::MakeAudioInputStream(params, device_id); 151 AudioManagerBase::MakeAudioInputStream(params, device_id);
142 152
143 // The audio manager for Android creates streams intended for real-time 153 // The audio manager for Android creates streams intended for real-time
144 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. 154 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION.
145 // If a Bluetooth headset is used, the audio stream will use the SCO 155 // If a Bluetooth headset is used, the audio stream will use the SCO
146 // channel and therefore have a limited bandwidth (8kHz). 156 // channel and therefore have a limited bandwidth (8kHz).
147 if (stream && has_no_input_streams) { 157 if (stream && has_no_input_streams) {
148 communication_mode_is_on_ = true; 158 communication_mode_is_on_ = true;
149 SetCommunicationAudioModeOn(true); 159 SetCommunicationAudioModeOn(true);
150 } 160 }
151 return stream; 161 return stream;
152 } 162 }
153 163
154 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { 164 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) {
165 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
155 AudioManagerBase::ReleaseOutputStream(stream); 166 AudioManagerBase::ReleaseOutputStream(stream);
156 base::AutoLock lock(streams_lock_);
157 streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); 167 streams_.erase(static_cast<OpenSLESOutputStream*>(stream));
158 } 168 }
159 169
160 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { 170 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) {
171 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
172 DCHECK(!j_audio_manager_.is_null());
161 AudioManagerBase::ReleaseInputStream(stream); 173 AudioManagerBase::ReleaseInputStream(stream);
162 174
163 // Restore the audio mode which was used before the first communication- 175 // Restore the audio mode which was used before the first communication-
164 // mode stream was created. 176 // mode stream was created.
165 if (HasNoAudioInputStreams()) { 177 if (HasNoAudioInputStreams()) {
166 communication_mode_is_on_ = false; 178 communication_mode_is_on_ = false;
167 SetCommunicationAudioModeOn(false); 179 SetCommunicationAudioModeOn(false);
168 } 180 }
169 } 181 }
170 182
171 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( 183 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream(
172 const AudioParameters& params) { 184 const AudioParameters& params) {
173 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 185 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
186 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
174 return new OpenSLESOutputStream(this, params, SL_ANDROID_STREAM_MEDIA); 187 return new OpenSLESOutputStream(this, params, SL_ANDROID_STREAM_MEDIA);
175 } 188 }
176 189
177 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( 190 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream(
178 const AudioParameters& params, 191 const AudioParameters& params,
179 const std::string& device_id) { 192 const std::string& device_id) {
180 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 193 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
181 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 194 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
182 195
183 // Set stream type which matches the current system-wide audio mode used by 196 // Set stream type which matches the current system-wide audio mode used by
184 // the Android audio manager. 197 // the Android audio manager.
185 const SLint32 stream_type = communication_mode_is_on_ ? 198 const SLint32 stream_type = communication_mode_is_on_ ?
186 SL_ANDROID_STREAM_VOICE : SL_ANDROID_STREAM_MEDIA; 199 SL_ANDROID_STREAM_VOICE : SL_ANDROID_STREAM_MEDIA;
187 return new OpenSLESOutputStream(this, params, stream_type); 200 return new OpenSLESOutputStream(this, params, stream_type);
188 } 201 }
189 202
190 AudioInputStream* AudioManagerAndroid::MakeLinearInputStream( 203 AudioInputStream* AudioManagerAndroid::MakeLinearInputStream(
191 const AudioParameters& params, const std::string& device_id) { 204 const AudioParameters& params, const std::string& device_id) {
192 // TODO(henrika): add support for device selection if/when any client 205 // TODO(henrika): add support for device selection if/when any client
193 // needs it. 206 // needs it.
194 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 207 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
195 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 208 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
196 return new OpenSLESInputStream(this, params); 209 return new OpenSLESInputStream(this, params);
197 } 210 }
198 211
199 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( 212 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream(
200 const AudioParameters& params, const std::string& device_id) { 213 const AudioParameters& params, const std::string& device_id) {
214 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
201 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 215 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
202 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; 216 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!";
217
203 // Use the device ID to select the correct input device. 218 // Use the device ID to select the correct input device.
204 // Note that the input device is always associated with a certain output 219 // Note that the input device is always associated with a certain output
205 // device, i.e., this selection does also switch the output device. 220 // device, i.e., this selection does also switch the output device.
206 // All input and output streams will be affected by the device selection. 221 // All input and output streams will be affected by the device selection.
207 if (!SetAudioDevice(device_id)) { 222 if (!SetAudioDevice(device_id)) {
208 LOG(ERROR) << "Unable to select audio device!"; 223 LOG(ERROR) << "Unable to select audio device!";
209 return NULL; 224 return NULL;
210 } 225 }
211 226
212 if (params.effects() != AudioParameters::NO_EFFECTS) { 227 if (params.effects() != AudioParameters::NO_EFFECTS) {
213 // Platform effects can only be enabled through the AudioRecord path. 228 // Platform effects can only be enabled through the AudioRecord path.
214 // An effect should only have been requested here if recommended by 229 // An effect should only have been requested here if recommended by
215 // AudioManagerAndroid.shouldUse<Effect>. 230 // AudioManagerAndroid.shouldUse<Effect>.
216 // 231 //
217 // Creating this class requires Jelly Bean, which is already guaranteed by 232 // Creating this class requires Jelly Bean, which is already guaranteed by
218 // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use 233 // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use
219 // the effect settings as a way to select the input path. 234 // the effect settings as a way to select the input path.
220 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16); 235 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16);
221 DVLOG(1) << "Creating AudioRecordInputStream"; 236 DVLOG(1) << "Creating AudioRecordInputStream";
222 return new AudioRecordInputStream(this, params); 237 return new AudioRecordInputStream(this, params);
223 } 238 }
224 DVLOG(1) << "Creating OpenSLESInputStream"; 239 DVLOG(1) << "Creating OpenSLESInputStream";
225 return new OpenSLESInputStream(this, params); 240 return new OpenSLESInputStream(this, params);
226 } 241 }
227 242
228 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, 243 // static
229 int channels) { 244 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) {
230 if (IsAudioLowLatencySupported()) { 245 return RegisterNativesImpl(env);
231 return GetAudioLowLatencyOutputFrameSize(); 246 }
232 } else { 247
233 return std::max(kDefaultOutputBufferSize, 248 void AudioManagerAndroid::SetMute(JNIEnv* env, jobject obj, jboolean muted) {
234 Java_AudioManagerAndroid_getMinOutputFrameSize( 249 GetTaskRunner()->PostTask(
235 base::android::AttachCurrentThread(), 250 FROM_HERE,
236 sample_rate, channels)); 251 base::Bind(
237 } 252 &AudioManagerAndroid::DoSetMuteOnAudioThread,
253 base::Unretained(this),
254 muted));
238 } 255 }
239 256
240 AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters( 257 AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters(
241 const std::string& output_device_id, 258 const std::string& output_device_id,
242 const AudioParameters& input_params) { 259 const AudioParameters& input_params) {
243 // TODO(tommi): Support |output_device_id|. 260 // TODO(tommi): Support |output_device_id|.
261 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
244 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; 262 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!";
245 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 263 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
246 int sample_rate = GetNativeOutputSampleRate(); 264 int sample_rate = GetNativeOutputSampleRate();
247 int buffer_size = GetOptimalOutputFrameSize(sample_rate, 2); 265 int buffer_size = GetOptimalOutputFrameSize(sample_rate, 2);
248 int bits_per_sample = 16; 266 int bits_per_sample = 16;
249 int input_channels = 0; 267 int input_channels = 0;
250 if (input_params.IsValid()) { 268 if (input_params.IsValid()) {
251 // Use the client's input parameters if they are valid. 269 // Use the client's input parameters if they are valid.
252 sample_rate = input_params.sample_rate(); 270 sample_rate = input_params.sample_rate();
253 bits_per_sample = input_params.bits_per_sample(); 271 bits_per_sample = input_params.bits_per_sample();
254 channel_layout = input_params.channel_layout(); 272 channel_layout = input_params.channel_layout();
255 input_channels = input_params.input_channels(); 273 input_channels = input_params.input_channels();
256 buffer_size = GetOptimalOutputFrameSize( 274 buffer_size = GetOptimalOutputFrameSize(
257 sample_rate, ChannelLayoutToChannelCount(channel_layout)); 275 sample_rate, ChannelLayoutToChannelCount(channel_layout));
258 } 276 }
259 277
260 int user_buffer_size = GetUserBufferSize(); 278 int user_buffer_size = GetUserBufferSize();
261 if (user_buffer_size) 279 if (user_buffer_size)
262 buffer_size = user_buffer_size; 280 buffer_size = user_buffer_size;
263 281
264 return AudioParameters( 282 return AudioParameters(
265 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 283 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels,
266 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); 284 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS);
267 } 285 }
268 286
269 bool AudioManagerAndroid::HasNoAudioInputStreams() { 287 bool AudioManagerAndroid::HasNoAudioInputStreams() {
270 return input_stream_count() == 0; 288 return input_stream_count() == 0;
271 } 289 }
272 290
273 // static 291 void AudioManagerAndroid::InitializeOnAudioThread() {
274 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { 292 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
275 return RegisterNativesImpl(env);
276 }
277 293
278 void AudioManagerAndroid::Init() { 294 // Create the Android audio manager on the audio thread.
295 DVLOG(2) << "Creating Java part of the audio manager";
296 j_audio_manager_.Reset(
297 Java_AudioManagerAndroid_createAudioManagerAndroid(
298 base::android::AttachCurrentThread(),
299 base::android::GetApplicationContext(),
300 reinterpret_cast<intptr_t>(this)));
301
302 // Prepare the list of audio devices and register receivers for device
303 // notifications.
279 Java_AudioManagerAndroid_init( 304 Java_AudioManagerAndroid_init(
280 base::android::AttachCurrentThread(), 305 base::android::AttachCurrentThread(),
281 j_audio_manager_.obj()); 306 j_audio_manager_.obj());
282 } 307 }
283 308
284 void AudioManagerAndroid::Close() { 309 void AudioManagerAndroid::ShutdownOnAudioThread() {
310 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
311 DVLOG(2) << "Destroying Java part of the audio manager";
285 Java_AudioManagerAndroid_close( 312 Java_AudioManagerAndroid_close(
286 base::android::AttachCurrentThread(), 313 base::android::AttachCurrentThread(),
287 j_audio_manager_.obj()); 314 j_audio_manager_.obj());
288 } 315 j_audio_manager_.Reset();
289
290 void AudioManagerAndroid::SetMute(JNIEnv* env, jobject obj, jboolean muted) {
291 GetTaskRunner()->PostTask(
292 FROM_HERE,
293 base::Bind(
294 &AudioManagerAndroid::DoSetMuteOnAudioThread,
295 base::Unretained(this),
296 muted));
297 }
298
299 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) {
300 base::AutoLock lock(streams_lock_);
301 for (OutputStreams::iterator it = streams_.begin();
302 it != streams_.end(); ++it) {
303 (*it)->SetMute(muted);
304 }
305 } 316 }
306 317
307 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { 318 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) {
308 Java_AudioManagerAndroid_setCommunicationAudioModeOn( 319 Java_AudioManagerAndroid_setCommunicationAudioModeOn(
309 base::android::AttachCurrentThread(), 320 base::android::AttachCurrentThread(),
310 j_audio_manager_.obj(), on); 321 j_audio_manager_.obj(), on);
311 } 322 }
312 323
313 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { 324 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) {
314 JNIEnv* env = AttachCurrentThread(); 325 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
315 326
316 // Send the unique device ID to the Java audio manager and make the 327 // Send the unique device ID to the Java audio manager and make the
317 // device switch. Provide an empty string to the Java audio manager 328 // device switch. Provide an empty string to the Java audio manager
318 // if the default device is selected. 329 // if the default device is selected.
330 JNIEnv* env = AttachCurrentThread();
319 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( 331 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString(
320 env, 332 env,
321 device_id == AudioManagerBase::kDefaultDeviceId ? 333 device_id == AudioManagerBase::kDefaultDeviceId ?
322 std::string() : device_id); 334 std::string() : device_id);
323 return Java_AudioManagerAndroid_setDevice( 335 return Java_AudioManagerAndroid_setDevice(
324 env, j_audio_manager_.obj(), j_device_id.obj()); 336 env, j_audio_manager_.obj(), j_device_id.obj());
325 } 337 }
326 338
327 int AudioManagerAndroid::GetNativeOutputSampleRate() { 339 int AudioManagerAndroid::GetNativeOutputSampleRate() {
328 return Java_AudioManagerAndroid_getNativeOutputSampleRate( 340 return Java_AudioManagerAndroid_getNativeOutputSampleRate(
329 base::android::AttachCurrentThread(), 341 base::android::AttachCurrentThread(),
330 j_audio_manager_.obj()); 342 j_audio_manager_.obj());
331 } 343 }
332 344
333 bool AudioManagerAndroid::IsAudioLowLatencySupported() { 345 bool AudioManagerAndroid::IsAudioLowLatencySupported() {
334 return Java_AudioManagerAndroid_isAudioLowLatencySupported( 346 return Java_AudioManagerAndroid_isAudioLowLatencySupported(
335 base::android::AttachCurrentThread(), 347 base::android::AttachCurrentThread(),
336 j_audio_manager_.obj()); 348 j_audio_manager_.obj());
337 } 349 }
338 350
339 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { 351 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() {
340 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( 352 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize(
341 base::android::AttachCurrentThread(), 353 base::android::AttachCurrentThread(),
342 j_audio_manager_.obj()); 354 j_audio_manager_.obj());
343 } 355 }
344 356
357 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate,
358 int channels) {
359 if (IsAudioLowLatencySupported())
360 return GetAudioLowLatencyOutputFrameSize();
361
362 return std::max(kDefaultOutputBufferSize,
363 Java_AudioManagerAndroid_getMinOutputFrameSize(
364 base::android::AttachCurrentThread(),
365 sample_rate, channels));
366 }
367
368 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) {
369 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
370 for (OutputStreams::iterator it = streams_.begin();
371 it != streams_.end(); ++it) {
372 (*it)->SetMute(muted);
373 }
374 }
375
345 } // namespace media 376 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/android/audio_manager_android.h ('k') | media/audio/audio_input_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698