OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 package org.chromium.media; | 5 package org.chromium.media; |
6 | 6 |
7 import android.bluetooth.BluetoothAdapter; | 7 import android.bluetooth.BluetoothAdapter; |
8 import android.bluetooth.BluetoothManager; | 8 import android.bluetooth.BluetoothManager; |
9 import android.content.BroadcastReceiver; | 9 import android.content.BroadcastReceiver; |
10 import android.content.ContentResolver; | 10 import android.content.ContentResolver; |
11 import android.content.Context; | 11 import android.content.Context; |
12 import android.content.Intent; | 12 import android.content.Intent; |
13 import android.content.IntentFilter; | 13 import android.content.IntentFilter; |
14 import android.content.pm.PackageManager; | 14 import android.content.pm.PackageManager; |
15 import android.database.ContentObserver; | 15 import android.database.ContentObserver; |
16 import android.media.audiofx.AcousticEchoCanceler; | |
16 import android.media.AudioFormat; | 17 import android.media.AudioFormat; |
17 import android.media.AudioManager; | 18 import android.media.AudioManager; |
18 import android.media.AudioRecord; | 19 import android.media.AudioRecord; |
19 import android.media.AudioTrack; | 20 import android.media.AudioTrack; |
20 import android.net.Uri; | 21 import android.net.Uri; |
21 import android.os.Build; | 22 import android.os.Build; |
22 import android.os.Handler; | 23 import android.os.Handler; |
23 import android.os.Looper; | 24 import android.os.Looper; |
24 import android.os.Process; | 25 import android.os.Process; |
25 import android.provider.Settings; | 26 import android.provider.Settings; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 static final int STATE_BLUETOOTH_TURNING_OFF = 6; | 105 static final int STATE_BLUETOOTH_TURNING_OFF = 6; |
105 // TODO(henrika): document the valid state transitions. | 106 // TODO(henrika): document the valid state transitions. |
106 | 107 |
107 // Use 44.1kHz as the default sampling rate. | 108 // Use 44.1kHz as the default sampling rate. |
108 private static final int DEFAULT_SAMPLING_RATE = 44100; | 109 private static final int DEFAULT_SAMPLING_RATE = 44100; |
109 // Randomly picked up frame size which is close to return value on N4. | 110 // Randomly picked up frame size which is close to return value on N4. |
110 // Return this value when getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER) | 111 // Return this value when getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER) |
111 // fails. | 112 // fails. |
112 private static final int DEFAULT_FRAME_PER_BUFFER = 256; | 113 private static final int DEFAULT_FRAME_PER_BUFFER = 256; |
113 | 114 |
115 // List of device models which have been vetted for good quality platform | |
116 // echo cancellation. | |
117 private static final Set<String> PLATFORM_AEC_MODEL_WHITELIST = | |
henrika (OOO until Aug 14)
2013/12/06 12:52:21
Guess you can follow this example instead of using
ajm
2013/12/10 06:37:16
Done.
| |
118 new HashSet<String>(Arrays.asList(new String[] { | |
119 "Nexus 5", | |
120 "Nexus 7" | |
121 })); | |
122 | |
114 private final AudioManager mAudioManager; | 123 private final AudioManager mAudioManager; |
115 private final Context mContext; | 124 private final Context mContext; |
116 private final long mNativeAudioManagerAndroid; | 125 private final long mNativeAudioManagerAndroid; |
117 | 126 |
118 private boolean mHasBluetoothPermission = false; | 127 private boolean mHasBluetoothPermission = false; |
119 private boolean mIsInitialized = false; | 128 private boolean mIsInitialized = false; |
120 private boolean mSavedIsSpeakerphoneOn; | 129 private boolean mSavedIsSpeakerphoneOn; |
121 private boolean mSavedIsMicrophoneMute; | 130 private boolean mSavedIsMicrophoneMute; |
122 | 131 |
123 private Integer mAudioDeviceState = STATE_NO_DEVICE_SELECTED; | 132 private Integer mAudioDeviceState = STATE_NO_DEVICE_SELECTED; |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
307 i++; | 316 i++; |
308 } | 317 } |
309 } | 318 } |
310 logd("getAudioInputDeviceNames: " + devices); | 319 logd("getAudioInputDeviceNames: " + devices); |
311 return array; | 320 return array; |
312 } | 321 } |
313 } | 322 } |
314 | 323 |
315 @CalledByNative | 324 @CalledByNative |
316 private int getNativeOutputSampleRate() { | 325 private int getNativeOutputSampleRate() { |
317 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.J ELLY_BEAN_MR1) { | 326 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { |
318 String sampleRateString = mAudioManager.getProperty( | 327 String sampleRateString = mAudioManager.getProperty( |
319 AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); | 328 AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); |
320 return (sampleRateString == null ? | 329 return (sampleRateString == null ? |
321 DEFAULT_SAMPLING_RATE : Integer.parseInt(sampleRateString)); | 330 DEFAULT_SAMPLING_RATE : Integer.parseInt(sampleRateString)); |
322 } else { | 331 } else { |
323 return DEFAULT_SAMPLING_RATE; | 332 return DEFAULT_SAMPLING_RATE; |
324 } | 333 } |
325 } | 334 } |
326 | 335 |
327 /** | 336 /** |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 } | 380 } |
372 | 381 |
373 @CalledByNative | 382 @CalledByNative |
374 private int getAudioLowLatencyOutputFrameSize() { | 383 private int getAudioLowLatencyOutputFrameSize() { |
375 String framesPerBuffer = | 384 String framesPerBuffer = |
376 mAudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PE R_BUFFER); | 385 mAudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PE R_BUFFER); |
377 return (framesPerBuffer == null ? | 386 return (framesPerBuffer == null ? |
378 DEFAULT_FRAME_PER_BUFFER : Integer.parseInt(framesPerBuffer)); | 387 DEFAULT_FRAME_PER_BUFFER : Integer.parseInt(framesPerBuffer)); |
379 } | 388 } |
380 | 389 |
390 @CalledByNative | |
391 public static boolean isPlatformAECSupported() { | |
henrika (OOO until Aug 14)
2013/12/06 12:52:21
Would it make sense to name this API to something
ajm
2013/12/06 19:06:43
Except that most (all?) devices will actually repo
Ami GONE FROM CHROMIUM
2013/12/06 19:22:53
hasAcousticEchoCanceler fails to connote that this
ajm
2013/12/10 06:37:16
Sounds good.
| |
392 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { | |
393 // AcousticEchoCanceler was added in API level 16 (Jelly Bean). | |
Ami GONE FROM CHROMIUM
2013/12/06 19:22:53
Wouldn't this be accounted for by l.397?
ajm
2013/12/10 06:37:16
As I understand it, we'll get a crash if we try to
| |
394 return false; | |
395 } | |
396 | |
397 boolean isAvailable = AcousticEchoCanceler.isAvailable(); | |
398 boolean isWhitelisted = PLATFORM_AEC_MODEL_WHITELIST.contains(Build.MODE L); | |
tommi (sloooow) - chröme
2013/12/06 12:11:34
nit: Since the list contains only two items, you p
ajm
2013/12/06 19:06:43
My initial implementation had all conditions in th
ajm
2013/12/10 06:37:16
Changed as recommended now.
| |
399 logd("AcousticEchoCanceler.isAvailable: " + isAvailable); | |
400 logd("Build.MODEL: " + Build.MODEL + " isWhitelisted: " + isWhitelisted) ; | |
Ami GONE FROM CHROMIUM
2013/12/06 19:22:53
I don't think these are worth spamming logcat for.
ajm
2013/12/10 06:37:16
Done.
| |
401 return isAvailable && isWhitelisted; | |
402 } | |
403 | |
381 /** Sets the speaker phone mode. */ | 404 /** Sets the speaker phone mode. */ |
382 public void setSpeakerphoneOn(boolean on) { | 405 public void setSpeakerphoneOn(boolean on) { |
383 boolean wasOn = mAudioManager.isSpeakerphoneOn(); | 406 boolean wasOn = mAudioManager.isSpeakerphoneOn(); |
384 if (wasOn == on) { | 407 if (wasOn == on) { |
385 return; | 408 return; |
386 } | 409 } |
387 mAudioManager.setSpeakerphoneOn(on); | 410 mAudioManager.setSpeakerphoneOn(on); |
388 } | 411 } |
389 | 412 |
390 /** Sets the microphone mute state. */ | 413 /** Sets the microphone mute state. */ |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
596 } | 619 } |
597 } | 620 } |
598 | 621 |
599 private void logDeviceInfo() { | 622 private void logDeviceInfo() { |
600 Log.i(TAG, "Manufacturer:" + Build.MANUFACTURER + | 623 Log.i(TAG, "Manufacturer:" + Build.MANUFACTURER + |
601 " Board: " + Build.BOARD + " Device: " + Build.DEVICE + | 624 " Board: " + Build.BOARD + " Device: " + Build.DEVICE + |
602 " Model: " + Build.MODEL + " PRODUCT: " + Build.PRODUCT); | 625 " Model: " + Build.MODEL + " PRODUCT: " + Build.PRODUCT); |
603 } | 626 } |
604 | 627 |
605 /** Trivial helper method for debug logging */ | 628 /** Trivial helper method for debug logging */ |
606 private void logd(String msg) { | 629 private static void logd(String msg) { |
607 Log.d(TAG, msg); | 630 Log.d(TAG, msg); |
608 } | 631 } |
609 | 632 |
610 /** Trivial helper method for error logging */ | 633 /** Trivial helper method for error logging */ |
611 private void loge(String msg) { | 634 private static void loge(String msg) { |
612 Log.e(TAG, msg); | 635 Log.e(TAG, msg); |
613 } | 636 } |
614 | 637 |
615 private class SettingsObserver extends ContentObserver { | 638 private class SettingsObserver extends ContentObserver { |
616 SettingsObserver() { | 639 SettingsObserver() { |
617 super(new Handler()); | 640 super(new Handler()); |
618 mContentResolver.registerContentObserver(Settings.System.CONTENT_URI , true, this); | 641 mContentResolver.registerContentObserver(Settings.System.CONTENT_URI , true, this); |
619 } | 642 } |
620 | 643 |
621 @Override | 644 @Override |
(...skipping 19 matching lines...) Expand all Loading... | |
641 synchronized(mSettingsObserverLock) { | 664 synchronized(mSettingsObserverLock) { |
642 mSettingsObserver = new SettingsObserver(); | 665 mSettingsObserver = new SettingsObserver(); |
643 mSettingsObserverLock.notify(); | 666 mSettingsObserverLock.notify(); |
644 } | 667 } |
645 | 668 |
646 // Listen for volume change. | 669 // Listen for volume change. |
647 Looper.loop(); | 670 Looper.loop(); |
648 } | 671 } |
649 } | 672 } |
650 } | 673 } |
OLD | NEW |