// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include #include #include "localdevicebroadcastreceiver_p.h" #include "android/jni_android_p.h" QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID) const char *scanModes[] = {"SCAN_MODE_NONE", "SCAN_MODE_CONNECTABLE", "SCAN_MODE_CONNECTABLE_DISCOVERABLE"}; const char *bondModes[] = {"BOND_NONE", "BOND_BONDING", "BOND_BONDED"}; LocalDeviceBroadcastReceiver::LocalDeviceBroadcastReceiver(QObject *parent) : AndroidBroadcastReceiver(parent), previousScanMode(0) { addAction(QJniObject::fromString( valueForStaticField())); addAction(QJniObject::fromString( valueForStaticField())); addAction(QJniObject::fromString( valueForStaticField())); addAction(QJniObject::fromString( valueForStaticField())); //cache integer values for host & bonding mode //don't use the java fields directly but refer to them by name for (uint i = 0; i < (sizeof(hostModePreset)/sizeof(hostModePreset[0])); i++) { hostModePreset[i] = QJniObject::getStaticField( QtJniTypes::Traits::className(), scanModes[i]); } for (uint i = 0; i < (sizeof(bondingModePreset)/sizeof(bondingModePreset[0])); i++) { bondingModePreset[i] = QJniObject::getStaticField( QtJniTypes::Traits::className(), bondModes[i]); } } void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobject intent) { Q_UNUSED(context); Q_UNUSED(env); QJniObject intentObject(intent); const QString action = intentObject.callMethod("getAction").toString(); qCDebug(QT_BT_ANDROID) << QStringLiteral("LocalDeviceBroadcastReceiver::onReceive() - event: %1").arg(action); if (action == valueForStaticField()) { const QJniObject extrasBundle = intentObject.callMethod("getExtras"); const QJniObject keyExtra = QJniObject::fromString(valueForStaticField()); int extra = extrasBundle.callMethod("getInt", keyExtra.object()); if (previousScanMode != extra) { previousScanMode = extra; if (extra == hostModePreset[0]) emit hostModeStateChanged(QBluetoothLocalDevice::HostPoweredOff); else if (extra == hostModePreset[1]) emit hostModeStateChanged(QBluetoothLocalDevice::HostConnectable); else if (extra == hostModePreset[2]) emit hostModeStateChanged(QBluetoothLocalDevice::HostDiscoverable); else qCWarning(QT_BT_ANDROID) << "Unknown Host State"; } } else if (action == valueForStaticField()) { //get BluetoothDevice QJniObject keyExtra = QJniObject::fromString( valueForStaticField()); const QJniObject bluetoothDevice = intentObject.callMethod("getParcelableExtra", keyExtra.object()); //get new bond state keyExtra = QJniObject::fromString(valueForStaticField()); const QJniObject extrasBundle = intentObject.callMethod("getExtras"); int bondState = extrasBundle.callMethod("getInt", keyExtra.object()); QBluetoothAddress address(bluetoothDevice.callMethod("getAddress").toString()); if (address.isNull()) return; if (bondState == bondingModePreset[0]) emit pairingStateChanged(address, QBluetoothLocalDevice::Unpaired); else if (bondState == bondingModePreset[1]) ; //we ignore this as Qt doesn't have equivalent API value else if (bondState == bondingModePreset[2]) emit pairingStateChanged(address, QBluetoothLocalDevice::Paired); else qCWarning(QT_BT_ANDROID) << "Unknown BOND_STATE_CHANGED value:" << bondState; } else if (action == valueForStaticField() || action == valueForStaticField()) { const QString connectEvent = valueForStaticField(); const bool isConnectEvent = action == connectEvent ? true : false; //get BluetoothDevice const QJniObject keyExtra = QJniObject::fromString(valueForStaticField()); QJniObject bluetoothDevice = intentObject.callMethod("getParcelableExtra", keyExtra.object()); QBluetoothAddress address(bluetoothDevice.callMethod("getAddress").toString()); if (address.isNull()) return; emit connectDeviceChanges(address, isConnectEvent); } } QT_END_NAMESPACE