summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@digia.com>2014-03-13 09:25:37 +0100
committerAlex Blasche <alexander.blasche@digia.com>2014-03-13 09:26:02 +0100
commit40ac14e13b0aa07124c6ae9ef8eacfe6d8550684 (patch)
treefeb2ac5da95042fb34d3a6ab57f7586e797f8dd4
parentc03d4f3472ee41c697332ccc95c7db358368b81d (diff)
parent61f2f050a750d286791e8848bcba2e990311ba29 (diff)
Merge branch 'stable' into dev
-rw-r--r--.gitignore8
-rw-r--r--examples/nfc/annotatedurl/annotatedurl.cpp17
-rw-r--r--examples/nfc/annotatedurl/main.cpp2
-rw-r--r--examples/nfc/ndefeditor/mainwindow.cpp14
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothBroadcastReceiver.java15
-rw-r--r--src/bluetooth/android/android.pri3
-rw-r--r--src/bluetooth/android/androidbroadcastreceiver.cpp13
-rw-r--r--src/bluetooth/android/androidbroadcastreceiver_p.h4
-rw-r--r--src/bluetooth/android/devicediscoverybroadcastreceiver.cpp29
-rw-r--r--src/bluetooth/android/jni_android.cpp112
-rw-r--r--src/bluetooth/android/jni_android_p.h75
-rw-r--r--src/bluetooth/android/localdevicebroadcastreceiver.cpp131
-rw-r--r--src/bluetooth/android/localdevicebroadcastreceiver_p.h3
-rw-r--r--src/bluetooth/android/servicediscoverybroadcastreceiver.cpp18
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp5
-rw-r--r--src/bluetooth/qbluetoothlocaldevice.cpp14
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_android.cpp1
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_android.cpp15
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp1
-rw-r--r--src/bluetooth/qbluetoothsocket_bluez.cpp3
-rw-r--r--src/bluetooth/qbluetoothsocket_p.cpp4
-rw-r--r--src/bluetooth/qbluetoothsocket_qnx.cpp3
-rw-r--r--src/bluetooth/qbluetoothuuid.cpp1
-rw-r--r--src/imports/nfc/qdeclarativenearfield.cpp9
-rw-r--r--src/nfc/doc/snippets/doc_src_qtnfc.cpp24
-rw-r--r--src/nfc/doc/snippets/doc_src_qtnfc.pro51
-rw-r--r--src/nfc/doc/snippets/doc_src_qtnfc.qml12
-rw-r--r--src/nfc/doc/snippets/snippets.pro13
-rw-r--r--src/nfc/doc/src/nfc-cpp.qdoc2
-rw-r--r--src/nfc/doc/src/nfc-index.qdoc4
-rw-r--r--src/nfc/doc/src/nfc-overview.qdoc115
-rw-r--r--src/nfc/qnearfieldmanager.cpp6
-rw-r--r--src/nfc/qnearfieldsharemanager.cpp1
-rw-r--r--src/nfc/qnearfieldsharetarget.cpp3
-rw-r--r--src/src.pro4
35 files changed, 549 insertions, 186 deletions
diff --git a/.gitignore b/.gitignore
index 7263c4fd..691e20fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,28 +28,32 @@ examples/bluetooth/btchat/btchat
examples/bluetooth/btfiletransfer/btfiletransfer
examples/bluetooth/btscanner/btscanner
examples/bluetooth/bttennis/bttennis
+examples/bluetooth/picturetransfer/qml_picturetransfer
examples/bluetooth/scanner/qml_scanner
examples/nfc/annotatedurl/annotatedurl
examples/nfc/ndefeditor/ndefeditor
examples/nfc/poster/qml_poster
examples/nfc/corkboard/qml_corkboard
+src/bluetooth/doc/snippets/bluetooth_cppsnippet
+src/nfc/doc/snippets/nfc_cppsnippet
tests/auto/cmake/build
tests/auto/qbluetoothaddress/tst_qbluetoothaddress
tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent
tests/auto/qbluetoothdeviceinfo/tst_qbluetoothdeviceinfo
tests/auto/qbluetoothhostinfo/tst_qbluetoothhostinfo
tests/auto/qbluetoothlocaldevice/tst_qbluetoothlocaldevice
+tests/auto/qbluetoothserver/tst_qbluetoothserver
tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent
tests/auto/qbluetoothserviceinfo/tst_qbluetoothserviceinfo
tests/auto/qbluetoothsocket/tst_qbluetoothsocket
tests/auto/qbluetoothtransfermanager/tst_qbluetoothtransfermanager
tests/auto/qbluetoothtransferrequest/tst_qbluetoothtransferrequest
tests/auto/qbluetoothuuid/tst_qbluetoothuuid
-tests/auto/ql2capserver/tst_ql2capserver
tests/auto/qndefmessage/tst_qndefmessage
+tests/auto/qndefnfcsmartposterrecord/tst_qndefnfcsmartposterrecord
tests/auto/qndefrecord/tst_qndefrecord
tests/auto/qnearfieldmanager/tst_qnearfieldmanager
tests/auto/qnearfieldtagtype1/tst_qnearfieldtagtype1
tests/auto/qnearfieldtagtype2/tst_qnearfieldtagtype2
-tests/auto/qrfcommserver/tst_qrfcommserver
+tests/bttestui/bttestui
tests/nfctestserver/nfctestserver
diff --git a/examples/nfc/annotatedurl/annotatedurl.cpp b/examples/nfc/annotatedurl/annotatedurl.cpp
index 293decf7..f29045b6 100644
--- a/examples/nfc/annotatedurl/annotatedurl.cpp
+++ b/examples/nfc/annotatedurl/annotatedurl.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNfc module.
@@ -63,8 +63,10 @@ AnnotatedUrl::~AnnotatedUrl()
{
}
+//! [handleMessage 1]
void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget *target)
{
+//! [handleMessage 1]
Q_UNUSED(target);
enum {
@@ -81,39 +83,40 @@ void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget *
QUrl url;
QPixmap pixmap;
+//! [handleMessage 2]
foreach (const QNdefRecord &record, message) {
if (record.isRecordType<QNdefNfcTextRecord>()) {
QNdefNfcTextRecord textRecord(record);
+ title = textRecord.text();
QLocale locale(textRecord.locale());
-
+//! [handleMessage 2]
// already found best match
if (bestMatch == MatchedLanguageAndCountry) {
// do nothing
} else if (bestMatch <= MatchedLanguage && locale == defaultLocale) {
- title = textRecord.text();
bestMatch = MatchedLanguageAndCountry;
} else if (bestMatch <= MatchedEnglish &&
locale.language() == defaultLocale.language()) {
- title = textRecord.text();
bestMatch = MatchedLanguage;
} else if (bestMatch <= MatchedFirst && locale.language() == QLocale::English) {
- title = textRecord.text();
bestMatch = MatchedEnglish;
} else if (bestMatch == MatchedNone) {
- title = textRecord.text();
bestMatch = MatchedFirst;
}
+//! [handleMessage 3]
} else if (record.isRecordType<QNdefNfcUriRecord>()) {
QNdefNfcUriRecord uriRecord(record);
url = uriRecord.uri();
+//! [handleMessage 3]
} else if (record.typeNameFormat() == QNdefRecord::Mime &&
record.type().startsWith("image/")) {
pixmap = QPixmap::fromImage(QImage::fromData(record.payload()));
+//! [handleMessage 4]
}
}
emit annotatedUrl(url, title, pixmap);
}
-
+//! [handleMessage 4]
diff --git a/examples/nfc/annotatedurl/main.cpp b/examples/nfc/annotatedurl/main.cpp
index c669e57b..351f33bf 100644
--- a/examples/nfc/annotatedurl/main.cpp
+++ b/examples/nfc/annotatedurl/main.cpp
@@ -57,6 +57,7 @@ int main(int argc, char *argv[])
QApplication a(argc, argv);
MainWindow mainWindow;
+ //! [QNearFieldManager register handler]
QNearFieldManager manager;
AnnotatedUrl annotatedUrl;
@@ -66,6 +67,7 @@ int main(int argc, char *argv[])
filter.appendRecord<QNdefNfcUriRecord>();
manager.registerNdefMessageHandler(filter, &annotatedUrl,
SLOT(handleMessage(QNdefMessage,QNearFieldTarget*)));
+ //! [QNearFieldManager register handler]
QObject::connect(&annotatedUrl, SIGNAL(annotatedUrl(QUrl,QString,QPixmap)),
&mainWindow, SLOT(displayAnnotatedUrl(QUrl,QString,QPixmap)));
diff --git a/examples/nfc/ndefeditor/mainwindow.cpp b/examples/nfc/ndefeditor/mainwindow.cpp
index df8f758c..fedb0866 100644
--- a/examples/nfc/ndefeditor/mainwindow.cpp
+++ b/examples/nfc/ndefeditor/mainwindow.cpp
@@ -120,8 +120,7 @@ void addRecord(Ui::MainWindow *ui, const QNdefRecord &record = QNdefRecord())
}
MainWindow::MainWindow(QWidget *parent)
-: QMainWindow(parent), ui(new Ui::MainWindow), m_manager(new QNearFieldManager(this)),
- m_touchAction(NoAction)
+: QMainWindow(parent), ui(new Ui::MainWindow), m_touchAction(NoAction)
{
ui->setupUi(this);
@@ -135,10 +134,13 @@ MainWindow::MainWindow(QWidget *parent)
QVBoxLayout *vbox = new QVBoxLayout;
ui->scrollAreaWidgetContents->setLayout(vbox);
+ //! [QNearFieldManager init]
+ m_manager = new QNearFieldManager(this);
connect(m_manager, SIGNAL(targetDetected(QNearFieldTarget*)),
this, SLOT(targetDetected(QNearFieldTarget*)));
connect(m_manager, SIGNAL(targetLost(QNearFieldTarget*)),
this, SLOT(targetLost(QNearFieldTarget*)));
+ //! [QNearFieldManager init]
}
MainWindow::~MainWindow()
@@ -205,7 +207,9 @@ void MainWindow::touchReceive()
m_touchAction = ReadNdef;
m_manager->setTargetAccessModes(QNearFieldManager::NdefReadTargetAccess);
+ //! [QNearFieldManager start detection]
m_manager->startTargetDetection();
+ //! [QNearFieldManager start detection]
}
void MainWindow::touchStore()
@@ -218,6 +222,7 @@ void MainWindow::touchStore()
m_manager->startTargetDetection();
}
+//! [QNearFieldTarget detected]
void MainWindow::targetDetected(QNearFieldTarget *target)
{
switch (m_touchAction) {
@@ -240,11 +245,14 @@ void MainWindow::targetDetected(QNearFieldTarget *target)
break;
}
}
+//! [QNearFieldTarget detected]
+//! [QNearFieldTarget lost]
void MainWindow::targetLost(QNearFieldTarget *target)
{
target->deleteLater();
}
+//! [QNearFieldTarget lost]
void MainWindow::ndefMessageRead(const QNdefMessage &message)
{
@@ -267,7 +275,9 @@ void MainWindow::ndefMessageRead(const QNdefMessage &message)
ui->status->setStyleSheet(QString());
m_manager->setTargetAccessModes(QNearFieldManager::NoTargetAccess);
+ //! [QNearFieldManager stop detection]
m_manager->stopTargetDetection();
+ //! [QNearFieldManager stop detection]
m_request = QNearFieldTarget::RequestId();
ui->statusBar->clearMessage();
}
diff --git a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothBroadcastReceiver.java b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothBroadcastReceiver.java
index 1f0049ef..ba96c0cf 100644
--- a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothBroadcastReceiver.java
+++ b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothBroadcastReceiver.java
@@ -62,7 +62,20 @@ public class QtBluetoothBroadcastReceiver extends BroadcastReceiver
public void onReceive(Context context, Intent intent)
{
- jniOnReceive(qtObject, context, intent);
+ synchronized (qtactivity) {
+ if (qtObject == 0)
+ return;
+
+ jniOnReceive(qtObject, context, intent);
+ }
+ }
+
+ public void unregisterReceiver()
+ {
+ synchronized (qtactivity) {
+ qtObject = 0;
+ qtactivity.unregisterReceiver(this);
+ }
}
public native void jniOnReceive(long qtObject, Context context, Intent intent);
diff --git a/src/bluetooth/android/android.pri b/src/bluetooth/android/android.pri
index 3c8a0380..0507894f 100644
--- a/src/bluetooth/android/android.pri
+++ b/src/bluetooth/android/android.pri
@@ -4,7 +4,8 @@ PRIVATE_HEADERS += \
android/servicediscoverybroadcastreceiver_p.h \
android/androidbroadcastreceiver_p.h \
android/localdevicebroadcastreceiver_p.h \
- android/serveracceptancethread_p.h
+ android/serveracceptancethread_p.h \
+ android/jni_android_p.h
SOURCES += \
diff --git a/src/bluetooth/android/androidbroadcastreceiver.cpp b/src/bluetooth/android/androidbroadcastreceiver.cpp
index affa7683..c17502ba 100644
--- a/src/bluetooth/android/androidbroadcastreceiver.cpp
+++ b/src/bluetooth/android/androidbroadcastreceiver.cpp
@@ -72,7 +72,6 @@ AndroidBroadcastReceiver::AndroidBroadcastReceiver(QObject* parent)
AndroidBroadcastReceiver::~AndroidBroadcastReceiver()
{
- unregisterReceiver();
}
bool AndroidBroadcastReceiver::isValid() const
@@ -85,19 +84,15 @@ void AndroidBroadcastReceiver::unregisterReceiver()
if (!valid)
return;
- activityObject.callObjectMethod(
- "unregisterReceiver",
- "(Landroid/content/BroadcastReceiver;)V",
- broadcastReceiverObject.object<jobject>());
+ broadcastReceiverObject.callMethod<void>("unregisterReceiver");
}
-void AndroidBroadcastReceiver::addAction(const QString &action)
+void AndroidBroadcastReceiver::addAction(const QAndroidJniObject &action)
{
- if (!valid)
+ if (!valid || !action.isValid())
return;
- QAndroidJniObject actionString = QAndroidJniObject::fromString(action);
- intentFilterObject.callMethod<void>("addAction", "(Ljava/lang/String;)V", actionString.object<jstring>());
+ intentFilterObject.callMethod<void>("addAction", "(Ljava/lang/String;)V", action.object<jstring>());
activityObject.callObjectMethod(
"registerReceiver",
diff --git a/src/bluetooth/android/androidbroadcastreceiver_p.h b/src/bluetooth/android/androidbroadcastreceiver_p.h
index baae6798..58c2b40b 100644
--- a/src/bluetooth/android/androidbroadcastreceiver_p.h
+++ b/src/bluetooth/android/androidbroadcastreceiver_p.h
@@ -58,14 +58,14 @@ public:
AndroidBroadcastReceiver(QObject* parent = 0);
virtual ~AndroidBroadcastReceiver();
- void addAction(const QString &filter);
+ void addAction(const QAndroidJniObject &filter);
bool isValid() const;
+ void unregisterReceiver();
protected:
friend void QtBroadcastReceiver_jniOnReceive(JNIEnv *, jobject, jlong, jobject, jobject);
virtual void onReceive(JNIEnv *env, jobject context, jobject intent) = 0;
- void unregisterReceiver();
QAndroidJniObject activityObject;
QAndroidJniObject intentFilterObject;
diff --git a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
index 16a6afe4..ca62f013 100644
--- a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
+++ b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
@@ -44,6 +44,7 @@
#include <QtCore/QLoggingCategory>
#include <QtBluetooth/QBluetoothAddress>
#include <QtBluetooth/QBluetoothDeviceInfo>
+#include "android/jni_android_p.h"
QT_BEGIN_NAMESPACE
@@ -51,9 +52,9 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
DeviceDiscoveryBroadcastReceiver::DeviceDiscoveryBroadcastReceiver(QObject* parent): AndroidBroadcastReceiver(parent)
{
- addAction(QStringLiteral("android.bluetooth.device.action.FOUND"));
- addAction(QStringLiteral("android.bluetooth.adapter.action.DISCOVERY_STARTED"));
- addAction(QStringLiteral("android.bluetooth.adapter.action.DISCOVERY_FINISHED"));
+ addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionFound));
+ addAction(valueForStaticField(JavaNames::BluetoothAdapter, JavaNames::ActionDiscoveryStarted));
+ addAction(valueForStaticField(JavaNames::BluetoothAdapter, JavaNames::ActionDiscoveryFinished));
}
void DeviceDiscoveryBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobject intent)
@@ -66,15 +67,18 @@ void DeviceDiscoveryBroadcastReceiver::onReceive(JNIEnv *env, jobject context, j
qCDebug(QT_BT_ANDROID) << "DeviceDiscoveryBroadcastReceiver::onReceive() - event:" << action;
- if (action == QStringLiteral("android.bluetooth.adapter.action.DISCOVERY_FINISHED") ) {
+ if (action == valueForStaticField(JavaNames::BluetoothAdapter,
+ JavaNames::ActionDiscoveryFinished).toString()) {
emit finished();
- } else if (action == QStringLiteral("android.bluetooth.adapter.action.DISCOVERY_STARTED") ) {
+ } else if (action == valueForStaticField(JavaNames::BluetoothAdapter,
+ JavaNames::ActionDiscoveryStarted).toString()) {
- } else if (action == QStringLiteral("android.bluetooth.device.action.FOUND")) {
+ } else if (action == valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ActionFound).toString()) {
//get BluetoothDevice
- QAndroidJniObject keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.DEVICE"));
- QAndroidJniObject bluetoothDevice =
+ QAndroidJniObject keyExtra = valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ExtraDevice);
+ const QAndroidJniObject bluetoothDevice =
intentObject.callObjectMethod("getParcelableExtra",
"(Ljava/lang/String;)Landroid/os/Parcelable;",
keyExtra.object<jstring>());
@@ -84,13 +88,14 @@ void DeviceDiscoveryBroadcastReceiver::onReceive(JNIEnv *env, jobject context, j
const QString deviceName = bluetoothDevice.callObjectMethod<jstring>("getName").toString();
const QBluetoothAddress deviceAddress(bluetoothDevice.callObjectMethod<jstring>("getAddress").toString());
- keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.RSSI"));
+ keyExtra = valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ExtraRssi);
+
int rssi = intentObject.callMethod<jshort>("getShortExtra",
"(Ljava/lang/String;S)S",
keyExtra.object<jstring>(),
0);
- QAndroidJniObject bluetoothClass = bluetoothDevice.callObjectMethod("getBluetoothClass",
+ const QAndroidJniObject bluetoothClass = bluetoothDevice.callObjectMethod("getBluetoothClass",
"()Landroid/bluetooth/BluetoothClass;");
if (!bluetoothClass.isValid())
return;
diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp
index 1e907fdd..ebc46a7c 100644
--- a/src/bluetooth/android/jni_android.cpp
+++ b/src/bluetooth/android/jni_android.cpp
@@ -44,13 +44,123 @@
#include <android/log.h>
#include <QtCore/QLoggingCategory>
#include <QtBluetooth/qbluetoothglobal.h>
-#include <QtAndroidExtras/QAndroidJniObject>
+#include "android/jni_android_p.h"
#include "android/androidbroadcastreceiver_p.h"
#include "android/serveracceptancethread_p.h"
#include "android/inputstreamthread_p.h"
Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
+typedef QHash<QByteArray, QAndroidJniObject> JCachedStringFields;
+Q_GLOBAL_STATIC(JCachedStringFields, cachedStringFields)
+
+//Java class names
+static const char * const javaBluetoothAdapterClassName = "android/bluetooth/BluetoothAdapter";
+static const char * const javaBluetoothDeviceClassName = "android/bluetooth/BluetoothDevice" ;
+
+//Java field names
+static const char * const javaActionAclConnected = "ACTION_ACL_CONNECTED";
+static const char * const javaActionAclDisconnected = "ACTION_ACL_DISCONNECTED";
+static const char * const javaActionBondStateChanged = "ACTION_BOND_STATE_CHANGED";
+static const char * const javaActionDiscoveryStarted = "ACTION_DISCOVERY_STARTED";
+static const char * const javaActionDiscoveryFinished = "ACTION_DISCOVERY_FINISHED";
+static const char * const javaActionFound = "ACTION_FOUND";
+static const char * const javaActionPairingRequest = "ACTION_PAIRING_REQUEST";
+static const char * const javaActionScanModeChanged = "ACTION_SCAN_MODE_CHANGED";
+static const char * const javaActionUuid = "ACTION_UUID";
+static const char * const javaExtraBondState = "EXTRA_BOND_STATE";
+static const char * const javaExtraDevice = "EXTRA_DEVICE";
+static const char * const javaExtraPairingKey = "EXTRA_PAIRING_KEY";
+static const char * const javaExtraPairingVariant = "EXTRA_PAIRING_VARIANT";
+static const char * const javaExtraRssi = "EXTRA_RSSI";
+static const char * const javaExtraScanMode = "EXTRA_SCAN_MODE";
+static const char * const javaExtraUuid = "EXTRA_UUID";
+
+/*
+ * This function operates on the assumption that each
+ * field is of type java/lang/String.
+ */
+QAndroidJniObject valueForStaticField(JavaNames javaName, JavaNames javaFieldName)
+{
+ //construct key
+ //the switch statements are used to reduce the number of duplicated strings
+ //in the library
+
+ const char* className;
+ switch (javaName) {
+ case JavaNames::BluetoothAdapter:
+ className = javaBluetoothAdapterClassName; break;
+ case JavaNames::BluetoothDevice:
+ className = javaBluetoothDeviceClassName; break;
+ default:
+ qWarning(QT_BT_ANDROID) << "Unknown java class name passed to valueForStaticField():" << javaName;
+ return QAndroidJniObject();
+ }
+
+ const char *fieldName;
+ switch (javaFieldName) {
+ case JavaNames::ActionAclConnected:
+ fieldName = javaActionAclConnected; break;
+ case JavaNames::ActionAclDisconnected:
+ fieldName = javaActionAclDisconnected; break;
+ case JavaNames::ActionBondStateChanged:
+ fieldName = javaActionBondStateChanged; break;
+ case JavaNames::ActionDiscoveryStarted:
+ fieldName = javaActionDiscoveryStarted; break;
+ case JavaNames::ActionDiscoveryFinished:
+ fieldName = javaActionDiscoveryFinished; break;
+ case JavaNames::ActionFound:
+ fieldName = javaActionFound; break;
+ case JavaNames::ActionPairingRequest:
+ fieldName = javaActionPairingRequest; break;
+ case JavaNames::ActionScanModeChanged:
+ fieldName = javaActionScanModeChanged; break;
+ case JavaNames::ActionUuid:
+ fieldName = javaActionUuid; break;
+ case JavaNames::ExtraBondState:
+ fieldName = javaExtraBondState; break;
+ case JavaNames::ExtraDevice:
+ fieldName = javaExtraDevice; break;
+ case JavaNames::ExtraPairingKey:
+ fieldName = javaExtraPairingKey; break;
+ case JavaNames::ExtraPairingVariant:
+ fieldName = javaExtraPairingVariant; break;
+ case JavaNames::ExtraRssi:
+ fieldName = javaExtraRssi; break;
+ case JavaNames::ExtraScanMode:
+ fieldName = javaExtraScanMode; break;
+ case JavaNames::ExtraUuid:
+ fieldName = javaExtraUuid; break;
+ default:
+ qWarning(QT_BT_ANDROID) << "Unknown java field name passed to valueForStaticField():" << javaFieldName;
+ return QAndroidJniObject();
+ }
+
+ int offset_class = qstrlen(className);
+ int offset_field = qstrlen(fieldName);
+ QByteArray key(offset_class + offset_field, Qt::Uninitialized);
+ memcpy(key.data(), className, offset_class);
+ memcpy(key.data()+offset_class, fieldName, offset_field);
+
+ JCachedStringFields::iterator it = cachedStringFields()->find(key);
+ if (it == cachedStringFields()->end()) {
+ QAndroidJniEnvironment env;
+ QAndroidJniObject fieldValue = QAndroidJniObject::getStaticObjectField(
+ className, fieldName, "Ljava/lang/String;");
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ cachedStringFields()->insert(key, QAndroidJniObject());
+ return QAndroidJniObject();
+ }
+
+ cachedStringFields()->insert(key, fieldValue);
+ return fieldValue;
+ } else {
+ return it.value();
+ }
+}
+
void QtBroadcastReceiver_jniOnReceive(JNIEnv *env, jobject /*javaObject*/,
jlong qtObject, jobject context, jobject intent)
{
diff --git a/src/bluetooth/android/jni_android_p.h b/src/bluetooth/android/jni_android_p.h
new file mode 100644
index 00000000..9cddd2f9
--- /dev/null
+++ b/src/bluetooth/android/jni_android_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JNI_ANDROID_P_H
+#define JNI_ANDROID_P_H
+
+#include <QtAndroidExtras/QAndroidJniEnvironment>
+#include <QtAndroidExtras/QAndroidJniObject>
+
+QT_BEGIN_NAMESPACE
+
+enum JavaNames {
+ BluetoothAdapter = 0,
+ BluetoothDevice,
+ ActionAclConnected,
+ ActionAclDisconnected,
+ ActionBondStateChanged,
+ ActionDiscoveryStarted,
+ ActionDiscoveryFinished,
+ ActionFound,
+ ActionPairingRequest,
+ ActionScanModeChanged,
+ ActionUuid,
+ ExtraBondState,
+ ExtraDevice,
+ ExtraPairingKey,
+ ExtraPairingVariant,
+ ExtraRssi,
+ ExtraScanMode,
+ ExtraUuid
+};
+
+QAndroidJniObject valueForStaticField(JavaNames javaName, JavaNames javaFieldName);
+
+QT_END_NAMESPACE
+
+#endif // JNI_ANDROID_P_H
diff --git a/src/bluetooth/android/localdevicebroadcastreceiver.cpp b/src/bluetooth/android/localdevicebroadcastreceiver.cpp
index 0e81ef22..5b7e4a38 100644
--- a/src/bluetooth/android/localdevicebroadcastreceiver.cpp
+++ b/src/bluetooth/android/localdevicebroadcastreceiver.cpp
@@ -40,21 +40,51 @@
****************************************************************************/
#include <QtCore/QLoggingCategory>
+#include <QtCore/private/qjnihelpers_p.h>
#include "localdevicebroadcastreceiver_p.h"
+#include "android/jni_android_p.h"
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
+const char *scanModes[] = {"SCAN_MODE_NONE", "SCAN_MODE_CONNECTABLE", "SCAN_MODE_CONNECTABLE_DISCOVERABLE"};
+const char *bondModes[] = {"BOND_NONE", "BOND_BONDING", "BOND_BONDED"};
+
LocalDeviceBroadcastReceiver::LocalDeviceBroadcastReceiver(QObject *parent) :
AndroidBroadcastReceiver(parent), previousScanMode(0)
{
- addAction(QStringLiteral("android.bluetooth.device.action.BOND_STATE_CHANGED"));
- addAction(QStringLiteral("android.bluetooth.adapter.action.SCAN_MODE_CHANGED"));
- addAction(QStringLiteral("android.bluetooth.device.action.ACL_CONNECTED"));
- addAction(QStringLiteral("android.bluetooth.device.action.ACL_DISCONNECTED"));
- addAction(QStringLiteral("android.bluetooth.device.action.PAIRING_REQUEST")); //API 19
+ addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionBondStateChanged));
+ addAction(valueForStaticField(JavaNames::BluetoothAdapter, JavaNames::ActionScanModeChanged));
+ addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionAclConnected));
+ addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionAclDisconnected));
+ if (QtAndroidPrivate::androidSdkVersion() >= 19)
+ addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionPairingRequest)); //API 19
+
+ //cache integer values for host & bonding mode
+ //don't use the java fields directly but refer to them by name
+ QAndroidJniEnvironment env;
+ for (uint i = 0; i < (sizeof(hostModePreset)/sizeof(hostModePreset[0])); i++) {
+ hostModePreset[i] = QAndroidJniObject::getStaticField<jint>(
+ "android/bluetooth/BluetoothAdapter",
+ scanModes[i]);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ hostModePreset[i] = 0;
+ }
+ }
+ for (uint i = 0; i < (sizeof(bondingModePreset)/sizeof(bondingModePreset[0])); i++) {
+ bondingModePreset[i] = QAndroidJniObject::getStaticField<jint>(
+ "android/bluetooth/BluetoothDevice",
+ bondModes[i]);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ bondingModePreset[i] = 0;
+ }
+ }
}
void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobject intent)
@@ -66,11 +96,13 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje
const QString action = intentObject.callObjectMethod("getAction", "()Ljava/lang/String;").toString();
qCDebug(QT_BT_ANDROID) << QStringLiteral("LocalDeviceBroadcastReceiver::onReceive() - event: %1").arg(action);
- if (action == QStringLiteral("android.bluetooth.adapter.action.SCAN_MODE_CHANGED")) {
- QAndroidJniObject extrasBundle =
+ if (action == valueForStaticField(JavaNames::BluetoothAdapter,
+ JavaNames::ActionScanModeChanged).toString()) {
+
+ const QAndroidJniObject extrasBundle =
intentObject.callObjectMethod("getExtras","()Landroid/os/Bundle;");
- QAndroidJniObject keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.adapter.extra.SCAN_MODE"));
+ const QAndroidJniObject keyExtra = valueForStaticField(JavaNames::BluetoothAdapter,
+ JavaNames::ExtraScanMode);
int extra = extrasBundle.callMethod<jint>("getInt",
"(Ljava/lang/String;)I",
@@ -79,34 +111,28 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje
if (previousScanMode != extra) {
previousScanMode = extra;
- switch (extra) {
- case 20: //BluetoothAdapter.SCAN_MODE_NONE
- emit hostModeStateChanged(QBluetoothLocalDevice::HostPoweredOff);
- break;
- case 21: //BluetoothAdapter.SCAN_MODE_CONNECTABLE
- emit hostModeStateChanged(QBluetoothLocalDevice::HostConnectable);
- break;
- case 23: //BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE
- emit hostModeStateChanged(QBluetoothLocalDevice::HostDiscoverable);
- break;
- default:
- qCWarning(QT_BT_ANDROID) << "Unknown Host State";
- break;
- }
+ if (extra == hostModePreset[0])
+ emit hostModeStateChanged(QBluetoothLocalDevice::HostPoweredOff);
+ else if (extra == hostModePreset[1])
+ emit hostModeStateChanged(QBluetoothLocalDevice::HostConnectable);
+ else if (extra == hostModePreset[2])
+ emit hostModeStateChanged(QBluetoothLocalDevice::HostDiscoverable);
+ else
+ qCWarning(QT_BT_ANDROID) << "Unknown Host State";
}
- } else if (action == QStringLiteral("android.bluetooth.device.action.BOND_STATE_CHANGED")) {
+ } else if (action == valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ActionBondStateChanged).toString()) {
//get BluetoothDevice
- QAndroidJniObject keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.DEVICE"));
- QAndroidJniObject bluetoothDevice =
+ QAndroidJniObject keyExtra = valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ExtraDevice);
+ const QAndroidJniObject bluetoothDevice =
intentObject.callObjectMethod("getParcelableExtra",
"(Ljava/lang/String;)Landroid/os/Parcelable;",
keyExtra.object<jstring>());
//get new bond state
- keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.BOND_STATE"));
- QAndroidJniObject extrasBundle =
+ keyExtra = valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ExtraBondState);
+ const QAndroidJniObject extrasBundle =
intentObject.callObjectMethod("getExtras","()Landroid/os/Bundle;");
int bondState = extrasBundle.callMethod<jint>("getInt",
"(Ljava/lang/String;)I",
@@ -116,29 +142,28 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje
if (address.isNull())
return;
- switch (bondState) {
- case 10: //BluetoothDevice.BOND_NONE
+ if (bondState == bondingModePreset[0])
emit pairingStateChanged(address, QBluetoothLocalDevice::Unpaired);
- break;
- case 11: //BluetoothDevice.BOND_BONDING
- //we ignore this as Qt doesn't have equivalent API.
- break;
- case 12: //BluetoothDevice.BOND_BONDED
+ else if (bondState == bondingModePreset[1])
+ ; //we ignore this as Qt doesn't have equivalent API value
+ else if (bondState == bondingModePreset[2])
emit pairingStateChanged(address, QBluetoothLocalDevice::Paired);
- break;
- default:
+ else
qCWarning(QT_BT_ANDROID) << "Unknown BOND_STATE_CHANGED value:" << bondState;
- break;
- }
- } else if (action == QStringLiteral("android.bluetooth.device.action.ACL_DISCONNECTED") ||
- action == QStringLiteral("android.bluetooth.device.action.ACL_CONNECTED")) {
+ } else if (action == valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ActionAclConnected).toString() ||
+ action == valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ActionAclDisconnected).toString()) {
+
+ const QString connectEvent = valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ActionAclConnected).toString();
const bool isConnectEvent =
- action == QStringLiteral("android.bluetooth.device.action.ACL_CONNECTED") ? true : false;
+ action == connectEvent ? true : false;
//get BluetoothDevice
- QAndroidJniObject keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.DEVICE"));
+ const QAndroidJniObject keyExtra = valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ExtraDevice);
QAndroidJniObject bluetoothDevice =
intentObject.callObjectMethod("getParcelableExtra",
"(Ljava/lang/String;)Landroid/os/Parcelable;",
@@ -149,10 +174,11 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje
return;
emit connectDeviceChanges(address, isConnectEvent);
- } else if (action == QStringLiteral("android.bluetooth.device.action.PAIRING_REQUEST")) {
+ } else if (action == valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ActionPairingRequest).toString()) {
- QAndroidJniObject keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.PAIRING_VARIANT"));
+ QAndroidJniObject keyExtra = valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ExtraPairingVariant);
int variant = intentObject.callMethod<jint>("getIntExtra",
"(Ljava/lang/String;I)I",
keyExtra.object<jstring>(),
@@ -164,8 +190,8 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje
return;
case 2: //BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION
{
- keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.PAIRING_KEY"));
+ keyExtra = valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ExtraPairingKey);
key = intentObject.callMethod<jint>("getIntExtra",
"(Ljava/lang/String;I)I",
keyExtra.object<jstring>(),
@@ -173,8 +199,7 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje
if (key == -1)
return;
- keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.DEVICE"));
+ keyExtra = valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ExtraDevice);
QAndroidJniObject bluetoothDevice =
intentObject.callObjectMethod("getParcelableExtra",
"(Ljava/lang/String;)Landroid/os/Parcelable;",
diff --git a/src/bluetooth/android/localdevicebroadcastreceiver_p.h b/src/bluetooth/android/localdevicebroadcastreceiver_p.h
index ddd65d92..4059b3bb 100644
--- a/src/bluetooth/android/localdevicebroadcastreceiver_p.h
+++ b/src/bluetooth/android/localdevicebroadcastreceiver_p.h
@@ -65,6 +65,9 @@ signals:
private:
int previousScanMode;
QAndroidJniObject pairingDevice;
+
+ int bondingModePreset[3];
+ int hostModePreset[3];
};
QT_END_NAMESPACE
diff --git a/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp b/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp
index 341617bc..0a3f97f9 100644
--- a/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp
+++ b/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp
@@ -41,9 +41,11 @@
#include "android/servicediscoverybroadcastreceiver_p.h"
#include <QtCore/QLoggingCategory>
+#include <QtCore/private/qjnihelpers_p.h>
#include <QtAndroidExtras/QAndroidJniEnvironment>
#include <QtBluetooth/QBluetoothAddress>
#include <QtBluetooth/QBluetoothDeviceInfo>
+#include "android/jni_android_p.h"
QT_BEGIN_NAMESPACE
@@ -51,7 +53,8 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
ServiceDiscoveryBroadcastReceiver::ServiceDiscoveryBroadcastReceiver(QObject* parent): AndroidBroadcastReceiver(parent)
{
- addAction(QStringLiteral("android.bluetooth.device.action.UUID"));
+ if (QtAndroidPrivate::androidSdkVersion() >= 15)
+ addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionUuid)); //API 15+
}
void ServiceDiscoveryBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobject intent)
@@ -64,19 +67,20 @@ void ServiceDiscoveryBroadcastReceiver::onReceive(JNIEnv *env, jobject context,
qCDebug(QT_BT_ANDROID) << "ServiceDiscoveryBroadcastReceiver::onReceive() - event:" << action;
- if (action == QStringLiteral("android.bluetooth.device.action.UUID")) {
- QAndroidJniObject keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.UUID"));
+ if (action == valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ActionUuid).toString()) {
+
+ QAndroidJniObject keyExtra = valueForStaticField(JavaNames::BluetoothDevice,
+ JavaNames::ExtraUuid);
QAndroidJniObject parcelableUuids = intentObject.callObjectMethod(
"getParcelableArrayExtra",
"(Ljava/lang/String;)[Landroid/os/Parcelable;",
keyExtra.object<jstring>());
if (!parcelableUuids.isValid())
return;
- QList<QBluetoothUuid> result = ServiceDiscoveryBroadcastReceiver::convertParcelableArray(parcelableUuids);
+ const QList<QBluetoothUuid> result = ServiceDiscoveryBroadcastReceiver::convertParcelableArray(parcelableUuids);
- keyExtra = QAndroidJniObject::fromString(
- QStringLiteral("android.bluetooth.device.extra.DEVICE"));
+ keyExtra = valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ExtraDevice);
QAndroidJniObject bluetoothDevice =
intentObject.callObjectMethod("getParcelableExtra",
"(Ljava/lang/String;)Landroid/os/Parcelable;",
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
index 320e0fb7..4f8ecdff 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
@@ -70,7 +70,10 @@ QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate()
if (m_active)
stop();
- delete receiver;
+ if (receiver) {
+ receiver->unregisterReceiver();
+ delete receiver;
+ }
}
bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const
diff --git a/src/bluetooth/qbluetoothlocaldevice.cpp b/src/bluetooth/qbluetoothlocaldevice.cpp
index e299ab71..14140846 100644
--- a/src/bluetooth/qbluetoothlocaldevice.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice.cpp
@@ -139,9 +139,11 @@ bool QBluetoothLocalDevice::isValid() const
\fn void QBluetoothLocalDevice::setHostMode(QBluetoothLocalDevice::HostMode mode)
Sets the host mode of this local Bluetooth device to \a mode.
- NOTE: Due to security policies of platforms, this method may behave different on different platforms. For example
- the system can ask the user for confirmation before turning Bluetooth on or off. Not all host modes may be
- supported on all platforms. Please refer to the platform specific Bluetooth documentation for details.
+
+ \note Due to varying security policies on the supported platforms, this method may have
+ differing behaviors on the various platforms. For example the system may ask the user for
+ confirmation before turning Bluetooth on or off and not all host modes may be supported.
+ Please refer to the platform specific Bluetooth documentation for details.
*/
/*!
@@ -172,8 +174,10 @@ bool QBluetoothLocalDevice::isValid() const
\fn QBluetoothLocalDevice::powerOn()
Powers on the device after returning it to the hostMode() state, if it was powered off.
- NOTE: Due to security policies of platforms, this method may behave different on different platforms. For example
- the system can ask the user for confirmation before turning Bluetooth on or off.
+
+ \note Due to varying security policies on the supported platforms, this method may have
+ differing behaviors on the various platforms. For example
+ the system may ask the user for confirmation before turning Bluetooth on or off.
Please refer to the platform specific Bluetooth documentation for details.
*/
diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp
index 4e441bc2..ff36837b 100644
--- a/src/bluetooth/qbluetoothlocaldevice_android.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp
@@ -74,6 +74,7 @@ QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate(
QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate()
{
+ receiver->unregisterReceiver();
delete receiver;
delete obj;
}
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
index e0e17c14..2e55d40e 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
@@ -98,8 +98,14 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
QBluetoothServiceDiscoveryAgentPrivate::~QBluetoothServiceDiscoveryAgentPrivate()
{
- delete receiver;
- delete localDeviceReceiver;
+ if (receiver) {
+ receiver->unregisterReceiver();
+ delete receiver;
+ }
+ if (localDeviceReceiver) {
+ localDeviceReceiver->unregisterReceiver();
+ delete localDeviceReceiver;
+ }
}
void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &address)
@@ -209,6 +215,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr
jboolean result = remoteDevice.callMethod<jboolean>("fetchUuidsWithSdp");
if (!result) {
//kill receiver to limit load of signals
+ receiver->unregisterReceiver();
receiver->deleteLater();
receiver = 0;
qCWarning(QT_BT_ANDROID) << "Cannot start dynamic fetch.";
@@ -223,6 +230,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::stop()
discoveredDevices.clear();
//kill receiver to limit load of signals
+ receiver->unregisterReceiver();
receiver->deleteLater();
receiver = 0;
@@ -435,7 +443,6 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Serial Port Profile"));
- //TODO Remove line below - work around
serviceInfo.setServiceUuid(uuids.at(i));
} else if (customUuids.contains(i)) {
//custom uuid but no serial port
@@ -493,6 +500,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_fetchUuidsTimeout()
Q_ASSERT(sdpCache.isEmpty());
//kill receiver to limit load of signals
+ receiver->unregisterReceiver();
receiver->deleteLater();
receiver = 0;
_q_serviceDiscoveryFinished();
@@ -509,6 +517,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_hostModeStateChanged(QBluetoothL
errorString = QBluetoothServiceDiscoveryAgent::tr("Device is powered off");
//kill receiver to limit load of signals
+ receiver->unregisterReceiver();
receiver->deleteLater();
receiver = 0;
diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp
index 769a5e68..a894fed3 100644
--- a/src/bluetooth/qbluetoothsocket_android.cpp
+++ b/src/bluetooth/qbluetoothsocket_android.cpp
@@ -324,7 +324,6 @@ quint16 QBluetoothSocketPrivate::peerPort() const
qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
{
//TODO implement buffered behavior (so far only unbuffered)
- //TODO check that readData and writeData return -1 on error (on all platforms)
Q_Q(QBluetoothSocket);
if (state != QBluetoothSocket::ConnectedState || !outputStream.isValid()) {
qCWarning(QT_BT_ANDROID) << "Socket::writeData: " << state << outputStream.isValid();
diff --git a/src/bluetooth/qbluetoothsocket_bluez.cpp b/src/bluetooth/qbluetoothsocket_bluez.cpp
index 825c6cd7..6aad6603 100644
--- a/src/bluetooth/qbluetoothsocket_bluez.cpp
+++ b/src/bluetooth/qbluetoothsocket_bluez.cpp
@@ -453,6 +453,7 @@ qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
if (::write(socket, data, maxSize) != maxSize) {
errorString = QBluetoothSocket::tr("Network Error");
q->setSocketError(QBluetoothSocket::NetworkError);
+ return -1;
}
emit q->bytesWritten(maxSize);
@@ -462,7 +463,7 @@ qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
else {
if(!connectWriteNotifier)
- return 0;
+ return -1;
if(txBuffer.size() == 0) {
connectWriteNotifier->setEnabled(true);
diff --git a/src/bluetooth/qbluetoothsocket_p.cpp b/src/bluetooth/qbluetoothsocket_p.cpp
index d64e7ecf..6e78be9e 100644
--- a/src/bluetooth/qbluetoothsocket_p.cpp
+++ b/src/bluetooth/qbluetoothsocket_p.cpp
@@ -123,7 +123,7 @@ qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
q->setSocketError(QBluetoothSocket::OperationError);
return -1;
}
- return 0;
+ return -1;
}
qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize)
@@ -139,7 +139,7 @@ qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize)
return -1;
}
- return 0;
+ return -1;
}
void QBluetoothSocketPrivate::close()
diff --git a/src/bluetooth/qbluetoothsocket_qnx.cpp b/src/bluetooth/qbluetoothsocket_qnx.cpp
index f60ba97a..4e277e28 100644
--- a/src/bluetooth/qbluetoothsocket_qnx.cpp
+++ b/src/bluetooth/qbluetoothsocket_qnx.cpp
@@ -226,6 +226,7 @@ qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
errorString = QBluetoothSocket::tr("Network Error");
q->setSocketError(QBluetoothSocket::NetworkError);
qCWarning(QT_BT_QNX) << Q_FUNC_INFO << "Socket error";
+ return -1;
}
Q_EMIT q->bytesWritten(maxSize);
@@ -233,7 +234,7 @@ qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
return maxSize;
} else {
if (!connectWriteNotifier)
- return 0;
+ return -1;
if (txBuffer.size() == 0) {
connectWriteNotifier->setEnabled(true);
diff --git a/src/bluetooth/qbluetoothuuid.cpp b/src/bluetooth/qbluetoothuuid.cpp
index 27215656..85d48d49 100644
--- a/src/bluetooth/qbluetoothuuid.cpp
+++ b/src/bluetooth/qbluetoothuuid.cpp
@@ -49,7 +49,6 @@
QT_BEGIN_NAMESPACE
// Bluetooth base UUID 00000000-0000-1000-8000-00805F9B34FB
-// TODO: make more efficient
Q_GLOBAL_STATIC_WITH_ARGS(QUuid, baseUuid, ("{00000000-0000-1000-8000-00805F9B34FB}"))
/*!
diff --git a/src/imports/nfc/qdeclarativenearfield.cpp b/src/imports/nfc/qdeclarativenearfield.cpp
index 673c9a0d..b1aeced7 100644
--- a/src/imports/nfc/qdeclarativenearfield.cpp
+++ b/src/imports/nfc/qdeclarativenearfield.cpp
@@ -69,14 +69,7 @@
and \l orderMatch properties to match the required NDEF messages. Once an NDEF message is
successfully read from a tag the \l messageRecords property is updated.
- \code
- NearField {
- filter: [ NdefFilter { type: "U"; typeNameFormat: NdefRecord.NfcRtd; minimum: 1; maximum: 1 } ]
- orderMatch: false
-
- onMessageRecordsChanged: displayMessage()
- }
- \endcode
+ \snippet doc_src_qtnfc.qml QML register for messages
*/
/*!
diff --git a/src/nfc/doc/snippets/doc_src_qtnfc.cpp b/src/nfc/doc/snippets/doc_src_qtnfc.cpp
index b7b0dfc4..62aa65e2 100644
--- a/src/nfc/doc/snippets/doc_src_qtnfc.cpp
+++ b/src/nfc/doc/snippets/doc_src_qtnfc.cpp
@@ -38,11 +38,35 @@
**
****************************************************************************/
+#include <QtCore/QObject>
//! [include]
#include <QtNfc/QNearFieldManager>
//! [include]
+#include <QtNfc/QNdefMessage>
//! [namespace]
QT_USE_NAMESPACE
//! [namespace]
+class MyClass : public QObject
+{
+ Q_OBJECT
+public:
+ MyClass() : QObject()
+ {
+//formatting adjusted to improve usage in docs
+//! [handleNdefMessage]
+QNearFieldManager *manager = new QNearFieldManager(this);
+manager->registerNdefMessageHandler(this,
+ SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget*)));
+//! [handleNdefMessage]
+ }
+
+public Q_SLOTS:
+ void handleNdefMessage(QNdefMessage,QNearFieldTarget*)
+ {
+ }
+};
+
+#include "doc_src_qtnfc.moc"
+
diff --git a/src/nfc/doc/snippets/doc_src_qtnfc.pro b/src/nfc/doc/snippets/doc_src_qtnfc.pro
deleted file mode 100644
index 5730e227..00000000
--- a/src/nfc/doc/snippets/doc_src_qtnfc.pro
+++ /dev/null
@@ -1,51 +0,0 @@
-#****************************************************************************
-#*
-#* Copyright (C) 2013 Aaron McCarthy <mccarthy.aaron@gmail.com>
-#* Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-#* Contact: http://www.qt-project.org/legal
-#*
-#* This file is part of the documentation of the Qt Toolkit.
-#*
-#* $QT_BEGIN_LICENSE:BSD$
-#* You may use this file under the terms of the BSD license as follows:
-#*
-#* "Redistribution and use in source and binary forms, with or without
-#* modification, are permitted provided that the following conditions are
-#* met:
-#* * Redistributions of source code must retain the above copyright
-#* notice, this list of conditions and the following disclaimer.
-#* * Redistributions in binary form must reproduce the above copyright
-#* notice, this list of conditions and the following disclaimer in
-#* the documentation and/or other materials provided with the
-#* distribution.
-#* * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-#* of its contributors may be used to endorse or promote products derived
-#* from this software without specific prior written permission.
-#*
-#*
-#* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-#*
-#* $QT_END_LICENSE$
-#*
-#***************************************************************************/
-
-#! [project modification]
-QT += nfc
-#! [project modification]
-
-SOURCES += main.cpp \
- doc_src_qtnfc.cpp \
- nfc.cpp \
- foorecord.cpp
-
-HEADERS += foorecord.h
diff --git a/src/nfc/doc/snippets/doc_src_qtnfc.qml b/src/nfc/doc/snippets/doc_src_qtnfc.qml
index 6c4d892d..427c24c6 100644
--- a/src/nfc/doc/snippets/doc_src_qtnfc.qml
+++ b/src/nfc/doc/snippets/doc_src_qtnfc.qml
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Aaron McCarthy <mccarthy.aaron@gmail.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -42,4 +43,13 @@
import QtNfc 5.2
//! [import]
-Item { }
+Item {
+//! [QML register for messages]
+ NearField {
+ filter: [ NdefFilter { type: "U"; typeNameFormat: NdefRecord.NfcRtd; minimum: 1; maximum: 1 } ]
+ orderMatch: false
+
+ onMessageRecordsChanged: displayMessage()
+ }
+//! [QML register for messages]
+}
diff --git a/src/nfc/doc/snippets/snippets.pro b/src/nfc/doc/snippets/snippets.pro
new file mode 100644
index 00000000..437782e4
--- /dev/null
+++ b/src/nfc/doc/snippets/snippets.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = nfc_cppsnippet
+QT = core
+#! [project modification]
+QT += nfc
+#! [project modification]
+
+SOURCES += main.cpp \
+ doc_src_qtnfc.cpp \
+ nfc.cpp \
+ foorecord.cpp
+
+HEADERS += foorecord.h
diff --git a/src/nfc/doc/src/nfc-cpp.qdoc b/src/nfc/doc/src/nfc-cpp.qdoc
index 4df93e69..cbb07e0c 100644
--- a/src/nfc/doc/src/nfc-cpp.qdoc
+++ b/src/nfc/doc/src/nfc-cpp.qdoc
@@ -38,6 +38,6 @@ The \l{Qt NFC} C++ API enables an application to access NFC Forum Tags.
To use the C++ library in your application, add the following configuration
option to your \c .pro file:
-\snippet doc_src_qtnfc.pro project modification
+\snippet snippets.pro project modification
*/
diff --git a/src/nfc/doc/src/nfc-index.qdoc b/src/nfc/doc/src/nfc-index.qdoc
index 2ec40891..2944a6ab 100644
--- a/src/nfc/doc/src/nfc-index.qdoc
+++ b/src/nfc/doc/src/nfc-index.qdoc
@@ -38,12 +38,14 @@ The NFC API provides APIs for interacting with NFC Forum Tags and NFC Forum Devi
target detection and loss, registering NDEF message handlers, reading and writing NDEF messages
on NFC Forum Tags and sending tag specific commands.
+Currently the API is supported on BlackBerry 10.
+
\section1 Getting started
To use the C++ library in your application, add the following configuration
option to your \c .pro file:
-\snippet doc_src_qtnfc.pro project modification
+\snippet snippets.pro project modification
To use the classes of the module in your application you need the following
import statement in your \c .qml file:
diff --git a/src/nfc/doc/src/nfc-overview.qdoc b/src/nfc/doc/src/nfc-overview.qdoc
index b7d029bb..b068dfb5 100644
--- a/src/nfc/doc/src/nfc-overview.qdoc
+++ b/src/nfc/doc/src/nfc-overview.qdoc
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Aaron McCarthy <mccarthy.aaron@gmail.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -36,14 +37,114 @@
With the Qt NFC API typical use cases are:
\list
- \li Detect NFC tags entering and leaving the communication range.
- \li Read and write NDEF message on NFC Forum Tags.
- \li Register an NDEF message handler for a particular content type.
+ \li Detecting NFC tags.
+ \li Reading and writing NDEF messages.
+ \li Registering NDEF message handlers.
+ \li Sharing files and messages.
\endlist
-The following sections describe how to use Qt NFC C++ classes for the above use cases.
+The following sections describe how to use Qt NFC C++ classes and QML types for the above use cases.
-\section1 Detect NFC tags entering and leaving communication range.
-\section1 Read and write an NDEF message on NFC Forum Tags.
-\section1 Register an NDEF message handler for a particular content type.
+\section1 C++ Overview
+
+The C++ API provides access to the full feature set of the Qt NFC API. This section introduces the
+major features available to developers.
+
+\section2 Detecting NFC Tags
+
+The \l QNearFieldManager class is responsible for the detection of new NFC tags coming
+into range of the device. The \l QNearFieldManager::targetDetected() and
+\l QNearFieldManager::targetLost() signals are emitted when
+a tag comes into or leaves the range. The passed \l QNearFieldTarget parameter acts
+as primary interaction point for each detected tag. The detection does not actually start though until
+\l QNearFieldManager::startTargetDetection() has been called.
+
+\snippet ndefeditor/mainwindow.cpp QNearFieldManager init
+\snippet ndefeditor/mainwindow.cpp QNearFieldManager start detection
+
+Finally the detection can be stopped:
+
+\snippet ndefeditor/mainwindow.cpp QNearFieldManager stop detection
+
+Although each \l QNearFieldTarget instance is owned by its related \l QNearFieldManager
+instance it can be beneficial to manually delete each instance. Otherwise they would continue to
+exist until the \l QNearFieldManager instance is deleted. The best way to do that would be in response
+to the \l QNearFieldManager::targetLost() signal:
+
+\snippet ndefeditor/mainwindow.cpp QNearFieldTarget lost
+
+\note The target object should only be deleted via deleteLater() if it is deleted inside the slot.
+
+\section2 Reading and Writing NDEF Messages
+
+The \l QNearFieldTarget instance returned by \l QNearFieldManager::targetDetected() signal
+is used to interact with the tag. Reading and writing a message is an asynchronous operation.
+The \l QNearFieldTarget::RequestId class associates individual operations and their results.
+
+\snippet ndefeditor/mainwindow.cpp QNearFieldTarget detected
+
+Once the \l QNearFieldTarget::readNdefMessages() request was successfully processed, the
+\l QNearFieldTarget::ndefMessageRead() signal is emitted. Each returned \l QNdefMessage
+may consist of zero or more \l QNdefRecord entries, which can be identified by their type.
+For more information about processing of records, see the \l QNdefRecord class documentation.
+As the above code demonstrates, writing of NDEF messages is triggered via
+\l QNearFieldTarget::writeNdefMessages(). The successful completion of the write operation
+is indicated by the emission of the \l QNearFieldTarget::ndefMessagesWritten() signal. Any
+type of error during read or write is indicated via \l QNearFieldTarget::error().
+
+\section2 Registering NDEF Message Handlers
+
+The above described method (of reading NDEF messages) directly connects to the platform's NFC infrastructure.
+However on some platforms (in particular mobile platforms) this may not actually trigger the target slot
+if the application is currently running in the background. This is not desirable in cases where an
+application wants to be activated if the platform detects a tag of particular type.
+For this purpose the Qt NFC API provides the possibility to register an NDEF message handler. The handler
+is called by the operating system, when the detected NDEF message matches the given filter criteria.
+Depending on the platform it may even be possible to start the application that registered the handler.
+
+\note This feature is not available on all platforms and, in addition to the code snippets below,
+may require further platform specific setup.
+
+\snippet annotatedurl/main.cpp QNearFieldManager register handler
+
+For comparison an application that uses an empty NDEF filter (match all behavior) in combination with
+\l QNearFieldManager::registerNdefMessageHandler() would behave similarly to another application that uses
+\l QNearFieldTarget::readNdefMessages() while being in the forground. For more information about
+registration details of NDEF message handlers, see the
+\l {QNearFieldManager#automatically-launching-ndef-message-handlers}{QNearFieldManager} class description.
+
+The content of \c handleMessage() may look like the snippet below. Any incoming NDEF message of type
+\c text or \c uri will be processed:
+
+\snippet annotatedurl/annotatedurl.cpp handleMessage 1
+\snippet annotatedurl/annotatedurl.cpp handleMessage 2
+\snippet annotatedurl/annotatedurl.cpp handleMessage 3
+\snippet annotatedurl/annotatedurl.cpp handleMessage 4
+
+\section2 Sharing Files and Messages
+
+Since Qt 5.3, Qt NFC provides a generic NFC share feature. If both devices support the same protocol,
+the feature can be used to share files or NDEF messages. The advantage is that the two involved partners
+can quickly establish a connection via NFC but transfer the data through, for example, Bluetooth or Wifi.
+Effectively, this combines the low configuration effort of NFC with high data rate communication bearers
+which usually require a much more complex setup.
+
+\note The API does not make any guarantees about the actual communication bearer used during the transfer.
+The bearer is chosen based on the device's capabilities and the properties of the to-be-shared data.
+
+\l QNearFieldShareManager and \l QNearFieldShareTarget are responsible for accessing the NFC share feature.
+
+\section1 QML Overview
+
+The QML API only supports a very small subset of the Qt NFC feature set. This section outlines the available QML features.
+
+\section2 Reading NDEF Messages
+
+The user can specify NDEF filters and use those filters to register for the automatic reception of NDEF
+messages which match those filters. The \l NearField::messageRecords property contains the list of NDEF records
+of the last NDEF message read matching the given filters.
+
+\snippet doc_src_qtnfc.qml QML register for messages
+
+If no filter is set, the message handler will match all incoming NDEF messages.
*/
diff --git a/src/nfc/qnearfieldmanager.cpp b/src/nfc/qnearfieldmanager.cpp
index f2fafdce..88656a6e 100644
--- a/src/nfc/qnearfieldmanager.cpp
+++ b/src/nfc/qnearfieldmanager.cpp
@@ -103,11 +103,7 @@ QT_BEGIN_NAMESPACE
If the application has been registered as an NDEF message handler, the application only needs
to call the registerNdefMessageHandler() function:
- \code
- QNearFieldManager *manager = new QNearFieldManager;
- manager->registerNdefMessageHandler(this,
- SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget)));
- \endcode
+ \snippet doc_src_qtnfc.cpp handleNdefMessage
On BlackBerry the registration for NDEF message handlers is done over the
\l{https://developer.blackberry.com/native/documentation/core/invocation_framework.html}{Invocation Framework}.
diff --git a/src/nfc/qnearfieldsharemanager.cpp b/src/nfc/qnearfieldsharemanager.cpp
index b3e736b6..43b1634b 100644
--- a/src/nfc/qnearfieldsharemanager.cpp
+++ b/src/nfc/qnearfieldsharemanager.cpp
@@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
\ingroup connectivity-nfc
\inmodule QtNfc
+ \since 5.3
Applications can share NDEF data or file content using NFC technology by tapping two NFC-enabled devices
together. The QNearFieldShareManager provides a high level entry point to access this functionality.
diff --git a/src/nfc/qnearfieldsharetarget.cpp b/src/nfc/qnearfieldsharetarget.cpp
index 9ac66c5c..606090b5 100644
--- a/src/nfc/qnearfieldsharetarget.cpp
+++ b/src/nfc/qnearfieldsharetarget.cpp
@@ -58,9 +58,12 @@ QT_BEGIN_NAMESPACE
\ingroup connectivity-nfc
\inmodule QtNfc
+ \since 5.3
The QNearFieldShareTarget class can be used for sharing NDEF message or files to a remote
NFC enabled device supporting the same protocol.
+
+ \sa QNearFieldShareManager
*/
/*!
diff --git a/src/src.pro b/src/src.pro
index 7f37867e..e2ed3c88 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -7,6 +7,10 @@ bluetooth_doc_snippets.subdir = bluetooth/doc/snippets
bluetooth_doc_snippets.depends = bluetooth
SUBDIRS += bluetooth_doc_snippets
+nfc_doc_snippets.subdir = nfc/doc/snippets
+nfc_doc_snippets.depends = nfc
+SUBDIRS += nfc_doc_snippets
+
qtHaveModule(quick) {
imports.depends += bluetooth nfc
SUBDIRS += imports