summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qmltypes/QtApplicationManager/SystemUI/plugins.qmltypes5
-rw-r--r--src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp6
-rw-r--r--src/dbus-lib/dbuspolicy.cpp6
-rw-r--r--src/dbus-lib/io.qt.applicationmanager.xml4
-rw-r--r--src/manager-lib/applicationmanager.cpp39
-rw-r--r--src/manager-lib/applicationmanager.h3
-rw-r--r--src/window-lib/waylandcompositor.cpp9
-rw-r--r--src/window-lib/waylandcompositor.h1
-rw-r--r--src/window-lib/windowmanager.cpp20
9 files changed, 83 insertions, 10 deletions
diff --git a/qmltypes/QtApplicationManager/SystemUI/plugins.qmltypes b/qmltypes/QtApplicationManager/SystemUI/plugins.qmltypes
index 5b7ce6ce..f9b4460c 100644
--- a/qmltypes/QtApplicationManager/SystemUI/plugins.qmltypes
+++ b/qmltypes/QtApplicationManager/SystemUI/plugins.qmltypes
@@ -1124,6 +1124,11 @@ Module {
Parameter { name: "pid"; type: "int"; }
}
Method {
+ name: "identifyAllApplications"
+ type: "QStringList"
+ Parameter { name: "pid"; type: "int"; }
+ }
+ Method {
name: "applicationRunState"
type: "RunState"
Parameter { name: "id"; type: "string"; }
diff --git a/src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp b/src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp
index c12ae788..5ad54940 100644
--- a/src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp
+++ b/src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp
@@ -206,6 +206,12 @@ QString ApplicationManagerAdaptor::identifyApplication(qlonglong pid)
return ApplicationManager::instance()->identifyApplication(pid);
}
+QStringList ApplicationManagerAdaptor::identifyAllApplications(qlonglong pid)
+{
+ AM_AUTHENTICATE_DBUS(QStringList)
+ return ApplicationManager::instance()->identifyAllApplications(pid);
+}
+
bool ApplicationManagerAdaptor::openUrl(const QString &url)
{
AM_AUTHENTICATE_DBUS(bool)
diff --git a/src/dbus-lib/dbuspolicy.cpp b/src/dbus-lib/dbuspolicy.cpp
index ef6214f6..43ed01b0 100644
--- a/src/dbus-lib/dbuspolicy.cpp
+++ b/src/dbus-lib/dbuspolicy.cpp
@@ -140,7 +140,11 @@ bool DBusPolicy::check(QDBusAbstractAdaptor *dbusAdaptor, const QByteArray &func
if (!ip->m_capabilities.isEmpty()) {
pid = dbusContext->connection().interface()->servicePid(dbusContext->message().service());
- QStringList appCaps = ApplicationManager::instance()->capabilities(ApplicationManager::instance()->identifyApplication(pid));
+ const auto apps = ApplicationManager::instance()->identifyAllApplications(pid);
+ if (apps.size() > 1)
+ throw "multiple apps per pid are not supported";
+ const QString appId = !apps.isEmpty() ? apps.constFirst() : QString();
+ QStringList appCaps = ApplicationManager::instance()->capabilities(appId);
bool match = false;
for (const QString &cap : ip->m_capabilities)
match = match && std::binary_search(appCaps.cbegin(), appCaps.cend(), cap);
diff --git a/src/dbus-lib/io.qt.applicationmanager.xml b/src/dbus-lib/io.qt.applicationmanager.xml
index 70ca1111..74294862 100644
--- a/src/dbus-lib/io.qt.applicationmanager.xml
+++ b/src/dbus-lib/io.qt.applicationmanager.xml
@@ -95,6 +95,10 @@
<arg type="s" direction="out"/>
<arg name="pid" type="x" direction="in"/>
</method>
+ <method name="identifyAllApplications">
+ <arg type="as" direction="out"/>
+ <arg name="pid" type="x" direction="in"/>
+ </method>
<method name="applicationRunState">
<arg type="u" direction="out"/>
<arg name="id" type="s" direction="in"/>
diff --git a/src/manager-lib/applicationmanager.cpp b/src/manager-lib/applicationmanager.cpp
index 58da711f..938333bb 100644
--- a/src/manager-lib/applicationmanager.cpp
+++ b/src/manager-lib/applicationmanager.cpp
@@ -515,19 +515,23 @@ Application *ApplicationManager::fromId(const QString &id) const
return nullptr;
}
-Application *ApplicationManager::fromProcessId(qint64 pid) const
+QVector<Application *> ApplicationManager::fromProcessId(qint64 pid) const
{
+ QVector<Application *> apps;
+
// pid could be an indirect child (e.g. when started via gdbserver)
qint64 appmanPid = QCoreApplication::applicationPid();
while ((pid > 1) && (pid != appmanPid)) {
for (Application *app : d->apps) {
+ if (apps.contains(app))
+ continue;
if (app->currentRuntime() && (app->currentRuntime()->applicationProcessId() == pid))
- return app;
+ apps.append(app);
}
pid = getParentPid(pid);
}
- return nullptr;
+ return apps;
}
Application *ApplicationManager::fromSecurityToken(const QByteArray &securityToken) const
@@ -1119,12 +1123,37 @@ QStringList ApplicationManager::capabilities(const QString &id) const
Validates the process running with process-identifier \a pid as a process started by the
application manager.
+ \note If multiple applications are running within the same container process, this function
+ will return only the first matching application. See identifyAllApplications() for
+ a way to retrieve all application ids.
+
Returns the application's \c id on success, or an empty string on failure.
*/
QString ApplicationManager::identifyApplication(qint64 pid) const
{
- Application *app = fromProcessId(pid);
- return app ? app->id() : QString();
+ const auto apps = fromProcessId(pid);
+ return !apps.isEmpty() ? apps.constFirst()->id() : QString();
+}
+
+/*!
+ \qmlmethod list<string> ApplicationManager::identifyAllApplications(int pid)
+
+ Validates the process running with process-identifier \a pid as a process started by the
+ application manager.
+
+ If multiple applications are running within the same container process, this function will
+ return all those application ids.
+
+ Returns a list with the applications' \c ids on success, or an empty list on failure.
+*/
+QStringList ApplicationManager::identifyAllApplications(qint64 pid) const
+{
+ const auto apps = fromProcessId(pid);
+ QStringList result;
+ result.reserve(apps.size());
+ for (const auto &app : apps)
+ result << app->id();
+ return result;
}
void ApplicationManager::shutDown()
diff --git a/src/manager-lib/applicationmanager.h b/src/manager-lib/applicationmanager.h
index d7d8f0fa..498f2ba5 100644
--- a/src/manager-lib/applicationmanager.h
+++ b/src/manager-lib/applicationmanager.h
@@ -102,7 +102,7 @@ public:
QVector<Application *> applications() const;
Application *fromId(const QString &id) const;
- Application *fromProcessId(qint64 pid) const;
+ QVector<Application *> fromProcessId(qint64 pid) const;
Application *fromSecurityToken(const QByteArray &securityToken) const;
QVector<Application *> schemeHandlers(const QString &scheme) const;
QVector<Application *> mimeTypeHandlers(const QString &mimeType) const;
@@ -151,6 +151,7 @@ public:
Q_SCRIPTABLE bool openUrl(const QString &url);
Q_SCRIPTABLE QStringList capabilities(const QString &id) const;
Q_SCRIPTABLE QString identifyApplication(qint64 pid) const;
+ Q_SCRIPTABLE QStringList identifyAllApplications(qint64 pid) const;
Q_SCRIPTABLE QT_PREPEND_NAMESPACE_AM(Am::RunState) applicationRunState(const QString &id) const;
ApplicationManagerInternalSignals internalSignals;
diff --git a/src/window-lib/waylandcompositor.cpp b/src/window-lib/waylandcompositor.cpp
index 45b2cbb7..8854089d 100644
--- a/src/window-lib/waylandcompositor.cpp
+++ b/src/window-lib/waylandcompositor.cpp
@@ -94,6 +94,13 @@ WaylandCompositor *WindowSurface::compositor() const
return m_compositor;
}
+QString WindowSurface::applicationId() const
+{
+ if (m_xdgSurface && m_xdgSurface->toplevel())
+ return m_xdgSurface->toplevel()->appId();
+ return { };
+}
+
bool WindowSurface::isPopup() const
{
return m_popup;
@@ -167,7 +174,7 @@ WaylandCompositor::WaylandCompositor(QQuickWindow *window, const QString &waylan
auto wmext = new QWaylandQtWindowManager(this);
connect(wmext, &QWaylandQtWindowManager::openUrl, this, [](QWaylandClient *client, const QUrl &url) {
- if (ApplicationManager::instance()->fromProcessId(client->processId()))
+ if (!ApplicationManager::instance()->fromProcessId(client->processId()).isEmpty())
ApplicationManager::instance()->openUrl(url.toString());
});
diff --git a/src/window-lib/waylandcompositor.h b/src/window-lib/waylandcompositor.h
index ddf0ab97..fdb8add9 100644
--- a/src/window-lib/waylandcompositor.h
+++ b/src/window-lib/waylandcompositor.h
@@ -90,6 +90,7 @@ public:
QWaylandWlShellSurface *shellSurface() const;
WaylandCompositor *compositor() const;
+ QString applicationId() const;
bool isPopup() const;
QRect popupGeometry() const;
void sendResizing(const QSize &size);
diff --git a/src/window-lib/windowmanager.cpp b/src/window-lib/windowmanager.cpp
index 0d8c7e9c..69201f01 100644
--- a/src/window-lib/windowmanager.cpp
+++ b/src/window-lib/windowmanager.cpp
@@ -808,11 +808,27 @@ void WindowManager::waylandSurfaceCreated(QWaylandSurface *surface)
void WindowManager::waylandSurfaceMapped(WindowSurface *surface)
{
qint64 processId = surface->processId();
- Application *app = ApplicationManager::instance()->fromProcessId(processId);
+ const auto apps = ApplicationManager::instance()->fromProcessId(processId);
+ Application *app = nullptr;
+
+ if (apps.size() == 1) {
+ app = apps.constFirst();
+ } else if (apps.size() > 1) {
+ // if there is more than one app within the same process, check the XDG surface appId
+ const QString xdgAppId = surface->applicationId();
+ if (!xdgAppId.isEmpty()) {
+ for (const auto &checkApp : apps) {
+ if (checkApp->id() == xdgAppId) {
+ app = checkApp;
+ break;
+ }
+ }
+ }
+ }
if (!app && ApplicationManager::instance()->securityChecksEnabled()) {
qCCritical(LogGraphics) << "SECURITY ALERT: an unknown application with pid" << processId
- << "tried to map a Wayland surface!";
+ << "tried to map a Wayland surface!";
return;
}