diff options
Diffstat (limited to 'src')
4 files changed, 100 insertions, 9 deletions
diff --git a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java index 3348e4de..53c7305f 100644 --- a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java +++ b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java @@ -52,6 +52,7 @@ import android.os.Handler; import android.os.Looper; import android.util.Log; import java.util.concurrent.atomic.AtomicInteger; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Hashtable; @@ -60,6 +61,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.UUID; + public class QtBluetoothLE { private static final String TAG = "QtBluetoothGatt"; private final BluetoothAdapter mBluetoothAdapter; @@ -1282,6 +1284,32 @@ public class QtBluetoothLE { return modifiedHandle; } + // Directly called from public Qt API + public boolean requestConnectionUpdatePriority(double minimalInterval) + { + if (mBluetoothGatt == null) + return false; + + try { + //Android API v21 + Method connectionUpdateMethod = mBluetoothGatt.getClass().getDeclaredMethod( + "requestConnectionPriority", int.class); + if (connectionUpdateMethod == null) + return false; + + int requestPriority = 0; // BluetoothGatt.CONNECTION_PRIORITY_BALANCED + if (minimalInterval < 30) + requestPriority = 1; // BluetoothGatt.CONNECTION_PRIORITY_HIGH + else if (minimalInterval > 100) + requestPriority = 2; //BluetoothGatt/CONNECTION_PRIORITY_LOW_POWER + + Object result = connectionUpdateMethod.invoke(mBluetoothGatt, requestPriority); + return (Boolean) result; + } catch (Exception ex) { + return false; + } + } + public native void leConnectionStateChange(long qtObject, int wasErrorTransition, int newState); public native void leServicesDiscovered(long qtObject, int errorCode, String uuidList); public native void leServiceDetailDiscoveryFinished(long qtObject, final String serviceUuid, diff --git a/src/bluetooth/qlowenergyconnectionparameters.cpp b/src/bluetooth/qlowenergyconnectionparameters.cpp index af4502dd..95256402 100644 --- a/src/bluetooth/qlowenergyconnectionparameters.cpp +++ b/src/bluetooth/qlowenergyconnectionparameters.cpp @@ -68,6 +68,32 @@ public: with each other. In general, a lower connection interval and latency means faster communication, but also higher power consumption. How these criteria should be weighed against each other is highly dependent on the concrete use case. + + Android only indirectly permits the adjustment of this parameter set. + The platform separates the connection parameters into three categories (hight, low & balanced + priority). Each category implies a predefined set of values for \l minimumInterval(), + \l maximumInterval() and \l latency(). Additionally, the value ranges of each category can vary + from one Android device to the next. Qt uses the \l minimumInterval() to determine the target + category as follows: + + \table + \header + \li minimumInterval() + \li Android priority + \row + \li interval < 30 + \li CONNECTION_PRIORITY_HIGH + \row + \li 30 <= interval <= 100 + \li CONNECTION_PRIORITY_BALANCED + \row + \li interval > 100 + \li CONNECTION_PRIORITY_LOW_POWER + \endtable + + The \l supervisionTimeout() cannot be changed on Android and is therefore ignored. + + \inmodule QtBluetooth \ingroup shared @@ -163,6 +189,9 @@ int QLowEnergyConnectionParameters::latency() const Sets the link supervision timeout to \a timeout milliseconds. There are several constraints on this value: It must be in the range [100,32000] and it must be larger than (1 + \l latency()) * 2 * \l maximumInterval(). + + On Android, this timeout is not adjustable and therefore ignored. + \sa supervisionTimeout() */ void QLowEnergyConnectionParameters::setSupervisionTimeout(int timeout) diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp index 13077d7d..6a9b50a0 100644 --- a/src/bluetooth/qlowenergycontroller.cpp +++ b/src/bluetooth/qlowenergycontroller.cpp @@ -968,19 +968,35 @@ QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData /*! Requests the controller to update the connection according to \a parameters. If the request is successful, the \l connectionUpdated() signal will be emitted - with the actual new parameters. - See the \l QLowEnergyConnectionParameters class for more information on connection parameters. - \note Currently, this functionality is only implemented on Linux. - + with the actual new parameters. See the \l QLowEnergyConnectionParameters class for more + information on connection parameters. + + Android only indirectly permits the adjustment of this parameter set. + The connection parameters are separated into three categories (high, low & balanced priority). + Each category implies a pre-configured set of values for + \l QLowEnergyConnectionParameters::minimumInterval(), + \l QLowEnergyConnectionParameters::maximumInterval() and + \l QLowEnergyConnectionParameters::latency(). Although the connection request is an asynchronous + operation, Android does not provide a callback stating the result of the request. This is + an acknowledged Android bug. Due to this bug Android does not emit the \l connectionUpdated() + signal. + + \note Currently, this functionality is only implemented on Linux and Android. + + \sa connectionUpdated() \since 5.7 */ void QLowEnergyController::requestConnectionUpdate(const QLowEnergyConnectionParameters ¶meters) { - if (state() != ConnectedState) { + switch (state()) { + case ConnectedState: + case DiscoveredState: + case DiscoveringState: + d_ptr->requestConnectionUpdate(parameters); + break; + default: qCWarning(QT_BT) << "Connection update request only possible in connected state"; - return; } - d_ptr->requestConnectionUpdate(parameters); } /*! diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index 20b6519c..6cd1ced1 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -45,6 +45,7 @@ #include <QtBluetooth/QLowEnergyDescriptorData> #include <QtBluetooth/QLowEnergyAdvertisingData> #include <QtBluetooth/QLowEnergyAdvertisingParameters> +#include <QtBluetooth/QLowEnergyConnectionParameters> QT_BEGIN_NAMESPACE @@ -771,8 +772,25 @@ void QLowEnergyControllerPrivate::stopAdvertising() void QLowEnergyControllerPrivate::requestConnectionUpdate(const QLowEnergyConnectionParameters ¶ms) { - Q_UNUSED(params); - qCWarning(QT_BT_ANDROID) << "Connection update not implemented for Android"; + // Possible since Android v21 + // Android does not permit specification of specific latency or min/max + // connection intervals (see BluetoothGatt.requestConnectionPriority() + // In fact, each device manufacturer is permitted to change those values via a config + // file too. Therefore we can only make an approximated guess (see implementation below) + // In addition there is no feedback signal (known bug) from the hardware layer as per v24. + + // TODO recheck in later Android releases whether callback for + // BluetoothGatt.requestConnectionPriority() was added + + if (role != QLowEnergyController::CentralRole) { + qCWarning(QT_BT_ANDROID) << "On Android, connection requests only work for central role"; + return; + } + + bool result = hub->javaObject().callMethod<jboolean>("requestConnectionUpdatePriority", + "(D)Z", params.minimumInterval()); + if (!result) + qCWarning(QT_BT_ANDROID) << "Cannot set connection update priority"; } // Conversion: QBluetoothUuid -> java.util.UUID |