Headset plug/unplug detection

This commit is contained in:
Gabriel Calero 2018-09-12 16:36:04 -03:00
parent 2d2a4804f7
commit 2943502c9b
4 changed files with 39 additions and 14 deletions

View file

@ -13,8 +13,6 @@ public class HeadsetStateReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
Log.d("[HEADSET] " , "BR - Wired headset on:" + audioManager.isWiredHeadsetOn());
notifyHeadsetOn(audioManager.isWiredHeadsetOn()); notifyHeadsetOn(audioManager.isWiredHeadsetOn());
} }
} }

View file

@ -63,13 +63,7 @@ void AndroidHelper::notifyHeadsetOn(bool pluggedIn) {
#if defined (Q_OS_ANDROID) #if defined (Q_OS_ANDROID)
auto audioClient = DependencyManager::get<AudioClient>(); auto audioClient = DependencyManager::get<AudioClient>();
if (audioClient) { if (audioClient) {
QAudioDeviceInfo activeDev = audioClient->getActiveAudioDevice(QAudio::AudioInput); QMetaObject::invokeMethod(audioClient.data(), "setHeadsetPluggedIn", Q_ARG(bool, pluggedIn));
Setting::Handle<bool> enableAEC(QStringList() << ANDROID_SETTINGS_GROUP << SETTING_AEC_KEY, false);
if ((pluggedIn || !enableAEC.get()) && !activeDev.isNull() && activeDev.deviceName() != VOICE_RECOGNITION) {
QMetaObject::invokeMethod(audioClient.get(), "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(QString, VOICE_RECOGNITION));
} else if ( (!pluggedIn && enableAEC.get()) && !activeDev.isNull() && activeDev.deviceName() != VOICE_COMMUNICATION) {
QMetaObject::invokeMethod(audioClient.get(), "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(QString, VOICE_COMMUNICATION));
}
} }
#endif #endif
} }

View file

@ -209,6 +209,7 @@ AudioClient::AudioClient() :
_positionGetter(DEFAULT_POSITION_GETTER), _positionGetter(DEFAULT_POSITION_GETTER),
#if defined(Q_OS_ANDROID) #if defined(Q_OS_ANDROID)
_checkInputTimer(this), _checkInputTimer(this),
_isHeadsetPluggedIn(false),
#endif #endif
_orientationGetter(DEFAULT_ORIENTATION_GETTER) { _orientationGetter(DEFAULT_ORIENTATION_GETTER) {
// avoid putting a lock in the device callback // avoid putting a lock in the device callback
@ -450,12 +451,14 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
#if defined (Q_OS_ANDROID) #if defined (Q_OS_ANDROID)
if (mode == QAudio::AudioInput) { if (mode == QAudio::AudioInput) {
Setting::Handle<bool> enableAEC(QStringList() << ANDROID_SETTINGS_GROUP << SETTING_AEC_KEY, false); Setting::Handle<bool> enableAEC(SETTING_AEC_KEY, false);
bool aecEnabled = enableAEC.get(); bool aecEnabled = enableAEC.get();
auto audioClient = DependencyManager::get<AudioClient>();
bool headsetOn = audioClient? audioClient->isHeadsetPluggedIn() : false ;
auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
for (auto inputDevice : inputDevices) { for (auto inputDevice : inputDevices) {
if ((aecEnabled && inputDevice.deviceName() == VOICE_COMMUNICATION) || if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) ||
(!aecEnabled && inputDevice.deviceName() == VOICE_RECOGNITION)) { ((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) {
return inputDevice; return inputDevice;
} }
} }
@ -1632,6 +1635,29 @@ void AudioClient::checkInputTimeout() {
#endif #endif
} }
void AudioClient::setHeadsetPluggedIn(bool pluggedIn) {
#if defined(Q_OS_ANDROID)
if (pluggedIn == !_isHeadsetPluggedIn && !_inputDeviceInfo.isNull()) {
QAndroidJniObject brand = QAndroidJniObject::getStaticObjectField<jstring>("android/os/Build", "BRAND");
// some samsung phones needs more time to shutdown the previous input device
if (brand.toString().contains("samsung", Qt::CaseInsensitive)) {
switchInputToAudioDevice(QAudioDeviceInfo(), true);
QThread::msleep(200);
}
Setting::Handle<bool> enableAEC(SETTING_AEC_KEY, false);
bool aecEnabled = enableAEC.get();
if ((pluggedIn || !aecEnabled) && _inputDeviceInfo.deviceName() != VOICE_RECOGNITION) {
switchAudioDevice(QAudio::AudioInput, VOICE_RECOGNITION);
} else if (!pluggedIn && aecEnabled && _inputDeviceInfo.deviceName() != VOICE_COMMUNICATION) {
switchAudioDevice(QAudio::AudioInput, VOICE_COMMUNICATION);
}
}
_isHeadsetPluggedIn = pluggedIn;
#endif
}
void AudioClient::outputNotify() { void AudioClient::outputNotify() {
int recentUnfulfilled = _audioOutputIODevice.getRecentUnfulfilledReads(); int recentUnfulfilled = _audioOutputIODevice.getRecentUnfulfilledReads();
if (recentUnfulfilled > 0) { if (recentUnfulfilled > 0) {

View file

@ -68,8 +68,7 @@
#define VOICE_RECOGNITION "voicerecognition" #define VOICE_RECOGNITION "voicerecognition"
#define VOICE_COMMUNICATION "voicecommunication" #define VOICE_COMMUNICATION "voicecommunication"
#define ANDROID_SETTINGS_GROUP "Android" #define SETTING_AEC_KEY "Android/aec"
#define SETTING_AEC_KEY "aec"
#endif #endif
class QAudioInput; class QAudioInput;
@ -176,6 +175,10 @@ public:
static QString getWinDeviceName(wchar_t* guid); static QString getWinDeviceName(wchar_t* guid);
#endif #endif
#if defined(Q_OS_ANDROID)
bool isHeadsetPluggedIn() { return _isHeadsetPluggedIn; }
#endif
public slots: public slots:
void start(); void start();
void stop(); void stop();
@ -224,6 +227,9 @@ public slots:
bool switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo = QAudioDeviceInfo()); bool switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo = QAudioDeviceInfo());
bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName); bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName);
// Qt opensles plugin is not able to detect when the headset is plugged in
void setHeadsetPluggedIn(bool pluggedIn);
float getInputVolume() const { return (_audioInput) ? (float)_audioInput->volume() : 0.0f; } float getInputVolume() const { return (_audioInput) ? (float)_audioInput->volume() : 0.0f; }
void setInputVolume(float volume, bool emitSignal = true); void setInputVolume(float volume, bool emitSignal = true);
void setReverb(bool reverb); void setReverb(bool reverb);
@ -285,6 +291,7 @@ private:
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
QTimer _checkInputTimer; QTimer _checkInputTimer;
long _inputReadsSinceLastCheck = 0l; long _inputReadsSinceLastCheck = 0l;
bool _isHeadsetPluggedIn;
#endif #endif
class Gate { class Gate {