~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to plasma/generic/dataengines/hotplug/hotplugengine.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   Copyright (C) 2007 Menard Alexis <darktears31@gmail.com>
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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.
 
18
*/
 
19
 
 
20
#include "hotplugengine.h"
 
21
 
 
22
#include <QTimer>
 
23
 
 
24
#include <KDirWatch>
 
25
#include <KConfigGroup>
 
26
#include <KDebug>
 
27
#include <KLocale>
 
28
#include <KStandardDirs>
 
29
#include <KDesktopFile>
 
30
#include <Plasma/DataContainer>
 
31
 
 
32
//solid specific includes
 
33
#include <Solid/DeviceNotifier>
 
34
#include <Solid/Device>
 
35
#include <Solid/DeviceInterface>
 
36
#include <Solid/StorageDrive>
 
37
#include <Solid/StorageVolume>
 
38
 
 
39
//#define HOTPLUGENGINE_TIMING
 
40
 
 
41
HotplugEngine::HotplugEngine(QObject* parent, const QVariantList& args)
 
42
    : Plasma::DataEngine(parent, args),
 
43
      m_dirWatch(new KDirWatch(this))
 
44
{
 
45
    QStringList folders = KGlobal::dirs()->findDirs("data", "solid/actions/");
 
46
    foreach (const QString &folder, folders) {
 
47
        m_dirWatch->addDir(folder, KDirWatch::WatchFiles);
 
48
    }
 
49
    connect(m_dirWatch, SIGNAL(dirty(const QString &)), this, SLOT(updatePredicates(const QString &)));
 
50
}
 
51
 
 
52
HotplugEngine::~HotplugEngine()
 
53
{
 
54
 
 
55
}
 
56
 
 
57
void HotplugEngine::init()
 
58
{
 
59
    findPredicates();
 
60
 
 
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);
 
71
    }
 
72
 
 
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 &)));
 
77
 
 
78
    m_encryptedPredicate = Solid::Predicate("StorageVolume", "usage", "Encrypted");
 
79
 
 
80
    processNextStartupDevice();
 
81
}
 
82
 
 
83
void HotplugEngine::processNextStartupDevice()
 
84
{
 
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);
 
90
    }
 
91
 
 
92
    if (m_startList.isEmpty()) {
 
93
        m_predicates.clear();
 
94
    } else {
 
95
        QTimer::singleShot(0, this, SLOT(processNextStartupDevice()));
 
96
    }
 
97
}
 
98
 
 
99
void HotplugEngine::findPredicates()
 
100
{
 
101
    m_predicates.clear();
 
102
 
 
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));
 
108
    }
 
109
 
 
110
    if (m_predicates.isEmpty()) {
 
111
        m_predicates.insert(QString(), Solid::Predicate::fromString(QString()));
 
112
    }
 
113
}
 
114
 
 
115
void HotplugEngine::updatePredicates(const QString &path)
 
116
{
 
117
    Q_UNUSED(path)
 
118
 
 
119
    findPredicates();
 
120
 
 
121
    QHashIterator<QString, Solid::Device> it(m_devices);
 
122
    while (it.hasNext()) {
 
123
        it.next();
 
124
        Solid::Device device(it.value());
 
125
        QString udi(it.key());
 
126
 
 
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);
 
132
                setData(udi, data);
 
133
            } else {
 
134
                onDeviceAdded(device, false);
 
135
            }
 
136
        } else if (!m_encryptedPredicate.matches(device) && sources().contains(udi)) {
 
137
            removeSource(udi);
 
138
            scheduleSourcesUpdated();
 
139
        }
 
140
    }
 
141
}
 
142
 
 
143
QStringList HotplugEngine::predicatesForDevice(Solid::Device &device) const
 
144
{
 
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()) {
 
150
        it.next();
 
151
        if (it.value().matches(device)) {
 
152
            //kDebug() << "     hit" << it.key();
 
153
            interestingDesktopFiles << it.key();
 
154
        }
 
155
    }
 
156
 
 
157
    return interestingDesktopFiles;
 
158
}
 
159
 
 
160
void HotplugEngine::onDeviceAdded(const QString &udi)
 
161
{
 
162
    Solid::Device device(udi);
 
163
    onDeviceAdded(device);
 
164
}
 
165
 
 
166
void HotplugEngine::onDeviceAdded(Solid::Device &device, bool added)
 
167
{
 
168
    //kDebug() << "adding" << device.udi();
 
169
#ifdef HOTPLUGENGINE_TIMING
 
170
    QTime t;
 
171
    t.start();
 
172
#endif
 
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();
 
180
#endif
 
181
            return;
 
182
        }
 
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();
 
191
#endif
 
192
            return;
 
193
        }
 
194
    }
 
195
 
 
196
    m_devices.insert(device.udi(), device);
 
197
 
 
198
    if (m_predicates.isEmpty()) {
 
199
        findPredicates();
 
200
    }
 
201
 
 
202
    const QStringList interestingDesktopFiles = predicatesForDevice(device);
 
203
    const bool isEncryptedContainer = m_encryptedPredicate.matches(device);
 
204
 
 
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());
 
212
 
 
213
        if (!device.description().isEmpty()) {
 
214
            data.insert("text", device.description());
 
215
        } else {
 
216
            data.insert("text", QString(device.vendor() + QLatin1Char(' ') + device.product()));
 
217
        }
 
218
        data.insert("icon", device.icon());
 
219
        data.insert("emblems", device.emblems());
 
220
        data.insert("predicateFiles", interestingDesktopFiles);
 
221
        data.insert("isEncryptedContainer", isEncryptedContainer);
 
222
 
 
223
        setData(device.udi(), data);
 
224
        //kDebug() << "add hardware solid : " << udi;
 
225
    }
 
226
 
 
227
#ifdef HOTPLUGENGINE_TIMING
 
228
    kDebug() << "total time" << t.restart();
 
229
#endif
 
230
}
 
231
 
 
232
void HotplugEngine::onDeviceRemoved(const QString &udi)
 
233
{
 
234
    //kDebug() << "remove hardware:" << udi;
 
235
 
 
236
    if (m_startList.contains(udi)) {
 
237
        m_startList.remove(udi);
 
238
        return;
 
239
    }
 
240
 
 
241
    m_devices.remove(udi);
 
242
    removeSource(udi);
 
243
    scheduleSourcesUpdated();
 
244
}
 
245
 
 
246
#include "hotplugengine.moc"