Solid

imobiledevice.cpp
1/*
2 SPDX-FileCopyrightText: 2020 MBition GmbH
3 SPDX-FileContributor: Kai Uwe Broulik <kai_uwe.broulik@mbition.io>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "imobiledevice.h"
9
10#include <QCoreApplication>
11#include <QScopeGuard>
12
13#include "imobile_debug.h"
14
15#include "imobile.h"
16#include "imobileportablemediaplayer.h"
17
18#include <libimobiledevice/libimobiledevice.h>
19#include <libimobiledevice/lockdown.h>
20
21using namespace Solid::Backends::IMobile;
22
23IMobileDevice::IMobileDevice(const QString &udi)
24 : Solid::Ifaces::Device()
25 , m_udi(udi)
26{
27 const QString deviceId = udi.mid(udiPrefix().length() + 1);
28
29 idevice_t device;
30 auto ret = idevice_new(&device, deviceId.toUtf8().constData());
31 if (ret != IDEVICE_E_SUCCESS) {
32 qCWarning(IMOBILE) << "Failed to create device instance for" << deviceId << ret;
33 return;
34 }
35
36 auto deviceCleanup = qScopeGuard([device] {
37 idevice_free(device);
38 });
39
40 lockdownd_client_t lockdowndClient = nullptr;
41 auto lockdownRet = lockdownd_client_new(device, &lockdowndClient, "kde_solid_imobile");
42 if (lockdownRet != LOCKDOWN_E_SUCCESS || !lockdowndClient) {
43 qCWarning(IMOBILE) << "Failed to create lockdownd client for" << deviceId;
44 return;
45 }
46
47 auto lockdowndClientCleanup = qScopeGuard([lockdowndClient] {
48 lockdownd_client_free(lockdowndClient);
49 });
50
51 char *name = nullptr;
52 lockdownRet = lockdownd_get_device_name(lockdowndClient, &name);
53 if (lockdownRet != LOCKDOWN_E_SUCCESS) {
54 qCWarning(IMOBILE) << "Failed to get device name for" << deviceId << lockdownRet;
55 } else if (name) {
56 m_name = QString::fromUtf8(name);
57 free(name);
58 }
59
60 plist_t deviceClassEntry = nullptr;
61 lockdownRet = lockdownd_get_value(lockdowndClient, nullptr /*global domain*/, "DeviceClass", &deviceClassEntry);
62 if (lockdownRet != LOCKDOWN_E_SUCCESS) {
63 qCWarning(IMOBILE) << "Failed to get device class for" << deviceId << lockdownRet;
64 } else {
65 char *deviceClass = nullptr;
66 plist_get_string_val(deviceClassEntry, &deviceClass);
67 if (deviceClass) {
68 m_deviceClass = QString::fromUtf8(deviceClass);
69 free(deviceClass);
70 }
71 }
72}
73
74IMobileDevice::~IMobileDevice()
75{
76}
77
78QString IMobileDevice::udi() const
79{
80 return m_udi;
81}
82
83QString IMobileDevice::parentUdi() const
84{
85 return udiPrefix();
86}
87
88QString IMobileDevice::vendor() const
89{
90 return QCoreApplication::translate("imobiledevice", "Apple", "Company name");
91}
92
93QString IMobileDevice::product() const
94{
95 // TODO would be nice to use actual product names, e.g. "iPhone 5S"
96 // but accessing device type requires doing a handshake with the device,
97 // which will fail if locked or not paired, and also would require us
98 // to maintain a giant mapping table
99 return m_deviceClass;
100}
101
102QString IMobileDevice::icon() const
103{
104 if (m_deviceClass.contains(QLatin1String("iPod"))) {
105 return QStringLiteral("multimedia-player-apple-ipod-touch");
106 } else if (m_deviceClass.contains(QLatin1String("iPad"))) {
107 return QStringLiteral("computer-apple-ipad");
108 } else {
109 return QStringLiteral("phone-apple-iphone");
110 }
111}
112
113QStringList IMobileDevice::emblems() const
114{
115 return {};
116}
117
118QString IMobileDevice::description() const
119{
120 return m_name;
121}
122
123bool IMobileDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const
124{
125 switch (type) {
126 // TODO would be cool to support GenericInterface for reading
127 // arbitrary plist configuration, cf. what ideviceinfo tool does
128
129 case Solid::DeviceInterface::PortableMediaPlayer:
130 return true;
131
132 default:
133 return false;
134 }
135}
136
137QObject *IMobileDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type)
138{
139 if (!queryDeviceInterface(type)) {
140 return nullptr;
141 }
142
143 switch (type) {
144 case Solid::DeviceInterface::PortableMediaPlayer:
145 return new PortableMediaPlayer(this);
146
147 default:
148 Q_UNREACHABLE();
149 return nullptr;
150 }
151}
152
153#include "moc_imobiledevice.cpp"
Type
This enum type defines the type of device interface that a Device can have.
This class allows applications to deal with devices available in the underlying system.
QString name(StandardAction id)
const char * constData() const const
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromUtf8(QByteArrayView str)
QString mid(qsizetype position, qsizetype n) const const
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:03:23 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.