File indexing completed on 2024-05-12 04:01:50

0001 /*
0002     SPDX-FileCopyrightText: 2005-2007 Kevin Ottens <ervin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "device.h"
0008 #include "device_p.h"
0009 #include "devicemanager_p.h"
0010 #include "devicenotifier.h"
0011 
0012 #include "deviceinterface_p.h"
0013 #include "soliddefs_p.h"
0014 
0015 #include <solid/devices/ifaces/device.h>
0016 
0017 #include <solid/battery.h>
0018 #include <solid/block.h>
0019 #include <solid/camera.h>
0020 #include <solid/devices/ifaces/battery.h>
0021 #include <solid/devices/ifaces/block.h>
0022 #include <solid/devices/ifaces/camera.h>
0023 #include <solid/devices/ifaces/genericinterface.h>
0024 #include <solid/devices/ifaces/networkshare.h>
0025 #include <solid/devices/ifaces/opticaldisc.h>
0026 #include <solid/devices/ifaces/opticaldrive.h>
0027 #include <solid/devices/ifaces/portablemediaplayer.h>
0028 #include <solid/devices/ifaces/processor.h>
0029 #include <solid/devices/ifaces/storageaccess.h>
0030 #include <solid/devices/ifaces/storagedrive.h>
0031 #include <solid/devices/ifaces/storagevolume.h>
0032 #include <solid/genericinterface.h>
0033 #include <solid/networkshare.h>
0034 #include <solid/opticaldisc.h>
0035 #include <solid/opticaldrive.h>
0036 #include <solid/portablemediaplayer.h>
0037 #include <solid/processor.h>
0038 #include <solid/storageaccess.h>
0039 #include <solid/storagedrive.h>
0040 #include <solid/storagevolume.h>
0041 
0042 Solid::Device::Device(const QString &udi)
0043 {
0044     DeviceManagerPrivate *manager = static_cast<DeviceManagerPrivate *>(Solid::DeviceNotifier::instance());
0045     d = manager->findRegisteredDevice(udi);
0046 }
0047 
0048 Solid::Device::Device(const Device &device)
0049     : d(device.d)
0050 {
0051 }
0052 
0053 Solid::Device::~Device()
0054 {
0055 }
0056 
0057 Solid::Device &Solid::Device::operator=(const Solid::Device &device)
0058 {
0059     d = device.d;
0060     return *this;
0061 }
0062 
0063 bool Solid::Device::isValid() const
0064 {
0065     return d->backendObject() != nullptr;
0066 }
0067 
0068 QString Solid::Device::udi() const
0069 {
0070     return d->udi();
0071 }
0072 
0073 QString Solid::Device::parentUdi() const
0074 {
0075     return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), parentUdi());
0076 }
0077 
0078 Solid::Device Solid::Device::parent() const
0079 {
0080     QString udi = parentUdi();
0081 
0082     if (udi.isEmpty()) {
0083         return Device();
0084     } else {
0085         return Device(udi);
0086     }
0087 }
0088 
0089 QString Solid::Device::vendor() const
0090 {
0091     return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), vendor());
0092 }
0093 
0094 QString Solid::Device::product() const
0095 {
0096     return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), product());
0097 }
0098 
0099 QString Solid::Device::icon() const
0100 {
0101     return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), icon());
0102 }
0103 
0104 QStringList Solid::Device::emblems() const
0105 {
0106     return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QStringList(), emblems());
0107 }
0108 
0109 QString Solid::Device::displayName() const
0110 {
0111     return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), displayName());
0112 }
0113 
0114 QString Solid::Device::description() const
0115 {
0116     return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), description());
0117 }
0118 
0119 bool Solid::Device::isDeviceInterface(const DeviceInterface::Type &type) const
0120 {
0121     return_SOLID_CALL(Ifaces::Device *, d->backendObject(), false, queryDeviceInterface(type));
0122 }
0123 
0124 #define deviceinterface_cast(IfaceType, DevType, backendObject) (qobject_cast<IfaceType *>(backendObject) ? new DevType(backendObject) : nullptr)
0125 
0126 Solid::DeviceInterface *Solid::Device::asDeviceInterface(const DeviceInterface::Type &type)
0127 {
0128     const Solid::DeviceInterface *interface = const_cast<const Device *>(this)->asDeviceInterface(type);
0129     return const_cast<Solid::DeviceInterface *>(interface);
0130 }
0131 
0132 const Solid::DeviceInterface *Solid::Device::asDeviceInterface(const DeviceInterface::Type &type) const
0133 {
0134     Ifaces::Device *device = qobject_cast<Ifaces::Device *>(d->backendObject());
0135 
0136     if (device != nullptr) {
0137         DeviceInterface *iface = d->interface(type);
0138 
0139         if (iface != nullptr) {
0140             return iface;
0141         }
0142 
0143         QObject *dev_iface = device->createDeviceInterface(type);
0144 
0145         if (dev_iface != nullptr) {
0146             switch (type) {
0147             case DeviceInterface::GenericInterface:
0148                 iface = deviceinterface_cast(Ifaces::GenericInterface, GenericInterface, dev_iface);
0149                 break;
0150             case DeviceInterface::Processor:
0151                 iface = deviceinterface_cast(Ifaces::Processor, Processor, dev_iface);
0152                 break;
0153             case DeviceInterface::Block:
0154                 iface = deviceinterface_cast(Ifaces::Block, Block, dev_iface);
0155                 break;
0156             case DeviceInterface::StorageAccess:
0157                 iface = deviceinterface_cast(Ifaces::StorageAccess, StorageAccess, dev_iface);
0158                 break;
0159             case DeviceInterface::StorageDrive:
0160                 iface = deviceinterface_cast(Ifaces::StorageDrive, StorageDrive, dev_iface);
0161                 break;
0162             case DeviceInterface::OpticalDrive:
0163                 iface = deviceinterface_cast(Ifaces::OpticalDrive, OpticalDrive, dev_iface);
0164                 break;
0165             case DeviceInterface::StorageVolume:
0166                 iface = deviceinterface_cast(Ifaces::StorageVolume, StorageVolume, dev_iface);
0167                 break;
0168             case DeviceInterface::OpticalDisc:
0169                 iface = deviceinterface_cast(Ifaces::OpticalDisc, OpticalDisc, dev_iface);
0170                 break;
0171             case DeviceInterface::Camera:
0172                 iface = deviceinterface_cast(Ifaces::Camera, Camera, dev_iface);
0173                 break;
0174             case DeviceInterface::PortableMediaPlayer:
0175                 iface = deviceinterface_cast(Ifaces::PortableMediaPlayer, PortableMediaPlayer, dev_iface);
0176                 break;
0177             case DeviceInterface::Battery:
0178                 iface = deviceinterface_cast(Ifaces::Battery, Battery, dev_iface);
0179                 break;
0180             case DeviceInterface::NetworkShare:
0181                 iface = deviceinterface_cast(Ifaces::NetworkShare, NetworkShare, dev_iface);
0182                 break;
0183             case DeviceInterface::Unknown:
0184             case DeviceInterface::Last:
0185                 break;
0186             }
0187         }
0188 
0189         if (iface != nullptr) {
0190             // Lie on the constness since we're simply doing caching here
0191             const_cast<Device *>(this)->d->setInterface(type, iface);
0192             iface->d_ptr->setDevicePrivate(d.data());
0193         }
0194 
0195         return iface;
0196     } else {
0197         return nullptr;
0198     }
0199 }
0200 
0201 //////////////////////////////////////////////////////////////////////
0202 
0203 Solid::DevicePrivate::DevicePrivate(const QString &udi)
0204     : QObject()
0205     , QSharedData()
0206     , m_udi(udi)
0207 {
0208 }
0209 
0210 Solid::DevicePrivate::~DevicePrivate()
0211 {
0212     setBackendObject(nullptr);
0213 }
0214 
0215 void Solid::DevicePrivate::_k_destroyed(QObject *object)
0216 {
0217     Q_UNUSED(object);
0218     setBackendObject(nullptr);
0219 }
0220 
0221 void Solid::DevicePrivate::setBackendObject(Ifaces::Device *object)
0222 {
0223     if (m_backendObject) {
0224         m_backendObject.data()->disconnect(this);
0225     }
0226 
0227     delete m_backendObject.data();
0228     m_backendObject = object;
0229 
0230     if (object) {
0231         connect(object, SIGNAL(destroyed(QObject *)), this, SLOT(_k_destroyed(QObject *)));
0232     }
0233 
0234     if (!m_ifaces.isEmpty()) {
0235         qDeleteAll(m_ifaces);
0236 
0237         m_ifaces.clear();
0238         if (!ref.deref()) {
0239             deleteLater();
0240         }
0241     }
0242 }
0243 
0244 Solid::DeviceInterface *Solid::DevicePrivate::interface(const DeviceInterface::Type &type) const
0245 {
0246     return m_ifaces[type];
0247 }
0248 
0249 void Solid::DevicePrivate::setInterface(const DeviceInterface::Type &type, DeviceInterface *interface)
0250 {
0251     if (m_ifaces.isEmpty()) {
0252         ref.ref();
0253     }
0254     m_ifaces[type] = interface;
0255 }
0256 
0257 #include "moc_device_p.cpp"