on xenial help sign in
Expose a new greeter DBus property, IsActive, which tells apps and indicators when the integrated-greeter screen is active. Useful for switching UI modes when the screen is locked.

Approved by: Michael Zanetti, PS Jenkins bot

commitf5dd6b4baf7e0a56449c686055c3171780096ff3 authorMichael Terry <michael.terry@canonical.com> dateThu 17 Jul 2014, 09:36 (12 years ago) parentc2d4a7ca56c9f8
10 files changed+180−1
plugins/LightDM/CMakeLists.txt+1 plugins/LightDM/DBusGreeter.cpp+60 plugins/LightDM/DBusGreeter.h+54 plugins/LightDM/Greeter.cpp+17 plugins/LightDM/Greeter.h+4 plugins/LightDM/plugin.cpp+3 qml/Shell.qml+6 tests/mocks/LightDM/CMakeLists.txt+1 tests/plugins/LightDM/CMakeLists.txt+1−1 tests/plugins/LightDM/dbus.cpp+33
plugins/LightDM/CMakeLists.txt+1
@@ -15,6 +15,7 @@ include_directories(
1515
1616set(QMLPLUGIN_SRC
1717 ../Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
18+ DBusGreeter.cpp
1819 DBusGreeterList.cpp
1920 Greeter.cpp
2021 plugin.cpp
plugins/LightDM/DBusGreeter.cppnew file+60
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright (C) 2014 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 "DBusGreeter.h"
18+#include "Greeter.h"
19+
20+#include <QDBusMessage>
21+#include <QStringList>
22+
23+DBusGreeter::DBusGreeter(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(isActiveChanged()), this, SLOT(isActiveChangedHandler()));
30+}
31+
32+bool DBusGreeter::isActive() const
33+{
34+ return m_greeter->isActive();
35+}
36+
37+void DBusGreeter::isActiveChangedHandler()
38+{
39+ notifyPropertyChanged("IsActive", isActive());
40+ Q_EMIT isActiveChanged();
41+}
42+
43+// Manually emit a PropertiesChanged signal over DBus, because QtDBus
44+// doesn't do it for us on Q_PROPERTIES, oddly enough.
45+void DBusGreeter::notifyPropertyChanged(const QString& propertyName, const QVariant &value)
46+{
47+ QDBusMessage message;
48+ QVariantMap changedProps;
49+
50+ changedProps.insert(propertyName, value);
51+
52+ message = QDBusMessage::createSignal(m_path,
53+ "org.freedesktop.DBus.Properties",
54+ "PropertiesChanged");
55+ message << "com.canonical.UnityGreeter";
56+ message << changedProps;
57+ message << QStringList();
58+
59+ m_connection.send(message);
60+}
plugins/LightDM/DBusGreeter.hnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2014 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_DBUSGREETER_H
18+#define UNITY_DBUSGREETER_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 DBusGreeter : public QObject
30+{
31+ Q_OBJECT
32+ Q_CLASSINFO("D-Bus Interface", "com.canonical.UnityGreeter")
33+
34+ Q_PROPERTY(bool IsActive READ isActive NOTIFY isActiveChanged) // since 14.10
35+
36+public:
37+ explicit DBusGreeter(Greeter *greeter, const QDBusConnection &connection, const QString &path);
38+
39+ bool isActive() const;
40+
41+Q_SIGNALS:
42+ void isActiveChanged();
43+
44+private Q_SLOTS:
45+ void isActiveChangedHandler();
46+ void notifyPropertyChanged(const QString &propertyName, const QVariant &value);
47+
48+private:
49+ Greeter *m_greeter;
50+ QDBusConnection m_connection;
51+ QString m_path;
52+};
53+
54+#endif
plugins/LightDM/Greeter.cpp+17
@@ -25,6 +25,7 @@ public:
2525 explicit GreeterPrivate(Greeter *parent);
2626
2727 QLightDM::Greeter *m_greeter;
28+ bool m_active;
2829 bool wasPrompted;
2930 bool promptless;
3031
@@ -38,6 +39,7 @@ private:
3839
3940GreeterPrivate::GreeterPrivate(Greeter* parent)
4041 : m_greeter(new QLightDM::Greeter(parent)),
42+ m_active(false),
4143 wasPrompted(false),
4244 promptless(false),
4345 q_ptr(parent)
@@ -60,6 +62,21 @@ Greeter::Greeter(QObject* parent)
6062 d->m_greeter->connectSync();
6163}
6264
65+bool Greeter::isActive() const
66+{
67+ Q_D(const Greeter);
68+ return d->m_active;
69+}
70+
71+void Greeter::setIsActive(bool active)
72+{
73+ Q_D(Greeter);
74+ if (d->m_active != active) {
75+ d->m_active = active;
76+ Q_EMIT isActiveChanged();
77+ }
78+}
79+
6380bool Greeter::isAuthenticated() const
6481{
6582 Q_D(const Greeter);
plugins/LightDM/Greeter.h+4
@@ -34,6 +34,7 @@ class Greeter : public QObject
3434{
3535 Q_OBJECT
3636
37+ Q_PROPERTY(bool active READ isActive WRITE setIsActive NOTIFY isActiveChanged)
3738 Q_PROPERTY(bool authenticated READ isAuthenticated)
3839 Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
3940 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
@@ -41,6 +42,7 @@ class Greeter : public QObject
4142public:
4243 explicit Greeter(QObject* parent=0);
4344
45+ bool isActive() const;
4446 bool isAuthenticated() const;
4547 QString authenticationUser() const;
4648 bool promptless() const;
@@ -49,12 +51,14 @@ public Q_SLOTS:
4951 void authenticate(const QString &username=QString());
5052 void respond(const QString &response);
5153 bool startSessionSync(const QString &session=QString());
54+ void setIsActive(bool isActive);
5255
5356Q_SIGNALS:
5457 void showMessage(const QString &text, bool isError);
5558 void showPrompt(const QString &text, bool isSecret);
5659 void authenticationComplete();
5760 void authenticationUserChanged(const QString &user);
61+ void isActiveChanged();
5862 void promptlessChanged();
5963
6064 // This signal is emitted by external agents like indicators, and the UI
plugins/LightDM/plugin.cpp+3
@@ -18,6 +18,7 @@
1818 */
1919
2020#include "plugin.h"
21+#include "DBusGreeter.h"
2122#include "DBusGreeterList.h"
2223#include "Greeter.h"
2324#include "UsersModel.h"
@@ -39,6 +40,8 @@ static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
3940
4041 Greeter *greeter = new Greeter();
4142 QDBusConnection connection = QDBusConnection::sessionBus();
43+ DBusGreeter *root = new DBusGreeter(greeter, connection, "/");
44+ connection.registerObject("/", root, QDBusConnection::ExportScriptableContents);
4245 DBusGreeterList *list = new DBusGreeterList(greeter, connection, GREETER_LIST_DBUS_PATH);
4346 connection.registerObject(GREETER_LIST_DBUS_PATH, list, QDBusConnection::ExportScriptableContents);
4447 connection.registerService(GREETER_DBUS_SERVICE);
qml/Shell.qml+6
@@ -373,6 +373,12 @@ FocusScope {
373373 }
374374 }
375375
376+ Binding {
377+ target: LightDM.Greeter
378+ property: "active"
379+ value: greeter.shown || lockscreen.shown
380+ }
381+
376382 Rectangle {
377383 anchors.fill: parent
378384 color: "black"
tests/mocks/LightDM/CMakeLists.txt+1
@@ -18,6 +18,7 @@ include_directories(
1818)
1919
2020set(QMLPLUGIN_SRC
21+ ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeter.cpp
2122 ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeterList.cpp
2223 ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
2324 ${CMAKE_SOURCE_DIR}/plugins/LightDM/plugin.cpp
tests/plugins/LightDM/CMakeLists.txt+1−1
@@ -19,7 +19,7 @@ target_link_libraries(test-lightdm-dbus
1919
2020add_definitions(-DCURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
2121
22−add_custom_target(testLightDMDBus 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}/test-lightdm-dbus)
22+add_custom_target(testLightDMDBus xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum 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}/test-lightdm-dbus)
2323add_dependencies(testLightDMDBus test-lightdm-dbus)
2424
2525add_dependencies(qmluitests testLightDMDBus)
tests/plugins/LightDM/dbus.cpp+33
@@ -38,6 +38,13 @@ private Q_SLOTS:
3838 // SIGNAL method, because QtDBus doesn't know about PropertiesChanged.
3939 // So we connect the hard way for the benefit of any tests that want
4040 // to watch.
41+ QDBusConnection::sessionBus().connect(
42+ "com.canonical.UnityGreeter",
43+ "/",
44+ "org.freedesktop.DBus.Properties",
45+ "PropertiesChanged",
46+ this,
47+ SIGNAL(PropertiesChangedRelay(const QString&, const QVariantMap&, const QStringList&)));
4148 QDBusConnection::sessionBus().connect(
4249 "com.canonical.UnityGreeter",
4350 "/list",
@@ -57,6 +64,12 @@ private Q_SLOTS:
5764 view->show();
5865 QTest::qWaitForWindowExposed(view);
5966
67+ dbusMain = new QDBusInterface("com.canonical.UnityGreeter",
68+ "/",
69+ "com.canonical.UnityGreeter",
70+ QDBusConnection::sessionBus(), view);
71+ QVERIFY(dbusMain->isValid());
72+
6073 dbusList = new QDBusInterface("com.canonical.UnityGreeter",
6174 "/list",
6275 "com.canonical.UnityGreeter.List",
@@ -155,9 +168,29 @@ private Q_SLOTS:
155168 QVERIFY(arguments.at(1).toMap()["EntryIsLocked"] == false);
156169 }
157170
171+ void testIsActive()
172+ {
173+ QVERIFY(!greeter->isActive());
174+ QVERIFY(!dbusMain->property("IsActive").toBool());
175+
176+ QSignalSpy spy(this, SIGNAL(PropertiesChangedRelay(QString, QVariantMap, QStringList)));
177+ greeter->setIsActive(true);
178+ spy.wait();
179+
180+ QVERIFY(greeter->isActive());
181+ QVERIFY(dbusMain->property("IsActive").toBool());
182+
183+ QCOMPARE(spy.count(), 1);
184+ QList<QVariant> arguments = spy.takeFirst();
185+ QCOMPARE(arguments.at(0).toString(), QString("com.canonical.UnityGreeter"));
186+ QVERIFY(arguments.at(1).toMap().contains("IsActive"));
187+ QVERIFY(arguments.at(1).toMap()["IsActive"].toBool());
188+ }
189+
158190private:
159191 QQuickView *view;
160192 Greeter *greeter;
193+ QDBusInterface *dbusMain;
161194 QDBusInterface *dbusList;
162195};
163196