File indexing completed on 2023-09-24 04:02:11
0001 /* 0002 * SPDX-FileCopyrightText: 2014-2015 David Rosca <nowrep@gmail.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "deviceinterface.h" 0008 #include "batteryinterface.h" 0009 #include "inputinterface.h" 0010 #include "mediaplayerinterface.h" 0011 #include "mediatransportinterface.h" 0012 #include "objectmanager.h" 0013 0014 #include <QDBusArgument> 0015 #include <QDBusConnection> 0016 #include <QDBusMessage> 0017 0018 static const QLatin1String MediaPlayerUuid("0000110E-0000-1000-8000-00805F9B34FB"); 0019 static const QLatin1String MediaTransportUuid("0000110B-0000-1000-8000-00805F9B34FB"); 0020 0021 // DeviceObject 0022 DeviceObject::DeviceObject(const QDBusObjectPath &path, QObject *parent) 0023 : QObject(parent) 0024 { 0025 QDBusConnection::sessionBus().registerObject(path.path(), this); 0026 } 0027 0028 // DeviceInterface 0029 DeviceInterface::DeviceInterface(const QDBusObjectPath &path, const QVariantMap &properties, QObject *parent) 0030 : QDBusAbstractAdaptor(parent) 0031 { 0032 setPath(path); 0033 setObjectParent(parent); 0034 setProperties(properties); 0035 setName(QStringLiteral("org.bluez.Device1")); 0036 0037 // Alias needs special handling 0038 setAlias(properties.value(QStringLiteral("Alias")).toString()); 0039 0040 // Create Battery1 0041 if (properties.contains(QStringLiteral("Battery"))) { 0042 const QVariantMap &inputProps = qdbus_cast<QVariantMap>(properties.value(QStringLiteral("Battery"))); 0043 BatteryInterface *input = new BatteryInterface(path, inputProps, parent); 0044 0045 ObjectManager *manager = ObjectManager::self(); 0046 manager->addObject(input); 0047 0048 QVariantMap props = properties; 0049 props.remove(QStringLiteral("Battery")); 0050 setProperties(props); 0051 } 0052 0053 // Create Input1 0054 if (properties.contains(QStringLiteral("Input"))) { 0055 const QVariantMap &inputProps = qdbus_cast<QVariantMap>(properties.value(QStringLiteral("Input"))); 0056 InputInterface *input = new InputInterface(path, inputProps, parent); 0057 0058 ObjectManager *manager = ObjectManager::self(); 0059 manager->addObject(input); 0060 0061 QVariantMap props = properties; 0062 props.remove(QStringLiteral("Input")); 0063 setProperties(props); 0064 } 0065 } 0066 0067 QString DeviceInterface::address() const 0068 { 0069 return Object::property(QStringLiteral("Address")).toString(); 0070 } 0071 0072 QString DeviceInterface::name() const 0073 { 0074 return Object::property(QStringLiteral("Name")).toString(); 0075 } 0076 0077 QString DeviceInterface::alias() const 0078 { 0079 return Object::property(QStringLiteral("Alias")).toString(); 0080 } 0081 0082 void DeviceInterface::setAlias(const QString &alias) 0083 { 0084 Object::changeProperty(QStringLiteral("Alias"), alias.isEmpty() ? name() : alias); 0085 } 0086 0087 QString DeviceInterface::icon() const 0088 { 0089 return Object::property(QStringLiteral("Icon")).toString(); 0090 } 0091 0092 quint32 DeviceInterface::deviceClass() const 0093 { 0094 return Object::property(QStringLiteral("Class")).toUInt(); 0095 } 0096 0097 quint16 DeviceInterface::appearance() const 0098 { 0099 return Object::property(QStringLiteral("Appearance")).toUInt(); 0100 } 0101 0102 bool DeviceInterface::paired() const 0103 { 0104 return Object::property(QStringLiteral("Paired")).toBool(); 0105 } 0106 0107 bool DeviceInterface::connected() const 0108 { 0109 return Object::property(QStringLiteral("Connected")).toBool(); 0110 } 0111 0112 bool DeviceInterface::trusted() const 0113 { 0114 return Object::property(QStringLiteral("Trusted")).toBool(); 0115 } 0116 0117 void DeviceInterface::setTrusted(bool trusted) 0118 { 0119 Object::changeProperty(QStringLiteral("Trusted"), trusted); 0120 } 0121 0122 bool DeviceInterface::blocked() const 0123 { 0124 return Object::property(QStringLiteral("Blocked")).toBool(); 0125 } 0126 0127 void DeviceInterface::setBlocked(bool blocked) 0128 { 0129 Object::changeProperty(QStringLiteral("Blocked"), blocked); 0130 } 0131 0132 QDBusObjectPath DeviceInterface::adapter() const 0133 { 0134 return Object::property(QStringLiteral("Adapter")).value<QDBusObjectPath>(); 0135 } 0136 0137 bool DeviceInterface::legacyPairing() const 0138 { 0139 return Object::property(QStringLiteral("LegacyPairing")).toBool(); 0140 } 0141 0142 qint16 DeviceInterface::rssi() const 0143 { 0144 return Object::property(QStringLiteral("RSSI")).toInt(); 0145 } 0146 0147 QStringList DeviceInterface::uuids() const 0148 { 0149 return Object::property(QStringLiteral("UUIDs")).toStringList(); 0150 } 0151 0152 QString DeviceInterface::modalias() const 0153 { 0154 return Object::property(QStringLiteral("Modalias")).toString(); 0155 } 0156 0157 MediaTransportInterface *DeviceInterface::mediaTransport() const 0158 { 0159 return m_mediaTransport; 0160 } 0161 0162 void DeviceInterface::Connect() 0163 { 0164 if (uuids().contains(MediaPlayerUuid)) { 0165 connectMediaPlayer(); 0166 } 0167 0168 if (uuids().contains(MediaTransportUuid)) { 0169 connectMediaTransport(); 0170 } 0171 0172 Object::changeProperty(QStringLiteral("Connected"), true); 0173 } 0174 0175 void DeviceInterface::Disconnect() 0176 { 0177 if (uuids().contains(MediaPlayerUuid)) { 0178 disconnectMediaPlayer(); 0179 } 0180 0181 if (uuids().contains(MediaTransportUuid)) { 0182 disconnectMediaTransport(); 0183 } 0184 0185 Object::changeProperty(QStringLiteral("Connected"), false); 0186 } 0187 0188 void DeviceInterface::ConnectProfile(const QString &uuid, const QDBusMessage &msg) 0189 { 0190 if (!uuids().contains(uuid)) { 0191 QDBusMessage error = msg.createErrorReply(QStringLiteral("org.bluez.Error.DoesNotExist"), QStringLiteral("Profile UUID not supported")); 0192 QDBusConnection::sessionBus().send(error); 0193 return; 0194 } 0195 0196 if (m_connectedUuids.contains(uuid)) { 0197 QDBusMessage error = msg.createErrorReply(QStringLiteral("org.bluez.Error.AlreadyConnected"), QStringLiteral("Profile already connected")); 0198 QDBusConnection::sessionBus().send(error); 0199 return; 0200 } 0201 0202 if (uuid == MediaPlayerUuid) { 0203 connectMediaPlayer(); 0204 } else if (uuid == MediaTransportUuid) { 0205 connectMediaTransport(); 0206 } else { 0207 Q_UNIMPLEMENTED(); 0208 } 0209 0210 Object::changeProperty(QStringLiteral("Connected"), true); 0211 } 0212 0213 void DeviceInterface::DisconnectProfile(const QString &uuid, const QDBusMessage &msg) 0214 { 0215 if (!uuids().contains(uuid)) { 0216 QDBusMessage error = msg.createErrorReply(QStringLiteral("org.bluez.Error.DoesNotExist"), QStringLiteral("Profile UUID not supported")); 0217 QDBusConnection::sessionBus().send(error); 0218 return; 0219 } 0220 0221 if (!m_connectedUuids.contains(uuid)) { 0222 QDBusMessage error = msg.createErrorReply(QStringLiteral("org.bluez.Error.NotConnected"), QStringLiteral("Profile not connected")); 0223 QDBusConnection::sessionBus().send(error); 0224 return; 0225 } 0226 0227 if (uuid == MediaPlayerUuid) { 0228 disconnectMediaPlayer(); 0229 } else if (uuid == MediaTransportUuid) { 0230 disconnectMediaTransport(); 0231 } else { 0232 Q_UNIMPLEMENTED(); 0233 } 0234 0235 Object::changeProperty(QStringLiteral("Connected"), false); 0236 } 0237 0238 void DeviceInterface::Pair() 0239 { 0240 Q_UNIMPLEMENTED(); 0241 } 0242 0243 void DeviceInterface::CancelPairing() 0244 { 0245 Q_UNIMPLEMENTED(); 0246 } 0247 0248 void DeviceInterface::connectMediaPlayer() 0249 { 0250 const QVariantMap &properties = qdbus_cast<QVariantMap>(Object::property(QStringLiteral("MediaPlayer"))); 0251 const QDBusObjectPath &path = properties.value(QStringLiteral("Path")).value<QDBusObjectPath>(); 0252 QVariantMap props = properties; 0253 props.remove(QStringLiteral("Path")); 0254 0255 MediaPlayerObject *mediaPlayerObj = new MediaPlayerObject(path); 0256 m_mediaPlayer = new MediaPlayerInterface(path, props, mediaPlayerObj); 0257 0258 ObjectManager *manager = ObjectManager::self(); 0259 manager->addObject(m_mediaPlayer); 0260 manager->addAutoDeleteObject(mediaPlayerObj); 0261 0262 m_connectedUuids.append(MediaPlayerUuid); 0263 } 0264 0265 void DeviceInterface::disconnectMediaPlayer() 0266 { 0267 ObjectManager *manager = ObjectManager::self(); 0268 manager->removeObject(m_mediaPlayer); 0269 m_connectedUuids.removeOne(MediaPlayerUuid); 0270 0271 m_mediaPlayer = nullptr; 0272 } 0273 0274 void DeviceInterface::connectMediaTransport() 0275 { 0276 const QVariantMap &properties = qdbus_cast<QVariantMap>(Object::property(QStringLiteral("MediaTransport"))); 0277 const QDBusObjectPath &path = properties.value(QStringLiteral("Path")).value<QDBusObjectPath>(); 0278 QVariantMap props = properties; 0279 props.remove(QStringLiteral("Path")); 0280 0281 MediaTransportObject *transportObj = new MediaTransportObject(path); 0282 m_mediaTransport = new MediaTransportInterface(path, props, transportObj); 0283 0284 ObjectManager *manager = ObjectManager::self(); 0285 manager->addObject(m_mediaTransport); 0286 manager->addAutoDeleteObject(transportObj); 0287 0288 m_connectedUuids.append(MediaTransportUuid); 0289 } 0290 0291 void DeviceInterface::disconnectMediaTransport() 0292 { 0293 ObjectManager *manager = ObjectManager::self(); 0294 manager->removeObject(m_mediaTransport); 0295 m_connectedUuids.removeOne(MediaTransportUuid); 0296 0297 m_mediaTransport = nullptr; 0298 } 0299 0300 #include "moc_deviceinterface.cpp"