on xenial help sign in
Merge from trunk
commit36a7f2950ad126a64ca105e387b7415e90e0caa2 authorMichael Terry <michael.terry@canonical.com> dateThu 5 Dec 2013, 09:00 (13 years ago) parent965723a5846fb5
21 files changed+402−22
Dash/graphics/phone/screenshots/angrybirds@12.png Greeter/LoginList.qml+11 Hud/SliderLabel.qml+4−2 debian/control+1−1 graphics/applicationIcons/angrybirds@18.png graphics/applicationIcons/media-player@18.png graphics/applicationIcons/music@18.png graphics/applicationIcons/ski_safari@18.png graphics/applicationIcons/skype@18.png plugins/HudClient/hudclient.cpp+1−16 plugins/LightDM/CMakeLists.txt+1 plugins/LightDM/DBusGreeterList.cpp+77 plugins/LightDM/DBusGreeterList.h+61 plugins/LightDM/Greeter.cpp+1 plugins/LightDM/Greeter.h+6−1 plugins/LightDM/plugin.cpp+14−2 tests/plugins/CMakeLists.txt+1 tests/plugins/LightDM/CMakeLists.txt+25 tests/plugins/LightDM/dbus.cpp+166 tests/plugins/LightDM/greeter.qml+22 tests/qmltests/Greeter/tst_Tablet.qml+11
Dash/graphics/phone/screenshots/angrybirds@12.pngdeleted

Binary file not shown.

Greeter/LoginList.qml+11
@@ -289,5 +289,16 @@ Item {
289289 }
290290 passwordInput.text = "";
291291 }
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+ }
292303 }
293304}
Hud/SliderLabel.qml+4−2
@@ -36,10 +36,12 @@ Item {
3636 label.text = sliderData["label"]
3737 slider.minimumValue = sliderData["min"]
3838 slider.maximumValue = sliderData["max"]
39− slider.live = sliderData["live"]
39+ if("live" in sliderData)
40+ slider.live = sliderData["live"]
4041 // SDK Slider does not support step yet
4142// slider.step = sliderData["step"]
42− slider.value = sliderData["value"]
43+ if("value" in sliderData)
44+ slider.value = sliderData["value"]
4345 action = sliderData["action"]
4446 }
4547
debian/control+1−1
@@ -17,7 +17,7 @@ Build-Depends: cmake,
1717 liblightdm-qt5-3-dev,
1818 libpulse-dev,
1919 libqmenumodel-dev (>= 0.2.7),
20− libqt5v8-5-private-dev,
20+ qtdeclarative5-dev (>= 5.2~) | libqt5v8-5-private-dev,
2121 libunity-api-dev (>= 7.80.4),
2222 libunity-mir-dev,
2323 libunity-scopes-json-def-phone,
graphics/applicationIcons/angrybirds@18.pngdeleted

Binary file not shown.

graphics/applicationIcons/media-player@18.pngdeleted

Binary file not shown.

graphics/applicationIcons/music@18.pngdeleted

Binary file not shown.

graphics/applicationIcons/ski_safari@18.pngdeleted

Binary file not shown.

graphics/applicationIcons/skype@18.pngdeleted

Binary file not shown.

plugins/HudClient/hudclient.cpp+1−16
@@ -243,28 +243,13 @@ void HudClient::modelReady(bool needDisconnect)
243243 }
244244}
245245
246−static QVariant QVariantFromGVariant(GVariant *value)
247−{
248− // Only handle the cases we care for now
249− switch (g_variant_classify(value)) {
250− case G_VARIANT_CLASS_BOOLEAN:
251− return QVariant((bool) g_variant_get_boolean(value));
252− case G_VARIANT_CLASS_DOUBLE:
253− return QVariant(g_variant_get_double(value));
254− case G_VARIANT_CLASS_STRING:
255− return QVariant(QString::fromUtf8(g_variant_get_string(value, NULL)));
256− default:
257− return QVariant();
258− }
259−}
260−
261246static void addAttribute(QVariantMap &properties, GMenuModel *menuModel, int item, const char *attribute) {
262247 GVariant *v = g_menu_model_get_item_attribute_value(menuModel, item, attribute, NULL);
263248
264249 if (v == NULL)
265250 return;
266251
267− properties.insert(attribute, QVariantFromGVariant(v));
252+ properties.insert(attribute, DeeListModel::VariantForData(v));
268253 g_variant_unref(v);
269254}
270255
plugins/LightDM/CMakeLists.txt+1
@@ -15,6 +15,7 @@ include_directories(
1515
1616set(QMLPLUGIN_SRC
1717 ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
18+ DBusGreeterList.cpp
1819 Greeter.cpp
1920 plugin.cpp
2021 URLDispatcher.cpp
plugins/LightDM/DBusGreeterList.cppnew file+77
@@ -0,0 +1,77 @@
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+#include <QDBusMessage>
21+#include <QStringList>
22+
23+DBusGreeterList::DBusGreeterList(Greeter *greeter, const QDBusConnection &connection, const QString &path)
24+ : QObject(greeter),
25+ m_greeter(greeter),
26+ m_connection(connection),
27+ m_path(path)
28+{
29+ connect(m_greeter, SIGNAL(authenticationUserChanged(const QString &)), this, SLOT(authenticationUserChangedHandler(const QString &)));
30+ connect(m_greeter, SIGNAL(promptlessChanged()), this, SLOT(promptlessChangedHandler()));
31+}
32+
33+QString DBusGreeterList::GetActiveEntry() const
34+{
35+ return m_greeter->authenticationUser();
36+}
37+
38+void DBusGreeterList::SetActiveEntry(const QString &entry)
39+{
40+ Q_EMIT m_greeter->requestAuthenticationUser(entry);
41+}
42+
43+bool DBusGreeterList::entryIsLocked() const
44+{
45+ return !m_greeter->promptless();
46+}
47+
48+void DBusGreeterList::authenticationUserChangedHandler(const QString &user)
49+{
50+ notifyPropertyChanged("ActiveEntry", user);
51+ Q_EMIT EntrySelected(user);
52+}
53+
54+void DBusGreeterList::promptlessChangedHandler()
55+{
56+ notifyPropertyChanged("EntryIsLocked", entryIsLocked());
57+ Q_EMIT entryIsLockedChanged();
58+}
59+
60+// Manually emit a PropertiesChanged signal over DBus, because QtDBus
61+// doesn't do it for us on Q_PROPERTIES, oddly enough.
62+void DBusGreeterList::notifyPropertyChanged(const QString& propertyName, const QVariant &value)
63+{
64+ QDBusMessage message;
65+ QVariantMap changedProps;
66+
67+ changedProps.insert(propertyName, value);
68+
69+ message = QDBusMessage::createSignal(m_path,
70+ "org.freedesktop.DBus.Properties",
71+ "PropertiesChanged");
72+ message << "com.canonical.UnityGreeter.List";
73+ message << changedProps;
74+ message << QStringList();
75+
76+ m_connection.send(message);
77+}
plugins/LightDM/DBusGreeterList.hnew file+61
@@ -0,0 +1,61 @@
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_DBUSGREETERLIST_H
18+#define UNITY_DBUSGREETERLIST_H
19+
20+#include <QDBusConnection>
21+#include <QObject>
22+
23+class Greeter;
24+class QDBusInterface;
25+
26+/** This is an internal class used to talk with the indicators.
27+ */
28+
29+class DBusGreeterList : public QObject
30+{
31+ Q_OBJECT
32+ Q_CLASSINFO("D-Bus Interface", "com.canonical.UnityGreeter.List")
33+
34+ Q_PROPERTY(QString ActiveEntry READ GetActiveEntry WRITE SetActiveEntry NOTIFY EntrySelected) // since 14.04
35+ Q_PROPERTY(bool EntryIsLocked READ entryIsLocked NOTIFY entryIsLockedChanged) // since 14.04
36+
37+public:
38+ explicit DBusGreeterList(Greeter *greeter, const QDBusConnection &connection, const QString &path);
39+
40+ Q_SCRIPTABLE void SetActiveEntry(const QString &entry); // since 13.04
41+ Q_SCRIPTABLE QString GetActiveEntry() const; // since 13.10
42+
43+ bool entryIsLocked() const;
44+
45+Q_SIGNALS:
46+ Q_SCRIPTABLE void EntrySelected(const QString &entry); // since 13.10
47+
48+ void entryIsLockedChanged();
49+
50+private Q_SLOTS:
51+ void authenticationUserChangedHandler(const QString &user);
52+ void promptlessChangedHandler();
53+ void notifyPropertyChanged(const QString &propertyName, const QVariant &value);
54+
55+private:
56+ Greeter *m_greeter;
57+ QDBusConnection m_connection;
58+ QString m_path;
59+};
60+
61+#endif
plugins/LightDM/Greeter.cpp+1
@@ -88,6 +88,7 @@ void Greeter::authenticate(const QString &username)
8888 }
8989
9090 d->m_greeter->authenticate(username);
91+ Q_EMIT authenticationUserChanged(username);
9192}
9293
9394void Greeter::respond(const QString &response)
plugins/LightDM/Greeter.h+6−1
@@ -35,7 +35,7 @@ class Greeter : public QObject
3535 Q_OBJECT
3636
3737 Q_PROPERTY(bool authenticated READ isAuthenticated)
38− Q_PROPERTY(QString authenticationUser READ authenticationUser)
38+ Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
3939 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
4040
4141public:
@@ -54,8 +54,13 @@ Q_SIGNALS:
5454 void showMessage(const QString &text, bool isError);
5555 void showPrompt(const QString &text, bool isSecret);
5656 void authenticationComplete();
57+ void authenticationUserChanged(const QString &user);
5758 void promptlessChanged();
5859
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+
5964private:
6065 GreeterPrivate * const d_ptr;
6166
plugins/LightDM/plugin.cpp+14−2
@@ -18,6 +18,7 @@
1818 */
1919
2020#include "plugin.h"
21+#include "DBusGreeterList.h"
2122#include "Greeter.h"
2223#include "URLDispatcher.h"
2324#include "UsersModel.h"
@@ -25,14 +26,25 @@
2526#include <libusermetricsoutput/UserMetrics.h>
2627#include <QLightDM/UsersModel>
2728
28−#include <QtCore/QAbstractItemModel>
29+#include <QAbstractItemModel>
30+#include <QDBusConnection>
2931#include <QtQml/qqml.h>
3032
33+static const char* GREETER_LIST_DBUS_PATH = "/list";
34+static const char* GREETER_DBUS_SERVICE = "com.canonical.UnityGreeter";
35+
3136static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
3237{
3338 Q_UNUSED(engine)
3439 Q_UNUSED(scriptEngine)
35− return new Greeter();
40+
41+ Greeter *greeter = new Greeter();
42+ QDBusConnection connection = QDBusConnection::sessionBus();
43+ DBusGreeterList *list = new DBusGreeterList(greeter, connection, GREETER_LIST_DBUS_PATH);
44+ connection.registerObject(GREETER_LIST_DBUS_PATH, list, QDBusConnection::ExportScriptableContents);
45+ connection.registerService(GREETER_DBUS_SERVICE);
46+
47+ return greeter;
3648}
3749
3850static QObject *dispatcher_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
tests/plugins/CMakeLists.txt+1
@@ -1,4 +1,5 @@
11add_subdirectory(AccountsService)
2+add_subdirectory(LightDM)
23add_subdirectory(ListViewWithPageHeader)
34add_subdirectory(SessionManager)
45add_subdirectory(Ubuntu)
tests/plugins/LightDM/CMakeLists.txtnew file+25
@@ -0,0 +1,25 @@
1+include(FindPkgConfig)
2+pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-3)
3+
4+add_executable(test-lightdm-dbus
5+ dbus.cpp
6+ ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
7+ )
8+qt5_use_modules(test-lightdm-dbus Core DBus Quick Test)
9+
10+include_directories(
11+ ${CMAKE_CURRENT_BINARY_DIR}
12+ ${CMAKE_SOURCE_DIR}/plugins/LightDM
13+ ${LIBLIGHTDM_INCLUDE_DIRS}
14+ )
15+
16+target_link_libraries(test-lightdm-dbus
17+ ${LIBLIGHTDM_LDFLAGS}
18+ )
19+
20+add_definitions(-DCURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
21+
22+add_custom_target(testLightDMDBus dbus-launch env QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/plugins LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/liblightdm/full ${CMAKE_CURRENT_BINARY_DIR}/test-lightdm-dbus)
23+add_dependencies(testLightDMDBus test-lightdm-dbus)
24+
25+add_dependencies(qmluitests testLightDMDBus)
tests/plugins/LightDM/dbus.cppnew file+166
@@ -0,0 +1,166 @@
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+Q_SIGNALS:
31+ void PropertiesChangedRelay(const QString &interface, const QVariantMap &changed, const QStringList &invalidated);
32+
33+private Q_SLOTS:
34+
35+ void initTestCase()
36+ {
37+ // Qt doesn't like us connecting to PropertiesChanged using normal
38+ // SIGNAL method, because QtDBus doesn't know about PropertiesChanged.
39+ // So we connect the hard way for the benefit of any tests that want
40+ // to watch.
41+ QDBusConnection::sessionBus().connect(
42+ "com.canonical.UnityGreeter",
43+ "/list",
44+ "org.freedesktop.DBus.Properties",
45+ "PropertiesChanged",
46+ this,
47+ SIGNAL(PropertiesChangedRelay(const QString&, const QVariantMap&, const QStringList&)));
48+ }
49+
50+ void init()
51+ {
52+ view = new QQuickView();
53+ view->setSource(QUrl::fromLocalFile(CURRENT_SOURCE_DIR "/greeter.qml"));
54+ greeter = dynamic_cast<Greeter*>(view->rootObject()->property("greeter").value<QObject*>());
55+ QVERIFY(greeter);
56+ QVERIFY(greeter->authenticationUser() == "");
57+ view->show();
58+ QTest::qWaitForWindowExposed(view);
59+
60+ dbusList = new QDBusInterface("com.canonical.UnityGreeter",
61+ "/list",
62+ "com.canonical.UnityGreeter.List",
63+ QDBusConnection::sessionBus(), view);
64+ QVERIFY(dbusList->isValid());
65+ }
66+
67+ void cleanup()
68+ {
69+ delete view;
70+ }
71+
72+ void testGetActiveEntry()
73+ {
74+ greeter->authenticate("has-password");
75+
76+ QDBusReply<QString> reply = dbusList->call("GetActiveEntry");
77+ QVERIFY(reply.isValid());
78+ QVERIFY(reply.value() == "has-password");
79+ }
80+
81+ void testSetActiveEntry()
82+ {
83+ QSignalSpy spy(greeter, SIGNAL(requestAuthenticationUser(QString)));
84+ QDBusReply<void> reply = dbusList->call("SetActiveEntry", "has-password");
85+ QVERIFY(reply.isValid());
86+ spy.wait();
87+
88+ QCOMPARE(spy.count(), 1);
89+ QList<QVariant> arguments = spy.takeFirst();
90+ QVERIFY(arguments.at(0).toString() == "has-password");
91+ }
92+
93+ void testEntrySelectedSignal()
94+ {
95+ QSignalSpy spy(dbusList, SIGNAL(EntrySelected(QString)));
96+ greeter->authenticate("has-password");
97+ spy.wait();
98+
99+ QCOMPARE(spy.count(), 1);
100+ QList<QVariant> arguments = spy.takeFirst();
101+ QVERIFY(arguments.at(0).toString() == "has-password");
102+ }
103+
104+ void testActiveEntryGet()
105+ {
106+ greeter->authenticate("has-password");
107+ QVERIFY(dbusList->property("ActiveEntry").toString() == "has-password");
108+ }
109+
110+ void testActiveEntrySet()
111+ {
112+ QSignalSpy spy(greeter, SIGNAL(requestAuthenticationUser(QString)));
113+ QVERIFY(dbusList->setProperty("ActiveEntry", "has-password"));
114+ spy.wait();
115+
116+ QCOMPARE(spy.count(), 1);
117+ QList<QVariant> arguments = spy.takeFirst();
118+ QVERIFY(arguments.at(0).toString() == "has-password");
119+ }
120+
121+ void testActiveEntryChanged()
122+ {
123+ QSignalSpy spy(this, SIGNAL(PropertiesChangedRelay(QString, QVariantMap, QStringList)));
124+ greeter->authenticate("has-password");
125+ spy.wait();
126+
127+ QCOMPARE(spy.count(), 1);
128+ QList<QVariant> arguments = spy.takeFirst();
129+ QVERIFY(arguments.at(0).toString() == "com.canonical.UnityGreeter.List");
130+ QVERIFY(arguments.at(1).toMap().contains("ActiveEntry"));
131+ QVERIFY(arguments.at(1).toMap()["ActiveEntry"] == "has-password");
132+ }
133+
134+ void testEntryIsLockedGet()
135+ {
136+ QVERIFY(dbusList->property("EntryIsLocked").toBool());
137+
138+ greeter->authenticate("no-password");
139+ QVERIFY(!dbusList->property("EntryIsLocked").toBool());
140+
141+ greeter->authenticate("has-password");
142+ QVERIFY(dbusList->property("EntryIsLocked").toBool());
143+ }
144+
145+ void testEntryIsLockedChanged()
146+ {
147+ QSignalSpy spy(this, SIGNAL(PropertiesChangedRelay(QString, QVariantMap, QStringList)));
148+ greeter->authenticate("no-password");
149+ spy.wait();
150+
151+ QCOMPARE(spy.count(), 2); // once for locked, once for user; first will be locked mode
152+ QList<QVariant> arguments = spy.takeFirst();
153+ QVERIFY(arguments.at(0).toString() == "com.canonical.UnityGreeter.List");
154+ QVERIFY(arguments.at(1).toMap().contains("EntryIsLocked"));
155+ QVERIFY(arguments.at(1).toMap()["EntryIsLocked"] == false);
156+ }
157+
158+private:
159+ QQuickView *view;
160+ Greeter *greeter;
161+ QDBusInterface *dbusList;
162+};
163+
164+QTEST_MAIN(GreeterDBusTest)
165+
166+#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 {
324324 tryCompare(greeter, "rightTeaserPressed", false)
325325 }
326326
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+ }
327338 }
328339}