Merge pull request #10747 from zzmp/audio/select-log

Log audio selections
This commit is contained in:
druiz17 2017-06-23 07:54:03 -07:00 committed by GitHub
commit 91ce9235ea
2 changed files with 85 additions and 59 deletions

View file

@ -9,18 +9,30 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <map>
#include "AudioDevices.h" #include "AudioDevices.h"
#include "Application.h" #include "Application.h"
#include "AudioClient.h" #include "AudioClient.h"
#include "Audio.h" #include "Audio.h"
#include "UserActivityLogger.h"
using namespace scripting; using namespace scripting;
Setting::Handle<QString> inputDeviceDesktop { QStringList { Audio::AUDIO, Audio::DESKTOP, "INPUT" }}; static Setting::Handle<QString> desktopInputDeviceSetting { QStringList { Audio::AUDIO, Audio::DESKTOP, "INPUT" }};
Setting::Handle<QString> outputDeviceDesktop { QStringList { Audio::AUDIO, Audio::DESKTOP, "OUTPUT" }}; static Setting::Handle<QString> desktopOutputDeviceSetting { QStringList { Audio::AUDIO, Audio::DESKTOP, "OUTPUT" }};
Setting::Handle<QString> inputDeviceHMD { QStringList { Audio::AUDIO, Audio::HMD, "INPUT" }}; static Setting::Handle<QString> hmdInputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "INPUT" }};
Setting::Handle<QString> outputDeviceHMD { QStringList { Audio::AUDIO, Audio::HMD, "OUTPUT" }}; static Setting::Handle<QString> hmdOutputDeviceSetting { QStringList { Audio::AUDIO, Audio::HMD, "OUTPUT" }};
Setting::Handle<QString>& getSetting(bool contextIsHMD, QAudio::Mode mode) {
if (mode == QAudio::AudioInput) {
return contextIsHMD ? hmdInputDeviceSetting : desktopInputDeviceSetting;
} else { // if (mode == QAudio::AudioOutput)
return contextIsHMD ? hmdOutputDeviceSetting : desktopOutputDeviceSetting;
}
}
QHash<int, QByteArray> AudioDeviceList::_roles { QHash<int, QByteArray> AudioDeviceList::_roles {
{ Qt::DisplayRole, "display" }, { Qt::DisplayRole, "display" },
@ -43,32 +55,37 @@ QVariant AudioDeviceList::data(const QModelIndex& index, int role) const {
} }
bool AudioDeviceList::setData(const QModelIndex& index, const QVariant& value, int role) { bool AudioDeviceList::setData(const QModelIndex& index, const QVariant& value, int role) {
if (!index.isValid() || index.row() >= _devices.size()) { if (!index.isValid() || index.row() >= _devices.size() || role != Qt::CheckStateRole) {
return false; return false;
} }
// only allow switching to a new device, not deactivating an in-use device
auto selected = value.toBool();
if (!selected) {
return false;
}
return setDevice(index.row(), true);
}
bool AudioDeviceList::setDevice(int row, bool fromUser) {
bool success = false; bool success = false;
auto& device = _devices[row];
if (role == Qt::CheckStateRole) { // skip if already selected
auto selected = value.toBool(); if (!device.selected) {
auto& device = _devices[index.row()]; auto client = DependencyManager::get<AudioClient>();
QMetaObject::invokeMethod(client.data(), "switchAudioDevice", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, success),
Q_ARG(QAudio::Mode, _mode),
Q_ARG(const QAudioDeviceInfo&, device.info));
// only allow switching to a new device, not deactivating an in-use device if (success) {
if (selected device.selected = true;
// skip if already selected if (fromUser) {
&& selected != device.selected) { emit deviceSelected(device.info, _selectedDevice);
auto client = DependencyManager::get<AudioClient>();
QMetaObject::invokeMethod(client.data(), "switchAudioDevice", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, success),
Q_ARG(QAudio::Mode, _mode),
Q_ARG(const QAudioDeviceInfo&, device.info));
if (success) {
device.selected = true;
emit deviceSelected(device.info);
emit deviceChanged(device.info);
} }
emit deviceChanged(device.info);
} }
} }
@ -88,12 +105,12 @@ void AudioDeviceList::resetDevice(bool contextIsHMD, const QString& device) {
} }
} }
if (i < rowCount()) { if (i < rowCount()) {
success = setData(createIndex(i, 0), true, Qt::CheckStateRole); success = setDevice(i, false);
} }
// the selection failed - reset it // the selection failed - reset it
if (!success) { if (!success) {
emit deviceSelected(QAudioDeviceInfo()); emit deviceSelected();
} }
} }
@ -167,48 +184,55 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
_inputs.onDevicesChanged(client->getAudioDevices(QAudio::AudioInput)); _inputs.onDevicesChanged(client->getAudioDevices(QAudio::AudioInput));
_outputs.onDevicesChanged(client->getAudioDevices(QAudio::AudioOutput)); _outputs.onDevicesChanged(client->getAudioDevices(QAudio::AudioOutput));
connect(&_inputs, &AudioDeviceList::deviceSelected, this, &AudioDevices::onInputDeviceSelected); connect(&_inputs, &AudioDeviceList::deviceSelected, [&](const QAudioDeviceInfo& device, const QAudioDeviceInfo& previousDevice) {
connect(&_outputs, &AudioDeviceList::deviceSelected, this, &AudioDevices::onOutputDeviceSelected); onDeviceSelected(QAudio::AudioInput, device, previousDevice);
});
connect(&_outputs, &AudioDeviceList::deviceSelected, [&](const QAudioDeviceInfo& device, const QAudioDeviceInfo& previousDevice) {
onDeviceSelected(QAudio::AudioOutput, device, previousDevice);
});
} }
void AudioDevices::onContextChanged(const QString& context) { void AudioDevices::onContextChanged(const QString& context) {
QString input; auto input = getSetting(_contextIsHMD, QAudio::AudioInput).get();
QString output; auto output = getSetting(_contextIsHMD, QAudio::AudioOutput).get();
if (_contextIsHMD) {
input = inputDeviceHMD.get();
output = outputDeviceHMD.get();
} else {
input = inputDeviceDesktop.get();
output = outputDeviceDesktop.get();
}
_inputs.resetDevice(_contextIsHMD, input); _inputs.resetDevice(_contextIsHMD, input);
_outputs.resetDevice(_contextIsHMD, output); _outputs.resetDevice(_contextIsHMD, output);
} }
void AudioDevices::onInputDeviceSelected(const QAudioDeviceInfo& device) { void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, const QAudioDeviceInfo& previousDevice) {
QString deviceName; QString deviceName = device.isNull() ? QString() : device.deviceName();
auto& setting = getSetting(_contextIsHMD, mode);
// check for a previous device
auto wasDefault = setting.get().isNull();
// store the selected device
setting.set(deviceName);
// log the selected device
if (!device.isNull()) { if (!device.isNull()) {
deviceName = device.deviceName(); QJsonObject data;
}
if (_contextIsHMD) { const QString MODE = "audio_mode";
inputDeviceHMD.set(deviceName); const QString INPUT = "INPUT";
} else { const QString OUTPUT = "OUTPUT"; data[MODE] = mode == QAudio::AudioInput ? INPUT : OUTPUT;
inputDeviceDesktop.set(deviceName);
}
}
void AudioDevices::onOutputDeviceSelected(const QAudioDeviceInfo& device) { const QString CONTEXT = "display_mode";
QString deviceName; data[CONTEXT] = _contextIsHMD ? Audio::HMD : Audio::DESKTOP;
if (!device.isNull()) {
deviceName = device.deviceName();
}
if (_contextIsHMD) { const QString DISPLAY = "display_device";
outputDeviceHMD.set(deviceName); data[DISPLAY] = qApp->getActiveDisplayPlugin()->getName();
} else {
outputDeviceDesktop.set(deviceName); const QString DEVICE = "device";
const QString PREVIOUS_DEVICE = "previous_device";
const QString WAS_DEFAULT = "was_default";
data[DEVICE] = deviceName;
data[PREVIOUS_DEVICE] = previousDevice.deviceName();
data[WAS_DEFAULT] = wasDefault;
UserActivityLogger::getInstance().logAction("selected_audio_device", data);
} }
} }

View file

@ -43,7 +43,8 @@ public:
void resetDevice(bool contextIsHMD, const QString& device); void resetDevice(bool contextIsHMD, const QString& device);
signals: signals:
void deviceSelected(const QAudioDeviceInfo& device); void deviceSelected(const QAudioDeviceInfo& device = QAudioDeviceInfo(),
const QAudioDeviceInfo& previousDevice = QAudioDeviceInfo());
void deviceChanged(const QAudioDeviceInfo& device); void deviceChanged(const QAudioDeviceInfo& device);
private slots: private slots:
@ -53,6 +54,8 @@ private slots:
private: private:
friend class AudioDevices; friend class AudioDevices;
bool setDevice(int index, bool fromUser);
static QHash<int, QByteArray> _roles; static QHash<int, QByteArray> _roles;
static Qt::ItemFlags _flags; static Qt::ItemFlags _flags;
@ -76,8 +79,7 @@ signals:
private slots: private slots:
void onContextChanged(const QString& context); void onContextChanged(const QString& context);
void onInputDeviceSelected(const QAudioDeviceInfo& device); void onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, const QAudioDeviceInfo& previousDevice);
void onOutputDeviceSelected(const QAudioDeviceInfo& device);
void onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device); void onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device);
void onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices); void onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices);