Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qbluetoothsocket_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 "qbluetoothsocket.h"
7#include "qbluetoothaddress.h"
12#include <QCoreApplication>
13#include <QtCore/QLoggingCategory>
14#include <QtCore/QThread>
15#include <QtCore/QTime>
16#include <QtCore/QJniEnvironment>
17
19
20Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
21
22#define USE_FALLBACK true
23
24Q_BLUETOOTH_EXPORT bool useReverseUuidWorkAroundConnect = true;
25
26/* BluetoothSocket.connect() can block up to 10s. Therefore it must be
27 * in a separate thread. Unfortunately if BluetoothSocket.close() is
28 * called while connect() is still blocking the resulting behavior is not reliable.
29 * This may well be an Android platform bug. In any case, close() must
30 * be queued up until connect() has returned.
31 *
32 * The WorkerThread manages the connect() and close() calls. Interaction
33 * with the main thread happens via signals and slots. There is an accepted but
34 * undesirable side effect of this approach as the user may call connect()
35 * and close() and the socket would continue to successfully connect to
36 * the remote device just to immidiately close the physical connection again.
37 *
38 * WorkerThread and SocketConnectWorker are cleaned up via the threads
39 * finished() signal.
40 */
41
43{
45public:
47 const QJniObject& targetUuid,
48 const QBluetoothUuid& qtTargetUuid)
49 : QObject(),
50 mSocketObject(socket),
51 mTargetUuid(targetUuid),
52 mQtTargetUuid(qtTargetUuid)
53 {
54 static int t = qRegisterMetaType<QJniObject>();
55 Q_UNUSED(t);
56 }
57
61 const QJniObject &targetUuid,
62 const QBluetoothUuid &qtUuid);
63public slots:
65 {
67
68 qCDebug(QT_BT_ANDROID) << "Connecting socket";
69 auto methodId = env.findMethod(mSocketObject.objectClass(), "connect", "()V");
70 if (methodId)
71 env->CallVoidMethod(mSocketObject.object(), methodId);
72 if (!methodId || env.checkAndClearExceptions()) {
73 emit socketConnectFailed(mSocketObject, mTargetUuid, mQtTargetUuid);
74 QThread::currentThread()->quit();
75 return;
76 }
77
78 qCDebug(QT_BT_ANDROID) << "Socket connection established";
79 emit socketConnectDone(mSocketObject);
80 }
81
83 {
84 qCDebug(QT_BT_ANDROID) << "Executing queued closeSocket()";
85
86 mSocketObject.callMethod<void>("close");
87 QThread::currentThread()->quit();
88 }
89
90private:
91 QJniObject mSocketObject;
92 QJniObject mTargetUuid;
93 // same as mTargetUuid above - just the Qt C++ version rather than jni uuid
94 QBluetoothUuid mQtTargetUuid;
95};
96
97class WorkerThread: public QThread
98{
100public:
102 : QThread(), workerPointer(0)
103 {
104 }
105
106 // Runs in same thread as QBluetoothSocketPrivateAndroid
133
134private:
135 QPointer<SocketConnectWorker> workerPointer;
136};
137
139 :
140 inputThread(0)
141{
144 qRegisterMetaType<QBluetoothSocket::SocketError>();
145 qRegisterMetaType<QBluetoothSocket::SocketState>();
146}
147
153
162
163/*
164 * Workaround for QTBUG-61392. If the underlying Android bug gets fixed,
165 * we need to consider restoring the non-reversed fallbackConnect from the repository.
166 */
168{
169 Q_Q(QBluetoothSocket);
170
171 qCWarning(QT_BT_ANDROID) << "Falling back to reverse uuid workaround.";
172 const QBluetoothUuid reverse = reverseUuid(uuid);
173 if (reverse.isNull())
174 return false;
175
176 QString tempUuid = reverse.toString(QUuid::WithoutBraces);
177
178 QJniEnvironment env;
179 const QJniObject inputString = QJniObject::fromString(tempUuid);
180 const QJniObject uuidObject = QJniObject::callStaticMethod<QtJniTypes::UUID>(
181 QtJniTypes::Traits<QtJniTypes::UUID>::className(), "fromString",
182 inputString.object<jstring>());
183
184 if (secFlags == QBluetooth::SecurityFlags(QBluetooth::Security::NoSecurity)) {
185 qCDebug(QT_BT_ANDROID) << "Connecting via insecure rfcomm";
186 socketObject = remoteDevice.callMethod<QtJniTypes::BluetoothSocket>(
187 "createInsecureRfcommSocketToServiceRecord",
188 uuidObject.object<QtJniTypes::UUID>());
189 } else {
190 qCDebug(QT_BT_ANDROID) << "Connecting via secure rfcomm";
191 socketObject = remoteDevice.callMethod<QtJniTypes::BluetoothSocket>(
192 "createRfcommSocketToServiceRecord",
193 uuidObject.object<QtJniTypes::UUID>());
194 }
195
196 if (!socketObject.isValid()) {
198 errorString = QBluetoothSocket::tr("Cannot connect to %1",
199 "%1 = uuid").arg(reverse.toString());
202 return false;
203 }
204
205 WorkerThread *workerThread = new WorkerThread();
206 workerThread->setupWorker(this, socketObject, uuidObject, USE_FALLBACK);
207 workerThread->start();
209
210 return true;
211}
212
213/*
214 * The call order during a connectToServiceHelper() is as follows:
215 *
216 * 1. call connectToServiceHelper()
217 * 2. wait for execution of SocketConnectThread::run()
218 * 3. if threaded connect succeeds call socketConnectSuccess() via signals
219 * -> done
220 * 4. if threaded connect fails call defaultSocketConnectFailed() via signals
221 * 5. call fallBackReversedConnect()
222 * -> if failure entire connectToServiceHelper() fails
223 * Note: This fallback can be disabled with private API boolean
224 * 6. if threaded connect on one of above fallbacks succeeds call socketConnectSuccess()
225 * via signals
226 * -> done
227 * 7. if threaded connect on fallback channel fails call fallbackSocketConnectFailed()
228 * -> complete failure of entire connectToServiceHelper()
229 * */
231 const QBluetoothUuid &uuid,
232 QIODevice::OpenMode openMode)
233{
234 Q_Q(QBluetoothSocket);
236
237 qCDebug(QT_BT_ANDROID) << "connectToServiceHelper()" << address.toString() << uuid.toString();
238
240 qCWarning(QT_BT_ANDROID) << "Bluetooth socket connect failed due to missing permissions";
241 errorString = QBluetoothSocket::tr(
242 "Bluetooth socket connect failed due to missing permissions.");
245 return;
246 }
247
249
250 if (!adapter.isValid()) {
251 qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
252 errorString = QBluetoothSocket::tr("Device does not support Bluetooth");
255 return;
256 }
257
258 const int state = adapter.callMethod<jint>("getState");
259 if (state != 12 ) { //BluetoothAdapter.STATE_ON
260 qCWarning(QT_BT_ANDROID) << "Bluetooth device offline";
261 errorString = QBluetoothSocket::tr("Device is powered off");
264 return;
265 }
266
267 QJniEnvironment env;
268 QJniObject inputString = QJniObject::fromString(address.toString());
269 remoteDevice = adapter.callMethod<QtJniTypes::BluetoothDevice>("getRemoteDevice",
270 inputString.object<jstring>());
271 if (!remoteDevice.isValid()) {
272 errorString = QBluetoothSocket::tr("Cannot access address %1", "%1 = Bt address e.g. 11:22:33:44:55:66").arg(address.toString());
275 return;
276 }
277
278 //cut leading { and trailing } {xxx-xxx}
279 const QString tempUuid = uuid.toString(QUuid::WithoutBraces);
280
281 inputString = QJniObject::fromString(tempUuid);
282 const QJniObject uuidObject = QJniObject::callStaticMethod<QtJniTypes::UUID>(
283 QtJniTypes::Traits<QtJniTypes::UUID>::className(), "fromString",
284 inputString.object<jstring>());
285
286 if (secFlags == QBluetooth::SecurityFlags(QBluetooth::Security::NoSecurity)) {
287 qCDebug(QT_BT_ANDROID) << "Connecting via insecure rfcomm";
288 socketObject = remoteDevice.callMethod<QtJniTypes::BluetoothSocket>(
289 "createInsecureRfcommSocketToServiceRecord",
290 uuidObject.object<QtJniTypes::UUID>());
291 } else {
292 qCDebug(QT_BT_ANDROID) << "Connecting via secure rfcomm";
293 socketObject = remoteDevice.callMethod<QtJniTypes::BluetoothSocket>(
294 "createRfcommSocketToServiceRecord",
295 uuidObject.object<QtJniTypes::UUID>());
296 }
297
298 if (!socketObject.isValid()) {
300 errorString = QBluetoothSocket::tr("Cannot connect to %1 on %2",
301 "%1 = uuid, %2 = Bt address").arg(uuid.toString()).arg(address.toString());
304 return;
305 }
306
307 WorkerThread *workerThread = new WorkerThread();
308 workerThread->setupWorker(this, socketObject, uuidObject, !USE_FALLBACK, uuid);
309 workerThread->start();
311}
312
314 const QBluetoothServiceInfo &service, QIODevice::OpenMode openMode)
315{
316 Q_Q(QBluetoothSocket);
317
320 qCWarning(QT_BT_ANDROID) << "QBluetoothSocketPrivateAndroid::connectToService called on busy socket";
321 errorString = QBluetoothSocket::tr("Trying to connect while connection is in progress");
323 return;
324 }
325
326 // Workaround for QTBUG-75035
327 /* Not all Android devices publish or discover the SPP uuid for serial services.
328 * Also, Android does not permit the detection of the protocol used by a serial
329 * Bluetooth connection.
330 *
331 * Therefore, QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices()
332 * may have to guess what protocol a potential custom uuid uses. The guessing works
333 * reasonably well as long as the SDP discovery finds the SPP uuid. Otherwise
334 * the SPP and rfcomm protocol info is missing in \a service.
335 *
336 * Android only supports RFCOMM (no L2CP). We assume (in favor of user experience)
337 * that a non-RFCOMM protocol implies a missing SPP uuid during discovery but the user
338 * still wanting to connect with the given \a service instance.
339 */
340
341 auto protocol = service.socketProtocol();
342 switch (protocol) {
345 qCWarning(QT_BT_ANDROID) << "Changing socket protocol to RFCOMM";
347 break;
349 break;
350 }
351
352 if (!ensureNativeSocket(protocol)) {
353 errorString = QBluetoothSocket::tr("Socket type not supported");
355 return;
356 }
357 connectToServiceHelper(service.device().address(), service.serviceUuid(), openMode);
358}
359
361 const QBluetoothAddress &address, const QBluetoothUuid &uuid,
362 QIODevice::OpenMode openMode)
363{
364 Q_Q(QBluetoothSocket);
365
367 qCWarning(QT_BT_ANDROID) << "QBluetoothSocketPrivateAndroid::connectToService called on busy socket";
368 errorString = QBluetoothSocket::tr("Trying to connect while connection is in progress");
370 return;
371 }
372
373 if (q->socketType() == QBluetoothServiceInfo::UnknownProtocol) {
374 qCWarning(QT_BT_ANDROID) << "QBluetoothSocketPrivateAndroid::connectToService cannot "
375 "connect with 'UnknownProtocol' (type provided by given service)";
376 errorString = QBluetoothSocket::tr("Socket type not supported");
378 return;
379 }
380
381 if (!ensureNativeSocket(q->socketType())) {
382 errorString = QBluetoothSocket::tr("Socket type not supported");
384 return;
385 }
387}
388
390 const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode)
391{
392 Q_UNUSED(port);
395
396 Q_Q(QBluetoothSocket);
397
398 errorString = tr("Connecting to port is not supported");
400 qCWarning(QT_BT_ANDROID) << "Connecting to port is not supported";
401}
402
404{
405 Q_Q(QBluetoothSocket);
406 QJniEnvironment env;
407
408 // test we didn't get a success from a previous connect
409 // which was cleaned up late
410 if (socket != socketObject)
411 return;
412
413 if (inputThread) {
415 inputThread = 0;
416 }
417
418 inputStream = socketObject.callMethod<QtJniTypes::InputStream>("getInputStream");
419 outputStream = socketObject.callMethod<QtJniTypes::OutputStream>("getOutputStream");
420
421 if (!inputStream.isValid() || !outputStream.isValid()) {
422
425
426
427 errorString = QBluetoothSocket::tr("Obtaining streams for service failed");
430 return;
431 }
432
433 inputThread = new InputStreamThread(this);
434 QObject::connect(inputThread, SIGNAL(dataAvailable()),
435 q, SIGNAL(readyRead()), Qt::QueuedConnection);
436 QObject::connect(inputThread, SIGNAL(errorOccurred(int)), this, SLOT(inputThreadError(int)),
438
439 if (!inputThread->run()) {
440 //close socket again
442
444
445 delete inputThread;
446 inputThread = 0;
447
448 errorString = QBluetoothSocket::tr("Input stream thread cannot be started");
451 return;
452 }
453
454 // only unbuffered behavior supported at this stage
456
458}
459
461 const QJniObject &socket, const QJniObject &targetUuid,
462 const QBluetoothUuid &qtTargetUuid)
463{
464 Q_UNUSED(targetUuid);
465 Q_Q(QBluetoothSocket);
466
467 // test we didn't get a fail from a previous connect
468 // which was cleaned up late - should be same socket
469 if (socket != socketObject)
470 return;
471
473 errorString = QBluetoothSocket::tr("Connection to service failed");
477 qCWarning(QT_BT_ANDROID) << "Socket connect workaround failed";
478 }
479}
480
482 const QJniObject &socket, const QJniObject &targetUuid)
483{
484 Q_UNUSED(targetUuid);
485 Q_Q(QBluetoothSocket);
486
487 // test we didn't get a fail from a previous connect
488 // which was cleaned up late - should be same socket
489 if (socket != socketObject)
490 return;
491
492 qCWarning(QT_BT_ANDROID) << "Socket connect via workaround failed.";
493 errorString = QBluetoothSocket::tr("Connection to service failed");
495
498}
499
501{
503 return;
504
505 if (socketObject.isValid()) {
506 QJniEnvironment env;
507
508 /*
509 * BluetoothSocket.close() triggers an abort of the input stream
510 * thread because inputStream.read() throws IOException
511 * In turn the thread stops and throws an error which sets
512 * new state, error and emits relevant signals.
513 * See QBluetoothSocketPrivateAndroid::inputThreadError() for details
514 */
515
516 if (inputThread)
518
520
522
523 if (inputThread) {
524 // inputThread exists hence we had a successful connect
525 // which means inputThread is responsible for setting Unconnected
526
527 //don't delete here as signals caused by Java Thread are still
528 //going to be emitted
529 //delete occurs in inputThreadError()
530 inputThread = 0;
531 } else {
532 // inputThread doesn't exist hence
533 // we abort in the middle of connect(). WorkerThread will do
534 // close() without further feedback. Therefore we have to set
535 // Unconnected (now) in advance
536 Q_Q(QBluetoothSocket);
537 q->setOpenMode(QIODevice::NotOpen);
539 emit q->readChannelFinished();
540 }
541 }
542}
543
545{
547 qCWarning(QT_BT_ANDROID) << "Bluetooth socket localName() failed due to"
548 "missing permissions";
549 } else if (adapter.isValid()) {
550 return adapter.callMethod<jstring>("getName").toString();
551 }
552
553 return QString();
554}
555
557{
559
561 qCWarning(QT_BT_ANDROID) << "Bluetooth socket localAddress() failed due to"
562 "missing permissions";
563 } else if (adapter.isValid()) {
564 result = adapter.callMethod<jstring>("getAddress").toString();
565 }
566
568}
569
571{
572 // Impossible to get channel number with current Android API (Levels 5 to 19)
573 return 0;
574}
575
577{
578 if (!remoteDevice.isValid())
579 return QString();
580
581 return remoteDevice.callMethod<jstring>("getName").toString();
582}
583
585{
586 if (!remoteDevice.isValid())
587 return QBluetoothAddress();
588
589 const QString address = remoteDevice.callMethod<jstring>("getAddress").toString();
591}
592
594{
595 // Impossible to get channel number with current Android API (Levels 5 to 13)
596 return 0;
597}
598
600{
601 //TODO implement buffered behavior (so far only unbuffered)
602 Q_Q(QBluetoothSocket);
604 qCWarning(QT_BT_ANDROID) << "Socket::writeData: " << state << outputStream.isValid();
605 errorString = QBluetoothSocket::tr("Cannot write while not connected");
607 return -1;
608 }
609
610 QJniEnvironment env;
611 jbyteArray nativeData = env->NewByteArray((qint32)maxSize);
612 env->SetByteArrayRegion(nativeData, 0, (qint32)maxSize, reinterpret_cast<const jbyte*>(data));
613 auto methodId = env.findMethod(outputStream.objectClass(),
614 "write",
615 "([BII)V");
616 if (methodId)
617 env->CallVoidMethod(outputStream.object(), methodId, nativeData, 0, (qint32)maxSize);
618 env->DeleteLocalRef(nativeData);
619
620 if (!methodId || env.checkAndClearExceptions()) {
621 qCWarning(QT_BT_ANDROID) << "Error while writing";
622 errorString = QBluetoothSocket::tr("Error during write on socket.");
624 return -1;
625 }
626
627 emit q->bytesWritten(maxSize);
628 return maxSize;
629}
630
632{
633 Q_Q(QBluetoothSocket);
635 qCWarning(QT_BT_ANDROID) << "Socket::readData: " << state << inputThread ;
636 errorString = QBluetoothSocket::tr("Cannot read while not connected");
638 return -1;
639 }
640
641 return inputThread->readData(data, maxSize);
642}
643
645{
646 Q_Q(QBluetoothSocket);
647
648 if (errorCode != -1) { //magic error which is expected and can be ignored
649 errorString = QBluetoothSocket::tr("Network error during read");
651 }
652
653 //finally we can delete the InputStreamThread
654 InputStreamThread *client = qobject_cast<InputStreamThread *>(sender());
655 if (client)
656 client->deleteLater();
657
658 if (socketObject.isValid()) {
659 //triggered when remote side closed the socket
660 //cleanup internal objects
661 //if it was call to local close()/abort() the objects are cleaned up already
662
664
666 if (inputThread) {
667 // deleted already above (client->deleteLater())
668 inputThread = 0;
669 }
670 }
671
672 q->setOpenMode(QIODevice::NotOpen);
674 emit q->readChannelFinished();
675}
676
678{
679 /* This function is called by QBluetoothSocket::close and softer version
680 QBluetoothSocket::disconnectFromService() which difference I do not quite fully understand.
681 Anyways we end up in Android "close" function call.
682 */
683 abort();
684}
685
687 QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode)
688{
689 Q_UNUSED(socketDescriptor);
691 Q_UNUSED(socketState);
693 qCWarning(QT_BT_ANDROID) << "No socket descriptor support on Android.";
694 return false;
695}
696
698 QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode)
699{
700 Q_Q(QBluetoothSocket);
701
702 if (q->state() != QBluetoothSocket::SocketState::UnconnectedState || !socket.isValid())
703 return false;
704
705 if (!ensureNativeSocket(socketType_))
706 return false;
707
709
710 inputStream = socketObject.callMethod<QtJniTypes::InputStream>("getInputStream");
711 outputStream = socketObject.callMethod<QtJniTypes::OutputStream>("getOutputStream");
712
713 if (!inputStream.isValid() || !outputStream.isValid()) {
714
715 //close socket again
716 socketObject.callMethod<void>("close");
717
719
720
721 errorString = QBluetoothSocket::tr("Obtaining streams for service failed");
724 return false;
725 }
726
727 remoteDevice = socketObject.callMethod<QtJniTypes::BluetoothDevice>("getRemoteDevice");
728
729 if (inputThread) {
731 inputThread = 0;
732 }
733 inputThread = new InputStreamThread(this);
734 QObject::connect(inputThread, SIGNAL(dataAvailable()),
735 q, SIGNAL(readyRead()), Qt::QueuedConnection);
736 QObject::connect(inputThread, SIGNAL(errorOccurred(int)), this, SLOT(inputThreadError(int)),
738 inputThread->run();
739
740 // WorkerThread manages all sockets for us
741 // When we come through here the socket was already connected by
742 // server socket listener (see QBluetoothServer)
743 // Therefore we only use WorkerThread to potentially close it later on
744 WorkerThread *workerThread = new WorkerThread();
745 workerThread->setupWorker(this, socketObject, QJniObject(), !USE_FALLBACK);
746 workerThread->start();
747
748 q->setOpenMode(openMode | QIODevice::Unbuffered);
749 q->setSocketState(socketState);
750
751 return true;
752}
753
755{
756 //We cannot access buffer directly as it is part of different thread
757 if (inputThread)
758 return inputThread->bytesAvailable();
759
760 return 0;
761}
762
764{
765 return 0; // nothing because always unbuffered
766}
767
768/*
769 * This function is part of a workaround for QTBUG-61392
770 *
771 * Returns null uuid if the given \a serviceUuid is not a uuid
772 * derived from the Bluetooth base uuid.
773 */
775{
776 if (serviceUuid.isNull())
777 return QBluetoothUuid();
778
779 bool isBaseUuid = false;
780 serviceUuid.toUInt32(&isBaseUuid);
781 if (isBaseUuid)
782 return serviceUuid;
783
784 const QUuid::Id128Bytes original = serviceUuid.toBytes();
785 QUuid::Id128Bytes reversed;
786 for (int i = 0; i < 16; i++)
787 reversed.data[15-i] = original.data[i];
788 return QBluetoothUuid{reversed};
789}
790
792{
793 // We cannot access buffer directly as it is part of different thread
794 if (inputThread)
795 return inputThread->canReadLine();
796
797 return false;
798}
799
801
802#include <qbluetoothsocket_android.moc>
QJniObject getDefaultBluetoothAdapter()
QT_BEGIN_NAMESPACE bool ensureAndroidPermission(QBluetoothPermission::CommunicationModes modes)
qint64 bytesAvailable() const
qint64 readData(char *data, qint64 maxSize)
\inmodule QtBluetooth
\inmodule QtBluetooth
Protocol
This enum describes the socket protocol used by the service.
QBluetoothSocket::OpenMode openMode
QBluetooth::SecurityFlags secFlags
QBluetoothServiceInfo::Protocol socketType
QBluetoothSocket::SocketState state
void defaultSocketConnectFailed(const QJniObject &socket, const QJniObject &targetUuid, const QBluetoothUuid &qtTargetUuid)
void connectToServiceHelper(const QBluetoothAddress &address, const QBluetoothUuid &uuid, QIODevice::OpenMode openMode) override
static QBluetoothUuid reverseUuid(const QBluetoothUuid &serviceUuid)
bool ensureNativeSocket(QBluetoothServiceInfo::Protocol type) override
QBluetoothAddress peerAddress() const override
void fallbackSocketConnectFailed(const QJniObject &socket, const QJniObject &targetUuid)
bool setSocketDescriptor(const QJniObject &socket, QBluetoothServiceInfo::Protocol socketType, QBluetoothSocket::SocketState socketState=QBluetoothSocket::SocketState::ConnectedState, QBluetoothSocket::OpenMode openMode=QBluetoothSocket::ReadWrite) override
QBluetoothAddress localAddress() const override
void connectToService(const QBluetoothServiceInfo &service, QIODevice::OpenMode openMode) override
void socketConnectSuccess(const QJniObject &socket)
qint64 writeData(const char *data, qint64 maxSize) override
qint64 readData(char *data, qint64 maxSize) override
bool fallBackReversedConnect(const QBluetoothUuid &uuid)
\inmodule QtBluetooth
SocketState
This enum describes the state of the Bluetooth socket.
\inmodule QtBluetooth
quint32 toUInt32(bool *ok=nullptr) const
Returns the 32 bit representation of this UUID.
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition qobject.cpp:2658
QScopedPointer< QObjectData > d_ptr
Definition qobject.h:373
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
Definition qobject.cpp:1643
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8870
void start(Priority=InheritPriority)
Definition qthread.cpp:996
static QThread * currentThread()
Definition qthread.cpp:1039
void finished(QPrivateSignal)
@ WithoutBraces
Definition quuid.h:54
QString toString(StringFormat mode=WithBraces) const
Definition quuid.cpp:650
Id128Bytes toBytes(QSysInfo::Endian order=QSysInfo::BigEndian) const noexcept
Definition quuid.h:232
bool isNull() const noexcept
Returns true if this is the null UUID {00000000-0000-0000-0000-000000000000}; otherwise returns false...
Definition quuid.cpp:818
SocketConnectWorker(const QJniObject &socket, const QJniObject &targetUuid, const QBluetoothUuid &qtTargetUuid)
void socketConnectFailed(const QJniObject &socket, const QJniObject &targetUuid, const QBluetoothUuid &qtUuid)
void socketConnectDone(const QJniObject &socket)
void setupWorker(QBluetoothSocketPrivateAndroid *d_ptr, const QJniObject &socketObject, const QJniObject &uuidObject, bool useFallback, const QBluetoothUuid &qtUuid=QBluetoothUuid())
Combined button and popup list for selecting options.
@ QueuedConnection
#define USE_FALLBACK
Q_BLUETOOTH_EXPORT bool useReverseUuidWorkAroundConnect
bool useReverseUuidWorkAroundConnect
EGLOutputPortEXT port
static QT_BEGIN_NAMESPACE const char * socketType(QSocketNotifier::Type type)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint GLuint64EXT address
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
#define tr(X)
#define Q_OBJECT
#define slots
#define signals
#define emit
#define Q_UNUSED(x)
unsigned short quint16
Definition qtypes.h:48
int qint32
Definition qtypes.h:49
long long qint64
Definition qtypes.h:60
QTcpSocket * socket
[1]
char * toString(const MyType &t)
[31]
\inmodule QtCore
Definition quuid.h:58
quint8 data[16]
Definition quuid.h:59