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(QLatin1Char(';'))) {
36 // skip empty and comment lines
37 } else if (line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) {
38 currGroup = line.mid(1, line.length() - 2); // strip [ and ]
39 } else if (line.indexOf(QLatin1Char('=')) != -1) {
40 int index = line.indexOf(QLatin1Char('='));
41 if (currGroup == group && line.left(index) == key) {
42 line = line.right(line.length() - index - 1);
43 if (line.startsWith(QLatin1Char('"')) && line.endsWith(QLatin1Char('"'))) {
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(QStringLiteral("ID_MEDIA_PLAYER")).toInt() == 1) {
74 return {QStringLiteral("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, QStringLiteral("Device"), QStringLiteral("AccessProtocol"));
89 return value.split(QLatin1Char(';'), Qt::SkipEmptyParts);
90}
91
92QStringList PortableMediaPlayer::supportedDrivers(QString protocol) const
93{
94 Q_UNUSED(protocol)
95
96 if (!supportedProtocols().isEmpty()) {
97 return {QStringLiteral("usb")};
98 }
99 if (m_device->property(QStringLiteral("USBMUX_SUPPORTED")).toBool() == true) {
100 return {QStringLiteral("usbmux")};
101 }
102 return {};
103}
104
105QVariant PortableMediaPlayer::driverHandle(const QString &driver) const
106{
107 if (driver == QLatin1String("mtp") || driver == QLatin1String("usbmux")) {
108 return m_device->property(QStringLiteral("ID_SERIAL_SHORT"));
109 }
110
111 return QVariant();
112}
113
114QString PortableMediaPlayer::mediaPlayerInfoFilePath() const
115{
116 QString relativeFilename = m_device->property(QStringLiteral("ID_MEDIA_PLAYER")).toString();
117 if (relativeFilename.isEmpty()) {
118 qWarning() << "We attached PortableMediaPlayer interface to device" << m_device->udi() << "but m_device->property(\"ID_MEDIA_PLAYER\") is empty???";
119 return QString();
120 }
121 relativeFilename.prepend(QStringLiteral("media-player-info/"));
122 relativeFilename.append(QStringLiteral(".mpi"));
124 if (filename.isEmpty()) {
125 qWarning() << "media player info file" << relativeFilename << "not found under user and"
126 << "system XDG data directories. Do you have media-player-info installed?";
127 }
128 return filename;
129}
130
131#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
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:14:22 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.