Solid

udevportablemediaplayer.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Rafael Fernández López <ereslibre@kde.org>
3 SPDX-FileCopyrightText: 2010 Lukas Tinkl <ltinkl@redhat.com>
4 SPDX-FileCopyrightText: 2011 Matej Laitl <matej@laitl.cz>
5
6 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7*/
8
9#include "udevportablemediaplayer.h"
10
11#include <QChar>
12#include <QDebug>
13#include <QFile>
14#include <QTextStream>
15#include <qstandardpaths.h>
16
17using namespace Solid::Backends::UDev;
18
19/**
20 * Reads one value from media-player-info ini-like file.
21 *
22 * @param file file to open. May advance current seek position
23 * @param group group name to read from, e.g. "Device" for [Device] group
24 * @param key key name, e.g. "AccessProtocol"
25 * @return value as a string or an empty string
26 */
27static QString readMpiValue(QIODevice &file, const QString &group, const QString &key)
28{
29 QTextStream mpiStream(&file);
30 QString line;
31 QString currGroup;
32
33 while (!mpiStream.atEnd()) {
34 line = mpiStream.readLine().trimmed(); // trimmed is needed for possible indentation
35 if (line.isEmpty() || line.startsWith(QChar(';'))) {
36 // skip empty and comment lines
37 } else if (line.startsWith(QChar('[')) && line.endsWith(QChar(']'))) {
38 currGroup = line.mid(1, line.length() - 2); // strip [ and ]
39 } else if (line.indexOf(QChar('=')) != -1) {
40 int index = line.indexOf(QChar('='));
41 if (currGroup == group && line.left(index) == key) {
42 line = line.right(line.length() - index - 1);
43 if (line.startsWith(QChar('"')) && line.endsWith(QChar('"'))) {
44 line = line.mid(1, line.length() - 2); // strip enclosing double quotes
45 }
46 return line;
47 }
48 } else {
49 qWarning() << "readMpiValue: cannot parse line:" << line;
50 }
51 }
52 return QString();
53}
54
55PortableMediaPlayer::PortableMediaPlayer(UDevDevice *device)
56 : DeviceInterface(device)
57{
58}
59
60PortableMediaPlayer::~PortableMediaPlayer()
61{
62}
63
64QStringList PortableMediaPlayer::supportedProtocols() const
65{
66 /* There are multiple packages that set ID_MEDIA_PLAYER:
67 * * gphoto2 sets it to numeric 1 (for _some_ cameras it supports) and it hopefully
68 * means MTP-compatible device.
69 * * libmtp >= 1.0.4 sets it to numeric 1 and this always denotes MTP-compatible player.
70 * * media-player-info sets it to a string that denotes a name of the .mpi file with
71 * additional info.
72 */
73 if (m_device->property("ID_MEDIA_PLAYER").toInt() == 1) {
74 return QStringList() << "mtp";
75 }
76
77 QString mpiFileName = mediaPlayerInfoFilePath();
78 if (mpiFileName.isEmpty()) {
79 return QStringList();
80 }
81 // we unfornutately cannot use QSettings as it cannot read unquoted valued with semicolons in it
82 QFile mpiFile(mpiFileName);
83 if (!mpiFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
84 qWarning() << "Cannot open" << mpiFileName << "for reading."
85 << "Check your media-player-info installation.";
86 return QStringList();
87 }
88 QString value = readMpiValue(mpiFile, QString("Device"), QString("AccessProtocol"));
89 return value.split(QChar(';'), Qt::SkipEmptyParts);
90}
91
92QStringList PortableMediaPlayer::supportedDrivers(QString protocol) const
93{
94 Q_UNUSED(protocol)
95 QStringList res;
96
97 if (!supportedProtocols().isEmpty()) {
98 res << "usb";
99 }
100 if (m_device->property("USBMUX_SUPPORTED").toBool() == true) {
101 res << "usbmux";
102 }
103 return res;
104}
105
106QVariant PortableMediaPlayer::driverHandle(const QString &driver) const
107{
108 if (driver == "mtp" || driver == "usbmux") {
109 return m_device->property("ID_SERIAL_SHORT");
110 }
111
112 return QVariant();
113}
114
115QString PortableMediaPlayer::mediaPlayerInfoFilePath() const
116{
117 QString relativeFilename = m_device->property("ID_MEDIA_PLAYER").toString();
118 if (relativeFilename.isEmpty()) {
119 qWarning() << "We attached PortableMediaPlayer interface to device" << m_device->udi() << "but m_device->property(\"ID_MEDIA_PLAYER\") is empty???";
120 return QString();
121 }
122 relativeFilename.prepend("media-player-info/");
123 relativeFilename.append(".mpi");
125 if (filename.isEmpty()) {
126 qWarning() << "media player info file" << relativeFilename << "not found under user and"
127 << "system XDG data directories. Do you have media-player-info installed?";
128 }
129 return filename;
130}
131
132#include "moc_udevportablemediaplayer.cpp"
QString locate(StandardLocation type, const QString &fileName, LocateOptions options)
QString & append(QChar ch)
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) const const
QString & prepend(QChar ch)
QString right(qsizetype n) const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString trimmed() const const
SkipEmptyParts
bool toBool() const const
int toInt(bool *ok) const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:12 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.