Merge lp:~unity-team/unity/phablet-pinlock into lp:unity/phablet
- phablet-pinlock
- Merge into phablet
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 |
Related bugs: |
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
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
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.
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.
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
> 670 + LightDM.
> 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(
> Greeter:
>
> 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(
> 724 + Q_EMIT q->showPrompt(
> Greeter:
>
> 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.
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.
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
723 - Q_EMIT q->showPrompt(
724 + Q_EMIT q->showPrompt(
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.
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 701. By Michael Zanetti
-
don't go to fullscreen mode as long as the lockscreen is here
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 702. By Michael Zanetti
-
reset lockscreen when greeter activates
- 703. By Michael Zanetti
-
make it translateable
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 704. By Michael Zanetti
-
remove debug echo
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 705. By Michael Zanetti
-
fix whitespaces
- 706. By Michael Zanetti
-
update usage() of run_on_device
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:705
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 707. By Michael Zanetti
-
fix getopts short args
- 708. By Michael Zanetti
-
remove unused imports
- 709. By Michael Zanetti
-
abstract WrongPasswordAn
imation
MichaĆ Sawicz (saviq) wrote : | # |
84 + function reset() {
85 + pinPadLoader.
86 + pinPadLoader.
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.placeholde
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.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:708
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:709
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 710. By Michael Zanetti
-
fix some coding style issues
Michael Zanetti (mzanetti) wrote : | # |
> 84 + function reset() {
> 85 + pinPadLoader.
> 86 + pinPadLoader.
> 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.placeholde
> 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.
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.
- 711. By Michael Zanetti
-
fix whitespace issues again
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:710
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:711
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 712. By Michael Zanetti
-
added missing copyright header
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:712
http://
Executed test runs:
None: http://
None: http://
None: http://
None: http://
Click here to trigger a rebuild:
http://
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.
569 + LightDM.
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.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:712
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:712
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:712
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:712
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
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 WrongPasswordAn
imation - 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
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 | +} |
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"){ "Please enter your PIN:", Greeter: :PromptTypeSecr et);
716 + Q_EMIT q->showPrompt(
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: :PromptTypeSecr et); "Please enter your password:", Greeter: :PromptTypeSecr et);
724 + Q_EMIT q->showPrompt(
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).