Changeset View
Standalone View
src/solid/devices/backends/iokit/iokitdevice.cpp
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | Copyright 2009 Harald Fernengel <harry@kdevelop.org> | 2 | Copyright 2009 Harald Fernengel <harry@kdevelop.org> | ||
3 | Copyright 2017 René J.V. Bertin <rjvbertin@gmail.com> | ||||
3 | 4 | | |||
4 | This library is free software; you can redistribute it and/or | 5 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | 6 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | 7 | License as published by the Free Software Foundation; either | ||
7 | version 2.1 of the License, or (at your option) version 3, or any | 8 | version 2.1 of the License, or (at your option) version 3, or any | ||
8 | later version accepted by the membership of KDE e.V. (or its | 9 | later version accepted by the membership of KDE e.V. (or its | ||
9 | successor approved by the membership of KDE e.V.), which shall | 10 | successor approved by the membership of KDE e.V.), which shall | ||
10 | act as a proxy defined in Section 6 of version 3 of the license. | 11 | act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | 12 | | |||
12 | This library is distributed in the hope that it will be useful, | 13 | This library is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | Lesser General Public License for more details. | 16 | Lesser General Public License for more details. | ||
16 | 17 | | |||
17 | You should have received a copy of the GNU Lesser General Public | 18 | You should have received a copy of the GNU Lesser General Public | ||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | 19 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 20 | */ | ||
20 | 21 | | |||
21 | #include "iokitdevice.h" | 22 | #include "iokitdevice.h" | ||
22 | #include "iokitgenericinterface.h" | 23 | #include "iokitgenericinterface.h" | ||
23 | #include "iokitprocessor.h" | 24 | #include "iokitprocessor.h" | ||
24 | #include "iokitbattery.h" | 25 | #include "iokitbattery.h" | ||
26 | #include "iokitstorage.h" | ||||
27 | #include "iokitstorageaccess.h" | ||||
28 | #include "iokitvolume.h" | ||||
29 | #include "iokitopticaldrive.h" | ||||
30 | #include "iokitopticaldisc.h" | ||||
31 | | ||||
32 | #include <QDebug> | ||||
33 | #include <QSet> | ||||
34 | #include <QPointer> | ||||
35 | #include <QUrl> | ||||
25 | 36 | | |||
26 | #include <QtCore/qdebug.h> | 37 | #include <sys/types.h> | ||
38 | #include <sys/sysctl.h> | ||||
27 | 39 | | |||
28 | #include <IOKit/IOKitLib.h> | 40 | #include <IOKit/IOKitLib.h> | ||
29 | #include <IOKit/usb/IOUSBLib.h> | 41 | #include <IOKit/usb/IOUSBLib.h> | ||
30 | #include <IOKit/network/IOEthernetInterface.h> | 42 | #include <IOKit/network/IOEthernetInterface.h> | ||
31 | 43 | | |||
32 | #include <CoreFoundation/CoreFoundation.h> | 44 | #include <CoreFoundation/CoreFoundation.h> | ||
33 | 45 | | |||
34 | // from cfhelper.cpp | 46 | // from cfhelper.cpp | ||
35 | extern QMap<QString, QVariant> q_toVariantMap(const CFMutableDictionaryRef &dict); | 47 | extern QMap<QString, QVariant> q_toVariantMap(const CFMutableDictionaryRef &dict); | ||
48 | extern bool q_sysctlbyname(const char *name, QString &result); | ||||
49 | | ||||
50 | typedef QSet<Solid::DeviceInterface::Type> DeviceInterfaceTypes; | ||||
36 | 51 | | |||
37 | namespace Solid | 52 | namespace Solid | ||
38 | { | 53 | { | ||
39 | namespace Backends | 54 | namespace Backends | ||
40 | { | 55 | { | ||
41 | namespace IOKit | 56 | namespace IOKit | ||
42 | { | 57 | { | ||
43 | 58 | | |||
44 | // returns a solid type from an entry and its properties | 59 | // returns a solid type from an entry and its properties | ||
45 | static Solid::DeviceInterface::Type typeFromEntry(const io_registry_entry_t &entry, | 60 | static DeviceInterfaceTypes typesFromEntry(const io_registry_entry_t &entry, | ||
46 | const QMap<QString, QVariant> &properties) | 61 | const QMap<QString, QVariant> &properties, | ||
62 | Solid::DeviceInterface::Type &mainType) | ||||
47 | { | 63 | { | ||
64 | DeviceInterfaceTypes types; | ||||
65 | mainType = Solid::DeviceInterface::Unknown; | ||||
48 | if (IOObjectConformsTo(entry, "AppleACPICPU")) { | 66 | if (IOObjectConformsTo(entry, "AppleACPICPU")) { | ||
49 | return Solid::DeviceInterface::Processor; | 67 | mainType = Solid::DeviceInterface::Processor; | ||
68 | types << mainType; | ||||
50 | } | 69 | } | ||
51 | if (IOObjectConformsTo(entry, "AppleSmartBattery")) { | 70 | if (IOObjectConformsTo(entry, "AppleSmartBattery")) { | ||
52 | return Solid::DeviceInterface::Battery; | 71 | mainType = Solid::DeviceInterface::Battery; | ||
72 | types << mainType; | ||||
73 | } | ||||
74 | const QString bsdName = QStringLiteral("BSD Name"), | ||||
75 | leaf = QStringLiteral("Leaf"); | ||||
76 | if (IOObjectConformsTo(entry, "IOCDMedia") | ||||
77 | || IOObjectConformsTo(entry, "IODVDMedia") | ||||
78 | || IOObjectConformsTo(entry, "IOBDMedia")) { | ||||
79 | mainType = Solid::DeviceInterface::OpticalDrive; | ||||
80 | types << mainType | ||||
81 | << Solid::DeviceInterface::OpticalDisc; | ||||
82 | } | ||||
83 | if (properties.contains(bsdName) && properties.value(bsdName).toString().startsWith(QStringLiteral("disk"))) { | ||||
84 | if ((properties.contains(leaf) && properties.value(leaf).toBool() == false) | ||||
85 | || mainType == Solid::DeviceInterface::OpticalDrive) { | ||||
86 | if (mainType == Solid::DeviceInterface::Unknown) { | ||||
87 | mainType = Solid::DeviceInterface::StorageDrive; | ||||
88 | } | ||||
89 | types << Solid::DeviceInterface::StorageDrive; | ||||
90 | } else if (mainType == Solid::DeviceInterface::Unknown) { | ||||
91 | mainType = Solid::DeviceInterface::StorageVolume; | ||||
92 | } | ||||
93 | types << Solid::DeviceInterface::StorageVolume; | ||||
53 | } | 94 | } | ||
54 | 95 | | |||
55 | return Solid::DeviceInterface::Unknown; | 96 | if (types.isEmpty()) { | ||
97 | types << mainType; | ||||
98 | // qWarning() << "unsupported entry" << entry << "with properties" << properties; | ||||
99 | } | ||||
100 | | ||||
101 | return types; | ||||
56 | } | 102 | } | ||
57 | 103 | | |||
58 | // gets all properties from an entry into a QMap | 104 | // gets all properties from an entry into a QMap | ||
59 | static QMap<QString, QVariant> getProperties(const io_registry_entry_t &entry) | 105 | static QMap<QString, QVariant> getProperties(const io_registry_entry_t &entry) | ||
60 | { | 106 | { | ||
61 | CFMutableDictionaryRef propertyDict = 0; | 107 | CFMutableDictionaryRef propertyDict = 0; | ||
62 | 108 | | |||
63 | if (IORegistryEntryCreateCFProperties(entry, &propertyDict, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) { | 109 | if (IORegistryEntryCreateCFProperties(entry, &propertyDict, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) { | ||
64 | return QMap<QString, QVariant>(); | 110 | return QMap<QString, QVariant>(); | ||
65 | } | 111 | } | ||
66 | 112 | | |||
67 | QMap<QString, QVariant> result = q_toVariantMap(propertyDict); | 113 | QMap<QString, QVariant> result = q_toVariantMap(propertyDict); | ||
68 | 114 | | |||
69 | CFRelease(propertyDict); | 115 | CFRelease(propertyDict); | ||
70 | 116 | | |||
117 | io_name_t className; | ||||
118 | IOObjectGetClass(entry, className); | ||||
119 | result["className"] = QString::fromUtf8(className); | ||||
120 | | ||||
71 | return result; | 121 | return result; | ||
72 | } | 122 | } | ||
73 | 123 | | |||
74 | // gets the parent's Udi from an entry | 124 | // gets the parent's Udi from an entry | ||
75 | static QString getParentDeviceUdi(const io_registry_entry_t &entry) | 125 | static QString getParentDeviceUdi(const io_registry_entry_t &entry) | ||
76 | { | 126 | { | ||
77 | io_registry_entry_t parent = 0; | 127 | io_registry_entry_t parent = 0; | ||
78 | kern_return_t ret = IORegistryEntryGetParentEntry(entry, kIOServicePlane, &parent); | 128 | kern_return_t ret = IORegistryEntryGetParentEntry(entry, kIOServicePlane, &parent); | ||
Show All 10 Lines | |||||
89 | } | 139 | } | ||
90 | 140 | | |||
91 | // now we can release the parent | 141 | // now we can release the parent | ||
92 | IOObjectRelease(parent); | 142 | IOObjectRelease(parent); | ||
93 | 143 | | |||
94 | return result; | 144 | return result; | ||
95 | } | 145 | } | ||
96 | 146 | | |||
147 | static const QString computerModel() | ||||
148 | { | ||||
anthonyfieroni: QString has a default constructor. | |||||
149 | QString qModel; | ||||
anthonyfieroni: nullptr even on C functions | |||||
150 | q_sysctlbyname("hw.model", qModel); | ||||
151 | return qModel; | ||||
kfunk: Use `nullptr` everywhere | |||||
152 | } | ||||
153 | | ||||
97 | class IOKitDevicePrivate | 154 | class IOKitDevicePrivate | ||
kfunk: Style: Use `qModel = ...` | |||||
98 | { | 155 | { | ||
99 | public: | 156 | public: | ||
kfunk: `new`/`delete` mismatch. Use `delete[]` | |||||
(This keeps biting me. Even C doesn't have separate de/allocators for pointers to scalars and pointers to arrays ...) rjvbb: (This keeps biting me. Even C doesn't have separate de/allocators for pointers to scalars and… | |||||
100 | inline IOKitDevicePrivate() | 157 | inline IOKitDevicePrivate() | ||
101 | : type(Solid::DeviceInterface::Unknown) | 158 | : type({Solid::DeviceInterface::Unknown}) | ||
102 | {} | 159 | , parentDevice(nullptr) | ||
160 | { | ||||
161 | } | ||||
162 | ~IOKitDevicePrivate() | ||||
163 | { | ||||
164 | if (parentDevice) { | ||||
165 | delete parentDevice; | ||||
166 | parentDevice = nullptr; | ||||
167 | } | ||||
kfunk: Initialize at class member decl | |||||
168 | } | ||||
103 | 169 | | |||
104 | void init(const QString &udiString, const io_registry_entry_t &entry); | 170 | void init(const QString &udiString, const io_registry_entry_t &entry); | ||
171 | IOKitDevice* getParentDevice(); | ||||
That's *very* odd style. Why does a private class delete its public counterpart? I've never seen this. kfunk: That's *very* odd style. Why does a private class delete its public counterpart? I've never… | |||||
Heh, that's because there is (was) a confusion in parenthood here. The member var didn't point to the private class parent, but holds a reference to the parent of the current IOKit device. Currently it's used and thus allocated only when getting the device icon. rjvbb: Heh, that's because there is (was) a confusion in parenthood here. The member var didn't point… | |||||
105 | 172 | | |||
106 | QString udi; | 173 | QString udi; | ||
107 | QString parentUdi; | 174 | QString parentUdi; | ||
108 | QMap<QString, QVariant> properties; | 175 | QMap<QString, QVariant> properties; | ||
109 | Solid::DeviceInterface::Type type; | 176 | DeviceInterfaceTypes type; | ||
177 | Solid::DeviceInterface::Type mainType; | ||||
178 | IOKitDevice *parentDevice; | ||||
110 | }; | 179 | }; | ||
111 | 180 | | |||
112 | void IOKitDevicePrivate::init(const QString &udiString, const io_registry_entry_t &entry) | 181 | void IOKitDevicePrivate::init(const QString &udiString, const io_registry_entry_t &entry) | ||
113 | { | 182 | { | ||
114 | Q_ASSERT(entry != MACH_PORT_NULL); | 183 | Q_ASSERT(entry != MACH_PORT_NULL); | ||
115 | 184 | | |||
116 | udi = udiString; | 185 | udi = udiString; | ||
117 | 186 | | |||
118 | properties = getProperties(entry); | 187 | properties = getProperties(entry); | ||
119 | 188 | | |||
120 | io_name_t className; | | |||
121 | IOObjectGetClass(entry, className); | | |||
122 | properties["className"] = QString::fromUtf8(className); | | |||
123 | | ||||
124 | parentUdi = getParentDeviceUdi(entry); | 189 | parentUdi = getParentDeviceUdi(entry); | ||
125 | type = typeFromEntry(entry, properties); | 190 | type = typesFromEntry(entry, properties, mainType); | ||
191 | if (udi.contains(QStringLiteral("IOBD")) || udi.contains(QStringLiteral("BD PX"))) { | ||||
192 | qWarning() << "Solid: BlueRay entry" << entry << "mainType=" << mainType << "typeList:" << type | ||||
193 | << "with properties" << properties; | ||||
194 | } | ||||
195 | if (mainType != Solid::DeviceInterface::Unknown) { | ||||
196 | } | ||||
126 | 197 | | |||
Don't leave commented code around. Either enable this code paths properly via categorized logging or remove it altogether. kfunk: Don't leave commented code around. Either enable this code paths properly via categorized… | |||||
I'd love to, but Solid doesn't have any modern logging set up. Rather than introducing that through the back(end) door, wouldn't it be better if this were done for all of Solid? (Preferably by someone having a good overview of the entire framework...) rjvbb: I'd love to, but Solid doesn't have any modern logging set up. Rather than introducing that… | |||||
127 | IOObjectRelease(entry); | 198 | IOObjectRelease(entry); | ||
128 | } | 199 | } | ||
129 | 200 | | |||
201 | IOKitDevice* IOKitDevicePrivate::getParentDevice() | ||||
202 | { | ||||
203 | if (!parentDevice) { | ||||
204 | parentDevice = new IOKitDevice(parentUdi); | ||||
205 | } | ||||
206 | return parentDevice; | ||||
207 | } | ||||
208 | | ||||
130 | IOKitDevice::IOKitDevice(const QString &udi, const io_registry_entry_t &entry) | 209 | IOKitDevice::IOKitDevice(const QString &udi, const io_registry_entry_t &entry) | ||
131 | : d(new IOKitDevicePrivate) | 210 | : d(new IOKitDevicePrivate) | ||
132 | { | 211 | { | ||
133 | d->init(udi, entry); | 212 | d->init(udi, entry); | ||
134 | } | 213 | } | ||
135 | 214 | | |||
136 | IOKitDevice::IOKitDevice(const QString &udi) | 215 | IOKitDevice::IOKitDevice(const QString &udi) | ||
137 | : d(new IOKitDevicePrivate) | 216 | : d(new IOKitDevicePrivate) | ||
138 | { | 217 | { | ||
218 | if (udi.isEmpty()) { | ||||
219 | qWarning() << Q_FUNC_INFO << "Tried to create Device from empty UDI"; | ||||
220 | return; | ||||
221 | } | ||||
222 | | ||||
139 | io_registry_entry_t entry = IORegistryEntryFromPath( | 223 | io_registry_entry_t entry = IORegistryEntryFromPath( | ||
140 | kIOMasterPortDefault, | 224 | kIOMasterPortDefault, | ||
141 | udi.toLocal8Bit().constData()); | 225 | udi.toLocal8Bit().constData()); | ||
142 | 226 | | |||
143 | if (entry == MACH_PORT_NULL) { | 227 | if (entry == MACH_PORT_NULL) { | ||
144 | qDebug() << Q_FUNC_INFO << "Tried to create Device from invalid UDI" << udi; | 228 | qWarning() << Q_FUNC_INFO << "Tried to create Device from invalid UDI" << udi; | ||
145 | return; | 229 | return; | ||
146 | } | 230 | } | ||
147 | 231 | | |||
148 | d->init(udi, entry); | 232 | d->init(udi, entry); | ||
149 | } | 233 | } | ||
150 | 234 | | |||
235 | IOKitDevice::IOKitDevice(const IOKitDevice &device) | ||||
236 | : d(new IOKitDevicePrivate) | ||||
237 | { | ||||
238 | if (device.udi().isEmpty()) { | ||||
239 | qWarning() << Q_FUNC_INFO << "Tried to create Device from empty UDI"; | ||||
240 | return; | ||||
241 | } | ||||
242 | | ||||
243 | io_registry_entry_t entry = IORegistryEntryFromPath( | ||||
244 | kIOMasterPortDefault, | ||||
245 | device.udi().toLocal8Bit().constData()); | ||||
246 | | ||||
247 | if (entry == MACH_PORT_NULL) { | ||||
248 | qWarning() << Q_FUNC_INFO << "Tried to create Device from invalid UDI" << device.udi(); | ||||
249 | return; | ||||
250 | } | ||||
251 | | ||||
252 | d->init(device.udi(), entry); | ||||
253 | } | ||||
254 | | ||||
151 | IOKitDevice::~IOKitDevice() | 255 | IOKitDevice::~IOKitDevice() | ||
152 | { | 256 | { | ||
153 | delete d; | 257 | delete d; | ||
154 | } | 258 | } | ||
155 | 259 | | |||
260 | bool IOKitDevice::conformsToIOKitClass(const QString &className) const | ||||
261 | { | ||||
262 | bool conforms = false; | ||||
263 | if (!className.isEmpty()) { | ||||
264 | io_registry_entry_t entry = IORegistryEntryFromPath( | ||||
265 | kIOMasterPortDefault, | ||||
266 | udi().toLocal8Bit().constData()); | ||||
267 | if (entry != MACH_PORT_NULL) { | ||||
268 | conforms = IOObjectConformsTo(entry, className.toLocal8Bit().constData()); | ||||
269 | IOObjectRelease(entry); | ||||
270 | } | ||||
271 | } | ||||
272 | return conforms; | ||||
273 | } | ||||
274 | | ||||
156 | QString IOKitDevice::udi() const | 275 | QString IOKitDevice::udi() const | ||
157 | { | 276 | { | ||
158 | return d->udi; | 277 | return d->udi; | ||
159 | } | 278 | } | ||
160 | 279 | | |||
161 | QString IOKitDevice::parentUdi() const | 280 | QString IOKitDevice::parentUdi() const | ||
162 | { | 281 | { | ||
163 | return d->parentUdi; | 282 | return d->parentUdi; | ||
164 | } | 283 | } | ||
165 | 284 | | |||
166 | QString IOKitDevice::vendor() const | 285 | QString IOKitDevice::vendor() const | ||
167 | { | 286 | { | ||
168 | return QString(); // TODO | 287 | QString vendor; | ||
288 | if (parentUdi().isEmpty()) { | ||||
289 | return QStringLiteral("Apple"); | ||||
290 | } | ||||
291 | switch (d->mainType) { | ||||
292 | case Solid::DeviceInterface::Processor: | ||||
293 | return Processor::vendor(); | ||||
294 | break; | ||||
anthonyfieroni: break after return is useless | |||||
I know, I do this as a matter of principle (and I'll leave it in since I'll undoubtedly be the principal maintainer of this code for the foreseeable future). rjvbb: I know, I do this as a matter of principle (and I'll leave it in since I'll undoubtedly be the… | |||||
295 | case Solid::DeviceInterface::Battery: | ||||
296 | return property(QStringLiteral("Manufacturer")).toString(); | ||||
297 | break; | ||||
298 | case Solid::DeviceInterface::StorageDrive: | ||||
299 | case Solid::DeviceInterface::OpticalDrive: | ||||
300 | case Solid::DeviceInterface::OpticalDisc: | ||||
301 | return IOKitStorage(this).vendor(); | ||||
302 | break; | ||||
303 | case Solid::DeviceInterface::StorageVolume: | ||||
304 | return IOKitVolume(this).vendor(); | ||||
305 | break; | ||||
306 | default: | ||||
307 | return QString(); | ||||
Why not return here as well? For consistency. You can end the function with Q_UNREACHABLE(); return {}; Very common pattern. kfunk: Why not `return` here as well? For consistency.
You can end the function with
```… | |||||
308 | break; | ||||
309 | } | ||||
310 | return QString(); | ||||
169 | } | 311 | } | ||
170 | 312 | | |||
171 | QString IOKitDevice::product() const | 313 | QString IOKitDevice::product() const | ||
172 | { | 314 | { | ||
315 | if (parentUdi().isEmpty()) { | ||||
316 | return computerModel(); | ||||
317 | } | ||||
318 | switch (d->mainType) { | ||||
319 | case Solid::DeviceInterface::Processor: | ||||
320 | return Processor::product(); | ||||
321 | break; | ||||
322 | case Solid::DeviceInterface::Battery: | ||||
323 | return property(QStringLiteral("DeviceName")).toString(); | ||||
324 | break; | ||||
325 | case Solid::DeviceInterface::StorageDrive: | ||||
326 | case Solid::DeviceInterface::OpticalDrive: | ||||
327 | case Solid::DeviceInterface::OpticalDisc: | ||||
328 | return IOKitStorage(this).product(); | ||||
329 | break; | ||||
330 | case Solid::DeviceInterface::StorageVolume: | ||||
331 | return IOKitVolume(this).product(); | ||||
332 | break; | ||||
333 | } | ||||
173 | return QString(); // TODO | 334 | return QString(); // TODO | ||
174 | } | 335 | } | ||
175 | 336 | | |||
176 | QString IOKitDevice::icon() const | 337 | QString IOKitDevice::description() const | ||
177 | { | 338 | { | ||
178 | return QString(); // TODO | 339 | switch (d->mainType) { | ||
340 | case Solid::DeviceInterface::Processor: | ||||
341 | return QStringLiteral("Processor"); | ||||
342 | break; | ||||
343 | case Solid::DeviceInterface::Battery: | ||||
344 | return QStringLiteral("Apple Smart Battery"); | ||||
345 | break; | ||||
346 | case Solid::DeviceInterface::StorageDrive: | ||||
347 | case Solid::DeviceInterface::OpticalDrive: | ||||
348 | case Solid::DeviceInterface::OpticalDisc: | ||||
349 | return IOKitStorage(this).description(); | ||||
350 | break; | ||||
351 | case Solid::DeviceInterface::StorageVolume: { | ||||
352 | const QString volLabel = IOKitVolume(this).description(); | ||||
353 | const QString mountPoint = IOKitStorageAccess(this).filePath(); | ||||
354 | if (volLabel.isEmpty()) { | ||||
355 | return QUrl::fromLocalFile(mountPoint).fileName(); | ||||
356 | } else if (mountPoint.startsWith(QStringLiteral("/Volumes/"))) { | ||||
357 | // Mac users will expect to see the name under which the volume is mounted here. | ||||
358 | return QString(QStringLiteral("%1 (%2)")).arg(QUrl::fromLocalFile(mountPoint).fileName()).arg(volLabel); | ||||
359 | } | ||||
360 | return volLabel; | ||||
361 | break; | ||||
362 | } | ||||
363 | } | ||||
364 | return product(); // TODO | ||||
179 | } | 365 | } | ||
180 | 366 | | |||
181 | QStringList IOKitDevice::emblems() const | 367 | QString IOKitDevice::icon() const | ||
182 | { | 368 | { | ||
183 | return QStringList(); // TODO | 369 | // adapted from HalDevice::icon() | ||
370 | if (parentUdi().isEmpty()) { | ||||
371 | if (computerModel().contains(QStringLiteral("MacBook"))) { | ||||
372 | return QStringLiteral("computer-laptop"); | ||||
373 | } else { | ||||
374 | return QStringLiteral("computer"); | ||||
375 | } | ||||
376 | | ||||
377 | } else if (d->type.contains(Solid::DeviceInterface::StorageDrive)) { | ||||
anthonyfieroni: QStringLiteral | |||||
378 | IOKitStorage drive(this); | ||||
379 | Solid::StorageDrive::DriveType driveType = drive.driveType(); | ||||
380 | | ||||
381 | switch (driveType) { | ||||
382 | case Solid::StorageDrive::Floppy: | ||||
383 | // why not :) | ||||
384 | return QStringLiteral("media-floppy"); | ||||
385 | break; | ||||
386 | case Solid::StorageDrive::CdromDrive: { | ||||
387 | const IOKitOpticalDisc disc(this); | ||||
388 | if (disc.availableContent() == Solid::OpticalDisc::Audio ) { | ||||
389 | return QStringLiteral("media-optical-audio"); | ||||
390 | } else switch (disc.discType()) { | ||||
391 | case Solid::OpticalDisc::CdRom: | ||||
392 | return QStringLiteral("media-optical-data"); | ||||
393 | break; | ||||
394 | case Solid::OpticalDisc::CdRecordable: | ||||
395 | case Solid::OpticalDisc::CdRewritable: | ||||
396 | return QStringLiteral("media-optical-recordable"); | ||||
397 | break; | ||||
398 | case Solid::OpticalDisc::BluRayRom: | ||||
399 | case Solid::OpticalDisc::BluRayRecordable: | ||||
400 | case Solid::OpticalDisc::BluRayRewritable: | ||||
401 | return QStringLiteral("media-optical-blu-ray"); | ||||
402 | break; | ||||
403 | } | ||||
404 | break; | ||||
405 | } | ||||
406 | case Solid::StorageDrive::SdMmc: | ||||
407 | return QStringLiteral("media-flash-sd-mmc"); | ||||
408 | break; | ||||
409 | case Solid::StorageDrive::CompactFlash: | ||||
410 | return QStringLiteral("media-flash-cf"); | ||||
411 | break; | ||||
412 | } | ||||
413 | if (drive.bus() == Solid::StorageDrive::Usb) { | ||||
414 | return QStringLiteral("drive-removable-media-usb"); | ||||
184 | } | 415 | } | ||
416 | if (drive.isRemovable()) { | ||||
417 | return QStringLiteral("drive-removable-media"); | ||||
418 | } | ||||
419 | return QStringLiteral("drive-harddisk"); | ||||
185 | 420 | | |||
186 | QString IOKitDevice::description() const | 421 | } else if (d->mainType == Solid::DeviceInterface::StorageVolume) { | ||
422 | } else if (d->mainType == Solid::DeviceInterface::Battery) { | ||||
423 | return QStringLiteral("battery"); | ||||
424 | } else if (d->mainType == Solid::DeviceInterface::Processor) { | ||||
425 | return QStringLiteral("cpu"); // FIXME: Doesn't follow icon spec | ||||
426 | } else { | ||||
427 | QString iconName = d->getParentDevice()->icon(); | ||||
428 | | ||||
429 | if (!iconName.isEmpty()) { | ||||
430 | return iconName; | ||||
431 | } | ||||
432 | | ||||
433 | return QStringLiteral("drive-harddisk"); | ||||
434 | } | ||||
435 | return QString(); | ||||
436 | } | ||||
437 | | ||||
438 | QStringList IOKitDevice::emblems() const | ||||
187 | { | 439 | { | ||
188 | return product(); // TODO | 440 | return QStringList(); // TODO | ||
189 | } | 441 | } | ||
190 | 442 | | |||
191 | QVariant IOKitDevice::property(const QString &key) const | 443 | QVariant IOKitDevice::property(const QString &key) const | ||
192 | { | 444 | { | ||
445 | if (!d->properties.contains(key)) { | ||||
446 | return QObject::property(key.toUtf8()); | ||||
447 | } | ||||
193 | return d->properties.value(key); | 448 | return d->properties.value(key); | ||
194 | } | 449 | } | ||
195 | 450 | | |||
196 | QMap<QString, QVariant> IOKitDevice::allProperties() const | 451 | QMap<QString, QVariant> IOKitDevice::allProperties() const | ||
197 | { | 452 | { | ||
198 | return d->properties; | 453 | return d->properties; | ||
199 | } | 454 | } | ||
200 | 455 | | |||
201 | bool IOKitDevice::propertyExists(const QString &key) const | 456 | bool IOKitDevice::iOKitPropertyExists(const QString &key) const | ||
202 | { | 457 | { | ||
203 | return d->properties.contains(key); | 458 | return d->properties.contains(key); | ||
204 | } | 459 | } | ||
205 | 460 | | |||
206 | bool IOKitDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const | 461 | bool IOKitDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const | ||
207 | { | 462 | { | ||
208 | return (type == Solid::DeviceInterface::GenericInterface | 463 | switch (type) { | ||
209 | || type == d->type); | 464 | case Solid::DeviceInterface::GenericInterface: | ||
465 | return true; | ||||
466 | break; | ||||
467 | case Solid::DeviceInterface::StorageAccess: | ||||
468 | if (d->type.contains(Solid::DeviceInterface::StorageDrive) | ||||
469 | || d->type.contains(Solid::DeviceInterface::StorageVolume)) { | ||||
470 | return true; | ||||
471 | } | ||||
472 | break; | ||||
473 | default: | ||||
474 | return d->type.contains(type); | ||||
475 | break; | ||||
476 | } | ||||
477 | return false; | ||||
kfunk: Returning inside the case statements would make this code clearer as well. | |||||
I don't share that opinion and think that multiple exit points do not make the code more efficient either (judging from stepping through the code in a debugger). But whatever... rjvbb: I don't share that opinion and think that multiple exit points do not make the code more… | |||||
210 | } | 478 | } | ||
211 | 479 | | |||
212 | QObject *IOKitDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type) | 480 | QObject *IOKitDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type) | ||
213 | { | 481 | { | ||
214 | QObject *iface = 0; | 482 | QObject *iface = nullptr; | ||
215 | 483 | | |||
216 | switch (type) { | 484 | switch (type) { | ||
217 | case Solid::DeviceInterface::GenericInterface: | 485 | case Solid::DeviceInterface::GenericInterface: | ||
218 | iface = new GenericInterface(this); | 486 | iface = new GenericInterface(this); | ||
219 | break; | 487 | break; | ||
220 | case Solid::DeviceInterface::Processor: | 488 | case Solid::DeviceInterface::Processor: | ||
221 | if (d->type == Solid::DeviceInterface::Processor) { | 489 | if (d->type.contains(Solid::DeviceInterface::Processor)) { | ||
222 | iface = new Processor(this); | 490 | iface = new Processor(this); | ||
223 | } | 491 | } | ||
224 | break; | 492 | break; | ||
225 | case Solid::DeviceInterface::Battery: | 493 | case Solid::DeviceInterface::Battery: | ||
226 | if (d->type == Solid::DeviceInterface::Battery) { | 494 | if (d->type.contains(Solid::DeviceInterface::Battery)) { | ||
227 | iface = new Battery(this); | 495 | iface = new Battery(this); | ||
228 | } | 496 | } | ||
229 | break; | 497 | break; | ||
498 | case Solid::DeviceInterface::OpticalDrive: | ||||
499 | if (d->type.contains(Solid::DeviceInterface::OpticalDrive)) { | ||||
500 | iface = new IOKitOpticalDrive(this); | ||||
501 | } | ||||
502 | break; | ||||
503 | case Solid::DeviceInterface::OpticalDisc: | ||||
504 | if (d->type.contains(Solid::DeviceInterface::OpticalDisc)) { | ||||
505 | iface = new IOKitOpticalDisc(this); | ||||
506 | } | ||||
507 | break; | ||||
508 | case Solid::DeviceInterface::StorageDrive: | ||||
509 | if (d->type.contains(Solid::DeviceInterface::StorageDrive)) { | ||||
510 | iface = new IOKitStorage(this); | ||||
511 | } | ||||
512 | break; | ||||
513 | case Solid::DeviceInterface::Block: | ||||
514 | if (d->type.contains(Solid::DeviceInterface::OpticalDisc)) { | ||||
515 | iface = new IOKitOpticalDisc(this); | ||||
516 | } else if (d->type.contains(Solid::DeviceInterface::OpticalDrive)) { | ||||
517 | iface = new IOKitOpticalDrive(this); | ||||
518 | } else if (d->type.contains(Solid::DeviceInterface::StorageVolume)) { | ||||
519 | iface = new IOKitVolume(this); | ||||
520 | } else if (d->type.contains(Solid::DeviceInterface::StorageDrive)) { | ||||
521 | iface = new IOKitStorage(this); | ||||
522 | } | ||||
523 | break; | ||||
524 | case Solid::DeviceInterface::StorageVolume: | ||||
525 | if (d->type.contains(Solid::DeviceInterface::StorageVolume)) { | ||||
526 | iface = new IOKitVolume(this); | ||||
527 | } | ||||
528 | break; | ||||
529 | case Solid::DeviceInterface::StorageAccess: | ||||
530 | if (d->type.contains(Solid::DeviceInterface::StorageDrive) | ||||
531 | || d->type.contains(Solid::DeviceInterface::StorageVolume)) { | ||||
532 | iface = new IOKitStorageAccess(this); | ||||
533 | } | ||||
534 | break; | ||||
230 | // the rest is TODO | 535 | // the rest is TODO | ||
231 | } | 536 | } | ||
232 | 537 | | |||
233 | return iface; | 538 | return iface; | ||
234 | } | 539 | } | ||
235 | 540 | | |||
236 | } | 541 | } | ||
237 | } | 542 | } | ||
238 | } // namespaces | 543 | } // namespaces | ||
239 | 544 | |
QString has a default constructor.