on xenial help sign in
Add a SessionsModel to lightdm to support the greeter's session chooser
47ffbf2Josh Arenson
plugins/LightDM/CMakeLists.txt+1−2
@@ -7,9 +7,7 @@ include_directories(
7 ${CMAKE_CURRENT_SOURCE_DIR}
7 ${CMAKE_CURRENT_SOURCE_DIR}
8 ${CMAKE_CURRENT_BINARY_DIR}
8 ${CMAKE_CURRENT_BINARY_DIR}
9 ${CMAKE_SOURCE_DIR}/plugins/Utils
9 ${CMAKE_SOURCE_DIR}/plugins/Utils
10− ${CMAKE_SOURCE_DIR}/tests/mocks/LightDM/IntegratedLightDM
11 ${CMAKE_BINARY_DIR}/tests/mocks/LightDM/IntegratedLightDM
10 ${CMAKE_BINARY_DIR}/tests/mocks/LightDM/IntegratedLightDM
12− ${LIBLIGHTDM_INCLUDE_DIRS}
13 ${libunity8-private_SOURCE_DIR}
11 ${libunity8-private_SOURCE_DIR}
14 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
12 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
15)
13)
@@ -20,6 +18,7 @@ set(QMLPLUGIN_SRC
20 DBusGreeterList.cpp
18 DBusGreeterList.cpp
21 Greeter.cpp
19 Greeter.cpp
22 plugin.cpp
20 plugin.cpp
21+ SessionsModel.cpp
23 UsersModel.cpp
22 UsersModel.cpp
24 )
23 )
25
24
plugins/LightDM/FullLightDM/CMakeLists.txt+1
@@ -6,6 +6,7 @@ add_definitions(-DFULL_LIGHTDM)
6
6
7include_directories(
7include_directories(
8 ../
8 ../
9+ ${LIBLIGHTDM_INCLUDE_DIRS}
9 ${CMAKE_CURRENT_BINARY_DIR}
10 ${CMAKE_CURRENT_BINARY_DIR}
10 )
11 )
11
12
plugins/LightDM/Greeter.cpp+7−2
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2015 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -13,7 +13,6 @@
13 * You should have received a copy of the GNU General Public License
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16− * Author: Michael Terry <michael.terry@canonical.com>
17 */
16 */
18
17
19#include "Greeter.h"
18#include "Greeter.h"
@@ -72,6 +71,12 @@ QString Greeter::authenticationUser() const
72 return d->m_greeter->authenticationUser();
71 return d->m_greeter->authenticationUser();
73}
72}
74
73
74+QString Greeter::defaultSessionHint() const
75+{
76+ Q_D(const Greeter);
77+ return d->m_greeter->defaultSessionHint();
78+}
79+
75bool Greeter::promptless() const
80bool Greeter::promptless() const
76{
81{
77 Q_D(const Greeter);
82 Q_D(const Greeter);
plugins/LightDM/Greeter.h+3−2
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2012,2013 Canonical, Ltd.
2+ * Copyright (C) 2012,2013,2015 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -13,7 +13,6 @@
13 * You should have received a copy of the GNU General Public License
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16− * Authors: Michael Terry <michael.terry@canonical.com>
17 */
16 */
18
17
19/* This class is a really tiny filter around QLightDM::Greeter. There are some
18/* This class is a really tiny filter around QLightDM::Greeter. There are some
@@ -37,6 +36,7 @@ class Greeter : public QObject
37 Q_PROPERTY(bool active READ isActive WRITE setIsActive NOTIFY isActiveChanged)
36 Q_PROPERTY(bool active READ isActive WRITE setIsActive NOTIFY isActiveChanged)
38 Q_PROPERTY(bool authenticated READ isAuthenticated NOTIFY isAuthenticatedChanged)
37 Q_PROPERTY(bool authenticated READ isAuthenticated NOTIFY isAuthenticatedChanged)
39 Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
38 Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
39+ Q_PROPERTY(QString defaultSession READ defaultSessionHint CONSTANT)
40 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
40 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
41 Q_PROPERTY(QString selectUser READ selectUser CONSTANT)
41 Q_PROPERTY(QString selectUser READ selectUser CONSTANT)
42
42
@@ -46,6 +46,7 @@ public:
46 bool isActive() const;
46 bool isActive() const;
47 bool isAuthenticated() const;
47 bool isAuthenticated() const;
48 QString authenticationUser() const;
48 QString authenticationUser() const;
49+ QString defaultSessionHint() const;
49 bool promptless() const;
50 bool promptless() const;
50 QString selectUser() const;
51 QString selectUser() const;
51
52
plugins/LightDM/IntegratedLightDM/CMakeLists.txt+1
@@ -7,6 +7,7 @@ foreach(include_directory ${QMLPLUGIN_INCLUDES})
7endforeach()
7endforeach()
8
8
9include_directories(
9include_directories(
10+ . #QLightDM
10 ${QMLPLUGIN_INCLUDES}
11 ${QMLPLUGIN_INCLUDES}
11 ${libunity8-private_SOURCE_DIR}
12 ${libunity8-private_SOURCE_DIR}
12 ${CMAKE_CURRENT_BINARY_DIR}
13 ${CMAKE_CURRENT_BINARY_DIR}
plugins/LightDM/IntegratedLightDM/QLightDM/Greeternew file+17
@@ -0,0 +1,17 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "../liblightdm/Greeter.h"
plugins/LightDM/IntegratedLightDM/QLightDM/SessionsModelnew file+17
@@ -0,0 +1,17 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "../liblightdm/SessionsModel.h"
plugins/LightDM/IntegratedLightDM/QLightDM/UsersModelnew file+17
@@ -0,0 +1,17 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "../liblightdm/UsersModel.h"
plugins/LightDM/IntegratedLightDM/liblightdm/CMakeLists.txt+2
@@ -2,8 +2,10 @@ pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
2
2
3set(LibLightDM_SOURCES
3set(LibLightDM_SOURCES
4 Greeter.cpp
4 Greeter.cpp
5+ SessionsModel.cpp
5 UsersModel.cpp
6 UsersModel.cpp
6 GreeterPrivate.cpp
7 GreeterPrivate.cpp
8+ SessionsModelPrivate.cpp
7 UsersModelPrivate.cpp
9 UsersModelPrivate.cpp
8 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
10 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
9 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
11 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModel.cppnew file+88
@@ -0,0 +1,88 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+
19+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
20+ * CHANGES MADE HERE MUST BE REFLECTED ON THE MOCK LIB
21+ * COUNTERPART IN tests/mocks/LightDM/IntegratedLightDM/liblightdm
22+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
23+
24+// LightDM currently is Qt4 compatible, and so doesn't define setRoleNames.
25+// To use the same method of setting role name that it does, we
26+// set our compatibility to Qt4 here too.
27+#define QT_DISABLE_DEPRECATED_BEFORE QT_VERSION_CHECK(4, 0, 0)
28+
29+#include "SessionsModel.h"
30+#include "SessionsModelPrivate.h"
31+#include <QtCore/QDir>
32+#include <QtCore/QString>
33+
34+namespace QLightDM
35+{
36+
37+SessionsModel::SessionsModel(QObject* parent) :
38+ QAbstractListModel(parent),
39+ d_ptr(new SessionsModelPrivate(this))
40+{
41+ Q_D(SessionsModel);
42+ m_roleNames = QAbstractListModel::roleNames();
43+ m_roleNames[KeyRole] = "key";
44+ m_roleNames[TypeRole] = "type";
45+}
46+
47+SessionsModel::~SessionsModel()
48+{
49+ delete d_ptr;
50+}
51+
52+QVariant SessionsModel::data(const QModelIndex& index, int role) const
53+{
54+ Q_D(const SessionsModel);
55+
56+ if(!index.isValid()) {
57+ return QVariant();
58+ }
59+
60+ int row = index.row();
61+
62+ switch (role) {
63+ case QLightDM::SessionsModel::KeyRole:
64+ return d->sessionItems[row].key;
65+ case Qt::DisplayRole:
66+ return d->sessionItems[row].name;
67+ default:
68+ return QVariant();
69+ }
70+}
71+
72+QHash<int, QByteArray> SessionsModel::roleNames() const
73+{
74+ return m_roleNames;
75+}
76+
77+int SessionsModel::rowCount(const QModelIndex& parent) const
78+{
79+ Q_D(const SessionsModel);
80+
81+ if (parent.isValid()) {
82+ return 0;
83+ } else { // parent is root
84+ return d->sessionItems.size();
85+ }
86+}
87+
88+} // namespace QLightDM
plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModel.hnew file+72
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef UNITY_INTEGRATED_SESSIONSMODEL_H
19+#define UNITY_INTEGRATED_SESSIONSMODEL_H
20+
21+#include <QtCore/QAbstractListModel>
22+#include <QtCore/QString>
23+
24+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
25+ * CHANGES MADE HERE MUST BE REFLECTED ON THE MOCK LIB
26+ * COUNTERPART IN tests/mocks/LightDM/IntegratedLightDM/liblightdm
27+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
28+
29+// This is taken from liblightdm and modified to confirm to our syle conventions
30+namespace QLightDM
31+{
32+class SessionsModelPrivate;
33+
34+class Q_DECL_EXPORT SessionsModel : public QAbstractListModel
35+ {
36+ Q_OBJECT
37+
38+ Q_ENUMS(SessionModelRoles SessionType)
39+
40+ public:
41+
42+ enum SessionModelRoles {
43+ //name is exposed as Qt::DisplayRole
44+ //comment is exposed as Qt::TooltipRole
45+ KeyRole = Qt::UserRole,
46+ IdRole = KeyRole, /** Deprecated */
47+ TypeRole
48+ };
49+
50+ enum SessionType {
51+ LocalSessions,
52+ RemoteSessions
53+ };
54+
55+ explicit SessionsModel(QObject* parent=0); /** Deprecated. Loads local sessions*/
56+ explicit SessionsModel(SessionsModel::SessionType, QObject* parent=0);
57+ virtual ~SessionsModel();
58+
59+ QHash<int, QByteArray> roleNames() const override;
60+ int rowCount(const QModelIndex& parent) const override;
61+ QVariant data(const QModelIndex& index, int role) const override;
62+
63+ protected:
64+ SessionsModelPrivate* const d_ptr;
65+
66+ private:
67+ QHash<int, QByteArray> m_roleNames;
68+ Q_DECLARE_PRIVATE(SessionsModel)
69+ };
70+}
71+
72+#endif // UNITY_INTEGRATED_SESSIONSMODEL_H
plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.cppnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#include "SessionsModelPrivate.h"
19+
20+#include <QDir>
21+#include <QSettings>
22+#include <QStringList>
23+
24+namespace QLightDM
25+{
26+
27+SessionsModelPrivate::SessionsModelPrivate(SessionsModel* parent)
28+ : q_ptr(parent)
29+{
30+ // Since this model is never visible, as there is only 1 session,
31+ // just use the session name as the key
32+ QString sessionName = qgetenv("XDG_SESSION_DESKTOP");
33+ sessionItems.append({sessionName, "", sessionName, ""});
34+}
35+
36+} // namespace QLightDM
plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.hnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef UNITY_INTEGRATED_SESSIONSMODEL_PRIVATE_H
19+#define UNITY_INTEGRATED_SESSIONSMODEL_PRIVATE_H
20+
21+#include <QtCore/QList>
22+#include <QtCore/QString>
23+
24+namespace QLightDM
25+{
26+class SessionsModel;
27+
28+class SessionItem
29+{
30+public:
31+ QString key;
32+ QString type; // unused
33+ QString name;
34+ QString comment; // unused
35+};
36+
37+class SessionsModelPrivate
38+{
39+public:
40+ explicit SessionsModelPrivate(SessionsModel* parent=0);
41+ virtual ~SessionsModelPrivate() = default;
42+
43+ QList<SessionItem> sessionItems;
44+
45+protected:
46+ SessionsModel* const q_ptr;
47+
48+private:
49+ Q_DECLARE_PUBLIC(SessionsModel)
50+};
51+
52+} // namespace QLightDM
53+
54+#endif // UNITY_INTEGRATED_SESSIONSMODEL_PRIVATE_H
plugins/LightDM/SessionsModel.cppnew file+122
@@ -0,0 +1,122 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#include "SessionsModel.h"
19+#include <QtCore/QFile>
20+#include <QtCore/QSortFilterProxyModel>
21+
22+QHash<int, QByteArray> SessionsModel::roleNames() const
23+{
24+ return m_roleNames;
25+}
26+
27+int SessionsModel::rowCount(const QModelIndex& parent) const
28+{
29+ return m_model->rowCount(parent);
30+}
31+
32+QList<QUrl> SessionsModel::iconSearchDirectories() const
33+{
34+ return m_iconSearchDirectories;
35+}
36+
37+void SessionsModel::setIconSearchDirectories(const QList<QUrl> searchDirectories)
38+{
39+ // QML gives us a url with file:// prepended which breaks QFile::exists()
40+ // so convert the url to a local file
41+ QList<QUrl> localList = {};
42+ Q_FOREACH(const QUrl& searchDirectory, searchDirectories)
43+ {
44+ localList.append(searchDirectory.toLocalFile());
45+ }
46+ m_iconSearchDirectories = localList;
47+ Q_EMIT iconSearchDirectoriesChanged();
48+}
49+
50+QUrl SessionsModel::iconUrl(const QString sessionName) const
51+{
52+ Q_FOREACH(const QUrl& searchDirectory, m_iconSearchDirectories)
53+ {
54+ // This is an established icon naming convention
55+ QString customIconUrl = searchDirectory.toString(QUrl::StripTrailingSlash) +
56+ "/custom_" + sessionName + "_badge.png";
57+ QString iconUrl = searchDirectory.toString(QUrl::StripTrailingSlash) +
58+ "/" + sessionName + "_badge.png";
59+
60+ QFile customIconFile(customIconUrl);
61+ QFile iconFile(iconUrl);
62+ if (customIconFile.exists()) {
63+ return QUrl(customIconUrl);
64+ } else if (iconFile.exists()) {
65+ return QUrl(iconUrl);
66+ } else{
67+ // Search the legacy way
68+ QString path = searchDirectory.toString(QUrl::StripTrailingSlash) + "/";
69+ if (sessionName == "ubuntu" || sessionName == "ubuntu-2d") {
70+ path += "ubuntu_badge.png";
71+ } else if(
72+ sessionName == "gnome-classic" ||
73+ sessionName == "gnome-flashback-compiz" ||
74+ sessionName == "gnome-flashback-metacity" ||
75+ sessionName == "gnome-shell" ||
76+ sessionName == "gnome-wayland" ||
77+ sessionName == "gnome"
78+ ){
79+ path += "gnome_badge.png";
80+ } else if (sessionName == "plasma") {
81+ path += "kde_badge.png";
82+ } else if (sessionName == "xterm") {
83+ path += "recovery_console_badge.png";
84+ } else if (sessionName == "remote-login") {
85+ path += "remote_login_help.png";
86+ }
87+
88+ if (QFile(path).exists()) {
89+ return path;
90+ }
91+ }
92+ }
93+
94+ // FIXME make this smarter
95+ return QUrl("./graphics/session_icons/unknown_badge.png");
96+}
97+
98+QVariant SessionsModel::data(const QModelIndex& index, int role) const
99+{
100+ switch (role) {
101+ case SessionsModel::IconRole:
102+ return iconUrl(m_model->data(index, Qt::DisplayRole).toString());
103+ default:
104+ return m_model->data(index, role);
105+ }
106+}
107+
108+SessionsModel::SessionsModel(QObject* parent)
109+ : UnitySortFilterProxyModelQML(parent)
110+{
111+ // Add a custom IconRole that isn't in either of the lightdm implementations
112+ m_model = new QLightDM::SessionsModel(this);
113+ m_roleNames = m_model->roleNames();
114+ m_roleNames[IconRole] = "icon_url";
115+
116+ setModel(m_model);
117+ setSourceModel(m_model);
118+ setSortCaseSensitivity(Qt::CaseInsensitive);
119+ setSortLocaleAware(true);
120+ setSortRole(Qt::DisplayRole);
121+ sort(0);
122+}
plugins/LightDM/SessionsModel.hnew file+68
@@ -0,0 +1,68 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef UNITY_SESSIONSMODEL_H
19+#define UNITY_SESSIONSMODEL_H
20+
21+#include <unitysortfilterproxymodelqml.h>
22+#include <QLightDM/SessionsModel>
23+#include <QtCore/QHash>
24+#include <QtCore/QObject>
25+#include <QtCore/QUrl>
26+
27+class SessionsModel : public UnitySortFilterProxyModelQML
28+{
29+ Q_OBJECT
30+
31+ Q_ENUMS(SessionModelRoles)
32+
33+ Q_PROPERTY(QList<QUrl> iconSearchDirectories READ iconSearchDirectories
34+ WRITE setIconSearchDirectories NOTIFY iconSearchDirectoriesChanged)
35+Q_SIGNALS:
36+ void iconSearchDirectoriesChanged();
37+
38+public:
39+ enum SessionModelRoles {
40+ /* This is tricky / ugly. Since we are ultimately chaining 3 enums together,
41+ * the _first_ value of this enum MUST be the _last_ value of
42+ * QLightDM::SessionsModel::SessionModelRoles and consquently, this must
43+ * also match the last value in the corresponding enum of the integrated lib
44+ */
45+ TypeRole = QLightDM::SessionsModel::SessionModelRoles::TypeRole,
46+ IconRole
47+ };
48+
49+ explicit SessionsModel(QObject* parent=nullptr);
50+
51+ QHash<int, QByteArray> roleNames() const override;
52+ int rowCount(const QModelIndex& parent) const override;
53+ QVariant data(const QModelIndex& index, int role) const override;
54+ QList<QUrl> iconSearchDirectories() const;
55+ Q_INVOKABLE QUrl iconUrl(const QString sessionName) const;
56+
57+ void setIconSearchDirectories(const QList<QUrl> searchDirectories);
58+private:
59+ QLightDM::SessionsModel* m_model;
60+ QHash<int, QByteArray> m_roleNames;
61+ QList<QUrl> m_iconSearchDirectories{
62+ QUrl("/usr/share/unity8/Greeter/graphics/session_icons"),
63+ QUrl("/usr/local/share/unity-greeter"),
64+ QUrl("/usr/share/unity-greeter/")};
65+
66+};
67+
68+#endif // UNITY_SESSIONSMODEL_H
plugins/LightDM/plugin.cpp+17−7
@@ -19,9 +19,11 @@
19#include "DBusGreeter.h"
19#include "DBusGreeter.h"
20#include "DBusGreeterList.h"
20#include "DBusGreeterList.h"
21#include "Greeter.h"
21#include "Greeter.h"
22+#include "SessionsModel.h"
22#include "UsersModel.h"
23#include "UsersModel.h"
23#include <libusermetricsoutput/ColorTheme.h>
24#include <libusermetricsoutput/ColorTheme.h>
24#include <libusermetricsoutput/UserMetrics.h>
25#include <libusermetricsoutput/UserMetrics.h>
26+#include <QLightDM/SessionsModel>
25#include <QLightDM/UsersModel>
27#include <QLightDM/UsersModel>
26
28
27#include <QAbstractItemModel>
29#include <QAbstractItemModel>
@@ -40,6 +42,13 @@ static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
40 return greeter;
42 return greeter;
41}
43}
42
44
45+static QObject *sessions_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
46+{
47+ Q_UNUSED(engine)
48+ Q_UNUSED(scriptEngine)
49+ return new SessionsModel();
50+}
51+
43static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
52static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
44{
53{
45 Q_UNUSED(engine)
54 Q_UNUSED(engine)
@@ -61,21 +70,22 @@ void PLUGIN_CLASSNAME::registerTypes(const char *uri)
61
70
62#if defined INTEGRATED_LIGHTDM
71#if defined INTEGRATED_LIGHTDM
63 Q_ASSERT(uri == QLatin1String("LightDM.IntegratedLightDM"));
72 Q_ASSERT(uri == QLatin1String("LightDM.IntegratedLightDM"));
64−#elif defined FULL_LIGHTDM
65− Q_ASSERT(uri == QLatin1String("LightDM.FullLightDM"));
66−#endif
67− qRegisterMetaType<QLightDM::Greeter::MessageType>("QLightDM::Greeter::MessageType");
68− qRegisterMetaType<QLightDM::Greeter::PromptType>("QLightDM::Greeter::PromptType");
69−
70−#if defined INTEGRATED_LIGHTDM
71 qmlRegisterSingletonType<Greeter>(uri, 0, 1, "Greeter", greeter_provider);
73 qmlRegisterSingletonType<Greeter>(uri, 0, 1, "Greeter", greeter_provider);
72#elif defined FULL_LIGHTDM
74#elif defined FULL_LIGHTDM
75+ Q_ASSERT(uri == QLatin1String("LightDM.FullLightDM"));
73 qmlRegisterSingletonType<QLightDM::Greeter>(uri, 0, 1, "Greeter", greeter_provider);
76 qmlRegisterSingletonType<QLightDM::Greeter>(uri, 0, 1, "Greeter", greeter_provider);
74#else
77#else
75 #error No library defined in LightDM plugin
78 #error No library defined in LightDM plugin
76#endif
79#endif
77
80
81+ qRegisterMetaType<QLightDM::Greeter::MessageType>("QLightDM::Greeter::MessageType");
82+ qRegisterMetaType<QLightDM::Greeter::PromptType>("QLightDM::Greeter::PromptType");
83+
84+ qmlRegisterSingletonType<SessionsModel>(uri, 0, 1, "Sessions", sessions_provider);
85+ qmlRegisterUncreatableType<SessionsModel>(uri, 0, 1, "SessionRoles", QStringLiteral("Type is not instantiable"));
86+
78 qmlRegisterSingletonType<UsersModel>(uri, 0, 1, "Users", users_provider);
87 qmlRegisterSingletonType<UsersModel>(uri, 0, 1, "Users", users_provider);
79 qmlRegisterUncreatableType<QLightDM::UsersModel>(uri, 0, 1, "UserRoles", QStringLiteral("Type is not instantiable"));
88 qmlRegisterUncreatableType<QLightDM::UsersModel>(uri, 0, 1, "UserRoles", QStringLiteral("Type is not instantiable"));
89+
80 qmlRegisterSingletonType<UserMetricsOutput::UserMetrics>(uri, 0, 1, "Infographic", infographic_provider);
90 qmlRegisterSingletonType<UserMetricsOutput::UserMetrics>(uri, 0, 1, "Infographic", infographic_provider);
81}
91}
tests/mocks/LightDM/IntegratedLightDM/CMakeLists.txt+2
@@ -19,9 +19,11 @@ set(QMLPLUGIN_SRC
19 ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeter.cpp
19 ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeter.cpp
20 ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeterList.cpp
20 ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeterList.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
22+ ${CMAKE_SOURCE_DIR}/plugins/LightDM/SessionsModel.cpp
22 ${CMAKE_SOURCE_DIR}/plugins/LightDM/UsersModel.cpp
23 ${CMAKE_SOURCE_DIR}/plugins/LightDM/UsersModel.cpp
23 ${CMAKE_SOURCE_DIR}/plugins/Utils/unitysortfilterproxymodelqml.cpp
24 ${CMAKE_SOURCE_DIR}/plugins/Utils/unitysortfilterproxymodelqml.cpp
24 MockGreeter.cpp
25 MockGreeter.cpp
26+ MockSessionsModel.cpp
25 MockUsersModel.cpp
27 MockUsersModel.cpp
26 plugin.cpp
28 plugin.cpp
27 )
29 )
tests/mocks/LightDM/IntegratedLightDM/MockSessionsModel.cppnew file+37
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#include "MockSessionsModel.h"
19+#include <QLightDM/SessionsModel>
20+
21+QString MockSessionsModel::testScenario() const
22+{
23+ QLightDM::SessionsModel* qSessionsModel =
24+ static_cast<QLightDM::SessionsModel*>(sourceModel());
25+
26+ return qSessionsModel->testScenario();
27+}
28+
29+void MockSessionsModel::setTestScenario(const QString testScenario)
30+{
31+ QLightDM::SessionsModel* qSessionsModel =
32+ static_cast<QLightDM::SessionsModel*>(sourceModel());
33+
34+ if (qSessionsModel->testScenario() != testScenario) {
35+ qSessionsModel->setTestScenario(testScenario);
36+ }
37+}
tests/mocks/LightDM/IntegratedLightDM/MockSessionsModel.hnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef MOCK_UNITY_SESSIONSMODEL_H
19+#define MOCK_UNITY_SESSIONSMODEL_H
20+
21+#include <SessionsModel.h>
22+
23+class MockSessionsModel : public SessionsModel
24+{
25+ Q_OBJECT
26+
27+ Q_PROPERTY(QString testScenario READ testScenario WRITE setTestScenario)
28+
29+public:
30+ QString testScenario() const;
31+ void setTestScenario(QString testScenario);
32+};
33+
34+#endif // MOCK_UNITY_SESSIONSMODEL_H
tests/mocks/LightDM/IntegratedLightDM/QLightDM/SessionsModelnew file+17
@@ -0,0 +1,17 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "../liblightdm/SessionsModel.h"
tests/mocks/LightDM/IntegratedLightDM/liblightdm/CMakeLists.txt+2
@@ -1,7 +1,9 @@
1set(LibLightDM_SOURCES
1set(LibLightDM_SOURCES
2 Greeter.cpp
2 Greeter.cpp
3+ SessionsModel.cpp
3 UsersModel.cpp
4 UsersModel.cpp
4 GreeterPrivate.cpp
5 GreeterPrivate.cpp
6+ SessionsModelPrivate.cpp
5 UsersModelPrivate.cpp
7 UsersModelPrivate.cpp
6 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
8 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
7 )
9 )
tests/mocks/LightDM/IntegratedLightDM/liblightdm/Greeter.cpp+1−1
@@ -51,7 +51,7 @@ QString Greeter::getHint(const QString &name) const
51
51
52QString Greeter::defaultSessionHint() const
52QString Greeter::defaultSessionHint() const
53{
53{
54− return "ubuntu";
54+ return QStringLiteral("ubuntu");
55}
55}
56
56
57bool Greeter::hideUsersHint() const
57bool Greeter::hideUsersHint() const
tests/mocks/LightDM/IntegratedLightDM/liblightdm/SessionsModel.cppnew file+99
@@ -0,0 +1,99 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+
19+// LightDM currently is Qt4 compatible, and so doesn't define setRoleNames.
20+// To use the same method of setting role name that it does, we
21+// set our compatibility to Qt4 here too.
22+#define QT_DISABLE_DEPRECATED_BEFORE QT_VERSION_CHECK(4, 0, 0)
23+
24+#include "SessionsModel.h"
25+#include "SessionsModelPrivate.h"
26+#include <QtCore/QDir>
27+#include <QtCore/QString>
28+
29+namespace QLightDM
30+{
31+
32+SessionsModel::SessionsModel(QObject* parent) :
33+ QAbstractListModel(parent),
34+ d_ptr(new SessionsModelPrivate(this))
35+{
36+ Q_D(SessionsModel);
37+ m_roleNames = QAbstractListModel::roleNames();
38+ m_roleNames[KeyRole] = "key";
39+ m_roleNames[TypeRole] = "type";
40+}
41+
42+SessionsModel::~SessionsModel()
43+{
44+ delete d_ptr;
45+}
46+
47+QVariant SessionsModel::data(const QModelIndex& index, int role) const
48+{
49+ Q_D(const SessionsModel);
50+
51+ if(!index.isValid()) {
52+ return QVariant();
53+ }
54+
55+ int row = index.row();
56+
57+ switch (role) {
58+ case QLightDM::SessionsModel::KeyRole:
59+ return d->sessionItems[row].key;
60+ case Qt::DisplayRole:
61+ return d->sessionItems[row].name;
62+ default:
63+ return QVariant();
64+ }
65+}
66+
67+QHash<int, QByteArray> SessionsModel::roleNames() const
68+{
69+ return m_roleNames;
70+}
71+
72+int SessionsModel::rowCount(const QModelIndex& parent) const
73+{
74+ Q_D(const SessionsModel);
75+
76+ if (parent.isValid()) {
77+ return 0;
78+ } else { // parent is root
79+ return d->sessionItems.size();
80+ }
81+}
82+
83+QString SessionsModel::testScenario() const
84+{
85+ Q_D(const SessionsModel);
86+ return d->testScenario;
87+}
88+
89+void SessionsModel::setTestScenario(QString testScenario)
90+{
91+ Q_D(SessionsModel);
92+
93+ if (d->testScenario != testScenario) {
94+ d->testScenario = testScenario;
95+ d->resetEntries();
96+ }
97+}
98+
99+} // namespace QLightDM
tests/mocks/LightDM/IntegratedLightDM/liblightdm/SessionsModel.hnew file+72
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef UNITY_MOCK_SESSIONSMODEL_H
19+#define UNITY_MOCK_SESSIONSMODEL_H
20+
21+#include <QtCore/QAbstractListModel>
22+#include <QtCore/QString>
23+
24+namespace QLightDM
25+{
26+class SessionsModelPrivate;
27+
28+class Q_DECL_EXPORT SessionsModel : public QAbstractListModel
29+ {
30+ Q_OBJECT
31+
32+ Q_ENUMS(SessionModelRoles SessionType)
33+
34+ // Mock-only API for testing purposes
35+ Q_PROPERTY(QString testScenario READ testScenario WRITE setTestScenario)
36+
37+ public:
38+
39+ enum SessionModelRoles {
40+ //name is exposed as Qt::DisplayRole
41+ //comment is exposed as Qt::TooltipRole
42+ KeyRole = Qt::UserRole,
43+ IdRole = KeyRole, /** Deprecated */
44+ TypeRole
45+ };
46+
47+ enum SessionType {
48+ LocalSessions,
49+ RemoteSessions
50+ };
51+
52+ explicit SessionsModel(QObject* parent=nullptr); /** Deprecated. Loads local sessions*/
53+ explicit SessionsModel(SessionsModel::SessionType, QObject* parent=nullptr);
54+ virtual ~SessionsModel();
55+
56+ QHash<int, QByteArray> roleNames() const override;
57+ int rowCount(const QModelIndex& parent) const override;
58+ QVariant data(const QModelIndex& index, int role) const override;
59+
60+ QString testScenario() const;
61+ void setTestScenario(QString testScenario);
62+
63+ protected:
64+ SessionsModelPrivate* const d_ptr;
65+
66+ private:
67+ QHash<int, QByteArray> m_roleNames;
68+ Q_DECLARE_PRIVATE(SessionsModel)
69+ };
70+}
71+
72+#endif // UNITY_MOCK_SESSIONSMODEL_H
tests/mocks/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.cppnew file+73
@@ -0,0 +1,73 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "SessionsModel.h"
18+#include "SessionsModelPrivate.h"
19+
20+namespace QLightDM
21+{
22+
23+SessionsModelPrivate::SessionsModelPrivate(SessionsModel* parent)
24+ : testScenario("singleSession")
25+ , q_ptr(parent)
26+{
27+ resetEntries();
28+}
29+
30+void SessionsModelPrivate::resetEntries()
31+{
32+ Q_Q(SessionsModel);
33+
34+ q->beginResetModel();
35+ if (testScenario == "multipleSessions") {
36+ resetEntries_multipleSessions();
37+ } else if (testScenario == "noSessions") {
38+ resetEntries_noSessions();
39+ } else {
40+ resetEntries_singleSession();
41+ }
42+ q->endResetModel();
43+}
44+
45+void SessionsModelPrivate::resetEntries_multipleSessions()
46+{
47+ sessionItems =
48+ {
49+ {"ubuntu", "", "Ubuntu", ""},
50+ {"ubuntu-2d", "", "Ubuntu 2D", ""},
51+ {"gnome", "", "GNOME", ""},
52+ {"gnome-classic", "", "GNOME Classic", ""},
53+ {"gnome-flashback-compiz", "", "GNOME Flashback (Compiz)", ""},
54+ {"gnome-flashback-metacity", "", "GNOME Flashback (Metacity)", ""},
55+ {"gnome-wayland", "", "GNOME on Wayland", ""},
56+ {"plasma", "", "Plasma", ""},
57+ {"kde", "", "KDE" , ""},
58+ {"xterm", "", "Recovery Console", ""},
59+ {"", "", "Unknown?", ""}
60+ };
61+}
62+
63+void SessionsModelPrivate::resetEntries_noSessions()
64+{
65+ sessionItems = {};
66+}
67+
68+void SessionsModelPrivate::resetEntries_singleSession()
69+{
70+ sessionItems = {{"ubuntu", "", "Ubuntu", ""}};
71+}
72+
73+} // namespace QLightDM
tests/mocks/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.hnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef UNITY_MOCK_SESSIONSMODEL_PRIVATE_H
19+#define UNITY_MOCK_SESSIONSMODEL_PRIVATE_H
20+
21+#include <QtCore/QList>
22+#include <QtCore/QString>
23+
24+namespace QLightDM
25+{
26+class SessionsModel;
27+
28+class SessionItem
29+{
30+public:
31+ QString key;
32+ QString type; // unused
33+ QString name;
34+ QString comment; // unused
35+};
36+
37+class SessionsModelPrivate
38+{
39+public:
40+ explicit SessionsModelPrivate(SessionsModel* parent=0);
41+ virtual ~SessionsModelPrivate() = default;
42+
43+ QList<SessionItem> sessionItems;
44+ QString testScenario;
45+
46+ void resetEntries();
47+protected:
48+ SessionsModel* const q_ptr;
49+
50+private:
51+ void resetEntries_multipleSessions();
52+ void resetEntries_noSessions();
53+ void resetEntries_singleSession();
54+ Q_DECLARE_PUBLIC(SessionsModel)
55+};
56+
57+} // namespace QLightDM
58+
59+#endif // UNITY_MOCK_SESSIONSMODEL_PRIVATE_H
tests/mocks/LightDM/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+22−22
@@ -60,7 +60,7 @@ void UsersModelPrivate::resetEntries_single()
60{
60{
61 entries =
61 entries =
62 {
62 {
63− { "single", "Single User", 0, 0, false, false, 0, 0, 0 },
63+ { "single", "Single User", 0, 0, false, false, "ubuntu", 0 },
64 };
64 };
65}
65}
66
66
@@ -68,7 +68,7 @@ void UsersModelPrivate::resetEntries_singlePassphrase()
68{
68{
69 entries =
69 entries =
70 {
70 {
71− { "single", "Single User", 0, 0, false, false, 0, 0, 0 },
71+ { "single", "Single User", 0, 0, false, false, "ubuntu", 0 },
72 };
72 };
73}
73}
74
74
@@ -76,7 +76,7 @@ void UsersModelPrivate::resetEntries_singlePin()
76{
76{
77 entries =
77 entries =
78 {
78 {
79− { "has-pin", "Has PIN", 0, 0, false, false, 0, 0, 0 },
79+ { "has-pin", "Has PIN", 0, 0, false, false, "ubuntu", 0 },
80 };
80 };
81}
81}
82
82
@@ -84,26 +84,26 @@ void UsersModelPrivate::resetEntries_full()
84{
84{
85 entries =
85 entries =
86 {
86 {
87− { "has-password", "Has Password", 0, 0, false, false, 0, 0, 0 },
87+ { "has-password", "Has Password", 0, 0, false, false, "ubuntu", 0 },
88− { "has-pin", "Has PIN", 0, 0, false, false, 0, 0, 0 },
88+ { "has-pin", "Has PIN", 0, 0, false, false, "ubuntu", 0 },
89− { "different-prompt", "Different Prompt", 0, 0, false, false, 0, 0, 0 },
89+ { "different-prompt", "Different Prompt", 0, 0, false, false, "ubuntu", 0 },
90− { "no-password", "No Password", 0, 0, false, false, 0, 0, 0 },
90+ { "no-password", "No Password", 0, 0, false, false, "ubuntu", 0 },
91− { "auth-error", "Auth Error", 0, 0, false, false, 0, 0, 0 },
91+ { "auth-error", "Auth Error", 0, 0, false, false, "ubuntu", 0 },
92− { "two-factor", "Two Factor", 0, 0, false, false, 0, 0, 0 },
92+ { "two-factor", "Two Factor", 0, 0, false, false, "ubuntu", 0 },
93− { "info-prompt", "Info Prompt", 0, 0, false, false, 0, 0, 0 },
93+ { "info-prompt", "Info Prompt", 0, 0, false, false, "ubuntu", 0 },
94− { "html-info-prompt", "HTML Info Prompt", 0, 0, false, false, 0, 0, 0 },
94+ { "html-info-prompt", "HTML Info Prompt", 0, 0, false, false, "ubuntu", 0 },
95− { "long-info-prompt", "Long Info Prompt", 0, 0, false, false, 0, 0, 0 },
95+ { "long-info-prompt", "Long Info Prompt", 0, 0, false, false, "ubuntu", 0 },
96− { "wide-info-prompt", "Wide Info Prompt", 0, 0, false, false, 0, 0, 0 },
96+ { "wide-info-prompt", "Wide Info Prompt", 0, 0, false, false, "ubuntu", 0 },
97− { "multi-info-prompt", "Multi Info Prompt", 0, 0, false, false, 0, 0, 0 },
97+ { "multi-info-prompt", "Multi Info Prompt", 0, 0, false, false, "ubuntu", 0 },
98− { "long-name", "Long name (far far too long to fit, seriously this would never fit on the screen, you will never see this part of the name)", 0, 0, false, false, 0, 0, 0 },
98+ { "long-name", "Long name (far far too long to fit, seriously this would never fit on the screen, you will never see this part of the name)", 0, 0, false, false, "ubuntu", 0 },
99− { "color-background", "Color Background", "#dd4814", 0, false, false, 0, 0, 0 },
99+ { "color-background", "Color Background", "#dd4814", 0, false, false, "ubuntu", 0 },
100 // white and black are a bit redundant, but useful for manually testing if UI is still readable
100 // white and black are a bit redundant, but useful for manually testing if UI is still readable
101− { "white-background", "White Background", "#ffffff", 0, false, false, 0, 0, 0 },
101+ { "white-background", "White Background", "#ffffff", 0, false, false, "ubuntu", 0 },
102− { "black-background", "Black Background", "#000000", 0, false, false, 0, 0, 0 },
102+ { "black-background", "Black Background", "#000000", 0, false, false, "ubuntu", 0 },
103− { "no-background", "No Background", "", 0, false, false, 0, 0, 0 },
103+ { "no-background", "No Background", "", 0, false, false, "ubuntu", 0 },
104− { "unicode", "가나다라마", 0, 0, false, false, 0, 0, 0 },
104+ { "unicode", "가나다라마", 0, 0, false, false, "ubuntu", 0 },
105− { "no-response", "No Response", 0, 0, false, false, 0, 0, 0 },
105+ { "no-response", "No Response", 0, 0, false, false, "ubuntu", 0 },
106− { "empty-name", "", 0, 0, false, false, 0, 0, 0 },
106+ { "empty-name", "", 0, 0, false, false, "ubuntu", 0 },
107 };
107 };
108}
108}
109
109
tests/mocks/LightDM/IntegratedLightDM/plugin.cpp+11
@@ -18,7 +18,9 @@
18#include <DBusGreeter.h>
18#include <DBusGreeter.h>
19#include <DBusGreeterList.h>
19#include <DBusGreeterList.h>
20#include "MockGreeter.h"
20#include "MockGreeter.h"
21+#include "MockSessionsModel.h"
21#include "MockUsersModel.h"
22#include "MockUsersModel.h"
23+#include <QLightDM/SessionsModel>
22#include "ColorTheme.h"
24#include "ColorTheme.h"
23#include "UserMetrics.h"
25#include "UserMetrics.h"
24#include <QLightDM/UsersModel>
26#include <QLightDM/UsersModel>
@@ -39,6 +41,13 @@ static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
39 return greeter;
41 return greeter;
40}
42}
41
43
44+static QObject *sessions_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
45+{
46+ Q_UNUSED(engine)
47+ Q_UNUSED(scriptEngine)
48+ return new MockSessionsModel;
49+}
50+
42static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
51static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
43{
52{
44 Q_UNUSED(engine)
53 Q_UNUSED(engine)
@@ -62,6 +71,8 @@ void LightDMPlugin::registerTypes(const char *uri)
62 qRegisterMetaType<QLightDM::Greeter::MessageType>("QLightDM::Greeter::MessageType");
71 qRegisterMetaType<QLightDM::Greeter::MessageType>("QLightDM::Greeter::MessageType");
63 qRegisterMetaType<QLightDM::Greeter::PromptType>("QLightDM::Greeter::PromptType");
72 qRegisterMetaType<QLightDM::Greeter::PromptType>("QLightDM::Greeter::PromptType");
64 qmlRegisterSingletonType<MockGreeter>(uri, 0, 1, "Greeter", greeter_provider);
73 qmlRegisterSingletonType<MockGreeter>(uri, 0, 1, "Greeter", greeter_provider);
74+ qmlRegisterSingletonType<MockSessionsModel>(uri, 0, 1, "Sessions", sessions_provider);
75+ qmlRegisterUncreatableType<SessionsModel>(uri, 0, 1, "SessionRoles", "Type is not instantiable");
65 qmlRegisterSingletonType<MockUsersModel>(uri, 0, 1, "Users", users_provider);
76 qmlRegisterSingletonType<MockUsersModel>(uri, 0, 1, "Users", users_provider);
66 qmlRegisterUncreatableType<QLightDM::UsersModel>(uri, 0, 1, "UserRoles", "Type is not instantiable");
77 qmlRegisterUncreatableType<QLightDM::UsersModel>(uri, 0, 1, "UserRoles", "Type is not instantiable");
67 qmlRegisterSingletonType<UserMetricsOutput::UserMetrics>(uri, 0, 1, "Infographic", infographic_provider);
78 qmlRegisterSingletonType<UserMetricsOutput::UserMetrics>(uri, 0, 1, "Infographic", infographic_provider);
tests/plugins/LightDM/IntegratedLightDM/CMakeLists.txt+23
@@ -44,6 +44,29 @@ target_include_directories(GreeterPamTestExec PUBLIC
44 )
44 )
45add_qmltest_target(testGreeterPam GreeterPamTestExec COMMAND $<TARGET_FILE:GreeterPamTestExec>)
45add_qmltest_target(testGreeterPam GreeterPamTestExec COMMAND $<TARGET_FILE:GreeterPamTestExec>)
46
46
47+# SessionsModelTest
48+add_executable(GreeterSessionsModelTestExec
49+ sessionsmodel.cpp
50+ ${CMAKE_SOURCE_DIR}/plugins/LightDM/SessionsModel.cpp
51+ ${CMAKE_SOURCE_DIR}/plugins/Utils/unitysortfilterproxymodelqml.cpp
52+ )
53+add_dependencies(GreeterSessionsModelTestExec MockLightDM)
54+qt5_use_modules(GreeterSessionsModelTestExec Core Test)
55+target_link_libraries(GreeterSessionsModelTestExec
56+ MockLightDM
57+ )
58+target_include_directories(GreeterSessionsModelTestExec PUBLIC
59+ ${CMAKE_SOURCE_DIR}/plugins/LightDM
60+ ${CMAKE_SOURCE_DIR}/plugins/Utils
61+ ${CMAKE_SOURCE_DIR}/tests/mocks/LightDM/IntegratedLightDM
62+ )
63+add_unity8_uitest(GreeterSessions GreeterSessionsModelTestExec
64+ ENVIRONMENT LIBLIGHTDM_MOCK_MODE=full
65+ DEPENDS MockLightDM
66+ LIGHTDM
67+ )
68+
69+# UsersModelTest
47add_executable(GreeterUsersModelTestExec
70add_executable(GreeterUsersModelTestExec
48 usersmodel.cpp
71 usersmodel.cpp
49 ${CMAKE_SOURCE_DIR}/plugins/LightDM/UsersModel.cpp
72 ${CMAKE_SOURCE_DIR}/plugins/LightDM/UsersModel.cpp
tests/plugins/LightDM/IntegratedLightDM/sessionsmodel.cppnew file+96
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "SessionsModel.h"
18+
19+#include <QLightDM/SessionsModel>
20+#include <QtCore/QModelIndex>
21+#include <QtTest>
22+#include <QString>
23+
24+class GreeterSessionsModelTest : public QObject
25+{
26+ Q_OBJECT
27+
28+private Q_SLOTS:
29+
30+ void init()
31+ {
32+ model = new SessionsModel();
33+ QVERIFY(model);
34+ sourceModel = new QLightDM::SessionsModel();
35+ QVERIFY(sourceModel);
36+ }
37+
38+ void cleanup()
39+ {
40+ delete model;
41+ delete sourceModel;
42+ }
43+
44+ static QModelIndex findByKey(QAbstractItemModel *model, const QString& key)
45+ {
46+ for (int i = 0; i < model->rowCount(QModelIndex()); i++) {
47+ if (model->data(model->index(i, 0), QLightDM::SessionsModel::KeyRole).toString() == key)
48+ return model->index(i, 0);
49+ }
50+
51+ return QModelIndex();
52+ }
53+
54+ void testIconDirectoriesAreValid()
55+ {
56+ Q_FOREACH(const QUrl& searchDirectory, model->iconSearchDirectories())
57+ {
58+ QVERIFY(searchDirectory.isValid());
59+ }
60+ }
61+
62+ void testMultipleSessionsCountIsCorrect()
63+ {
64+ sourceModel->setTestScenario("multipleSessions");
65+ QVERIFY(sourceModel->rowCount(QModelIndex()) > 1);
66+ }
67+
68+ void testNoSessionsCountIsCorrect()
69+ {
70+ sourceModel->setTestScenario("noSessions");
71+ QVERIFY(sourceModel->rowCount(QModelIndex()) == 0);
72+ }
73+
74+ void testSingleSessionCountIsCorrect()
75+ {
76+ sourceModel->setTestScenario("singleSession");
77+ QVERIFY(sourceModel->rowCount(QModelIndex()) == 1);
78+ }
79+
80+ void testSessionNameIsCorrect()
81+ {
82+ // This is testing the lookup, not the correctness of the strings,
83+ // so one test should be sufficient
84+ sourceModel->setTestScenario("multipleSessions");
85+ QVERIFY(model->data(findByKey(sourceModel, "ubuntu"),
86+ Qt::DisplayRole).toString() == "Ubuntu");
87+ }
88+
89+private:
90+ SessionsModel *model;
91+ QLightDM::SessionsModel *sourceModel;
92+};
93+
94+QTEST_MAIN(GreeterSessionsModelTest)
95+
96+#include "sessionsmodel.moc"