File indexing completed on 2024-05-12 05:36:52
0001 /* 0002 * SPDX-FileCopyrightText: 2018-2019 Daniel Vrátil <dvratil@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "device.h" 0008 #include "dbushelper.h" 0009 #include "deviceinterface.h" 0010 #include "libkbolt_debug.h" 0011 0012 #include <stdexcept> 0013 0014 using namespace Bolt; 0015 0016 using DeviceInterface = org::freedesktop::bolt1::Device; 0017 0018 class DBusException : public std::runtime_error 0019 { 0020 public: 0021 DBusException(const QString &what) 0022 : std::runtime_error(what.toStdString()) 0023 { 0024 } 0025 }; 0026 0027 Device::Device(QObject *parent) 0028 : QObject(parent) 0029 { 0030 } 0031 0032 Device::Device(const QDBusObjectPath &path, QObject *parent) 0033 : QObject(parent) 0034 , mInterface(std::make_unique<DeviceInterface>(DBusHelper::serviceName(), path.path(), DBusHelper::connection())) 0035 , mDBusPath(path) 0036 { 0037 if (!mInterface->isValid()) { 0038 throw DBusException(QStringLiteral("Failed to obtain DBus interface for device %1: %2").arg(path.path(), mInterface->lastError().message())); 0039 } 0040 0041 // cache UID in case the we still need to identify the device, even if it's 0042 // gone on DBus 0043 mUid = mInterface->uid(); 0044 } 0045 0046 Device::~Device() = default; 0047 0048 QSharedPointer<Device> Device::create(const QDBusObjectPath &path) 0049 { 0050 try { 0051 return QSharedPointer<Device>::create(path); 0052 } catch (const DBusException &e) { 0053 qCWarning(log_libkbolt, "%s", e.what()); 0054 return {}; 0055 } 0056 } 0057 0058 QDBusObjectPath Device::dbusPath() const 0059 { 0060 return mDBusPath; 0061 } 0062 0063 QString Device::uid() const 0064 { 0065 return mUid; 0066 } 0067 0068 QString Device::name() const 0069 { 0070 return mInterface->name(); 0071 } 0072 0073 QString Device::vendor() const 0074 { 0075 return mInterface->vendor(); 0076 } 0077 0078 Type Device::type() const 0079 { 0080 const auto val = mInterface->type(); 0081 return val.isEmpty() ? Type::Unknown : typeFromString(val); 0082 } 0083 0084 Status Device::status() const 0085 { 0086 if (mStatusOverride == Status::Unknown) { 0087 const auto val = mInterface->status(); 0088 return val.isEmpty() ? Status::Unknown : statusFromString(val); 0089 } else { 0090 return mStatusOverride; 0091 } 0092 } 0093 0094 void Device::setStatusOverride(Status status) 0095 { 0096 if (mStatusOverride != status) { 0097 mStatusOverride = status; 0098 Q_EMIT statusChanged(status); 0099 } 0100 } 0101 0102 void Device::clearStatusOverride() 0103 { 0104 setStatusOverride(Status::Unknown); 0105 } 0106 0107 AuthFlags Device::authFlags() const 0108 { 0109 const auto val = mInterface->authFlags(); 0110 return val.isEmpty() ? Auth::None : authFlagsFromString(val); 0111 } 0112 0113 QString Device::parent() const 0114 { 0115 return mInterface->parentUid(); 0116 } 0117 0118 QString Device::sysfsPath() const 0119 { 0120 return mInterface->sysfsPath(); 0121 } 0122 0123 QDateTime Device::connectTime() const 0124 { 0125 const auto val = mInterface->connectTime(); 0126 return val == 0 ? QDateTime() : QDateTime::fromSecsSinceEpoch(val); 0127 } 0128 0129 QDateTime Device::authorizeTime() const 0130 { 0131 const auto val = mInterface->authorizeTime(); 0132 return val == 0 ? QDateTime() : QDateTime::fromSecsSinceEpoch(val); 0133 } 0134 0135 bool Device::stored() const 0136 { 0137 return mInterface ? mInterface->stored() : false; 0138 } 0139 0140 Policy Device::policy() const 0141 { 0142 const auto val = mInterface->policy(); 0143 return val.isEmpty() ? Policy::Unknown : policyFromString(val); 0144 } 0145 0146 KeyState Device::keyState() const 0147 { 0148 const auto val = mInterface->key(); 0149 return val.isEmpty() ? KeyState::Unknown : keyStateFromString(val); 0150 } 0151 0152 QDateTime Device::storeTime() const 0153 { 0154 const auto val = mInterface->storeTime(); 0155 return val == 0 ? QDateTime() : QDateTime::fromSecsSinceEpoch(val); 0156 } 0157 0158 QString Device::label() const 0159 { 0160 return mInterface->label(); 0161 } 0162 0163 void Device::authorize(AuthFlags authFlags, std::function<void()> successCb, std::function<void(const QString &)> errorCb) 0164 { 0165 qCDebug(log_libkbolt, "Authorizing device %s with auth flags %s", qUtf8Printable(mUid), qUtf8Printable(authFlagsToString(authFlags))); 0166 0167 setStatusOverride(Status::Authorizing); 0168 DBusHelper::call<QString>( 0169 mInterface.get(), 0170 QStringLiteral("Authorize"), 0171 authFlagsToString(authFlags), 0172 [this, cb = std::move(successCb)]() { 0173 qCDebug(log_libkbolt, "Device %s was successfully authorized", qUtf8Printable(mUid)); 0174 clearStatusOverride(); 0175 if (cb) { 0176 cb(); 0177 } 0178 }, 0179 [this, cb = std::move(errorCb)](const QString &error) { 0180 qCWarning(log_libkbolt, "Failed to authorize device %s: %s", qUtf8Printable(mUid), qUtf8Printable(error)); 0181 setStatusOverride(Status::AuthError); 0182 if (cb) { 0183 cb(error); 0184 } 0185 }, 0186 this); 0187 } 0188 0189 #include "moc_device.cpp"