| 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/audio_manager_base.h" | 5 #include "media/audio/audio_manager_base.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 #endif | 59 #endif |
| 60 #if defined(OS_MACOSX) | 60 #if defined(OS_MACOSX) |
| 61 // On Mac, use a UI loop to get native message pump so that CoreAudio property | 61 // On Mac, use a UI loop to get native message pump so that CoreAudio property |
| 62 // listener callbacks fire. | 62 // listener callbacks fire. |
| 63 CHECK(audio_thread_->StartWithOptions( | 63 CHECK(audio_thread_->StartWithOptions( |
| 64 base::Thread::Options(MessageLoop::TYPE_UI, 0))); | 64 base::Thread::Options(MessageLoop::TYPE_UI, 0))); |
| 65 #else | 65 #else |
| 66 CHECK(audio_thread_->Start()); | 66 CHECK(audio_thread_->Start()); |
| 67 #endif | 67 #endif |
| 68 message_loop_ = audio_thread_->message_loop_proxy(); | 68 message_loop_ = audio_thread_->message_loop_proxy(); |
| 69 | |
| 70 #if defined(OS_ANDROID) | |
| 71 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 72 jobject context = base::android::GetApplicationContext(); | |
| 73 j_audio_manager_.Reset( | |
| 74 Java_AudioManagerAndroid_createAudioManagerAndroid(env, context)); | |
| 75 #endif | |
| 76 } | 69 } |
| 77 | 70 |
| 78 AudioManagerBase::~AudioManagerBase() { | 71 AudioManagerBase::~AudioManagerBase() { |
| 79 // The platform specific AudioManager implementation must have already | 72 // The platform specific AudioManager implementation must have already |
| 80 // stopped the audio thread. Otherwise, we may destroy audio streams before | 73 // stopped the audio thread. Otherwise, we may destroy audio streams before |
| 81 // stopping the thread, resulting an unexpected behavior. | 74 // stopping the thread, resulting an unexpected behavior. |
| 82 // This way we make sure activities of the audio streams are all stopped | 75 // This way we make sure activities of the audio streams are all stopped |
| 83 // before we destroy them. | 76 // before we destroy them. |
| 84 CHECK(!audio_thread_.get()); | 77 CHECK(!audio_thread_.get()); |
| 85 // All the output streams should have been deleted. | 78 // All the output streams should have been deleted. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 base::Unretained(this))); | 125 base::Unretained(this))); |
| 133 #endif | 126 #endif |
| 134 } else if (params.format() == AudioParameters::AUDIO_FAKE) { | 127 } else if (params.format() == AudioParameters::AUDIO_FAKE) { |
| 135 stream = FakeAudioOutputStream::MakeFakeStream(this, params); | 128 stream = FakeAudioOutputStream::MakeFakeStream(this, params); |
| 136 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { | 129 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { |
| 137 stream = MakeLinearOutputStream(params); | 130 stream = MakeLinearOutputStream(params); |
| 138 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 131 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
| 139 stream = MakeLowLatencyOutputStream(params); | 132 stream = MakeLowLatencyOutputStream(params); |
| 140 } | 133 } |
| 141 | 134 |
| 142 if (stream) { | 135 if (stream) |
| 143 ++num_output_streams_; | 136 ++num_output_streams_; |
| 144 #if defined(OS_ANDROID) | |
| 145 if (num_output_streams_ == 1) | |
| 146 RegisterHeadsetReceiver(); | |
| 147 #endif | |
| 148 } | |
| 149 | 137 |
| 150 return stream; | 138 return stream; |
| 151 } | 139 } |
| 152 | 140 |
| 153 AudioInputStream* AudioManagerBase::MakeAudioInputStream( | 141 AudioInputStream* AudioManagerBase::MakeAudioInputStream( |
| 154 const AudioParameters& params, const std::string& device_id) { | 142 const AudioParameters& params, const std::string& device_id) { |
| 155 // TODO(miu): Fix ~20 call points across several unit test modules to call | 143 // TODO(miu): Fix ~20 call points across several unit test modules to call |
| 156 // this method on the audio thread, then uncomment the following: | 144 // this method on the audio thread, then uncomment the following: |
| 157 // DCHECK(message_loop_->BelongsToCurrentThread()); | 145 // DCHECK(message_loop_->BelongsToCurrentThread()); |
| 158 | 146 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 } | 191 } |
| 204 #endif | 192 #endif |
| 205 } else if (params.format() == AudioParameters::AUDIO_FAKE) { | 193 } else if (params.format() == AudioParameters::AUDIO_FAKE) { |
| 206 stream = FakeAudioInputStream::MakeFakeStream(this, params); | 194 stream = FakeAudioInputStream::MakeFakeStream(this, params); |
| 207 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { | 195 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { |
| 208 stream = MakeLinearInputStream(params, device_id); | 196 stream = MakeLinearInputStream(params, device_id); |
| 209 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 197 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
| 210 stream = MakeLowLatencyInputStream(params, device_id); | 198 stream = MakeLowLatencyInputStream(params, device_id); |
| 211 } | 199 } |
| 212 | 200 |
| 213 if (stream) { | 201 if (stream) |
| 214 ++num_input_streams_; | 202 ++num_input_streams_; |
| 203 |
| 215 #if defined(OS_ANDROID) | 204 #if defined(OS_ANDROID) |
| 216 if (num_input_streams_ == 1) | 205 if (num_input_streams_ == 1) |
| 217 SetAudioMode(kAudioModeInCommunication); | 206 SetAudioMode(kAudioModeInCommunication); |
| 218 #endif | 207 #endif |
| 219 } | |
| 220 | 208 |
| 221 return stream; | 209 return stream; |
| 222 } | 210 } |
| 223 | 211 |
| 224 AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( | 212 AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( |
| 225 const AudioParameters& params) { | 213 const AudioParameters& params) { |
| 226 #if defined(OS_IOS) | 214 #if defined(OS_IOS) |
| 227 // IOS implements audio input only. | 215 // IOS implements audio input only. |
| 228 NOTIMPLEMENTED(); | 216 NOTIMPLEMENTED(); |
| 229 return NULL; | 217 return NULL; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 media::AudioDeviceNames* device_names) { | 291 media::AudioDeviceNames* device_names) { |
| 304 } | 292 } |
| 305 | 293 |
| 306 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { | 294 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { |
| 307 DCHECK(stream); | 295 DCHECK(stream); |
| 308 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. | 296 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. |
| 309 // For example, pass the ownership to AudioManager so it can delete the | 297 // For example, pass the ownership to AudioManager so it can delete the |
| 310 // streams. | 298 // streams. |
| 311 --num_output_streams_; | 299 --num_output_streams_; |
| 312 delete stream; | 300 delete stream; |
| 313 #if defined(OS_ANDROID) | |
| 314 if (!num_output_streams_) | |
| 315 UnregisterHeadsetReceiver(); | |
| 316 #endif | |
| 317 } | 301 } |
| 318 | 302 |
| 319 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { | 303 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { |
| 320 DCHECK(stream); | 304 DCHECK(stream); |
| 321 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. | 305 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. |
| 322 --num_input_streams_; | 306 --num_input_streams_; |
| 323 delete stream; | 307 delete stream; |
| 324 #if defined(OS_ANDROID) | 308 #if defined(OS_ANDROID) |
| 325 if (!num_input_streams_) | 309 if (!num_input_streams_) |
| 326 SetAudioMode(kAudioModeNormal); | 310 SetAudioMode(kAudioModeNormal); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 } | 433 } |
| 450 | 434 |
| 451 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { | 435 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { |
| 452 DCHECK(message_loop_->BelongsToCurrentThread()); | 436 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 453 DVLOG(1) << "Firing OnDeviceChange() notifications."; | 437 DVLOG(1) << "Firing OnDeviceChange() notifications."; |
| 454 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); | 438 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); |
| 455 } | 439 } |
| 456 | 440 |
| 457 #if defined(OS_ANDROID) | 441 #if defined(OS_ANDROID) |
| 458 void AudioManagerBase::SetAudioMode(int mode) { | 442 void AudioManagerBase::SetAudioMode(int mode) { |
| 459 Java_AudioManagerAndroid_setMode( | 443 JNIEnv* env = base::android::AttachCurrentThread(); |
| 460 base::android::AttachCurrentThread(), | 444 jobject context = base::android::GetApplicationContext(); |
| 461 j_audio_manager_.obj(), mode); | 445 DCHECK(context); |
| 446 |
| 447 Java_AudioManagerAndroid_setMode(env, context, mode); |
| 462 } | 448 } |
| 463 | 449 #endif |
| 464 void AudioManagerBase::RegisterHeadsetReceiver() { | |
| 465 Java_AudioManagerAndroid_registerHeadsetReceiver( | |
| 466 base::android::AttachCurrentThread(), | |
| 467 j_audio_manager_.obj()); | |
| 468 } | |
| 469 | |
| 470 void AudioManagerBase::UnregisterHeadsetReceiver() { | |
| 471 Java_AudioManagerAndroid_unregisterHeadsetReceiver( | |
| 472 base::android::AttachCurrentThread(), | |
| 473 j_audio_manager_.obj()); | |
| 474 } | |
| 475 #endif // defined(OS_ANDROID) | |
| 476 | 450 |
| 477 } // namespace media | 451 } // namespace media |
| OLD | NEW |