Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(849)

Side by Side Diff: media/audio/android/audio_manager_android.cc

Issue 131503006: Initialization of audio manager for Android is now done on the audio thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nit Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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(
73 AudioDeviceNames* device_names) { 68 AudioDeviceNames* device_names) {
69 CreateAndInitOnAudioThread();
70
74 // Always add default device parameters as first element. 71 // Always add default device parameters as first element.
75 DCHECK(device_names->empty()); 72 DCHECK(device_names->empty());
76 AddDefaultDevice(device_names); 73 AddDefaultDevice(device_names);
77 74
75 // Get list of available audio devices.
78 JNIEnv* env = AttachCurrentThread(); 76 JNIEnv* env = AttachCurrentThread();
79 ScopedJavaLocalRef<jobjectArray> j_device_array = 77 ScopedJavaLocalRef<jobjectArray> j_device_array =
80 Java_AudioManagerAndroid_getAudioInputDeviceNames( 78 Java_AudioManagerAndroid_getAudioInputDeviceNames(
81 env, j_audio_manager_.obj()); 79 env, j_audio_manager_.obj());
82 jsize len = env->GetArrayLength(j_device_array.obj()); 80 jsize len = env->GetArrayLength(j_device_array.obj());
83 AudioDeviceName device; 81 AudioDeviceName device;
84 for (jsize i = 0; i < len; ++i) { 82 for (jsize i = 0; i < len; ++i) {
85 ScopedJavaLocalRef<jobject> j_device( 83 ScopedJavaLocalRef<jobject> j_device(
86 env, env->GetObjectArrayElement(j_device_array.obj(), i)); 84 env, env->GetObjectArrayElement(j_device_array.obj(), i));
87 ScopedJavaLocalRef<jstring> j_device_name = 85 ScopedJavaLocalRef<jstring> j_device_name =
88 Java_AudioDeviceName_name(env, j_device.obj()); 86 Java_AudioDeviceName_name(env, j_device.obj());
89 ConvertJavaStringToUTF8(env, j_device_name.obj(), &device.device_name); 87 ConvertJavaStringToUTF8(env, j_device_name.obj(), &device.device_name);
90 ScopedJavaLocalRef<jstring> j_device_id = 88 ScopedJavaLocalRef<jstring> j_device_id =
91 Java_AudioDeviceName_id(env, j_device.obj()); 89 Java_AudioDeviceName_id(env, j_device.obj());
92 ConvertJavaStringToUTF8(env, j_device_id.obj(), &device.unique_id); 90 ConvertJavaStringToUTF8(env, j_device_id.obj(), &device.unique_id);
93 device_names->push_back(device); 91 device_names->push_back(device);
94 } 92 }
95 } 93 }
96 94
97 void AudioManagerAndroid::GetAudioOutputDeviceNames( 95 void AudioManagerAndroid::GetAudioOutputDeviceNames(
98 AudioDeviceNames* device_names) { 96 AudioDeviceNames* device_names) {
99 // TODO(henrika): enumerate using GetAudioInputDeviceNames(). 97 // TODO(henrika): enumerate using GetAudioInputDeviceNames().
100 AddDefaultDevice(device_names); 98 AddDefaultDevice(device_names);
101 } 99 }
102 100
103 AudioParameters AudioManagerAndroid::GetInputStreamParameters( 101 AudioParameters AudioManagerAndroid::GetInputStreamParameters(
104 const std::string& device_id) { 102 const std::string& device_id) {
105 JNIEnv* env = AttachCurrentThread(); 103 CreateAndInitOnAudioThread();
104
106 // Use mono as preferred number of input channels on Android to save 105 // Use mono as preferred number of input channels on Android to save
107 // resources. Using mono also avoids a driver issue seen on Samsung 106 // resources. Using mono also avoids a driver issue seen on Samsung
108 // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details. 107 // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details.
108 JNIEnv* env = AttachCurrentThread();
109 CHECK(env);
109 ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO; 110 ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
110 int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize( 111 int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize(
111 env, GetNativeOutputSampleRate(), 112 env, GetNativeOutputSampleRate(),
112 ChannelLayoutToChannelCount(channel_layout)); 113 ChannelLayoutToChannelCount(channel_layout));
113 int effects = AudioParameters::NO_EFFECTS; 114 int effects = AudioParameters::NO_EFFECTS;
114 effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ? 115 effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ?
115 AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS; 116 AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS;
116 AudioParameters params( 117 AudioParameters params(
117 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0, 118 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0,
118 GetNativeOutputSampleRate(), 16, 119 GetNativeOutputSampleRate(), 16,
119 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects); 120 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects);
120 return params; 121 return params;
121 } 122 }
122 123
123 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( 124 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream(
124 const AudioParameters& params, 125 const AudioParameters& params,
125 const std::string& device_id) { 126 const std::string& device_id) {
126 bool had_no_streams = HadNoAudioStreams(); 127 CreateAndInitOnAudioThread();
128 bool has_no_streams = HasNoAudioStreams();
127 AudioOutputStream* stream = 129 AudioOutputStream* stream =
128 AudioManagerBase::MakeAudioOutputStream(params, std::string()); 130 AudioManagerBase::MakeAudioOutputStream(params, std::string());
129 131
130 // The audio manager for Android creates streams intended for real-time 132 // The audio manager for Android creates streams intended for real-time
131 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. 133 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION.
132 // If a Bluetooth headset is used, the audio stream will use the SCO 134 // If a Bluetooth headset is selected, the audio stream will use the SCO
133 // channel and therefore have a limited bandwidth (8-16kHz). 135 // channel and therefore have a limited bandwidth (8-16kHz).
134 if (stream && had_no_streams) 136 if (stream && has_no_streams)
135 SetCommunicationAudioModeOn(true); 137 SetCommunicationAudioModeOn(true);
136 138
137 { 139 streams_.insert(static_cast<OpenSLESOutputStream*>(stream));
138 base::AutoLock lock(streams_lock_);
139 streams_.insert(static_cast<OpenSLESOutputStream*>(stream));
140 }
141 140
142 return stream; 141 return stream;
143 } 142 }
144 143
145 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( 144 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream(
146 const AudioParameters& params, const std::string& device_id) { 145 const AudioParameters& params, const std::string& device_id) {
147 bool had_no_streams = HadNoAudioStreams(); 146 CreateAndInitOnAudioThread();
147 bool has_no_streams = HasNoAudioStreams();
148 AudioInputStream* stream = 148 AudioInputStream* stream =
149 AudioManagerBase::MakeAudioInputStream(params, device_id); 149 AudioManagerBase::MakeAudioInputStream(params, device_id);
150 150
151 // The audio manager for Android creates streams intended for real-time 151 // The audio manager for Android creates streams intended for real-time
152 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. 152 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION.
153 // If a Bluetooth headset is used, the audio stream will use the SCO 153 // If a Bluetooth headset is used, the audio stream will use the SCO
154 // channel and therefore have a limited bandwidth (8kHz). 154 // channel and therefore have a limited bandwidth (8kHz).
155 if (stream && had_no_streams) 155 if (stream && has_no_streams)
156 SetCommunicationAudioModeOn(true); 156 SetCommunicationAudioModeOn(true);
157 return stream; 157 return stream;
158 } 158 }
159 159
160 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { 160 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) {
161 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
161 AudioManagerBase::ReleaseOutputStream(stream); 162 AudioManagerBase::ReleaseOutputStream(stream);
162 163
163 // Restore the audio mode which was used before the first communication- 164 // Restore the audio mode which was used before the first communication-
164 // mode stream was created. 165 // mode stream was created.
165 if (HadNoAudioStreams()) 166 if (HasNoAudioStreams())
166 SetCommunicationAudioModeOn(false); 167 SetCommunicationAudioModeOn(false);
167 base::AutoLock lock(streams_lock_); 168
168 streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); 169 streams_.erase(static_cast<OpenSLESOutputStream*>(stream));
169 } 170 }
170 171
171 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { 172 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) {
173 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
174 DCHECK(!j_audio_manager_.is_null());
172 AudioManagerBase::ReleaseInputStream(stream); 175 AudioManagerBase::ReleaseInputStream(stream);
173 176
174 // Restore the audio mode which was used before the first communication- 177 // Restore the audio mode which was used before the first communication-
175 // mode stream was created. 178 // mode stream was created.
176 if (HadNoAudioStreams()) 179 if (HasNoAudioStreams())
177 SetCommunicationAudioModeOn(false); 180 SetCommunicationAudioModeOn(false);
178 } 181 }
179 182
180 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( 183 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream(
181 const AudioParameters& params) { 184 const AudioParameters& params) {
182 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 185 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
183 return new OpenSLESOutputStream(this, params); 186 return new OpenSLESOutputStream(this, params);
184 } 187 }
185 188
186 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( 189 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream(
187 const AudioParameters& params, 190 const AudioParameters& params,
188 const std::string& device_id) { 191 const std::string& device_id) {
189 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 192 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
190 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 193 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
194 CreateAndInitOnAudioThread();
191 return new OpenSLESOutputStream(this, params); 195 return new OpenSLESOutputStream(this, params);
192 } 196 }
193 197
194 AudioInputStream* AudioManagerAndroid::MakeLinearInputStream( 198 AudioInputStream* AudioManagerAndroid::MakeLinearInputStream(
195 const AudioParameters& params, const std::string& device_id) { 199 const AudioParameters& params, const std::string& device_id) {
196 // TODO(henrika): add support for device selection if/when any client 200 // TODO(henrika): add support for device selection if/when any client
197 // needs it. 201 // needs it.
198 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 202 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
199 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 203 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
204 CreateAndInitOnAudioThread();
200 return new OpenSLESInputStream(this, params); 205 return new OpenSLESInputStream(this, params);
201 } 206 }
202 207
203 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( 208 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream(
204 const AudioParameters& params, const std::string& device_id) { 209 const AudioParameters& params, const std::string& device_id) {
205 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 210 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
206 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; 211 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!";
212 CreateAndInitOnAudioThread();
213
207 // Use the device ID to select the correct input device. 214 // Use the device ID to select the correct input device.
208 // Note that the input device is always associated with a certain output 215 // Note that the input device is always associated with a certain output
209 // device, i.e., this selection does also switch the output device. 216 // device, i.e., this selection does also switch the output device.
210 // All input and output streams will be affected by the device selection. 217 // All input and output streams will be affected by the device selection.
211 if (!SetAudioDevice(device_id)) { 218 if (!SetAudioDevice(device_id)) {
212 LOG(ERROR) << "Unable to select audio device!"; 219 LOG(ERROR) << "Unable to select audio device!";
213 return NULL; 220 return NULL;
214 } 221 }
215 222
216 if (params.effects() != AudioParameters::NO_EFFECTS) { 223 if (params.effects() != AudioParameters::NO_EFFECTS) {
217 // Platform effects can only be enabled through the AudioRecord path. 224 // Platform effects can only be enabled through the AudioRecord path.
218 // An effect should only have been requested here if recommended by 225 // An effect should only have been requested here if recommended by
219 // AudioManagerAndroid.shouldUse<Effect>. 226 // AudioManagerAndroid.shouldUse<Effect>.
220 // 227 //
221 // Creating this class requires Jelly Bean, which is already guaranteed by 228 // Creating this class requires Jelly Bean, which is already guaranteed by
222 // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use 229 // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use
223 // the effect settings as a way to select the input path. 230 // the effect settings as a way to select the input path.
224 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16); 231 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16);
225 DVLOG(1) << "Creating AudioRecordInputStream"; 232 DVLOG(1) << "Creating AudioRecordInputStream";
226 return new AudioRecordInputStream(this, params); 233 return new AudioRecordInputStream(this, params);
227 } 234 }
228 DVLOG(1) << "Creating OpenSLESInputStream"; 235 DVLOG(1) << "Creating OpenSLESInputStream";
229 return new OpenSLESInputStream(this, params); 236 return new OpenSLESInputStream(this, params);
230 } 237 }
231 238
232 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, 239 // static
233 int channels) { 240 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) {
234 if (IsAudioLowLatencySupported()) { 241 return RegisterNativesImpl(env);
235 return GetAudioLowLatencyOutputFrameSize(); 242 }
236 } else { 243
237 return std::max(kDefaultOutputBufferSize, 244 void AudioManagerAndroid::SetMute(JNIEnv* env, jobject obj, jboolean muted) {
238 Java_AudioManagerAndroid_getMinOutputFrameSize( 245 GetTaskRunner()->PostTask(
239 base::android::AttachCurrentThread(), 246 FROM_HERE,
240 sample_rate, channels)); 247 base::Bind(
241 } 248 &AudioManagerAndroid::DoSetMuteOnAudioThread,
249 base::Unretained(this),
250 muted));
242 } 251 }
243 252
244 AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters( 253 AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters(
245 const std::string& output_device_id, 254 const std::string& output_device_id,
246 const AudioParameters& input_params) { 255 const AudioParameters& input_params) {
256 CreateAndInitOnAudioThread();
DaleCurtis 2014/02/18 19:13:14 You mention in the description that you wanted to
henrika (OOO until Aug 14) 2014/02/19 10:37:01 It started out with the crash reported here: https
tommi (sloooow) - chröme 2014/02/19 10:48:35 Yes, I think that's (Dale's suggestion) a good ide
henrika (OOO until Aug 14) 2014/02/19 13:45:13 Done.
257
247 // TODO(tommi): Support |output_device_id|. 258 // TODO(tommi): Support |output_device_id|.
248 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; 259 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!";
249 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 260 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
250 int sample_rate = GetNativeOutputSampleRate(); 261 int sample_rate = GetNativeOutputSampleRate();
251 int buffer_size = GetOptimalOutputFrameSize(sample_rate, 2); 262 int buffer_size = GetOptimalOutputFrameSize(sample_rate, 2);
252 int bits_per_sample = 16; 263 int bits_per_sample = 16;
253 int input_channels = 0; 264 int input_channels = 0;
254 if (input_params.IsValid()) { 265 if (input_params.IsValid()) {
255 // Use the client's input parameters if they are valid. 266 // Use the client's input parameters if they are valid.
256 sample_rate = input_params.sample_rate(); 267 sample_rate = input_params.sample_rate();
257 bits_per_sample = input_params.bits_per_sample(); 268 bits_per_sample = input_params.bits_per_sample();
258 channel_layout = input_params.channel_layout(); 269 channel_layout = input_params.channel_layout();
259 input_channels = input_params.input_channels(); 270 input_channels = input_params.input_channels();
260 buffer_size = GetOptimalOutputFrameSize( 271 buffer_size = GetOptimalOutputFrameSize(
261 sample_rate, ChannelLayoutToChannelCount(channel_layout)); 272 sample_rate, ChannelLayoutToChannelCount(channel_layout));
262 } 273 }
263 274
264 int user_buffer_size = GetUserBufferSize(); 275 int user_buffer_size = GetUserBufferSize();
265 if (user_buffer_size) 276 if (user_buffer_size)
266 buffer_size = user_buffer_size; 277 buffer_size = user_buffer_size;
267 278
268 return AudioParameters( 279 return AudioParameters(
269 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 280 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels,
270 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); 281 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS);
271 } 282 }
272 283
273 bool AudioManagerAndroid::HadNoAudioStreams() { 284 void AudioManagerAndroid::WillDestroyCurrentMessageLoop() {
DaleCurtis 2014/02/18 19:13:14 Regardless of the outcome from above, instead of u
henrika (OOO until Aug 14) 2014/02/19 10:37:01 Will harmonize. Thanks for pointing that out.
henrika (OOO until Aug 14) 2014/02/19 13:45:13 Done.
285 CloseOnAudioThread();
286 }
287
288 void AudioManagerAndroid::CreateAndInitOnAudioThread() {
289 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
290
291 // Ensure that we only create and initialize the Java part once.
292 if (!j_audio_manager_.is_null())
293 return;
294
295 JNIEnv* env = base::android::AttachCurrentThread();
296 CHECK(env);
297
298 // Create the Android audio manager on the audio thread.
299 DVLOG(2) << "Creating Java part of the audio manager";
300 j_audio_manager_.Reset(
301 Java_AudioManagerAndroid_createAudioManagerAndroid(
302 env,
303 base::android::GetApplicationContext(),
304 reinterpret_cast<intptr_t>(this)));
305
306 // Prepare the list of audio devices and register receivers for device
307 // notifications.
308 Init();
309
310 // Ensure that we are notified when the audio thread dies.
311 base::MessageLoop::current()->AddDestructionObserver(this);
312 }
313
314 void AudioManagerAndroid::CloseOnAudioThread() {
315 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
316 if (j_audio_manager_.is_null())
317 return;
318 Close();
319 DVLOG(2) << "Destroying Java part of the audio manager";
320 j_audio_manager_.Reset();
321 }
322
323 bool AudioManagerAndroid::HasNoAudioStreams() {
274 return output_stream_count() == 0 && input_stream_count() == 0; 324 return output_stream_count() == 0 && input_stream_count() == 0;
275 } 325 }
276 326
277 // static
278 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) {
279 return RegisterNativesImpl(env);
280 }
281
282 void AudioManagerAndroid::Init() { 327 void AudioManagerAndroid::Init() {
DaleCurtis 2014/02/18 19:13:14 These two methods are only called in one place eac
henrika (OOO until Aug 14) 2014/02/19 10:37:01 Will fix.
283 Java_AudioManagerAndroid_init( 328 Java_AudioManagerAndroid_init(
284 base::android::AttachCurrentThread(), 329 base::android::AttachCurrentThread(),
285 j_audio_manager_.obj()); 330 j_audio_manager_.obj());
286 } 331 }
287 332
288 void AudioManagerAndroid::Close() { 333 void AudioManagerAndroid::Close() {
289 Java_AudioManagerAndroid_close( 334 Java_AudioManagerAndroid_close(
290 base::android::AttachCurrentThread(), 335 base::android::AttachCurrentThread(),
291 j_audio_manager_.obj()); 336 j_audio_manager_.obj());
292 } 337 }
293 338
294 void AudioManagerAndroid::SetMute(JNIEnv* env, jobject obj, jboolean muted) {
295 GetTaskRunner()->PostTask(
296 FROM_HERE,
297 base::Bind(
298 &AudioManagerAndroid::DoSetMuteOnAudioThread,
299 base::Unretained(this),
300 muted));
301 }
302
303 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) {
304 base::AutoLock lock(streams_lock_);
305 for (OutputStreams::iterator it = streams_.begin();
306 it != streams_.end(); ++it) {
307 (*it)->SetMute(muted);
308 }
309 }
310
311 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { 339 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) {
312 Java_AudioManagerAndroid_setCommunicationAudioModeOn( 340 Java_AudioManagerAndroid_setCommunicationAudioModeOn(
313 base::android::AttachCurrentThread(), 341 base::android::AttachCurrentThread(),
314 j_audio_manager_.obj(), on); 342 j_audio_manager_.obj(), on);
315 } 343 }
316 344
317 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { 345 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) {
318 JNIEnv* env = AttachCurrentThread(); 346 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
319 347
320 // Send the unique device ID to the Java audio manager and make the 348 // Send the unique device ID to the Java audio manager and make the
321 // device switch. Provide an empty string to the Java audio manager 349 // device switch. Provide an empty string to the Java audio manager
322 // if the default device is selected. 350 // if the default device is selected.
351 JNIEnv* env = AttachCurrentThread();
352 CHECK(env);
323 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( 353 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString(
324 env, 354 env,
325 device_id == AudioManagerBase::kDefaultDeviceId ? 355 device_id == AudioManagerBase::kDefaultDeviceId ?
326 std::string() : device_id); 356 std::string() : device_id);
327 return Java_AudioManagerAndroid_setDevice( 357 return Java_AudioManagerAndroid_setDevice(
328 env, j_audio_manager_.obj(), j_device_id.obj()); 358 env, j_audio_manager_.obj(), j_device_id.obj());
329 } 359 }
330 360
331 int AudioManagerAndroid::GetNativeOutputSampleRate() { 361 int AudioManagerAndroid::GetNativeOutputSampleRate() {
332 return Java_AudioManagerAndroid_getNativeOutputSampleRate( 362 return Java_AudioManagerAndroid_getNativeOutputSampleRate(
333 base::android::AttachCurrentThread(), 363 base::android::AttachCurrentThread(),
334 j_audio_manager_.obj()); 364 j_audio_manager_.obj());
335 } 365 }
336 366
337 bool AudioManagerAndroid::IsAudioLowLatencySupported() { 367 bool AudioManagerAndroid::IsAudioLowLatencySupported() {
338 return Java_AudioManagerAndroid_isAudioLowLatencySupported( 368 return Java_AudioManagerAndroid_isAudioLowLatencySupported(
339 base::android::AttachCurrentThread(), 369 base::android::AttachCurrentThread(),
340 j_audio_manager_.obj()); 370 j_audio_manager_.obj());
341 } 371 }
342 372
343 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { 373 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() {
344 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( 374 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize(
345 base::android::AttachCurrentThread(), 375 base::android::AttachCurrentThread(),
346 j_audio_manager_.obj()); 376 j_audio_manager_.obj());
347 } 377 }
348 378
379 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate,
380 int channels) {
381 if (IsAudioLowLatencySupported()) {
382 return GetAudioLowLatencyOutputFrameSize();
383 } else {
384 return std::max(kDefaultOutputBufferSize,
385 Java_AudioManagerAndroid_getMinOutputFrameSize(
386 base::android::AttachCurrentThread(),
387 sample_rate, channels));
388 }
389 }
390
391 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) {
392 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
393 for (OutputStreams::iterator it = streams_.begin();
394 it != streams_.end(); ++it) {
395 (*it)->SetMute(muted);
396 }
397 }
398
349 } // namespace media 399 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/android/audio_manager_android.h ('k') | media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698