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
public void onReceive(Context context, Intent intent) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
Log.d("[HEADSET] " , "BR - Wired headset on:" + audioManager.isWiredHeadsetOn());
notifyHeadsetOn(audioManager.isWiredHeadsetOn());
}
}

View file

@ -63,13 +63,7 @@ void AndroidHelper::notifyHeadsetOn(bool pluggedIn) {
#if defined (Q_OS_ANDROID)
auto audioClient = DependencyManager::get<AudioClient>();
if (audioClient) {
QAudioDeviceInfo activeDev = audioClient->getActiveAudioDevice(QAudio::AudioInput);
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));
}
QMetaObject::invokeMethod(audioClient.data(), "setHeadsetPluggedIn", Q_ARG(bool, pluggedIn));
}
#endif
}

View file

@ -209,6 +209,7 @@ AudioClient::AudioClient() :
_positionGetter(DEFAULT_POSITION_GETTER),
#if defined(Q_OS_ANDROID)
_checkInputTimer(this),
_isHeadsetPluggedIn(false),
#endif
_orientationGetter(DEFAULT_ORIENTATION_GETTER) {
// avoid putting a lock in the device callback
@ -450,12 +451,14 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
#if defined (Q_OS_ANDROID)
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();
auto audioClient = DependencyManager::get<AudioClient>();
bool headsetOn = audioClient? audioClient->isHeadsetPluggedIn() : false ;
auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
for (auto inputDevice : inputDevices) {
if ((aecEnabled && inputDevice.deviceName() == VOICE_COMMUNICATION) ||
(!aecEnabled && inputDevice.deviceName() == VOICE_RECOGNITION)) {
if (((headsetOn || !aecEnabled) && inputDevice.deviceName() == VOICE_RECOGNITION) ||
((!headsetOn && aecEnabled) && inputDevice.deviceName() == VOICE_COMMUNICATION)) {
return inputDevice;
}
}
@ -1632,6 +1635,29 @@ void AudioClient::checkInputTimeout() {
#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() {
int recentUnfulfilled = _audioOutputIODevice.getRecentUnfulfilledReads();
if (recentUnfulfilled > 0) {

View file

@ -68,8 +68,7 @@
#define VOICE_RECOGNITION "voicerecognition"
#define VOICE_COMMUNICATION "voicecommunication"
#define ANDROID_SETTINGS_GROUP "Android"
#define SETTING_AEC_KEY "aec"
#define SETTING_AEC_KEY "Android/aec"
#endif
class QAudioInput;
@ -176,6 +175,10 @@ public:
static QString getWinDeviceName(wchar_t* guid);
#endif
#if defined(Q_OS_ANDROID)
bool isHeadsetPluggedIn() { return _isHeadsetPluggedIn; }
#endif
public slots:
void start();
void stop();
@ -224,6 +227,9 @@ public slots:
bool switchAudioDevice(QAudio::Mode mode, const QAudioDeviceInfo& deviceInfo = QAudioDeviceInfo());
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; }
void setInputVolume(float volume, bool emitSignal = true);
void setReverb(bool reverb);
@ -285,6 +291,7 @@ private:
#ifdef Q_OS_ANDROID
QTimer _checkInputTimer;
long _inputReadsSinceLastCheck = 0l;
bool _isHeadsetPluggedIn;
#endif
class Gate {