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
22QT_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*/
119QNearFieldManager::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*/
142QNearFieldManager::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*/
160QNearFieldManager::~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*/
173bool 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*/
189bool 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*/
211bool 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*/
236void 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*/
258void QNearFieldManager::setUserInformation(const QString &message)
259{
260 Q_D(QNearFieldManager);
261
262 d->setUserInformation(message);
263}
264
265QT_END_NAMESPACE
266
267#include "moc_qnearfieldmanager_p.cpp"
268
269#include "moc_qnearfieldmanager.cpp"
270

source code of qtconnectivity/src/nfc/qnearfieldmanager.cpp