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
localdevicebroadcastreceiver.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/qrandom.h>
7#include "android/jni_android_p.h"
8
10
11Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
12
13const char *scanModes[] = {"SCAN_MODE_NONE", "SCAN_MODE_CONNECTABLE", "SCAN_MODE_CONNECTABLE_DISCOVERABLE"};
14const char *bondModes[] = {"BOND_NONE", "BOND_BONDING", "BOND_BONDED"};
15
16LocalDeviceBroadcastReceiver::LocalDeviceBroadcastReceiver(QObject *parent) :
17 AndroidBroadcastReceiver(parent), previousScanMode(0)
18{
19 addAction(QJniObject::fromString(
20 valueForStaticField<QtJniTypes::BluetoothDevice, JavaNames::ActionBondStateChanged>()));
21 addAction(QJniObject::fromString(
22 valueForStaticField<QtJniTypes::BluetoothAdapter, JavaNames::ActionScanModeChanged>()));
23 addAction(QJniObject::fromString(
24 valueForStaticField<QtJniTypes::BluetoothDevice, JavaNames::ActionAclConnected>()));
25 addAction(QJniObject::fromString(
26 valueForStaticField<QtJniTypes::BluetoothDevice, JavaNames::ActionAclDisconnected>()));
27
28 //cache integer values for host & bonding mode
29 //don't use the java fields directly but refer to them by name
30 for (uint i = 0; i < (sizeof(hostModePreset)/sizeof(hostModePreset[0])); i++) {
31 hostModePreset[i] = QJniObject::getStaticField<jint>(
32 QtJniTypes::Traits<QtJniTypes::BluetoothAdapter>::className(),
33 scanModes[i]);
34 }
35
36 for (uint i = 0; i < (sizeof(bondingModePreset)/sizeof(bondingModePreset[0])); i++) {
37 bondingModePreset[i] = QJniObject::getStaticField<jint>(
38 QtJniTypes::Traits<QtJniTypes::BluetoothDevice>::className(),
39 bondModes[i]);
40 }
41}
42
43void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobject intent)
44{
45 Q_UNUSED(context);
46 Q_UNUSED(env);
47
48 QJniObject intentObject(intent);
49 const QString action = intentObject.callMethod<jstring>("getAction").toString();
50 qCDebug(QT_BT_ANDROID) << QStringLiteral("LocalDeviceBroadcastReceiver::onReceive() - event: %1").arg(action);
51
52 if (action == valueForStaticField<QtJniTypes::BluetoothAdapter,
53 JavaNames::ActionScanModeChanged>()) {
54
55 const QJniObject extrasBundle =
56 intentObject.callMethod<QtJniTypes::Bundle>("getExtras");
57 const QJniObject keyExtra =
58 QJniObject::fromString(valueForStaticField<QtJniTypes::BluetoothAdapter,
59 JavaNames::ExtraScanMode>());
60
61 int extra = extrasBundle.callMethod<jint>("getInt", keyExtra.object<jstring>());
62
63 if (previousScanMode != extra) {
64 previousScanMode = extra;
65
66 if (extra == hostModePreset[0])
67 emit hostModeStateChanged(QBluetoothLocalDevice::HostPoweredOff);
68 else if (extra == hostModePreset[1])
69 emit hostModeStateChanged(QBluetoothLocalDevice::HostConnectable);
70 else if (extra == hostModePreset[2])
71 emit hostModeStateChanged(QBluetoothLocalDevice::HostDiscoverable);
72 else
73 qCWarning(QT_BT_ANDROID) << "Unknown Host State";
74 }
75 } else if (action == valueForStaticField<QtJniTypes::BluetoothDevice,
76 JavaNames::ActionBondStateChanged>()) {
77 //get BluetoothDevice
78 QJniObject keyExtra = QJniObject::fromString(
79 valueForStaticField<QtJniTypes::BluetoothDevice,
80 JavaNames::ExtraDevice>());
81 const QJniObject bluetoothDevice =
82 intentObject.callMethod<QtJniTypes::Parcelable>("getParcelableExtra",
83 keyExtra.object<jstring>());
84
85 //get new bond state
86 keyExtra = QJniObject::fromString(valueForStaticField<QtJniTypes::BluetoothDevice,
87 JavaNames::ExtraBondState>());
88 const QJniObject extrasBundle =
89 intentObject.callMethod<QtJniTypes::Bundle>("getExtras");
90 int bondState = extrasBundle.callMethod<jint>("getInt", keyExtra.object<jstring>());
91
92 QBluetoothAddress address(bluetoothDevice.callMethod<jstring>("getAddress").toString());
93 if (address.isNull())
94 return;
95
96 if (bondState == bondingModePreset[0])
97 emit pairingStateChanged(address, QBluetoothLocalDevice::Unpaired);
98 else if (bondState == bondingModePreset[1])
99 ; //we ignore this as Qt doesn't have equivalent API value
100 else if (bondState == bondingModePreset[2])
101 emit pairingStateChanged(address, QBluetoothLocalDevice::Paired);
102 else
103 qCWarning(QT_BT_ANDROID) << "Unknown BOND_STATE_CHANGED value:" << bondState;
104
105 } else if (action == valueForStaticField<QtJniTypes::BluetoothDevice,
106 JavaNames::ActionAclConnected>() ||
107 action == valueForStaticField<QtJniTypes::BluetoothDevice,
108 JavaNames::ActionAclDisconnected>()) {
109
110 const QString connectEvent = valueForStaticField<QtJniTypes::BluetoothDevice,
111 JavaNames::ActionAclConnected>();
112 const bool isConnectEvent =
113 action == connectEvent ? true : false;
114
115 //get BluetoothDevice
116 const QJniObject keyExtra =
117 QJniObject::fromString(valueForStaticField<QtJniTypes::BluetoothDevice,
118 JavaNames::ExtraDevice>());
119 QJniObject bluetoothDevice =
120 intentObject.callMethod<QtJniTypes::Parcelable>("getParcelableExtra",
121 keyExtra.object<jstring>());
122
123 QBluetoothAddress address(bluetoothDevice.callMethod<jstring>("getAddress").toString());
124 if (address.isNull())
125 return;
126
127 emit connectDeviceChanges(address, isConnectEvent);
128 }
129}
130
131QT_END_NAMESPACE
virtual void onReceive(JNIEnv *env, jobject context, jobject intent)
const char * bondModes[]