2
* Copyright (C) 2007 Menard Alexis <darktears31@gmail.com>
4
* This program is free software you can redistribute it and/or
5
* modify it under the terms of the GNU Library General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Library General Public License for more details.
14
* You should have received a copy of the GNU Library General Public License
15
* along with this library; see the file COPYING.LIB. If not, write to
16
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
* Boston, MA 02110-1301, USA.
20
#include "hotplugengine.h"
25
#include <KConfigGroup>
28
#include <KStandardDirs>
29
#include <KDesktopFile>
30
#include <Plasma/DataContainer>
32
//solid specific includes
33
#include <Solid/DeviceNotifier>
34
#include <Solid/Device>
35
#include <Solid/DeviceInterface>
36
#include <Solid/StorageDrive>
37
#include <Solid/StorageVolume>
39
//#define HOTPLUGENGINE_TIMING
41
HotplugEngine::HotplugEngine(QObject* parent, const QVariantList& args)
42
: Plasma::DataEngine(parent, args),
43
m_dirWatch(new KDirWatch(this))
45
QStringList folders = KGlobal::dirs()->findDirs("data", "solid/actions/");
46
foreach (const QString &folder, folders) {
47
m_dirWatch->addDir(folder, KDirWatch::WatchFiles);
49
connect(m_dirWatch, SIGNAL(dirty(const QString &)), this, SLOT(updatePredicates(const QString &)));
52
HotplugEngine::~HotplugEngine()
57
void HotplugEngine::init()
61
Solid::Predicate p(Solid::DeviceInterface::StorageAccess);
62
p |= Solid::Predicate(Solid::DeviceInterface::StorageDrive);
63
p |= Solid::Predicate(Solid::DeviceInterface::StorageVolume);
64
p |= Solid::Predicate(Solid::DeviceInterface::OpticalDrive);
65
p |= Solid::Predicate(Solid::DeviceInterface::PortableMediaPlayer);
66
p |= Solid::Predicate(Solid::DeviceInterface::SmartCardReader);
67
p |= Solid::Predicate(Solid::DeviceInterface::Camera);
68
QList<Solid::Device> devices = Solid::Device::listFromQuery(p);
69
foreach (const Solid::Device &dev, devices) {
70
m_startList.insert(dev.udi(), dev);
73
connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(const QString &)),
74
this, SLOT(onDeviceAdded(const QString &)));
75
connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(const QString &)),
76
this, SLOT(onDeviceRemoved(const QString &)));
78
m_encryptedPredicate = Solid::Predicate("StorageVolume", "usage", "Encrypted");
80
processNextStartupDevice();
83
void HotplugEngine::processNextStartupDevice()
85
if (!m_startList.isEmpty()) {
86
QHash<QString, Solid::Device>::iterator it = m_startList.begin();
87
//Solid::Device dev = const_cast<Solid::Device &>(m_startList.takeFirst());
88
onDeviceAdded(it.value(), false);
89
m_startList.erase(it);
92
if (m_startList.isEmpty()) {
95
QTimer::singleShot(0, this, SLOT(processNextStartupDevice()));
99
void HotplugEngine::findPredicates()
101
m_predicates.clear();
103
foreach (const QString &path, KGlobal::dirs()->findAllResources("data", "solid/actions/")) {
104
KDesktopFile cfg(path);
105
const QString string_predicate = cfg.desktopGroup().readEntry("X-KDE-Solid-Predicate");
106
//kDebug() << path << string_predicate;
107
m_predicates.insert(KUrl(path).fileName(), Solid::Predicate::fromString(string_predicate));
110
if (m_predicates.isEmpty()) {
111
m_predicates.insert(QString(), Solid::Predicate::fromString(QString()));
115
void HotplugEngine::updatePredicates(const QString &path)
121
QHashIterator<QString, Solid::Device> it(m_devices);
122
while (it.hasNext()) {
124
Solid::Device device(it.value());
125
QString udi(it.key());
127
const QStringList predicates = predicatesForDevice(device);
128
if (!predicates.isEmpty()) {
129
if (sources().contains(udi)) {
130
Plasma::DataEngine::Data data;
131
data.insert("predicateFiles", predicates);
134
onDeviceAdded(device, false);
136
} else if (!m_encryptedPredicate.matches(device) && sources().contains(udi)) {
138
scheduleSourcesUpdated();
143
QStringList HotplugEngine::predicatesForDevice(Solid::Device &device) const
145
QStringList interestingDesktopFiles;
146
//search in all desktop configuration file if the device inserted is a correct device
147
QHashIterator<QString, Solid::Predicate> it(m_predicates);
148
//kDebug() << "=================" << udi;
149
while (it.hasNext()) {
151
if (it.value().matches(device)) {
152
//kDebug() << " hit" << it.key();
153
interestingDesktopFiles << it.key();
157
return interestingDesktopFiles;
160
void HotplugEngine::onDeviceAdded(const QString &udi)
162
Solid::Device device(udi);
163
onDeviceAdded(device);
166
void HotplugEngine::onDeviceAdded(Solid::Device &device, bool added)
168
//kDebug() << "adding" << device.udi();
169
#ifdef HOTPLUGENGINE_TIMING
173
// Skip things we know we don't care about
174
if (device.isDeviceInterface(Solid::DeviceInterface::StorageDrive)) {
175
Solid::DeviceInterface *dev = device.asDeviceInterface(Solid::DeviceInterface::StorageDrive);
176
Solid::StorageDrive *drive = static_cast<Solid::StorageDrive *>(dev);
177
if (!drive->isHotpluggable()) {
178
#ifdef HOTPLUGENGINE_TIMING
179
kDebug() << "storage, but not pluggable, returning" << t.restart();
183
} else if (device.isDeviceInterface(Solid::DeviceInterface::StorageVolume)) {
184
Solid::DeviceInterface *dev = device.asDeviceInterface(Solid::DeviceInterface::StorageVolume);
185
Solid::StorageVolume *volume = static_cast<Solid::StorageVolume *>(dev);
186
Solid::StorageVolume::UsageType type = volume->usage();
187
if (type == Solid::StorageVolume::Unused ||
188
type == Solid::StorageVolume::PartitionTable) {
189
#ifdef HOTPLUGENGINE_TIMING
190
kDebug() << "storage volume, but not of interest" << t.restart();
196
m_devices.insert(device.udi(), device);
198
if (m_predicates.isEmpty()) {
202
const QStringList interestingDesktopFiles = predicatesForDevice(device);
203
const bool isEncryptedContainer = m_encryptedPredicate.matches(device);
205
if (!interestingDesktopFiles.isEmpty() || isEncryptedContainer) {
206
//kDebug() << device.product();
207
//kDebug() << device.vendor();
208
//kDebug() << "number of interesting desktop file : " << interestingDesktopFiles.size();
209
Plasma::DataEngine::Data data;
210
data.insert("added", added);
211
data.insert("udi", device.udi());
213
if (!device.description().isEmpty()) {
214
data.insert("text", device.description());
216
data.insert("text", QString(device.vendor() + QLatin1Char(' ') + device.product()));
218
data.insert("icon", device.icon());
219
data.insert("emblems", device.emblems());
220
data.insert("predicateFiles", interestingDesktopFiles);
221
data.insert("isEncryptedContainer", isEncryptedContainer);
223
setData(device.udi(), data);
224
//kDebug() << "add hardware solid : " << udi;
227
#ifdef HOTPLUGENGINE_TIMING
228
kDebug() << "total time" << t.restart();
232
void HotplugEngine::onDeviceRemoved(const QString &udi)
234
//kDebug() << "remove hardware:" << udi;
236
if (m_startList.contains(udi)) {
237
m_startList.remove(udi);
241
m_devices.remove(udi);
243
scheduleSourcesUpdated();
246
#include "hotplugengine.moc"