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.cpp98
1 files changed, 69 insertions, 29 deletions
diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp
index 93089182..a894fed3 100644
--- a/src/bluetooth/qbluetoothsocket_android.cpp
+++ b/src/bluetooth/qbluetoothsocket_android.cpp
@@ -97,7 +97,6 @@ void QBluetoothSocketPrivate::connectToServiceConc(const QBluetoothAddress &addr
Q_Q(QBluetoothSocket);
Q_UNUSED(openMode);
- qDebug() << "GGGGConnecting to" << address.toString() << uuid.toString();
if (!adapter.isValid()) {
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
errorString = QBluetoothSocket::tr("Device does not support Bluetooth");
@@ -171,9 +170,7 @@ void QBluetoothSocketPrivate::connectToServiceConc(const QBluetoothAddress &addr
}
if (inputThread) {
- inputThread->stop();
- inputThread->wait();
- delete inputThread;
+ inputThread->deleteLater();
inputThread = 0;
}
@@ -201,10 +198,29 @@ void QBluetoothSocketPrivate::connectToServiceConc(const QBluetoothAddress &addr
}
inputThread = new InputStreamThread(this);
- QObject::connect(inputThread, SIGNAL(dataAvailable()), q, SIGNAL(readyRead()), Qt::QueuedConnection);
+ QObject::connect(inputThread, SIGNAL(dataAvailable()),
+ q, SIGNAL(readyRead()), Qt::QueuedConnection);
QObject::connect(inputThread, SIGNAL(error()),
this, SLOT(inputThreadError()), Qt::QueuedConnection);
- inputThread->start();
+
+ if (!inputThread->run()) {
+ //close socket again
+ socketObject.callMethod<void>("close");
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+
+ socketObject = inputStream = outputStream = remoteDevice = QAndroidJniObject();
+
+ delete inputThread;
+ inputThread = 0;
+
+ errorString = QBluetoothSocket::tr("Input stream thread cannot be started");
+ q->setSocketError(QBluetoothSocket::NetworkError);
+ q->setSocketState(QBluetoothSocket::UnconnectedState);
+ return;
+ }
q->setSocketState(QBluetoothSocket::ConnectedState);
emit q->connected();
@@ -233,6 +249,10 @@ void QBluetoothSocketPrivate::abort()
* new state, error and emits relevant signals.
* See QBluetoothSocketPrivate::inputThreadError() for details
*/
+
+ if (inputThread)
+ inputThread->prepareForClosure();
+
//triggers abort of input thread as well
socketObject.callMethod<void>("close");
if (env->ExceptionCheck()) {
@@ -243,9 +263,9 @@ void QBluetoothSocketPrivate::abort()
}
if (inputThread) {
- inputThread->stop();
- inputThread->wait();
- delete inputThread;
+ //don't delete here as signals caused by Java Thread are still
+ //going to be emitted
+ //delete occurs in inputThreadError()
inputThread = 0;
}
@@ -304,10 +324,9 @@ quint16 QBluetoothSocketPrivate::peerPort() const
qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
{
//TODO implement buffered behavior (so far only unbuffered)
- //TODO check that readData and writeData return -1 on error (on all platforms)
Q_Q(QBluetoothSocket);
if (state != QBluetoothSocket::ConnectedState || !outputStream.isValid()) {
- qCWarning(QT_BT_ANDROID) << "Socket::writeData: " << (int)state << outputStream.isValid() ;
+ qCWarning(QT_BT_ANDROID) << "Socket::writeData: " << state << outputStream.isValid();
errorString = QBluetoothSocket::tr("Cannot write while not connected");
q->setSocketError(QBluetoothSocket::OperationError);
return -1;
@@ -335,8 +354,8 @@ qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize)
{
Q_Q(QBluetoothSocket);
if (state != QBluetoothSocket::ConnectedState || !inputThread) {
- qCWarning(QT_BT_ANDROID) << "Socket::writeData: " << (int)state << outputStream.isValid() ;
- errorString = QBluetoothSocket::tr("Cannot write while not connected");
+ qCWarning(QT_BT_ANDROID) << "Socket::readData: " << state << inputThread ;
+ errorString = QBluetoothSocket::tr("Cannot read while not connected");
q->setSocketError(QBluetoothSocket::OperationError);
return -1;
}
@@ -344,13 +363,38 @@ qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize)
return inputThread->readData(data, maxSize);
}
-void QBluetoothSocketPrivate::inputThreadError()
+void QBluetoothSocketPrivate::inputThreadError(int errorCode)
{
Q_Q(QBluetoothSocket);
- //any error from InputThread is a NetworkError
- errorString = QBluetoothSocket::tr("Network error during read");
- q->setSocketError(QBluetoothSocket::NetworkError);
+ if (errorCode != -1) { //magic error which is expected and can be ignored
+ errorString = QBluetoothSocket::tr("Network error during read");
+ q->setSocketError(QBluetoothSocket::NetworkError);
+ }
+
+ //finally we can delete the InputStreamThread
+ InputStreamThread *client = qobject_cast<InputStreamThread *>(sender());
+ if (client)
+ client->deleteLater();
+
+ if (socketObject.isValid()) {
+ //triggered when remote side closed the socket
+ //cleanup internal objects
+ //if it was call to local close()/abort() the objects are cleaned up already
+
+ bool stillConnected = socketObject.callMethod<jboolean>("isConnected");
+ if (stillConnected) {
+ QAndroidJniEnvironment env;
+ socketObject.callMethod<void>("close");
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ }
+
+ inputStream = outputStream = remoteDevice = socketObject = QAndroidJniObject();
+ }
+
q->setSocketState(QBluetoothSocket::UnconnectedState);
emit q->disconnected();
}
@@ -412,17 +456,18 @@ bool QBluetoothSocketPrivate::setSocketDescriptor(const QAndroidJniObject &socke
return false;
}
+ remoteDevice = socketObject.callObjectMethod("getRemoteDevice", "()Landroid/bluetooth/BluetoothDevice;");
+
if (inputThread) {
- inputThread->stop();
- inputThread->wait();
- delete inputThread;
+ inputThread->deleteLater();
inputThread = 0;
}
inputThread = new InputStreamThread(this);
- QObject::connect(inputThread, SIGNAL(dataAvailable()), q, SIGNAL(readyRead()), Qt::QueuedConnection);
- QObject::connect(inputThread, SIGNAL(error()),
- this, SLOT(inputThreadError()), Qt::QueuedConnection);
- inputThread->start();
+ QObject::connect(inputThread, SIGNAL(dataAvailable()),
+ q, SIGNAL(readyRead()), Qt::QueuedConnection);
+ QObject::connect(inputThread, SIGNAL(error(int)),
+ this, SLOT(inputThreadError(int)), Qt::QueuedConnection);
+ inputThread->run();
q->setSocketState(socketState);
@@ -434,11 +479,6 @@ bool QBluetoothSocketPrivate::setSocketDescriptor(const QAndroidJniObject &socke
return true;
}
-int QBluetoothSocketPrivate::socketDescriptor() const
-{
- return 0;
-}
-
qint64 QBluetoothSocketPrivate::bytesAvailable() const
{
//We cannot access buffer directly as it is part of different thread