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(StandardShortcut id)
The single responsibility of this class is to create arguments valid for logind Inhibit call.
Definition fakebattery.h:16
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 Fri May 3 2024 11:47:59 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.