Chromium Code Reviews| 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 |