Merge lp:~unity-team/unity/phablet-pinlock into lp:unity/phablet

Proposed by Michael Zanetti
Status: Superseded
Proposed branch: lp:~unity-team/unity/phablet-pinlock
Merge into: lp:unity/phablet
Prerequisite: lp:~mterry/unity/phablet-greeter-single-user
Diff against target: 1433 lines (+1091/-39)
23 files modified
Components/WrongPasswordAnimation.qml (+46/-0)
Greeter/Lockscreen.qml (+149/-0)
Greeter/LoginList.qml (+3/-23)
Greeter/PassphraseLockscreen.qml (+87/-0)
Greeter/PinLockscreen.qml (+111/-0)
Greeter/PinPadButton.qml (+59/-0)
Shell.qml (+46/-8)
plugins/LightDM/CMakeLists.txt (+1/-1)
run (+17/-1)
run_on_device (+19/-5)
tests/mocks/LightDM/CMakeLists.txt (+2/-0)
tests/mocks/LightDM/full/GreeterPrivate.cpp (+7/-1)
tests/mocks/LightDM/full/UsersModelPrivate.cpp (+1/-0)
tests/mocks/LightDM/single-passphrase/CMakeLists.txt (+21/-0)
tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp (+53/-0)
tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp (+61/-0)
tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp (+33/-0)
tests/mocks/LightDM/single-pin/CMakeLists.txt (+21/-0)
tests/mocks/LightDM/single-pin/GreeterPrivate.cpp (+53/-0)
tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp (+61/-0)
tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp (+33/-0)
tests/qmltests/CMakeLists.txt (+2/-0)
tests/qmltests/Greeter/tst_Lockscreen.qml (+205/-0)
To merge this branch: bzr merge lp:~unity-team/unity/phablet-pinlock
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
MichaƂ Sawicz Needs Fixing
Review via email: mp+167115@code.launchpad.net

This proposal supersedes a proposal from 2013-05-27.

This proposal has been superseded by a proposal from 2013-06-06.

Commit message

Add Lockscreens

- A PIN Lockscreen
- A Passphrase Lockscreen

Description of the change

This also introduces 2 LightDM mocks. One for triggering a user with a PIN protection ("1234") and one with a user protected by a passphrase ("password").

Use ./run -p to trigger the PIN locking
Use ./run -k to trigger the passphrase locking

This also passes -p and -k through run_on_device

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

I haven't looked at the new code yet, but here's a review of some of the touch points with existing code:

670 + LightDM.Greeter.authenticate("has-pin")

Testing code?

715 + } else if (authenticationUser == "has-pin"){
716 + Q_EMIT q->showPrompt("Please enter your PIN:", Greeter::PromptTypeSecret);

Please make that just "PIN". That's what the pam_pin module does. And Shell.qml should check for an exact match, not an indexOf. In the UI, you can check for the string and present a nicer one if needed.

723 - Q_EMIT q->showPrompt("Password: ", Greeter::PromptTypeSecret);
724 + Q_EMIT q->showPrompt("Please enter your password:", Greeter::PromptTypeSecret);

PAM will likely just give us "Password:", so we should keep our mock close to that. Plus, you'll have to change some of the qmltests that check for "Password" being passed back. You can, however, check in the UI if the string is "Password" and present something nicer. It's not translated from PAM. (Which reminds me, we should pass it through gettext in LoginList.qml)

732 - authenticated = (response == "password");
733 + if (authenticationUser == "has-password") {
734 + authenticated = (response == "password");

Actually, not only has-password has a password. All the users are assumed to have "password" as their password unless otherwise specified. (And no-password users never get to the handleRespond() function) So please just check for the pin user and fallback to checking for "password".

751 + { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },

I see you added the user to the "full" mock lightdm. I think it would be more useful to add a new mock liblightdm that only has the pin user. That way we can get a more phone-like experience.

See https://code.launchpad.net/~mterry/unity/phablet-greeter-single-user/+merge/166296 which will make the phone UI only active if there's just one user. And it shows how to add a new mock liblightdm (and corrects a couple bugs with our current multiple mock support).

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

Actually, let me double confirm that "Password: " is not translated from PAM. I see that it's marked for translation in PAM, but I thought LightDM used the C locale for that. It's hard to tell from the lightdm source, so I'll ask Robert.

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

<mterry> robert_ancell, does LightDM use the C locale with PAM, or will it actually get translated prompts back from it?
<robert_ancell> mterry, in trunk it uses the correct locale, in older versions the C locale

So... The prompt will be potentially translated, so we shouldn't check for "Password" like I proposed.

But my comment about keeping close to what PAM will give us in the mocks and just use "Password: " still stands.

Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

> 670 + LightDM.Greeter.authenticate("has-pin")
> Testing code?

Don't really know. Somehow this needs to be triggered so designers and testers can have a go. I'm still unsure who actually should trigger this when the screen locks... This seemed like a sensible place to me. Where would you trigger the locking?

> 715 + } else if (authenticationUser == "has-pin"){
> 716 + Q_EMIT q->showPrompt("Please enter your PIN:",
> Greeter::PromptTypeSecret);
>
> Please make that just "PIN". That's what the pam_pin module does. And
> Shell.qml should check for an exact match, not an indexOf. In the UI, you can
> check for the string and present a nicer one if needed.

Done.

> 723 - Q_EMIT q->showPrompt("Password: ", Greeter::PromptTypeSecret);
> 724 + Q_EMIT q->showPrompt("Please enter your password:",
> Greeter::PromptTypeSecret);
>
> PAM will likely just give us "Password:", so we should keep our mock close to
> that. Plus, you'll have to change some of the qmltests that check for
> "Password" being passed back. You can, however, check in the UI if the string
> is "Password" and present something nicer. It's not translated from PAM.
> (Which reminds me, we should pass it through gettext in LoginList.qml)
>
> 732 - authenticated = (response == "password");
> 733 + if (authenticationUser == "has-password") {
> 734 + authenticated = (response == "password");
>
> Actually, not only has-password has a password. All the users are assumed to
> have "password" as their password unless otherwise specified. (And no-
> password users never get to the handleRespond() function) So please just
> check for the pin user and fallback to checking for "password".

Done.

> 751 + { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
>
> I see you added the user to the "full" mock lightdm. I think it would be more
> useful to add a new mock liblightdm that only has the pin user. That way we
> can get a more phone-like experience.

No. Because I need also the password user for the tests. This code does not only handle PINs but also passphrases by now. Don't think its useful to have another two single-user backends for those use cases when it can be handled by the full backend easily.

Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

> <mterry> robert_ancell, does LightDM use the C locale with PAM, or will it
> actually get translated prompts back from it?
> <robert_ancell> mterry, in trunk it uses the correct locale, in older versions
> the C locale
>
> So... The prompt will be potentially translated, so we shouldn't check for
> "Password" like I proposed.
>
> But my comment about keeping close to what PAM will give us in the mocks and
> just use "Password: " still stands.

Waiting for some guidance on what to do here.

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

723 - Q_EMIT q->showPrompt("Password: ", Greeter::PromptTypeSecret);
724 + Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret);

This looks like an accidental change. We want to keep that space there to test that we strip the space successfully.

Additionally, we talked on IRC about how I'd like to see a new mock for a single PIN user.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:693
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/165924/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1123/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1145/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-armhf-ci/998/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-i386-ci/1002/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1123/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:695
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/165924/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1124/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1146/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-armhf-ci/999/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-i386-ci/1003/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1124/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:696
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/165924/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1126/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1148/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-armhf-ci/1001/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-i386-ci/1005/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1126/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:697
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/165924/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1128/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1150/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-armhf-ci/1003/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-i386-ci/1007/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1128/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:700
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/165924/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1129/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1151/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-armhf-ci/1004/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-i386-ci/1008/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1129/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:700
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/167115/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1130/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1152/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-armhf-ci/1005/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-raring-i386-ci/1009/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1130/rebuild

review: Needs Fixing (continuous-integration)
lp:~unity-team/unity/phablet-pinlock updated
701. By Michael Zanetti

don't go to fullscreen mode as long as the lockscreen is here

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:701
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/167115/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1139/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1165/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-saucy-armhf-ci/5/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-saucy-i386-ci/5/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1139/rebuild

review: Needs Fixing (continuous-integration)
lp:~unity-team/unity/phablet-pinlock updated
702. By Michael Zanetti

reset lockscreen when greeter activates

703. By Michael Zanetti

make it translateable

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:703
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/167115/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1143/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1172/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-saucy-armhf-ci/9/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-saucy-i386-ci/9/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1143/rebuild

review: Needs Fixing (continuous-integration)
lp:~unity-team/unity/phablet-pinlock updated
704. By Michael Zanetti

remove debug echo

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:704
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/167115/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1145/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1175/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-saucy-armhf-ci/11/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-saucy-i386-ci/11/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1145/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:704
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-team/unity/phablet-pinlock/+merge/167115/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/unity-phablet-ci/1147/
Executed test runs:
    FAILURE: http://s-jenkins:8080/job/unity-phablet-qmluitests/1178/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-saucy-armhf-ci/13/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-saucy-i386-ci/13/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/unity-phablet-ci/1147/rebuild

review: Needs Fixing (continuous-integration)
lp:~unity-team/unity/phablet-pinlock updated
705. By Michael Zanetti

fix whitespaces

706. By Michael Zanetti

update usage() of run_on_device

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/unity/phablet-pinlock updated
707. By Michael Zanetti

fix getopts short args

708. By Michael Zanetti

remove unused imports

709. By Michael Zanetti

abstract WrongPasswordAnimation

Revision history for this message
MichaƂ Sawicz (saviq) wrote :

84 + function reset() {
85 + pinPadLoader.resetting = true
86 + pinPadLoader.resetting = false
87 + }

Could you think of a better way to do this? Are we testing that this actually works? And please semicolons at end of line.

123 + Binding {
124 + target: pinPadLoader.item
125 + property: "pinLength"
126 + value: root.pinLength
127 + }
128 + Binding {
129 + target: pinPadLoader.item
130 + property: "placeholderText"
131 + value: root.placeholderText
132 + }
133 + Binding {
134 + target: pinPadLoader.item
135 + property: "username"
136 + value: root.username
137 + }

We should vote on whether we prefer this or the less-verbose approach of Qt.binding() assignment ;)

148 + spacing: units.gu(1)
149 + Icon {

162 + }
163 + Label {

Newlines, please.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~unity-team/unity/phablet-pinlock updated
710. By Michael Zanetti

fix some coding style issues

Revision history for this message
Michael Zanetti (mzanetti) wrote :

> 84 + function reset() {
> 85 + pinPadLoader.resetting = true
> 86 + pinPadLoader.resetting = false
> 87 + }
>
> Could you think of a better way to do this? Are we testing that this actually
> works? And please semicolons at end of line.

Added the semicolons. what I need to do is to unset and re-set the loaders source. I could do that with loader.source = "" but that would break all the bindings and the code around would need to be made imperative to always correctly set the source. As you know how much I value keeping QML declarative, I think this is the best approach even though I agree it reads a bit weird at first.

> 123 + Binding {
> 124 + target: pinPadLoader.item
> 125 + property: "pinLength"
> 126 + value: root.pinLength
> 127 + }
> 128 + Binding {
> 129 + target: pinPadLoader.item
> 130 + property: "placeholderText"
> 131 + value: root.placeholderText
> 132 + }
> 133 + Binding {
> 134 + target: pinPadLoader.item
> 135 + property: "username"
> 136 + value: root.username
> 137 + }
>
> We should vote on whether we prefer this or the less-verbose approach of
> Qt.binding() assignment ;)

The problem I have with Qt.binding() is that its again imperative. I'd need some Component.onCompleted or whatever to trigger it, which is what I don't like. In my private projects I would write this as

Binding { target: pinPadLoader.item; property: "username"; value: root.username }

which makes it look a bit less verbose (I have a virtual limit of around 2 - 4 properties that can go into one line).

> 148 + spacing: units.gu(1)
> 149 + Icon {
>
> 162 + }
> 163 + Label {
>
> Newlines, please.

Done.

lp:~unity-team/unity/phablet-pinlock updated
711. By Michael Zanetti

fix whitespace issues again

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~unity-team/unity/phablet-pinlock updated
712. By Michael Zanetti

added missing copyright header

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

Looks mostly fine to me.

566 + // If there is only one user, we start authenticating with that one here.
567 + // If there are more users, the Greeter will handle that
568 + if (LightDM.Users.count == 1) {
569 + LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
570 + }

This feels a bit mismatched. I don't like the different code paths, though I get why you did it. No change requested, just noting.

As for the testing changes... I love the new plugins. But why add the has-pin user to the full/ plugin? I'd assume the single-pin/ plugin was the choice for testing the PIN screen. Similarly, the passphrase screen isn't tested via the single-passphrase/ plugin.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

712. By Michael Zanetti

added missing copyright header

711. By Michael Zanetti

fix whitespace issues again

710. By Michael Zanetti

fix some coding style issues

709. By Michael Zanetti

abstract WrongPasswordAnimation

708. By Michael Zanetti

remove unused imports

707. By Michael Zanetti

fix getopts short args

706. By Michael Zanetti

update usage() of run_on_device

705. By Michael Zanetti

fix whitespaces

704. By Michael Zanetti

remove debug echo

703. By Michael Zanetti

make it translateable

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Components/WrongPasswordAnimation.qml'
2--- Components/WrongPasswordAnimation.qml 1970-01-01 00:00:00 +0000
3+++ Components/WrongPasswordAnimation.qml 2013-06-05 16:11:30 +0000
4@@ -0,0 +1,46 @@
5+/*
6+ * Copyright (C) 2013 Canonical, Ltd.
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+import QtQuick 2.0
22+
23+SequentialAnimation {
24+ id: root
25+
26+ property var target
27+
28+ NumberAnimation {
29+ target: root.target
30+ property: "anchors.horizontalCenterOffset"
31+ duration: 50
32+ easing.type: Easing.InQuad
33+ to: units.gu(2)
34+ }
35+ NumberAnimation {
36+ target: root.target
37+ property: "anchors.horizontalCenterOffset"
38+ duration: 100
39+ easing.type: Easing.InOutQuad
40+ to: -units.gu(2)
41+ }
42+ NumberAnimation {
43+ target: root.target
44+ easing.type: Easing.OutElastic
45+ properties: "anchors.horizontalCenterOffset"
46+ to: 0
47+ duration: 400
48+ easing.overshoot: units.gu(2)
49+ }
50+}
51
52=== added file 'Greeter/Lockscreen.qml'
53--- Greeter/Lockscreen.qml 1970-01-01 00:00:00 +0000
54+++ Greeter/Lockscreen.qml 2013-06-05 16:11:30 +0000
55@@ -0,0 +1,149 @@
56+/*
57+ * Copyright (C) 2013 Canonical, Ltd.
58+ *
59+ * This program is free software; you can redistribute it and/or modify
60+ * it under the terms of the GNU General Public License as published by
61+ * the Free Software Foundation; version 3.
62+ *
63+ * This program is distributed in the hope that it will be useful,
64+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
65+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66+ * GNU General Public License for more details.
67+ *
68+ * You should have received a copy of the GNU General Public License
69+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
70+ */
71+
72+import QtQuick 2.0
73+import Ubuntu.Components 0.1
74+import "../Components"
75+import LightDM 0.1 as LightDM
76+
77+Showable {
78+ id: root
79+
80+ // Determine if a numeric or alphanumeric pad is used.
81+ property bool alphaNumeric: false
82+
83+ // Placeholder text
84+ property string placeholderText: ""
85+
86+ // In case the Lockscreen can show a greeter message, this is the username
87+ property string username: ""
88+
89+ // As the numeric PIN pad doesn't have a OK button by design, we need to auto-confirm on a certain length.
90+ // This is ignored by the alphaNumeric lockscreen as that one is confirmed with pressing enter on the OSK.
91+ property int pinLength: 4
92+
93+ property url background: ""
94+
95+ signal unlocked()
96+ signal cancel()
97+ signal emergencyCall()
98+
99+ function reset() {
100+ pinPadLoader.resetting = true;
101+ pinPadLoader.resetting = false;
102+ }
103+
104+ Image {
105+ anchors.fill: parent
106+ source: root.required ? root.background : ""
107+ }
108+
109+ MouseArea {
110+ anchors.fill: root
111+ }
112+
113+ Loader {
114+ id: pinPadLoader
115+ objectName: "pinPadLoader"
116+ anchors {
117+ left: parent.left
118+ right: parent.right
119+ verticalCenter: parent.verticalCenter
120+ verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : 0
121+ }
122+ property bool resetting: false
123+
124+ source: (!resetting && root.required) ? (root.alphaNumeric ? "PassphraseLockscreen.qml" : "PinLockscreen.qml") : ""
125+
126+ Connections {
127+ target: pinPadLoader.item
128+
129+ onEntered: {
130+ LightDM.Greeter.respond(passphrase);
131+ }
132+
133+ onCancel: {
134+ root.cancel()
135+ }
136+ }
137+
138+ Binding {
139+ target: pinPadLoader.item
140+ property: "pinLength"
141+ value: root.pinLength
142+ }
143+ Binding {
144+ target: pinPadLoader.item
145+ property: "placeholderText"
146+ value: root.placeholderText
147+ }
148+ Binding {
149+ target: pinPadLoader.item
150+ property: "username"
151+ value: root.username
152+ }
153+ }
154+
155+ Column {
156+ anchors {
157+ left: parent.left
158+ top: pinPadLoader.bottom
159+ topMargin: units.gu(4)
160+ right: parent.right
161+ bottom: parent.bottom
162+ }
163+ spacing: units.gu(1)
164+
165+ Icon {
166+ objectName: "emergencyCallIcon"
167+ height: units.gu(3)
168+ width: height
169+ anchors.horizontalCenter: parent.horizontalCenter
170+ name: "phone-app-call-symbolic"
171+ color: "white"
172+ opacity: 0.9
173+
174+ MouseArea {
175+ anchors.fill: parent
176+ onClicked: root.emergencyCall()
177+ }
178+ }
179+
180+ Label {
181+ text: i18n.tr("Emergency call")
182+ color: "white"
183+ opacity: 0.9
184+ fontSize: "medium"
185+ anchors.horizontalCenter: parent.horizontalCenter
186+ }
187+ }
188+
189+ Connections {
190+ target: LightDM.Greeter
191+
192+ onAuthenticationComplete: {
193+ if (LightDM.Greeter.promptless) {
194+ return;
195+ }
196+ if (LightDM.Greeter.authenticated) {
197+ root.unlocked();
198+ pinPadLoader.item.clear(false);
199+ } else {
200+ pinPadLoader.item.clear(true);
201+ }
202+ }
203+ }
204+}
205
206=== modified file 'Greeter/LoginList.qml'
207--- Greeter/LoginList.qml 2013-05-30 20:26:43 +0000
208+++ Greeter/LoginList.qml 2013-06-05 16:11:30 +0000
209@@ -17,6 +17,7 @@
210 import QtQuick 2.0
211 import Ubuntu.Components 0.1
212 import LightDM 0.1 as LightDM
213+import "../Components"
214
215 Item {
216 id: root
217@@ -218,30 +219,9 @@
218 source: "graphics/icon_arrow.png"
219 }
220
221- SequentialAnimation {
222+ WrongPasswordAnimation {
223 id: wrongPasswordAnimation
224- NumberAnimation {
225- target: passwordInput
226- property: "anchors.horizontalCenterOffset"
227- duration: 50
228- easing.type: Easing.InQuad
229- to: units.gu(2)
230- }
231- NumberAnimation {
232- target: passwordInput
233- property: "anchors.horizontalCenterOffset"
234- duration: 100
235- easing.type: Easing.InOutQuad
236- to: -units.gu(2)
237- }
238- NumberAnimation {
239- target: passwordInput
240- easing.type: Easing.OutElastic
241- properties: "anchors.horizontalCenterOffset"
242- to: 0
243- duration: 400
244- easing.overshoot: units.gu(2)
245- }
246+ target: passwordInput
247 }
248
249 Connections {
250
251=== added file 'Greeter/PassphraseLockscreen.qml'
252--- Greeter/PassphraseLockscreen.qml 1970-01-01 00:00:00 +0000
253+++ Greeter/PassphraseLockscreen.qml 2013-06-05 16:11:30 +0000
254@@ -0,0 +1,87 @@
255+/*
256+ * Copyright (C) 2013 Canonical, Ltd.
257+ *
258+ * This program is free software; you can redistribute it and/or modify
259+ * it under the terms of the GNU General Public License as published by
260+ * the Free Software Foundation; version 3.
261+ *
262+ * This program is distributed in the hope that it will be useful,
263+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
264+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
265+ * GNU General Public License for more details.
266+ *
267+ * You should have received a copy of the GNU General Public License
268+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
269+ */
270+
271+import QtQuick 2.0
272+import Ubuntu.Components 0.1
273+import "../Components"
274+
275+Item {
276+ id: root
277+ height: highlightItem.height
278+
279+ property alias placeholderText: pinentryField.placeholderText
280+ property string username: ""
281+
282+ signal entered(string passphrase)
283+ signal cancel()
284+
285+ function clear(playAnimation) {
286+ pinentryField.text = "";
287+ if (playAnimation) {
288+ wrongPasswordAnimation.start();
289+ } else {
290+ pinentryField.focus = false
291+ }
292+ }
293+
294+ Rectangle {
295+ id: highlightItem
296+ width: units.gu(32)
297+ height: units.gu(10)
298+ anchors.centerIn: parent
299+ color: Qt.rgba(0.1, 0.1, 0.1, 0.4)
300+ border.color: Qt.rgba(0.4, 0.4, 0.4, 0.4)
301+ border.width: units.dp(1)
302+ radius: units.gu(1.5)
303+ antialiasing: true
304+
305+ Label {
306+ objectName: "greeterLabel"
307+ anchors {
308+ left: parent.left
309+ top: parent.top
310+ right: parent.right
311+ margins: units.gu(1.5)
312+ }
313+ text: root.username.length > 0 ? i18n.tr("Hello %1").arg(root.username) : i18n.tr("Hello")
314+ color: "white"
315+ }
316+
317+ TextField {
318+ id: pinentryField
319+ objectName: "pinentryField"
320+ anchors {
321+ horizontalCenter: parent.horizontalCenter
322+ bottom: parent.bottom
323+ margins: units.gu(1)
324+ }
325+ height: units.gu(4.5)
326+ width: parent.width - units.gu(2)
327+ echoMode: TextInput.Password
328+ opacity: 0.9
329+ hasClearButton: false
330+
331+ onAccepted: {
332+ root.entered(pinentryField.text);
333+ }
334+ }
335+ }
336+
337+ WrongPasswordAnimation {
338+ id: wrongPasswordAnimation
339+ target: pinentryField
340+ }
341+}
342
343=== added file 'Greeter/PinLockscreen.qml'
344--- Greeter/PinLockscreen.qml 1970-01-01 00:00:00 +0000
345+++ Greeter/PinLockscreen.qml 2013-06-05 16:11:30 +0000
346@@ -0,0 +1,111 @@
347+/*
348+ * Copyright (C) 2013 Canonical, Ltd.
349+ *
350+ * This program is free software; you can redistribute it and/or modify
351+ * it under the terms of the GNU General Public License as published by
352+ * the Free Software Foundation; version 3.
353+ *
354+ * This program is distributed in the hope that it will be useful,
355+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
356+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
357+ * GNU General Public License for more details.
358+ *
359+ * You should have received a copy of the GNU General Public License
360+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
361+ */
362+
363+import QtQuick 2.0
364+import Ubuntu.Components 0.1
365+import "../Components"
366+
367+Column {
368+ id: root
369+ anchors.centerIn: parent
370+ spacing: units.gu(2.5)
371+
372+ property alias placeholderText: pinentryField.placeholderText
373+ property int padWidth: units.gu(32)
374+ property int pinLength: 4
375+
376+ signal entered(string passphrase)
377+ signal cancel()
378+
379+ function clear(playAnimation) {
380+ pinentryField.text = "";
381+ if (playAnimation) {
382+ wrongPasswordAnimation.start();
383+ }
384+ }
385+
386+ TextField {
387+ id: pinentryField
388+ objectName: "pinentryField"
389+ anchors.horizontalCenter: parent.horizontalCenter
390+ width: units.gu(32)
391+ height: units.gu(5)
392+ echoMode: TextInput.Password
393+ font.pixelSize: units.dp(44)
394+ color: "white"
395+ opacity: 0.9
396+ hasClearButton: false
397+ horizontalAlignment: Text.AlignHCenter
398+
399+ onTextChanged: {
400+ if (pinentryField.text.length === root.pinLength) {
401+ root.entered(pinentryField.text);
402+ }
403+ }
404+
405+ // Using a MouseArea to eat clicks. We don't want to disable the TextField for styling reasons
406+ MouseArea {
407+ anchors.fill: parent
408+ }
409+ }
410+
411+ Grid {
412+ anchors {
413+ left: parent.left
414+ right: parent.right
415+ margins: (parent.width - root.padWidth) / 2
416+ }
417+
418+ columns: 3
419+ spacing: units.gu(1)
420+
421+ Repeater {
422+ model: 9
423+
424+ PinPadButton {
425+ objectName: "pinPadButton" + (index + 1)
426+ text: index + 1
427+
428+ onClicked: {
429+ pinentryField.text = pinentryField.text + text
430+ }
431+ }
432+ }
433+
434+ PinPadButton {
435+ objectName: "pinPadButtonBack"
436+ iconName: "back"
437+ onClicked: root.cancel();
438+
439+ }
440+ PinPadButton {
441+ objectName: "pinPadButton0"
442+ text: "0"
443+ onClicked: pinentryField.text = pinentryField.text + text
444+
445+ }
446+ PinPadButton {
447+ objectName: "pinPadButtonErase"
448+ iconName: "erase"
449+ onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
450+ }
451+ }
452+
453+ WrongPasswordAnimation {
454+ id: wrongPasswordAnimation
455+ target: pinentryField
456+ }
457+}
458
459=== added file 'Greeter/PinPadButton.qml'
460--- Greeter/PinPadButton.qml 1970-01-01 00:00:00 +0000
461+++ Greeter/PinPadButton.qml 2013-06-05 16:11:30 +0000
462@@ -0,0 +1,59 @@
463+/*
464+ * Copyright (C) 2013 Canonical, Ltd.
465+ *
466+ * This program is free software; you can redistribute it and/or modify
467+ * it under the terms of the GNU General Public License as published by
468+ * the Free Software Foundation; version 3.
469+ *
470+ * This program is distributed in the hope that it will be useful,
471+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
472+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
473+ * GNU General Public License for more details.
474+ *
475+ * You should have received a copy of the GNU General Public License
476+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
477+ */
478+
479+import QtQuick 2.0
480+import Ubuntu.Components 0.1
481+
482+UbuntuShape {
483+ id: root
484+ width: units.gu(10)
485+ height: units.gu(7)
486+ radius: "medium"
487+
488+ property alias text: label.text
489+ property alias iconName: icon.name
490+
491+ signal clicked()
492+
493+ Behavior on color {
494+ ColorAnimation { duration: 100 }
495+ }
496+
497+ Label {
498+ id: label
499+ anchors.centerIn: parent
500+ color: "white"
501+ fontSize: "x-large"
502+ font.weight: Font.Light
503+ opacity: 0.9
504+ }
505+
506+ Icon {
507+ id: icon
508+ height: units.gu(3)
509+ width: height
510+ anchors.centerIn: parent
511+ color: "white"
512+ opacity: 0.9
513+ }
514+
515+ MouseArea {
516+ anchors.fill: parent
517+ onClicked: root.clicked()
518+ onPressed: root.color = Qt.rgba(0, 0, 0, 0.3)
519+ onReleased: root.color = Qt.rgba(0, 0, 0, 0)
520+ }
521+}
522
523=== modified file 'Shell.qml'
524--- Shell.qml 2013-06-03 19:25:43 +0000
525+++ Shell.qml 2013-06-05 16:11:30 +0000
526@@ -67,7 +67,7 @@
527 }
528
529 readonly property bool fullscreenMode: {
530- if (greeter.shown) {
531+ if (greeter.shown || lockscreen.shown) {
532 return false;
533 } else if (mainStage.usingScreenshots) { // Window Manager animating so want to re-evaluate fullscreen mode
534 return mainStage.switchingFromFullscreenToFullscreen;
535@@ -124,7 +124,6 @@
536
537 Item {
538 id: underlay
539-
540 anchors.fill: parent
541 visible: !(panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth)
542 && (stages.fullyHidden
543@@ -148,7 +147,7 @@
544 Dash {
545 id: dash
546
547- available: !greeter.shown
548+ available: !greeter.shown && !lockscreen.shown
549 hides: [stages, launcher, panel.indicators]
550 shown: disappearingAnimationProgress !== 1.0
551 enabled: disappearingAnimationProgress === 0.0
552@@ -301,7 +300,7 @@
553 && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
554 shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
555
556- available: !greeter.shown && enabled
557+ available: !greeter.shown && !lockscreen.shown && enabled
558 hides: [launcher, panel.indicators]
559 shown: false
560 showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
561@@ -352,6 +351,40 @@
562 orientation: Qt.Horizontal
563 }
564
565+ Lockscreen {
566+ id: lockscreen
567+ hides: [launcher, panel.indicators, hud]
568+ shown: false
569+ enabled: true
570+ showAnimation: StandardAnimation { property: "opacity"; to: 1 }
571+ hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
572+ y: panel.panelHeight
573+ x: required ? 0 : - width
574+ width: parent.width
575+ height: parent.height - panel.panelHeight
576+ background: shell.background
577+
578+ onUnlocked: lockscreen.hide()
579+ onCancel: greeter.show()
580+
581+ Component.onCompleted: LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
582+ }
583+
584+ Connections {
585+ target: LightDM.Greeter
586+
587+ onShowPrompt: {
588+ // TODO: There's no better way for now to determine if its a PIN or a passphrase.
589+ if (text == "PIN") {
590+ lockscreen.alphaNumeric = false
591+ } else {
592+ lockscreen.alphaNumeric = true
593+ }
594+ lockscreen.placeholderText = i18n.tr("Please enter %1:").arg(text);
595+ lockscreen.show();
596+ }
597+ }
598+
599 Greeter {
600 id: greeter
601
602@@ -360,7 +393,6 @@
603 shown: true
604 showAnimation: StandardAnimation { property: "x"; to: greeterRevealer.openedValue }
605 hideAnimation: StandardAnimation { property: "x"; to: greeterRevealer.closedValue }
606-
607 y: panel.panelHeight
608 width: parent.width
609 height: parent.height - panel.panelHeight
610@@ -370,6 +402,12 @@
611
612 onShownChanged: {
613 if (shown) {
614+ lockscreen.reset();
615+ // If there is only one user, we start authenticating with that one here.
616+ // If there are more users, the Greeter will handle that
617+ if (LightDM.Users.count == 1) {
618+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
619+ }
620 greeter.forceActiveFocus();
621 // FIXME: *FocusedApplication are not updated when unfocused, hence the need to check whether
622 // the stage was actually shown
623@@ -397,7 +435,7 @@
624
625 InputFilterArea {
626 anchors.fill: parent
627- blockInput: greeter.shown
628+ blockInput: greeter.shown || lockscreen.shown
629 }
630
631 Revealer {
632@@ -426,7 +464,7 @@
633 hides: [launcher]
634 }
635 fullscreenMode: shell.fullscreenMode
636- searchVisible: !greeter.shown
637+ searchVisible: !greeter.shown && !lockscreen.shown
638
639 InputFilterArea {
640 anchors.fill: parent
641@@ -440,7 +478,7 @@
642 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
643 height: parent.height
644
645- available: !greeter.shown && !panel.indicators.shown
646+ available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown
647 shown: false
648 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
649 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
650
651=== modified file 'plugins/LightDM/CMakeLists.txt'
652--- plugins/LightDM/CMakeLists.txt 2013-05-28 10:26:22 +0000
653+++ plugins/LightDM/CMakeLists.txt 2013-06-05 16:11:30 +0000
654@@ -40,4 +40,4 @@
655
656 install(FILES qmldir
657 DESTINATION ${SHELL_APP_DIR}/plugins/LightDM
658- )
659\ No newline at end of file
660+ )
661
662=== modified file 'run'
663--- run 2013-06-03 15:33:42 +0000
664+++ run 2013-06-05 16:11:30 +0000
665@@ -4,6 +4,8 @@
666 export LD_LIBRARY_PATH=$PWD/../unity_build/build/lib
667 GDB=false
668 FAKE=false
669+PINLOCK=false
670+KEYLOCK=false
671 MOUSE_TOUCH=true
672
673 usage() {
674@@ -11,6 +13,8 @@
675 echo "Script to run the shell.\n" >&2
676 echo "OPTIONS:" >&2
677 echo " -f, --fake Force use of fake Qml modules." >&2
678+ echo " -p, --pinlock Use a pin protected user." >&2
679+ echo " -k, --keylock Use a passphrase protected user." >&2
680 echo " -g, --gdb Run through gdb." >&2
681 echo " -h, --help Show this help." >&2
682 echo " -m, --nomousetouch Run without -mousetouch argument." >&2
683@@ -18,7 +22,7 @@
684 exit 1
685 }
686
687-ARGS=`getopt -n$0 -u -a --longoptions="fake,gdb,help,nomousetouch" -o "fghm" -- "$@"`
688+ARGS=`getopt -n$0 -u -a --longoptions="fake,pinlock,keylock,gdb,help,nomousetouch" -o "fpkghm" -- "$@"`
689 [ $? -ne 0 ] && usage
690 eval set -- "$ARGS"
691
692@@ -26,6 +30,8 @@
693 do
694 case "$1" in
695 -f|--fake) FAKE=true;;
696+ -p|--pinlock) PINLOCK=true;;
697+ -k|--keylock) KEYLOCK=true;;
698 -g|--gdb) GDB=true;;
699 -h|--help) usage;;
700 -m|--nomousetouch) MOUSE_TOUCH=false;;
701@@ -39,6 +45,16 @@
702 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single
703 fi
704
705+if $PINLOCK; then
706+ export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
707+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single-pin
708+fi
709+
710+if $KEYLOCK; then
711+ export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
712+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single-passphrase
713+fi
714+
715 # Force icon theme if running on the desktop, otherwise gnome theme (if running
716 # on Ubuntu Desktop) will be used and icons won't be found
717 if [ -n "$DESKTOP_SESSION" ]; then
718
719=== modified file 'run_on_device'
720--- run_on_device 2013-05-29 08:21:31 +0000
721+++ run_on_device 2013-06-05 16:11:30 +0000
722@@ -11,6 +11,8 @@
723 RUN_OPTIONS=-qmljsdebugger=port:$TARGET_DEBUG_PORT
724 SETUP=false
725 GDB=false
726+PINLOCK=false
727+KEYLOCK=false
728 SUDO="echo $PASSWORD | sudo -S"
729 NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
730
731@@ -19,6 +21,8 @@
732 echo "Script to setup a build environment for the shell and sync build and run it on the device\n"
733 echo "OPTIONS:"
734 echo " -s, --setup Setup the build environment"
735+ echo " -p, --pinlock Enable a PIN lock screen when running"
736+ echo " -k, --keylock Enable a Keyboard lock screen when running"
737 echo ""
738 echo "IMPORTANT:"
739 echo " * Make sure to have the networking and PPAs setup on the device beforehand (phablet-deploy-networking && phablet-ppa-fetch)."
740@@ -83,11 +87,19 @@
741 adb shell "chroot /data/ubuntu /usr/bin/service ubuntu-session restart"
742 fi
743 adb shell pkill $BINARY
744+ ARGS="--nomousetouch"
745 if $GDB; then
746- exec_with_ssh "cd $CODE_DIR/ && ./run --gdb --nomousetouch -- $RUN_OPTIONS"
747- else
748- exec_with_ssh "cd $CODE_DIR && ./run --nomousetouch -- $RUN_OPTIONS"
749- fi
750+ ARGS="$ARGS --gdb"
751+ fi
752+ if $PINLOCK; then
753+ ARGS="$ARGS -p"
754+ fi
755+ if $KEYLOCK; then
756+ ARGS="$ARGS -k"
757+ fi
758+
759+ exec_with_ssh "cd $CODE_DIR/ && ./run $ARGS -- $RUN_OPTIONS"
760+
761 if [ $CONTAINS_SHELL -eq 0 ]; then
762 echo "Restoring $SERVICEFILE on device from $SERVICEFILE.backup"
763 adb shell cp $SERVICEFILE.backup $SERVICEFILE
764@@ -95,7 +107,7 @@
765 fi
766 }
767
768-set -- `getopt -n$0 -u -a --longoptions="setup,gdb,help" "sgh" "$@"`
769+set -- `getopt -n$0 -u -a --longoptions="setup,gdb,pinlock,keylock,help" "sgpkh" "$@"`
770
771 # FIXME: giving incorrect arguments does not call usage and exit
772 while [ $# -gt 0 ]
773@@ -103,6 +115,8 @@
774 case "$1" in
775 -s|--setup) SETUP=true;;
776 -g|--gdb) GDB=true;;
777+ -p|--pinlock) PINLOCK=true;;
778+ -k|--keylock) KEYLOCK=true;;
779 -h|--help) usage;;
780 --) shift;break;;
781 esac
782
783=== modified file 'tests/mocks/LightDM/CMakeLists.txt'
784--- tests/mocks/LightDM/CMakeLists.txt 2013-06-03 15:32:21 +0000
785+++ tests/mocks/LightDM/CMakeLists.txt 2013-06-05 16:11:30 +0000
786@@ -7,6 +7,8 @@
787 add_subdirectory(demo)
788 add_subdirectory(full)
789 add_subdirectory(single)
790+add_subdirectory(single-pin)
791+add_subdirectory(single-passphrase)
792
793 include_directories(
794 ${CMAKE_CURRENT_SOURCE_DIR}
795
796=== modified file 'tests/mocks/LightDM/full/GreeterPrivate.cpp'
797--- tests/mocks/LightDM/full/GreeterPrivate.cpp 2013-05-24 13:48:29 +0000
798+++ tests/mocks/LightDM/full/GreeterPrivate.cpp 2013-06-05 16:11:30 +0000
799@@ -53,6 +53,8 @@
800 if (authenticationUser == "no-password") {
801 authenticated = true;
802 Q_EMIT q->authenticationComplete();
803+ } else if (authenticationUser == "has-pin"){
804+ Q_EMIT q->showPrompt("PIN", Greeter::PromptTypeSecret);
805 } else if (authenticationUser == "auth-error") {
806 authenticated = false;
807 Q_EMIT q->authenticationComplete();
808@@ -85,7 +87,11 @@
809 return;
810 }
811
812- authenticated = (response == "password");
813+ if (authenticationUser == "has-pin") {
814+ authenticated = (response == "1234");
815+ } else {
816+ authenticated = (response == "password");
817+ }
818 Q_EMIT q->authenticationComplete();
819 }
820
821
822=== modified file 'tests/mocks/LightDM/full/UsersModelPrivate.cpp'
823--- tests/mocks/LightDM/full/UsersModelPrivate.cpp 2013-05-23 19:53:33 +0000
824+++ tests/mocks/LightDM/full/UsersModelPrivate.cpp 2013-06-05 16:11:30 +0000
825@@ -27,6 +27,7 @@
826 entries =
827 {
828 { "has-password", "Has Password", 0, 0, false, false, 0, 0 },
829+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
830 { "different-prompt", "Different Prompt", 0, 0, false, false, 0, 0 },
831 { "no-password", "No Password", 0, 0, false, false, 0, 0 },
832 { "auth-error", "Auth Error", 0, 0, false, false, 0, 0 },
833
834=== added directory 'tests/mocks/LightDM/single-passphrase'
835=== added file 'tests/mocks/LightDM/single-passphrase/CMakeLists.txt'
836--- tests/mocks/LightDM/single-passphrase/CMakeLists.txt 1970-01-01 00:00:00 +0000
837+++ tests/mocks/LightDM/single-passphrase/CMakeLists.txt 2013-06-05 16:11:30 +0000
838@@ -0,0 +1,21 @@
839+set(LibLightDM_SOURCES
840+ ../Greeter.cpp
841+ ../UsersModel.cpp
842+ ../InfographicModel.cpp
843+ GreeterPrivate.cpp
844+ UsersModelPrivate.cpp
845+ InfographicModelPrivate.cpp
846+ ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
847+ )
848+
849+
850+add_library(MockLightDM-single-passphrase SHARED ${LibLightDM_SOURCES})
851+
852+qt5_use_modules(MockLightDM-single-passphrase Gui)
853+
854+set_target_properties(MockLightDM-single-passphrase PROPERTIES
855+ OUTPUT_NAME lightdm-qt5-2)
856+
857+install(TARGETS MockLightDM-single-passphrase
858+ DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/single-passphrase
859+ )
860
861=== added file 'tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp'
862--- tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp 1970-01-01 00:00:00 +0000
863+++ tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp 2013-06-05 16:11:30 +0000
864@@ -0,0 +1,53 @@
865+/*
866+ * Copyright (C) 2013 Canonical, Ltd.
867+ *
868+ * This program is free software; you can redistribute it and/or modify
869+ * it under the terms of the GNU General Public License as published by
870+ * the Free Software Foundation; version 3.
871+ *
872+ * This program is distributed in the hope that it will be useful,
873+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
874+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
875+ * GNU General Public License for more details.
876+ *
877+ * You should have received a copy of the GNU General Public License
878+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
879+ *
880+ * Author: Michael Terry <michael.terry@canonical.com>
881+ */
882+
883+#include "../Greeter.h"
884+#include "../GreeterPrivate.h"
885+
886+#include <QDebug>
887+
888+namespace QLightDM
889+{
890+
891+GreeterPrivate::GreeterPrivate(Greeter* parent)
892+ : authenticated(false),
893+ authenticationUser(),
894+ q_ptr(parent)
895+{
896+}
897+
898+void GreeterPrivate::handleAuthenticate()
899+{
900+ Q_Q(Greeter);
901+
902+ qDebug() << "handleAuthentication called!" << authenticationUser;
903+
904+ Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret);
905+}
906+
907+void GreeterPrivate::handleRespond(const QString &response)
908+{
909+ Q_Q(Greeter);
910+
911+
912+ authenticated = (response == "password");
913+ qDebug() << "responding" << response << authenticated;
914+ Q_EMIT q->authenticationComplete();
915+}
916+
917+}
918
919=== added file 'tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp'
920--- tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp 1970-01-01 00:00:00 +0000
921+++ tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp 2013-06-05 16:11:30 +0000
922@@ -0,0 +1,61 @@
923+/*
924+ * Copyright (C) 2013 Canonical, Ltd.
925+ *
926+ * This program is free software; you can redistribute it and/or modify
927+ * it under the terms of the GNU General Public License as published by
928+ * the Free Software Foundation; version 3.
929+ *
930+ * This program is distributed in the hope that it will be useful,
931+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
932+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
933+ * GNU General Public License for more details.
934+ *
935+ * You should have received a copy of the GNU General Public License
936+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
937+ *
938+ * Author: Pete Woods <pete.woods@canonical.com>
939+ */
940+
941+#include "../InfographicModelPrivate.h"
942+
943+namespace QLightDM
944+{
945+
946+void InfographicModelPrivate::generateFakeData()
947+{
948+ std::default_random_engine generator;
949+ std::normal_distribution<qreal> distribution(0.5, 0.2);
950+ auto rand = std::bind(distribution, generator);
951+
952+ QColor orange = QColor::fromRgbF(0.9, 0.3, 0.1, 1.0);
953+ QColor yellow = QColor::fromRgbF(1.0, 0.6, 0.0, 1.0);
954+ QColor red = QColor::fromRgbF(0.8, 0.0, 0.0, 1.0);
955+ QColor darkPurple = QColor::fromRgbF(0.5, 0.2, 0.3, 1.0);
956+ QColor lightPurple = QColor::fromRgbF(0.8, 0.1, 0.8, 1.0);
957+ QColor pink(QColor::fromRgbF(0.75, 0.13, 0.75));
958+
959+ InfographicColorTheme orangeTheme(orange, orange, orange);
960+ InfographicColorTheme yellowTheme(yellow, yellow, yellow);
961+ InfographicColorTheme redTheme(red, red, red);
962+ InfographicColorTheme darkPurpleTheme(darkPurple, darkPurple, darkPurple);
963+ InfographicColorTheme lightPurpleTheme(lightPurple, lightPurple,
964+ lightPurple);
965+ InfographicColorTheme pinkTheme(pink, pink, pink);
966+
967+ {
968+ QVariantList firstMonth;
969+ while (firstMonth.size() < 17)
970+ firstMonth.push_back(QVariant(rand()));
971+ while (firstMonth.size() < 31)
972+ firstMonth.push_back(QVariant());
973+ QVariantList secondMonth;
974+ while (secondMonth.size() < 31)
975+ secondMonth.push_back(QVariant(rand()));
976+ QSharedPointer<InfographicData> data(
977+ new InfographicData("<b>5km</b> travelled", yellowTheme,
978+ firstMonth, orangeTheme, secondMonth, this));
979+ m_fakeData.insert("has-pin", data);
980+ }
981+}
982+
983+}
984
985=== added file 'tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp'
986--- tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp 1970-01-01 00:00:00 +0000
987+++ tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp 2013-06-05 16:11:30 +0000
988@@ -0,0 +1,33 @@
989+/*
990+ * Copyright (C) 2013 Canonical, Ltd.
991+ *
992+ * This program is free software; you can redistribute it and/or modify
993+ * it under the terms of the GNU General Public License as published by
994+ * the Free Software Foundation; version 3.
995+ *
996+ * This program is distributed in the hope that it will be useful,
997+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
998+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
999+ * GNU General Public License for more details.
1000+ *
1001+ * You should have received a copy of the GNU General Public License
1002+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1003+ *
1004+ * Author: Michael Terry <michael.terry@canonical.com>
1005+ */
1006+
1007+#include "../UsersModelPrivate.h"
1008+
1009+namespace QLightDM
1010+{
1011+
1012+UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
1013+ : q_ptr(parent)
1014+{
1015+ entries =
1016+ {
1017+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
1018+ };
1019+}
1020+
1021+}
1022
1023=== added directory 'tests/mocks/LightDM/single-pin'
1024=== added file 'tests/mocks/LightDM/single-pin/CMakeLists.txt'
1025--- tests/mocks/LightDM/single-pin/CMakeLists.txt 1970-01-01 00:00:00 +0000
1026+++ tests/mocks/LightDM/single-pin/CMakeLists.txt 2013-06-05 16:11:30 +0000
1027@@ -0,0 +1,21 @@
1028+set(LibLightDM_SOURCES
1029+ ../Greeter.cpp
1030+ ../UsersModel.cpp
1031+ ../InfographicModel.cpp
1032+ GreeterPrivate.cpp
1033+ UsersModelPrivate.cpp
1034+ InfographicModelPrivate.cpp
1035+ ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
1036+ )
1037+
1038+
1039+add_library(MockLightDM-single-pin SHARED ${LibLightDM_SOURCES})
1040+
1041+qt5_use_modules(MockLightDM-single-pin Gui)
1042+
1043+set_target_properties(MockLightDM-single-pin PROPERTIES
1044+ OUTPUT_NAME lightdm-qt5-2)
1045+
1046+install(TARGETS MockLightDM-single-pin
1047+ DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/single-pin
1048+ )
1049
1050=== added file 'tests/mocks/LightDM/single-pin/GreeterPrivate.cpp'
1051--- tests/mocks/LightDM/single-pin/GreeterPrivate.cpp 1970-01-01 00:00:00 +0000
1052+++ tests/mocks/LightDM/single-pin/GreeterPrivate.cpp 2013-06-05 16:11:30 +0000
1053@@ -0,0 +1,53 @@
1054+/*
1055+ * Copyright (C) 2013 Canonical, Ltd.
1056+ *
1057+ * This program is free software; you can redistribute it and/or modify
1058+ * it under the terms of the GNU General Public License as published by
1059+ * the Free Software Foundation; version 3.
1060+ *
1061+ * This program is distributed in the hope that it will be useful,
1062+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1063+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1064+ * GNU General Public License for more details.
1065+ *
1066+ * You should have received a copy of the GNU General Public License
1067+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1068+ *
1069+ * Author: Michael Terry <michael.terry@canonical.com>
1070+ */
1071+
1072+#include "../Greeter.h"
1073+#include "../GreeterPrivate.h"
1074+
1075+#include <QDebug>
1076+
1077+namespace QLightDM
1078+{
1079+
1080+GreeterPrivate::GreeterPrivate(Greeter* parent)
1081+ : authenticated(false),
1082+ authenticationUser(),
1083+ q_ptr(parent)
1084+{
1085+}
1086+
1087+void GreeterPrivate::handleAuthenticate()
1088+{
1089+ Q_Q(Greeter);
1090+
1091+ qDebug() << "handleAuthentication called!" << authenticationUser;
1092+
1093+ Q_EMIT q->showPrompt("PIN:", Greeter::PromptTypeSecret);
1094+}
1095+
1096+void GreeterPrivate::handleRespond(const QString &response)
1097+{
1098+ Q_Q(Greeter);
1099+
1100+
1101+ authenticated = (response == "1234");
1102+ qDebug() << "responding" << response << authenticated;
1103+ Q_EMIT q->authenticationComplete();
1104+}
1105+
1106+}
1107
1108=== added file 'tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp'
1109--- tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp 1970-01-01 00:00:00 +0000
1110+++ tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp 2013-06-05 16:11:30 +0000
1111@@ -0,0 +1,61 @@
1112+/*
1113+ * Copyright (C) 2013 Canonical, Ltd.
1114+ *
1115+ * This program is free software; you can redistribute it and/or modify
1116+ * it under the terms of the GNU General Public License as published by
1117+ * the Free Software Foundation; version 3.
1118+ *
1119+ * This program is distributed in the hope that it will be useful,
1120+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1121+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1122+ * GNU General Public License for more details.
1123+ *
1124+ * You should have received a copy of the GNU General Public License
1125+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1126+ *
1127+ * Author: Pete Woods <pete.woods@canonical.com>
1128+ */
1129+
1130+#include "../InfographicModelPrivate.h"
1131+
1132+namespace QLightDM
1133+{
1134+
1135+void InfographicModelPrivate::generateFakeData()
1136+{
1137+ std::default_random_engine generator;
1138+ std::normal_distribution<qreal> distribution(0.5, 0.2);
1139+ auto rand = std::bind(distribution, generator);
1140+
1141+ QColor orange = QColor::fromRgbF(0.9, 0.3, 0.1, 1.0);
1142+ QColor yellow = QColor::fromRgbF(1.0, 0.6, 0.0, 1.0);
1143+ QColor red = QColor::fromRgbF(0.8, 0.0, 0.0, 1.0);
1144+ QColor darkPurple = QColor::fromRgbF(0.5, 0.2, 0.3, 1.0);
1145+ QColor lightPurple = QColor::fromRgbF(0.8, 0.1, 0.8, 1.0);
1146+ QColor pink(QColor::fromRgbF(0.75, 0.13, 0.75));
1147+
1148+ InfographicColorTheme orangeTheme(orange, orange, orange);
1149+ InfographicColorTheme yellowTheme(yellow, yellow, yellow);
1150+ InfographicColorTheme redTheme(red, red, red);
1151+ InfographicColorTheme darkPurpleTheme(darkPurple, darkPurple, darkPurple);
1152+ InfographicColorTheme lightPurpleTheme(lightPurple, lightPurple,
1153+ lightPurple);
1154+ InfographicColorTheme pinkTheme(pink, pink, pink);
1155+
1156+ {
1157+ QVariantList firstMonth;
1158+ while (firstMonth.size() < 17)
1159+ firstMonth.push_back(QVariant(rand()));
1160+ while (firstMonth.size() < 31)
1161+ firstMonth.push_back(QVariant());
1162+ QVariantList secondMonth;
1163+ while (secondMonth.size() < 31)
1164+ secondMonth.push_back(QVariant(rand()));
1165+ QSharedPointer<InfographicData> data(
1166+ new InfographicData("<b>5km</b> travelled", yellowTheme,
1167+ firstMonth, orangeTheme, secondMonth, this));
1168+ m_fakeData.insert("has-pin", data);
1169+ }
1170+}
1171+
1172+}
1173
1174=== added file 'tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp'
1175--- tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp 1970-01-01 00:00:00 +0000
1176+++ tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp 2013-06-05 16:11:30 +0000
1177@@ -0,0 +1,33 @@
1178+/*
1179+ * Copyright (C) 2013 Canonical, Ltd.
1180+ *
1181+ * This program is free software; you can redistribute it and/or modify
1182+ * it under the terms of the GNU General Public License as published by
1183+ * the Free Software Foundation; version 3.
1184+ *
1185+ * This program is distributed in the hope that it will be useful,
1186+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1187+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1188+ * GNU General Public License for more details.
1189+ *
1190+ * You should have received a copy of the GNU General Public License
1191+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1192+ *
1193+ * Author: Michael Terry <michael.terry@canonical.com>
1194+ */
1195+
1196+#include "../UsersModelPrivate.h"
1197+
1198+namespace QLightDM
1199+{
1200+
1201+UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
1202+ : q_ptr(parent)
1203+{
1204+ entries =
1205+ {
1206+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
1207+ };
1208+}
1209+
1210+}
1211
1212=== modified file 'tests/qmltests/CMakeLists.txt'
1213--- tests/qmltests/CMakeLists.txt 2013-06-05 11:06:52 +0000
1214+++ tests/qmltests/CMakeLists.txt 2013-06-05 16:11:30 +0000
1215@@ -47,6 +47,8 @@
1216 ${CMAKE_BINARY_DIR}/tests/mocks)
1217 add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
1218 add_qml_test(Dash/People PeopleFilterGrid IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
1219+add_qml_test(Greeter Lockscreen IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
1220+ PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
1221 add_qml_test(Greeter Tablet IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
1222 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
1223 add_qml_test(Greeter Phone IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
1224
1225=== added file 'tests/qmltests/Greeter/tst_Lockscreen.qml'
1226--- tests/qmltests/Greeter/tst_Lockscreen.qml 1970-01-01 00:00:00 +0000
1227+++ tests/qmltests/Greeter/tst_Lockscreen.qml 2013-06-05 16:11:30 +0000
1228@@ -0,0 +1,205 @@
1229+/*
1230+ * Copyright 2013 Canonical Ltd.
1231+ *
1232+ * This program is free software; you can redistribute it and/or modify
1233+ * it under the terms of the GNU General Public License as published by
1234+ * the Free Software Foundation; version 3.
1235+ *
1236+ * This program is distributed in the hope that it will be useful,
1237+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1238+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1239+ * GNU General Public License for more details.
1240+ *
1241+ * You should have received a copy of the GNU General Public License
1242+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1243+ */
1244+
1245+import QtQuick 2.0
1246+import QtTest 1.0
1247+import ".."
1248+import "../../../Greeter"
1249+import Ubuntu.Components 0.1
1250+import LightDM 0.1 as LightDM
1251+import Unity.Test 0.1 as UT
1252+
1253+Rectangle {
1254+ width: units.gu(60)
1255+ height: units.gu(80)
1256+ color: "orange"
1257+
1258+ Lockscreen {
1259+ id: lockscreen
1260+ anchors.fill: parent
1261+ anchors.rightMargin: units.gu(18)
1262+ placeholderText: "Please enter your PIN"
1263+ alphaNumeric: pinPadCheckBox.checked
1264+ pinLength: pinLengthTextField.text
1265+ username: "Lola"
1266+ }
1267+
1268+ Connections {
1269+ target: lockscreen
1270+
1271+ onEmergencyCall: emergencyCheckBox.checked = true
1272+ onUnlocked: unlockedCheckBox.checked = true
1273+ }
1274+
1275+ Connections {
1276+ target: LightDM.Greeter
1277+
1278+ onShowPrompt: {
1279+ if (text.indexOf("PIN") >= 0) {
1280+ lockscreen.alphaNumeric = false
1281+ } else {
1282+ lockscreen.alphaNumeric = true
1283+ }
1284+ lockscreen.placeholderText = text;
1285+ }
1286+ }
1287+
1288+ Rectangle {
1289+ anchors.fill: parent
1290+ anchors.leftMargin: lockscreen.width
1291+ color: "lightgray"
1292+
1293+ Column {
1294+ anchors.fill: parent
1295+ anchors.margins: units.gu(1)
1296+
1297+ Row {
1298+ CheckBox {
1299+ id: pinPadCheckBox
1300+ }
1301+ Label {
1302+ text: "Alphanumeric"
1303+ anchors.verticalCenter: parent.verticalCenter
1304+ }
1305+ }
1306+ Row {
1307+ CheckBox {
1308+ id: emergencyCheckBox
1309+ }
1310+ Label {
1311+ text: "Emergency Call"
1312+ anchors.verticalCenter: parent.verticalCenter
1313+ }
1314+ }
1315+ Row {
1316+ TextField {
1317+ id: pinLengthTextField
1318+ width: units.gu(7)
1319+ text: "4"
1320+ }
1321+ Label {
1322+ text: "PIN length"
1323+ }
1324+ }
1325+ Label {
1326+ id: pinLabel
1327+ anchors.verticalCenter: parent.verticalCenter
1328+ }
1329+ Row {
1330+ CheckBox {
1331+ id: unlockedCheckBox
1332+ }
1333+ Label {
1334+ text: "Unlocked signal"
1335+ anchors.verticalCenter: parent.verticalCenter
1336+ }
1337+ }
1338+ Button {
1339+ text: "start auth (1234)"
1340+ onClicked: LightDM.Greeter.authenticate("has-pin")
1341+ }
1342+ Button {
1343+ text: "start auth (password)"
1344+ onClicked: LightDM.Greeter.authenticate("has-password")
1345+ }
1346+ }
1347+ }
1348+
1349+ UT.UnityTestCase {
1350+ name: "Lockscreen"
1351+ when: windowShown
1352+
1353+ function test_loading_data() {
1354+ return [
1355+ {tag: "numeric", alphanumeric: false, pinPadAvailable: true },
1356+ {tag: "alphanumeric", alphanumeric: true, pinPadAvailable: false }
1357+ ]
1358+ }
1359+
1360+ function test_loading(data) {
1361+ lockscreen.alphaNumeric = data.alphanumeric
1362+ waitForRendering(lockscreen)
1363+ if (data.pinPadAvailable) {
1364+ compare(findChild(lockscreen, "pinPadButton8").text, "8", "Could not find number 8 on PinPad")
1365+ } else {
1366+ compare(findChild(lockscreen, "pinPadButton8"), undefined, "Could find number 8 on PinPad even though it should be only OSK")
1367+ }
1368+ }
1369+
1370+ function test_emergency_call_data() {
1371+ return [
1372+ {tag: "numeric", alphanumeric: false },
1373+ {tag: "alphanumeric", alphanumeric: true }
1374+ ]
1375+ }
1376+
1377+ function test_emergency_call(data) {
1378+ emergencyCheckBox.checked = false
1379+ lockscreen.alphaNumeric = data.alphanumeric
1380+ waitForRendering(lockscreen)
1381+ var emergencyButton = findChild(lockscreen, "emergencyCallIcon")
1382+ mouseClick(emergencyButton, units.gu(1), units.gu(1))
1383+ tryCompare(emergencyCheckBox, "checked", true)
1384+
1385+ }
1386+
1387+ function test_labels_data() {
1388+ return [
1389+ {tag: "numeric", alphanumeric: false, placeholderText: "Please enter your PIN", username: "foobar" },
1390+ {tag: "alphanumeric", alphanumeric: true, placeholderText: "Please enter your password", username: "Lola" }
1391+ ]
1392+ }
1393+
1394+ function test_labels(data) {
1395+ lockscreen.alphaNumeric = data.alphanumeric
1396+ lockscreen.placeholderText = data.placeholderText
1397+ waitForRendering(lockscreen)
1398+ compare(findChild(lockscreen, "pinentryField").placeholderText, data.placeholderText, "Placeholdertext is not what it should be")
1399+ if (data.alphanumeric) {
1400+ compare(findChild(lockscreen, "greeterLabel").text, "Hello " + data.username, "Greeter is not set correctly")
1401+ }
1402+ }
1403+
1404+
1405+ function test_unlock_data() {
1406+ return [
1407+ {tag: "numeric", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true},
1408+ {tag: "alphanumeric", alphanumeric: true, username: "has-password", password: "password", unlockedSignal: true},
1409+ {tag: "numeric (wrong)", alphanumeric: false, username: "has-pin", password: "4321", unlockedSignal: false},
1410+ {tag: "alphanumeric (wrong)", alphanumeric: true, username: "has-password", password: "drowssap", unlockedSignal: false},
1411+ ]
1412+ }
1413+
1414+ function test_unlock(data) {
1415+ unlockedCheckBox.checked = false
1416+ LightDM.Greeter.authenticate(data.username)
1417+
1418+ if (data.alphanumeric) {
1419+ var inputField = findChild(lockscreen, "pinentryField")
1420+ mouseClick(inputField, units.gu(1), units.gu(1))
1421+ typeString(data.password)
1422+ keyClick(Qt.Key_Enter)
1423+ } else {
1424+ for (var i = 0; i < data.password.length; ++i) {
1425+ var character = data.password.charAt(i)
1426+ var button = findChild(lockscreen, "pinPadButton" + character)
1427+ mouseClick(button, units.gu(1), units.gu(1))
1428+ }
1429+ }
1430+ tryCompare(unlockedCheckBox, "checked", data.unlockedSignal)
1431+ }
1432+ }
1433+}

Subscribers

People subscribed via source and target branches