Skip to content
This repository has been archived by the owner on Nov 4, 2023. It is now read-only.

Commit

Permalink
plugins: create ProcessControl plugin
Browse files Browse the repository at this point in the history
This plugin is used to watch for applications requesting location
updates, and keep them awaken even when unfocused. In the future we
might listen for wake-up requests coming from other system processes.

Contributes to ubports/ubuntu-touch#1067
  • Loading branch information
mardy committed Feb 14, 2022
1 parent e0555f2 commit 1a1597d
Show file tree
Hide file tree
Showing 12 changed files with 392 additions and 1 deletion.
1 change: 1 addition & 0 deletions debian/unity8-private.install
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ usr/lib/*/unity8/qml/Greeter
usr/lib/*/unity8/qml/LightDM
usr/lib/*/unity8/qml/Lights
usr/lib/*/unity8/qml/Powerd
usr/lib/*/unity8/qml/ProcessControl
usr/lib/*/unity8/qml/ScreenshotDirectory
usr/lib/*/unity8/qml/SessionBroadcast
usr/lib/*/unity8/qml/UInput
Expand Down
1 change: 1 addition & 0 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ add_subdirectory(Greeter)
add_subdirectory(LightDM)
add_subdirectory(Lights)
add_subdirectory(Powerd)
add_subdirectory(ProcessControl)
add_subdirectory(ScreenshotDirectory)
add_subdirectory(SessionBroadcast)
add_subdirectory(Ubuntu)
Expand Down
21 changes: 21 additions & 0 deletions plugins/ProcessControl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
add_definitions(-DSM_BUSNAME=sessionBus)

add_library(ProcessControl-qml MODULE
LocationWatcher.cpp
ProcessControl.cpp
plugin.cpp
)

target_link_libraries(ProcessControl-qml
Qt5::DBus Qt5::Qml
)

target_include_directories(ProcessControl-qml PRIVATE ${CMAKE_CURRENT_BINARY_DIR})

add_unity8_plugin(ProcessControl 0.1 ProcessControl TARGETS ProcessControl-qml)

set(DBUS_IFACE_DIR "${CMAKE_INSTALL_PREFIX}/share/dbus-1/interfaces")

install(FILES com.lomiri.ProcessControl.xml
DESTINATION "${DBUS_IFACE_DIR}"
)
99 changes: 99 additions & 0 deletions plugins/ProcessControl/LocationWatcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (C) 2021 UBports Foundation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Alberto Mardegan <mardy@users.sourceforge.net>
*/

#include "LocationWatcher.h"

#include "ProcessControl.h"

#include <QDBusConnection>
#include <QDebug>
#include <QStringList>
#include <QTimer>

namespace {
const QString locationServiceName = QStringLiteral("com.ubuntu.location.Service");
const QString locationObjectPath = QStringLiteral("/com/ubuntu/location/Service");
const QString propertiesInterface = QStringLiteral("org.freedesktop.DBus.Properties");
const QString methodPropertiesChanged = QStringLiteral("PropertiesChanged");
} // namespace

class LocationWatcherPrivate: public QObject
{
Q_OBJECT

public:
LocationWatcherPrivate(ProcessControl *processControl);

private Q_SLOTS:
void onPropertiesChanged(const QString &interface,
const QVariantMap &changedProps,
const QStringList &invalidatedProps);

private:
friend class LocationWatcher;
ProcessControl *m_processControl;
QDBusConnection m_connection;
QStringList m_clientApplications;
};

LocationWatcherPrivate::LocationWatcherPrivate(ProcessControl *processControl):
QObject(),
m_processControl(processControl),
m_connection(QDBusConnection::systemBus())
{
m_connection.connect(locationServiceName,
locationObjectPath,
propertiesInterface,
methodPropertiesChanged,
this,
SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
}

void LocationWatcherPrivate::onPropertiesChanged(const QString &interface,
const QVariantMap &changedProps,
const QStringList &invalidatedProps)
{
Q_UNUSED(interface);
Q_UNUSED(invalidatedProps);

qDebug() << Q_FUNC_INFO << changedProps;
const auto i = changedProps.find(QStringLiteral("ClientApplications"));
if (i != changedProps.end()) {
const QStringList appIds = i.value().toStringList();
qDebug() << "Location clients changed:" << appIds;
/* We need to strip off the version (app IDs are in the form
* "<publisher>_<app-name>_<version>") */
m_clientApplications.clear();
for (const QString &appId: appIds) {
QStringList parts = appId.split('_');
QString versionLessAppId = parts.mid(0, 2).join('_');
m_clientApplications.append(versionLessAppId);
}
m_processControl->setAwakenProcesses(m_clientApplications);
}
}

LocationWatcher::LocationWatcher(ProcessControl *processControl):
QObject(processControl),
d_ptr(new LocationWatcherPrivate(processControl))
{
}

LocationWatcher::~LocationWatcher() = default;

#include "LocationWatcher.moc"
41 changes: 41 additions & 0 deletions plugins/ProcessControl/LocationWatcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 UBports Foundation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Alberto Mardegan <mardy@users.sourceforge.net>
*/

#ifndef LOMIRI_LOCATIONWATCHER_H
#define LOMIRI_LOCATIONWATCHER_H

#include <QObject>
#include <QScopedPointer>

class ProcessControl;

class LocationWatcherPrivate;
class LocationWatcher: public QObject
{
Q_OBJECT

public:
explicit LocationWatcher(ProcessControl *processControl);
~LocationWatcher();

private:
Q_DECLARE_PRIVATE(LocationWatcher)
QScopedPointer<LocationWatcherPrivate> d_ptr;
};

#endif // LOMIRI_LOCATIONWATCHER_H
56 changes: 56 additions & 0 deletions plugins/ProcessControl/ProcessControl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2021 UBports Foundation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Alberto Mardegan <mardy@users.sourceforge.net>
*/

#include "ProcessControl.h"

#include <QDebug>

class ProcessControlPrivate
{
public:
ProcessControlPrivate(ProcessControl *q);

private:
friend class ProcessControl;
QStringList m_awakenProcesses;
};

ProcessControlPrivate::ProcessControlPrivate(ProcessControl *q)
{
}

ProcessControl::ProcessControl(QObject* parent):
QObject(parent),
d_ptr(new ProcessControlPrivate(this))
{
}

ProcessControl::~ProcessControl() = default;

void ProcessControl::setAwakenProcesses(const QStringList &processes)
{
Q_D(ProcessControl);
d->m_awakenProcesses = processes;
Q_EMIT awakenProcessesChanged();
}

QStringList ProcessControl::awakenProcesses() const
{
Q_D(const ProcessControl);
return d->m_awakenProcesses;
}
48 changes: 48 additions & 0 deletions plugins/ProcessControl/ProcessControl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2021 UBports Foundation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Alberto Mardegan <mardy@users.sourceforge.net>
*/

#ifndef LOMIRI_PROCESSCONTROL_H
#define LOMIRI_PROCESSCONTROL_H

#include <QObject>
#include <QScopedPointer>
#include <QStringList>

class ProcessControlPrivate;
class ProcessControl: public QObject
{
Q_OBJECT
Q_PROPERTY(QStringList awakenProcesses READ awakenProcesses
NOTIFY awakenProcessesChanged)

public:
explicit ProcessControl(QObject *parent = 0);
~ProcessControl();

void setAwakenProcesses(const QStringList &processes);
QStringList awakenProcesses() const;

Q_SIGNALS:
void awakenProcessesChanged();

private:
Q_DECLARE_PRIVATE(ProcessControl)
QScopedPointer<ProcessControlPrivate> d_ptr;
};

#endif // LOMIRI_PROCESSCONTROL_H
41 changes: 41 additions & 0 deletions plugins/ProcessControl/com.lomiri.ProcessControl.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<!--
This is an interface meant to be accessible only from privileged system
processes.
It can be used to request Lomiri to alter the normal lifecycle of selected
applications, typically by granting them more wake-up times than they'd
normally have. For example, a location daemon could request a temporary
wake-up of its clients so that they'd be able to process the location
updates.
-->
<interface name="com.lomiri.ProcessControl">

<!--
Request a temporary wake-up of the selected processes.
Whether the request will actually be fulfilled is up to Lomiri.
This method will not return an error reply if a process listed in the
`processes` argument is not found.
-->
<method name="RequestWakeup">
<!--
The list of processes to be waken-up. Each process is specified by its
application ID (appId).
-->
<arg name="processes" direction="in" type="as" />

<!--
The desired time span that should be granted to each of the
applications, in milliseconds.
-->
<arg name="timeSpan" direction="in" type="t" />

<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>

</interface>
</node>
41 changes: 41 additions & 0 deletions plugins/ProcessControl/plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 UBports Foundation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Alberto Mardegan <mardy@users.sourceforge.net>
*/

#include "plugin.h"

#include "LocationWatcher.h"
#include "ProcessControl.h"

#include <QQmlEngine>

static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine);
Q_UNUSED(scriptEngine);

ProcessControl *processControl = new ProcessControl();
new LocationWatcher(processControl);

return processControl;
}

void ProcessControlPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("ProcessControl"));
qmlRegisterSingletonType<ProcessControl>(uri, 0, 1, "ProcessControl", service_provider);
}
Loading

0 comments on commit 1a1597d

Please sign in to comment.