summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Greilich <j.greilich@gmx.de>2023-01-26 19:19:21 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-02-03 18:32:24 +0000
commit491597cfb4529a77c4bfa57542ad169e8ec07067 (patch)
tree7a489a10a171e066785406f3bc4b105b806639e0
parented01eae6433a4e3d72e8aff7b9ebc862a0df7d99 (diff)
iOS NFC: Always ensure timeout after session invalidation
iOS needs some time after invalidating a session before a new session can be started. Otherwise the NFC dialog of iOS will not show up. For restarting a session inside the iOS NearfieldManager, this was already solved with a timeout of 2 seconds. This commit fixes the case, that a user of the Nearfieldmanager restarts a session manually too fast. Change-Id: Ic91ad225a9cab13ba92523f33a19f44af68575a0 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> (cherry picked from commit 849ba86ba9a073a266219b6a39786e20f4f3ed7b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/nfc/qnearfieldmanager_ios.mm97
-rw-r--r--src/nfc/qnearfieldmanager_ios_p.h5
2 files changed, 61 insertions, 41 deletions
diff --git a/src/nfc/qnearfieldmanager_ios.mm b/src/nfc/qnearfieldmanager_ios.mm
index 3d3172db..fd9de125 100644
--- a/src/nfc/qnearfieldmanager_ios.mm
+++ b/src/nfc/qnearfieldmanager_ios.mm
@@ -46,6 +46,10 @@ QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl()
} else {
qCWarning(QT_IOS_NFC, "Failed to allocate NDEF reading session's delegate");
}
+
+ sessionTimer.setInterval(2000);
+ sessionTimer.setSingleShot(true);
+ connect(&sessionTimer, &QTimer::timeout, this, &QNearFieldManagerPrivateImpl::onSessionTimer);
}
QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
@@ -94,15 +98,16 @@ bool QNearFieldManagerPrivateImpl::startTargetDetection(QNearFieldTarget::Access
case QNearFieldTarget::TagTypeSpecificAccess:
if (@available(iOS 13, *))
if (NFCTagReaderSession.readingAvailable) {
- detectionRunning = true;
- startSession();
- activeAccessMethod = accessMethod;
- return true;
+ detectionRunning = scheduleSession(accessMethod);
+ if (detectionRunning)
+ activeAccessMethod = accessMethod;
+ return detectionRunning;
}
return false;
case QNearFieldTarget::NdefAccess:
if (NFCNDEFReaderSession.readingAvailable) {
- if (startNdefSession())
+ detectionRunning = scheduleSession(accessMethod);
+ if (detectionRunning)
activeAccessMethod = accessMethod;
return detectionRunning;
}
@@ -114,44 +119,60 @@ bool QNearFieldManagerPrivateImpl::startTargetDetection(QNearFieldTarget::Access
void QNearFieldManagerPrivateImpl::stopTargetDetection(const QString &errorMessage)
{
- if (detectionRunning) {
- if (activeAccessMethod == QNearFieldTarget::TagTypeSpecificAccess) {
- stopSession(errorMessage);
- } else if (activeAccessMethod == QNearFieldTarget::NdefAccess) {
- stopNdefSession(errorMessage);
- } else {
- qCWarning(QT_IOS_NFC, "Unknown access method, cannot stop target detection");
- return;
- }
+ if (!detectionRunning)
+ return;
+
+ isSessionScheduled = false;
- detectionRunning = false;
- Q_EMIT targetDetectionStopped();
+ if (activeAccessMethod == QNearFieldTarget::TagTypeSpecificAccess) {
+ stopSession(errorMessage);
+ } else if (activeAccessMethod == QNearFieldTarget::NdefAccess) {
+ stopNdefSession(errorMessage);
+ } else {
+ qCWarning(QT_IOS_NFC, "Unknown access method, cannot stop target detection");
+ return;
}
+
+ detectionRunning = false;
+ Q_EMIT targetDetectionStopped();
}
+bool QNearFieldManagerPrivateImpl::scheduleSession(QNearFieldTarget::AccessMethod accessMethod)
+{
+ if (sessionTimer.isActive()) {
+ isSessionScheduled = true;
+ return true;
+ }
+
+ if (accessMethod == QNearFieldTarget::TagTypeSpecificAccess) {
+ startSession();
+ return true;
+ } else if (accessMethod == QNearFieldTarget::NdefAccess) {
+ return startNdefSession();
+ }
+
+ return false;
+}
void QNearFieldManagerPrivateImpl::startSession()
{
- if (detectionRunning) {
- if (@available(iOS 13, *)) {
- [delegate startSession];
- }
+ if (@available(iOS 13, *)) {
+ [delegate startSession];
}
}
bool QNearFieldManagerPrivateImpl::startNdefSession()
{
if (!ndefDelegate)
- return detectionRunning = false;
+ return false;
if (auto queue = qt_Nfc_Queue()) {
- dispatch_sync(queue, ^{
- detectionRunning = [ndefDelegate startSession];
- });
- return detectionRunning;
+ __block bool startSessionSucceded = false;
+ dispatch_sync(queue, ^{ startSessionSucceded = [ndefDelegate startSession]; });
+ return startSessionSucceded;
}
- return detectionRunning = false;
+ return false;
}
void QNearFieldManagerPrivateImpl::stopSession(const QString &error)
@@ -235,25 +256,21 @@ void QNearFieldManagerPrivateImpl::onTargetLost(QNearFieldTargetPrivateImpl *tar
void QNearFieldManagerPrivateImpl::onDidInvalidateWithError(bool doRestart)
{
clearTargets();
+ sessionTimer.start();
- if (detectionRunning && doRestart)
- {
- if (!isRestarting) {
- isRestarting = true;
- using namespace std::chrono_literals;
- QTimer::singleShot(2s, this, [this](){
- isRestarting = false;
- if (activeAccessMethod == QNearFieldTarget::NdefAccess)
- startNdefSession();
- else
- startSession();
- });
- }
+ if (detectionRunning && doRestart && scheduleSession(activeAccessMethod))
return;
- }
detectionRunning = false;
Q_EMIT targetDetectionStopped();
}
+void QNearFieldManagerPrivateImpl::onSessionTimer()
+{
+ if (isSessionScheduled && !scheduleSession(activeAccessMethod)) {
+ detectionRunning = false;
+ Q_EMIT targetDetectionStopped();
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/nfc/qnearfieldmanager_ios_p.h b/src/nfc/qnearfieldmanager_ios_p.h
index 5b38b4fe..ef638ecb 100644
--- a/src/nfc/qnearfieldmanager_ios_p.h
+++ b/src/nfc/qnearfieldmanager_ios_p.h
@@ -59,10 +59,12 @@ private:
QT_MANGLE_NAMESPACE(QIosTagReaderDelegate) *delegate API_AVAILABLE(ios(13.0)) = nullptr;
QIosNfcNdefSessionDelegate *ndefDelegate = nullptr;
bool detectionRunning = false;
- bool isRestarting = false;
+ bool isSessionScheduled = false;
+ QTimer sessionTimer;
QList<QNearFieldTargetPrivateImpl *> detectedTargets;
QNearFieldTarget::AccessMethod activeAccessMethod = QNearFieldTarget::UnknownAccess;
+ bool scheduleSession(QNearFieldTarget::AccessMethod accessMethod);
void startSession();
bool startNdefSession();
void stopSession(const QString &error);
@@ -73,6 +75,7 @@ private Q_SLOTS:
void onTagDiscovered(void *target);
void onTargetLost(QNearFieldTargetPrivateImpl *target);
void onDidInvalidateWithError(bool doRestart);
+ void onSessionTimer();
};