| 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/context_utils.h" | 8 #include "base/android/context_utils.h" |
| 9 #include "base/android/jni_array.h" | 9 #include "base/android/jni_array.h" |
| 10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 58 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 59 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, | 59 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
| 60 AudioLogFactory* audio_log_factory) | 60 AudioLogFactory* audio_log_factory) |
| 61 : AudioManagerBase(std::move(task_runner), | 61 : AudioManagerBase(std::move(task_runner), |
| 62 std::move(worker_task_runner), | 62 std::move(worker_task_runner), |
| 63 audio_log_factory), | 63 audio_log_factory), |
| 64 communication_mode_is_on_(false), | 64 communication_mode_is_on_(false), |
| 65 output_volume_override_set_(false), | 65 output_volume_override_set_(false), |
| 66 output_volume_override_(0) { | 66 output_volume_override_(0) { |
| 67 SetMaxOutputStreamsAllowed(kMaxOutputStreams); | 67 SetMaxOutputStreamsAllowed(kMaxOutputStreams); |
| 68 | |
| 69 // WARNING: This is executed on the UI loop, do not add any code here which | |
| 70 // loads libraries or attempts to call out into the OS. Instead add such code | |
| 71 // to the InitializeOnAudioThread() method below. | |
| 72 | |
| 73 // Task must be posted last to avoid races from handing out "this" to the | |
| 74 // audio thread. | |
| 75 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( | |
| 76 &AudioManagerAndroid::InitializeOnAudioThread, | |
| 77 base::Unretained(this))); | |
| 78 } | 68 } |
| 79 | 69 |
| 80 AudioManagerAndroid::~AudioManagerAndroid() { | 70 AudioManagerAndroid::~AudioManagerAndroid() { |
| 81 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 71 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 82 Shutdown(); | 72 Shutdown(); |
| 83 | 73 |
| 74 if (j_audio_manager_.is_null()) |
| 75 return; |
| 84 DVLOG(2) << "Destroying Java part of the audio manager"; | 76 DVLOG(2) << "Destroying Java part of the audio manager"; |
| 85 Java_AudioManagerAndroid_close(base::android::AttachCurrentThread(), | 77 Java_AudioManagerAndroid_close(base::android::AttachCurrentThread(), |
| 86 j_audio_manager_.obj()); | 78 j_audio_manager_.obj()); |
| 87 j_audio_manager_.Reset(); | 79 j_audio_manager_.Reset(); |
| 88 } | 80 } |
| 89 | 81 |
| 82 void AudioManagerAndroid::InitializeIfNeeded() { |
| 83 GetTaskRunner()->PostTask( |
| 84 FROM_HERE, base::Bind(base::Bind(base::IgnoreResult( |
| 85 &AudioManagerAndroid::GetJavaAudioManager)), |
| 86 base::Unretained(this))); |
| 87 } |
| 88 |
| 90 bool AudioManagerAndroid::HasAudioOutputDevices() { | 89 bool AudioManagerAndroid::HasAudioOutputDevices() { |
| 91 return true; | 90 return true; |
| 92 } | 91 } |
| 93 | 92 |
| 94 bool AudioManagerAndroid::HasAudioInputDevices() { | 93 bool AudioManagerAndroid::HasAudioInputDevices() { |
| 95 return true; | 94 return true; |
| 96 } | 95 } |
| 97 | 96 |
| 98 void AudioManagerAndroid::GetAudioInputDeviceNames( | 97 void AudioManagerAndroid::GetAudioInputDeviceNames( |
| 99 AudioDeviceNames* device_names) { | 98 AudioDeviceNames* device_names) { |
| 100 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 99 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 101 | 100 |
| 102 // Always add default device parameters as first element. | 101 // Always add default device parameters as first element. |
| 103 DCHECK(device_names->empty()); | 102 DCHECK(device_names->empty()); |
| 104 AddDefaultDevice(device_names); | 103 AddDefaultDevice(device_names); |
| 105 | 104 |
| 106 // Get list of available audio devices. | 105 // Get list of available audio devices. |
| 107 JNIEnv* env = AttachCurrentThread(); | 106 JNIEnv* env = AttachCurrentThread(); |
| 108 ScopedJavaLocalRef<jobjectArray> j_device_array = | 107 ScopedJavaLocalRef<jobjectArray> j_device_array = |
| 109 Java_AudioManagerAndroid_getAudioInputDeviceNames( | 108 Java_AudioManagerAndroid_getAudioInputDeviceNames(env, |
| 110 env, j_audio_manager_.obj()); | 109 GetJavaAudioManager()); |
| 111 if (j_device_array.is_null()) { | 110 if (j_device_array.is_null()) { |
| 112 // Most probable reason for a NULL result here is that the process lacks | 111 // Most probable reason for a NULL result here is that the process lacks |
| 113 // MODIFY_AUDIO_SETTINGS or RECORD_AUDIO permissions. | 112 // MODIFY_AUDIO_SETTINGS or RECORD_AUDIO permissions. |
| 114 return; | 113 return; |
| 115 } | 114 } |
| 116 jsize len = env->GetArrayLength(j_device_array.obj()); | 115 jsize len = env->GetArrayLength(j_device_array.obj()); |
| 117 AudioDeviceName device; | 116 AudioDeviceName device; |
| 118 for (jsize i = 0; i < len; ++i) { | 117 for (jsize i = 0; i < len; ++i) { |
| 119 ScopedJavaLocalRef<jobject> j_device( | 118 ScopedJavaLocalRef<jobject> j_device( |
| 120 env, env->GetObjectArrayElement(j_device_array.obj(), i)); | 119 env, env->GetObjectArrayElement(j_device_array.obj(), i)); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 } | 192 } |
| 194 | 193 |
| 195 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { | 194 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { |
| 196 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 195 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 197 streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); | 196 streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); |
| 198 AudioManagerBase::ReleaseOutputStream(stream); | 197 AudioManagerBase::ReleaseOutputStream(stream); |
| 199 } | 198 } |
| 200 | 199 |
| 201 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { | 200 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { |
| 202 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 201 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 203 DCHECK(!j_audio_manager_.is_null()); | |
| 204 AudioManagerBase::ReleaseInputStream(stream); | 202 AudioManagerBase::ReleaseInputStream(stream); |
| 205 | 203 |
| 206 // Restore the audio mode which was used before the first communication- | 204 // Restore the audio mode which was used before the first communication- |
| 207 // mode stream was created. | 205 // mode stream was created. |
| 208 if (HasNoAudioInputStreams()) { | 206 if (HasNoAudioInputStreams()) { |
| 209 communication_mode_is_on_ = false; | 207 communication_mode_is_on_ = false; |
| 210 SetCommunicationAudioModeOn(false); | 208 SetCommunicationAudioModeOn(false); |
| 211 } | 209 } |
| 212 } | 210 } |
| 213 | 211 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 buffer_size = user_buffer_size; | 340 buffer_size = user_buffer_size; |
| 343 | 341 |
| 344 return AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, | 342 return AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, |
| 345 sample_rate, bits_per_sample, buffer_size); | 343 sample_rate, bits_per_sample, buffer_size); |
| 346 } | 344 } |
| 347 | 345 |
| 348 bool AudioManagerAndroid::HasNoAudioInputStreams() { | 346 bool AudioManagerAndroid::HasNoAudioInputStreams() { |
| 349 return input_stream_count() == 0; | 347 return input_stream_count() == 0; |
| 350 } | 348 } |
| 351 | 349 |
| 352 void AudioManagerAndroid::InitializeOnAudioThread() { | 350 jobject AudioManagerAndroid::GetJavaAudioManager() { |
| 353 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 351 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 352 if (j_audio_manager_.is_null()) { |
| 353 // Create the Android audio manager on the audio thread. |
| 354 DVLOG(2) << "Creating Java part of the audio manager"; |
| 355 j_audio_manager_.Reset(Java_AudioManagerAndroid_createAudioManagerAndroid( |
| 356 base::android::AttachCurrentThread(), |
| 357 base::android::GetApplicationContext(), |
| 358 reinterpret_cast<intptr_t>(this))); |
| 354 | 359 |
| 355 // Create the Android audio manager on the audio thread. | 360 // Prepare the list of audio devices and register receivers for device |
| 356 DVLOG(2) << "Creating Java part of the audio manager"; | 361 // notifications. |
| 357 j_audio_manager_.Reset( | 362 Java_AudioManagerAndroid_init(base::android::AttachCurrentThread(), |
| 358 Java_AudioManagerAndroid_createAudioManagerAndroid( | 363 j_audio_manager_.obj()); |
| 359 base::android::AttachCurrentThread(), | 364 } |
| 360 base::android::GetApplicationContext(), | 365 return j_audio_manager_.obj(); |
| 361 reinterpret_cast<intptr_t>(this))); | |
| 362 | |
| 363 // Prepare the list of audio devices and register receivers for device | |
| 364 // notifications. | |
| 365 Java_AudioManagerAndroid_init( | |
| 366 base::android::AttachCurrentThread(), | |
| 367 j_audio_manager_.obj()); | |
| 368 } | 366 } |
| 369 | 367 |
| 370 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { | 368 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { |
| 371 Java_AudioManagerAndroid_setCommunicationAudioModeOn( | 369 Java_AudioManagerAndroid_setCommunicationAudioModeOn( |
| 372 base::android::AttachCurrentThread(), | 370 base::android::AttachCurrentThread(), GetJavaAudioManager(), on); |
| 373 j_audio_manager_.obj(), on); | |
| 374 } | 371 } |
| 375 | 372 |
| 376 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { | 373 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { |
| 377 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 374 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 378 | 375 |
| 379 // Send the unique device ID to the Java audio manager and make the | 376 // Send the unique device ID to the Java audio manager and make the |
| 380 // device switch. Provide an empty string to the Java audio manager | 377 // device switch. Provide an empty string to the Java audio manager |
| 381 // if the default device is selected. | 378 // if the default device is selected. |
| 382 JNIEnv* env = AttachCurrentThread(); | 379 JNIEnv* env = AttachCurrentThread(); |
| 383 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( | 380 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( |
| 384 env, device_id == AudioDeviceDescription::kDefaultDeviceId ? std::string() | 381 env, device_id == AudioDeviceDescription::kDefaultDeviceId ? std::string() |
| 385 : device_id); | 382 : device_id); |
| 386 return Java_AudioManagerAndroid_setDevice( | 383 return Java_AudioManagerAndroid_setDevice(env, GetJavaAudioManager(), |
| 387 env, j_audio_manager_.obj(), j_device_id.obj()); | 384 j_device_id.obj()); |
| 388 } | 385 } |
| 389 | 386 |
| 390 int AudioManagerAndroid::GetNativeOutputSampleRate() { | 387 int AudioManagerAndroid::GetNativeOutputSampleRate() { |
| 391 return Java_AudioManagerAndroid_getNativeOutputSampleRate( | 388 return Java_AudioManagerAndroid_getNativeOutputSampleRate( |
| 392 base::android::AttachCurrentThread(), | 389 base::android::AttachCurrentThread(), GetJavaAudioManager()); |
| 393 j_audio_manager_.obj()); | |
| 394 } | 390 } |
| 395 | 391 |
| 396 bool AudioManagerAndroid::IsAudioLowLatencySupported() { | 392 bool AudioManagerAndroid::IsAudioLowLatencySupported() { |
| 397 return Java_AudioManagerAndroid_isAudioLowLatencySupported( | 393 return Java_AudioManagerAndroid_isAudioLowLatencySupported( |
| 398 base::android::AttachCurrentThread(), | 394 base::android::AttachCurrentThread(), GetJavaAudioManager()); |
| 399 j_audio_manager_.obj()); | |
| 400 } | 395 } |
| 401 | 396 |
| 402 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { | 397 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { |
| 403 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( | 398 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( |
| 404 base::android::AttachCurrentThread(), | 399 base::android::AttachCurrentThread(), GetJavaAudioManager()); |
| 405 j_audio_manager_.obj()); | |
| 406 } | 400 } |
| 407 | 401 |
| 408 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, | 402 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, |
| 409 int channels) { | 403 int channels) { |
| 410 if (IsAudioLowLatencySupported()) | 404 if (IsAudioLowLatencySupported()) |
| 411 return GetAudioLowLatencyOutputFrameSize(); | 405 return GetAudioLowLatencyOutputFrameSize(); |
| 412 | 406 |
| 413 return std::max(kDefaultOutputBufferSize, | 407 return std::max(kDefaultOutputBufferSize, |
| 414 Java_AudioManagerAndroid_getMinOutputFrameSize( | 408 Java_AudioManagerAndroid_getMinOutputFrameSize( |
| 415 base::android::AttachCurrentThread(), | 409 base::android::AttachCurrentThread(), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 429 output_volume_override_ = volume; | 423 output_volume_override_ = volume; |
| 430 | 424 |
| 431 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 425 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 432 for (OutputStreams::iterator it = streams_.begin(); | 426 for (OutputStreams::iterator it = streams_.begin(); |
| 433 it != streams_.end(); ++it) { | 427 it != streams_.end(); ++it) { |
| 434 (*it)->SetVolume(volume); | 428 (*it)->SetVolume(volume); |
| 435 } | 429 } |
| 436 } | 430 } |
| 437 | 431 |
| 438 } // namespace media | 432 } // namespace media |
| OLD | NEW |