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 |