1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qnearfieldmanager.h" |
5 | #include "qnearfieldmanager_p.h" |
6 | |
7 | #if defined(QT_SIMULATOR) |
8 | #include "qnearfieldmanager_simulator_p.h" |
9 | #elif defined(ANDROID_NFC) |
10 | #include "qnearfieldmanager_android_p.h" |
11 | #elif defined(IOS_NFC) |
12 | #include "qnearfieldmanager_ios_p.h" |
13 | #elif defined(PCSC_NFC) |
14 | #include "qnearfieldmanager_pcsc_p.h" |
15 | #else |
16 | #include "qnearfieldmanager_generic_p.h" |
17 | #endif |
18 | |
19 | #include <QtCore/QMetaType> |
20 | #include <QtCore/QMetaMethod> |
21 | |
22 | QT_BEGIN_NAMESPACE |
23 | |
24 | /*! |
25 | \class QNearFieldManager |
26 | \brief The QNearFieldManager class provides access to notifications for NFC events. |
27 | |
28 | \ingroup connectivity-nfc |
29 | \inmodule QtNfc |
30 | \since 5.2 |
31 | |
32 | NFC Forum devices support two modes of communications. The first mode, peer-to-peer |
33 | communications, is used to communicate between two NFC Forum devices. The second mode, |
34 | master/slave communications, is used to communicate between an NFC Forum device and an NFC |
35 | Forum Tag or Contactless Card. The targetDetected() signal is emitted when a target device |
36 | enters communications range. Communications can be initiated from the slot connected to this |
37 | signal. |
38 | |
39 | NFC Forum devices generally operate as the master in master/slave communications. Some devices |
40 | are also capable of operating as the slave, so called Card Emulation mode. In this mode the |
41 | local NFC device emulates a NFC Forum Tag or Contactless Card. |
42 | |
43 | Applications can connect to the targetDetected() and targetLost() signals to get notified when |
44 | an NFC Forum Tag enters or leaves proximity. Before these signals are emitted target detection |
45 | must be started with the startTargetDetection() function. Target detection can be stopped with |
46 | the stopTargetDetection() function. When the target is no longer required the target should be |
47 | deleted as other applications may be blocked from accessing the target. |
48 | */ |
49 | |
50 | /*! |
51 | \enum QNearFieldManager::AdapterState |
52 | |
53 | \since 5.12 |
54 | |
55 | This enum describes the different states a NFC adapter can have. |
56 | |
57 | \value Offline The nfc adapter is offline. |
58 | \value TurningOn The nfc adapter is turning on. |
59 | \value Online The nfc adapter is online. |
60 | \value TurningOff The nfc adapter is turning off. |
61 | */ |
62 | |
63 | /*! |
64 | \fn void QNearFieldManager::adapterStateChanged(AdapterState state) |
65 | |
66 | \since 5.12 |
67 | |
68 | This signal is emitted whenever the \a state of the NFC adapter changed. |
69 | |
70 | \note Currently, this signal is only emitted on Android. |
71 | */ |
72 | |
73 | /*! |
74 | \fn void QNearFieldManager::targetDetectionStopped() |
75 | |
76 | \since 6.2 |
77 | |
78 | This signal is emitted whenever the target detection is stopped. |
79 | |
80 | \note Mostly this signal is emitted when \l stopTargetDetection() has been called. |
81 | Additionally the user is able to stop the detection on iOS within a popup shown |
82 | by the system during the scan, which also leads to emitting this signal. |
83 | */ |
84 | |
85 | /*! |
86 | \fn void QNearFieldManager::targetDetected(QNearFieldTarget *target) |
87 | |
88 | This signal is emitted whenever a target is detected. The \a target parameter represents the |
89 | detected target. |
90 | |
91 | This signal will be emitted for all detected targets. |
92 | |
93 | QNearFieldManager maintains ownership of \a target, however, it will not be destroyed until |
94 | the QNearFieldManager destructor is called. Ownership may be transferred by calling |
95 | setParent(). |
96 | |
97 | Do not delete \a target from the slot connected to this signal, instead call deleteLater(). |
98 | |
99 | \note that if \a target is deleted before it moves out of proximity the targetLost() signal |
100 | will not be emitted. |
101 | |
102 | \sa targetLost() |
103 | */ |
104 | |
105 | /*! |
106 | \fn void QNearFieldManager::targetLost(QNearFieldTarget *target) |
107 | |
108 | This signal is emitted whenever a target moves out of proximity. The \a target parameter |
109 | represents the lost target. |
110 | |
111 | Do not delete \a target from the slot connected to this signal, instead use deleteLater(). |
112 | |
113 | \sa QNearFieldTarget::disconnected() |
114 | */ |
115 | |
116 | /*! |
117 | Constructs a new near field manager with \a parent. |
118 | */ |
119 | QNearFieldManager::QNearFieldManager(QObject *parent) |
120 | : QObject(parent), d_ptr(new QNearFieldManagerPrivateImpl) |
121 | { |
122 | qRegisterMetaType<AdapterState>(); |
123 | |
124 | connect(sender: d_ptr, signal: &QNearFieldManagerPrivate::adapterStateChanged, |
125 | context: this, slot: &QNearFieldManager::adapterStateChanged); |
126 | connect(sender: d_ptr, signal: &QNearFieldManagerPrivate::targetDetectionStopped, |
127 | context: this, slot: &QNearFieldManager::targetDetectionStopped); |
128 | connect(sender: d_ptr, signal: &QNearFieldManagerPrivate::targetDetected, |
129 | context: this, slot: &QNearFieldManager::targetDetected); |
130 | connect(sender: d_ptr, signal: &QNearFieldManagerPrivate::targetLost, |
131 | context: this, slot: &QNearFieldManager::targetLost); |
132 | } |
133 | |
134 | /*! |
135 | \internal |
136 | |
137 | Constructs a new near field manager with the specified \a backend and with \a parent. |
138 | |
139 | \note: This constructor is only enable for internal builds and is used for testing the |
140 | simulator backend. |
141 | */ |
142 | QNearFieldManager::QNearFieldManager(QNearFieldManagerPrivate *backend, QObject *parent) |
143 | : QObject(parent), d_ptr(backend) |
144 | { |
145 | qRegisterMetaType<AdapterState>(); |
146 | |
147 | connect(sender: d_ptr, signal: &QNearFieldManagerPrivate::adapterStateChanged, |
148 | context: this, slot: &QNearFieldManager::adapterStateChanged); |
149 | connect(sender: d_ptr, signal: &QNearFieldManagerPrivate::targetDetectionStopped, |
150 | context: this, slot: &QNearFieldManager::targetDetectionStopped); |
151 | connect(sender: d_ptr, signal: &QNearFieldManagerPrivate::targetDetected, |
152 | context: this, slot: &QNearFieldManager::targetDetected); |
153 | connect(sender: d_ptr, signal: &QNearFieldManagerPrivate::targetLost, |
154 | context: this, slot: &QNearFieldManager::targetLost); |
155 | } |
156 | |
157 | /*! |
158 | Destroys the near field manager. |
159 | */ |
160 | QNearFieldManager::~QNearFieldManager() |
161 | { |
162 | delete d_ptr; |
163 | } |
164 | |
165 | /*! |
166 | \since 6.2 |
167 | |
168 | Returns \c true if the device has a NFC adapter and |
169 | it is turned on; otherwise returns \c false. |
170 | |
171 | \sa isSupported() |
172 | */ |
173 | bool QNearFieldManager::isEnabled() const |
174 | { |
175 | Q_D(const QNearFieldManager); |
176 | |
177 | return d->isEnabled(); |
178 | } |
179 | |
180 | /*! |
181 | \since 5.12 |
182 | |
183 | Returns \c true if the underlying device has a NFC adapter; otherwise |
184 | returns \c false. If an \a accessMethod is given, the function returns |
185 | \c true only if the NFC adapter supports the given \a accessMethod. |
186 | |
187 | \sa isEnabled() |
188 | */ |
189 | bool QNearFieldManager::isSupported(QNearFieldTarget::AccessMethod accessMethod) const |
190 | { |
191 | Q_D(const QNearFieldManager); |
192 | |
193 | return d->isSupported(accessMethod); |
194 | } |
195 | |
196 | /*! |
197 | \fn bool QNearFieldManager::startTargetDetection(QNearFieldTarget::AccessMethod accessMethod) |
198 | |
199 | Starts detecting targets and returns \c true if target detection is |
200 | successfully started; otherwise returns \c false. Causes the targetDetected() signal to be emitted |
201 | when a target is within proximity. Only tags with the given \a accessMethod will be delivered. |
202 | Active detection continues until \l stopTargetDetection() has been called. |
203 | |
204 | To detect targets with a different \a accessMethod, stopTargetDetection() must be called first. |
205 | |
206 | \note On iOS it is impossible to start target detection for both NdefAccess and TagTypeSpecificAccess |
207 | at the same time. So if AnyAccess is selected, NdefAccess will be used instead. |
208 | |
209 | \sa stopTargetDetection() |
210 | */ |
211 | bool QNearFieldManager::startTargetDetection(QNearFieldTarget::AccessMethod accessMethod) |
212 | { |
213 | Q_D(QNearFieldManager); |
214 | |
215 | return d->startTargetDetection(accessMethod); |
216 | } |
217 | |
218 | /*! |
219 | Stops detecting targets. The \l targetDetected() signal will no longer be emitted until another |
220 | call to \l startTargetDetection() is made. Targets detected before are still valid. |
221 | |
222 | \note On iOS, detected targets become invalid after this call (e.g. an attempt to write or |
223 | read NDEF messages will result in an error). |
224 | |
225 | If an \a errorMessage is provided, this is a hint to the system that the goal, the application |
226 | had, was not reached. The \a errorMessage and a matching error icon are shown to the user. |
227 | Calling this function with an empty \a errorMessage, implies a successful operation end; |
228 | otherwise an \a errorMessage should be passed to this function. |
229 | |
230 | \note Currently, \a errorMessage only has an effect on iOS because a popup is shown by the |
231 | system during the scan where the \a errorMessage is visible. Other platforms will ignore this |
232 | parameter. |
233 | |
234 | \sa setUserInformation() |
235 | */ |
236 | void QNearFieldManager::stopTargetDetection(const QString &errorMessage) |
237 | { |
238 | Q_D(QNearFieldManager); |
239 | |
240 | d->stopTargetDetection(errorMessage); |
241 | } |
242 | |
243 | /*! |
244 | \since 6.2 |
245 | |
246 | Sets the message shown to the user by the system. If the target detection is running the |
247 | \a message will be updated immediately and can be used as a progress message. The last message |
248 | set before a call to \l startTargetDetection() without an error message is used as a success |
249 | message. If the target detection is not running the \a message will be used as the initial |
250 | message when the next detection is started. By default no message is shown to the user. |
251 | |
252 | \note Currently, this function only has an effect on iOS because a popup is shown by the system |
253 | during the scan. On iOS, this \a message is mapped to the alert message which is shown upon |
254 | successful completion of the scan. Other platforms will ignore \a message. |
255 | |
256 | \sa startTargetDetection(), stopTargetDetection() |
257 | */ |
258 | void QNearFieldManager::setUserInformation(const QString &message) |
259 | { |
260 | Q_D(QNearFieldManager); |
261 | |
262 | d->setUserInformation(message); |
263 | } |
264 | |
265 | QT_END_NAMESPACE |
266 | |
267 | #include "moc_qnearfieldmanager_p.cpp" |
268 | |
269 | #include "moc_qnearfieldmanager.cpp" |
270 | |