summaryrefslogtreecommitdiffstats
path: root/examples/applicationmanager/intents/doc/src/intents.qdoc
blob: 65a0d5d8682dc58bcf09cbba6f96d63fe23cffb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Luxoft Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
** Licensees holding valid commercial Qt Automotive Suite licenses may use
** this file in accordance with the commercial license agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and The Qt Company.  For
** licensing terms and conditions see https://www.qt.io/terms-conditions.
** For further information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!

\example applicationmanager/intents
\title Intents System-UI and Applications Example
\image intents-example.png The Intents example with all applications running.
\brief Three applications and a System-UI communicating over Intents.
\ingroup applicationmanager-examples

\section1 Introduction

This example shows how the System-UI and applications can send and receive Intents. Just like in the
"Hello World!" example, the window management part is kept to a minimum: the 2x2 grid on the right
will always show the System-UI part (gray) in the top-left quadrant, while the three apps (red,
green and blue) will dynamically occupy the other quadrants in the order they are started. You're
able to see icons and names of the available applications on the left and start and stop them by
clicking on their respective icons.

Each application, as well as the System-UI look alike and have the same functionality available in
the UI: You can choose from one of the available intent ids in the top combo-box (labeled \e Intent),
and optionally also specify which application you would like to handle the chosen request via the
combo-box below (labeled \e Application).
Clicking the \e Request button will create and send the corresponding intent request to the
application-manager's IntentServer for handling. There are three possible outcomes:
\list
\li The \e Intent / \e Application combination was valid and the target application was able to
    handle the request: the \l{IntentRequest::result}{result of this request} will be shown
    as JSON text in the lower output field labeled \e Request.

\li Either the \e Intent / \e Application combination was invalid or the target application was not
    able to handle the request properly: the \l{IntentRequest::errorMessage}
    {error message of this request} will be shown as plain text in the lower output field
    labeled \e Request.

\li You did not specify an \e Application, plus the chosen \e Intent can be handled by more than
    one application: in this case the example's System-UI will display a dialog, prompting the user
    to \l{IntentServer::disambiguationRequest}{disambiguate the request}.
\endlist


\section1 Files and folder structure

This example is comprised of a System-UI and three sample applications ("Red Intents", "Green Intents"
and "Blue Intents"), making for four separate QML applications in total. System-UI is also just a QML
application in the end, albeit a special one.

Each application is put in its own separate directory as described below. Since the QtQuickControls
2 based UI is used by all the applications and the System-UI, its component live in a shared
directory.

\list
\li \tt{system-ui.qml}
\li \tt{\b{apps}}
    \list
    \li \tt{\b{intents.blue}}
        \list
        \li \tt{icon.png}
        \li \tt{info.yaml}
        \li \tt{main.qml}
        \endlist
    \li \tt{\b{intents.red}}
        \list
        \li \tt{icon.png}
        \li \tt{info.yaml}
        \li \tt{main.qml}
        \endlist
    \li \tt{\b{intents.green}}
        \list
        \li \tt{icon.png}
        \li \tt{info.yaml}
        \li \tt{main.qml}
        \endlist
    \endlist
\li \tt{\b{shared}}
    \list
    \li \tt{IntentsApplicationWindow.qml}
    \li \tt{IntentsUIPage.qml}
    \endlist
\endlist

As you can see above, each application, besides its main QML file, also has an icon and a
\tt{info.yaml}. That YAML file contains the application metadata, which also includes the
definition of the intents that this application is able to handle.

\section1 Running

Assuming the \c appman executable is in your path, you can run the System-UI as follows:

\badcode
examples/applicationmanager/intents$ appman --builtin-apps-manifest-dir ./apps system-ui.qml
\endcode

Adding \c{-o "ui: { style: material }" } will make the example look and feel a lot nicer.

And this is what you should see:

\image intents-launched.png

For information on these and other command line options you can run \tt{appman --help}.


\section1 Application implementation

All the applicationa (red, green and blue) are exactly the same and their \c main.qml just
instantiates the shared IntentsApplicationWindow component.

\snippet applicationmanager/intents/apps/intents.red/main.qml Main

The IntentsApplicationWindow component is actually a top-level ApplicationManagerWindow, with its
UI contents being defined by instantiating the - also shared - component \c IntentsUIPage. This UI
component does not have any intent specific code, so the actual sending is done in signal
handler attached to the IntentsUIPage request signal:

\snippet applicationmanager/intents/shared/IntentsApplicationWindow.qml Send Intent

After calling IntentClient::sendIntentRequest with the parameters as chosen in the UI, the
example code will connect a function object to the \l{IntentClientRequest::replyReceived}
{request's replyReceived} signal. As mentioned in the introduction, it will then dump the result
into the \e Request field in the UI.

In addition, it defines all the necessary IntentHandlers for the applications, e.g.:

\snippet applicationmanager/intents/shared/IntentsApplicationWindow.qml Intent Handler

These intent handlers are pretty simple, with each one just triggering a simple animation that is
also defined in this file, so for the \c rotate-window intent this would be:

\snippet applicationmanager/intents/shared/IntentsApplicationWindow.qml Intent Animation

Just implementing IntentHandlers in QML is not enough though, because the application-manager needs
the information on which application supports which intents \b before the applications are already
running, most importantly to faciliate auto-starting applications on intent requests. As for
every other application configuration in the application-manager, this is done through the
applications's manifest file \c info.yaml:

The \b Red application defines three available intents.

\quotefromfile applicationmanager/intents/apps/intents.red/info.yaml
\skipto intents:
\printto

Additionally, the red application gains the \c call-blue capability, which is required by certain
intents in the blue application (see below)

\quotefromfile applicationmanager/intents/apps/intents.red/info.yaml
\skipto capabilities:
\printline capabilities


The \b Green application defines only two available intents. Please note that even though the green
application has an IntentHandler for the \c blink-window intent through the shared
IntentsApplicationWindow component, this handler would never be called, since this intent id is not
registered with the system via the \c info.yaml manifest:

\quotefromfile applicationmanager/intents/apps/intents.green/info.yaml
\skipto intents:
\printto

The \b Blue application has the most complex intent definition. In addition to handling the same
three intents as the red application, it registeres the \c blue-window-private intent that has the
attribute \c{visibility: private}. Private intents can only be requested from the same application
that registered them, so in this case only blue can successfully request the \c blue-window-private
intent. Furthermore, the \c rotate-window intent in this application can only be requested by
applications that have the \c call-blue capability: here the red application comes with the
required capability, while the green one doesn't (see above).

\quotefromfile applicationmanager/intents/apps/intents.blue/info.yaml
\skipto intents:
\printto


\section1 System-UI implementation

The windows and application management part of the System-UI is in large parts a copy of the
"Hello-World!" example. Instead of arranging all incoming application windows in a column on the
right, the Intents example uses a 2x2 grid to display its own UI and the three applications it
comes with. The System-UI in the top-left part is the shared IntentsUIPage component, that is used
the same way in the applications (see below).

What is special about the System-UI as compared to the applications, is the disambiguation
mechanism and the accompanying UI. Registering for the IntentServer's disambiguation requests is
done here:

\snippet applicationmanager/intents/system-ui.qml Connection

Since we want to stay flexible with regards to the number of parallel intent requests in the system,
we just add the incoming request to a queue (\c allRequests). The \c Dialog that consumes that
queue is a fairly standard QtQuickControls 2 dialog, that gives you nice UI showing you the
possible application choices coming from the IntentServer::disambiguationRequested() signal. Upon
pressing \e Ok or \e Cancel, the dialog will notify the IntentServer about the user's decision:

\snippet applicationmanager/intents/system-ui.qml OkCancel

*/