summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/qbluetoothsocket_android.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bluetooth/qbluetoothsocket_android.cpp')
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp156
1 files changed, 109 insertions, 47 deletions
diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp
index d0b901ae..9047bb31 100644
--- a/src/bluetooth/qbluetoothsocket_android.cpp
+++ b/src/bluetooth/qbluetoothsocket_android.cpp
@@ -39,8 +39,10 @@
****************************************************************************/
#include "qbluetoothsocket.h"
-#include "qbluetoothsocket_p.h"
+#include "qbluetoothsocket_android_p.h"
#include "qbluetoothaddress.h"
+#include "qbluetoothdeviceinfo.h"
+#include "qbluetoothserviceinfo.h"
#include <QtCore/QLoggingCategory>
#include <QtCore/QThread>
#include <QtCore/QTime>
@@ -148,8 +150,8 @@ public:
{
}
- // Runs in same thread as QBluetoothSocketPrivate
- void setupWorker(QBluetoothSocketPrivate* d_ptr, const QAndroidJniObject& socketObject,
+ // Runs in same thread as QBluetoothSocketPrivateAndroid
+ void setupWorker(QBluetoothSocketPrivateAndroid* d_ptr, const QAndroidJniObject& socketObject,
const QAndroidJniObject& uuidObject, bool useFallback,
const QBluetoothUuid& qtUuid = QBluetoothUuid())
{
@@ -159,18 +161,18 @@ public:
connect(this, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &QThread::finished, this, &QObject::deleteLater);
- connect(d_ptr, &QBluetoothSocketPrivate::connectJavaSocket,
+ connect(d_ptr, &QBluetoothSocketPrivateAndroid::connectJavaSocket,
worker, &SocketConnectWorker::connectSocket);
- connect(d_ptr, &QBluetoothSocketPrivate::closeJavaSocket,
+ connect(d_ptr, &QBluetoothSocketPrivateAndroid::closeJavaSocket,
worker, &SocketConnectWorker::closeSocket);
connect(worker, &SocketConnectWorker::socketConnectDone,
- d_ptr, &QBluetoothSocketPrivate::socketConnectSuccess);
+ d_ptr, &QBluetoothSocketPrivateAndroid::socketConnectSuccess);
if (useFallback) {
connect(worker, &SocketConnectWorker::socketConnectFailed,
- d_ptr, &QBluetoothSocketPrivate::fallbackSocketConnectFailed);
+ d_ptr, &QBluetoothSocketPrivateAndroid::fallbackSocketConnectFailed);
} else {
connect(worker, &SocketConnectWorker::socketConnectFailed,
- d_ptr, &QBluetoothSocketPrivate::defaultSocketConnectFailed);
+ d_ptr, &QBluetoothSocketPrivateAndroid::defaultSocketConnectFailed);
}
workerPointer = worker;
@@ -204,16 +206,11 @@ static QBluetoothUuid reverseUuid(const QBluetoothUuid &serviceUuid)
return QBluetoothUuid(reversed);
}
-QBluetoothSocketPrivate::QBluetoothSocketPrivate()
- : socket(-1),
- socketType(QBluetoothServiceInfo::UnknownProtocol),
- state(QBluetoothSocket::UnconnectedState),
- socketError(QBluetoothSocket::NoSocketError),
- connecting(false),
- discoveryAgent(0),
- secFlags(QBluetooth::Secure),
+QBluetoothSocketPrivateAndroid::QBluetoothSocketPrivateAndroid()
+ :
inputThread(0)
{
+ secFlags = QBluetooth::Secure;
adapter = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter",
"getDefaultAdapter",
"()Landroid/bluetooth/BluetoothAdapter;");
@@ -221,13 +218,13 @@ QBluetoothSocketPrivate::QBluetoothSocketPrivate()
qRegisterMetaType<QBluetoothSocket::SocketState>();
}
-QBluetoothSocketPrivate::~QBluetoothSocketPrivate()
+QBluetoothSocketPrivateAndroid::~QBluetoothSocketPrivateAndroid()
{
if (state != QBluetoothSocket::UnconnectedState)
emit closeJavaSocket();
}
-bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothServiceInfo::Protocol type)
+bool QBluetoothSocketPrivateAndroid::ensureNativeSocket(QBluetoothServiceInfo::Protocol type)
{
socketType = type;
if (socketType == QBluetoothServiceInfo::RfcommProtocol)
@@ -236,7 +233,7 @@ bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothServiceInfo::Protocol
return false;
}
-bool QBluetoothSocketPrivate::fallBackConnect(QAndroidJniObject uuid, int channel)
+bool QBluetoothSocketPrivateAndroid::fallBackConnect(QAndroidJniObject uuid, int channel)
{
qCWarning(QT_BT_ANDROID) << "Falling back to getServiceChannel() workaround.";
@@ -355,7 +352,7 @@ bool QBluetoothSocketPrivate::fallBackConnect(QAndroidJniObject uuid, int channe
/*
* Workaround for QTBUG-61392
*/
-bool QBluetoothSocketPrivate::fallBackReversedConnect(const QBluetoothUuid &uuid)
+bool QBluetoothSocketPrivateAndroid::fallBackReversedConnect(const QBluetoothUuid &uuid)
{
Q_Q(QBluetoothSocket);
@@ -408,31 +405,31 @@ bool QBluetoothSocketPrivate::fallBackReversedConnect(const QBluetoothUuid &uuid
}
/*
- * The call order during a connectToService() is as follows:
+ * The call order during a connectToServiceHelper() is as follows:
*
- * 1. call connectToService()
+ * 1. call connectToServiceHelper()
* 2. wait for execution of SocketConnectThread::run()
* 3. if threaded connect succeeds call socketConnectSuccess() via signals
* -> done
* 4. if threaded connect fails call defaultSocketConnectFailed() via signals
* 5. call fallBackConnect() if Android version 22 or below
- * -> Android 23+ complete failure of entire connectToService()
+ * -> Android 23+ complete failure of entire connectToServiceHelper()
* 6. call fallBackReversedConnect() if Android version 23 or above
- * -> if failure entire connectToService() fails
+ * -> if failure entire connectToServiceHelper() fails
* 7. if threaded connect on one of above fallbacks succeeds call socketConnectSuccess()
* via signals
* -> done
* 8. if threaded connect on fallback channel fails call fallbackSocketConnectFailed()
- * -> complete failure of entire connectToService()
+ * -> complete failure of entire connectToServiceHelper()
* */
-void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address,
+void QBluetoothSocketPrivateAndroid::connectToServiceHelper(const QBluetoothAddress &address,
const QBluetoothUuid &uuid,
QIODevice::OpenMode openMode)
{
Q_Q(QBluetoothSocket);
Q_UNUSED(openMode);
- qCDebug(QT_BT_ANDROID) << "connectToService()" << address.toString() << uuid.toString();
+ qCDebug(QT_BT_ANDROID) << "connectToServiceHelper()" << address.toString() << uuid.toString();
q->setSocketState(QBluetoothSocket::ConnectingState);
@@ -508,7 +505,71 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address,
emit connectJavaSocket();
}
-void QBluetoothSocketPrivate::socketConnectSuccess(const QAndroidJniObject &socket)
+void QBluetoothSocketPrivateAndroid::connectToService(
+ const QBluetoothServiceInfo &service, QIODevice::OpenMode openMode)
+{
+ Q_Q(QBluetoothSocket);
+
+ if (q->state() != QBluetoothSocket::UnconnectedState
+ && q->state() != QBluetoothSocket::ServiceLookupState) {
+ qCWarning(QT_BT_ANDROID) << "QBluetoothSocketPrivateAndroid::connectToService called on busy socket";
+ errorString = QBluetoothSocket::tr("Trying to connect while connection is in progress");
+ q->setSocketError(QBluetoothSocket::OperationError);
+ return;
+ }
+
+ if (!ensureNativeSocket(service.socketProtocol())) {
+ errorString = QBluetoothSocket::tr("Socket type not supported");
+ q->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+ connectToServiceHelper(service.device().address(), service.serviceUuid(), openMode);
+}
+
+void QBluetoothSocketPrivateAndroid::connectToService(
+ const QBluetoothAddress &address, const QBluetoothUuid &uuid,
+ QIODevice::OpenMode openMode)
+{
+ Q_Q(QBluetoothSocket);
+
+ if (q->state() != QBluetoothSocket::UnconnectedState) {
+ qCWarning(QT_BT_ANDROID) << "QBluetoothSocketPrivateAndroid::connectToService called on busy socket";
+ errorString = QBluetoothSocket::tr("Trying to connect while connection is in progress");
+ q->setSocketError(QBluetoothSocket::OperationError);
+ return;
+ }
+
+ if (q->socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT_ANDROID) << "QBluetoothSocketPrivateAndroid::connectToService cannot "
+ "connect with 'UnknownProtocol' (type provided by given service)";
+ errorString = QBluetoothSocket::tr("Socket type not supported");
+ q->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
+ if (!ensureNativeSocket(q->socketType())) {
+ errorString = QBluetoothSocket::tr("Socket type not supported");
+ q->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+ connectToServiceHelper(address, uuid, openMode);
+}
+
+void QBluetoothSocketPrivateAndroid::connectToService(
+ const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode)
+{
+ Q_UNUSED(port);
+ Q_UNUSED(openMode);
+ Q_UNUSED(address);
+
+ Q_Q(QBluetoothSocket);
+
+ errorString = tr("Connecting to port is not supported");
+ q->setSocketError(QBluetoothSocket::ServiceNotFoundError);
+ qCWarning(QT_BT_ANDROID) << "Connecting to port is not supported";
+}
+
+void QBluetoothSocketPrivateAndroid::socketConnectSuccess(const QAndroidJniObject &socket)
{
Q_Q(QBluetoothSocket);
QAndroidJniEnvironment env;
@@ -568,7 +629,7 @@ void QBluetoothSocketPrivate::socketConnectSuccess(const QAndroidJniObject &sock
emit q->connected();
}
-void QBluetoothSocketPrivate::defaultSocketConnectFailed(
+void QBluetoothSocketPrivateAndroid::defaultSocketConnectFailed(
const QAndroidJniObject &socket, const QAndroidJniObject &targetUuid,
const QBluetoothUuid &qtTargetUuid)
{
@@ -597,7 +658,7 @@ void QBluetoothSocketPrivate::defaultSocketConnectFailed(
}
}
-void QBluetoothSocketPrivate::fallbackSocketConnectFailed(
+void QBluetoothSocketPrivateAndroid::fallbackSocketConnectFailed(
const QAndroidJniObject &socket, const QAndroidJniObject &targetUuid)
{
Q_UNUSED(targetUuid);
@@ -616,7 +677,7 @@ void QBluetoothSocketPrivate::fallbackSocketConnectFailed(
q->setSocketState(QBluetoothSocket::UnconnectedState);
}
-void QBluetoothSocketPrivate::abort()
+void QBluetoothSocketPrivateAndroid::abort()
{
if (state == QBluetoothSocket::UnconnectedState)
return;
@@ -629,7 +690,7 @@ void QBluetoothSocketPrivate::abort()
* thread because inputStream.read() throws IOException
* In turn the thread stops and throws an error which sets
* new state, error and emits relevant signals.
- * See QBluetoothSocketPrivate::inputThreadError() for details
+ * See QBluetoothSocketPrivateAndroid::inputThreadError() for details
*/
if (inputThread)
@@ -658,7 +719,7 @@ void QBluetoothSocketPrivate::abort()
}
}
-QString QBluetoothSocketPrivate::localName() const
+QString QBluetoothSocketPrivateAndroid::localName() const
{
if (adapter.isValid())
return adapter.callObjectMethod<jstring>("getName").toString();
@@ -666,7 +727,7 @@ QString QBluetoothSocketPrivate::localName() const
return QString();
}
-QBluetoothAddress QBluetoothSocketPrivate::localAddress() const
+QBluetoothAddress QBluetoothSocketPrivateAndroid::localAddress() const
{
QString result;
if (adapter.isValid())
@@ -675,13 +736,13 @@ QBluetoothAddress QBluetoothSocketPrivate::localAddress() const
return QBluetoothAddress(result);
}
-quint16 QBluetoothSocketPrivate::localPort() const
+quint16 QBluetoothSocketPrivateAndroid::localPort() const
{
// Impossible to get channel number with current Android API (Levels 5 to 19)
return 0;
}
-QString QBluetoothSocketPrivate::peerName() const
+QString QBluetoothSocketPrivateAndroid::peerName() const
{
if (!remoteDevice.isValid())
return QString();
@@ -689,7 +750,7 @@ QString QBluetoothSocketPrivate::peerName() const
return remoteDevice.callObjectMethod("getName", "()Ljava/lang/String;").toString();
}
-QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const
+QBluetoothAddress QBluetoothSocketPrivateAndroid::peerAddress() const
{
if (!remoteDevice.isValid())
return QBluetoothAddress();
@@ -700,13 +761,13 @@ QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const
return QBluetoothAddress(address);
}
-quint16 QBluetoothSocketPrivate::peerPort() const
+quint16 QBluetoothSocketPrivateAndroid::peerPort() const
{
// Impossible to get channel number with current Android API (Levels 5 to 13)
return 0;
}
-qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
+qint64 QBluetoothSocketPrivateAndroid::writeData(const char *data, qint64 maxSize)
{
//TODO implement buffered behavior (so far only unbuffered)
Q_Q(QBluetoothSocket);
@@ -736,7 +797,7 @@ qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
return maxSize;
}
-qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize)
+qint64 QBluetoothSocketPrivateAndroid::readData(char *data, qint64 maxSize)
{
Q_Q(QBluetoothSocket);
if (state != QBluetoothSocket::ConnectedState || !inputThread) {
@@ -749,7 +810,7 @@ qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize)
return inputThread->readData(data, maxSize);
}
-void QBluetoothSocketPrivate::inputThreadError(int errorCode)
+void QBluetoothSocketPrivateAndroid::inputThreadError(int errorCode)
{
Q_Q(QBluetoothSocket);
@@ -779,10 +840,11 @@ void QBluetoothSocketPrivate::inputThreadError(int errorCode)
q->setSocketState(QBluetoothSocket::UnconnectedState);
q->setOpenMode(QIODevice::NotOpen);
+ emit q->readChannelFinished();
emit q->disconnected();
}
-void QBluetoothSocketPrivate::close()
+void QBluetoothSocketPrivateAndroid::close()
{
/* This function is called by QBluetoothSocket::close and softer version
QBluetoothSocket::disconnectFromService() which difference I do not quite fully understand.
@@ -791,7 +853,7 @@ void QBluetoothSocketPrivate::close()
abort();
}
-bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
+bool QBluetoothSocketPrivateAndroid::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode)
{
Q_UNUSED(socketDescriptor);
@@ -802,7 +864,7 @@ bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoo
return false;
}
-bool QBluetoothSocketPrivate::setSocketDescriptor(const QAndroidJniObject &socket, QBluetoothServiceInfo::Protocol socketType_,
+bool QBluetoothSocketPrivateAndroid::setSocketDescriptor(const QAndroidJniObject &socket, QBluetoothServiceInfo::Protocol socketType_,
QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode)
{
Q_Q(QBluetoothSocket);
@@ -870,7 +932,7 @@ bool QBluetoothSocketPrivate::setSocketDescriptor(const QAndroidJniObject &socke
return true;
}
-qint64 QBluetoothSocketPrivate::bytesAvailable() const
+qint64 QBluetoothSocketPrivateAndroid::bytesAvailable() const
{
//We cannot access buffer directly as it is part of different thread
if (inputThread)
@@ -879,12 +941,12 @@ qint64 QBluetoothSocketPrivate::bytesAvailable() const
return 0;
}
-qint64 QBluetoothSocketPrivate::bytesToWrite() const
+qint64 QBluetoothSocketPrivateAndroid::bytesToWrite() const
{
return 0; // nothing because always unbuffered
}
-bool QBluetoothSocketPrivate::canReadLine() const
+bool QBluetoothSocketPrivateAndroid::canReadLine() const
{
// We cannot access buffer directly as it is part of different thread
if (inputThread)