Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
jni_android.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Lauri Laanmets (Proekspert AS) <lauri.laanmets@eesti.ee>
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include <jni.h>
6#include <android/log.h>
7#include <QtCore/QLoggingCategory>
8#include <QtBluetooth/qtbluetoothglobal.h>
14
16
17Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
18
20Q_GLOBAL_STATIC(JCachedStringFields, cachedStringFields)
21
22/*
23 * This function operates on the assumption that each
24 * field is of type java/lang/String.
25 */
26QJniObject valueFromStaticFieldCache(const char *key, const char *className, const char *fieldName)
27{
28 JCachedStringFields::iterator it = cachedStringFields()->find(key);
29 if (it == cachedStringFields()->end()) {
31 QJniObject fieldValue = QJniObject::getStaticObjectField(
32 className, fieldName, "Ljava/lang/String;");
33 if (!fieldValue.isValid()) {
34 cachedStringFields()->insert(key, QJniObject());
35 return QJniObject();
36 }
37
38 cachedStringFields()->insert(key, fieldValue);
39 return fieldValue;
40 } else {
41 return it.value();
42 }
43}
44
45void QtBroadcastReceiver_jniOnReceive(JNIEnv *env, jobject /*javaObject*/,
46 jlong qtObject, QtJniTypes::Context context,
47 QtJniTypes::Intent intent)
48{
49 reinterpret_cast<AndroidBroadcastReceiver*>(qtObject)->onReceive(env, context, intent);
50}
51Q_DECLARE_JNI_NATIVE_METHOD(QtBroadcastReceiver_jniOnReceive, jniOnReceive)
52
53static void QtBluetoothSocketServer_errorOccurred(JNIEnv */*env*/, jobject /*javaObject*/,
54 jlong qtObject, jint errorCode)
55{
56 reinterpret_cast<ServerAcceptanceThread*>(qtObject)->javaThreadErrorOccurred(errorCode);
57}
58Q_DECLARE_JNI_NATIVE_METHOD(QtBluetoothSocketServer_errorOccurred, errorOccurred)
59
60static void QtBluetoothSocketServer_newSocket(JNIEnv */*env*/, jobject /*javaObject*/,
61 jlong qtObject, QtJniTypes::BluetoothSocket socket)
62{
63 reinterpret_cast<ServerAcceptanceThread*>(qtObject)->javaNewSocket(socket);
64}
65Q_DECLARE_JNI_NATIVE_METHOD(QtBluetoothSocketServer_newSocket, newSocket)
66
67static void QtBluetoothInputStreamThread_errorOccurred(JNIEnv */*env*/, jobject /*javaObject*/,
68 jlong qtObject, jint errorCode)
69{
70 reinterpret_cast<InputStreamThread*>(qtObject)->javaThreadErrorOccurred(errorCode);
71}
72Q_DECLARE_JNI_NATIVE_METHOD(QtBluetoothInputStreamThread_errorOccurred, errorOccurred)
73
74static void QtBluetoothInputStreamThread_readyData(JNIEnv */*env*/, jobject /*javaObject*/,
75 jlong qtObject, jbyteArray buffer, jint bufferLength)
76{
77 reinterpret_cast<InputStreamThread*>(qtObject)->javaReadyRead(buffer, bufferLength);
78}
79Q_DECLARE_JNI_NATIVE_METHOD(QtBluetoothInputStreamThread_readyData, readyData)
80
81void QtBluetoothLE_leScanResult(JNIEnv *env, jobject, jlong qtObject,
82 QtJniTypes::BluetoothDevice bluetoothDevice, jint rssi,
83 jbyteArray scanRecord)
84{
85 if (Q_UNLIKELY(qtObject == 0))
86 return;
87
88 reinterpret_cast<AndroidBroadcastReceiver*>(qtObject)->onReceiveLeScan(
89 env, bluetoothDevice, rssi,
90 scanRecord);
91}
92Q_DECLARE_JNI_NATIVE_METHOD(QtBluetoothLE_leScanResult, leScanResult)
93
94static const char logTag[] = "QtBluetooth";
95static const char classErrorMsg[] = "Can't find class \"%s\"";
96
97#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
98clazz = env.findClass<CLASS_NAME>(); \
99if (!clazz) { \
100 __android_log_print(ANDROID_LOG_FATAL, logTag, classErrorMsg, \
101 QtJniTypes::className<CLASS_NAME>().data()); \
102 return JNI_FALSE; \
103} \
104
105#define LEHUB_SCOPED_METHOD(Method) Q_JNI_NATIVE_SCOPED_METHOD(Method, LowEnergyNotificationHub)
106
107static bool registerNatives()
108{
109 jclass clazz;
110 QJniEnvironment env;
111
112 FIND_AND_CHECK_CLASS(QtJniTypes::QtBtBroadcastReceiver);
113 if (!env.registerNativeMethods(clazz,
114 {
115 Q_JNI_NATIVE_METHOD(QtBroadcastReceiver_jniOnReceive)
116 }))
117 {
118 __android_log_print(ANDROID_LOG_FATAL, logTag,
119 "registerNativeMethods for BroadcastReceiver failed");
120 return false;
121 }
122
123 FIND_AND_CHECK_CLASS(QtJniTypes::QtBtLECentral);
124 if (!env.registerNativeMethods(clazz,
125 {
126 Q_JNI_NATIVE_METHOD(QtBluetoothLE_leScanResult),
127 LEHUB_SCOPED_METHOD(lowEnergy_connectionChange),
128 LEHUB_SCOPED_METHOD(lowEnergy_mtuChanged),
129 LEHUB_SCOPED_METHOD(lowEnergy_servicesDiscovered),
130 LEHUB_SCOPED_METHOD(lowEnergy_serviceDetailsDiscovered),
131 LEHUB_SCOPED_METHOD(lowEnergy_characteristicRead),
132 LEHUB_SCOPED_METHOD(lowEnergy_descriptorRead),
133 LEHUB_SCOPED_METHOD(lowEnergy_characteristicWritten),
134 LEHUB_SCOPED_METHOD(lowEnergy_descriptorWritten),
135 LEHUB_SCOPED_METHOD(lowEnergy_characteristicChanged),
136 LEHUB_SCOPED_METHOD(lowEnergy_serviceError),
137 LEHUB_SCOPED_METHOD(lowEnergy_remoteRssiRead)
138 }))
139 {
140 __android_log_print(ANDROID_LOG_FATAL, logTag,
141 "registerNativeMethods for QBLuetoothLE failed");
142 return false;
143 }
144
145 FIND_AND_CHECK_CLASS(QtJniTypes::QtBtLEServer);
146 if (!env.registerNativeMethods(clazz,
147 {
148 LEHUB_SCOPED_METHOD(lowEnergy_connectionChange),
149 LEHUB_SCOPED_METHOD(lowEnergy_mtuChanged),
150 LEHUB_SCOPED_METHOD(lowEnergy_advertisementError),
151 LEHUB_SCOPED_METHOD(lowEnergy_serverCharacteristicChanged),
152 LEHUB_SCOPED_METHOD(lowEnergy_serverDescriptorWritten)
153 }))
154 {
155 __android_log_print(ANDROID_LOG_FATAL, logTag,
156 "registerNativeMethods for QBLuetoothLEServer failed");
157 return false;
158 }
159
160 FIND_AND_CHECK_CLASS(QtJniTypes::QtBtSocketServer);
161 if (!env.registerNativeMethods(clazz,
162 {
163 Q_JNI_NATIVE_METHOD(QtBluetoothSocketServer_errorOccurred),
164 Q_JNI_NATIVE_METHOD(QtBluetoothSocketServer_newSocket)
165 }))
166 {
167 __android_log_print(ANDROID_LOG_FATAL, logTag,
168 "registerNativeMethods for SocketServer failed");
169 return false;
170 }
171
172 FIND_AND_CHECK_CLASS(QtJniTypes::QtBtInputStreamThread);
173 if (!env.registerNativeMethods(clazz,
174 {
175 Q_JNI_NATIVE_METHOD(QtBluetoothInputStreamThread_errorOccurred),
176 Q_JNI_NATIVE_METHOD(QtBluetoothInputStreamThread_readyData)
177 }))
178 {
179 __android_log_print(ANDROID_LOG_FATAL, logTag,
180 "registerNativeMethods for InputStreamThread failed");
181 return false;
182 }
183
184 return true;
185}
186
188
189Q_BLUETOOTH_EXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
190{
191 static bool initialized = false;
192 if (initialized)
193 return JNI_VERSION_1_6;
194 initialized = true;
195
196 typedef union {
197 JNIEnv *nativeEnvironment;
198 void *venv;
199 } UnionJNIEnvToVoid;
200
201 UnionJNIEnvToVoid uenv;
202 uenv.venv = 0;
203
204 if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_6) != JNI_OK) {
205 __android_log_print(ANDROID_LOG_FATAL, logTag, "GetEnv failed");
206 return -1;
207 }
208
209 if (!registerNatives()) {
210 __android_log_print(ANDROID_LOG_FATAL, logTag, "registerNatives failed");
211 return -1;
212 }
213
214 if (QT_BT_ANDROID().isDebugEnabled())
215 __android_log_print(ANDROID_LOG_INFO, logTag, "Bluetooth start");
216
217 return JNI_VERSION_1_6;
218}
quint8 rssi
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qhash.h:818
\inmodule QtCore
\inmodule QtCore
iterator find(const T &value)
Definition qset.h:159
QSet< QString >::iterator it
QT_END_NAMESPACE Q_BLUETOOTH_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *)
QT_BEGIN_NAMESPACE typedef QHash< QByteArray, QJniObject > JCachedStringFields
void QtBroadcastReceiver_jniOnReceive(JNIEnv *env, jobject, jlong qtObject, QtJniTypes::Context context, QtJniTypes::Intent intent)
QJniObject valueFromStaticFieldCache(const char *key, const char *className, const char *fieldName)
static const char logTag[]
#define FIND_AND_CHECK_CLASS(CLASS_NAME)
void QtBluetoothLE_leScanResult(JNIEnv *env, jobject, jlong qtObject, QtJniTypes::BluetoothDevice bluetoothDevice, jint rssi, jbyteArray scanRecord)
static void QtBluetoothInputStreamThread_errorOccurred(JNIEnv *, jobject, jlong qtObject, jint errorCode)
static void QtBluetoothInputStreamThread_readyData(JNIEnv *, jobject, jlong qtObject, jbyteArray buffer, jint bufferLength)
static const char classErrorMsg[]
static void QtBluetoothSocketServer_newSocket(JNIEnv *, jobject, jlong qtObject, QtJniTypes::BluetoothSocket socket)
static void QtBluetoothSocketServer_errorOccurred(JNIEnv *, jobject, jlong qtObject, jint errorCode)
static bool registerNatives()
Combined button and popup list for selecting options.
static void * context
#define Q_UNLIKELY(x)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLuint64 key
GLuint GLuint end
GLenum GLuint buffer
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble s
[6]
Definition qopenglext.h:235
const char className[16]
[1]
Definition qwizard.cpp:100
QTcpSocket * socket
[1]