summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/android
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@digia.com>2014-10-29 13:04:49 +0100
committerAlex Blasche <alexander.blasche@digia.com>2014-11-04 09:47:24 +0100
commit7c12e73031c7dde3d422f9a2d0baeaa25b75fabb (patch)
treefcc6a333174cb741bc459855778ae0917e8f2cdc /src/bluetooth/android
parentcb3054e2373dec8e800c1b5208555936ef3ae63b (diff)
Android: Add ability to (dis)connect to BTLE devices on Android
and keep tracking the connection state Change-Id: If4d05fa18c78802ae06096884fba78eed123e77f Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'src/bluetooth/android')
-rw-r--r--src/bluetooth/android/android.pri6
-rw-r--r--src/bluetooth/android/jni_android.cpp3
-rw-r--r--src/bluetooth/android/lowenergynotificationhub.cpp110
-rw-r--r--src/bluetooth/android/lowenergynotificationhub_p.h80
4 files changed, 197 insertions, 2 deletions
diff --git a/src/bluetooth/android/android.pri b/src/bluetooth/android/android.pri
index 0507894f..c50a919a 100644
--- a/src/bluetooth/android/android.pri
+++ b/src/bluetooth/android/android.pri
@@ -5,7 +5,8 @@ PRIVATE_HEADERS += \
android/androidbroadcastreceiver_p.h \
android/localdevicebroadcastreceiver_p.h \
android/serveracceptancethread_p.h \
- android/jni_android_p.h
+ android/jni_android_p.h \
+ android/lowenergynotificationhub_p.h
SOURCES += \
@@ -15,4 +16,5 @@ SOURCES += \
android/jni_android.cpp \
android/androidbroadcastreceiver.cpp \
android/localdevicebroadcastreceiver.cpp \
- android/serveracceptancethread.cpp
+ android/serveracceptancethread.cpp \
+ android/lowenergynotificationhub.cpp
diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp
index 061d6ce2..6fffc018 100644
--- a/src/bluetooth/android/jni_android.cpp
+++ b/src/bluetooth/android/jni_android.cpp
@@ -40,6 +40,7 @@
#include "android/androidbroadcastreceiver_p.h"
#include "android/serveracceptancethread_p.h"
#include "android/inputstreamthread_p.h"
+#include "android/lowenergynotificationhub_p.h"
Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
@@ -198,6 +199,8 @@ static JNINativeMethod methods[] = {
static JNINativeMethod methods_le[] = {
{"leScanResult", "(JLandroid/bluetooth/BluetoothDevice;I)V",
(void *) QtBluetoothLE_leScanResult},
+ {"leConnectionStateChange", "(JII)V",
+ (void *) LowEnergyNotificationHub::lowEnergy_connectionChange},
};
static JNINativeMethod methods_server[] = {
diff --git a/src/bluetooth/android/lowenergynotificationhub.cpp b/src/bluetooth/android/lowenergynotificationhub.cpp
new file mode 100644
index 00000000..d662cd5b
--- /dev/null
+++ b/src/bluetooth/android/lowenergynotificationhub.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** 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:LGPL21$
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lowenergynotificationhub_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QTime>
+#include <QtAndroidExtras/QAndroidJniEnvironment>
+
+QT_BEGIN_NAMESPACE
+
+typedef QHash<long, LowEnergyNotificationHub*> HubMapType;
+Q_GLOBAL_STATIC(HubMapType, hubMap)
+
+QReadWriteLock LowEnergyNotificationHub::lock;
+
+Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
+
+LowEnergyNotificationHub::LowEnergyNotificationHub(
+ const QBluetoothAddress &remote, QObject *parent)
+ : QObject(parent), javaToCtoken(0)
+{
+ QAndroidJniEnvironment env;
+ const QAndroidJniObject address =
+ QAndroidJniObject::fromString(remote.toString());
+ jBluetoothLe = QAndroidJniObject("org/qtproject/qt5/android/bluetooth/QtBluetoothLE",
+ "(Ljava/lang/String;Landroid/app/Activity;)V",
+ address.object<jstring>(),
+ QtAndroidPrivate::activity());
+
+
+ if (env->ExceptionCheck() || !jBluetoothLe.isValid()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ jBluetoothLe = QAndroidJniObject();
+ return;
+ }
+
+ // register C++ class pointer in Java
+ qsrand(QTime::currentTime().msec());
+ lock.lockForWrite();
+
+ while (true) {
+ javaToCtoken = qrand();
+ if (!hubMap()->contains(javaToCtoken))
+ break;
+ }
+
+ hubMap()->insert(javaToCtoken, this);
+ lock.unlock();
+
+ jBluetoothLe.setField<jlong>("qtObject", javaToCtoken);
+}
+
+LowEnergyNotificationHub::~LowEnergyNotificationHub()
+{
+ lock.lockForWrite();
+ hubMap()->remove(javaToCtoken);
+ lock.unlock();
+}
+
+// runs in Java thread
+void LowEnergyNotificationHub::lowEnergy_connectionChange(
+ JNIEnv *, jobject, jlong qtObject, jint errorCode, jint newState)
+{
+ lock.lockForRead();
+ LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
+ lock.unlock();
+ if (!hub)
+ return;
+
+ QMetaObject::invokeMethod(hub, "connectionUpdated", Qt::QueuedConnection,
+ Q_ARG(QLowEnergyController::ControllerState,
+ (QLowEnergyController::ControllerState)newState),
+ Q_ARG(QLowEnergyController::Error,
+ (QLowEnergyController::Error)errorCode));
+}
+
+QT_END_NAMESPACE
diff --git a/src/bluetooth/android/lowenergynotificationhub_p.h b/src/bluetooth/android/lowenergynotificationhub_p.h
new file mode 100644
index 00000000..68999a3e
--- /dev/null
+++ b/src/bluetooth/android/lowenergynotificationhub_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** 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:LGPL21$
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LOWENERGYNOTIFICATIONHUB_H
+#define LOWENERGYNOTIFICATIONHUB_H
+
+#include <QtCore/QObject>
+#include <QtCore/QReadWriteLock>
+#include <QtCore/private/qjnihelpers_p.h>
+#include <QtAndroidExtras/QAndroidJniObject>
+#include <QtBluetooth/QBluetoothAddress>
+#include <jni.h>
+
+#include "qlowenergycontroller_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class LowEnergyNotificationHub : public QObject
+{
+ Q_OBJECT
+public:
+ explicit LowEnergyNotificationHub(const QBluetoothAddress &remote,
+ QObject *parent = 0);
+ ~LowEnergyNotificationHub();
+
+ static void lowEnergy_connectionChange(JNIEnv*, jobject, jlong qtObject,
+ jint errorCode, jint newState);
+
+ QAndroidJniObject javaObject()
+ {
+ return jBluetoothLe;
+ }
+
+signals:
+ void connectionUpdated(QLowEnergyController::ControllerState newState,
+ QLowEnergyController::Error errorCode);
+
+public slots:
+private:
+ static QReadWriteLock lock;
+
+ QAndroidJniObject jBluetoothLe;
+ long javaToCtoken;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // LOWENERGYNOTIFICATIONHUB_H
+