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