dde-dock/frame/model/volumemodel.cpp
donghualin c7826edd46 fix: 删除任务栏对libdframeworkdbus-dev库的依赖
1、删除项目中对libdframeworkdbus-dev库的依赖,通过使用xml2cpp的工具来自动生成dbus接口文件,在使用到dbus库的项目中包含生成文件的目录
2、修改相关服务中v20的接口(com.deepin...)为v23的接口(org.deepin...)

Log:
Influence: 打开控制中心,鼠标移动唤醒任务栏、加载插件等,观察相关功能是否正常
Task: https://pms.uniontech.com/task-view-182009.html
Change-Id: I960c849d06ed271ebbb9f8e479d9879967523581
2022-09-19 11:41:31 +00:00

395 lines
8.0 KiB
C++

#include "volumemodel.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QVariantMap>
#include <QDebug>
/**
* @brief 声音控制的类
* @param parent
*/
static const QString serviceName = QString("org.deepin.daemon.Audio1");
static const QString servicePath = QString("/org/deepin/daemon/Audio1");
VolumeModel::VolumeModel(QObject *parent)
: QObject(parent)
, m_audio(new DBusAudio(serviceName, servicePath, QDBusConnection::sessionBus(), this))
{
reloadSinks();
reloadPorts();
connect(m_audio, &DBusAudio::DefaultSinkChanged, this, &VolumeModel::onDefaultSinkChanged);
}
VolumeModel::~VolumeModel()
{
clearPorts();
clearSinks();
}
void VolumeModel::setActivePort(AudioPorts *port)
{
m_audio->SetPort(port->cardId(), port->name(), port->direction());
}
QList<AudioSink *> VolumeModel::sinks() const
{
return m_sinks;
}
QList<AudioPorts *> VolumeModel::ports() const
{
return m_ports;
}
AudioSink *VolumeModel::defaultSink() const
{
for (AudioSink *sink : m_sinks) {
if (sink->isDefault())
return sink;
}
return nullptr;
}
void VolumeModel::setVolume(int volumn)
{
for (AudioSink *audiosink : m_sinks) {
if (audiosink->isDefault()) {
audiosink->setVolume(volumn, true);
break;
}
}
}
void VolumeModel::setMute(bool value)
{
for (AudioSink *audiosink : m_sinks) {
if (audiosink->isDefault()) {
audiosink->setMute(value);
break;
}
}
}
int VolumeModel::volume()
{
for (AudioSink *audiosink : m_sinks) {
if (audiosink->isDefault())
return audiosink->volume();
}
return 0;
}
bool VolumeModel::isMute()
{
for (AudioSink *audiosink : m_sinks) {
if (audiosink->isDefault())
return audiosink->isMute();
}
return false;
}
bool VolumeModel::existActiveOutputDevice()
{
for (AudioPorts *port : m_ports) {
if (port->direction() == 1)
return true;
}
return false;
}
void VolumeModel::reloadSinks()
{
clearSinks();
const QString defaultSinkPath = m_audio->defaultSink().path();
QList<QDBusObjectPath> sinkPaths = m_audio->sinks();
for (const QDBusObjectPath &sinkPath : sinkPaths) {
const QString path = sinkPath.path();
AudioSink *sink = new AudioSink(path, (path == defaultSinkPath), this);
connect(sink, &AudioSink::volumeChanged, this, [ = ](int volume) {
if (sink->isDefault())
Q_EMIT volumeChanged(volume);
});
connect(sink, &AudioSink::muteChanged, this, [ = ](bool isMute) {
if (sink->isDefault())
Q_EMIT muteChanged(isMute);
});
m_sinks << sink;
}
}
void VolumeModel::reloadPorts()
{
clearPorts();
QString cards = m_audio->cardsWithoutUnavailable();
QJsonParseError error;
QJsonDocument json = QJsonDocument::fromJson(cards.toLocal8Bit(), &error);
if (error.error != QJsonParseError::NoError)
return;
uint sinkCardId = 0;
QString sinkCardName;
AudioSink *sink = defaultSink();
if (sink) {
sinkCardId = sink->cardId();
sinkCardName = sink->name();
}
QJsonArray array = json.array();
for (const QJsonValue value : array) {
QJsonObject cardObject = value.toObject();
uint cardId = static_cast<uint>(cardObject.value("Id").toInt());
QString cardName = cardObject.value("Name").toString();
QJsonArray jPorts = cardObject.value("Ports").toArray();
for (const QJsonValue jPortValue : jPorts) {
QJsonObject jPort = jPortValue.toObject();
if (!jPort.value("Enabled").toBool())
continue;
int direction = jPort.value("Direction").toInt();
if (direction != 1)
continue;
AudioPorts *port = new AudioPorts(cardId, cardName);
port->setName(jPort.value("Name").toString());
port->setDescription(jPort.value("Description").toString());
port->setDirection(direction);
if (port->cardId() == sinkCardId && port->name() == sinkCardName)
port->setIsChecked(true);
m_ports << port;
}
}
}
void VolumeModel::onDefaultSinkChanged(const QDBusObjectPath &value)
{
AudioSink *audioSink = nullptr;
const QString defaultPath = value.path();
for (AudioSink *sink : m_sinks) {
sink->setDefault(defaultPath == sink->m_devicePath);
if (sink->isDefault())
audioSink = sink;
}
if (!audioSink)
return;
bool checkChanged = false;
for (AudioPorts *port : m_ports) {
bool oldChecked = port->isChecked();
port->setIsChecked(port->cardId() == audioSink->cardId()
&& port->name() == audioSink->name());
if (oldChecked != port->isChecked() && port->isChecked())
checkChanged = true;
}
if (checkChanged)
Q_EMIT checkPortChanged();
Q_EMIT defaultSinkChanged(audioSink);
}
void VolumeModel::clearSinks()
{
for (AudioSink *sink : m_sinks)
delete sink;
m_sinks.clear();
}
void VolumeModel::clearPorts()
{
for (AudioPorts *port : m_ports)
delete port;
m_ports.clear();
}
/**
* @brief 具体的声音设备
* @param parent
*/
AudioSink::AudioSink(QString path, bool isDefault, QObject *parent)
: QObject(parent)
, m_devicePath(path)
, m_sink(new DBusSink(serviceName, path, QDBusConnection::sessionBus(), this))
, m_isDefault(isDefault)
{
connect(m_sink, &DBusSink::MuteChanged, this, &AudioSink::muteChanged);
connect(m_sink, &DBusSink::VolumeChanged, this, [ this ](double value) {
Q_EMIT this->volumeChanged(static_cast<int>(value * 100));
});
}
AudioSink::~AudioSink()
{
}
void AudioSink::setDefault(bool isDefaultSink)
{
m_isDefault = isDefaultSink;
}
bool AudioSink::isDefault()
{
return m_isDefault;
}
bool AudioSink::isHeadPhone()
{
return false;
}
void AudioSink::setBalance(double value, bool isPlay)
{
m_sink->SetBalance(value, isPlay);
}
void AudioSink::setFade(double value)
{
m_sink->SetFade(value);
}
void AudioSink::setMute(bool mute)
{
m_sink->SetMute(mute);
}
void AudioSink::setPort(QString name)
{
m_sink->SetPort(name);
}
void AudioSink::setVolume(int value, bool isPlay)
{
m_sink->SetVolume((value * 0.01), isPlay);
}
bool AudioSink::isMute()
{
return m_sink->mute();
}
bool AudioSink::supportBalance()
{
return m_sink->supportBalance();
}
bool AudioSink::suoportFade()
{
return m_sink->supportFade();
}
double AudioSink::balance()
{
return m_sink->balance();
}
double AudioSink::baseVolume()
{
return m_sink->baseVolume();
}
double AudioSink::fade()
{
return m_sink->fade();
}
int AudioSink::volume()
{
return static_cast<int>(m_sink->volume() * 100);
}
QString AudioSink::description()
{
return m_sink->activePort().description;
}
QString AudioSink::name()
{
return m_sink->activePort().name;
}
uint AudioSink::cardId()
{
return m_sink->card();
}
AudioPorts::AudioPorts(uint cardId, QString cardName)
: m_cardId(cardId)
, m_cardName(cardName)
, m_direction(0)
, m_isCheck(false)
, m_isHeadPhone(false)
{
}
AudioPorts::~AudioPorts()
{
}
uint AudioPorts::cardId() const
{
return m_cardId;
}
QString AudioPorts::cardName() const
{
return m_cardName;
}
void AudioPorts::setName(const QString &name)
{
m_portName = name;
}
QString AudioPorts::name() const
{
return m_portName;
}
void AudioPorts::setDescription(const QString &desc)
{
m_description = desc;
}
QString AudioPorts::description() const
{
return m_description;
}
void AudioPorts::setDirection(int dir)
{
m_direction = dir;
}
void AudioPorts::setIsChecked(bool isChecked)
{
m_isCheck = isChecked;
}
int AudioPorts::direction() const
{
return m_direction;
}
bool AudioPorts::isChecked() const
{
return m_isCheck;
}
bool AudioPorts::isHeadPhone() const
{
return m_isHeadPhone;
}