on xenial help sign in
merge prereq
7ed41feJosh Arenson
data/51-unity8-greeter.conf−3
@@ -1,5 +1,2 @@
1[Seat:*]
1[Seat:*]
2greeter-session=unity8-greeter
2greeter-session=unity8-greeter
3−
4−# When unity8 can be run under mir on the desktop, change this to unity.
5−type=unity
data/unity8-greeter.desktop.in+1−1
@@ -2,6 +2,6 @@
2Type=Application
2Type=Application
3Name=Unity 8 Greeter
3Name=Unity 8 Greeter
4Comment=The converged Unity shell's Greeter
4Comment=The converged Unity shell's Greeter
5−Exec=/usr/bin/unity8-greeter-wrapper /usr/bin/unity8 --mode=greeter
5+Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8-greeter-wrapper @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8 --mode=greeter
6X-LightDM-Session-Type=mir
6X-LightDM-Session-Type=mir
7X-Ubuntu-Touch=true
7X-Ubuntu-Touch=true
data/unity8-greeter.pklanew file+44
@@ -0,0 +1,44 @@
1+# DO NOT EDIT THIS FILE, it will be overwritten on update
2+# Place your local configurations under /etc/polkit-1/localauthority/
3+
4+[Disable Controlling of Network Devices]
5+Identity=unix-user:lightdm
6+Action=org.freedesktop.NetworkManager.enable-disable-network;org.freedesktop.NetworkManager.enable-disable-wifi;org.freedesktop.NetworkManager.enable-disable-wwan;org.freedesktop.NetworkManager.enable-disable-wimax;
7+ResultActive=no
8+ResultInactive=no
9+ResultsAny=no
10+
11+[Disable Sleep and Wake]
12+Identity=unix-user:lightdm
13+Action=org.freedesktop.NetworkManager.sleep-wake
14+ResultActive=no
15+ResultInactive=no
16+ResultsAny=no
17+
18+[Disable WiFi Sharing]
19+Identity=unix-user:lightdm
20+Action=org.freedesktop.NetworkManager.wifi.share.protected;org.freedesktop.NetworkManager.wifi.share.open
21+ResultActive=no
22+ResultInactive=no
23+ResultsAny=no
24+
25+[Disable Settings Modifications]
26+Identity=unix-user:lightdm
27+Action=org.freedesktop.NetworkManager.settings.modify.own;org.freedesktop.NetworkManager.settings.modify.system;org.freedesktop.NetworkManager.settings.modify.hostname
28+ResultActive=no
29+ResultInactive=no
30+ResultsAny=no
31+
32+[Disable User Connections]
33+Identity=unix-user:lightdm
34+Action=org.freedesktop.NetworkManager.use-user-connections
35+ResultActive=no
36+ResultInactive=no
37+ResultsAny=no
38+
39+[Enable Controlling of Network Connections]
40+Identity=unix-user:lightdm
41+Action=org.freedesktop.NetworkManager.network-control
42+ResultActive=yes
43+ResultInactive=no
44+ResultsAny=no
debian/unity8-greeter.install+1
@@ -1,4 +1,5 @@
1data/unity8-greeter-wrapper usr/bin/
1data/unity8-greeter-wrapper usr/bin/
2data/unity8-greeter-init.conf usr/share/upstart/sessions/
2data/unity8-greeter-init.conf usr/share/upstart/sessions/
3+data/unity8-greeter.pkla /var/lib/polkit-1/localauthority/10-vendor.d/
3usr/share/lightdm/greeters/unity8-greeter.desktop
4usr/share/lightdm/greeters/unity8-greeter.desktop
4usr/share/lightdm/lightdm.conf.d/51-unity8-greeter.conf
5usr/share/lightdm/lightdm.conf.d/51-unity8-greeter.conf
plugins/LightDM/Greeter.cpp+6
@@ -83,6 +83,12 @@ bool Greeter::promptless() const
83 return d->promptless;
83 return d->promptless;
84}
84}
85
85
86+QString Greeter::selectUser() const
87+{
88+ Q_D(const Greeter);
89+ return d->m_greeter->selectUserHint();
90+}
91+
86void Greeter::authenticate(const QString &username)
92void Greeter::authenticate(const QString &username)
87{
93{
88 Q_D(Greeter);
94 Q_D(Greeter);
plugins/LightDM/Greeter.h+2
@@ -38,6 +38,7 @@ class Greeter : public QObject
38 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)
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
42
42public:
43public:
43 explicit Greeter(QObject* parent=0);
44 explicit Greeter(QObject* parent=0);
@@ -47,6 +48,7 @@ public:
47 QString authenticationUser() const;
48 QString authenticationUser() const;
48 QString defaultSessionHint() const;
49 QString defaultSessionHint() const;
49 bool promptless() const;
50 bool promptless() const;
51+ QString selectUser() const;
50
52
51public Q_SLOTS:
53public Q_SLOTS:
52 void authenticate(const QString &username=QString());
54 void authenticate(const QString &username=QString());
plugins/Unity/Indicators/indicatorsmanager.cpp+1−1
@@ -291,7 +291,7 @@ Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
291 // The rest of the indicators respect their default profile (which is "phone", even on desktop PCs)
291 // The rest of the indicators respect their default profile (which is "phone", even on desktop PCs)
292 if ((new_indicator->identifier() == QStringLiteral("indicator-session"))
292 if ((new_indicator->identifier() == QStringLiteral("indicator-session"))
293 || (new_indicator->identifier() == QStringLiteral("indicator-power") && m_platform.isPC())) {
293 || (new_indicator->identifier() == QStringLiteral("indicator-power") && m_platform.isPC())) {
294− new_indicator->setProfile(QStringLiteral("desktop"));
294+ new_indicator->setProfile(m_profile.replace(QStringLiteral("phone"), QStringLiteral("desktop")));
295 } else {
295 } else {
296 new_indicator->setProfile(m_profile);
296 new_indicator->setProfile(m_profile);
297 }
297 }
qml/Greeter/Greeter.qml+19−10
@@ -114,7 +114,8 @@ Showable {
114 id: d
114 id: d
115
115
116 readonly property bool multiUser: LightDMService.users.count > 1
116 readonly property bool multiUser: LightDMService.users.count > 1
117+ readonly property int selectUserIndex: d.getUserIndex(LightDMService.greeter.selectUser)
117− property int currentIndex
118+ property int currentIndex: Math.max(selectUserIndex, 0)
118 property bool waiting
119 property bool waiting
119
120
120 // We want 'launcherOffset' to animate down to zero. But not to animate
121 // We want 'launcherOffset' to animate down to zero. But not to animate
@@ -131,7 +132,23 @@ Showable {
131 UbuntuNumberAnimation {}
132 UbuntuNumberAnimation {}
132 }
133 }
133
134
135+ function getUserIndex(username) {
136+ if (username === "")
137+ return -1;
138+
139+ // Find index for requested user, if it exists
140+ for (var i = 0; i < LightDMService.users.count; i++) {
141+ if (username === LightDMService.users.data(i, LightDMService.userRoles.NameRole)) {
142+ return i;
143+ }
144+ }
145+
146+ return -1;
147+ }
148+
134 function selectUser(uid, reset) {
149 function selectUser(uid, reset) {
150+ if (uid < 0)
151+ return;
135 d.waiting = true;
152 d.waiting = true;
136 if (reset) {
153 if (reset) {
137 loader.item.reset();
154 loader.item.reset();
@@ -440,15 +457,7 @@ Showable {
440 }
457 }
441 }
458 }
442
459
443− onRequestAuthenticationUser: {
460+ onRequestAuthenticationUser: d.selectUser(d.getUserIndex(user), true)
444− // Find index for requested user, if it exists
445− for (var i = 0; i < LightDMService.users.count; i++) {
446− if (user === LightDMService.users.data(i, LightDMService.userRoles.NameRole)) {
447− d.selectUser(i, true);
448− return;
449− }
450− }
451− }
452 }
461 }
453
462
454 Connections {
463 Connections {
qml/Shell.qml+8−3
@@ -259,8 +259,8 @@ StyledItem {
259 ? "phone"
259 ? "phone"
260 : shell.usageScenario
260 : shell.usageScenario
261 readonly property string qmlComponent: {
261 readonly property string qmlComponent: {
262− if(shell.mode === "greeter") {
262+ if (shell.mode === "greeter") {
263− return "Stages/ShimStage.qml"
263+ return "Stages/AbstractStage.qml"
264 } else if (applicationsDisplayLoader.usageScenario === "phone") {
264 } else if (applicationsDisplayLoader.usageScenario === "phone") {
265 return "Stages/PhoneStage.qml";
265 return "Stages/PhoneStage.qml";
266 } else if (applicationsDisplayLoader.usageScenario === "tablet") {
266 } else if (applicationsDisplayLoader.usageScenario === "tablet") {
@@ -531,7 +531,12 @@ StyledItem {
531
531
532 indicatorsModel: Indicators.IndicatorsModel {
532 indicatorsModel: Indicators.IndicatorsModel {
533 // tablet and phone both use the same profile
533 // tablet and phone both use the same profile
534+ // FIXME: use just "phone" for greeter too, but first fix
535+ // greeter app launching to either load the app inside the
536+ // greeter or tell the session to load the app. This will
537+ // involve taking the url-dispatcher dbus name and using
538+ // SessionBroadcast to tell the session.
534− profile: "phone"
539+ profile: shell.mode === "greeter" ? "desktop_greeter" : "phone"
535 Component.onCompleted: load();
540 Component.onCompleted: load();
536 }
541 }
537 }
542 }
qml/Stages/ShimStage.qmldeleted−43
@@ -1,43 +0,0 @@
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−import QtQuick 2.4
18−import Ubuntu.Components 1.3
19−
20−AbstractStage {
21− id: shimStage
22−
23− anchors.fill: parent
24−
25− Text {
26− id: greeterModeText
27−
28− anchors.horizontalCenter: parent.horizontalCenter
29− anchors.top: parent.top
30− anchors.topMargin: units.gu(10)
31− font.bold: true
32− horizontalAlignment: Text.AlignHCenter
33− text: "Shell is in \"greeter\" mode"
34− }
35−
36− Text {
37− anchors.centerIn: parent
38− color: UbuntuColors.orange
39− font.pointSize: units.gu(8)
40− horizontalAlignment: Text.AlignHCenter
41− text: "Shim \nStage"
42− }
43−}
tests/mocks/LightDM/IntegratedLightDM/MockGreeter.cpp+16
@@ -33,3 +33,19 @@ void MockGreeter::setMockMode(QString mockMode)
33 Q_EMIT mockModeChanged(mockMode);
33 Q_EMIT mockModeChanged(mockMode);
34 }
34 }
35}
35}
36+
37+QString MockGreeter::selectUserHint() const
38+{
39+ Q_D(const Greeter);
40+ return d->m_greeter->selectUserHint();
41+}
42+
43+void MockGreeter::setSelectUserHint(const QString &selectUserHint)
44+{
45+ Q_D(Greeter);
46+
47+ if (d->m_greeter->selectUserHint() != selectUserHint) {
48+ d->m_greeter->setSelectUserHint(selectUserHint);
49+ Q_EMIT selectUserHintChanged();
50+ }
51+}
tests/mocks/LightDM/IntegratedLightDM/MockGreeter.h+5
@@ -25,13 +25,18 @@ class MockGreeter : public Greeter {
25 Q_OBJECT
25 Q_OBJECT
26
26
27 Q_PROPERTY(QString mockMode READ mockMode WRITE setMockMode NOTIFY mockModeChanged)
27 Q_PROPERTY(QString mockMode READ mockMode WRITE setMockMode NOTIFY mockModeChanged)
28+ Q_PROPERTY(QString selectUser READ selectUserHint WRITE setSelectUserHint NOTIFY selectUserHintChanged)
28
29
29public:
30public:
30 QString mockMode() const;
31 QString mockMode() const;
31 void setMockMode(QString mockMode);
32 void setMockMode(QString mockMode);
32
33
34+ QString selectUserHint() const;
35+ void setSelectUserHint(const QString &selectUserHint);
36+
33Q_SIGNALS:
37Q_SIGNALS:
34 void mockModeChanged(QString mode);
38 void mockModeChanged(QString mode);
39+ void selectUserHintChanged();
35};
40};
36
41
37#endif // MOCK_UNITY_GREETER_H
42#endif // MOCK_UNITY_GREETER_H
tests/mocks/LightDM/IntegratedLightDM/liblightdm/Greeter.cpp+8−1
@@ -76,7 +76,14 @@ bool Greeter::lockHint () const
76
76
77QString Greeter::selectUserHint() const
77QString Greeter::selectUserHint() const
78{
78{
79+ Q_D(const Greeter);
79− return "";
80+ return d->selectUserHint;
81+}
82+
83+void Greeter::setSelectUserHint(const QString &selectUserHint)
84+{
85+ Q_D(Greeter);
86+ d->selectUserHint = selectUserHint;
80}
87}
81
88
82bool Greeter::selectGuestHint() const
89bool Greeter::selectGuestHint() const
tests/mocks/LightDM/IntegratedLightDM/liblightdm/Greeter.h+1
@@ -70,6 +70,7 @@ public:
70 bool lockHint () const;
70 bool lockHint () const;
71 bool hasGuestAccountHint() const;
71 bool hasGuestAccountHint() const;
72 QString selectUserHint() const;
72 QString selectUserHint() const;
73+ void setSelectUserHint(const QString &selectUserHint); // only in mock
73 bool selectGuestHint() const;
74 bool selectGuestHint() const;
74 QString autologinUserHint() const;
75 QString autologinUserHint() const;
75 bool autologinGuestHint() const;
76 bool autologinGuestHint() const;
tests/mocks/LightDM/IntegratedLightDM/liblightdm/GreeterPrivate.h+1
@@ -34,6 +34,7 @@ public:
34 bool authenticated;
34 bool authenticated;
35 QString authenticationUser;
35 QString authenticationUser;
36 bool twoFactorDone;
36 bool twoFactorDone;
37+ QString selectUserHint;
37
38
38 QString mockMode;
39 QString mockMode;
39
40
tests/qmltests/Greeter/TestView.qml+2
@@ -33,6 +33,7 @@ Item {
33 property var infographicModel
33 property var infographicModel
34 readonly property bool fullyShown: _fullyShown
34 readonly property bool fullyShown: _fullyShown
35 readonly property bool required: _required
35 readonly property bool required: _required
36+ readonly property bool animating: false
36
37
37 property bool _fullyShown: true
38 property bool _fullyShown: true
38 property bool _required: true
39 property bool _required: true
@@ -41,6 +42,7 @@ Item {
41 signal responded(string response)
42 signal responded(string response)
42 signal tease()
43 signal tease()
43 signal emergencyCall()
44 signal emergencyCall()
45+ signal promptlessLogin()
44
46
45 signal _showMessageCalled(string html)
47 signal _showMessageCalled(string html)
46 signal _showPromptCalled(string text, bool isSecret, bool isDefaultPrompt)
48 signal _showPromptCalled(string text, bool isSecret, bool isDefaultPrompt)
tests/qmltests/Greeter/tst_Greeter.qml+27−9
@@ -139,7 +139,9 @@ Item {
139
139
140 function init() {
140 function init() {
141 greeterSettings.lockedOutTime = 0;
141 greeterSettings.lockedOutTime = 0;
142− resetLoader();
142+ LightDM.Greeter.selectUser = "";
143+ greeter.failedLoginsDelayAttempts = 7;
144+ greeter.failedLoginsDelayMinutes = 5;
143 teaseSpy.clear();
145 teaseSpy.clear();
144 sessionStartedSpy.clear();
146 sessionStartedSpy.clear();
145 activeChangedSpy.clear();
147 activeChangedSpy.clear();
@@ -151,11 +153,7 @@ Item {
151 viewAuthenticationFailedSpy.clear();
153 viewAuthenticationFailedSpy.clear();
152 viewResetSpy.clear();
154 viewResetSpy.clear();
153 viewTryToUnlockSpy.clear();
155 viewTryToUnlockSpy.clear();
154− tryCompare(greeter, "waiting", false);
156+ resetLoader();
155− view = findChild(greeter, "testView");
156− verifySelected(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
157− greeter.failedLoginsDelayAttempts = 7;
158− greeter.failedLoginsDelayMinutes = 5;
159 }
157 }
160
158
161 function resetLoader() {
159 function resetLoader() {
@@ -167,6 +165,8 @@ Item {
167 loader.active = true;
165 loader.active = true;
168 tryCompare(loader, "status", Loader.Ready);
166 tryCompare(loader, "status", Loader.Ready);
169 removeTimeConstraintsFromSwipeAreas(loader.item);
167 removeTimeConstraintsFromSwipeAreas(loader.item);
168+ tryCompare(greeter, "waiting", false);
169+ view = findChild(greeter, "testView");
170 }
170 }
171
171
172 function getIndexOf(name) {
172 function getIndexOf(name) {
@@ -191,6 +191,7 @@ Item {
191 compare(view.currentIndex, i);
191 compare(view.currentIndex, i);
192 compare(AccountsService.user, name);
192 compare(AccountsService.user, name);
193 compare(LightDM.Greeter.authenticationUser, name);
193 compare(LightDM.Greeter.authenticationUser, name);
194+ return i;
194 }
195 }
195
196
196 function verifyLoggedIn() {
197 function verifyLoggedIn() {
@@ -229,11 +230,9 @@ Item {
229
230
230 function test_promptless() {
231 function test_promptless() {
231 selectUser("no-password");
232 selectUser("no-password");
232− tryCompare(viewAuthenticationSucceededSpy, "count", 1);
233+ tryCompare(view, "locked", false);
233− compare(sessionStartedSpy.count, 1);
234 compare(viewShowPromptSpy.count, 0);
234 compare(viewShowPromptSpy.count, 0);
235 compare(viewHideSpy.count, 0);
235 compare(viewHideSpy.count, 0);
236− compare(view.locked, false);
237 }
236 }
238
237
239 function test_twoFactorPass() {
238 function test_twoFactorPass() {
@@ -553,5 +552,24 @@ Item {
553 compare(viewResetSpy.count, 1);
552 compare(viewResetSpy.count, 1);
554 tryCompare(viewShowPromptSpy, "count", 1);
553 tryCompare(viewShowPromptSpy, "count", 1);
555 }
554 }
555+
556+ function test_selectUserHint() {
557+ LightDM.Greeter.selectUser = "info-prompt";
558+ resetLoader();
559+ var i = verifySelected("info-prompt");
560+ verify(i != 0); // sanity-check that info-prompt isn't default 0 answer
561+ }
562+
563+ function test_selectUserHintUnset() {
564+ LightDM.Greeter.selectUser = "";
565+ resetLoader();
566+ verifySelected(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
567+ }
568+
569+ function test_selectUserHintInvalid() {
570+ LightDM.Greeter.selectUser = "not-a-real-user";
571+ resetLoader();
572+ verifySelected(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
573+ }
556 }
574 }
557}
575}