Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[settings] Add C++ API for querying partition information. Contribute…
…s to JB#35430
  • Loading branch information
denexter committed Jul 5, 2016
1 parent 110fd5b commit 4270bf6
Show file tree
Hide file tree
Showing 22 changed files with 1,465 additions and 173 deletions.
1 change: 1 addition & 0 deletions rpm/nemo-qml-plugin-systemsettings.spec
Expand Up @@ -17,6 +17,7 @@ BuildRequires: pkgconfig(mce)
BuildRequires: pkgconfig(mlite5)
BuildRequires: pkgconfig(usb-moded-qt5)
BuildRequires: pkgconfig(libshadowutils)
BuildRequires: pkgconfig(blkid)

%description
%{summary}.
Expand Down
182 changes: 28 additions & 154 deletions src/aboutsettings.cpp
Expand Up @@ -33,7 +33,6 @@

#include <QDebug>
#include <QStringList>
#include <QtSystemInfo/QStorageInfo>
#include <QNetworkInfo>
#include <QDeviceInfo>
#include <QFile>
Expand All @@ -44,9 +43,6 @@
#include <QVariant>
#include <QSettings>

#include <mntent.h>


namespace
{

Expand Down Expand Up @@ -119,72 +115,10 @@ void parseReleaseFile(const QString &filename, QMap<QString, QString> *result)
}
}

struct StorageInfo {
StorageInfo()
: partitionSize(0)
, availableDiskSpace(0)
, totalDiskSpace(0)
, external(false)
, mounted(false)
{ }

QString mountPath;
QString devicePath;
QString filesystem;
quint64 partitionSize;
qlonglong availableDiskSpace;
qlonglong totalDiskSpace;
bool external;
bool mounted;
};


QMap<QString, StorageInfo> parseExternalPartitions()
{
QMap<QString, StorageInfo> devices;

QFile partitions(QStringLiteral("/proc/partitions"));
if (!partitions.open(QIODevice::ReadOnly))
return devices;

// Read file headers
partitions.readLine();
partitions.readLine();

while (!partitions.atEnd()) {
QByteArray line = partitions.readLine().trimmed();

int nameIndex = line.lastIndexOf(' ');
if (nameIndex <= 0)
continue;

int sizeIndex = line.lastIndexOf(' ', nameIndex - 1);
if (sizeIndex == -1)
continue;

QByteArray size = line.mid(sizeIndex+1, nameIndex - sizeIndex - 1);
QByteArray name = line.mid(nameIndex+1);

if (name.startsWith("mmcblk1")) {
// If adding a partition remove the whole device.
devices.remove(QStringLiteral("/dev/mmcblk1"));

StorageInfo info;
info.devicePath = QStringLiteral("/dev/") + QString::fromLatin1(name);
info.partitionSize = size.toULongLong() * 1024;
info.external = true;

devices.insert(info.devicePath, info);
}
}

return devices;
}

}

AboutSettings::AboutSettings(QObject *parent)
: QObject(parent), m_sysinfo(new QStorageInfo(this)), m_netinfo(new QNetworkInfo(this)),
: QObject(parent), m_netinfo(new QNetworkInfo(this)),
m_devinfo(new QDeviceInfo(this))
{
QSettings settings(QStringLiteral("/mnt/vendor_data/vendor-data.ini"), QSettings::IniFormat);
Expand All @@ -200,12 +134,12 @@ AboutSettings::~AboutSettings()

qlonglong AboutSettings::totalDiskSpace() const
{
return m_sysinfo->totalDiskSpace("/");
return m_partitionManager.root().bytesTotal();
}

qlonglong AboutSettings::availableDiskSpace() const
{
return m_sysinfo->availableDiskSpace("/");
return m_partitionManager.root().bytesAvailable();
}

QVariant AboutSettings::diskUsageModel() const
Expand Down Expand Up @@ -282,98 +216,38 @@ QString AboutSettings::vendorVersion() const

void AboutSettings::refreshStorageModels()
{
// Optional mountpoints that we want to report disk usage for
QStringList candidates;
candidates << QStringLiteral("/home");

QMap<QString, StorageInfo> devices = parseExternalPartitions();

FILE *fsd = setmntent(_PATH_MOUNTED, "r");
struct mntent entry;
char buffer[3*PATH_MAX];
while ((getmntent_r(fsd, &entry, buffer, sizeof(buffer))) != NULL) {
StorageInfo info;
info.mountPath = QString::fromLatin1(entry.mnt_dir);
info.devicePath = QString::fromLatin1(entry.mnt_fsname);
info.filesystem = QString::fromLatin1(entry.mnt_type);

bool addInfo = false;
if (info.mountPath == QLatin1String("/") && info.devicePath.startsWith(QLatin1Char('/'))) {
// Always report rootfs, replacing other mounts from same device
addInfo = true;
} else if (!devices.contains(info.devicePath) || devices.value(info.devicePath).external) {
// Optional candidates and external storage
if (candidates.contains(info.mountPath)) {
addInfo = true;
} else if (info.devicePath.startsWith(QLatin1String("/dev/mmcblk1"))) {
info.external = true;
addInfo = true;
}
}

if (addInfo) {
info.mounted = !info.external || !info.mountPath.isEmpty();
info.availableDiskSpace = info.mounted ? m_sysinfo->availableDiskSpace(info.mountPath) : 0;
info.totalDiskSpace = info.mounted ? m_sysinfo->totalDiskSpace(info.mountPath) : info.partitionSize;

bool ignoreDuplicateEntry = false;
if (info.external) {
for (QMap<QString, StorageInfo>::Iterator it = devices.begin(); it != devices.end(); it++) {
const StorageInfo &currInfo = it.value();
if (info.external && info.totalDiskSpace == currInfo.totalDiskSpace) {
const QString &currMountPath = currInfo.mountPath;

// it appears the same device has been mounted under multiple paths, so ignore
// the one with the longer device path, assuming it's the extraneous entry
if (currMountPath.indexOf(info.mountPath) >= 0) {
// remove the duplicate and keep this entry
devices.erase(it);
break;
} else if (info.mountPath.indexOf(currMountPath) >= 0) {
// ignore this entry
ignoreDuplicateEntry = true;
break;
}
}
}
}
if (!ignoreDuplicateEntry) {
devices.insert(info.devicePath, info);
}
}
}
endmntent(fsd);

m_internalStorage.clear();
m_externalStorage.clear();

int internalPartitionCount = 0;
foreach (const StorageInfo &info, devices) {
if (!info.external) {
internalPartitionCount++;
}
}
m_partitionManager.refresh();

foreach (const StorageInfo &info, devices) {
for (auto partition : m_partitionManager.partitions()) {
QVariantMap row;
row[QStringLiteral("mounted")] = info.mounted;
row[QStringLiteral("path")] = info.mountPath;
row[QStringLiteral("available")] = info.availableDiskSpace;
row[QStringLiteral("total")] = info.totalDiskSpace;
row[QStringLiteral("filesystem")] = info.filesystem;
row[QStringLiteral("devicePath")] = info.devicePath;

if (!info.external) {
row[QStringLiteral("storageType")] = internalPartitionCount == 1 ? QStringLiteral("mass")
: info.mountPath == QLatin1String("/") ? QStringLiteral("system")
: QStringLiteral("user");


m_internalStorage << QVariant(row);
} else {
row[QStringLiteral("storageType")] = QStringLiteral("card");
row[QStringLiteral("mounted")] = partition.status() == Partition::Mounted;
row[QStringLiteral("path")] = partition.mountPath();
row[QStringLiteral("available")] = partition.bytesAvailable();
row[QStringLiteral("total")] = partition.bytesTotal();
row[QStringLiteral("filesystem")] = partition.filesystemType();
row[QStringLiteral("devicePath")] = partition.devicePath();
row[QStringLiteral("storageType")] = [&partition]() {
switch (partition.storageType()) {
case Partition::System:
return QStringLiteral("system");
case Partition::User:
return QStringLiteral("user");
case Partition::Mass:
return QStringLiteral("mass");
case Partition::External:
return QStringLiteral("card");
default:
return QString();
}
}();

if (partition.storageType() == Partition::External) {
m_externalStorage << QVariant(row);
} else {
m_internalStorage << QVariant(row);
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/aboutsettings.h
Expand Up @@ -35,10 +35,12 @@
#include <QObject>
#include <QVariant>

class QStorageInfo;
#include <systemsettingsglobal.h>
#include <partitionmanager.h>

class QNetworkInfo;
class QDeviceInfo;
class AboutSettings: public QObject
class SYSTEMSETTINGS_EXPORT AboutSettings: public QObject
{
Q_OBJECT

Expand Down Expand Up @@ -90,12 +92,13 @@ class AboutSettings: public QObject
void storageChanged();

private:
QStorageInfo *m_sysinfo;
QNetworkInfo *m_netinfo;
QDeviceInfo *m_devinfo;

QVariantList m_internalStorage;
QVariantList m_externalStorage;
PartitionManager m_partitionManager;

mutable QMap<QString, QString> m_osRelease;
mutable QMap<QString, QString> m_hardwareRelease;

Expand Down
4 changes: 3 additions & 1 deletion src/alarmtonemodel.h
Expand Up @@ -36,7 +36,9 @@
#include <QFileInfo>
#include <QJSValue>

class AlarmToneModel
#include <systemsettingsglobal.h>

class SYSTEMSETTINGS_EXPORT AlarmToneModel
: public QAbstractListModel
{
Q_OBJECT
Expand Down
4 changes: 3 additions & 1 deletion src/datetimesettings.h
Expand Up @@ -38,7 +38,9 @@
#include <timed-qt5/interface>
#include <timed-qt5/wallclock>

class DateTimeSettings: public QObject
#include <systemsettingsglobal.h>

class SYSTEMSETTINGS_EXPORT DateTimeSettings: public QObject
{
Q_OBJECT

Expand Down
4 changes: 3 additions & 1 deletion src/developermodesettings.h
Expand Up @@ -40,9 +40,11 @@
#include <QDBusInterface>
#include <QNetworkInterface>

#include <systemsettingsglobal.h>

class DeveloperModeSettingsWorker;

class DeveloperModeSettings : public QObject
class SYSTEMSETTINGS_EXPORT DeveloperModeSettings : public QObject
{
Q_OBJECT
Q_ENUMS(Status)
Expand Down
4 changes: 3 additions & 1 deletion src/devicelockiface.h
Expand Up @@ -36,7 +36,9 @@
#include <QProcess>
#include <QDebug>

class DeviceLockInterface : public QObject
#include <systemsettingsglobal.h>

class SYSTEMSETTINGS_EXPORT DeviceLockInterface : public QObject
{
Q_OBJECT
Q_ENUMS(ResetMode)
Expand Down
4 changes: 3 additions & 1 deletion src/diskusage.h
Expand Up @@ -38,9 +38,11 @@
#include <QJSValue>
#include <QScopedPointer>

#include <systemsettingsglobal.h>

class DiskUsagePrivate;

class DiskUsage : public QObject
class SYSTEMSETTINGS_EXPORT DiskUsage : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(DiskUsage)
Expand Down
4 changes: 3 additions & 1 deletion src/displaysettings.h
Expand Up @@ -40,7 +40,9 @@ class ComNokiaMceSignalInterface;
class QDBusVariant;
class MGConfItem;

class DisplaySettings: public QObject
#include <systemsettingsglobal.h>

class SYSTEMSETTINGS_EXPORT DisplaySettings: public QObject
{
Q_OBJECT

Expand Down
7 changes: 5 additions & 2 deletions src/languagemodel.h
Expand Up @@ -35,7 +35,10 @@
#include <QAbstractListModel>
#include <QList>

class Language {

#include <systemsettingsglobal.h>

class SYSTEMSETTINGS_EXPORT Language {
public:
Language(QString name, QString localeCode, QString region, QString regionLabel);
QString name() const;
Expand All @@ -50,7 +53,7 @@ class Language {
QString m_regionLabel;
};

class LanguageModel: public QAbstractListModel
class SYSTEMSETTINGS_EXPORT LanguageModel: public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int currentIndex READ currentIndex NOTIFY currentIndexChanged)
Expand Down

0 comments on commit 4270bf6

Please sign in to comment.