Merge lp:~laney/ubuntu-system-settings/fix-storage-page into lp:ubuntu-system-settings

Proposed by Iain Lane on 2015-02-18
Status: Merged
Approved by: Ken VanDine on 2015-02-18
Approved revision: 1315
Merged at revision: 1318
Proposed branch: lp:~laney/ubuntu-system-settings/fix-storage-page
Merge into: lp:ubuntu-system-settings
Diff against target: 290 lines (+152/-13)
5 files modified
debian/copyright (+6/-0)
plugins/about/PageComponent.qml (+1/-1)
plugins/about/Storage.qml (+5/-9)
plugins/about/storageabout.cpp (+133/-3)
plugins/about/storageabout.h (+7/-0)
To merge this branch: bzr merge lp:~laney/ubuntu-system-settings/fix-storage-page
Reviewer Review Type Date Requested Status
Ken VanDine Approve on 2015-02-18
Sebastien Bacher (community) 2015-02-18 Approve on 2015-02-18
PS Jenkins bot continuous-integration Needs Fixing on 2015-02-18
Review via email: mp+250119@code.launchpad.net

Commit Message

Reintroduce the functionality dropped in the Qt 5.4 transition - expose the functions we need from QStorageInfo to QML, and copy over a heuristic function to tell if a drive is "internal" or not.

Description of the Change

Someone please test this on bq.

To post a comment you must log in.
1315. By Iain Lane on 2015-02-18

Remove stray warning

Sebastien Bacher (seb128) wrote :

Seems fine to me, works fine on my desktop. My bq runs rtm but Ken has it on vivid and said he would test, letting him deal with the status change

review: Approve
Ken VanDine (ken-vandine) wrote :

Works fine on my krillin. I also ran the autopilot tests on krillin, 100% pass :-D

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/copyright'
2--- debian/copyright 2013-06-20 09:30:32 +0000
3+++ debian/copyright 2015-02-18 15:35:19 +0000
4@@ -9,6 +9,12 @@
5 On Debian systems, the complete text of the GNU General
6 Public License version 3 can be found in `/usr/share/common-licenses/GPL-3'.
7
8+Files: plugins/about/storageabout.cpp
9+Copyright: 2013 Canonical Ltd, 2012 Digia Plc and/or its subsidiary(-ies).
10+License: GPL-3
11+ On Debian systems, the complete text of the GNU General
12+ Public License version 3 can be found in `/usr/share/common-licenses/GPL-3'.
13+
14 Files: plugins/background/aeg.jpg
15 Copyright: 2012 Tauno Erik
16 License: CC-BY-SA-3.0
17
18=== modified file 'plugins/about/PageComponent.qml'
19--- plugins/about/PageComponent.qml 2015-02-17 10:38:26 +0000
20+++ plugins/about/PageComponent.qml 2015-02-18 15:35:19 +0000
21@@ -171,7 +171,7 @@
22 /* TRANSLATORS: that's the free disk space, indicated in the most appropriate storage unit */
23 value: i18n.tr("%1 free").arg(Utilities.formatSize(backendInfos.getFreeSpace("/home")))
24 progression: true
25- /*onClicked: pageStack.push(Qt.resolvedUrl("Storage.qml"))*/
26+ onClicked: pageStack.push(Qt.resolvedUrl("Storage.qml"))
27 }
28
29 SettingsItemTitle {
30
31=== modified file 'plugins/about/Storage.qml'
32--- plugins/about/Storage.qml 2014-10-24 20:04:30 +0000
33+++ plugins/about/Storage.qml 2015-02-18 15:35:19 +0000
34@@ -36,15 +36,14 @@
35 property var allDrives: {
36 var drives = ["/"] // Always consider /
37 var paths = [backendInfo.getDevicePath("/")]
38- var systemDrives = storageInfo.allLogicalDrives
39+ var systemDrives = backendInfo.mountedVolumes
40 for (var i = 0; i < systemDrives.length; i++) {
41 var drive = systemDrives[i]
42- var type = storageInfo.driveType(drive)
43 var path = backendInfo.getDevicePath(drive)
44 /* only deal with the device's storage for now, external mounts
45 handling would require being smarter on the categories
46 computation as well and is not in the current design */
47- if ((type === StorageInfo.InternalDrive) &&
48+ if (backendInfo.isInternal(drive) &&
49 paths.indexOf(path) == -1 && // Haven't seen this device before
50 path.charAt(0) === "/") { // Has a real mount point
51 drives.push(drive)
52@@ -56,14 +55,15 @@
53 property real diskSpace: {
54 var space = 0
55 for (var i = 0; i < allDrives.length; i++) {
56- space += storageInfo.totalDiskSpace(allDrives[i])
57+ space += backendInfo.getTotalSpace(allDrives[i])
58 }
59 return space
60 }
61 /* Limit the free space to the user available one (see bug #1374134) */
62 property real freediskSpace: {
63- return storageInfo.availableDiskSpace("/home")
64+ return backendInfo.getFreeSpace("/home")
65 }
66+
67 property real usedByUbuntu: diskSpace -
68 freediskSpace -
69 backendInfo.homeSize -
70@@ -120,10 +120,6 @@
71
72 }
73
74- StorageInfo {
75- id: storageInfo
76- }
77-
78 Flickable {
79 id: scrollWidget
80 anchors.fill: parent
81
82=== modified file 'plugins/about/storageabout.cpp'
83--- plugins/about/storageabout.cpp 2015-02-17 10:38:26 +0000
84+++ plugins/about/storageabout.cpp 2015-02-18 15:35:19 +0000
85@@ -1,6 +1,8 @@
86 /*
87 * Copyright (C) 2013 Canonical Ltd
88 *
89+ * isInternal() is Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
90+ *
91 * This program is free software: you can redistribute it and/or modify
92 * it under the terms of the GNU General Public License version 3 as
93 * published by the Free Software Foundation.
94@@ -21,6 +23,9 @@
95
96 #include <QDebug>
97
98+#include <mntent.h>
99+#include <sys/stat.h>
100+
101 #include <gio/gio.h>
102 #include <gio/gunixmounts.h>
103 #include <glib.h>
104@@ -325,25 +330,141 @@
105 m_cancellable));
106 }
107
108+QStringList StorageAbout::getMountedVolumes() const
109+{
110+ QStringList out;
111+
112+ Q_FOREACH (const QStorageInfo &storage, QStorageInfo::mountedVolumes())
113+ if (storage.isValid() && storage.isReady())
114+ out.append(storage.rootPath());
115+
116+ return out;
117+}
118+
119 QString StorageAbout::getDevicePath(const QString mount_point)
120 {
121 QString s_mount_point;
122-
123 GUnixMountEntry * g_mount_point = nullptr;
124
125 if (!mount_point.isNull() && !mount_point.isEmpty()) {
126- g_mount_point = g_unix_mount_at(mount_point.toLocal8Bit(), nullptr);
127+ g_mount_point = g_unix_mount_at(mount_point.toLocal8Bit(), nullptr);
128 }
129
130 if (g_mount_point) {
131 const gchar * device_path =
132- g_unix_mount_get_device_path(g_mount_point);
133+ g_unix_mount_get_device_path(g_mount_point);
134 s_mount_point = QString::fromLocal8Bit(device_path);
135
136 g_unix_mount_free (g_mount_point);
137 }
138
139 return s_mount_point;
140+ }
141+
142+/* This function was copied from QtSystems, as it was removed when the
143+ * QSystemInfo class moved to Qt 5.4.
144+ *
145+ * The license terms state, in part:
146+ *
147+ * Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
148+ *
149+ * GNU General Public License Usage
150+ * Alternatively, this file may be used under the terms of the GNU
151+ * General Public License version 3.0 as published by the Free Software
152+ * Foundation and appearing in the file LICENSE.GPL included in the
153+ * packaging of this file. Please review the following information to
154+ * ensure the GNU General Public License version 3.0 requirements will be
155+ * met: http://www.gnu.org/copyleft/gpl.html.
156+ *
157+ */
158+bool StorageAbout::isInternal(const QString &drive)
159+{
160+ bool ret = false;
161+ FILE *fsDescription = setmntent(_PATH_MOUNTED, "r");
162+ struct mntent entry;
163+ char buffer[512];
164+ while ((getmntent_r(fsDescription, &entry, buffer, sizeof(buffer))) != NULL) {
165+ if (drive != QString::fromLatin1(entry.mnt_dir))
166+ continue;
167+
168+ if (strcmp(entry.mnt_type, "binfmt_misc") == 0
169+ || strcmp(entry.mnt_type, "debugfs") == 0
170+ || strcmp(entry.mnt_type, "devpts") == 0
171+ || strcmp(entry.mnt_type, "devtmpfs") == 0
172+ || strcmp(entry.mnt_type, "fusectl") == 0
173+ || strcmp(entry.mnt_type, "none") == 0
174+ || strcmp(entry.mnt_type, "proc") == 0
175+ || strcmp(entry.mnt_type, "ramfs") == 0
176+ || strcmp(entry.mnt_type, "securityfs") == 0
177+ || strcmp(entry.mnt_type, "sysfs") == 0
178+ || strcmp(entry.mnt_type, "tmpfs") == 0
179+ || strcmp(entry.mnt_type, "cifs") == 0
180+ || strcmp(entry.mnt_type, "ncpfs") == 0
181+ || strcmp(entry.mnt_type, "nfs") == 0
182+ || strcmp(entry.mnt_type, "nfs4") == 0
183+ || strcmp(entry.mnt_type, "smbfs") == 0
184+ || strcmp(entry.mnt_type, "iso9660") == 0) {
185+ ret = false;
186+ break;
187+ }
188+
189+ if (strcmp(entry.mnt_type, "rootfs") == 0) {
190+ ret = true;
191+ break;
192+ }
193+
194+ // Now need to guess if it's InternalDrive or RemovableDrive
195+ QString fsName(QString::fromLatin1(entry.mnt_fsname));
196+ if (fsName.contains(QString(QStringLiteral("mapper")))) {
197+ struct stat status;
198+ stat(entry.mnt_fsname, &status);
199+ fsName = QString(QStringLiteral("/sys/block/dm-%1/removable")).arg(status.st_rdev & 0377);
200+ } else {
201+ fsName = fsName.section(QString(QStringLiteral("/")), 2, 3);
202+ if (!fsName.isEmpty()) {
203+ if (fsName.length() > 3) {
204+ // only take the parent of the device
205+ if (fsName.at(fsName.size() -1).isDigit() && fsName.at(fsName.size() - 2) == QChar(QLatin1Char('p')))
206+ fsName.chop(2);
207+ if (fsName.startsWith(QString(QStringLiteral("mmc")))) {
208+ // "removable" attribute is set only for removable media, and we may have internal mmc cards
209+ fsName = QString(QStringLiteral("/sys/block/")) + fsName + QString(QStringLiteral("/device/uevent"));
210+ QFile file(fsName);
211+ if (file.open(QIODevice::ReadOnly)) {
212+ QByteArray buf = file.readLine();
213+ while (buf.size() > 0) {
214+ if (qstrncmp(buf.constData(), "MMC_TYPE=", 9) == 0) {
215+ if (qstrncmp(buf.constData() + 9, "MMC", 3) == 0)
216+ ret = true;
217+ else if (qstrncmp(buf.constData() + 9, "SD", 2) == 0)
218+ ret = false;
219+ if (ret) {
220+ endmntent(fsDescription);
221+ return ret;
222+ }
223+ break; // fall back to check the "removable" attribute
224+ }
225+ buf = file.readLine();
226+ }
227+ }
228+ }
229+ }
230+ fsName = QString(QStringLiteral("/sys/block/")) + fsName + QString(QStringLiteral("/removable"));
231+ }
232+ }
233+ QFile removable(fsName);
234+ char isRemovable;
235+ if (!removable.open(QIODevice::ReadOnly) || 1 != removable.read(&isRemovable, 1))
236+ break;
237+ if (isRemovable == '0')
238+ ret = true;
239+ else
240+ ret = false;
241+ break;
242+ }
243+
244+ endmntent(fsDescription);
245+ return ret;
246 }
247
248 qint64 StorageAbout::getFreeSpace(const QString mount_point)
249@@ -355,6 +476,15 @@
250 return -1;
251 }
252
253+qint64 StorageAbout::getTotalSpace(const QString mount_point)
254+{
255+ QStorageInfo si(mount_point);
256+ if (si.isValid())
257+ return si.bytesTotal();
258+
259+ return -1;
260+}
261+
262 StorageAbout::~StorageAbout() {
263 if (m_cancellable) {
264 g_cancellable_cancel(m_cancellable);
265
266=== modified file 'plugins/about/storageabout.h'
267--- plugins/about/storageabout.h 2015-02-17 10:38:26 +0000
268+++ plugins/about/storageabout.h 2015-02-18 15:35:19 +0000
269@@ -54,6 +54,10 @@
270 READ getClickSize
271 CONSTANT)
272
273+ Q_PROPERTY(QStringList mountedVolumes
274+ READ getMountedVolumes
275+ CONSTANT)
276+
277 Q_PROPERTY(quint64 moviesSize
278 READ getMoviesSize
279 NOTIFY sizeReady)
280@@ -110,8 +114,11 @@
281 quint64 getPicturesSize();
282 quint64 getHomeSize();
283 Q_INVOKABLE void populateSizes();
284+ QStringList getMountedVolumes() const;
285 Q_INVOKABLE QString getDevicePath (const QString mount_point);
286 Q_INVOKABLE qint64 getFreeSpace (const QString mount_point);
287+ Q_INVOKABLE qint64 getTotalSpace (const QString mount_point);
288+ Q_INVOKABLE bool isInternal(const QString &drive);
289 bool getDeveloperMode();
290 void setDeveloperMode(bool newMode);
291

Subscribers

People subscribed via source and target branches