on xenial help sign in
Make sure that our greeter lockout screen knows that time passes even when suspended
commita67e41cb3300ec1c61baa75cc2db6ce4b7df0e4d authorMichael Terry <michael.terry@canonical.com> dateMon 2 Mar 2015, 16:24 (12 years ago) parent45c4ba4
2 files changed+45−12
qml/Greeter/Greeter.qml+30−12 tests/qmltests/Greeter/tst_Greeter.qml+15
qml/Greeter/Greeter.qml+30−12
@@ -51,7 +51,7 @@ Showable {
5151
5252 property int maxFailedLogins: -1 // disabled by default for now, will enable via settings in future
5353 property int failedLoginsDelayAttempts: 7 // number of failed logins
54− property int failedLoginsDelayMinutes: 5 // minutes of forced waiting
54+ property real failedLoginsDelayMinutes: 5 // minutes of forced waiting
5555
5656 signal tease()
5757 signal sessionStarted()
@@ -110,7 +110,6 @@ Showable {
110110
111111 readonly property bool multiUser: LightDM.Users.count > 1
112112 property int currentIndex
113− property int delayMinutes
114113 property bool waiting
115114
116115 // We want 'launcherOffset' to animate down to zero. But not to animate
@@ -185,13 +184,31 @@ Showable {
185184
186185 Timer {
187186 id: forcedDelayTimer
188− interval: 1000 * 60
187+
188+ // We use a short interval and check against the system wall clock
189+ // because we have to consider the case that the system is suspended
190+ // for a few minutes. When we wake up, we want to quickly be correct.
191+ interval: 500
192+
193+ property var delayTarget;
194+ property int delayMinutes;
195+
196+ onDelayMinutesChanged: console.log("MIKE delayMinutes", delayMinutes);
197+
198+ function forceDelay(delay /* in minutes */) {
199+ delayTarget = new Date();
200+ delayTarget.setTime(delayTarget.getTime() + delay * 60000);
201+ delayMinutes = Math.ceil(delay);
202+ start();
203+ }
204+
189205 onTriggered: {
190− if (d.delayMinutes > 0) {
191− d.delayMinutes -= 1;
192− if (d.delayMinutes > 0) {
193− start(); // go again
194− }
206+ var diff = delayTarget - new Date();
207+ if (diff > 0) {
208+ delayMinutes = Math.ceil(diff / 60000);
209+ start(); // go again
210+ } else {
211+ delayMinutes = 0;
195212 }
196213 }
197214 }
@@ -262,7 +279,7 @@ Showable {
262279 Binding {
263280 target: loader.item
264281 property: "delayMinutes"
265− value: d.delayMinutes
282+ value: forcedDelayTimer.delayMinutes
266283 }
267284
268285 Binding {
@@ -363,9 +380,10 @@ Showable {
363380 }
364381
365382 // Check if we should initiate a forced login delay
366− if (failedLoginsDelayAttempts > 0 && AccountsService.failedLogins % failedLoginsDelayAttempts == 0) {
367− d.delayMinutes = failedLoginsDelayMinutes;
368− forcedDelayTimer.start();
383+ if (failedLoginsDelayAttempts > 0
384+ && AccountsService.failedLogins > 0
385+ && AccountsService.failedLogins % failedLoginsDelayAttempts == 0) {
386+ forcedDelayTimer.forceDelay(failedLoginsDelayMinutes);
369387 }
370388
371389 loader.item.notifyAuthenticationFailed();
tests/qmltests/Greeter/tst_Greeter.qml+15
@@ -146,6 +146,8 @@ Item {
146146 tryCompare(greeter, "waiting", false);
147147 view = findChild(greeter, "testView");
148148 verifySelected(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
149+ greeter.failedLoginsDelayAttempts = 7;
150+ greeter.failedLoginsDelayMinutes = 5;
149151 }
150152
151153 function cleanup() {
@@ -429,6 +431,19 @@ Item {
429431 compare(LightDM.Infographic.username, "has-password");
430432 }
431433
434+ function test_forcedDelay() {
435+ greeter.failedLoginsDelayAttempts = 1;
436+ greeter.failedLoginsDelayMinutes = 0.1; // make delay very short
437+
438+ selectUser("has-password");
439+ tryCompare(viewShowPromptSpy, "count", 1);
440+
441+ compare(view.delayMinutes, 0);
442+ view.responded("wr0ng p4ssw0rd");
443+ tryCompare(view, "delayMinutes", 1);
444+ tryCompare(view, "delayMinutes", 0);
445+ }
446+
432447 function test_dbusRequestAuthenticationUser() {
433448 selectUser("no-password");
434449 LightDM.Greeter.requestAuthenticationUser("has-password");