diff --git a/api/dbus/org.desktopspec.ApplicationManager1.xml b/api/dbus/org.desktopspec.ApplicationManager1.xml index 5cbe67a..a2d757d 100644 --- a/api/dbus/org.desktopspec.ApplicationManager1.xml +++ b/api/dbus/org.desktopspec.ApplicationManager1.xml @@ -15,8 +15,8 @@ - - + + >(); - qDBusRegisterMetaType>>(); qRegisterMetaType(); qDBusRegisterMetaType(); qRegisterMetaType(); @@ -46,7 +44,8 @@ int main(int argc, char *argv[]) auto storageDir = getXDGDataHome() + QDir::separator() + "deepin" + QDir::separator() + "ApplicationManager"; auto storage = ApplicationManager1Storage::createApplicationManager1Storage(storageDir); - ApplicationManager1Service AMService{std::make_unique(), AMBus, storage}; + ApplicationManager1Service AMService{std::make_unique(), storage}; + AMService.initService(AMBus); #ifdef PROFILING_MODE auto end = std::chrono::high_resolution_clock::now(); diff --git a/src/cgroupsidentifier.cpp b/src/cgroupsidentifier.cpp index 61d710e..557348e 100644 --- a/src/cgroupsidentifier.cpp +++ b/src/cgroupsidentifier.cpp @@ -19,19 +19,25 @@ IdentifyRet CGroupsIdentifier::Identify(pid_t pid) auto UnitStr = parseCGroupsPath(AppCgroupFile); + if (UnitStr.isEmpty()) { + qWarning() << "process CGroups file failed."; + return {}; + } + auto [appId, launcher, InstanceId] = processUnitName(UnitStr); return {std::move(appId), std::move(InstanceId)}; } QString CGroupsIdentifier::parseCGroupsPath(QFile &cgroupFile) noexcept { - QTextStream stream{&cgroupFile}; - - if (stream.atEnd()) { - qWarning() << "read from cgroup file failed:" << stream.status(); + QString content = cgroupFile.readAll(); + if (content.isEmpty()) { return {}; } + + QTextStream stream{&content}; stream.setEncoding(QStringConverter::Utf8); + QString CGP; while (!stream.atEnd()) { auto line = stream.readLine(); diff --git a/src/dbus/applicationmanager1service.cpp b/src/dbus/applicationmanager1service.cpp index 7eb1f09..ede24c5 100644 --- a/src/dbus/applicationmanager1service.cpp +++ b/src/dbus/applicationmanager1service.cpp @@ -14,10 +14,13 @@ ApplicationManager1Service::~ApplicationManager1Service() = default; ApplicationManager1Service::ApplicationManager1Service(std::unique_ptr ptr, - QDBusConnection &connection, std::weak_ptr storage) noexcept : m_identifier(std::move(ptr)) , m_storage(std::move(storage)) +{ +} + +void ApplicationManager1Service::initService(QDBusConnection &connection) noexcept { if (!connection.registerService(DDEApplicationManager1ServiceName)) { qFatal("%s", connection.lastError().message().toLocal8Bit().data()); @@ -314,8 +317,7 @@ void ApplicationManager1Service::removeAllApplication() noexcept } QString ApplicationManager1Service::Identify(const QDBusUnixFileDescriptor &pidfd, - QDBusObjectPath &application, - QDBusObjectPath &application_instance) + ObjectMap &application_instance_info) const noexcept { if (!pidfd.isValid()) { qWarning() << "pidfd isn't a valid unix file descriptor"; @@ -353,15 +355,32 @@ QString ApplicationManager1Service::Identify(const QDBusUnixFileDescriptor &pidf const auto ret = m_identifier->Identify(pid); + if (ret.ApplicationId.isEmpty()) { + qInfo() << "Identify failed."; + return {}; + } + auto app = std::find_if(m_applicationList.cbegin(), m_applicationList.cend(), [&ret](const auto &appPtr) { return appPtr->id() == ret.ApplicationId; }); + if (app == m_applicationList.cend()) { qWarning() << "can't find application:" << ret.ApplicationId; return {}; } - application = m_applicationList.key(*app); - application_instance = (*app)->findInstance(ret.InstanceId); + + auto instance = (*app)->findInstance(ret.InstanceId); + + if (auto path = instance.path(); path.isEmpty()) { + qWarning() << "can't find instance:" << path; + return {}; + } + + auto instanceObj = (*app)->m_Instances.constFind(instance); + auto map = getChildInterfacesAndPropertiesFromObject(instanceObj->get()); + + application_instance_info.insert(instance, map); + return ret.ApplicationId; } diff --git a/src/dbus/applicationmanager1service.h b/src/dbus/applicationmanager1service.h index 18cb369..4ef8823 100644 --- a/src/dbus/applicationmanager1service.h +++ b/src/dbus/applicationmanager1service.h @@ -24,7 +24,6 @@ class ApplicationManager1Service final : public QObject Q_OBJECT public: explicit ApplicationManager1Service(std::unique_ptr ptr, - QDBusConnection &connection, std::weak_ptr storage) noexcept; ~ApplicationManager1Service() override; ApplicationManager1Service(const ApplicationManager1Service &) = delete; @@ -35,6 +34,7 @@ public: Q_PROPERTY(QList List READ list NOTIFY listChanged) [[nodiscard]] QList list() const; + void initService(QDBusConnection &connection) noexcept; bool addApplication(DesktopFile desktopFileSource) noexcept; void removeOneApplication(const QDBusObjectPath &application) noexcept; void removeAllApplication() noexcept; @@ -44,7 +44,7 @@ public: JobManager1Service &jobManager() noexcept { return *m_jobManager; } public Q_SLOTS: - QString Identify(const QDBusUnixFileDescriptor &pidfd, QDBusObjectPath &application, QDBusObjectPath &application_instance); + QString Identify(const QDBusUnixFileDescriptor &pidfd, ObjectMap &application_instance_info) const noexcept; void ReloadApplications(); [[nodiscard]] ObjectMap GetManagedObjects() const; diff --git a/tests/main.cpp b/tests/main.cpp index bddfcc3..1da4fe8 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -4,12 +4,20 @@ #include #include +#include "global.h" #include #include namespace { -void registerComplexDbusType() +void registerComplexDbusType() // FIXME: test shouldn't associate with DBus { + qRegisterMetaType(); + qDBusRegisterMetaType(); + qRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType>(); + qRegisterMetaType(); + qDBusRegisterMetaType(); qDBusRegisterMetaType(); } } // namespace diff --git a/tests/ut_applicationmanager.cpp b/tests/ut_applicationmanager.cpp index a68fbbb..1437cac 100644 --- a/tests/ut_applicationmanager.cpp +++ b/tests/ut_applicationmanager.cpp @@ -6,6 +6,7 @@ #include "dbus/applicationservice.h" #include "cgroupsidentifier.h" #include "constant.h" +#include "dbus/instanceadaptor.h" #include #include #include @@ -34,7 +35,7 @@ public: bus.initGlobalServerBus(DBusType::Session); bus.setDestBus(); std::shared_ptr tmp{nullptr}; - m_am = new ApplicationManager1Service{std::make_unique(), bus.globalServerBus(), tmp}; + m_am = new ApplicationManager1Service{std::make_unique(), tmp}; auto ptr = std::make_unique(QString{"/usr/share/applications/test-Application.desktop"}); DesktopFile file{std::move(ptr), "test-Application", 0, 0}; QSharedPointer app = QSharedPointer::create(std::move(file), nullptr, tmp); @@ -42,13 +43,13 @@ public: InstancePath.path().split('/').last(), ApplicationPath.path(), QString{"/"}, QString{"DDE"}); app->m_Instances.insert(InstancePath, instance); m_am->m_applicationList.insert(ApplicationPath, app); + new InstanceAdaptor{instance.data()}; } static void TearDownTestCase() { m_am->deleteLater(); } static inline ApplicationManager1Service *m_am{nullptr}; - const static inline QDBusObjectPath ApplicationPath{QString{DDEApplicationManager1ObjectPath} + "/" + - QUuid::createUuid().toString(QUuid::Id128)}; + const static inline QDBusObjectPath ApplicationPath{QString{DDEApplicationManager1ObjectPath} + "/test_2dApplication"}; const static inline QDBusObjectPath InstancePath{ApplicationPath.path() + "/" + QUuid::createUuid().toString(QUuid::Id128)}; }; @@ -96,12 +97,22 @@ TEST_F(TestApplicationManager, identifyService) auto pidfd = pidfd_open(fakePid, 0); ASSERT_TRUE(pidfd > 0) << std::strerror(errno); - QDBusObjectPath application; - QDBusObjectPath application_instance; - auto appId = m_am->Identify(QDBusUnixFileDescriptor{pidfd}, application, application_instance); + ObjectMap instanceInfo; + auto appId = m_am->Identify(QDBusUnixFileDescriptor{pidfd}, instanceInfo); EXPECT_EQ(appId.toStdString(), QString{"test-Application"}.toStdString()); - EXPECT_EQ(application.path().toStdString(), ApplicationPath.path().toStdString()); - EXPECT_EQ(application_instance.path().toStdString(), InstancePath.path().toStdString()); + + auto instance = instanceInfo.constFind(InstancePath); + if (instance == instanceInfo.cend()) { + GTEST_SKIP_("couldn't find instance and skip."); + } + + ObjectInterfaceMap map{{QString{InstanceInterface}, + QVariantMap{{QString{"Application"}, ApplicationPath}, + {QString{"SystemdUnitPath"}, QDBusObjectPath{"/"}}, + {QString{"Launcher"}, QString{"DDE"}}, + {QString{"Orphaned"}, false}}}}; + EXPECT_EQ(instance.value(), map); + close(pidfd); if (pidFile.exists()) { @@ -136,10 +147,18 @@ TEST_F(TestApplicationManager, identifyService) pidfd = pidfd_open(fakePid, 0); ASSERT_TRUE(pidfd > 0) << std::strerror(errno); - appId = m_am->Identify(QDBusUnixFileDescriptor{pidfd}, application, application_instance); + instanceInfo.clear(); + + appId = m_am->Identify(QDBusUnixFileDescriptor{pidfd}, instanceInfo); EXPECT_EQ(appId.toStdString(), QString{"test-Application"}.toStdString()); - EXPECT_EQ(application.path().toStdString(), ApplicationPath.path().toStdString()); - EXPECT_EQ(application_instance.path().toStdString(), InstancePath.path().toStdString()); + + instance = instanceInfo.constFind(InstancePath); + if (instance == instanceInfo.cend()) { + GTEST_SKIP_("couldn't find instance and skip."); + } + + EXPECT_EQ(instance.value(), map); + close(pidfd); if (pidFile.exists()) { diff --git a/tests/ut_job.cpp b/tests/ut_job.cpp index 80522e4..d1bfaa9 100644 --- a/tests/ut_job.cpp +++ b/tests/ut_job.cpp @@ -22,16 +22,16 @@ public: m_thread = QThread::create( [](QPromise promise) { - std::this_thread::sleep_for(2ms); + std::this_thread::sleep_for(4ms); promise.start(); - std::this_thread::sleep_for(1ms); + std::this_thread::sleep_for(2ms); if (promise.isCanceled()) { return; } - std::this_thread::sleep_for(1ms); + std::this_thread::sleep_for(2ms); promise.suspendIfRequested(); - std::this_thread::sleep_for(1ms); + std::this_thread::sleep_for(2ms); std::size_t x{0}; for (std::size_t i = 0; i < 20000; ++i) { @@ -62,14 +62,14 @@ TEST_F(TestJob, cancelJob) { m_thread->start(); - std::this_thread::sleep_for(1ms); - EXPECT_EQ(m_jobService->status().toStdString(), std::string{"pending"}); std::this_thread::sleep_for(2ms); + EXPECT_EQ(m_jobService->status().toStdString(), std::string{"pending"}); + std::this_thread::sleep_for(4ms); EXPECT_EQ(m_jobService->status().toStdString(), std::string{"running"}); m_jobService->Cancel(); - std::this_thread::sleep_for(1ms); + std::this_thread::sleep_for(2ms); EXPECT_EQ(m_jobService->status().toStdString(), std::string{"canceled"}); } @@ -78,20 +78,20 @@ TEST_F(TestJob, suspendAndResumeJob) { m_thread->start(); - std::this_thread::sleep_for(3ms); + std::this_thread::sleep_for(6ms); EXPECT_EQ(m_jobService->status().toStdString(), std::string{"running"}); m_jobService->Suspend(); - std::this_thread::sleep_for(1ms); + std::this_thread::sleep_for(2ms); EXPECT_EQ(m_jobService->status().toStdString(), std::string{"suspending"}); - std::this_thread::sleep_for(1ms); + std::this_thread::sleep_for(2ms); EXPECT_EQ(m_jobService->status().toStdString(), std::string{"suspended"}); m_jobService->Resume(); - std::this_thread::sleep_for(1ms); + std::this_thread::sleep_for(2ms); EXPECT_EQ(m_jobService->status().toStdString(), std::string{"running"}); EXPECT_TRUE(m_thread->wait());