OLD | NEW |
---|---|
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 18 matching lines...) Expand all Loading... | |
40 static const int kDefaultInputBufferSize = 1024; | 41 static const int kDefaultInputBufferSize = 1024; |
41 static const int kDefaultOutputBufferSize = 2048; | 42 static const int kDefaultOutputBufferSize = 2048; |
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 SetMaxOutputStreamsAllowed(kMaxOutputStreams); | 50 SetMaxOutputStreamsAllowed(kMaxOutputStreams); |
50 | |
51 j_audio_manager_.Reset( | |
52 Java_AudioManagerAndroid_createAudioManagerAndroid( | |
53 base::android::AttachCurrentThread(), | |
54 base::android::GetApplicationContext(), | |
55 reinterpret_cast<intptr_t>(this))); | |
56 Init(); | |
57 } | 51 } |
58 | 52 |
59 AudioManagerAndroid::~AudioManagerAndroid() { | 53 AudioManagerAndroid::~AudioManagerAndroid() { |
60 Close(); | |
61 Shutdown(); | 54 Shutdown(); |
55 // Verify that WillDestroyCurrentMessageLoop() has been called. | |
56 DCHECK(j_audio_manager_.is_null()); | |
62 } | 57 } |
63 | 58 |
64 bool AudioManagerAndroid::HasAudioOutputDevices() { | 59 bool AudioManagerAndroid::HasAudioOutputDevices() { |
65 return true; | 60 return true; |
66 } | 61 } |
67 | 62 |
68 bool AudioManagerAndroid::HasAudioInputDevices() { | 63 bool AudioManagerAndroid::HasAudioInputDevices() { |
69 return true; | 64 return true; |
70 } | 65 } |
71 | 66 |
72 void AudioManagerAndroid::GetAudioInputDeviceNames( | 67 void AudioManagerAndroid::GetAudioInputDeviceNames( |
DaleCurtis
2014/02/03 19:09:16
Is there no way to move this call on to the audio
henrika (OOO until Aug 14)
2014/02/03 19:23:42
It is called on a so called device thread in the a
DaleCurtis
2014/02/03 19:33:15
Actually we can remove that thread now that we hav
henrika (OOO until Aug 14)
2014/02/04 10:09:36
I would very much appreciate if you could close th
DaleCurtis
2014/02/04 19:14:11
https://codereview.chromium.org/154143002/
| |
73 AudioDeviceNames* device_names) { | 68 AudioDeviceNames* device_names) { |
74 // Always add default device parameters as first element. | 69 // Get list of available audio devices and use the audio thread to reduce |
75 DCHECK(device_names->empty()); | 70 // the number of calling threads to the Java layer. Also, ensure that the |
76 AddDefaultDevice(device_names); | 71 // calling thread sees this function call as synchronous. |
77 | 72 scoped_refptr<base::SingleThreadTaskRunner> task_runner(GetTaskRunner()); |
78 JNIEnv* env = AttachCurrentThread(); | 73 if (task_runner->BelongsToCurrentThread()) { |
79 ScopedJavaLocalRef<jobjectArray> j_device_array = | 74 GetAudioInputDeviceNamesOnAudioThread(NULL, device_names); |
80 Java_AudioManagerAndroid_getAudioInputDeviceNames( | 75 } else { |
81 env, j_audio_manager_.obj()); | 76 base::WaitableEvent event(false, false); |
82 jsize len = env->GetArrayLength(j_device_array.obj()); | 77 task_runner->PostTask( |
83 AudioDeviceName device; | 78 FROM_HERE, |
84 for (jsize i = 0; i < len; ++i) { | 79 base::Bind( |
85 ScopedJavaLocalRef<jobject> j_device( | 80 &AudioManagerAndroid::GetAudioInputDeviceNamesOnAudioThread, |
86 env, env->GetObjectArrayElement(j_device_array.obj(), i)); | 81 base::Unretained(this), |
87 ScopedJavaLocalRef<jstring> j_device_name = | 82 &event, |
88 Java_AudioDeviceName_name(env, j_device.obj()); | 83 device_names)); |
89 ConvertJavaStringToUTF8(env, j_device_name.obj(), &device.device_name); | 84 event.Wait(); |
90 ScopedJavaLocalRef<jstring> j_device_id = | |
91 Java_AudioDeviceName_id(env, j_device.obj()); | |
92 ConvertJavaStringToUTF8(env, j_device_id.obj(), &device.unique_id); | |
93 device_names->push_back(device); | |
94 } | 85 } |
95 } | 86 } |
96 | 87 |
97 void AudioManagerAndroid::GetAudioOutputDeviceNames( | 88 void AudioManagerAndroid::GetAudioOutputDeviceNames( |
98 AudioDeviceNames* device_names) { | 89 AudioDeviceNames* device_names) { |
99 // TODO(henrika): enumerate using GetAudioInputDeviceNames(). | 90 // TODO(henrika): enumerate using GetAudioInputDeviceNames(). |
100 AddDefaultDevice(device_names); | 91 AddDefaultDevice(device_names); |
101 } | 92 } |
102 | 93 |
103 AudioParameters AudioManagerAndroid::GetInputStreamParameters( | 94 AudioParameters AudioManagerAndroid::GetInputStreamParameters( |
104 const std::string& device_id) { | 95 const std::string& device_id) { |
96 CreateAndInit(); | |
DaleCurtis
2014/02/03 19:09:16
I think you need to always post this task during c
henrika (OOO until Aug 14)
2014/02/03 19:23:42
I recall your recent CL on Windows doing this but
| |
97 | |
105 JNIEnv* env = AttachCurrentThread(); | 98 JNIEnv* env = AttachCurrentThread(); |
99 CHECK(env); | |
100 | |
106 // Use mono as preferred number of input channels on Android to save | 101 // Use mono as preferred number of input channels on Android to save |
107 // resources. Using mono also avoids a driver issue seen on Samsung | 102 // resources. Using mono also avoids a driver issue seen on Samsung |
108 // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details. | 103 // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details. |
109 ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO; | 104 ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO; |
110 int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize( | 105 int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize( |
111 env, GetNativeOutputSampleRate(), | 106 env, GetNativeOutputSampleRate(), |
112 ChannelLayoutToChannelCount(channel_layout)); | 107 ChannelLayoutToChannelCount(channel_layout)); |
113 int effects = AudioParameters::NO_EFFECTS; | 108 int effects = AudioParameters::NO_EFFECTS; |
114 effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ? | 109 effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ? |
115 AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS; | 110 AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS; |
(...skipping 23 matching lines...) Expand all Loading... | |
139 { | 134 { |
140 base::AutoLock lock(streams_lock_); | 135 base::AutoLock lock(streams_lock_); |
141 streams_.insert(static_cast<OpenSLESOutputStream*>(stream)); | 136 streams_.insert(static_cast<OpenSLESOutputStream*>(stream)); |
142 } | 137 } |
143 | 138 |
144 return stream; | 139 return stream; |
145 } | 140 } |
146 | 141 |
147 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( | 142 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( |
148 const AudioParameters& params, const std::string& device_id) { | 143 const AudioParameters& params, const std::string& device_id) { |
144 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | |
149 bool had_no_streams = HadNoAudioStreams(); | 145 bool had_no_streams = HadNoAudioStreams(); |
150 AudioInputStream* stream = | 146 AudioInputStream* stream = |
151 AudioManagerBase::MakeAudioInputStream(params, device_id); | 147 AudioManagerBase::MakeAudioInputStream(params, device_id); |
152 | 148 |
153 // The audio manager for Android creates streams intended for real-time | 149 // The audio manager for Android creates streams intended for real-time |
154 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. | 150 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. |
155 // If a Bluetooth headset is used, the audio stream will use the SCO | 151 // If a Bluetooth headset is used, the audio stream will use the SCO |
156 // channel and therefore have a limited bandwidth (8kHz). | 152 // channel and therefore have a limited bandwidth (8kHz). |
157 if (stream && had_no_streams) | 153 if (stream && had_no_streams) |
158 SetCommunicationAudioModeOn(true); | 154 SetCommunicationAudioModeOn(true); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 // TODO(henrika): add support for device selection if/when any client | 195 // TODO(henrika): add support for device selection if/when any client |
200 // needs it. | 196 // needs it. |
201 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; | 197 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; |
202 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); | 198 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); |
203 return new OpenSLESInputStream(this, params); | 199 return new OpenSLESInputStream(this, params); |
204 } | 200 } |
205 | 201 |
206 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( | 202 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( |
207 const AudioParameters& params, const std::string& device_id) { | 203 const AudioParameters& params, const std::string& device_id) { |
208 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); | 204 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); |
205 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | |
209 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; | 206 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; |
210 // Use the device ID to select the correct input device. | 207 // Use the device ID to select the correct input device. |
211 // Note that the input device is always associated with a certain output | 208 // Note that the input device is always associated with a certain output |
212 // device, i.e., this selection does also switch the output device. | 209 // device, i.e., this selection does also switch the output device. |
213 // All input and output streams will be affected by the device selection. | 210 // All input and output streams will be affected by the device selection. |
214 if (!SetAudioDevice(device_id)) { | 211 if (!SetAudioDevice(device_id)) { |
215 LOG(ERROR) << "Unable to select audio device!"; | 212 LOG(ERROR) << "Unable to select audio device!"; |
216 return NULL; | 213 return NULL; |
217 } | 214 } |
218 | 215 |
219 if (params.effects() != AudioParameters::NO_EFFECTS) { | 216 if (params.effects() != AudioParameters::NO_EFFECTS) { |
220 // Platform effects can only be enabled through the AudioRecord path. | 217 // Platform effects can only be enabled through the AudioRecord path. |
221 // An effect should only have been requested here if recommended by | 218 // An effect should only have been requested here if recommended by |
222 // AudioManagerAndroid.shouldUse<Effect>. | 219 // AudioManagerAndroid.shouldUse<Effect>. |
223 // | 220 // |
224 // Creating this class requires Jelly Bean, which is already guaranteed by | 221 // Creating this class requires Jelly Bean, which is already guaranteed by |
225 // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use | 222 // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use |
226 // the effect settings as a way to select the input path. | 223 // the effect settings as a way to select the input path. |
227 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16); | 224 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16); |
228 DVLOG(1) << "Creating AudioRecordInputStream"; | 225 DVLOG(1) << "Creating AudioRecordInputStream"; |
229 return new AudioRecordInputStream(this, params); | 226 return new AudioRecordInputStream(this, params); |
230 } | 227 } |
231 DVLOG(1) << "Creating OpenSLESInputStream"; | 228 DVLOG(1) << "Creating OpenSLESInputStream"; |
232 return new OpenSLESInputStream(this, params); | 229 return new OpenSLESInputStream(this, params); |
233 } | 230 } |
234 | 231 |
232 void AudioManagerAndroid::WillDestroyCurrentMessageLoop() { | |
233 CloseOnAudioThread(); | |
234 } | |
235 | |
235 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, | 236 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, |
236 int channels) { | 237 int channels) { |
237 if (IsAudioLowLatencySupported()) { | 238 if (IsAudioLowLatencySupported()) { |
238 return GetAudioLowLatencyOutputFrameSize(); | 239 return GetAudioLowLatencyOutputFrameSize(); |
239 } else { | 240 } else { |
240 return std::max(kDefaultOutputBufferSize, | 241 return std::max(kDefaultOutputBufferSize, |
241 Java_AudioManagerAndroid_getMinOutputFrameSize( | 242 Java_AudioManagerAndroid_getMinOutputFrameSize( |
242 base::android::AttachCurrentThread(), | 243 base::android::AttachCurrentThread(), |
243 sample_rate, channels)); | 244 sample_rate, channels)); |
244 } | 245 } |
(...skipping 30 matching lines...) Expand all Loading... | |
275 | 276 |
276 bool AudioManagerAndroid::HadNoAudioStreams() { | 277 bool AudioManagerAndroid::HadNoAudioStreams() { |
277 return output_stream_count() == 0 && input_stream_count() == 0; | 278 return output_stream_count() == 0 && input_stream_count() == 0; |
278 } | 279 } |
279 | 280 |
280 // static | 281 // static |
281 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { | 282 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { |
282 return RegisterNativesImpl(env); | 283 return RegisterNativesImpl(env); |
283 } | 284 } |
284 | 285 |
286 void AudioManagerAndroid::CreateAndInit() { | |
287 scoped_refptr<base::SingleThreadTaskRunner> task_runner(GetTaskRunner()); | |
288 if (task_runner->BelongsToCurrentThread()) { | |
289 CreateAndInitOnAudioThread(NULL); | |
290 } else { | |
291 base::WaitableEvent event(false, false); | |
292 task_runner->PostTask( | |
293 FROM_HERE, | |
294 base::Bind( | |
295 &AudioManagerAndroid::CreateAndInitOnAudioThread, | |
296 base::Unretained(this), | |
297 &event)); | |
298 event.Wait(); | |
299 } | |
300 } | |
301 | |
302 void AudioManagerAndroid::CreateAndInitOnAudioThread( | |
303 base::WaitableEvent* event) { | |
304 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | |
305 if (!j_audio_manager_.is_null()) | |
306 return; | |
307 | |
308 JNIEnv* env = base::android::AttachCurrentThread(); | |
309 CHECK(env); | |
310 | |
311 // Create the Android audio manager on the audio thread. | |
312 j_audio_manager_.Reset( | |
313 Java_AudioManagerAndroid_createAudioManagerAndroid( | |
314 env, | |
315 base::android::GetApplicationContext(), | |
316 reinterpret_cast<intptr_t>(this))); | |
317 | |
318 // Prepare the list of audio devices and register receivers for device | |
319 // notifications. | |
320 Init(); | |
321 | |
322 // Ensure that we are notified when the audio thread dies. | |
323 base::MessageLoop::current()->AddDestructionObserver(this); | |
324 | |
325 if (event) | |
326 event->Signal(); | |
327 } | |
328 | |
285 void AudioManagerAndroid::Init() { | 329 void AudioManagerAndroid::Init() { |
286 Java_AudioManagerAndroid_init( | 330 Java_AudioManagerAndroid_init( |
287 base::android::AttachCurrentThread(), | 331 base::android::AttachCurrentThread(), |
288 j_audio_manager_.obj()); | 332 j_audio_manager_.obj()); |
289 } | 333 } |
290 | 334 |
291 void AudioManagerAndroid::Close() { | 335 void AudioManagerAndroid::Close() { |
292 Java_AudioManagerAndroid_close( | 336 Java_AudioManagerAndroid_close( |
293 base::android::AttachCurrentThread(), | 337 base::android::AttachCurrentThread(), |
294 j_audio_manager_.obj()); | 338 j_audio_manager_.obj()); |
295 } | 339 } |
296 | 340 |
297 void AudioManagerAndroid::SetMute(JNIEnv* env, jobject obj, jboolean muted) { | 341 void AudioManagerAndroid::SetMute(JNIEnv* env, jobject obj, jboolean muted) { |
298 GetTaskRunner()->PostTask( | 342 GetTaskRunner()->PostTask( |
299 FROM_HERE, | 343 FROM_HERE, |
300 base::Bind( | 344 base::Bind( |
301 &AudioManagerAndroid::DoSetMuteOnAudioThread, | 345 &AudioManagerAndroid::DoSetMuteOnAudioThread, |
302 base::Unretained(this), | 346 base::Unretained(this), |
303 muted)); | 347 muted)); |
304 } | 348 } |
305 | 349 |
306 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) { | 350 void AudioManagerAndroid::GetAudioInputDeviceNamesOnAudioThread( |
307 base::AutoLock lock(streams_lock_); | 351 base::WaitableEvent* event, AudioDeviceNames* device_names) { |
308 for (OutputStreams::iterator it = streams_.begin(); | 352 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
309 it != streams_.end(); ++it) { | 353 |
310 (*it)->SetMute(muted); | 354 // Set up the initial list of available audio devices and register for |
355 // broadcasted notifications about any changes of availability. | |
356 // This method is only executed when called for the first time and it can | |
357 // also be called from SetAudioDeviceOnAudioThread(). | |
358 // InitializeOnAudioThread(); | |
359 | |
360 // Always add default device parameters as first element. | |
361 DCHECK(device_names->empty()); | |
362 AddDefaultDevice(device_names); | |
363 | |
364 JNIEnv* env = AttachCurrentThread(); | |
365 ScopedJavaLocalRef<jobjectArray> j_device_array = | |
366 Java_AudioManagerAndroid_getAudioInputDeviceNames( | |
367 env, j_audio_manager_.obj()); | |
368 jsize len = env->GetArrayLength(j_device_array.obj()); | |
369 AudioDeviceName device; | |
370 for (jsize i = 0; i < len; ++i) { | |
371 ScopedJavaLocalRef<jobject> j_device( | |
372 env, env->GetObjectArrayElement(j_device_array.obj(), i)); | |
373 ScopedJavaLocalRef<jstring> j_device_name = | |
374 Java_AudioDeviceName_name(env, j_device.obj()); | |
375 ConvertJavaStringToUTF8(env, j_device_name.obj(), &device.device_name); | |
376 ScopedJavaLocalRef<jstring> j_device_id = | |
377 Java_AudioDeviceName_id(env, j_device.obj()); | |
378 ConvertJavaStringToUTF8(env, j_device_id.obj(), &device.unique_id); | |
379 device_names->push_back(device); | |
311 } | 380 } |
381 | |
382 if (event) | |
383 event->Signal(); | |
312 } | 384 } |
313 | 385 |
314 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { | 386 void AudioManagerAndroid::CloseOnAudioThread() { |
315 Java_AudioManagerAndroid_setCommunicationAudioModeOn( | 387 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
316 base::android::AttachCurrentThread(), | 388 if (j_audio_manager_.is_null()) |
317 j_audio_manager_.obj(), on); | 389 return; |
390 Close(); | |
391 j_audio_manager_.Reset(); | |
318 } | 392 } |
319 | 393 |
320 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { | 394 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { |
321 JNIEnv* env = AttachCurrentThread(); | 395 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
396 // Set up the initial list of available audio devices and register for | |
397 // broadcasted notifications about any changes of availability. | |
398 // This method is only executed when called for the first time and it can | |
399 // also be called from GetAudioInputDeviceNamesOnAudioThread(). | |
400 // InitializeOnAudioThread(); | |
322 | 401 |
323 // Send the unique device ID to the Java audio manager and make the | 402 // Send the unique device ID to the Java audio manager and make the |
324 // device switch. Provide an empty string to the Java audio manager | 403 // device switch. Provide an empty string to the Java audio manager |
325 // if the default device is selected. | 404 // if the default device is selected. |
405 JNIEnv* env = AttachCurrentThread(); | |
326 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( | 406 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( |
327 env, | 407 env, |
328 device_id == AudioManagerBase::kDefaultDeviceId ? | 408 device_id == AudioManagerBase::kDefaultDeviceId ? |
329 std::string() : device_id); | 409 std::string() : device_id); |
330 return Java_AudioManagerAndroid_setDevice( | 410 return Java_AudioManagerAndroid_setDevice( |
331 env, j_audio_manager_.obj(), j_device_id.obj()); | 411 env, j_audio_manager_.obj(), j_device_id.obj()); |
332 } | 412 } |
333 | 413 |
414 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) { | |
415 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | |
416 base::AutoLock lock(streams_lock_); | |
417 for (OutputStreams::iterator it = streams_.begin(); | |
418 it != streams_.end(); ++it) { | |
419 (*it)->SetMute(muted); | |
420 } | |
421 } | |
422 | |
423 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { | |
424 Java_AudioManagerAndroid_setCommunicationAudioModeOn( | |
425 base::android::AttachCurrentThread(), | |
426 j_audio_manager_.obj(), on); | |
427 } | |
428 | |
334 int AudioManagerAndroid::GetNativeOutputSampleRate() { | 429 int AudioManagerAndroid::GetNativeOutputSampleRate() { |
335 return Java_AudioManagerAndroid_getNativeOutputSampleRate( | 430 return Java_AudioManagerAndroid_getNativeOutputSampleRate( |
336 base::android::AttachCurrentThread(), | 431 base::android::AttachCurrentThread(), |
337 j_audio_manager_.obj()); | 432 j_audio_manager_.obj()); |
338 } | 433 } |
339 | 434 |
340 bool AudioManagerAndroid::IsAudioLowLatencySupported() { | 435 bool AudioManagerAndroid::IsAudioLowLatencySupported() { |
341 return Java_AudioManagerAndroid_isAudioLowLatencySupported( | 436 return Java_AudioManagerAndroid_isAudioLowLatencySupported( |
342 base::android::AttachCurrentThread(), | 437 base::android::AttachCurrentThread(), |
343 j_audio_manager_.obj()); | 438 j_audio_manager_.obj()); |
344 } | 439 } |
345 | 440 |
346 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { | 441 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { |
347 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( | 442 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( |
348 base::android::AttachCurrentThread(), | 443 base::android::AttachCurrentThread(), |
349 j_audio_manager_.obj()); | 444 j_audio_manager_.obj()); |
350 } | 445 } |
351 | 446 |
352 } // namespace media | 447 } // namespace media |
OLD | NEW |