service/mpris: finish mpris implementation

This commit is contained in:
outfoxxed 2024-05-21 04:05:15 -07:00
parent 3b6d1c3bd8
commit 4ee9ac7f7c
Signed by untrusted user: outfoxxed
GPG key ID: 4C88A185FB89301E
16 changed files with 911 additions and 578 deletions

View file

@ -188,9 +188,9 @@ public:
dbus::DBusPropertyGroup properties;
dbus::DBusProperty<quint32> version {this->properties, "Version"};
dbus::DBusProperty<QString> textDirection {this->properties, "TextDirection"};
dbus::DBusProperty<QString> textDirection {this->properties, "TextDirection", "", false};
dbus::DBusProperty<QString> status {this->properties, "Status"};
dbus::DBusProperty<QStringList> iconThemePath {this->properties, "IconThemePath"};
dbus::DBusProperty<QStringList> iconThemePath {this->properties, "IconThemePath", {}, false};
void prepareToShow(qint32 item, bool sendOpened);
void updateLayout(qint32 parent, qint32 depth);

View file

@ -112,6 +112,8 @@ void asyncReadPropertyInternal(
}
void AbstractDBusProperty::tryUpdate(const QVariant& variant) {
this->mExists = true;
auto error = this->read(variant);
if (error.isValid()) {
qCWarning(logDbusProperties).noquote()
@ -159,6 +161,44 @@ void AbstractDBusProperty::update() {
}
}
void AbstractDBusProperty::write() {
if (this->group == nullptr) {
qFatal(logDbusProperties) << "Tried to write dbus property" << this->name
<< "which is not attached to a group";
} else {
const QString propStr = this->toString();
if (this->group->interface == nullptr) {
qFatal(logDbusProperties).noquote()
<< "Tried to write property" << propStr << "of a disconnected interface";
}
qCDebug(logDbusProperties).noquote() << "Writing property" << propStr;
auto pendingCall = this->group->propertyInterface->Set(
this->group->interface->interface(),
this->name,
QDBusVariant(this->serialize())
);
auto* call = new QDBusPendingCallWatcher(pendingCall, this);
auto responseCallback = [propStr](QDBusPendingCallWatcher* call) {
const QDBusPendingReply<> reply = *call;
if (reply.isError()) {
qCWarning(logDbusProperties).noquote() << "Error writing property" << propStr;
qCWarning(logDbusProperties) << reply.error();
}
delete call;
};
QObject::connect(call, &QDBusPendingCallWatcher::finished, this, responseCallback);
}
}
bool AbstractDBusProperty::exists() const { return this->mExists; }
QString AbstractDBusProperty::toString() const {
const QString group = this->group == nullptr ? "{ NO GROUP }" : this->group->toString();
return group + ':' + this->name;
@ -232,7 +272,7 @@ void DBusPropertyGroup::updateAllViaGetAll() {
} else {
qCDebug(logDbusProperties).noquote()
<< "Received GetAll property set for" << this->toString();
this->updatePropertySet(reply.value());
this->updatePropertySet(reply.value(), true);
}
delete call;
@ -242,7 +282,7 @@ void DBusPropertyGroup::updateAllViaGetAll() {
QObject::connect(call, &QDBusPendingCallWatcher::finished, this, responseCallback);
}
void DBusPropertyGroup::updatePropertySet(const QVariantMap& properties) {
void DBusPropertyGroup::updatePropertySet(const QVariantMap& properties, bool complainMissing) {
for (const auto [name, value]: properties.asKeyValueRange()) {
auto prop = std::find_if(
this->properties.begin(),
@ -251,11 +291,21 @@ void DBusPropertyGroup::updatePropertySet(const QVariantMap& properties) {
);
if (prop == this->properties.end()) {
qCDebug(logDbusProperties) << "Ignoring untracked property update" << name << "for" << this;
qCDebug(logDbusProperties) << "Ignoring untracked property update" << name << "for"
<< this->toString();
} else {
(*prop)->tryUpdate(value);
}
}
if (complainMissing) {
for (const auto* prop: this->properties) {
if (prop->required && !properties.contains(prop->name)) {
qCWarning(logDbusProperties)
<< prop->name << "missing from property set for" << this->toString();
}
}
}
}
QString DBusPropertyGroup::toString() const {
@ -291,7 +341,7 @@ void DBusPropertyGroup::onPropertiesChanged(
}
}
this->updatePropertySet(changedProperties);
this->updatePropertySet(changedProperties, false);
}
} // namespace qs::dbus

View file

@ -79,22 +79,31 @@ class AbstractDBusProperty: public QObject {
Q_OBJECT;
public:
explicit AbstractDBusProperty(QString name, const QMetaType& type, QObject* parent = nullptr)
explicit AbstractDBusProperty(
QString name,
const QMetaType& type,
bool required,
QObject* parent = nullptr
)
: QObject(parent)
, name(std::move(name))
, type(type) {}
, type(type)
, required(required) {}
[[nodiscard]] bool exists() const;
[[nodiscard]] QString toString() const;
[[nodiscard]] virtual QString valueString() = 0;
public slots:
void update();
void write();
signals:
void changed();
protected:
virtual QDBusError read(const QVariant& variant) = 0;
virtual QVariant serialize() = 0;
private:
void tryUpdate(const QVariant& variant);
@ -103,6 +112,8 @@ private:
QString name;
QMetaType type;
bool required;
bool mExists = false;
friend class DBusPropertyGroup;
};
@ -133,7 +144,7 @@ private slots:
);
private:
void updatePropertySet(const QVariantMap& properties);
void updatePropertySet(const QVariantMap& properties, bool complainMissing);
DBusPropertiesInterface* propertyInterface = nullptr;
QDBusAbstractInterface* interface = nullptr;
@ -145,17 +156,23 @@ private:
template <typename T>
class DBusProperty: public AbstractDBusProperty {
public:
explicit DBusProperty(QString name, QObject* parent = nullptr, T value = T())
: AbstractDBusProperty(std::move(name), QMetaType::fromType<T>(), parent)
explicit DBusProperty(
QString name,
T value = T(),
bool required = true,
QObject* parent = nullptr
)
: AbstractDBusProperty(std::move(name), QMetaType::fromType<T>(), required, parent)
, value(std::move(value)) {}
explicit DBusProperty(
DBusPropertyGroup& group,
QString name,
QObject* parent = nullptr,
T value = T()
T value = T(),
bool required = true,
QObject* parent = nullptr
)
: DBusProperty(std::move(name), parent, std::move(value)) {
: DBusProperty(std::move(name), std::move(value), required, parent) {
group.attachProperty(this);
}
@ -165,7 +182,7 @@ public:
return str;
}
[[nodiscard]] T get() const { return this->value; }
[[nodiscard]] const T& get() const { return this->value; }
void set(T value) {
this->value = std::move(value);
@ -183,6 +200,8 @@ protected:
return result.error;
}
QVariant serialize() override { return QVariant::fromValue(this->value); }
private:
T value;