File indexing completed on 2024-05-12 05:35:55

0001 /*
0002     SPDX-FileCopyrightText: 2009 Trever Fischer <wm161@wm161.net>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "DeviceAutomounter.h"
0008 
0009 #include <KPluginFactory>
0010 
0011 #include <Solid/DeviceNotifier>
0012 #include <Solid/StorageAccess>
0013 #include <Solid/StorageVolume>
0014 
0015 #include <QDBusConnection>
0016 #include <QDBusMessage>
0017 
0018 #include <QTimer>
0019 
0020 K_PLUGIN_CLASS_WITH_JSON(DeviceAutomounter, "device_automounter.json")
0021 
0022 DeviceAutomounter::DeviceAutomounter(QObject *parent, const QVariantList &args)
0023     : KDEDModule(parent)
0024     , m_settings(new AutomounterSettings(this))
0025 {
0026     Q_UNUSED(args)
0027     QTimer::singleShot(0, this, &DeviceAutomounter::init);
0028 }
0029 
0030 DeviceAutomounter::~DeviceAutomounter()
0031 {
0032 }
0033 
0034 void DeviceAutomounter::init()
0035 {
0036     if (!m_settings->automountEnabled()) {
0037         // Automounting is disabled, no point in hanging around.
0038         QDBusConnection dbus = QDBusConnection::sessionBus();
0039         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded6"),
0040                                                           QStringLiteral("/kded"),
0041                                                           QStringLiteral("org.kde.kded6"),
0042                                                           QStringLiteral("setModuleAutoloading"));
0043         msg.setArguments({QVariant(QStringLiteral("device_automounter")), QVariant(false)});
0044         dbus.call(msg, QDBus::NoBlock);
0045 
0046         // Unload right away
0047         msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded6"),
0048                                              QStringLiteral("/kded"),
0049                                              QStringLiteral("org.kde.kded6"),
0050                                              QStringLiteral("unloadModule"));
0051         msg.setArguments({QVariant(QStringLiteral("device_automounter"))});
0052         dbus.call(msg, QDBus::NoBlock);
0053         return;
0054     }
0055 
0056     connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceAdded, this, &DeviceAutomounter::deviceAdded);
0057     const QList<Solid::Device> volumes = Solid::Device::listFromType(Solid::DeviceInterface::StorageVolume);
0058     for (Solid::Device volume : volumes) {
0059         // sa can be 0 (e.g. for the swap partition)
0060         if (const Solid::StorageAccess *sa = volume.as<Solid::StorageAccess>()) {
0061             connect(sa, &Solid::StorageAccess::accessibilityChanged, this, &DeviceAutomounter::deviceMountChanged);
0062         }
0063         automountDevice(volume, m_settings->Login);
0064     }
0065     m_settings->save();
0066 }
0067 
0068 void DeviceAutomounter::deviceMountChanged(bool accessible, const QString &udi)
0069 {
0070     m_settings->setDeviceLastSeenMounted(udi, accessible);
0071     m_settings->save();
0072 }
0073 
0074 void DeviceAutomounter::automountDevice(Solid::Device &dev, AutomounterSettings::AutomountType type)
0075 {
0076     if (dev.is<Solid::StorageVolume>() && dev.is<Solid::StorageAccess>()) {
0077         Solid::StorageAccess *sa = dev.as<Solid::StorageAccess>();
0078 
0079         m_settings->setDeviceLastSeenMounted(dev.udi(), sa->isAccessible());
0080         m_settings->setDeviceInfo(dev);
0081         m_settings->save();
0082 
0083         if (m_settings->shouldAutomountDevice(dev.udi(), type)) {
0084             Solid::StorageVolume *sv = dev.as<Solid::StorageVolume>();
0085             if (!sa->isAccessible() && !sv->isIgnored()) {
0086                 sa->setup();
0087             }
0088         }
0089     }
0090 }
0091 
0092 void DeviceAutomounter::deviceAdded(const QString &udi)
0093 {
0094     m_settings->load();
0095 
0096     Solid::Device dev(udi);
0097     automountDevice(dev, AutomounterSettings::Attach);
0098     m_settings->save();
0099 
0100     if (dev.is<Solid::StorageAccess>()) {
0101         Solid::StorageAccess *sa = dev.as<Solid::StorageAccess>();
0102         if (sa && !sa->isIgnored()) {
0103             connect(sa, &Solid::StorageAccess::accessibilityChanged, this, &DeviceAutomounter::deviceMountChanged);
0104         }
0105     }
0106 }
0107 
0108 #include "DeviceAutomounter.moc"