File indexing completed on 2024-12-01 12:29:49

0001 /*
0002  * BluezQt - Asynchronous Bluez wrapper library
0003  *
0004  * SPDX-FileCopyrightText: 2014 David Rosca <nowrep@gmail.com>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007  */
0008 
0009 #include "manager.h"
0010 #include "agent.h"
0011 #include "agentadaptor.h"
0012 #include "debug.h"
0013 #include "initmanagerjob.h"
0014 #include "manager_p.h"
0015 #include "pendingcall.h"
0016 #include "profile.h"
0017 #include "profile_p.h"
0018 #include "profileadaptor.h"
0019 #include "utils.h"
0020 
0021 namespace BluezQt
0022 {
0023 Manager::Manager(QObject *parent)
0024     : QObject(parent)
0025     , d(new ManagerPrivate(this))
0026 {
0027     Instance::setManager(this);
0028 }
0029 
0030 Manager::~Manager()
0031 {
0032     delete d;
0033 }
0034 
0035 InitManagerJob *Manager::init()
0036 {
0037     return new InitManagerJob(this);
0038 }
0039 
0040 bool Manager::isInitialized() const
0041 {
0042     return d->m_initialized;
0043 }
0044 
0045 bool Manager::isOperational() const
0046 {
0047     return d->m_initialized && d->m_bluezRunning && d->m_loaded;
0048 }
0049 
0050 bool Manager::isBluetoothOperational() const
0051 {
0052     return !d->m_bluetoothBlocked && d->m_bluezRunning && d->m_loaded && d->m_usableAdapter;
0053 }
0054 
0055 bool Manager::isBluetoothBlocked() const
0056 {
0057     return d->m_bluetoothBlocked;
0058 }
0059 
0060 bool Manager::setBluetoothBlocked(bool blocked)
0061 {
0062     if (blocked) {
0063         return d->m_rfkill->block();
0064     } else {
0065         return d->m_rfkill->unblock();
0066     }
0067 }
0068 
0069 AdapterPtr Manager::usableAdapter() const
0070 {
0071     return d->m_usableAdapter;
0072 }
0073 
0074 QList<AdapterPtr> Manager::adapters() const
0075 {
0076     return d->m_adapters.values();
0077 }
0078 
0079 QList<DevicePtr> Manager::devices() const
0080 {
0081     return d->m_devices.values();
0082 }
0083 
0084 PendingCall *Manager::startService()
0085 {
0086     QDBusMessage msg = QDBusMessage::createMethodCall(Strings::orgFreedesktopDBus(),
0087                                                       QStringLiteral("/org/freedesktop/DBus"),
0088                                                       Strings::orgFreedesktopDBus(),
0089                                                       QStringLiteral("StartServiceByName"));
0090     msg << Strings::orgBluez();
0091     msg << quint32(0);
0092 
0093     return new PendingCall(DBusConnection::orgBluez().asyncCall(msg), PendingCall::ReturnUint32);
0094 }
0095 
0096 AdapterPtr Manager::adapterForAddress(const QString &address) const
0097 {
0098     for (AdapterPtr adapter : std::as_const(d->m_adapters)) {
0099         if (adapter->address() == address) {
0100             return adapter;
0101         }
0102     }
0103     return AdapterPtr();
0104 }
0105 
0106 AdapterPtr Manager::adapterForUbi(const QString &ubi) const
0107 {
0108     return d->m_adapters.value(ubi);
0109 }
0110 
0111 DevicePtr Manager::deviceForAddress(const QString &address) const
0112 {
0113     DevicePtr device;
0114 
0115     for (AdapterPtr adapter : std::as_const(d->m_adapters)) {
0116         DevicePtr d = adapter->deviceForAddress(address);
0117         if (!d) {
0118             continue;
0119         }
0120 
0121         // Prefer powered adapter
0122         if (!device) {
0123             device = d;
0124         } else if (adapter->isPowered()) {
0125             device = d;
0126         }
0127     }
0128 
0129     return device;
0130 }
0131 
0132 DevicePtr Manager::deviceForUbi(const QString &ubi) const
0133 {
0134     return d->m_devices.value(ubi);
0135 }
0136 
0137 PendingCall *Manager::registerAgent(Agent *agent)
0138 {
0139     Q_ASSERT(agent);
0140 
0141     if (!d->m_bluezAgentManager) {
0142         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0143     }
0144 
0145     QString capability;
0146 
0147     switch (agent->capability()) {
0148     case Agent::DisplayOnly:
0149         capability = QStringLiteral("DisplayOnly");
0150         break;
0151     case Agent::DisplayYesNo:
0152         capability = QStringLiteral("DisplayYesNo");
0153         break;
0154     case Agent::KeyboardOnly:
0155         capability = QStringLiteral("KeyboardOnly");
0156         break;
0157     case Agent::NoInputNoOutput:
0158         capability = QStringLiteral("NoInputNoOutput");
0159         break;
0160     default:
0161         capability = QStringLiteral("DisplayYesNo");
0162         break;
0163     }
0164 
0165     new AgentAdaptor(agent, this);
0166 
0167     if (!DBusConnection::orgBluez().registerObject(agent->objectPath().path(), agent)) {
0168         qCDebug(BLUEZQT) << "Cannot register object" << agent->objectPath().path();
0169     }
0170 
0171     return new PendingCall(d->m_bluezAgentManager->RegisterAgent(agent->objectPath(), capability), PendingCall::ReturnVoid, this);
0172 }
0173 
0174 PendingCall *Manager::unregisterAgent(Agent *agent)
0175 {
0176     Q_ASSERT(agent);
0177 
0178     if (!d->m_bluezAgentManager) {
0179         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0180     }
0181 
0182     DBusConnection::orgBluez().unregisterObject(agent->objectPath().path());
0183 
0184     return new PendingCall(d->m_bluezAgentManager->UnregisterAgent(agent->objectPath()), PendingCall::ReturnVoid, this);
0185 }
0186 
0187 PendingCall *Manager::requestDefaultAgent(Agent *agent)
0188 {
0189     Q_ASSERT(agent);
0190 
0191     if (!d->m_bluezAgentManager) {
0192         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0193     }
0194 
0195     return new PendingCall(d->m_bluezAgentManager->RequestDefaultAgent(agent->objectPath()), PendingCall::ReturnVoid, this);
0196 }
0197 
0198 PendingCall *Manager::registerProfile(Profile *profile)
0199 {
0200     Q_ASSERT(profile);
0201 
0202     if (!d->m_bluezProfileManager) {
0203         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0204     }
0205 
0206     new ProfileAdaptor(profile, this);
0207 
0208     if (!DBusConnection::orgBluez().registerObject(profile->objectPath().path(), profile)) {
0209         qCDebug(BLUEZQT) << "Cannot register object" << profile->objectPath().path();
0210     }
0211 
0212     return new PendingCall(d->m_bluezProfileManager->RegisterProfile(profile->objectPath(), profile->uuid(), profile->d->options),
0213                            PendingCall::ReturnVoid,
0214                            this);
0215 }
0216 
0217 PendingCall *Manager::unregisterProfile(Profile *profile)
0218 {
0219     Q_ASSERT(profile);
0220 
0221     if (!d->m_bluezProfileManager) {
0222         return new PendingCall(PendingCall::InternalError, QStringLiteral("Manager not operational!"));
0223     }
0224 
0225     DBusConnection::orgBluez().unregisterObject(profile->objectPath().path());
0226 
0227     return new PendingCall(d->m_bluezProfileManager->UnregisterProfile(profile->objectPath()), PendingCall::ReturnVoid, this);
0228 }
0229 
0230 #if BLUEZQT_BUILD_DEPRECATED_SINCE(5, 57)
0231 MediaPtr Manager::media() const
0232 {
0233     return usableAdapter() ? usableAdapter()->media() : nullptr;
0234 }
0235 #endif
0236 
0237 Rfkill *Manager::rfkill() const
0238 {
0239     return d->m_rfkill;
0240 }
0241 
0242 } // namespace BluezQt
0243 
0244 #include "moc_manager.cpp"