QNearFieldManager: extend tests
Extend the implementation of the manager emulator, and provide tests to cover the implementation. This patch also fixes the tst_qnearfieldtagtype* to prevent the crashes when the matching target is not found. Task-number: QTBUG-94037 Pick-to: 6.2 Change-Id: I32e5ed747a85d996e4f0f6f66b3321ddebfbdb26 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
This commit is contained in:
parent
ded6f0ad10
commit
661da19ebb
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtNfc module of the Qt Toolkit.
|
||||
|
@ -62,9 +62,31 @@ bool QNearFieldManagerPrivateImpl::isEnabled() const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool QNearFieldManagerPrivateImpl::startTargetDetection(QNearFieldTarget::AccessMethod)
|
||||
bool QNearFieldManagerPrivateImpl::isSupported(QNearFieldTarget::AccessMethod accessMethod) const
|
||||
{
|
||||
return true;
|
||||
return accessMethod == QNearFieldTarget::NdefAccess
|
||||
|| accessMethod == QNearFieldTarget::AnyAccess;
|
||||
}
|
||||
|
||||
bool QNearFieldManagerPrivateImpl::startTargetDetection(QNearFieldTarget::AccessMethod accessMethod)
|
||||
{
|
||||
const bool supported = isSupported(accessMethod);
|
||||
if (supported)
|
||||
TagActivator::instance()->start();
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
void QNearFieldManagerPrivateImpl::stopTargetDetection(const QString &message)
|
||||
{
|
||||
setUserInformation(message);
|
||||
TagActivator::instance()->stop();
|
||||
emit targetDetectionStopped();
|
||||
}
|
||||
|
||||
void QNearFieldManagerPrivateImpl::setUserInformation(const QString &message)
|
||||
{
|
||||
emit userInformationChanged(message);
|
||||
}
|
||||
|
||||
void QNearFieldManagerPrivateImpl::reset()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtNfc module of the Qt Toolkit.
|
||||
|
@ -72,10 +72,17 @@ public:
|
|||
|
||||
bool isEnabled() const override;
|
||||
|
||||
bool isSupported(QNearFieldTarget::AccessMethod accessMethod) const override;
|
||||
|
||||
bool startTargetDetection(QNearFieldTarget::AccessMethod accessMethod) override;
|
||||
void stopTargetDetection(const QString &message) override;
|
||||
void setUserInformation(const QString &message) override;
|
||||
|
||||
void reset();
|
||||
|
||||
signals:
|
||||
void userInformationChanged(const QString &message);
|
||||
|
||||
private slots:
|
||||
void tagActivated(TagBase *tag);
|
||||
void tagDeactivated(TagBase *tag);
|
||||
|
|
|
@ -184,9 +184,7 @@ bool TagType2::waitForRequestCompleted(const QNearFieldTarget::RequestId &id, in
|
|||
return QNearFieldTagType2::waitForRequestCompleted(id, msecs);
|
||||
}
|
||||
|
||||
|
||||
TagActivator::TagActivator()
|
||||
: timerId(-1)
|
||||
TagActivator::TagActivator() : QObject()
|
||||
{
|
||||
qRegisterMetaType<QNearFieldTarget::Error>();
|
||||
}
|
||||
|
@ -237,21 +235,38 @@ void TagActivator::initialize()
|
|||
}
|
||||
|
||||
current = tagMap.end();
|
||||
|
||||
timerId = startTimer(1000);
|
||||
}
|
||||
|
||||
void TagActivator::reset()
|
||||
{
|
||||
QMutexLocker locker(&tagMutex);
|
||||
|
||||
killTimer(timerId);
|
||||
timerId = -1;
|
||||
stopInternal();
|
||||
|
||||
qDeleteAll(tagMap.keys());
|
||||
tagMap.clear();
|
||||
}
|
||||
|
||||
void TagActivator::start()
|
||||
{
|
||||
QMutexLocker locker(&tagMutex);
|
||||
timerId = startTimer(1000);
|
||||
}
|
||||
|
||||
void TagActivator::stop()
|
||||
{
|
||||
QMutexLocker locker(&tagMutex);
|
||||
stopInternal();
|
||||
}
|
||||
|
||||
void TagActivator::stopInternal()
|
||||
{
|
||||
if (timerId != -1) {
|
||||
killTimer(timerId);
|
||||
timerId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
TagActivator *TagActivator::instance()
|
||||
{
|
||||
return globalTagActivator();
|
||||
|
|
|
@ -108,6 +108,9 @@ public:
|
|||
void initialize();
|
||||
void reset();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
static TagActivator *instance();
|
||||
|
||||
protected:
|
||||
|
@ -118,8 +121,10 @@ signals:
|
|||
void tagDeactivated(TagBase *tag);
|
||||
|
||||
private:
|
||||
void stopInternal();
|
||||
|
||||
QMap<TagBase *, bool>::Iterator current;
|
||||
int timerId;
|
||||
int timerId = -1;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtNfc module of the Qt Toolkit.
|
||||
|
@ -52,6 +52,11 @@ public:
|
|||
private slots:
|
||||
void initTestCase();
|
||||
|
||||
void isSupported();
|
||||
void isSupported_data();
|
||||
|
||||
void userInformation();
|
||||
|
||||
void targetDetected_data();
|
||||
void targetDetected();
|
||||
};
|
||||
|
@ -72,56 +77,105 @@ void tst_QNearFieldManager::initTestCase()
|
|||
QVERIFY(manager.isEnabled());
|
||||
}
|
||||
|
||||
void tst_QNearFieldManager::isSupported()
|
||||
{
|
||||
QFETCH(QNearFieldTarget::AccessMethod, accessMethod);
|
||||
QFETCH(bool, supported);
|
||||
|
||||
QNearFieldManagerPrivateImpl *emulatorBackend = new QNearFieldManagerPrivateImpl;
|
||||
QNearFieldManager manager(emulatorBackend, nullptr);
|
||||
|
||||
QCOMPARE(manager.isSupported(accessMethod), supported);
|
||||
}
|
||||
|
||||
void tst_QNearFieldManager::isSupported_data()
|
||||
{
|
||||
QTest::addColumn<QNearFieldTarget::AccessMethod>("accessMethod");
|
||||
QTest::addColumn<bool>("supported");
|
||||
|
||||
QTest::newRow("UnknownAccess") << QNearFieldTarget::UnknownAccess << false;
|
||||
QTest::newRow("NdefAccess") << QNearFieldTarget::NdefAccess << true;
|
||||
QTest::newRow("TagTypeSpecificAccess") << QNearFieldTarget::TagTypeSpecificAccess << false;
|
||||
QTest::newRow("AnyAccess") << QNearFieldTarget::AnyAccess << true;
|
||||
}
|
||||
|
||||
void tst_QNearFieldManager::userInformation()
|
||||
{
|
||||
QNearFieldManagerPrivateImpl *emulatorBackend = new QNearFieldManagerPrivateImpl;
|
||||
QNearFieldManager manager(emulatorBackend, nullptr);
|
||||
|
||||
QSignalSpy spy(emulatorBackend, &QNearFieldManagerPrivateImpl::userInformationChanged);
|
||||
|
||||
manager.startTargetDetection(QNearFieldTarget::AnyAccess);
|
||||
|
||||
const QString progressString("NFC target detection in progress");
|
||||
manager.setUserInformation(progressString);
|
||||
|
||||
const QString errorString("Failed to detect NFC targets");
|
||||
manager.stopTargetDetection(errorString);
|
||||
|
||||
QCOMPARE(spy.count(), 2);
|
||||
QCOMPARE(spy.at(0).at(0).toString(), progressString);
|
||||
QCOMPARE(spy.at(1).at(0).toString(), errorString);
|
||||
}
|
||||
|
||||
void tst_QNearFieldManager::targetDetected_data()
|
||||
{
|
||||
QTest::addColumn<QNearFieldTarget::AccessMethod>("accessMethod");
|
||||
QTest::addColumn<bool>("deleteTarget");
|
||||
|
||||
QTest::newRow("AnyTarget") << false;
|
||||
QTest::newRow("NfcTagType1") << false;
|
||||
QTest::newRow("Delete Target") << true;
|
||||
QTest::newRow("UnknownAccess") << QNearFieldTarget::UnknownAccess << false;
|
||||
QTest::newRow("NdefAccess, no delete") << QNearFieldTarget::NdefAccess << false;
|
||||
QTest::newRow("AnyAccess, delete") << QNearFieldTarget::AnyAccess << true;
|
||||
}
|
||||
|
||||
void tst_QNearFieldManager::targetDetected()
|
||||
{
|
||||
QFETCH(QNearFieldTarget::AccessMethod, accessMethod);
|
||||
QFETCH(bool, deleteTarget);
|
||||
|
||||
QNearFieldManagerPrivateImpl *emulatorBackend = new QNearFieldManagerPrivateImpl;
|
||||
QNearFieldManager manager(emulatorBackend, 0);
|
||||
QNearFieldManager manager(emulatorBackend, nullptr);
|
||||
|
||||
QSignalSpy targetDetectedSpy(&manager, SIGNAL(targetDetected(QNearFieldTarget*)));
|
||||
QSignalSpy targetLostSpy(&manager, SIGNAL(targetLost(QNearFieldTarget*)));
|
||||
QSignalSpy targetDetectedSpy(&manager, &QNearFieldManager::targetDetected);
|
||||
QSignalSpy targetLostSpy(&manager, &QNearFieldManager::targetLost);
|
||||
QSignalSpy detectionStoppedSpy(&manager, &QNearFieldManager::targetDetectionStopped);
|
||||
|
||||
manager.startTargetDetection(QNearFieldTarget::UnknownAccess);
|
||||
const bool started = manager.startTargetDetection(accessMethod);
|
||||
|
||||
QTRY_VERIFY(!targetDetectedSpy.isEmpty());
|
||||
if (started) {
|
||||
QTRY_VERIFY(!targetDetectedSpy.isEmpty());
|
||||
|
||||
QNearFieldTarget *target = targetDetectedSpy.first().at(0).value<QNearFieldTarget *>();
|
||||
QNearFieldTarget *target = targetDetectedSpy.first().at(0).value<QNearFieldTarget *>();
|
||||
|
||||
QSignalSpy disconnectedSpy(target, SIGNAL(disconnected()));
|
||||
QSignalSpy disconnectedSpy(target, SIGNAL(disconnected()));
|
||||
|
||||
QVERIFY(target);
|
||||
QVERIFY(target);
|
||||
|
||||
QVERIFY(!target->uid().isEmpty());
|
||||
QVERIFY(!target->uid().isEmpty());
|
||||
|
||||
if (!deleteTarget) {
|
||||
QTRY_VERIFY(!targetLostSpy.isEmpty());
|
||||
if (!deleteTarget) {
|
||||
QTRY_VERIFY(!targetLostSpy.isEmpty());
|
||||
|
||||
QNearFieldTarget *lostTarget = targetLostSpy.first().at(0).value<QNearFieldTarget *>();
|
||||
QNearFieldTarget *lostTarget = targetLostSpy.first().at(0).value<QNearFieldTarget *>();
|
||||
|
||||
QCOMPARE(target, lostTarget);
|
||||
QCOMPARE(target, lostTarget);
|
||||
|
||||
QVERIFY(!disconnectedSpy.isEmpty());
|
||||
} else {
|
||||
delete target;
|
||||
QVERIFY(!disconnectedSpy.isEmpty());
|
||||
} else {
|
||||
delete target;
|
||||
|
||||
// wait for another targetDetected() without a targetLost() signal in between.
|
||||
targetDetectedSpy.clear();
|
||||
targetLostSpy.clear();
|
||||
// wait for another targetDetected() without a targetLost() signal in between.
|
||||
targetDetectedSpy.clear();
|
||||
targetLostSpy.clear();
|
||||
|
||||
QTRY_VERIFY(targetLostSpy.isEmpty() && !targetDetectedSpy.isEmpty());
|
||||
QTRY_VERIFY(targetLostSpy.isEmpty() && !targetDetectedSpy.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
manager.stopTargetDetection();
|
||||
|
||||
QCOMPARE(detectionStoppedSpy.count(), 1);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QNearFieldManager)
|
||||
|
|
|
@ -76,6 +76,7 @@ void tst_QNearFieldTagType1::init()
|
|||
targetParent = new QObject();
|
||||
|
||||
TagActivator::instance()->initialize();
|
||||
TagActivator::instance()->start();
|
||||
}
|
||||
|
||||
void tst_QNearFieldTagType1::cleanup()
|
||||
|
@ -104,6 +105,8 @@ void tst_QNearFieldTagType1::waitForMatchingTarget()
|
|||
void tst_QNearFieldTagType1::staticMemoryModel()
|
||||
{
|
||||
waitForMatchingTarget();
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
|
||||
QVERIFY(target->accessMethods() & QNearFieldTarget::TagTypeSpecificAccess);
|
||||
|
||||
|
@ -239,6 +242,8 @@ void tst_QNearFieldTagType1::dynamicMemoryModel()
|
|||
QList<QByteArray> seenIds;
|
||||
forever {
|
||||
waitForMatchingTarget();
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
|
||||
QNearFieldTarget::RequestId id = target->readIdentification();
|
||||
QVERIFY(target->waitForRequestCompleted(id));
|
||||
|
@ -368,6 +373,8 @@ void tst_QNearFieldTagType1::ndefMessages()
|
|||
QByteArray firstId;
|
||||
forever {
|
||||
waitForMatchingTarget();
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
|
||||
QNearFieldTarget::RequestId id = target->readIdentification();
|
||||
QVERIFY(target->waitForRequestCompleted(id));
|
||||
|
|
|
@ -77,6 +77,7 @@ void tst_QNearFieldTagType2::init()
|
|||
targetParent = new QObject();
|
||||
|
||||
TagActivator::instance()->initialize();
|
||||
TagActivator::instance()->start();
|
||||
}
|
||||
|
||||
void tst_QNearFieldTagType2::cleanup()
|
||||
|
@ -105,6 +106,8 @@ void tst_QNearFieldTagType2::waitForMatchingTarget()
|
|||
void tst_QNearFieldTagType2::staticMemoryModel()
|
||||
{
|
||||
waitForMatchingTarget();
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
|
||||
QVERIFY(target->accessMethods() & QNearFieldTarget::TagTypeSpecificAccess);
|
||||
|
||||
|
@ -166,6 +169,8 @@ void tst_QNearFieldTagType2::dynamicMemoryModel()
|
|||
QList<QByteArray> seenIds;
|
||||
forever {
|
||||
waitForMatchingTarget();
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
|
||||
QVERIFY(target->accessMethods() & QNearFieldTarget::TagTypeSpecificAccess);
|
||||
|
||||
|
@ -267,6 +272,8 @@ void tst_QNearFieldTagType2::ndefMessages()
|
|||
QByteArray firstId;
|
||||
forever {
|
||||
waitForMatchingTarget();
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
|
||||
QNearFieldTarget::RequestId id = target->readBlock(0);
|
||||
QVERIFY(target->waitForRequestCompleted(id));
|
||||
|
|
Loading…
Reference in New Issue