12#include <QCoreApplication>
13#include <QtCore/QLoggingCategory>
14#include <QtCore/QThread>
15#include <QtCore/QTime>
16#include <QtCore/QJniEnvironment>
22#define USE_FALLBACK true
51 mTargetUuid(targetUuid),
52 mQtTargetUuid(qtTargetUuid)
54 static int t = qRegisterMetaType<QJniObject>();
68 qCDebug(QT_BT_ANDROID) <<
"Connecting socket";
69 auto methodId = env.findMethod(mSocketObject.objectClass(),
"connect",
"()V");
71 env->CallVoidMethod(mSocketObject.object(), methodId);
72 if (!methodId || env.checkAndClearExceptions()) {
78 qCDebug(QT_BT_ANDROID) <<
"Socket connection established";
84 qCDebug(QT_BT_ANDROID) <<
"Executing queued closeSocket()";
86 mSocketObject.callMethod<
void>(
"close");
108 const QJniObject& uuidObject,
bool useFallback,
112 socketObject, uuidObject, qtUuid);
131 workerPointer = worker;
144 qRegisterMetaType<QBluetoothSocket::SocketError>();
145 qRegisterMetaType<QBluetoothSocket::SocketState>();
171 qCWarning(QT_BT_ANDROID) <<
"Falling back to reverse uuid workaround.";
179 const QJniObject inputString = QJniObject::fromString(tempUuid);
180 const QJniObject uuidObject = QJniObject::callStaticMethod<QtJniTypes::UUID>(
181 QtJniTypes::className<QtJniTypes::UUID>(),
"fromString",
182 inputString.object<jstring>());
185 qCDebug(QT_BT_ANDROID) <<
"Connecting via insecure rfcomm";
187 "createInsecureRfcommSocketToServiceRecord",
188 uuidObject.object<QtJniTypes::UUID>());
190 qCDebug(QT_BT_ANDROID) <<
"Connecting via secure rfcomm";
192 "createRfcommSocketToServiceRecord",
193 uuidObject.object<QtJniTypes::UUID>());
198 errorString = QBluetoothSocket::tr(
"Cannot connect to %1",
207 workerThread->
start();
232 QIODevice::OpenMode openMode)
240 qCWarning(QT_BT_ANDROID) <<
"Bluetooth socket connect failed due to missing permissions";
242 "Bluetooth socket connect failed due to missing permissions.");
251 qCWarning(QT_BT_ANDROID) <<
"Device does not support Bluetooth";
252 errorString = QBluetoothSocket::tr(
"Device does not support Bluetooth");
260 qCWarning(QT_BT_ANDROID) <<
"Bluetooth device offline";
261 errorString = QBluetoothSocket::tr(
"Device is powered off");
270 inputString.object<jstring>());
272 errorString = QBluetoothSocket::tr(
"Cannot access address %1",
"%1 = Bt address e.g. 11:22:33:44:55:66").
arg(
address.toString());
281 inputString = QJniObject::fromString(tempUuid);
282 const QJniObject uuidObject = QJniObject::callStaticMethod<QtJniTypes::UUID>(
283 QtJniTypes::className<QtJniTypes::UUID>(),
"fromString",
284 inputString.object<jstring>());
287 qCDebug(QT_BT_ANDROID) <<
"Connecting via insecure rfcomm";
289 "createInsecureRfcommSocketToServiceRecord",
290 uuidObject.object<QtJniTypes::UUID>());
292 qCDebug(QT_BT_ANDROID) <<
"Connecting via secure rfcomm";
294 "createRfcommSocketToServiceRecord",
295 uuidObject.object<QtJniTypes::UUID>());
300 errorString = QBluetoothSocket::tr(
"Cannot connect to %1 on %2",
309 workerThread->
start();
320 qCWarning(QT_BT_ANDROID) <<
"QBluetoothSocketPrivateAndroid::connectToService called on busy socket";
321 errorString = QBluetoothSocket::tr(
"Trying to connect while connection is in progress");
341 auto protocol = service.socketProtocol();
345 qCWarning(QT_BT_ANDROID) <<
"Changing socket protocol to RFCOMM";
353 errorString = QBluetoothSocket::tr(
"Socket type not supported");
362 QIODevice::OpenMode openMode)
367 qCWarning(QT_BT_ANDROID) <<
"QBluetoothSocketPrivateAndroid::connectToService called on busy socket";
368 errorString = QBluetoothSocket::tr(
"Trying to connect while connection is in progress");
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");
382 errorString = QBluetoothSocket::tr(
"Socket type not supported");
400 qCWarning(QT_BT_ANDROID) <<
"Connecting to port is not supported";
427 errorString = QBluetoothSocket::tr(
"Obtaining streams for service failed");
448 errorString = QBluetoothSocket::tr(
"Input stream thread cannot be started");
473 errorString = QBluetoothSocket::tr(
"Connection to service failed");
477 qCWarning(QT_BT_ANDROID) <<
"Socket connect workaround failed";
492 qCWarning(QT_BT_ANDROID) <<
"Socket connect via workaround failed.";
493 errorString = QBluetoothSocket::tr(
"Connection to service failed");
539 emit q->readChannelFinished();
547 qCWarning(QT_BT_ANDROID) <<
"Bluetooth socket localName() failed due to"
548 "missing permissions";
549 }
else if (
adapter.isValid()) {
561 qCWarning(QT_BT_ANDROID) <<
"Bluetooth socket localAddress() failed due to"
562 "missing permissions";
563 }
else if (
adapter.isValid()) {
605 errorString = QBluetoothSocket::tr(
"Cannot write while not connected");
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(),
618 env->DeleteLocalRef(nativeData);
620 if (!methodId || env.checkAndClearExceptions()) {
621 qCWarning(QT_BT_ANDROID) <<
"Error while writing";
622 errorString = QBluetoothSocket::tr(
"Error during write on socket.");
627 emit q->bytesWritten(maxSize);
636 errorString = QBluetoothSocket::tr(
"Cannot read while not connected");
648 if (errorCode != -1) {
649 errorString = QBluetoothSocket::tr(
"Network error during read");
674 emit q->readChannelFinished();
693 qCWarning(QT_BT_ANDROID) <<
"No socket descriptor support on Android.";
721 errorString = QBluetoothSocket::tr(
"Obtaining streams for service failed");
746 workerThread->
start();
749 q->setSocketState(socketState);
779 bool isBaseUuid =
false;
786 for (
int i = 0;
i < 16;
i++)
802#include <qbluetoothsocket_android.moc>
QJniObject getDefaultBluetoothAdapter()
QT_BEGIN_NAMESPACE bool ensureAndroidPermission(QBluetoothPermission::CommunicationModes modes)
Protocol
This enum describes the socket protocol used by the service.
QBluetoothSocket::OpenMode openMode
QBluetooth::SecurityFlags secFlags
QBluetoothServiceInfo::Protocol socketType
QBluetoothSocket::SocketState state
qint64 bytesToWrite() const override
bool canReadLine() const override
QString localName() const override
void defaultSocketConnectFailed(const QJniObject &socket, const QJniObject &targetUuid, const QBluetoothUuid &qtTargetUuid)
quint16 localPort() const override
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)
quint16 peerPort() const override
bool setSocketDescriptor(const QJniObject &socket, QBluetoothServiceInfo::Protocol socketType, QBluetoothSocket::SocketState socketState=QBluetoothSocket::SocketState::ConnectedState, QBluetoothSocket::OpenMode openMode=QBluetoothSocket::ReadWrite) override
QString peerName() const override
QBluetoothAddress localAddress() const override
QBluetoothSocketPrivateAndroid()
InputStreamThread * inputThread
void connectToService(const QBluetoothServiceInfo &service, QIODevice::OpenMode openMode) override
void inputThreadError(int errorCode)
qint64 bytesAvailable() const override
void socketConnectSuccess(const QJniObject &socket)
qint64 writeData(const char *data, qint64 maxSize) override
~QBluetoothSocketPrivateAndroid() override
qint64 readData(char *data, qint64 maxSize) override
bool fallBackReversedConnect(const QBluetoothUuid &uuid)
SocketState
This enum describes the state of the Bluetooth socket.
@ MissingPermissionsError
@ UnsupportedProtocolError
quint32 toUInt32(bool *ok=nullptr) const
Returns the 32 bit representation of this UUID.
void moveToThread(QThread *thread)
Changes the thread affinity for this object and its children.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
QScopedPointer< QObjectData > d_ptr
void deleteLater()
\threadsafe
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
void start(Priority=InheritPriority)
static QThread * currentThread()
void finished(QPrivateSignal)
QString toString(StringFormat mode=WithBraces) const
Id128Bytes toBytes(QSysInfo::Endian order=QSysInfo::BigEndian) const noexcept
bool isNull() const noexcept
Returns true if this is the null UUID {00000000-0000-0000-0000-000000000000}; otherwise returns false...
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.
Q_BLUETOOTH_EXPORT bool useReverseUuidWorkAroundConnect
bool useReverseUuidWorkAroundConnect
static QT_BEGIN_NAMESPACE const char * socketType(QSocketNotifier::Type type)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLuint64EXT address
GLdouble GLdouble GLdouble GLdouble q
char * toString(const MyType &t)
[31]