diff --git a/api/dbus/org.desktopspec.ApplicationManager1.Application.xml b/api/dbus/org.desktopspec.ApplicationManager1.Application.xml index 6d50c34..e516d7f 100644 --- a/api/dbus/org.desktopspec.ApplicationManager1.Application.xml +++ b/api/dbus/org.desktopspec.ApplicationManager1.Application.xml @@ -8,6 +8,60 @@ Missing fields will be added later." /> + + + + + + + + + + + + + + + + + + + @@ -32,41 +86,6 @@ /> - - - - - - - - @@ -81,24 +100,5 @@ this method will use the locale config of that user." /> - - - - - - - - - - - diff --git a/src/dbus/applicationmanager1service.cpp b/src/dbus/applicationmanager1service.cpp index 9d97efd..356d0f5 100644 --- a/src/dbus/applicationmanager1service.cpp +++ b/src/dbus/applicationmanager1service.cpp @@ -1,21 +1,23 @@ // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later - #include "applicationmanager1service.h" +#include "applicationmanager1adaptor.h" +#include "applicationadaptor.h" +#include "global.h" -ApplicationManager1Service::ApplicationManager1Service(QObject *parent) - : QObject(parent) +ApplicationManager1Service::~ApplicationManager1Service() = default; + +ApplicationManager1Service::ApplicationManager1Service() = default; + +QList ApplicationManager1Service::list() const { return m_applicationList.keys(); } + +bool ApplicationManager1Service::removeOneApplication(const QDBusObjectPath &application) { + return m_applicationList.remove(application) != 0; } -ApplicationManager1Service::~ApplicationManager1Service() {} - -QList ApplicationManager1Service::list() const -{ - // TODO: impl - return {}; -} +void ApplicationManager1Service::removeAllApplication() { m_applicationList.clear(); } QDBusObjectPath ApplicationManager1Service::Application(const QString &id) { @@ -32,10 +34,22 @@ QString ApplicationManager1Service::Identify(const QDBusUnixFileDescriptor &pidf } QDBusObjectPath ApplicationManager1Service::Launch(const QString &id, - const QString &action, + const QString &actions, const QStringList &fields, const QVariantMap &options) { - // TODO: impl + // TODO: impl reset of Launch + QString objectPath; + if (id.contains('.')) { + objectPath = id.split('.').first(); + } + objectPath.prepend(DDEApplicationManager1ApplicationObjectPath); + QSharedPointer app{new ApplicationService{id}}; + auto *ptr = app.data(); + if (registerObjectToDbus(ptr, objectPath, getDBusInterface())) { + QDBusObjectPath path{objectPath}; + m_applicationList.insert(path, app); + return path; + } return {}; } diff --git a/src/dbus/applicationmanager1service.h b/src/dbus/applicationmanager1service.h index a34072b..1eaf3d2 100644 --- a/src/dbus/applicationmanager1service.h +++ b/src/dbus/applicationmanager1service.h @@ -8,22 +8,36 @@ #include #include #include +#include +#include +#include "applicationservice.h" -class ApplicationManager1Service : public QObject +class ApplicationManager1Service final : public QObject { Q_OBJECT public: - explicit ApplicationManager1Service(QObject *parent = nullptr); - virtual ~ApplicationManager1Service(); + ApplicationManager1Service(); + ~ApplicationManager1Service() override; + ApplicationManager1Service(const ApplicationManager1Service &) = delete; + ApplicationManager1Service(ApplicationManager1Service &&) = delete; + ApplicationManager1Service &operator=(const ApplicationManager1Service &) = delete; + ApplicationManager1Service &operator=(ApplicationManager1Service&&) = delete; -public: Q_PROPERTY(QList List READ list) QList list() const; + void addApplication(const QString &ID, + const QStringList &actions, + bool AutoStart = false); + bool removeOneApplication(const QDBusObjectPath &application); + void removeAllApplication(); public Q_SLOTS: QDBusObjectPath Application(const QString &id); QString Identify(const QDBusUnixFileDescriptor &pidfd, QDBusObjectPath &application, QDBusObjectPath &application_instance); QDBusObjectPath Launch(const QString &id, const QString &action, const QStringList &fields, const QVariantMap &options); + +private: + QMap> m_applicationList; }; #endif diff --git a/src/dbus/applicationservice.cpp b/src/dbus/applicationservice.cpp index fc0c787..eb62659 100644 --- a/src/dbus/applicationservice.cpp +++ b/src/dbus/applicationservice.cpp @@ -3,16 +3,53 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "applicationservice.h" +#include "instanceadaptor.h" +#include -ApplicationService::ApplicationService(QObject *parent) - : QObject(parent) +ApplicationService::ApplicationService(QString ID) + : m_AutoStart(false) + , m_ID(std::move(ID)) + , m_applicationPath(DDEApplicationManager1ApplicationObjectPath + m_ID) { } -ApplicationService::~ApplicationService() {} +ApplicationService::~ApplicationService() = default; -QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringList &fields, const QVariantMap &options) +QString ApplicationService::GetActionName(const QString &identifier, const QStringList &env) { // TODO: impl return {}; } + +QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringList &fields, const QVariantMap &options) +{ + // TODO: impl launch app from systemd. + QString objectPath{m_applicationPath.path() + "/" + QUuid::createUuid().toString()}; + QSharedPointer ins{new InstanceService{objectPath, ""}}; + auto *ptr = ins.data(); + if (registerObjectToDbus(ptr, objectPath, getDBusInterface())) { + m_Instances.insert(QDBusObjectPath{objectPath}, ins); + return QDBusObjectPath{objectPath}; + } + return {}; +} + +QStringList ApplicationService::actions() const noexcept { return m_actions; } + +QStringList& ApplicationService::actionsRef() noexcept { return m_actions; } + +QString ApplicationService::iD() const noexcept { return m_ID; } + +IconMap ApplicationService::icons() const { return m_Icons; } + +IconMap& ApplicationService::iconsRef() { return m_Icons; } + +bool ApplicationService::isAutoStart() const noexcept { return m_AutoStart; } + +void ApplicationService::setAutoStart(bool autostart) noexcept { m_AutoStart = autostart; } + +QList ApplicationService::instances() const noexcept { return m_Instances.keys(); } + +bool ApplicationService::removeOneInstance(const QDBusObjectPath &instance) { return m_Instances.remove(instance) != 0; } + +void ApplicationService::removeAllInstance() { m_Instances.clear();} diff --git a/src/dbus/applicationservice.h b/src/dbus/applicationservice.h index e5d8e88..581345c 100644 --- a/src/dbus/applicationservice.h +++ b/src/dbus/applicationservice.h @@ -7,16 +7,58 @@ #include #include +#include +#include +#include +#include +#include "instanceservice.h" +#include "global.h" class ApplicationService : public QObject { Q_OBJECT public: - explicit ApplicationService(QObject *parent = nullptr); - virtual ~ApplicationService(); + ~ApplicationService() override; + ApplicationService(const ApplicationService&) = delete; + ApplicationService(ApplicationService &&) = delete; + ApplicationService& operator=(const ApplicationService&) = delete; + ApplicationService &operator=(ApplicationService &&) = delete; + + Q_PROPERTY(QStringList Actions READ actions CONSTANT) + QStringList actions() const noexcept; + QStringList& actionsRef() noexcept; + + Q_PROPERTY(QString ID READ iD CONSTANT) + QString iD() const noexcept; + + Q_PROPERTY(IconMap Icons READ icons) + IconMap icons() const; + IconMap& iconsRef(); + + Q_PROPERTY(bool AutoStart READ isAutoStart WRITE setAutoStart) + bool isAutoStart() const noexcept; + void setAutoStart(bool autostart) noexcept; + + Q_PROPERTY(QList Instances READ instances) + QList instances() const noexcept; + + void recoverInstances(const QList) noexcept; + bool removeOneInstance(const QDBusObjectPath &instance); + void removeAllInstance(); public Q_SLOTS: + QString GetActionName(const QString &identifier, const QStringList &env); QDBusObjectPath Launch(const QString &action, const QStringList &fields, const QVariantMap &options); + +private: + friend class ApplicationManager1Service; + explicit ApplicationService(QString ID); + bool m_AutoStart; + QString m_ID; + QDBusObjectPath m_applicationPath; + QStringList m_actions; + QMap> m_Instances; + IconMap m_Icons; }; #endif diff --git a/src/dbus/instanceservice.cpp b/src/dbus/instanceservice.cpp index 9df512a..1bd49b0 100644 --- a/src/dbus/instanceservice.cpp +++ b/src/dbus/instanceservice.cpp @@ -4,21 +4,13 @@ #include "instanceservice.h" -InstanceService::InstanceService(QObject *parent) - : QObject(parent) +InstanceService::InstanceService(QString application, QString systemdUnitPath) + : m_Application(std::move(application)), m_SystemdUnitPath(std::move(systemdUnitPath)) { } -InstanceService::~InstanceService() {} +InstanceService::~InstanceService() = default; -QDBusObjectPath InstanceService::application() const -{ - // TODO: impl - return {}; -} +QDBusObjectPath InstanceService::application() const { return m_Application; } -QDBusObjectPath InstanceService::systemdUnitPath() const -{ - // TODO: impl - return {}; -} +QDBusObjectPath InstanceService::systemdUnitPath() const { return m_SystemdUnitPath; } diff --git a/src/dbus/instanceservice.h b/src/dbus/instanceservice.h index 4642493..32549ed 100644 --- a/src/dbus/instanceservice.h +++ b/src/dbus/instanceservice.h @@ -12,15 +12,23 @@ class InstanceService : public QObject { Q_OBJECT public: - explicit InstanceService(QObject *parent = nullptr); - virtual ~InstanceService(); + ~InstanceService() override; + InstanceService(const InstanceService &) = delete; + InstanceService(InstanceService &&) = delete; + InstanceService &operator=(const InstanceService &) = delete; + InstanceService &operator=(InstanceService&&) = delete; -public: - Q_PROPERTY(QDBusObjectPath Application READ application) + Q_PROPERTY(QDBusObjectPath Application READ application CONSTANT) QDBusObjectPath application() const; - Q_PROPERTY(QDBusObjectPath SystemdUnitPath READ systemdUnitPath) + Q_PROPERTY(QDBusObjectPath SystemdUnitPath READ systemdUnitPath CONSTANT) QDBusObjectPath systemdUnitPath() const; + +private: + friend class ApplicationService; + InstanceService(QString application, QString systemdUnitPath); + const QDBusObjectPath m_Application; + const QDBusObjectPath m_SystemdUnitPath; }; #endif diff --git a/src/dbus/jobmanager1service.cpp b/src/dbus/jobmanager1service.cpp index 88f1943..db55e3d 100644 --- a/src/dbus/jobmanager1service.cpp +++ b/src/dbus/jobmanager1service.cpp @@ -3,10 +3,24 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "jobmanager1service.h" +#include +#include "global.h" -JobManager1Service::JobManager1Service(QObject *parent) - : QObject(parent) +JobManager1Service::JobManager1Service() = default; + +JobManager1Service::~JobManager1Service() = default; + +template +void addJob(const QDBusObjectPath &source, F func, Args &&...args) { + // TODO: impl } -JobManager1Service::~JobManager1Service() {} +bool JobManager1Service::removeJob(const QDBusObjectPath &job, + const QString &status, + const QString &message, + const QDBusVariant &result) +{ + // TODO: impl + return false; +} diff --git a/src/dbus/jobmanager1service.h b/src/dbus/jobmanager1service.h index ab00f3d..eb8f3eb 100644 --- a/src/dbus/jobmanager1service.h +++ b/src/dbus/jobmanager1service.h @@ -6,18 +6,31 @@ #define JOBMANAGER1SERVICE_H #include +#include #include - -class JobManager1Service : public QObject +#include +#include "jobservice.h" +class JobManager1Service final : public QObject { Q_OBJECT public: - explicit JobManager1Service(QObject *parent = nullptr); - virtual ~JobManager1Service(); + JobManager1Service(); + JobManager1Service(const JobManager1Service &) = delete; + JobManager1Service(JobManager1Service&&) = delete; + JobManager1Service &operator=(const JobManager1Service &) = delete; + JobManager1Service &operator=(JobManager1Service &&) = delete; + + ~JobManager1Service() override; + template + void addJob(const QDBusObjectPath &source,F func, Args&& ...args); + bool removeJob(const QDBusObjectPath &job, const QString &status, const QString &message, const QDBusVariant &result); Q_SIGNALS: void JobNew(const QDBusObjectPath &job, const QDBusObjectPath &source); void JobRemoved(const QDBusObjectPath &job, const QString &status, const QString &message, const QDBusVariant &result); + +private: + QMap> m_jobs; }; #endif diff --git a/src/dbus/jobservice.cpp b/src/dbus/jobservice.cpp index 37bf501..312d99c 100644 --- a/src/dbus/jobservice.cpp +++ b/src/dbus/jobservice.cpp @@ -4,41 +4,47 @@ #include "jobservice.h" -JobService::JobService(QObject *parent) - : QObject(parent) +JobService::JobService(const QFuture& job) + : m_job(job) { } -JobService::~JobService() {} +JobService::~JobService() = default; QString JobService::status() const { - if (job.isFinished()) + if (m_job.isFinished()) { return "finished"; - if (job.isCanceled()) + } + if (m_job.isCanceled()) { return "canceled"; - if (job.isSuspended()) + } + if (m_job.isSuspended()) { return "suspended"; - if (job.isSuspending()) + } + if (m_job.isSuspending()) { return "suspending"; - if (job.isStarted()) + } + if (m_job.isStarted()) { return "started"; - if (job.isRunning()) + } + if (m_job.isRunning()) { return "running"; + } return "failed"; } void JobService::Cancel() { - job.cancel(); + m_job.cancel(); } void JobService::Pause() { - job.suspend(); + m_job.suspend(); } void JobService::Resume() { - job.resume(); + m_job.resume(); } diff --git a/src/dbus/jobservice.h b/src/dbus/jobservice.h index fbf97d6..fcbd4a8 100644 --- a/src/dbus/jobservice.h +++ b/src/dbus/jobservice.h @@ -13,10 +13,8 @@ class JobService : public QObject { Q_OBJECT public: - explicit JobService(QObject *parent = nullptr); - virtual ~JobService(); + ~JobService() override; -public: Q_PROPERTY(QString Status READ status) QString status() const; @@ -26,7 +24,8 @@ public Q_SLOTS: void Resume(); private: - QFuture job; + explicit JobService(const QFuture& job); + QFuture m_job; }; #endif diff --git a/src/include/global.h b/src/include/global.h new file mode 100644 index 0000000..6207cbb --- /dev/null +++ b/src/include/global.h @@ -0,0 +1,82 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef GLOBAL_H +#define GLOBAL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +using IconMap = QMap>>; + +constexpr auto DDEApplicationManager1ServiceName = u8"org.deepin.dde.ApplicationManager1"; +constexpr auto DDEApplicationManager1ObjectPath = u8"/org/deepin/dde/ApplicationManager1"; +constexpr auto DDEApplicationManager1ApplicationObjectPath = u8"/org/deepin/dde/ApplicationManager1/Application/"; +constexpr auto DDEApplicationManager1JobManagerObjectPath = u8"/org/deepin/dde/ApplicationManager1/JobManager1"; +constexpr auto DDEApplicationManager1JobObjectPath = u8"/org/deepin/dde/ApplicationManager1/JobManager1/Job/"; + +class ApplicationManager1DBus +{ +public: + ApplicationManager1DBus(const ApplicationManager1DBus &) = delete; + ApplicationManager1DBus(ApplicationManager1DBus &&) = delete; + ApplicationManager1DBus &operator=(const ApplicationManager1DBus &) = delete; + ApplicationManager1DBus &operator=(ApplicationManager1DBus&&) = delete; + const QString &BusAddress() { return m_busAddress; } + void setBusAddress(const QString &address) { m_busAddress = address; } + QDBusConnection& CustomBus() + { + static auto con = QDBusConnection::connectToBus(m_busAddress, "org.deepin.dde.ApplicationManager1"); + if (!con.isConnected()) { + qWarning() << con.lastError(); + std::terminate(); + } + return con; + } + static ApplicationManager1DBus &instance() + { + static ApplicationManager1DBus dbus; + return dbus; + } + +private: + ApplicationManager1DBus() = default; + ~ApplicationManager1DBus() = default; + QString m_busAddress; +}; + +template +bool registerObjectToDbus(T parent, const QString &path, const QString &interface) +{ + using service_type = std::remove_const_t; + static_assert(std::is_pointer_v, "param type must be a pointer"); + static_assert(std::is_base_of_v> and + std::is_base_of_v, + "param type must derive QObject"); + auto &con = ApplicationManager1DBus::instance().CustomBus(); + if (!con.registerObject(path, interface, new U{parent})) { + qWarning() << "register object failed:" << path << interface << con.lastError(); + return false; + } + return true; +} + +template +QString getDBusInterface() +{ + auto meta = QMetaType::fromType(); + auto infoObject = meta.metaObject(); + if (auto infoIndex = infoObject->indexOfClassInfo("D-Bus Interface"); infoIndex != -1) { + return infoObject->classInfo(infoIndex).value(); + } + return {}; +} + +#endif