Introduce error codes for missing permissions

Some operating systems might request special permissions while working
with Bluetooth. Previously if the permissions were missing, we were
returning an UnknownError, and the error description, when available,
was not very good as well.

[ChangeLog][QtBluetooth] Various error enums are extended with new
error codes that represent missing permissions error. Error descriptions
are also updated, when available.

This patch also applies new error codes to Android implementation.

Fixes: QTBUG-102373
Change-Id: I247371de6b1eb8d39f0f99c50269d2b1f3bf21c2
Reviewed-by: Juha Vuolle <juha.vuolle@insta.fi>
This commit is contained in:
Ivan Solovev 2022-05-11 16:21:41 +02:00
parent 5f249c3d01
commit d58d134d25
19 changed files with 43 additions and 13 deletions

View File

@ -100,6 +100,9 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
\value LocationServiceTurnedOffError The location service is turned off. Usage of
Bluetooth APIs is not possible when location service
is turned off. This value was introduced by Qt 6.2.
\value [since 6.4] MissingPermissionsError The operating system requests
permissions which were not
granted by the user.
\value UnknownError An unknown error has occurred.
*/

View File

@ -66,6 +66,7 @@ public:
UnsupportedPlatformError,
UnsupportedDiscoveryMethod,
LocationServiceTurnedOffError,
MissingPermissionsError,
UnknownError = 100 // New errors must be added before Unknown error
};
Q_ENUM(Error)

View File

@ -148,7 +148,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
"Search not possible due to missing permission (ACCESS_FINE_LOCATION)";
errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Missing Location permission. Search is not possible.");
lastError = QBluetoothDeviceDiscoveryAgent::UnknownError;
lastError = QBluetoothDeviceDiscoveryAgent::MissingPermissionsError;
emit q->errorOccurred(lastError);
return;
}
@ -193,8 +193,9 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
if (!(ensureAndroidPermission(BluetoothPermission::Scan) &&
ensureAndroidPermission(BluetoothPermission::Connect))) {
qCWarning(QT_BT_ANDROID) << "Device discovery start() failed due to missing permissions";
errorString = QBluetoothDeviceDiscoveryAgent::tr("Bluetooth adapter error");
lastError = QBluetoothDeviceDiscoveryAgent::UnknownError;
errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Failed to start device discovery due to missing permissions.");
lastError = QBluetoothDeviceDiscoveryAgent::MissingPermissionsError;
emit q->errorOccurred(lastError);
return;
}

View File

@ -85,6 +85,9 @@ QT_IMPL_METATYPE_EXTERN_TAGGED(QBluetoothLocalDevice::Error, QBluetoothLocalDevi
\value NoError No known error
\value PairingError Error in pairing
\value [since 6.4] MissingPermissionsError The operating system requests
permissions which were not
granted by the user.
\value UnknownError Unknown error
*/

View File

@ -75,6 +75,7 @@ public:
enum Error {
NoError,
PairingError,
MissingPermissionsError,
UnknownError = 100
};
Q_ENUM(Error)

View File

@ -299,6 +299,7 @@ void QBluetoothLocalDevice::setHostMode(QBluetoothLocalDevice::HostMode requeste
if (!ensureAndroidPermission(BluetoothPermission::Advertise)) {
qCWarning(QT_BT_ANDROID) << "Local device setHostMode() failed due to"
"missing permissions";
emit errorOccurred(QBluetoothLocalDevice::MissingPermissionsError);
return;
}
const bool success = (bool)QJniObject::callStaticMethod<jboolean>(

View File

@ -111,6 +111,9 @@ QT_BEGIN_NAMESPACE
\value ServiceAlreadyRegisteredError The service or port was already registered
\value UnsupportedProtocolError The \l {QBluetoothServiceInfo::Protocol}{Protocol} is not
supported on this platform.
\value [since 6.4] MissingPermissionsError The operating system requests
permissions which were not
granted by the user.
*/
/*!

View File

@ -66,7 +66,8 @@ public:
PoweredOffError,
InputOutputError,
ServiceAlreadyRegisteredError,
UnsupportedProtocolError
UnsupportedProtocolError,
MissingPermissionsError
};
Q_ENUM(Error)

View File

@ -135,7 +135,7 @@ bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 por
if (!ensureAndroidPermission(BluetoothPermission::Connect)) {
qCWarning(QT_BT_ANDROID) << "Bluetooth server listen() failed due to missing permissions";
d->m_lastError = QBluetoothServer::UnknownError;
d->m_lastError = QBluetoothServer::MissingPermissionsError;
emit errorOccurred(d->m_lastError);
return false;
}

View File

@ -102,6 +102,9 @@ QT_BEGIN_NAMESPACE
\value InvalidBluetoothAdapterError The passed local adapter address does not match the physical
adapter address of any local Bluetooth device. This value
was introduced by Qt 5.3.
\value [since 6.4] MissingPermissionsError The operating system requests
permissions which were not
granted by the user.
\value UnknownError An unknown error has occurred.
*/

View File

@ -69,6 +69,7 @@ public:
InputOutputError = QBluetoothDeviceDiscoveryAgent::InputOutputError,
PoweredOffError = QBluetoothDeviceDiscoveryAgent::PoweredOffError,
InvalidBluetoothAdapterError = QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError,
MissingPermissionsError = QBluetoothDeviceDiscoveryAgent::MissingPermissionsError,
UnknownError = QBluetoothDeviceDiscoveryAgent::UnknownError //=100
//New Errors must be added after Unknown Error the space before UnknownError is reserved
//for future device discovery errors

View File

@ -119,8 +119,9 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr
if (!ensureAndroidPermission(BluetoothPermission::Connect)) {
qCWarning(QT_BT_ANDROID) << "Service discovery start() failed due to missing permissions";
error = QBluetoothServiceDiscoveryAgent::UnknownError;
errorString = QBluetoothServiceDiscoveryAgent::tr("Unable to perform SDP scan");
error = QBluetoothServiceDiscoveryAgent::MissingPermissionsError;
errorString = QBluetoothServiceDiscoveryAgent::tr(
"Failed to start service discovery due to missing permissions.");
emit q->errorOccurred(error);
_q_serviceDiscoveryFinished();
return;

View File

@ -131,6 +131,9 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
that did not permit it.
\value RemoteHostClosedError The remote host closed the connection. This value was
introduced by Qt 5.10.
\value [since 6.4] MissingPermissionsError The operating system requests
permissions which were not
granted by the user.
*/
/*!

View File

@ -91,7 +91,8 @@ public:
ServiceNotFoundError,
NetworkError,
UnsupportedProtocolError,
OperationError
OperationError,
MissingPermissionsError
};
Q_ENUM(SocketError)

View File

@ -278,8 +278,9 @@ void QBluetoothSocketPrivateAndroid::connectToServiceHelper(const QBluetoothAddr
if (!ensureAndroidPermission(BluetoothPermission::Connect)) {
qCWarning(QT_BT_ANDROID) << "Bluetooth socket connect failed due to missing permissions";
errorString = QBluetoothSocket::tr("Unknown socket error");
q->setSocketError(QBluetoothSocket::SocketError::UnknownSocketError);
errorString = QBluetoothSocket::tr(
"Bluetooth socket connect failed due to missing permissions.");
q->setSocketError(QBluetoothSocket::SocketError::MissingPermissionsError);
q->setSocketState(QBluetoothSocket::SocketState::UnconnectedState);
return;
}

View File

@ -169,6 +169,9 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
\value AuthorizationError The local Bluetooth device closed the connection due to
insufficient authorization.
This value was introduced by Qt 5.14.
\value [since 6.4] MissingPermissionsError The operating system requests
permissions which were not
granted by the user.
*/
/*!

View File

@ -67,7 +67,8 @@ public:
ConnectionError,
AdvertisingError,
RemoteHostClosedError,
AuthorizationError
AuthorizationError,
MissingPermissionsError
};
Q_ENUM(Error)

View File

@ -145,7 +145,7 @@ void QLowEnergyControllerPrivateAndroid::connectToDevice()
if (!ensureAndroidPermission(BluetoothPermission::Connect)) {
// This is unlikely to happen as a valid local adapter is a precondition
setError(QLowEnergyController::AuthorizationError);
setError(QLowEnergyController::MissingPermissionsError);
qCWarning(QT_BT_ANDROID) << "connectToDevice() failed due to missing permissions";
return;
}
@ -1004,7 +1004,7 @@ void QLowEnergyControllerPrivateAndroid::startAdvertising(const QLowEnergyAdvert
if (!(ensureAndroidPermission(BluetoothPermission::Advertise) &&
ensureAndroidPermission(BluetoothPermission::Connect))) {
qCWarning(QT_BT_ANDROID) << "startAdvertising() failed due to missing permissions";
setError(QLowEnergyController::AdvertisingError);
setError(QLowEnergyController::MissingPermissionsError);
setState(QLowEnergyController::UnconnectedState);
return;
}

View File

@ -489,6 +489,7 @@ void BtLocalDevice::dumpSocketInformation()
case QBluetoothSocket::SocketError::NetworkError: tmp += "NetworkError"; break;
//case QBluetoothSocket::SocketError::OperationError: tmp+= "OperationError"; break;
case QBluetoothSocket::SocketError::UnsupportedProtocolError: tmp += "UnsupportedProtocolError"; break;
case QBluetoothSocket::SocketError::MissingPermissionsError: tmp += "MissingPermissionsError"; break;
default: tmp+= "Undefined"; break;
}
@ -730,6 +731,7 @@ void BtLocalDevice::dumpServerInformation()
case QBluetoothSocket::SocketError::NetworkError: tmp += "NetworkError"; break;
case QBluetoothSocket::SocketError::UnsupportedProtocolError: tmp += "UnsupportedProtocolError"; break;
//case QBluetoothSocket::SocketError::OperationError: tmp+= "OperationError"; break;
case QBluetoothSocket::SocketError::MissingPermissionsError: tmp += "MissingPermissionsError"; break;
default: tmp += QString::number(static_cast<int>(client->error())); break;
}