Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
serveracceptancethread.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtCore/QLoggingCategory>
5#include <QtCore/QJniEnvironment>
6
7#include "android/serveracceptancethread_p.h"
8#include "android/jni_android_p.h"
9
11
12Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
13
14ServerAcceptanceThread::ServerAcceptanceThread(QObject *parent) :
15 QObject(parent), maxPendingConnections(1)
16{
17 qRegisterMetaType<QBluetoothServer::Error>();
18}
19
21{
22 Q_ASSERT(!isRunning());
23 QMutexLocker lock(&m_mutex);
24 shutdownPendingConnections();
25}
26
27void ServerAcceptanceThread::setServiceDetails(const QBluetoothUuid &uuid,
28 const QString &serviceName,
29 QBluetooth::SecurityFlags securityFlags)
30{
31 QMutexLocker lock(&m_mutex);
32 m_uuid = uuid;
33 m_serviceName = serviceName;
34 secFlags = securityFlags;
35}
36
38{
39 QMutexLocker lock(&m_mutex);
40 return !pendingSockets.isEmpty();
41}
42
43/*
44 * Returns the next pending connection or an invalid JNI object.
45 * Note that even a stopped thread may still have pending
46 * connections. Pending connections are only terminated upon
47 * thread restart or destruction.
48 */
50{
51 QMutexLocker lock(&m_mutex);
52 if (pendingSockets.isEmpty())
53 return QJniObject();
54 else
55 return pendingSockets.takeFirst();
56}
57
59{
60 QMutexLocker lock(&m_mutex);
61 maxPendingConnections = maximumCount;
62}
63
65{
66 QMutexLocker lock(&m_mutex);
67
68 if (!validSetup()) {
69 qCWarning(QT_BT_ANDROID) << "Invalid Server Socket setup";
70 return;
71 }
72
73 if (isRunning()) {
74 stop();
75 shutdownPendingConnections();
76 }
77
78 javaThread = QJniObject::construct<QtJniTypes::QtBtSocketServer>(
79 QNativeInterface::QAndroidApplication::context());
80 if (!javaThread.isValid())
81 return;
82
83 javaThread.setField<jlong>("qtObject", reinterpret_cast<long>(this));
84 javaThread.setField<jboolean>("logEnabled", QT_BT_ANDROID().isDebugEnabled());
85
86 QString tempUuid = m_uuid.toString(QUuid::WithoutBraces);
87
88 QJniObject uuidString = QJniObject::fromString(tempUuid);
89 QJniObject serviceNameString = QJniObject::fromString(m_serviceName);
90 bool isSecure = !(secFlags == QBluetooth::SecurityFlags(QBluetooth::Security::NoSecurity));
91 javaThread.callMethod<void>("setServiceDetails",
92 uuidString.object<jstring>(),
93 serviceNameString.object<jstring>(),
94 isSecure);
95 javaThread.callMethod<void>("start");
96}
97
99{
100 if (javaThread.isValid()) {
101 qCDebug(QT_BT_ANDROID) << "Closing server socket";
102 javaThread.callMethod<void>("close");
103 }
104}
105
107{
108 if (javaThread.isValid())
109 return javaThread.callMethod<jboolean>("isAlive");
110
111 return false;
112}
113
114//Runs inside the java thread
116{
117 qCDebug(QT_BT_ANDROID) << "JavaThread error:" << errorCode;
118 emit errorOccurred(QBluetoothServer::InputOutputError);
119}
120
121//Runs inside the Java thread
123{
124 QMutexLocker lock(&m_mutex);
125
126 QJniObject socket(s);
127 if (!socket.isValid())
128 return;
129
130 if (pendingSockets.size() < maxPendingConnections) {
131 qCDebug(QT_BT_ANDROID) << "New incoming java socket detected";
132 pendingSockets.append(socket);
133 emit newConnection();
134 } else {
135 qCWarning(QT_BT_ANDROID) << "Refusing connection due to limited pending socket queue";
136 socket.callMethod<void>("close");
137 }
138}
139
140bool ServerAcceptanceThread::validSetup() const
141{
142 return (!m_uuid.isNull() && !m_serviceName.isEmpty());
143}
144
145void ServerAcceptanceThread::shutdownPendingConnections()
146{
147 while (!pendingSockets.isEmpty()) {
148 QJniObject socket = pendingSockets.takeFirst();
149 socket.callMethod<void>("close");
150 }
151}
152
153QT_END_NAMESPACE
void setServiceDetails(const QBluetoothUuid &uuid, const QString &serviceName, QBluetooth::SecurityFlags securityFlags)
void javaNewSocket(jobject socket)
void javaThreadErrorOccurred(int errorCode)
void setMaxPendingConnections(int maximumCount)