on xenial help sign in
Add DBus interface from desktop greeter to unity8 greeter; add tests for same
6d5a5bbMichael Terry
Greeter/LoginList.qml+11
@@ -289,5 +289,16 @@ Item {
289 }
289 }
290 passwordInput.text = "";
290 passwordInput.text = "";
291 }
291 }
292+
293+ onRequestAuthenticationUser: {
294+ // Find index for requested user, if it exists
295+ for (var i = 0; i < userList.model.count; i++) {
296+ if (user == userList.model.data(i, LightDM.UserRoles.NameRole)) {
297+ moveTimer.start();
298+ userList.currentIndex = i;
299+ return;
300+ }
301+ }
302+ }
292 }
303 }
293}
304}
plugins/LightDM/CMakeLists.txt+2−1
@@ -17,6 +17,7 @@ include_directories(
17
17
18set(QMLPLUGIN_SRC
18set(QMLPLUGIN_SRC
19 ../Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
19 ../Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
20+ DBusGreeterList.cpp
20 Greeter.cpp
21 Greeter.cpp
21 plugin.cpp
22 plugin.cpp
22 UsersModel.cpp
23 UsersModel.cpp
@@ -33,7 +34,7 @@ target_link_libraries(LightDM-qml
33 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
34 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
34 )
35 )
35
36
36−qt5_use_modules(LightDM-qml Gui Qml)
37+qt5_use_modules(LightDM-qml DBus Gui Qml)
37
38
38# export the qmldir qmltypes and plugin files
39# export the qmldir qmltypes and plugin files
39export_qmlfiles(LightDM LightDM)
40export_qmlfiles(LightDM LightDM)
plugins/LightDM/DBusGreeterList.cppnew file+41
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (C) 2013 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 "DBusGreeterList.h"
18+#include "Greeter.h"
19+
20+DBusGreeterList::DBusGreeterList(Greeter *greeter)
21+ : QObject(greeter),
22+ m_greeter(greeter)
23+{
24+ connect(m_greeter, SIGNAL(authenticationUserChanged(const QString &)), this, SIGNAL(EntrySelected(const QString &)));
25+ connect(m_greeter, SIGNAL(promptlessChanged()), this, SIGNAL(entryIsLockedChanged()));
26+}
27+
28+QString DBusGreeterList::GetActiveEntry() const
29+{
30+ return m_greeter->authenticationUser();
31+}
32+
33+void DBusGreeterList::SetActiveEntry(const QString &entry)
34+{
35+ Q_EMIT m_greeter->requestAuthenticationUser(entry);
36+}
37+
38+bool DBusGreeterList::entryIsLocked() const
39+{
40+ return !m_greeter->promptless();
41+}
plugins/LightDM/DBusGreeterList.hnew file+53
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright (C) 2013 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+#ifndef UNITY_DBUSLIST_H
18+#define UNITY_DBUSLIST_H
19+
20+#include <QObject>
21+
22+class Greeter;
23+class QDBusInterface;
24+
25+/** This is an internal class used to talk with the indicators.
26+ */
27+
28+class DBusGreeterList : public QObject
29+{
30+ Q_OBJECT
31+ Q_CLASSINFO("D-Bus Interface", "com.canonical.UnityGreeter.List")
32+
33+ Q_PROPERTY(QString ActiveEntry READ GetActiveEntry WRITE SetActiveEntry NOTIFY EntrySelected) // since 14.04
34+ Q_PROPERTY(bool EntryIsLocked READ entryIsLocked NOTIFY entryIsLockedChanged) // since 14.04
35+
36+public:
37+ explicit DBusGreeterList(Greeter *greeter);
38+
39+ Q_SCRIPTABLE void SetActiveEntry(const QString &entry); // since 13.04
40+ Q_SCRIPTABLE QString GetActiveEntry() const; // since 13.10
41+
42+ bool entryIsLocked() const;
43+
44+Q_SIGNALS:
45+ Q_SCRIPTABLE void EntrySelected(const QString &entry); // since 13.10
46+
47+ void entryIsLockedChanged();
48+
49+private:
50+ Greeter *m_greeter;
51+};
52+
53+#endif
plugins/LightDM/Greeter.cpp+1
@@ -88,6 +88,7 @@ void Greeter::authenticate(const QString &username)
88 }
88 }
89
89
90 d->m_greeter->authenticate(username);
90 d->m_greeter->authenticate(username);
91+ Q_EMIT authenticationUserChanged(username);
91}
92}
92
93
93void Greeter::respond(const QString &response)
94void Greeter::respond(const QString &response)
plugins/LightDM/Greeter.h+6−1
@@ -35,7 +35,7 @@ class Greeter : public QObject
35 Q_OBJECT
35 Q_OBJECT
36
36
37 Q_PROPERTY(bool authenticated READ isAuthenticated)
37 Q_PROPERTY(bool authenticated READ isAuthenticated)
38− Q_PROPERTY(QString authenticationUser READ authenticationUser)
38+ Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
39 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
39 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
40
40
41public:
41public:
@@ -54,8 +54,13 @@ Q_SIGNALS:
54 void showMessage(const QString &text, bool isError);
54 void showMessage(const QString &text, bool isError);
55 void showPrompt(const QString &text, bool isSecret);
55 void showPrompt(const QString &text, bool isSecret);
56 void authenticationComplete();
56 void authenticationComplete();
57+ void authenticationUserChanged(const QString &user);
57 void promptlessChanged();
58 void promptlessChanged();
58
59
60+ // This signal is emitted by external agents like indicators, and the UI
61+ // should switch to this user if possible.
62+ void requestAuthenticationUser(const QString &user);
63+
59private:
64private:
60 GreeterPrivate * const d_ptr;
65 GreeterPrivate * const d_ptr;
61
66
plugins/LightDM/plugin.cpp+14−3
@@ -18,20 +18,31 @@
18 */
18 */
19
19
20#include "plugin.h"
20#include "plugin.h"
21+#include "DBusGreeterList.h"
21#include "Greeter.h"
22#include "Greeter.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>
25#include <QLightDM/UsersModel>
26#include <QLightDM/UsersModel>
26
27
27−#include <QtCore/QAbstractItemModel>
28+#include <QAbstractItemModel>
28−#include <QtQml/qqml.h>
29+#include <QDBusConnection>
30+#include <QtQml>
31+
32+static const char* GREETER_LIST_DBUS_PATH = "/list";
33+static const char* GREETER_DBUS_SERVICE = "com.canonical.UnityGreeter";
29
34
30static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
35static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
31{
36{
32 Q_UNUSED(engine)
37 Q_UNUSED(engine)
33 Q_UNUSED(scriptEngine)
38 Q_UNUSED(scriptEngine)
39+
40+ Greeter *greeter = new Greeter();
41+ DBusGreeterList *list = new DBusGreeterList(greeter);
42+ QDBusConnection::sessionBus().registerObject(GREETER_LIST_DBUS_PATH, list, QDBusConnection::ExportScriptableContents);
43+ QDBusConnection::sessionBus().registerService(GREETER_DBUS_SERVICE);
44+
34− return new Greeter();
45+ return greeter;
35}
46}
36
47
37static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
48static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
tests/mocks/LightDM/CMakeLists.txt+2−1
@@ -17,6 +17,7 @@ include_directories(
17)
17)
18
18
19set(QMLPLUGIN_SRC
19set(QMLPLUGIN_SRC
20+ ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeterList.cpp
20 ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/LightDM/plugin.cpp
22 ${CMAKE_SOURCE_DIR}/plugins/LightDM/plugin.cpp
22 ${CMAKE_SOURCE_DIR}/plugins/LightDM/UsersModel.cpp
23 ${CMAKE_SOURCE_DIR}/plugins/LightDM/UsersModel.cpp
@@ -39,7 +40,7 @@ target_link_libraries(MockLightDM-qml
39 -lusermetricsoutput
40 -lusermetricsoutput
40 )
41 )
41
42
42−qt5_use_modules(MockLightDM-qml Gui Qml)
43+qt5_use_modules(MockLightDM-qml DBus Gui Qml)
43
44
44# copy qmldir file into build directory for shadow builds
45# copy qmldir file into build directory for shadow builds
45file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
46file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
tests/plugins/CMakeLists.txt+1
@@ -1,4 +1,5 @@
1add_subdirectory(AccountsService)
1add_subdirectory(AccountsService)
2+add_subdirectory(LightDM)
2add_subdirectory(ListViewWithPageHeader)
3add_subdirectory(ListViewWithPageHeader)
3add_subdirectory(Ubuntu)
4add_subdirectory(Ubuntu)
4add_subdirectory(Unity)
5add_subdirectory(Unity)
tests/plugins/LightDM/CMakeLists.txtnew file+22
@@ -0,0 +1,22 @@
1+add_executable(testLightDMDBus
2+ dbus.cpp
3+ ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
4+ )
5+qt5_use_modules(testLightDMDBus Core DBus Quick Test)
6+
7+include_directories(
8+ ${CMAKE_CURRENT_BINARY_DIR}
9+ ${CMAKE_SOURCE_DIR}/plugins/LightDM
10+ ${LIBLIGHTDM_INCLUDE_DIRS}
11+ )
12+
13+target_link_libraries(testLightDMDBus
14+ -L${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full
15+ -llightdm-qt5-2
16+ )
17+
18+add_definitions(-DCURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
19+
20+add_test(NAME testLightDMDBus
21+ COMMAND dbus-launch env QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/tests/mocks LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full ${CMAKE_CURRENT_BINARY_DIR}/testLightDMDBus
22+ )
tests/plugins/LightDM/dbus.cppnew file+120
@@ -0,0 +1,120 @@
1+/*
2+ * Copyright (C) 2013 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 "Greeter.h"
18+
19+#include <QDBusInterface>
20+#include <QDBusReply>
21+#include <QSignalSpy>
22+#include <QQuickItem>
23+#include <QQuickView>
24+#include <QtTestGui>
25+
26+class GreeterDBusTest : public QObject
27+{
28+ Q_OBJECT
29+
30+private Q_SLOTS:
31+
32+ void init()
33+ {
34+ view = new QQuickView();
35+ view->setSource(QUrl::fromLocalFile(CURRENT_SOURCE_DIR "/greeter.qml"));
36+ greeter = dynamic_cast<Greeter*>(view->rootObject()->property("greeter").value<QObject*>());
37+ QVERIFY(greeter);
38+ QVERIFY(greeter->authenticationUser() == "");
39+ view->show();
40+ QTest::qWaitForWindowExposed(view);
41+
42+ dbusList = new QDBusInterface("com.canonical.UnityGreeter",
43+ "/list",
44+ "com.canonical.UnityGreeter.List",
45+ QDBusConnection::sessionBus(), view);
46+ QVERIFY(dbusList->isValid());
47+ }
48+
49+ void cleanup()
50+ {
51+ delete view;
52+ }
53+
54+ void testGetActiveEntry()
55+ {
56+ greeter->authenticate("has-password");
57+
58+ QDBusReply<QString> reply = dbusList->call("GetActiveEntry");
59+ QVERIFY(reply.isValid());
60+ QVERIFY(reply.value() == "has-password");
61+ }
62+
63+ void testSetActiveEntry()
64+ {
65+ QSignalSpy spy(greeter, SIGNAL(requestAuthenticationUser(QString)));
66+ QDBusReply<void> reply = dbusList->call("SetActiveEntry", "has-password");
67+ QVERIFY(reply.isValid());
68+ spy.wait();
69+
70+ QCOMPARE(spy.count(), 1);
71+ QList<QVariant> arguments = spy.takeFirst();
72+ QVERIFY(arguments.at(0).toString() == "has-password");
73+ }
74+
75+ void testEntrySelectedSignal()
76+ {
77+ QSignalSpy spy(dbusList, SIGNAL(EntrySelected(QString)));
78+ greeter->authenticate("has-password");
79+ spy.wait();
80+
81+ QCOMPARE(spy.count(), 1);
82+ QList<QVariant> arguments = spy.takeFirst();
83+ QVERIFY(arguments.at(0).toString() == "has-password");
84+ }
85+
86+ void testActiveEntryGet()
87+ {
88+ greeter->authenticate("has-password");
89+ QVERIFY(dbusList->property("ActiveEntry").toString() == "has-password");
90+ }
91+
92+ void testActiveEntrySet()
93+ {
94+ QSignalSpy spy(greeter, SIGNAL(requestAuthenticationUser(QString)));
95+ QVERIFY(dbusList->setProperty("ActiveEntry", "has-password"));
96+ spy.wait();
97+
98+ QCOMPARE(spy.count(), 1);
99+ QList<QVariant> arguments = spy.takeFirst();
100+ QVERIFY(arguments.at(0).toString() == "has-password");
101+ }
102+
103+ void testEntryIsLockedGet()
104+ {
105+ greeter->authenticate("has-password");
106+ QVERIFY(dbusList->property("EntryIsLocked").toBool());
107+
108+ greeter->authenticate("no-password");
109+ QVERIFY(!dbusList->property("EntryIsLocked").toBool());
110+ }
111+
112+private:
113+ QQuickView *view;
114+ Greeter *greeter;
115+ QDBusInterface *dbusList;
116+};
117+
118+QTEST_MAIN(GreeterDBusTest)
119+
120+#include "dbus.moc"
tests/plugins/LightDM/greeter.qmlnew file+22
@@ -0,0 +1,22 @@
1+/*
2+ * Copyright 2013 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+import QtQuick 2.0
18+import LightDM 0.1 as LightDM
19+
20+Item {
21+ property var greeter: LightDM.Greeter
22+}
tests/qmltests/Greeter/tst_Tablet.qml+11
@@ -324,5 +324,16 @@ Item {
324 tryCompare(greeter, "rightTeaserPressed", false)
324 tryCompare(greeter, "rightTeaserPressed", false)
325 }
325 }
326
326
327+ function test_dbus_set_active_entry() {
328+ select_user("no-password") // to guarantee a selected signal
329+ selectionSpy.clear()
330+ LightDM.Greeter.requestAuthenticationUser("has-password")
331+
332+ selectionSpy.wait()
333+ tryCompare(selectionSpy, "count", 1)
334+
335+ var userlist = findChild(greeter, "userList")
336+ compare(greeter.model.data(userlist.currentIndex, LightDM.UserRoles.NameRole), "has-password")
337+ }
327 }
338 }
328}
339}