summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Griebl <robert.griebl@qt.io>2022-08-18 22:17:05 +0200
committerRobert Griebl <robert.griebl@qt.io>2022-09-16 13:15:00 +0200
commit22929f522153d66187e4cb930b71a11c0b4166c6 (patch)
treef3407c13f7cf50c5fcb3330ad8cce68f9474d973 /src
parent1163402cf942842297dc4a24911f063da84fc97b (diff)
downloadqtapplicationmanager-22929f522153d66187e4cb930b71a11c0b4166c6.tar.gz
Intents: add broadcasts
This commit adds a new intent type: a broadcast. Broadcasts will be delivered to all applications (*), but they do not have the possibility to return a reply back to the sender. Implementation wise, they are just treated as normal requests that are multiplexed for every application. (*) This can be limited with the new handleOnlyWhenRunning flag. Change-Id: If9f954cf5e52707624b95c80c8e984dfd6c4315a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Dominik Holland <dominik.holland@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/application-lib/intentinfo.cpp13
-rw-r--r--src/application-lib/intentinfo.h4
-rw-r--r--src/application-lib/yamlpackagescanner.cpp3
-rw-r--r--src/intent-client-lib/intentclient.cpp59
-rw-r--r--src/intent-client-lib/intentclient.h9
-rw-r--r--src/intent-client-lib/intentclientrequest.cpp29
-rw-r--r--src/intent-client-lib/intentclientrequest.h8
-rw-r--r--src/intent-server-lib/intent.cpp20
-rw-r--r--src/intent-server-lib/intent.h10
-rw-r--r--src/intent-server-lib/intentserver.cpp121
-rw-r--r--src/intent-server-lib/intentserver.h2
-rw-r--r--src/intent-server-lib/intentserverrequest.cpp31
-rw-r--r--src/intent-server-lib/intentserverrequest.h14
-rw-r--r--src/intent-server-lib/intentserversysteminterface.cpp5
-rw-r--r--src/intent-server-lib/intentserversysteminterface.h4
-rw-r--r--src/launcher-lib/intentclientdbusimplementation.cpp3
-rw-r--r--src/manager-lib/intentaminterface.cpp77
-rw-r--r--src/manager-lib/intentaminterface.h16
18 files changed, 307 insertions, 121 deletions
diff --git a/src/application-lib/intentinfo.cpp b/src/application-lib/intentinfo.cpp
index b4854c13..f57a5688 100644
--- a/src/application-lib/intentinfo.cpp
+++ b/src/application-lib/intentinfo.cpp
@@ -64,8 +64,13 @@ QString IntentInfo::icon() const
return m_icon.isEmpty() ? m_packageInfo->icon() : m_icon;
}
+bool IntentInfo::handleOnlyWhenRunning() const
+{
+ return m_handleOnlyWhenRunning;
+}
+
-const quint32 IntentInfo::DataStreamVersion = 2;
+const quint32 IntentInfo::DataStreamVersion = 3;
void IntentInfo::writeToDataStream(QDataStream &ds) const
@@ -80,7 +85,8 @@ void IntentInfo::writeToDataStream(QDataStream &ds) const
<< m_categories
<< m_names
<< m_descriptions
- << m_icon;
+ << m_icon
+ << m_handleOnlyWhenRunning;
}
IntentInfo *IntentInfo::readFromDataStream(PackageInfo *pkg, QDataStream &ds)
@@ -98,7 +104,8 @@ IntentInfo *IntentInfo::readFromDataStream(PackageInfo *pkg, QDataStream &ds)
>> intent->m_categories
>> intent->m_names
>> intent->m_descriptions
- >> intent->m_icon;
+ >> intent->m_icon
+ >> intent->m_handleOnlyWhenRunning;
intent->m_visibility = (visibilityStr == qSL("public")) ? Public : Private;
intent->m_categories.sort();
diff --git a/src/application-lib/intentinfo.h b/src/application-lib/intentinfo.h
index 08df4315..94b9d2b7 100644
--- a/src/application-lib/intentinfo.h
+++ b/src/application-lib/intentinfo.h
@@ -44,6 +44,8 @@ public:
QMap<QString, QString> descriptions() const;
QString icon() const;
+ bool handleOnlyWhenRunning() const;
+
void writeToDataStream(QDataStream &ds) const;
static IntentInfo *readFromDataStream(PackageInfo *pkg, QDataStream &ds);
@@ -60,6 +62,8 @@ private:
QMap<QString, QString> m_descriptions; // language -> description
QString m_icon; // relative to the manifest's location
+ bool m_handleOnlyWhenRunning = false;
+
friend class YamlPackageScanner;
Q_DISABLE_COPY(IntentInfo)
};
diff --git a/src/application-lib/yamlpackagescanner.cpp b/src/application-lib/yamlpackagescanner.cpp
index a34bfb80..f092172b 100644
--- a/src/application-lib/yamlpackagescanner.cpp
+++ b/src/application-lib/yamlpackagescanner.cpp
@@ -318,6 +318,9 @@ PackageInfo *YamlPackageScanner::scan(QIODevice *source, const QString &fileName
intentInfo->m_categories = p->parseStringOrStringList();
intentInfo->m_categories.sort();
});
+ intentFields.emplace_back("handleOnlyWhenRunning", false, YamlParser::Scalar, [&intentInfo](YamlParser *p) {
+ intentInfo->m_handleOnlyWhenRunning = p->parseScalar().toBool();
+ });
p->parseFields(intentFields);
diff --git a/src/intent-client-lib/intentclient.cpp b/src/intent-client-lib/intentclient.cpp
index 17f2ac25..4078108f 100644
--- a/src/intent-client-lib/intentclient.cpp
+++ b/src/intent-client-lib/intentclient.cpp
@@ -71,6 +71,20 @@ IntentClient *IntentClient::instance()
return s_instance;
}
+/*! \qmlproperty string IntentClient::systemUiId
+
+ The hardcoded, special application id for targeting the System UI with an intent request.
+*/
+QString IntentClient::systemUiId() const
+{
+ return qSL(":sysui:");
+}
+
+int IntentClient::replyFromSystemTimeout() const
+{
+ return m_replyFromSystemTimeout;
+}
+
void IntentClient::setReplyFromSystemTimeout(int timeout)
{
m_replyFromSystemTimeout = timeout;
@@ -145,6 +159,9 @@ IntentClientRequest *IntentClient::sendIntentRequest(const QString &intentId, co
it. The request will fail, if this specified application doesn't exist or can't handle this
specific request, even though other applications would be able to do it.
+ There is the special application id \c IntentClient.systemUiId which can be used to target the
+ System UI.
+
\sa sendIntentRequest
*/
IntentClientRequest *IntentClient::sendIntentRequest(const QString &intentId, const QString &applicationId,
@@ -152,6 +169,8 @@ IntentClientRequest *IntentClient::sendIntentRequest(const QString &intentId, co
{
if (intentId.isEmpty())
return nullptr;
+ if (applicationId == qSL(":broadcast:")) // reserved
+ return nullptr;
//TODO: check that parameters only contains basic datatypes. convertFromJSVariant() does most of
// this already, but doesn't bail out on unconvertible types (yet)
@@ -162,13 +181,37 @@ IntentClientRequest *IntentClient::sendIntentRequest(const QString &intentId, co
return icr;
}
+/*! \qmlmethod bool IntentClient::broadcastIntentRequest(string intentId, var parameters)
+ \since 6.5
+
+ Broadcasts an intent request with the given \a intentId to the system. The additional
+ \a parameters are specific to the requested \a intentId, but the format is always the same: a
+ standard JavaScript object, which can also be just empty if the requested intent doesn't
+ require any parameters.
+
+ Broadcast requests do not generate replies. The return value is only ever \c false, if you
+ call this function with invalid arguments.
+*/
+bool IntentClient::broadcastIntentRequest(const QString &intentId, const QVariantMap &parameters)
+{
+ if (intentId.isEmpty())
+ return false;
+
+ //TODO: check that parameters only contains basic datatypes. convertFromJSVariant() does most of
+ // this already, but doesn't bail out on unconvertible types (yet)
+
+ requestToSystem(m_systemInterface->currentApplicationId(this), intentId, qSL(":broadcast:"), parameters);
+ return true;
+}
+
IntentClientRequest *IntentClient::requestToSystem(const QString &requestingApplicationId,
const QString &intentId, const QString &applicationId,
const QVariantMap &parameters)
{
IntentClientRequest *ir = new IntentClientRequest(IntentClientRequest::Direction::ToSystem,
requestingApplicationId, QUuid(),
- intentId, applicationId, parameters);
+ intentId, applicationId, parameters,
+ applicationId == qSL(":broadcast:"));
qCDebug(LogIntents) << "Application" << requestingApplicationId << "created an intent request for"
<< intentId << "(application:" << applicationId << ")";
@@ -181,6 +224,11 @@ void IntentClient::requestToSystemFinished(IntentClientRequest *icr, const QUuid
if (!icr)
return;
+ if (icr->isBroadcast()) {
+ icr->deleteLater();
+ return;
+ }
+
if (error) {
icr->setErrorMessage(errorMessage);
} else if (newRequestId.isNull()) {
@@ -228,17 +276,20 @@ void IntentClient::requestToApplication(const QUuid &requestId, const QString &i
const QString &requestingApplicationId,
const QString &applicationId, const QVariantMap &parameters)
{
+ bool broadcast = (requestingApplicationId == qSL(":broadcast:"));
+
qCDebug(LogIntents) << "Client: Incoming intent request" << requestId << "to application" << applicationId
- << "for intent" << intentId << "parameters" << parameters;
+ << "for intent" << intentId << (broadcast ? "(broadcast)" : "") << "parameters" << parameters;
IntentClientRequest *icr = new IntentClientRequest(IntentClientRequest::Direction::ToApplication,
requestingApplicationId, requestId, intentId,
- applicationId, parameters);
+ applicationId, parameters, broadcast);
IntentHandler *handler = m_handlers.value(qMakePair(intentId, applicationId));
if (handler) {
QQmlEngine::setObjectOwnership(icr, QQmlEngine::JavaScriptOwnership);
- icr->startTimeout(m_replyFromApplicationTimeout);
+ if (!broadcast)
+ icr->startTimeout(m_replyFromApplicationTimeout);
emit handler->requestReceived(icr);
} else {
diff --git a/src/intent-client-lib/intentclient.h b/src/intent-client-lib/intentclient.h
index ecc224e8..a405b8c3 100644
--- a/src/intent-client-lib/intentclient.h
+++ b/src/intent-client-lib/intentclient.h
@@ -26,13 +26,17 @@ class IntentClientSystemInterface;
class IntentClient : public QObject
{
Q_OBJECT
- Q_CLASSINFO("AM-QmlType", "QtApplicationManager/IntentClient 2.0 SINGLETON")
+ Q_CLASSINFO("AM-QmlType", "QtApplicationManager/IntentClient 2.1 SINGLETON")
+ Q_PROPERTY(QString systemUiId READ systemUiId CONSTANT REVISION 1)
public:
~IntentClient() override;
static IntentClient *createInstance(IntentClientSystemInterface *systemInterface);
static IntentClient *instance();
+ QString systemUiId() const;
+
+ int replyFromSystemTimeout() const;
void setReplyFromSystemTimeout(int timeout);
void setReplyFromApplicationTimeout(int timeout);
@@ -50,6 +54,9 @@ public:
const QString &applicationId,
const QVariantMap &parameters);
+ Q_REVISION(1) Q_INVOKABLE bool broadcastIntentRequest(const QString &intentId,
+ const QVariantMap &parameters);
+
private:
void requestToSystemFinished(IntentClientRequest *icr, const QUuid &newRequestId,
bool error, const QString &errorMessage);
diff --git a/src/intent-client-lib/intentclientrequest.cpp b/src/intent-client-lib/intentclientrequest.cpp
index 09836df2..e077fe35 100644
--- a/src/intent-client-lib/intentclientrequest.cpp
+++ b/src/intent-client-lib/intentclientrequest.cpp
@@ -126,6 +126,15 @@ QT_BEGIN_NAMESPACE_AM
\sa succeeded
*/
+/*! \qmlproperty bool IntentRequest::broadcast
+ \readonly
+ \since 6.5
+
+ Only Set to \c true, if the received request is a broadcast.
+
+ \note Valid only on received requests.
+*/
+
/*! \qmlsignal IntentRequest::replyReceived()
This signal gets emitted when a reply to an intent request is available. The signal handler
@@ -145,7 +154,7 @@ IntentClientRequest::Direction IntentClientRequest::direction() const
IntentClientRequest::~IntentClientRequest()
{
// the incoming request was gc'ed on the JavaScript side, but no reply was sent yet
- if ((direction() == Direction::ToApplication) && !m_finished)
+ if ((direction() == Direction::ToApplication) && !m_finished && !m_broadcast)
sendErrorReply(qSL("Request not handled"));
}
@@ -174,6 +183,11 @@ QVariantMap IntentClientRequest::parameters() const
return m_parameters;
}
+bool IntentClientRequest::isBroadcast() const
+{
+ return m_broadcast;
+}
+
bool IntentClientRequest::succeeded() const
{
return m_succeeded;
@@ -210,6 +224,11 @@ void IntentClientRequest::sendReply(const QVariantMap &result)
qmlWarning(this) << "Calling IntentRequest::sendReply on requests originating from this application is a no-op.";
return;
}
+ if (m_broadcast) {
+ qmlWarning(this) << "Calling IntentRequest::sendReply on broadcast requests is a no-op.";
+ return;
+ }
+
IntentClient *ic = IntentClient::instance();
if (QThread::currentThread() != ic->thread()) {
@@ -241,6 +260,10 @@ void IntentClientRequest::sendErrorReply(const QString &errorMessage)
qmlWarning(this) << "Calling IntentRequest::sendErrorReply on requests originating from this application is a no-op.";
return;
}
+ if (m_broadcast) {
+ qmlWarning(this) << "Calling IntentRequest::sendErrorReply on broadcast requests is a no-op.";
+ return;
+ }
IntentClient *ic = IntentClient::instance();
if (QThread::currentThread() != ic->thread()) {
@@ -286,7 +309,8 @@ void IntentClientRequest::connectNotify(const QMetaMethod &signal)
IntentClientRequest::IntentClientRequest(Direction direction, const QString &requestingApplicationId,
const QUuid &id, const QString &intentId,
- const QString &applicationId, const QVariantMap &parameters)
+ const QString &applicationId, const QVariantMap &parameters,
+ bool broadcast)
: QObject()
, m_direction(direction)
, m_id(id)
@@ -294,6 +318,7 @@ IntentClientRequest::IntentClientRequest(Direction direction, const QString &req
, m_requestingApplicationId(requestingApplicationId)
, m_applicationId(applicationId)
, m_parameters(parameters)
+ , m_broadcast(broadcast)
{ }
void IntentClientRequest::setRequestId(const QUuid &requestId)
diff --git a/src/intent-client-lib/intentclientrequest.h b/src/intent-client-lib/intentclientrequest.h
index 02d7b39c..016ab349 100644
--- a/src/intent-client-lib/intentclientrequest.h
+++ b/src/intent-client-lib/intentclientrequest.h
@@ -19,7 +19,7 @@ class IntentClient;
class IntentClientRequest : public QObject
{
Q_OBJECT
- Q_CLASSINFO("AM-QmlType", "QtApplicationManager/IntentRequest 2.0 UNCREATABLE")
+ Q_CLASSINFO("AM-QmlType", "QtApplicationManager/IntentRequest 2.1 UNCREATABLE")
Q_PROPERTY(QUuid requestId READ requestId NOTIFY requestIdChanged)
Q_PROPERTY(Direction direction READ direction CONSTANT)
@@ -30,6 +30,7 @@ class IntentClientRequest : public QObject
Q_PROPERTY(bool succeeded READ succeeded NOTIFY replyReceived)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY replyReceived)
Q_PROPERTY(QVariantMap result READ result NOTIFY replyReceived)
+ Q_PROPERTY(bool broadcast READ isBroadcast CONSTANT REVISION 1)
public:
enum class Direction { ToSystem, ToApplication };
@@ -43,6 +44,7 @@ public:
QString applicationId() const;
QString requestingApplicationId() const;
QVariantMap parameters() const;
+ bool isBroadcast() const;
const QVariantMap result() const;
bool succeeded() const;
@@ -62,7 +64,8 @@ protected:
private:
IntentClientRequest(Direction direction, const QString &requestingApplicationId, const QUuid &id,
- const QString &intentId, const QString &applicationId, const QVariantMap &parameters);
+ const QString &intentId, const QString &applicationId, const QVariantMap &parameters,
+ bool broadcast);
void setRequestId(const QUuid &requestId);
void setResult(const QVariantMap &result);
@@ -83,6 +86,7 @@ private:
// ToSystem: we have received the final result or errorMessage via replyReceived()
// ToApplication: the request was handled and send(Error)Reply was called
bool m_finished = false;
+ bool m_broadcast = false;
Q_DISABLE_COPY(IntentClientRequest)
diff --git a/src/intent-server-lib/intent.cpp b/src/intent-server-lib/intent.cpp
index af4a4549..95992a8b 100644
--- a/src/intent-server-lib/intent.cpp
+++ b/src/intent-server-lib/intent.cpp
@@ -142,6 +142,18 @@ QT_BEGIN_NAMESPACE_AM
If the intent does not specify a \c categories list, this will return the same as the
containing PackageObject::categories.
*/
+/*!
+ \qmlproperty bool IntentObject::handleOnlyWhenRunning
+ \readonly
+ \since 6.5
+
+ By default, applications are automatically started when a request is targeted at them, but
+ they are not currently running. If this property is set to \c true, then any requests for this
+ intent will only be forwarded to its handling application, if the application is actuallly
+ running.
+ This is useful for system-wide broadcasts that are only relevant if an application is active
+ (e.g. changes in internet availability).
+*/
Intent::Intent()
@@ -151,7 +163,7 @@ Intent::Intent(const QString &id, const QString &packageId, const QString &appli
const QStringList &capabilities, Intent::Visibility visibility,
const QVariantMap &parameterMatch, const QMap<QString, QString> &names,
const QMap<QString, QString> &descriptions, const QUrl &icon,
- const QStringList &categories)
+ const QStringList &categories, bool handleOnlyWhenRunning)
: m_intentId(id)
, m_visibility(visibility)
, m_requiredCapabilities(capabilities)
@@ -162,6 +174,7 @@ Intent::Intent(const QString &id, const QString &packageId, const QString &appli
, m_descriptions(descriptions)
, m_categories(categories)
, m_icon(icon)
+ , m_handleOnlyWhenRunning(handleOnlyWhenRunning)
{
}
@@ -273,6 +286,11 @@ QStringList Intent::categories() const
return m_categories;
}
+bool Intent::handleOnlyWhenRunning() const
+{
+ return m_handleOnlyWhenRunning;
+}
+
QT_END_NAMESPACE_AM
#include "moc_intent.cpp"
diff --git a/src/intent-server-lib/intent.h b/src/intent-server-lib/intent.h
index 5ccdc6d6..dc9a7350 100644
--- a/src/intent-server-lib/intent.h
+++ b/src/intent-server-lib/intent.h
@@ -17,7 +17,7 @@ QT_BEGIN_NAMESPACE_AM
class Intent : public QObject
{
Q_OBJECT
- Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/IntentObject 2.0 UNCREATABLE")
+ Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/IntentObject 2.1 UNCREATABLE")
Q_PROPERTY(QString intentId READ intentId CONSTANT)
Q_PROPERTY(QString packageId READ packageId CONSTANT)
@@ -33,6 +33,8 @@ class Intent : public QObject
Q_PROPERTY(QVariantMap descriptions READ descriptions CONSTANT)
Q_PROPERTY(QStringList categories READ categories CONSTANT)
+ Q_PROPERTY(bool handleOnlyWhenRunning READ handleOnlyWhenRunning CONSTANT REVISION 1)
+
public:
enum Visibility {
Public,
@@ -59,12 +61,14 @@ public:
QVariantMap descriptions() const;
QStringList categories() const;
+ bool handleOnlyWhenRunning() const;
+
private:
Intent(const QString &intentId, const QString &packageId, const QString &applicationId,
const QStringList &capabilities, Intent::Visibility visibility,
const QVariantMap &parameterMatch, const QMap<QString, QString> &names,
const QMap<QString, QString> &descriptions, const QUrl &icon,
- const QStringList &categories);
+ const QStringList &categories, bool handleOnlyWhenRunning);
QString m_intentId;
Visibility m_visibility = Private;
@@ -79,6 +83,8 @@ private:
QStringList m_categories;
QUrl m_icon;
+ bool m_handleOnlyWhenRunning = false;
+
friend class IntentServer;
friend class IntentServerHandler;
friend class TestPackageLoader; // for auto tests only
diff --git a/src/intent-server-lib/intentserver.cpp b/src/intent-server-lib/intentserver.cpp
index 3813e5db..476e0c77 100644
--- a/src/intent-server-lib/intentserver.cpp
+++ b/src/intent-server-lib/intentserver.cpp
@@ -122,6 +122,7 @@ IntentServer *IntentServer::createInstance(IntentServerSystemInterface *systemIn
systemInterface->initialize(is.get());
qmlRegisterType<Intent>("QtApplicationManager.SystemUI", 2, 0, "IntentObject");
+ qmlRegisterType<Intent, 1>("QtApplicationManager.SystemUI", 2, 1, "IntentObject");
qmlRegisterType<IntentModel>("QtApplicationManager.SystemUI", 2, 0, "IntentModel");
qmlRegisterSingletonType<IntentServer>("QtApplicationManager.SystemUI", 2, 0, "IntentServer",
@@ -211,7 +212,7 @@ Intent *IntentServer::addIntent(const QString &id, const QString &packageId,
const QStringList &capabilities, Intent::Visibility visibility,
const QVariantMap &parameterMatch, const QMap<QString, QString> &names,
const QMap<QString, QString> &descriptions, const QUrl &icon,
- const QStringList &categories)
+ const QStringList &categories, bool handleOnlyWhenRunning)
{
try {
if (id.isEmpty())
@@ -233,7 +234,8 @@ Intent *IntentServer::addIntent(const QString &id, const QString &packageId,
}
auto intent = new Intent(id, packageId, handlingApplicationId, capabilities, visibility,
- parameterMatch, names, descriptions, icon, categories);
+ parameterMatch, names, descriptions, icon, categories,
+ handleOnlyWhenRunning);
QQmlEngine::setObjectOwnership(intent, QQmlEngine::CppOwnership);
beginInsertRows(QModelIndex(), rowCount(), rowCount());
@@ -502,12 +504,12 @@ void IntentServer::processRequestQueue()
qCDebug(LogIntents) << "Processing intent request" << isr << isr->requestId() << "in state" << isr->state();
if (isr->state() == IntentServerRequest::State::ReceivedRequest) { // step 1) disambiguate
- if (isr->handlingApplicationId().isEmpty()) {
+ if (!isr->isBroadcast() && !isr->selectedIntent()) {
// not disambiguated yet
if (!isSignalConnected(QMetaMethod::fromSignal(&IntentServer::disambiguationRequest))) {
// If the System UI does not react to the signal, then just use the first match.
- isr->setHandlingApplicationId(isr->potentialIntents().constFirst()->packageId());
+ isr->setSelectedIntent(isr->potentialIntents().constFirst());
} else {
m_disambiguationQueue.enqueue(isr);
isr->setState(IntentServerRequest::State::WaitingForDisambiguation);
@@ -524,67 +526,80 @@ void IntentServer::processRequestQueue()
isr->parameters());
}
}
- if (!isr->handlingApplicationId().isEmpty()) {
+ if (isr->isBroadcast() || isr->selectedIntent()) {
qCDebug(LogIntents) << "No disambiguation necessary/required for intent" << isr->intentId();
isr->setState(IntentServerRequest::State::Disambiguated);
}
}
if (isr->state() == IntentServerRequest::State::Disambiguated) { // step 2) start app
- auto handlerIPC = m_systemInterface->findClientIpc(isr->handlingApplicationId());
+ auto handlerIPC = m_systemInterface->findClientIpc(isr->selectedIntent()->applicationId());
if (!handlerIPC) {
- qCDebug(LogIntents) << "Intent handler" << isr->handlingApplicationId() << "is not running";
- m_startingAppQueue.enqueue(isr);
- isr->setState(IntentServerRequest::State::WaitingForApplicationStart);
- if (m_startingAppTimeout > 0) {
- QTimer::singleShot(m_startingAppTimeout, this, [this, isr]() {
- if (m_startingAppQueue.removeOne(isr)) {
- isr->setRequestFailed(qSL("Starting handler application timed out after %1 ms").arg(m_startingAppTimeout));
- enqueueRequest(isr);
- }
- });
+ qCDebug(LogIntents) << "Intent handler" << isr->selectedIntent()->applicationId() << "is not running";
+
+ if (isr->potentialIntents().constFirst()->handleOnlyWhenRunning()) {
+ qCDebug(LogIntents) << " * skipping, because 'handleOnlyWhenRunning' is set";
+ isr->setRequestFailed(qSL("Skipping delivery due to handleOnlyWhenRunning"));
+ } else {
+ m_startingAppQueue.enqueue(isr);
+ isr->setState(IntentServerRequest::State::WaitingForApplicationStart);
+ if (m_startingAppTimeout > 0) {
+ QTimer::singleShot(m_startingAppTimeout, this, [this, isr]() {
+ if (m_startingAppQueue.removeOne(isr)) {
+ isr->setRequestFailed(qSL("Starting handler application timed out after %1 ms").arg(m_startingAppTimeout));
+ enqueueRequest(isr);
+ }
+ });
+ }
+ m_systemInterface->startApplication(isr->selectedIntent()->applicationId());
}
- m_systemInterface->startApplication(isr->handlingApplicationId());
} else {
- qCDebug(LogIntents) << "Intent handler" << isr->handlingApplicationId() << "is already running";
+ qCDebug(LogIntents) << "Intent handler" << isr->selectedIntent()->applicationId() << "is already running";
isr->setState(IntentServerRequest::State::StartedApplication);
}
}
if (isr->state() == IntentServerRequest::State::StartedApplication) { // step 3) send request out
- auto clientIPC = m_systemInterface->findClientIpc(isr->handlingApplicationId());
+ auto clientIPC = m_systemInterface->findClientIpc(isr->selectedIntent()->applicationId());
if (!clientIPC) {
qCWarning(LogIntents) << "Could not find an IPC connection for application"
- << isr->handlingApplicationId() << "to forward the intent request"
+ << isr->selectedIntent()->applicationId() << "to forward the intent request"
<< isr->requestId();
isr->setRequestFailed(qSL("No IPC channel to reach target application."));
} else {
qCDebug(LogIntents) << "Sending intent request to handler application"
- << isr->handlingApplicationId();
- m_sentToAppQueue.enqueue(isr);
- isr->setState(IntentServerRequest::State::WaitingForReplyFromApplication);
- if (m_sentToAppTimeout > 0) {
- QTimer::singleShot(m_sentToAppTimeout, this, [this, isr]() {
- if (m_sentToAppQueue.removeOne(isr)) {
- isr->setRequestFailed(qSL("Waiting for reply from handler application timed out after %1 ms").arg(m_sentToAppTimeout));
- enqueueRequest(isr);
- }
- });
+ << isr->selectedIntent()->applicationId();
+ if (!isr->isBroadcast()) {
+ m_sentToAppQueue.enqueue(isr);
+ isr->setState(IntentServerRequest::State::WaitingForReplyFromApplication);
+ if (m_sentToAppTimeout > 0) {
+ QTimer::singleShot(m_sentToAppTimeout, this, [this, isr]() {
+ if (m_sentToAppQueue.removeOne(isr)) {
+ isr->setRequestFailed(qSL("Waiting for reply from handler application timed out after %1 ms").arg(m_sentToAppTimeout));
+ enqueueRequest(isr);
+ }
+ });
+ }
+ } else {
+ // there are no replies for broadcasts, so we simply skip this step
+ isr->setState(IntentServerRequest::State::ReceivedReplyFromApplication);
}
m_systemInterface->requestToApplication(clientIPC, isr);
}
}
if (isr->state() == IntentServerRequest::State::ReceivedReplyFromApplication) { // step 5) send reply to requesting app
- auto clientIPC = m_systemInterface->findClientIpc(isr->requestingApplicationId());
- if (!clientIPC) {
- qCWarning(LogIntents) << "Could not find an IPC connection for application"
- << isr->requestingApplicationId() << "to forward the Intent reply"
- << isr->requestId();
- } else {
- qCDebug(LogIntents) << "Forwarding intent reply" << isr->requestId()
- << "to requesting application" << isr->requestingApplicationId();
- m_systemInterface->replyFromSystem(clientIPC, isr);
+ if (!isr->isBroadcast()) {
+ auto clientIPC = m_systemInterface->findClientIpc(isr->requestingApplicationId());
+ if (!clientIPC) {
+ qCWarning(LogIntents) << "Could not find an IPC connection for application"
+ << isr->requestingApplicationId() << "to forward the Intent reply"
+ << isr->requestId();
+ } else {
+ qCDebug(LogIntents) << "Forwarding intent reply" << isr->requestId()
+ << "to requesting application" << isr->requestingApplicationId();
+ m_systemInterface->replyFromSystem(clientIPC, isr);
+ }
}
QMetaObject::invokeMethod(this, [isr]() { delete isr; }, Qt::QueuedConnection); // aka deleteLater for non-QObject
isr = nullptr;
@@ -595,6 +610,9 @@ void IntentServer::processRequestQueue()
QList<QObject *> IntentServer::convertToQml(const QVector<Intent *> &intents)
{
+ //TODO: we really should copy here, because the Intent pointers may die: a disambiguation might
+ // be active, while one of the apps involved is removed or updated
+
QList<QObject *> ol;
for (auto intent : intents)
ol << intent;
@@ -675,7 +693,7 @@ void IntentServer::internalDisambiguateRequest(const QUuid &requestId, bool reje
if (reject) {
isr->setRequestFailed(qSL("Disambiguation was rejected"));
} else if (isr->potentialIntents().contains(selectedIntent)) {
- isr->setHandlingApplicationId(selectedIntent->applicationId());
+ isr->setSelectedIntent(selectedIntent);
isr->setState(IntentServerRequest::State::Disambiguated);
} else {
qCWarning(LogIntents) << "IntentServer::acknowledgeDisambiguationRequest for intent"
@@ -694,7 +712,7 @@ void IntentServer::applicationWasStarted(const QString &applicationId)
bool foundOne = false;
for (auto it = m_startingAppQueue.cbegin(); it != m_startingAppQueue.cend(); ) {
auto isr = *it;
- if (isr->handlingApplicationId() == applicationId) {
+ if (isr->selectedIntent()->applicationId() == applicationId) {
qCDebug(LogIntents) << "Intent request" << isr->intentId()
<< "can now be forwarded to application" << applicationId;
@@ -726,10 +744,10 @@ void IntentServer::replyFromApplication(const QString &replyingApplicationId, co
qCWarning(LogIntents) << "Got a reply for intent" << requestId << "from application"
<< replyingApplicationId << "but no reply was expected for this intent";
} else {
- if (isr->handlingApplicationId() != replyingApplicationId) {
+ if (isr->selectedIntent() && (isr->selectedIntent()->applicationId() != replyingApplicationId)) {
qCWarning(LogIntents) << "Got a reply for intent" << isr->requestId() << "from application"
<< replyingApplicationId << "but expected a reply from"
- << isr->handlingApplicationId() << "instead";
+ << isr->selectedIntent()->applicationId() << "instead";
isr->setRequestFailed(qSL("Request reply received from wrong application"));
} else {
QString errorMessage;
@@ -762,7 +780,8 @@ IntentServerRequest *IntentServer::requestToSystem(const QString &requestingAppl
}
QVector<Intent *> intents;
- if (applicationId.isEmpty()) {
+ bool broadcast = (applicationId == qSL(":broadcast:"));
+ if (applicationId.isEmpty() || broadcast) {
intents = filterByIntentId(m_intents, intentId, parameters);
} else {
if (Intent *intent = this->applicationIntent(intentId, applicationId, parameters))
@@ -783,9 +802,17 @@ IntentServerRequest *IntentServer::requestToSystem(const QString &requestingAppl
return nullptr;
}
- auto isr = new IntentServerRequest(requestingApplicationId, intentId, intents, parameters);
- enqueueRequest(isr);
- return isr;
+ if (broadcast) {
+ for (auto intent : qAsConst(intents)) {
+ auto isr = new IntentServerRequest(requestingApplicationId, intentId, { intent }, parameters, broadcast);
+ enqueueRequest(isr);
+ }
+ return nullptr; // this is not an error condition for broadcasts - there simply is no return value for the sender
+ } else {
+ auto isr = new IntentServerRequest(requestingApplicationId, intentId, intents, parameters, broadcast);
+ enqueueRequest(isr);
+ return isr;
+ }
}
QT_END_NAMESPACE_AM
diff --git a/src/intent-server-lib/intentserver.h b/src/intent-server-lib/intentserver.h
index cd0828ec..5419f175 100644
--- a/src/intent-server-lib/intentserver.h
+++ b/src/intent-server-lib/intentserver.h
@@ -47,7 +47,7 @@ public:
const QStringList &capabilities, Intent::Visibility visibility,
const QVariantMap &parameterMatch, const QMap<QString, QString> &names,
const QMap<QString, QString> &descriptions, const QUrl &icon,
- const QStringList &categories);
+ const QStringList &categories, bool handleOnlyWhenRunning);
void removeIntent(Intent *intent);
diff --git a/src/intent-server-lib/intentserverrequest.cpp b/src/intent-server-lib/intentserverrequest.cpp
index 7880007e..9641ccbb 100644
--- a/src/intent-server-lib/intentserverrequest.cpp
+++ b/src/intent-server-lib/intentserverrequest.cpp
@@ -9,18 +9,22 @@ QT_BEGIN_NAMESPACE_AM
IntentServerRequest::IntentServerRequest(const QString &requestingApplicationId, const QString &intentId,
const QVector<Intent *> &potentialIntents,
- const QVariantMap &parameters)
+ const QVariantMap &parameters, bool broadcast)
: m_id(QUuid::createUuid())
, m_state(State::ReceivedRequest)
+ , m_broadcast(broadcast)
, m_intentId(intentId)
, m_requestingApplicationId(requestingApplicationId)
- , m_potentialIntents(potentialIntents)
, m_parameters(parameters)
{
Q_ASSERT(!potentialIntents.isEmpty());
+ Q_ASSERT(!broadcast || (potentialIntents.size() == 1));
+
+ for (auto *intent : potentialIntents)
+ m_potentialIntents << intent;
if (potentialIntents.size() == 1)
- setHandlingApplicationId(potentialIntents.first()->applicationId());
+ setSelectedIntent(potentialIntents.constFirst());
}
IntentServerRequest::State IntentServerRequest::state() const
@@ -43,14 +47,19 @@ QString IntentServerRequest::requestingApplicationId() const
return m_requestingApplicationId;
}
-QString IntentServerRequest::handlingApplicationId() const
+Intent *IntentServerRequest::selectedIntent() const
{
- return m_handlingApplicationId;
+ return m_selectedIntent.get();
}
QVector<Intent *> IntentServerRequest::potentialIntents() const
{
- return m_potentialIntents;
+ QVector<Intent *> out;
+ for (auto &intent : m_potentialIntents) {
+ if (intent)
+ out << intent.get();
+ }
+ return out;
}
QVariantMap IntentServerRequest::parameters() const
@@ -68,6 +77,11 @@ QVariantMap IntentServerRequest::result() const
return m_result;
}
+bool IntentServerRequest::isBroadcast() const
+{
+ return m_broadcast;
+}
+
void IntentServerRequest::setRequestFailed(const QString &errorMessage)
{
m_succeeded = false;
@@ -88,9 +102,10 @@ void IntentServerRequest::setState(IntentServerRequest::State newState)
m_state = newState;
}
-void IntentServerRequest::setHandlingApplicationId(const QString &applicationId)
+void IntentServerRequest::setSelectedIntent(Intent *intent)
{
- m_handlingApplicationId = applicationId;
+ if (m_potentialIntents.contains(intent))
+ m_selectedIntent = intent;
}
QT_END_NAMESPACE_AM
diff --git a/src/intent-server-lib/intentserverrequest.h b/src/intent-server-lib/intentserverrequest.h
index eb8004f9..2b2bd27b 100644
--- a/src/intent-server-lib/intentserverrequest.h
+++ b/src/intent-server-lib/intentserverrequest.h
@@ -10,6 +10,7 @@
#include <QVariantMap>
#include <QUuid>
#include <QVector>
+#include <QPointer>
#include <QtAppManCommon/global.h>
#include <QtAppManIntentServer/intent.h>
@@ -23,7 +24,8 @@ class IntentServerRequest
public:
IntentServerRequest(const QString &requestingApplicationId, const QString &intentId,
- const QVector<Intent *> &potentialIntents, const QVariantMap &parameters);
+ const QVector<Intent *> &potentialIntents, const QVariantMap &parameters,
+ bool broadcast);
enum class State {
ReceivedRequest,
@@ -41,14 +43,15 @@ public:
QUuid requestId() const;
QString intentId() const;
QString requestingApplicationId() const;
- QString handlingApplicationId() const;
+ Intent *selectedIntent() const;
QVector<Intent *> potentialIntents() const;
QVariantMap parameters() const;
bool succeeded() const;
QVariantMap result() const;
+ bool isBroadcast() const;
void setState(State newState);
- void setHandlingApplicationId(const QString &applicationId);
+ void setSelectedIntent(Intent *intent);
void setRequestFailed(const QString &errorMessage);
void setRequestSucceeded(const QVariantMap &result);
@@ -57,10 +60,11 @@ private:
QUuid m_id;
State m_state;
bool m_succeeded = false;
+ bool m_broadcast = false;
QString m_intentId;
QString m_requestingApplicationId;
- QString m_handlingApplicationId;
- QVector<Intent *> m_potentialIntents;
+ QPointer<Intent> m_selectedIntent;
+ QVector<QPointer<Intent>> m_potentialIntents;
QVariantMap m_parameters;
QVariantMap m_result;
};
diff --git a/src/intent-server-lib/intentserversysteminterface.cpp b/src/intent-server-lib/intentserversysteminterface.cpp
index f17038d5..08945c12 100644
--- a/src/intent-server-lib/intentserversysteminterface.cpp
+++ b/src/intent-server-lib/intentserversysteminterface.cpp
@@ -14,8 +14,11 @@ void IntentServerSystemInterface::initialize(IntentServer *intentServer)
connect(this, &IntentServerSystemInterface::replyFromApplication,
m_is, &IntentServer::replyFromApplication);
+
+ // we need to explicitly decouple here via QueuedConnection. Otherwise the request queue
+ // handling in IntentServer can get out of sync
connect(this, &IntentServerSystemInterface::applicationWasStarted,
- m_is, &IntentServer::applicationWasStarted);
+ m_is, &IntentServer::applicationWasStarted, Qt::QueuedConnection);
}
IntentServer *IntentServerSystemInterface::intentServer() const
diff --git a/src/intent-server-lib/intentserversysteminterface.h b/src/intent-server-lib/intentserversysteminterface.h
index d317cc96..8b2f299c 100644
--- a/src/intent-server-lib/intentserversysteminterface.h
+++ b/src/intent-server-lib/intentserversysteminterface.h
@@ -37,9 +37,9 @@ public:
IntentServerRequest *requestToSystem(const QString &requestingApplicationId, const QString &intentId,
const QString &applicationId, const QVariantMap &parameters);
- virtual void replyFromSystem(IpcConnection *clientIPC, IntentServerRequest *irs) = 0;
+ virtual void replyFromSystem(IpcConnection *clientIPC, IntentServerRequest *isr) = 0;
- virtual void requestToApplication(IpcConnection *clientIPC, IntentServerRequest *irs) = 0;
+ virtual void requestToApplication(IpcConnection *clientIPC, IntentServerRequest *isr) = 0;
signals:
void applicationWasStarted(const QString &appId);
diff --git a/src/launcher-lib/intentclientdbusimplementation.cpp b/src/launcher-lib/intentclientdbusimplementation.cpp
index c4056a31..57451388 100644
--- a/src/launcher-lib/intentclientdbusimplementation.cpp
+++ b/src/launcher-lib/intentclientdbusimplementation.cpp
@@ -40,9 +40,12 @@ void IntentClientDBusImplementation::initialize(IntentClient *intentClient) Q_DE
QQmlEngine::setObjectOwnership(IntentClient::instance(), QQmlEngine::CppOwnership);
return IntentClient::instance();
});
+ qmlRegisterRevision<IntentClient, 1>("QtApplicationManager", 2, 1);
qmlRegisterUncreatableType<IntentClientRequest>("QtApplicationManager", 2, 0, "IntentRequest",
qSL("Cannot create objects of type IntentRequest"));
+ qmlRegisterUncreatableType<IntentClientRequest, 1>("QtApplicationManager", 2, 1, "IntentRequest",
+ qSL("Cannot create objects of type IntentRequest"));
qmlRegisterType<IntentHandler>("QtApplicationManager.Application", 2, 0, "IntentHandler");
diff --git a/src/manager-lib/intentaminterface.cpp b/src/manager-lib/intentaminterface.cpp
index 3aeb5b1d..28bc19ae 100644
--- a/src/manager-lib/intentaminterface.cpp
+++ b/src/manager-lib/intentaminterface.cpp
@@ -41,9 +41,6 @@
QT_BEGIN_NAMESPACE_AM
-static QString sysUiId() { return qSL(":sysui:"); }
-
-
//////////////////////////////////////////////////////////////////////////
// vvv IntentAMImplementation vvv
@@ -105,7 +102,7 @@ IntentServer *IntentAMImplementation::createIntentServerAndClientInstance(Packag
intentInfo->parameterMatch(), intentInfo->names(),
intentInfo->descriptions(),
QUrl::fromLocalFile(package->info()->baseDir().absoluteFilePath(intentInfo->icon())),
- intentInfo->categories())) {
+ intentInfo->categories(), intentInfo->handleOnlyWhenRunning())) {
throw Exception(Error::Intents, "could not add intent %1 for package %2")
.arg(intentInfo->id()).arg(package->id());
}
@@ -196,7 +193,7 @@ void IntentServerAMImplementation::initialize(IntentServer *server)
bool IntentServerAMImplementation::checkApplicationCapabilities(const QString &applicationId,
const QStringList &requiredCapabilities)
{
- if (applicationId == sysUiId()) // The System UI bypasses the capabilities check
+ if (applicationId == IntentClient::instance()->systemUiId()) // The System UI bypasses the capabilities check
return true;
const auto app = ApplicationManager::instance()->application(applicationId);
@@ -223,15 +220,15 @@ void IntentServerAMImplementation::startApplication(const QString &appId)
}
void IntentServerAMImplementation::requestToApplication(IntentServerSystemInterface::IpcConnection *clientIPC,
- IntentServerRequest *irs)
+ IntentServerRequest *isr)
{
- reinterpret_cast<IntentServerIpcConnection *>(clientIPC)->requestToApplication(irs);
+ reinterpret_cast<IntentServerIpcConnection *>(clientIPC)->requestToApplication(isr);
}
void IntentServerAMImplementation::replyFromSystem(IntentServerSystemInterface::IpcConnection *clientIPC,
- IntentServerRequest *irs)
+ IntentServerRequest *isr)
{
- reinterpret_cast<IntentServerIpcConnection *>(clientIPC)->replyFromSystem(irs);
+ reinterpret_cast<IntentServerIpcConnection *>(clientIPC)->replyFromSystem(isr);
}
@@ -251,7 +248,7 @@ QString IntentClientAMImplementation::currentApplicationId(QObject *hint)
{
QmlInProcessRuntime *runtime = QmlInProcessRuntime::determineRuntime(hint);
- return runtime ? runtime->application()->info()->id() : sysUiId();
+ return runtime ? runtime->application()->info()->id() : IntentClient::instance()->systemUiId();
}
void IntentClientAMImplementation::initialize(IntentClient *intentClient) Q_DECL_NOEXCEPT_EXPR(false)
@@ -263,9 +260,12 @@ void IntentClientAMImplementation::initialize(IntentClient *intentClient) Q_DECL
QQmlEngine::setObjectOwnership(IntentClient::instance(), QQmlEngine::CppOwnership);
return IntentClient::instance();
});
+ qmlRegisterRevision<IntentClient, 1>("QtApplicationManager", 2, 1);
qmlRegisterUncreatableType<IntentClientRequest>("QtApplicationManager", 2, 0, "IntentRequest",
qSL("Cannot create objects of type IntentRequest"));
+ qmlRegisterUncreatableType<IntentClientRequest, 1>("QtApplicationManager", 2, 1, "IntentRequest",
+ qSL("Cannot create objects of type IntentRequest"));
qmlRegisterType<IntentHandler>("QtApplicationManager.Application", 2, 0, "IntentHandler");
qmlRegisterType<IntentServerHandler>("QtApplicationManager.SystemUI", 2, 0, "IntentServerHandler");
@@ -334,7 +334,8 @@ void IntentServerIpcConnection::setReady(Application *application)
return;
m_application = application;
m_ready = true;
- emit applicationIsReady((isInProcess() && !application) ? sysUiId() : application->id());
+ emit applicationIsReady((isInProcess() && !application) ? IntentClient::instance()->systemUiId()
+ : application->id());
}
IntentServerIpcConnection *IntentServerIpcConnection::find(const QString &appId)
@@ -395,28 +396,29 @@ IntentServerInProcessIpcConnection *IntentServerInProcessIpcConnection::createSy
QString IntentServerInProcessIpcConnection::applicationId() const
{
- return m_isSystemUi ? sysUiId() : IntentServerIpcConnection::applicationId();
+ return m_isSystemUi ? IntentClient::instance()->systemUiId()
+ : IntentServerIpcConnection::applicationId();
}
-void IntentServerInProcessIpcConnection::requestToApplication(IntentServerRequest *irs)
+void IntentServerInProcessIpcConnection::requestToApplication(IntentServerRequest *isr)
{
// we need decouple the server/client interface at this point to have a consistent
// behavior in single- and multi-process mode
- QMetaObject::invokeMethod(this, [this, irs]() {
+ QMetaObject::invokeMethod(this, [this, isr]() {
auto clientInterface = m_interface->intentClientSystemInterface();
- emit clientInterface->requestToApplication(irs->requestId(), irs->intentId(),
- irs->requestingApplicationId(),
- irs->handlingApplicationId(), irs->parameters());
+ emit clientInterface->requestToApplication(isr->requestId(), isr->intentId(),
+ isr->isBroadcast() ? qSL(":broadcast:") : isr->requestingApplicationId(),
+ isr->selectedIntent()->applicationId(), isr->parameters());
}, Qt::QueuedConnection);
}
-void IntentServerInProcessIpcConnection::replyFromSystem(IntentServerRequest *irs)
+void IntentServerInProcessIpcConnection::replyFromSystem(IntentServerRequest *isr)
{
// we need decouple the server/client interface at this point to have a consistent
// behavior in single- and multi-process mode
- QMetaObject::invokeMethod(this, [this, irs]() {
+ QMetaObject::invokeMethod(this, [this, isr]() {
auto clientInterface = m_interface->intentClientSystemInterface();
- emit clientInterface->replyFromSystem(irs->requestId(), !irs->succeeded(), irs->result());
+ emit clientInterface->replyFromSystem(isr->requestId(), !isr->succeeded(), isr->result());
}, Qt::QueuedConnection);
}
@@ -465,17 +467,21 @@ IntentServerDBusIpcConnection *IntentServerDBusIpcConnection::find(QDBusConnecti
return nullptr;
}
-void IntentServerDBusIpcConnection::requestToApplication(IntentServerRequest *irs)
+void IntentServerDBusIpcConnection::requestToApplication(IntentServerRequest *isr)
{
- emit m_adaptor->requestToApplication(irs->requestId().toString(), irs->intentId(),
- irs->handlingApplicationId(),
- convertFromJSVariant(irs->parameters()).toMap());
+ Q_ASSERT(isr && isr->selectedIntent());
+
+ emit m_adaptor->requestToApplication(isr->requestId().toString(), isr->intentId(),
+ isr->selectedIntent()->applicationId(),
+ convertFromJSVariant(isr->parameters()).toMap());
}
-void IntentServerDBusIpcConnection::replyFromSystem(IntentServerRequest *irs)
+void IntentServerDBusIpcConnection::replyFromSystem(IntentServerRequest *isr)
{
- emit m_adaptor->replyFromSystem(irs->requestId().toString(), !irs->succeeded(),
- convertFromJSVariant(irs->result()).toMap());
+ Q_ASSERT(isr);
+
+ emit m_adaptor->replyFromSystem(isr->requestId().toString(), !isr->succeeded(),
+ convertFromJSVariant(isr->result()).toMap());
}
QString IntentServerDBusIpcConnection::requestToSystem(const QString &intentId,
@@ -483,13 +489,13 @@ QString IntentServerDBusIpcConnection::requestToSystem(const QString &intentId,
const QVariantMap &parameters)
{
auto requestingApplicationId = application() ? application()->id() : QString();
- auto irs = m_interface->requestToSystem(requestingApplicationId, intentId, applicationId,
+ auto isr = m_interface->requestToSystem(requestingApplicationId, intentId, applicationId,
convertFromDBusVariant(parameters).toMap());
- if (!irs) {
+ if (!isr) {
sendErrorReply(QDBusError::NotSupported, qL1S("No matching intent handler registered."));
return QString();
} else {
- return irs->requestId().toString();
+ return isr->requestId().toString();
}
}
@@ -733,9 +739,11 @@ void IntentServerHandler::componentComplete()
return;
}
+ QString sysUiId = IntentClient::instance()->systemUiId();
+
IntentServer *is = IntentServer::instance();
- is->addPackage(sysUiId());
- is->addApplication(sysUiId(), sysUiId());
+ is->addPackage(sysUiId);
+ is->addApplication(sysUiId, sysUiId);
const auto ids = intentIds();
for (const auto &intentId : ids) {
@@ -748,9 +756,10 @@ void IntentServerHandler::componentComplete()
for (auto it = qvm_descriptions.cbegin(); it != qvm_descriptions.cend(); ++it)
descriptions.insert(it.key(), it.value().toString());
- auto intent = is->addIntent(intentId, sysUiId(), sysUiId(), m_intent->requiredCapabilities(),
+ auto intent = is->addIntent(intentId, sysUiId, sysUiId, m_intent->requiredCapabilities(),
m_intent->visibility(), m_intent->parameterMatch(), names,
- descriptions, m_intent->icon(), m_intent->categories());
+ descriptions, m_intent->icon(), m_intent->categories(),
+ m_intent->handleOnlyWhenRunning());
if (intent)
m_registeredIntents << intent;
else
diff --git a/src/manager-lib/intentaminterface.h b/src/manager-lib/intentaminterface.h
index 81d7fd3f..f72418b3 100644
--- a/src/manager-lib/intentaminterface.h
+++ b/src/manager-lib/intentaminterface.h
@@ -54,8 +54,8 @@ public:
IpcConnection *findClientIpc(const QString &appId) override;
void startApplication(const QString &appId) override;
- void requestToApplication(IpcConnection *clientIPC, IntentServerRequest *irs) override;
- void replyFromSystem(IpcConnection *clientIPC, IntentServerRequest *irs) override;
+ void requestToApplication(IpcConnection *clientIPC, IntentServerRequest *isr) override;
+ void replyFromSystem(IpcConnection *clientIPC, IntentServerRequest *isr) override;
private:
IntentClientSystemInterface *m_icsi = nullptr;
@@ -94,8 +94,8 @@ public:
bool isReady() const;
void setReady(Application *application);
- virtual void replyFromSystem(IntentServerRequest *irs) = 0;
- virtual void requestToApplication(IntentServerRequest *irs) = 0;
+ virtual void replyFromSystem(IntentServerRequest *isr) = 0;
+ virtual void requestToApplication(IntentServerRequest *isr) = 0;
signals:
void applicationIsReady(const QString &applicationId);
@@ -122,8 +122,8 @@ public:
QString applicationId() const override;
- void replyFromSystem(IntentServerRequest *irs) override;
- void requestToApplication(IntentServerRequest *irs) override;
+ void replyFromSystem(IntentServerRequest *isr) override;
+ void requestToApplication(IntentServerRequest *isr) override;
private:
IntentServerInProcessIpcConnection(Application *application, IntentServerAMImplementation *iface);
@@ -146,8 +146,8 @@ public:
~IntentServerDBusIpcConnection() override;
QString requestToSystem(const QString &intentId, const QString &applicationId, const QVariantMap &parameters);
- void replyFromSystem(IntentServerRequest *irs) override;
- void requestToApplication(IntentServerRequest *irs) override;
+ void replyFromSystem(IntentServerRequest *isr) override;
+ void requestToApplication(IntentServerRequest *isr) override;
void replyFromApplication(const QString &requestId, bool error, const QVariantMap &result);