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
Diff against target: 1936 lines (+1298/-173)
35 files modified
Greeter/Greeter.qml (+2/-2)
Greeter/Lockscreen.qml (+142/-0)
Greeter/PassphraseLockscreen.qml (+107/-0)
Greeter/PinLockscreen.qml (+131/-0)
Greeter/PinPadButton.qml (+60/-0)
Shell.qml (+45/-7)
cmake/modules/QmlTest.cmake (+2/-1)
plugins/LightDM/CMakeLists.txt (+1/-1)
run (+18/-2)
run_on_device (+18/-5)
tests/autopilot/qml_phone_shell/tests/__init__.py (+4/-2)
tests/autopilot/qml_phone_shell/tests/testcases.py (+4/-4)
tests/mocks/LightDM/CMakeLists.txt (+6/-1)
tests/mocks/LightDM/demo/CMakeLists.txt (+1/-0)
tests/mocks/LightDM/demo/GreeterPrivate.cpp (+3/-10)
tests/mocks/LightDM/demo/InfographicModelPrivate.cpp (+3/-118)
tests/mocks/LightDM/demo/UsersModelPrivate.cpp (+1/-5)
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/mocks/LightDM/single/CMakeLists.txt (+20/-0)
tests/mocks/LightDM/single/GreeterPrivate.cpp (+48/-0)
tests/mocks/LightDM/single/InfographicModelPrivate.cpp (+28/-0)
tests/mocks/LightDM/single/UsersModelPrivate.cpp (+33/-0)
tests/qmltests/CMakeLists.txt (+5/-1)
tests/qmltests/Greeter/tst_Lockscreen.qml (+205/-0)
tests/qmltests/Greeter/tst_Phone.qml (+62/-0)
tests/qmltests/Greeter/tst_Tablet.qml (+5/-13)
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
Unity Team Pending
Review via email: mp+165924@code.launchpad.net

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

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

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 :

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 :

<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 :

> 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 :

> <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 :

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.

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

revert accidental change

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

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)
lp:~unity-team/unity/phablet-pinlock updated
694. By Michael Zanetti

merge trunk

695. By Michael Zanetti

always show password lockscreen (temporary)

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

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)
lp:~unity-team/unity/phablet-pinlock updated
696. By Michael Zanetti

added single user lightdm backend

use that by default, add -d to select demo one

697. By Michael Zanetti

revert to defaulting to the demo users

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

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 :

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)
lp:~unity-team/unity/phablet-pinlock updated
698. By Michael Zanetti

merge with mterry's single user branch

699. By Michael Zanetti

merge mterry single user branch

700. By Michael Zanetti

added a PIN test lib and a passphrase test lib

added -p and -k to run them

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/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)
lp:~unity-team/unity/phablet-pinlock updated
701. By Michael Zanetti

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

702. By Michael Zanetti

reset lockscreen when greeter activates

703. By Michael Zanetti

make it translateable

704. By Michael Zanetti

remove debug echo

705. By Michael Zanetti

fix whitespaces

706. By Michael Zanetti

update usage() of run_on_device

707. By Michael Zanetti

fix getopts short args

708. By Michael Zanetti

remove unused imports

709. By Michael Zanetti

abstract WrongPasswordAnimation

710. By Michael Zanetti

fix some coding style issues

711. By Michael Zanetti

fix whitespace issues again

712. By Michael Zanetti

added missing copyright header

Revision history for this message
Michael Terry (mterry) wrote :

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.

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=== modified file 'Greeter/Greeter.qml'
2--- Greeter/Greeter.qml 2013-05-20 11:05:59 +0000
3+++ Greeter/Greeter.qml 2013-06-03 18:14:27 +0000
4@@ -27,8 +27,8 @@
5 property alias model: greeterContentLoader.model
6 property bool locked: shown && multiUser && !greeterContentLoader.promptless
7
8- readonly property bool narrowMode: width <= units.gu(60)
9- readonly property bool multiUser: !narrowMode // TODO: populate with real value
10+ readonly property bool narrowMode: !multiUser && width <= units.gu(60)
11+ readonly property bool multiUser: LightDM.Users.count > 1
12
13 readonly property bool leftTeaserPressed: greeterContentLoader.status == Loader.Ready && greeterContentLoader.item.leftTeaserPressed
14
15
16=== added file 'Greeter/Lockscreen.qml'
17--- Greeter/Lockscreen.qml 1970-01-01 00:00:00 +0000
18+++ Greeter/Lockscreen.qml 2013-06-03 18:14:27 +0000
19@@ -0,0 +1,142 @@
20+/*
21+ * Copyright (C) 2013 Canonical, Ltd.
22+ *
23+ * This program is free software; you can redistribute it and/or modify
24+ * it under the terms of the GNU General Public License as published by
25+ * the Free Software Foundation; version 3.
26+ *
27+ * This program is distributed in the hope that it will be useful,
28+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30+ * GNU General Public License for more details.
31+ *
32+ * You should have received a copy of the GNU General Public License
33+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
34+ */
35+
36+import QtQuick 2.0
37+import QtGraphicalEffects 1.0
38+import Ubuntu.Components 0.1
39+import "../Components"
40+import LightDM 0.1 as LightDM
41+
42+Showable {
43+ id: root
44+
45+ // Determine if a numeric or alphanumeric pad is used.
46+ property bool alphaNumeric: false
47+
48+ // Placeholder text
49+ property string placeholderText: ""
50+
51+ // In case the Lockscreen can show a greeter message, this is the username
52+ property string username: ""
53+
54+ // As the numeric PIN pad doesn't have a OK button by design, we need to auto-confirm on a certain length.
55+ // This is ignored by the alphaNumeric lockscreen as that one is confirmed with pressing enter on the OSK.
56+ property int pinLength: 4
57+
58+ property url background: ""
59+
60+ signal unlocked()
61+ signal cancel()
62+ signal emergencyCall()
63+
64+ Image {
65+ anchors.fill: parent
66+ source: root.required ? root.background : ""
67+ }
68+
69+ MouseArea {
70+ anchors.fill: root
71+ }
72+
73+ Loader {
74+ id: pinPadLoader
75+ objectName: "pinPadLoader"
76+ anchors {
77+ left: parent.left
78+ right: parent.right
79+ verticalCenter: parent.verticalCenter
80+ verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : 0
81+ }
82+
83+ source: root.alphaNumeric ? "PassphraseLockscreen.qml" : "PinLockscreen.qml"
84+
85+ Connections {
86+ target: pinPadLoader.item
87+
88+ onEntered: {
89+ LightDM.Greeter.respond(passphrase);
90+ }
91+
92+ onCancel: {
93+ root.cancel()
94+ }
95+ }
96+
97+ Binding {
98+ target: pinPadLoader.item
99+ property: "pinLength"
100+ value: root.pinLength
101+ }
102+ Binding {
103+ target: pinPadLoader.item
104+ property: "placeholderText"
105+ value: root.placeholderText
106+ }
107+ Binding {
108+ target: pinPadLoader.item
109+ property: "username"
110+ value: root.username
111+ }
112+ }
113+
114+ Column {
115+ anchors {
116+ left: parent.left
117+ top: pinPadLoader.bottom
118+ topMargin: units.gu(4)
119+ right: parent.right
120+ bottom: parent.bottom
121+ }
122+ spacing: units.gu(1)
123+ Icon {
124+ objectName: "emergencyCallIcon"
125+ height: units.gu(3)
126+ width: height
127+ anchors.horizontalCenter: parent.horizontalCenter
128+ name: "phone-app-call-symbolic"
129+ color: "white"
130+ opacity: 0.9
131+
132+ MouseArea {
133+ anchors.fill: parent
134+ onClicked: root.emergencyCall()
135+ }
136+ }
137+ Label {
138+ text: "Emergency call"
139+ color: "white"
140+ opacity: 0.9
141+ fontSize: "medium"
142+ anchors.horizontalCenter: parent.horizontalCenter
143+ }
144+ }
145+
146+ Connections {
147+ target: LightDM.Greeter
148+
149+ onAuthenticationComplete: {
150+ if (LightDM.Greeter.promptless) {
151+ return;
152+ }
153+ if (LightDM.Greeter.authenticated) {
154+ root.unlocked();
155+ pinPadLoader.item.clear(false);
156+ } else {
157+ pinPadLoader.item.clear(true);
158+ }
159+ }
160+ }
161+}
162
163=== added file 'Greeter/PassphraseLockscreen.qml'
164--- Greeter/PassphraseLockscreen.qml 1970-01-01 00:00:00 +0000
165+++ Greeter/PassphraseLockscreen.qml 2013-06-03 18:14:27 +0000
166@@ -0,0 +1,107 @@
167+/*
168+ * Copyright (C) 2013 Canonical, Ltd.
169+ *
170+ * This program is free software; you can redistribute it and/or modify
171+ * it under the terms of the GNU General Public License as published by
172+ * the Free Software Foundation; version 3.
173+ *
174+ * This program is distributed in the hope that it will be useful,
175+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
176+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
177+ * GNU General Public License for more details.
178+ *
179+ * You should have received a copy of the GNU General Public License
180+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
181+ */
182+
183+import QtQuick 2.0
184+import Ubuntu.Components 0.1
185+
186+Item {
187+ id: root
188+ height: highlightItem.height
189+
190+ property alias placeholderText: pinentryField.placeholderText
191+ property string username: ""
192+
193+ signal entered(string passphrase)
194+ signal cancel()
195+
196+ function clear(playAnimation) {
197+ pinentryField.text = "";
198+ if (playAnimation) {
199+ wrongPasswordAnimation.start();
200+ } else {
201+ pinentryField.focus = false
202+ }
203+ }
204+
205+ Rectangle {
206+ id: highlightItem
207+ width: units.gu(32)
208+ height: units.gu(10)
209+ anchors.centerIn: parent
210+ color: Qt.rgba(0.1, 0.1, 0.1, 0.4)
211+ border.color: Qt.rgba(0.4, 0.4, 0.4, 0.4)
212+ border.width: units.dp(1)
213+ radius: units.gu(1.5)
214+ antialiasing: true
215+
216+ Label {
217+ objectName: "greeterLabel"
218+ anchors {
219+ left: parent.left
220+ top: parent.top
221+ right: parent.right
222+ margins: units.gu(1.5)
223+ }
224+ text: root.username.length > 0 ? "Hello %1".arg(root.username) : ""
225+ color: "white"
226+ }
227+
228+ TextField {
229+ id: pinentryField
230+ objectName: "pinentryField"
231+ anchors {
232+ horizontalCenter: parent.horizontalCenter
233+ bottom: parent.bottom
234+ margins: units.gu(1)
235+ }
236+ height: units.gu(4.5)
237+ width: parent.width - units.gu(2)
238+ echoMode: TextInput.Password
239+ opacity: 0.9
240+ hasClearButton: false
241+
242+ onAccepted: {
243+ root.entered(pinentryField.text);
244+ }
245+ }
246+ }
247+
248+ SequentialAnimation {
249+ id: wrongPasswordAnimation
250+ NumberAnimation {
251+ target: pinentryField
252+ property: "anchors.horizontalCenterOffset"
253+ duration: 50
254+ easing.type: Easing.InQuad
255+ to: units.gu(2)
256+ }
257+ NumberAnimation {
258+ target: pinentryField
259+ property: "anchors.horizontalCenterOffset"
260+ duration: 100
261+ easing.type: Easing.InOutQuad
262+ to: -units.gu(2)
263+ }
264+ NumberAnimation {
265+ target: pinentryField
266+ easing.type: Easing.OutElastic
267+ properties: "anchors.horizontalCenterOffset"
268+ to: 0
269+ duration: 400
270+ easing.overshoot: units.gu(2)
271+ }
272+ }
273+}
274
275=== added file 'Greeter/PinLockscreen.qml'
276--- Greeter/PinLockscreen.qml 1970-01-01 00:00:00 +0000
277+++ Greeter/PinLockscreen.qml 2013-06-03 18:14:27 +0000
278@@ -0,0 +1,131 @@
279+/*
280+ * Copyright (C) 2013 Canonical, Ltd.
281+ *
282+ * This program is free software; you can redistribute it and/or modify
283+ * it under the terms of the GNU General Public License as published by
284+ * the Free Software Foundation; version 3.
285+ *
286+ * This program is distributed in the hope that it will be useful,
287+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
288+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
289+ * GNU General Public License for more details.
290+ *
291+ * You should have received a copy of the GNU General Public License
292+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
293+ */
294+
295+import QtQuick 2.0
296+import Ubuntu.Components 0.1
297+
298+Column {
299+ id: root
300+ anchors.centerIn: parent
301+ spacing: units.gu(2.5)
302+
303+ property alias placeholderText: pinentryField.placeholderText
304+ property int padWidth: units.gu(32)
305+ property int pinLength: 4
306+
307+ signal entered(string passphrase)
308+ signal cancel()
309+
310+ function clear(playAnimation) {
311+ pinentryField.text = "";
312+ if (playAnimation) {
313+ wrongPasswordAnimation.start();
314+ }
315+ }
316+
317+ TextField {
318+ id: pinentryField
319+ objectName: "pinentryField"
320+ anchors.horizontalCenter: parent.horizontalCenter
321+ width: units.gu(32)
322+ height: units.gu(5)
323+ echoMode: TextInput.Password
324+ font.pixelSize: units.dp(44)
325+ color: "white"
326+ opacity: 0.9
327+ hasClearButton: false
328+ horizontalAlignment: Text.AlignHCenter
329+
330+ onTextChanged: {
331+ if (pinentryField.text.length === root.pinLength) {
332+ root.entered(pinentryField.text);
333+ }
334+ }
335+
336+ // Using a MouseArea to eat clicks. We don't want to disable the TextField for styling reasons
337+ MouseArea {
338+ anchors.fill: parent
339+ }
340+ }
341+
342+ Grid {
343+ anchors {
344+ left: parent.left
345+ right: parent.right
346+ margins: (parent.width - root.padWidth) / 2
347+ }
348+
349+ columns: 3
350+ spacing: units.gu(1)
351+
352+ Repeater {
353+ model: 9
354+
355+ PinPadButton {
356+ objectName: "pinPadButton" + (index + 1)
357+ text: index + 1
358+
359+ onClicked: {
360+ pinentryField.text = pinentryField.text + text
361+ }
362+ }
363+ }
364+
365+ PinPadButton {
366+ objectName: "pinPadButtonBack"
367+ iconName: "back"
368+ onClicked: root.cancel();
369+
370+ }
371+ PinPadButton {
372+ objectName: "pinPadButton0"
373+ text: "0"
374+ onClicked: pinentryField.text = pinentryField.text + text
375+
376+ }
377+ PinPadButton {
378+ objectName: "pinPadButtonErase"
379+ iconName: "erase"
380+ onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
381+ }
382+ }
383+
384+ SequentialAnimation {
385+ id: wrongPasswordAnimation
386+ NumberAnimation {
387+ target: pinentryField
388+ property: "anchors.horizontalCenterOffset"
389+ duration: 50
390+ easing.type: Easing.InQuad
391+ to: units.gu(2)
392+ }
393+ NumberAnimation {
394+ target: pinentryField
395+ property: "anchors.horizontalCenterOffset"
396+ duration: 100
397+ easing.type: Easing.InOutQuad
398+ to: -units.gu(2)
399+ }
400+ NumberAnimation {
401+ target: pinentryField
402+ easing.type: Easing.OutElastic
403+ properties: "anchors.horizontalCenterOffset"
404+ to: 0
405+ duration: 400
406+ easing.overshoot: units.gu(2)
407+ }
408+ }
409+}
410
411=== added file 'Greeter/PinPadButton.qml'
412--- Greeter/PinPadButton.qml 1970-01-01 00:00:00 +0000
413+++ Greeter/PinPadButton.qml 2013-06-03 18:14:27 +0000
414@@ -0,0 +1,60 @@
415+/*
416+ * Copyright (C) 2013 Canonical, Ltd.
417+ *
418+ * This program is free software; you can redistribute it and/or modify
419+ * it under the terms of the GNU General Public License as published by
420+ * the Free Software Foundation; version 3.
421+ *
422+ * This program is distributed in the hope that it will be useful,
423+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
424+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
425+ * GNU General Public License for more details.
426+ *
427+ * You should have received a copy of the GNU General Public License
428+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
429+ */
430+
431+import QtQuick 2.0
432+import Ubuntu.Components 0.1
433+
434+UbuntuShape {
435+ id: root
436+ width: units.gu(10)
437+ height: units.gu(7)
438+ radius: "medium"
439+
440+ property alias text: label.text
441+ property alias iconName: icon.name
442+
443+ signal clicked()
444+
445+ Behavior on color {
446+ ColorAnimation { duration: 100 }
447+ }
448+
449+ Label {
450+ id: label
451+ anchors.centerIn: parent
452+ color: "white"
453+ fontSize: "x-large"
454+ font.weight: Font.Light
455+ opacity: 0.9
456+ }
457+
458+ Icon {
459+ id: icon
460+ height: units.gu(3)
461+ width: height
462+ anchors.centerIn: parent
463+ color: "white"
464+ opacity: 0.9
465+ }
466+
467+ MouseArea {
468+ anchors.fill: parent
469+ onClicked: root.clicked()
470+ onPressed: root.color = Qt.rgba(0, 0, 0, 0.3)
471+ onReleased: root.color = Qt.rgba(0, 0, 0, 0)
472+ }
473+}
474+
475
476=== modified file 'Shell.qml'
477--- Shell.qml 2013-06-03 08:29:01 +0000
478+++ Shell.qml 2013-06-03 18:14:27 +0000
479@@ -17,6 +17,7 @@
480 import QtQuick 2.0
481 import Ubuntu.Application 0.1
482 import Ubuntu.Components 0.1
483+import QtGraphicalEffects 1.0
484 import LightDM 0.1 as LightDM
485 import "Dash"
486 import "Greeter"
487@@ -124,7 +125,6 @@
488
489 Item {
490 id: underlay
491-
492 anchors.fill: parent
493 visible: !(panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth)
494 && (stages.fullyHidden
495@@ -148,7 +148,7 @@
496 Dash {
497 id: dash
498
499- available: !greeter.shown
500+ available: !greeter.shown && !lockscreen.shown
501 hides: [stages, launcher, panel.indicators]
502 shown: disappearingAnimationProgress !== 1.0
503 enabled: disappearingAnimationProgress === 0.0
504@@ -301,7 +301,7 @@
505 && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
506 shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
507
508- available: !greeter.shown && enabled
509+ available: !greeter.shown && !lockscreen.shown && enabled
510 hides: [launcher, panel.indicators]
511 shown: false
512 showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
513@@ -352,6 +352,40 @@
514 orientation: Qt.Horizontal
515 }
516
517+ Lockscreen {
518+ id: lockscreen
519+ hides: [launcher, panel.indicators, hud]
520+ shown: false
521+ enabled: true
522+ showAnimation: StandardAnimation { property: "opacity"; to: 1 }
523+ hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
524+ y: panel.panelHeight
525+ x: required ? 0 : - width
526+ width: parent.width
527+ height: parent.height - panel.panelHeight
528+ background: shell.background
529+
530+ onUnlocked: lockscreen.hide()
531+ onCancel: greeter.show()
532+
533+ Component.onCompleted: LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
534+ }
535+
536+ Connections {
537+ target: LightDM.Greeter
538+
539+ onShowPrompt: {
540+ // TODO: There's no better way for now to determine if its a PIN or a passphrase.
541+ if (text == "PIN") {
542+ lockscreen.alphaNumeric = false
543+ } else {
544+ lockscreen.alphaNumeric = true
545+ }
546+ lockscreen.placeholderText = "Please enter %1:".arg(text);
547+ lockscreen.show();
548+ }
549+ }
550+
551 Greeter {
552 id: greeter
553
554@@ -360,7 +394,6 @@
555 shown: true
556 showAnimation: StandardAnimation { property: "x"; to: greeterRevealer.openedValue }
557 hideAnimation: StandardAnimation { property: "x"; to: greeterRevealer.closedValue }
558-
559 y: panel.panelHeight
560 width: parent.width
561 height: parent.height - panel.panelHeight
562@@ -370,6 +403,11 @@
563
564 onShownChanged: {
565 if (shown) {
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+ }
571 greeter.forceActiveFocus();
572 // FIXME: *FocusedApplication are not updated when unfocused, hence the need to check whether
573 // the stage was actually shown
574@@ -397,7 +435,7 @@
575
576 InputFilterArea {
577 anchors.fill: parent
578- blockInput: greeter.shown
579+ blockInput: greeter.shown || lockscreen.shown
580 }
581
582 Revealer {
583@@ -426,7 +464,7 @@
584 hides: [launcher]
585 }
586 fullscreenMode: shell.fullscreenMode
587- searchVisible: !greeter.shown
588+ searchVisible: !greeter.shown && !lockscreen.shown
589
590 InputFilterArea {
591 anchors.fill: parent
592@@ -440,7 +478,7 @@
593 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
594 height: parent.height
595
596- available: !greeter.shown && !panel.indicators.shown
597+ available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown
598 shown: false
599 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
600 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
601
602=== modified file 'cmake/modules/QmlTest.cmake'
603--- cmake/modules/QmlTest.cmake 2013-04-22 14:30:45 +0000
604+++ cmake/modules/QmlTest.cmake 2013-06-03 18:14:27 +0000
605@@ -23,7 +23,7 @@
606
607 macro(add_qml_test SUBPATH COMPONENT_NAME)
608 set(options NO_ADD_TEST NO_TARGETS)
609- set(multi_value_keywords IMPORT_PATHS TARGETS PROPERTIES)
610+ set(multi_value_keywords IMPORT_PATHS TARGETS PROPERTIES ENVIRONMENT)
611
612 cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})
613
614@@ -44,6 +44,7 @@
615 endif()
616
617 set(qmltest_command
618+ env ${qmltest_ENVIRONMENT}
619 ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
620 ${qmltestrunner_imports}
621 -o ${CMAKE_BINARY_DIR}/${qmltest_TARGET}.xml,xunitxml
622
623=== modified file 'plugins/LightDM/CMakeLists.txt'
624--- plugins/LightDM/CMakeLists.txt 2013-05-28 10:26:22 +0000
625+++ plugins/LightDM/CMakeLists.txt 2013-06-03 18:14:27 +0000
626@@ -40,4 +40,4 @@
627
628 install(FILES qmldir
629 DESTINATION ${SHELL_APP_DIR}/plugins/LightDM
630- )
631\ No newline at end of file
632+ )
633
634=== modified file 'run'
635--- run 2013-05-28 09:32:03 +0000
636+++ run 2013-06-03 18:14:27 +0000
637@@ -4,6 +4,8 @@
638 export LD_LIBRARY_PATH=$PWD/../unity_build/build/lib
639 GDB=false
640 FAKE=false
641+PINLOCK=false
642+KEYLOCK=false
643 MOUSE_TOUCH=true
644
645 usage() {
646@@ -11,6 +13,8 @@
647 echo "Script to run the shell.\n" >&2
648 echo "OPTIONS:" >&2
649 echo " -f, --fake Force use of fake Qml modules." >&2
650+ echo " -p, --pinlock Use a pin protected user." >&2
651+ echo " -k, --keylock Use a passphrase protected user." >&2
652 echo " -g, --gdb Run through gdb." >&2
653 echo " -h, --help Show this help." >&2
654 echo " -m, --nomousetouch Run without -mousetouch argument." >&2
655@@ -18,7 +22,7 @@
656 exit 1
657 }
658
659-ARGS=`getopt -n$0 -u -a --longoptions="fake,gdb,help,nomousetouch" -o "fghm" -- "$@"`
660+ARGS=`getopt -n$0 -u -a --longoptions="fake,pinlock,keylock,gdb,help,nomousetouch" -o "fghm" -- "$@"`
661 [ $? -ne 0 ] && usage
662 eval set -- "$ARGS"
663
664@@ -26,6 +30,8 @@
665 do
666 case "$1" in
667 -f|--fake) FAKE=true;;
668+ -p|--pinlock) PINLOCK=true;;
669+ -k|--keylock) KEYLOCK=true;;
670 -g|--gdb) GDB=true;;
671 -h|--help) usage;;
672 -m|--nomousetouch) MOUSE_TOUCH=false;;
673@@ -36,7 +42,17 @@
674
675 if $FAKE; then
676 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
677- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/full
678+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single
679+fi
680+
681+if $PINLOCK; then
682+ export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
683+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single-pin
684+fi
685+
686+if $KEYLOCK; then
687+ export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
688+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single-passphrase
689 fi
690
691 # Force icon theme if running on the desktop, otherwise gnome theme (if running
692
693=== modified file 'run_on_device'
694--- run_on_device 2013-05-29 08:21:31 +0000
695+++ run_on_device 2013-06-03 18:14:27 +0000
696@@ -11,6 +11,8 @@
697 RUN_OPTIONS=-qmljsdebugger=port:$TARGET_DEBUG_PORT
698 SETUP=false
699 GDB=false
700+PINLOCK=false
701+KEYLOCK=false
702 SUDO="echo $PASSWORD | sudo -S"
703 NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
704
705@@ -83,11 +85,20 @@
706 adb shell "chroot /data/ubuntu /usr/bin/service ubuntu-session restart"
707 fi
708 adb shell pkill $BINARY
709+ ARGS="--nomousetouch"
710 if $GDB; then
711- exec_with_ssh "cd $CODE_DIR/ && ./run --gdb --nomousetouch -- $RUN_OPTIONS"
712- else
713- exec_with_ssh "cd $CODE_DIR && ./run --nomousetouch -- $RUN_OPTIONS"
714- fi
715+ ARGS="$ARGS --gdb"
716+ fi
717+ if $PINLOCK; then
718+ ARGS="$ARGS -p"
719+ fi
720+ if $KEYLOCK; then
721+ ARGS="$ARGS -k"
722+ fi
723+
724+ echo "################################################### $ARGS"
725+ exec_with_ssh "cd $CODE_DIR/ && ./run $ARGS -- $RUN_OPTIONS"
726+
727 if [ $CONTAINS_SHELL -eq 0 ]; then
728 echo "Restoring $SERVICEFILE on device from $SERVICEFILE.backup"
729 adb shell cp $SERVICEFILE.backup $SERVICEFILE
730@@ -95,7 +106,7 @@
731 fi
732 }
733
734-set -- `getopt -n$0 -u -a --longoptions="setup,gdb,help" "sgh" "$@"`
735+set -- `getopt -n$0 -u -a --longoptions="setup,gdb,pinlock,keylock,help" "sgh" "$@"`
736
737 # FIXME: giving incorrect arguments does not call usage and exit
738 while [ $# -gt 0 ]
739@@ -103,6 +114,8 @@
740 case "$1" in
741 -s|--setup) SETUP=true;;
742 -g|--gdb) GDB=true;;
743+ -p|--pinlock) PINLOCK=true;;
744+ -k|--keylock) KEYLOCK=true;;
745 -h|--help) usage;;
746 --) shift;break;;
747 esac
748
749=== modified file 'tests/autopilot/qml_phone_shell/tests/__init__.py'
750--- tests/autopilot/qml_phone_shell/tests/__init__.py 2013-05-31 00:55:24 +0000
751+++ tests/autopilot/qml_phone_shell/tests/__init__.py 2013-06-03 18:14:27 +0000
752@@ -23,6 +23,8 @@
753
754 """A common test case class that provides several useful methods for shell tests."""
755
756+ lightdm_mock = "full"
757+
758 def setUp(self, geometry, grid_size):
759 super(ShellTestCase, self).setUp()
760 # Lets assume we are installed system wide if this file is somewhere in /usr
761@@ -37,7 +39,7 @@
762 self.launch_test_local(geometry)
763
764 def launch_test_local(self, geometry):
765- os.environ['LD_LIBRARY_PATH'] = "../../../unity_build/build/lib:../../builddir/tests/mocks/LightDM/full"
766+ os.environ['LD_LIBRARY_PATH'] = "../../../unity_build/build/lib:../../builddir/tests/mocks/LightDM/" + self.lightdm_mock
767 os.environ['QML2_IMPORT_PATH'] = "../../builddir/tests/mocks:../../builddir/plugins"
768 if geometry != "0x0":
769 self.app = self.launch_test_application(
770@@ -47,7 +49,7 @@
771 "../../builddir/qml-phone-shell", "-fullscreen", app_type='qt')
772
773 def launch_test_installed(self, geometry):
774- os.environ['LD_LIBRARY_PATH'] = "/usr/share/qml-phone-shell/plugins/mocks/LightDM/full"
775+ os.environ['LD_LIBRARY_PATH'] = "/usr/share/qml-phone-shell/plugins/mocks/LightDM/" + self.lightdm_mock
776 os.environ['QML2_IMPORT_PATH'] = "/usr/share/qml-phone-shell/plugins/mocks:/usr/share/qml-phone-shell/plugins"
777 if model() == 'Desktop' and geometry != "0x0":
778 self.app = self.launch_test_application(
779
780=== modified file 'tests/autopilot/qml_phone_shell/tests/testcases.py'
781--- tests/autopilot/qml_phone_shell/tests/testcases.py 2013-05-24 16:49:38 +0000
782+++ tests/autopilot/qml_phone_shell/tests/testcases.py 2013-06-03 18:14:27 +0000
783@@ -52,15 +52,15 @@
784
785 if model() == 'Desktop':
786 scenarios = [
787- ('Nexus 4', dict(app_width=768, app_height=1280, grid_unit_px=18)),
788- ('Nexus 10', dict(app_width=2560, app_height=1600, grid_unit_px=20)),
789+ ('Nexus 4', dict(app_width=768, app_height=1280, grid_unit_px=18, lightdm_mock="single")),
790+ ('Nexus 10', dict(app_width=2560, app_height=1600, grid_unit_px=20, lightdm_mock="full")),
791 # TODO: don't run fullscreen tests just yet as the VM is performing too badly for that. Enable this once
792 # Autopilot tests are running on bear metal.
793-# ('Fullscreen', dict(app_width=0, app_height=0, grid_unit_px=10)),
794+# ('Fullscreen', dict(app_width=0, app_height=0, grid_unit_px=10, lightdm_mock="full")),
795 ]
796 else:
797 scenarios = [
798- ('Fullscreen', dict(app_width=0, app_height=0, grid_unit_px=0)),
799+ ('Fullscreen', dict(app_width=0, app_height=0, grid_unit_px=0, lightdm_mock="single")),
800 ]
801
802 def setUp(self):
803
804=== modified file 'tests/mocks/LightDM/CMakeLists.txt'
805--- tests/mocks/LightDM/CMakeLists.txt 2013-05-28 10:47:02 +0000
806+++ tests/mocks/LightDM/CMakeLists.txt 2013-06-03 18:14:27 +0000
807@@ -6,6 +6,9 @@
808
809 add_subdirectory(demo)
810 add_subdirectory(full)
811+add_subdirectory(single)
812+add_subdirectory(single-pin)
813+add_subdirectory(single-passphrase)
814
815 include_directories(
816 ${CMAKE_CURRENT_SOURCE_DIR}
817@@ -27,8 +30,10 @@
818 # installed on the system. So we make sure we link to our full fake version
819 # At run time, we can point to whichever version we happen to be using via
820 # LD_LIBRARY_PATH.
821+add_dependencies(MockLightDM-qml MockLightDM-full)
822 target_link_libraries(MockLightDM-qml
823- MockLightDM-full
824+ -L${CMAKE_CURRENT_BINARY_DIR}/full
825+ -llightdm-qt5-2
826 )
827
828 qt5_use_modules(MockLightDM-qml Gui Qml)
829
830=== modified file 'tests/mocks/LightDM/demo/CMakeLists.txt'
831--- tests/mocks/LightDM/demo/CMakeLists.txt 2013-05-28 10:47:02 +0000
832+++ tests/mocks/LightDM/demo/CMakeLists.txt 2013-06-03 18:14:27 +0000
833@@ -11,3 +11,4 @@
834 add_library(MockLightDM-demo STATIC ${LibLightDM_SOURCES})
835
836 qt5_use_modules(MockLightDM-demo Gui)
837+
838
839=== modified file 'tests/mocks/LightDM/demo/GreeterPrivate.cpp'
840--- tests/mocks/LightDM/demo/GreeterPrivate.cpp 2013-05-23 18:07:17 +0000
841+++ tests/mocks/LightDM/demo/GreeterPrivate.cpp 2013-06-03 18:14:27 +0000
842@@ -33,20 +33,13 @@
843 {
844 Q_Q(Greeter);
845
846- if (authenticationUser == "guest") {
847- authenticated = true;
848- Q_EMIT q->authenticationComplete();
849- } else {
850- Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret);
851- }
852+ authenticated = true;
853+ Q_EMIT q->authenticationComplete();
854 }
855
856 void GreeterPrivate::handleRespond(const QString &response)
857 {
858- Q_Q(Greeter);
859-
860- authenticated = (response == "password");
861- Q_EMIT q->authenticationComplete();
862+ Q_UNUSED(response);
863 }
864
865 }
866
867=== modified file 'tests/mocks/LightDM/demo/InfographicModelPrivate.cpp'
868--- tests/mocks/LightDM/demo/InfographicModelPrivate.cpp 2013-06-03 11:37:02 +0000
869+++ tests/mocks/LightDM/demo/InfographicModelPrivate.cpp 2013-06-03 18:14:27 +0000
870@@ -44,20 +44,10 @@
871 colours.push_back(QColor::fromRgbF(0.63, 0.53, 0.3));
872 colours.push_back(QColor::fromRgbF(0.89, 0.56, 0.31));
873
874- colours.push_back(QColor::fromRgbF(0.17, 0.34, 0.36));
875- colours.push_back(QColor::fromRgbF(0.36, 0.54, 0.49));
876- colours.push_back(QColor::fromRgbF(0.65, 0.76, 0.64));
877-
878- colours.push_back(QColor::fromRgbF(0.21, 0.38, 0.37));
879- colours.push_back(QColor::fromRgbF(0.35, 0.49, 0.5));
880- colours.push_back(QColor::fromRgbF(0.67, 0.75, 0.82));
881-
882 InfographicColorTheme first(colours[0], colours[1], colours[2]);
883 InfographicColorTheme second(colours[3], colours[4], colours[5]);
884 InfographicColorTheme eighth(colours[6], colours[7], colours[8]);
885 InfographicColorTheme ninth(colours[9], colours[10], colours[11]);
886- InfographicColorTheme eleventh(colours[12], colours[13], colours[14]);
887- InfographicColorTheme twelfth(colours[15], colours[16], colours[17]);
888
889 {
890 QVariantList firstMonth;
891@@ -71,7 +61,7 @@
892 QSharedPointer<InfographicData> data(
893 new InfographicData("<b>52km</b> travelled", first, firstMonth,
894 ninth, secondMonth, this));
895- m_fakeData.insert("anna", data);
896+ m_fakeData.insert("guest", data);
897 }
898
899 {
900@@ -86,7 +76,7 @@
901 QSharedPointer<InfographicData> data(
902 new InfographicData("<b>33</b> messages today", second,
903 firstMonth, eighth, secondMonth, this));
904- m_fakeData.insert("anna", data);
905+ m_fakeData.insert("guest", data);
906 }
907
908 {
909@@ -101,112 +91,7 @@
910 QSharedPointer<InfographicData> data(
911 new InfographicData("<b>69</b> minutes talk time", eighth,
912 firstMonth, second, secondMonth, this));
913- m_fakeData.insert("anna", data);
914- }
915-
916- {
917- QVariantList firstMonth;
918- while (firstMonth.size() < 17)
919- firstMonth.push_back(QVariant(rand()));
920- while (firstMonth.size() < 31)
921- firstMonth.push_back(QVariant());
922- QVariantList secondMonth;
923- while (secondMonth.size() < 31)
924- secondMonth.push_back(QVariant(rand()));
925- QSharedPointer<InfographicData> data(
926- new InfographicData("<b>5km</b> travelled", ninth, firstMonth,
927- first, secondMonth, this));
928- m_fakeData.insert("lois", data);
929- }
930-
931- {
932- QVariantList firstMonth;
933- while (firstMonth.size() < 17)
934- firstMonth.push_back(QVariant(rand()));
935- while (firstMonth.size() < 31)
936- firstMonth.push_back(QVariant());
937- QVariantList secondMonth;
938- while (secondMonth.size() < 31)
939- secondMonth.push_back(QVariant(rand()));
940- QSharedPointer<InfographicData> data(
941- new InfographicData("<b>33</b> messages today", eleventh,
942- firstMonth, twelfth, secondMonth, this));
943- m_fakeData.insert("lois", data);
944- }
945-
946- {
947- QVariantList firstMonth;
948- while (firstMonth.size() < 17)
949- firstMonth.push_back(QVariant(rand()));
950- while (firstMonth.size() < 31)
951- firstMonth.push_back(QVariant());
952- QVariantList secondMonth;
953- while (secondMonth.size() < 31)
954- secondMonth.push_back(QVariant());
955- QSharedPointer<InfographicData> data(
956- new InfographicData("<b>19</b> minutes talk time", twelfth,
957- firstMonth, eleventh, secondMonth, this));
958- m_fakeData.insert("lois", data);
959- }
960-
961- {
962- QVariantList firstMonth;
963- while (firstMonth.size() < 29)
964- firstMonth.push_back(QVariant(rand()));
965- while (firstMonth.size() < 31)
966- firstMonth.push_back(QVariant());
967- QVariantList secondMonth;
968- while (secondMonth.size() < 31)
969- secondMonth.push_back(QVariant(rand()));
970- QSharedPointer<InfographicData> data(
971- new InfographicData("<b>5km</b> travelled", first, firstMonth,
972- ninth, secondMonth, this));
973- m_fakeData.insert("toomas", data);
974- }
975-
976- {
977- QVariantList firstMonth;
978- while (firstMonth.size() < 29)
979- firstMonth.push_back(QVariant(rand()));
980- while (firstMonth.size() < 31)
981- firstMonth.push_back(QVariant());
982- QVariantList secondMonth;
983- while (secondMonth.size() < 31)
984- secondMonth.push_back(QVariant(rand()));
985- QSharedPointer<InfographicData> data(
986- new InfographicData("<b>33</b> messages today", second,
987- firstMonth, eighth, secondMonth, this));
988- m_fakeData.insert("toomas", data);
989- }
990-
991- {
992- QVariantList firstMonth;
993- while (firstMonth.size() < 29)
994- firstMonth.push_back(QVariant(rand()));
995- while (firstMonth.size() < 31)
996- firstMonth.push_back(QVariant());
997- QVariantList secondMonth;
998- while (secondMonth.size() < 31)
999- secondMonth.push_back(QVariant());
1000- QSharedPointer<InfographicData> data(
1001- new InfographicData("<b>19</b> minutes talk time", eighth,
1002- firstMonth, second, secondMonth, this));
1003- m_fakeData.insert("toomas", data);
1004- }
1005-
1006- {
1007- QVariantList firstMonth;
1008- while (firstMonth.size() < 15)
1009- firstMonth.push_back(QVariant(rand()));
1010- while (firstMonth.size() < 31)
1011- firstMonth.push_back(QVariant());
1012- QVariantList secondMonth;
1013- while (secondMonth.size() < 31)
1014- secondMonth.push_back(QVariant(rand()));
1015- QSharedPointer<InfographicData> data(
1016- new InfographicData("<b>6</b>hrs watching videos today",
1017- eleventh, firstMonth, first, secondMonth, this));
1018- m_fakeData.insert("empty-name", data);
1019+ m_fakeData.insert("guest", data);
1020 }
1021 }
1022
1023
1024=== modified file 'tests/mocks/LightDM/demo/UsersModelPrivate.cpp'
1025--- tests/mocks/LightDM/demo/UsersModelPrivate.cpp 2013-05-23 18:07:17 +0000
1026+++ tests/mocks/LightDM/demo/UsersModelPrivate.cpp 2013-06-03 18:14:27 +0000
1027@@ -26,11 +26,7 @@
1028 {
1029 entries =
1030 {
1031- { "anna", "Anna Olson", 0, 0, false, false, 0, 0 },
1032- { "lois", "Lois Mcqueen", 0, 0, false, false, 0, 0 },
1033- { "lola", "Lola Chang", 0, 0, false, false, 0, 0 },
1034- { "toomas", "Toomas Vilms", 0, 0, false, false, 0, 0 },
1035- { "guest", "Guest", 0, 0, false, false, 0, 0 },
1036+ { "guest", "Guest", 0, 0, false, false, 0, 0 },
1037 };
1038 }
1039
1040
1041=== modified file 'tests/mocks/LightDM/full/GreeterPrivate.cpp'
1042--- tests/mocks/LightDM/full/GreeterPrivate.cpp 2013-05-24 13:48:29 +0000
1043+++ tests/mocks/LightDM/full/GreeterPrivate.cpp 2013-06-03 18:14:27 +0000
1044@@ -53,6 +53,8 @@
1045 if (authenticationUser == "no-password") {
1046 authenticated = true;
1047 Q_EMIT q->authenticationComplete();
1048+ } else if (authenticationUser == "has-pin"){
1049+ Q_EMIT q->showPrompt("PIN", Greeter::PromptTypeSecret);
1050 } else if (authenticationUser == "auth-error") {
1051 authenticated = false;
1052 Q_EMIT q->authenticationComplete();
1053@@ -85,7 +87,11 @@
1054 return;
1055 }
1056
1057- authenticated = (response == "password");
1058+ if (authenticationUser == "has-pin") {
1059+ authenticated = (response == "1234");
1060+ } else {
1061+ authenticated = (response == "password");
1062+ }
1063 Q_EMIT q->authenticationComplete();
1064 }
1065
1066
1067=== modified file 'tests/mocks/LightDM/full/UsersModelPrivate.cpp'
1068--- tests/mocks/LightDM/full/UsersModelPrivate.cpp 2013-05-23 19:53:33 +0000
1069+++ tests/mocks/LightDM/full/UsersModelPrivate.cpp 2013-06-03 18:14:27 +0000
1070@@ -27,6 +27,7 @@
1071 entries =
1072 {
1073 { "has-password", "Has Password", 0, 0, false, false, 0, 0 },
1074+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
1075 { "different-prompt", "Different Prompt", 0, 0, false, false, 0, 0 },
1076 { "no-password", "No Password", 0, 0, false, false, 0, 0 },
1077 { "auth-error", "Auth Error", 0, 0, false, false, 0, 0 },
1078
1079=== added directory 'tests/mocks/LightDM/single'
1080=== added directory 'tests/mocks/LightDM/single-passphrase'
1081=== added file 'tests/mocks/LightDM/single-passphrase/CMakeLists.txt'
1082--- tests/mocks/LightDM/single-passphrase/CMakeLists.txt 1970-01-01 00:00:00 +0000
1083+++ tests/mocks/LightDM/single-passphrase/CMakeLists.txt 2013-06-03 18:14:27 +0000
1084@@ -0,0 +1,21 @@
1085+set(LibLightDM_SOURCES
1086+ ../Greeter.cpp
1087+ ../UsersModel.cpp
1088+ ../InfographicModel.cpp
1089+ GreeterPrivate.cpp
1090+ UsersModelPrivate.cpp
1091+ InfographicModelPrivate.cpp
1092+ ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
1093+ )
1094+
1095+
1096+add_library(MockLightDM-single-passphrase SHARED ${LibLightDM_SOURCES})
1097+
1098+qt5_use_modules(MockLightDM-single-passphrase Gui)
1099+
1100+set_target_properties(MockLightDM-single-passphrase PROPERTIES
1101+ OUTPUT_NAME lightdm-qt5-2)
1102+
1103+install(TARGETS MockLightDM-single-passphrase
1104+ DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/single-passphrase
1105+ )
1106
1107=== added file 'tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp'
1108--- tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp 1970-01-01 00:00:00 +0000
1109+++ tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp 2013-06-03 18:14:27 +0000
1110@@ -0,0 +1,53 @@
1111+/*
1112+ * Copyright (C) 2013 Canonical, Ltd.
1113+ *
1114+ * This program is free software; you can redistribute it and/or modify
1115+ * it under the terms of the GNU General Public License as published by
1116+ * the Free Software Foundation; version 3.
1117+ *
1118+ * This program is distributed in the hope that it will be useful,
1119+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1120+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1121+ * GNU General Public License for more details.
1122+ *
1123+ * You should have received a copy of the GNU General Public License
1124+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1125+ *
1126+ * Author: Michael Terry <michael.terry@canonical.com>
1127+ */
1128+
1129+#include "../Greeter.h"
1130+#include "../GreeterPrivate.h"
1131+
1132+#include <QDebug>
1133+
1134+namespace QLightDM
1135+{
1136+
1137+GreeterPrivate::GreeterPrivate(Greeter* parent)
1138+ : authenticated(false),
1139+ authenticationUser(),
1140+ q_ptr(parent)
1141+{
1142+}
1143+
1144+void GreeterPrivate::handleAuthenticate()
1145+{
1146+ Q_Q(Greeter);
1147+
1148+ qDebug() << "handleAuthentication called!" << authenticationUser;
1149+
1150+ Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret);
1151+}
1152+
1153+void GreeterPrivate::handleRespond(const QString &response)
1154+{
1155+ Q_Q(Greeter);
1156+
1157+
1158+ authenticated = (response == "password");
1159+ qDebug() << "responding" << response << authenticated;
1160+ Q_EMIT q->authenticationComplete();
1161+}
1162+
1163+}
1164
1165=== added file 'tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp'
1166--- tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp 1970-01-01 00:00:00 +0000
1167+++ tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp 2013-06-03 18:14:27 +0000
1168@@ -0,0 +1,61 @@
1169+/*
1170+ * Copyright (C) 2013 Canonical, Ltd.
1171+ *
1172+ * This program is free software; you can redistribute it and/or modify
1173+ * it under the terms of the GNU General Public License as published by
1174+ * the Free Software Foundation; version 3.
1175+ *
1176+ * This program is distributed in the hope that it will be useful,
1177+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1178+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1179+ * GNU General Public License for more details.
1180+ *
1181+ * You should have received a copy of the GNU General Public License
1182+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1183+ *
1184+ * Author: Pete Woods <pete.woods@canonical.com>
1185+ */
1186+
1187+#include "../InfographicModelPrivate.h"
1188+
1189+namespace QLightDM
1190+{
1191+
1192+void InfographicModelPrivate::generateFakeData()
1193+{
1194+ std::default_random_engine generator;
1195+ std::normal_distribution<qreal> distribution(0.5, 0.2);
1196+ auto rand = std::bind(distribution, generator);
1197+
1198+ QColor orange = QColor::fromRgbF(0.9, 0.3, 0.1, 1.0);
1199+ QColor yellow = QColor::fromRgbF(1.0, 0.6, 0.0, 1.0);
1200+ QColor red = QColor::fromRgbF(0.8, 0.0, 0.0, 1.0);
1201+ QColor darkPurple = QColor::fromRgbF(0.5, 0.2, 0.3, 1.0);
1202+ QColor lightPurple = QColor::fromRgbF(0.8, 0.1, 0.8, 1.0);
1203+ QColor pink(QColor::fromRgbF(0.75, 0.13, 0.75));
1204+
1205+ InfographicColorTheme orangeTheme(orange, orange, orange);
1206+ InfographicColorTheme yellowTheme(yellow, yellow, yellow);
1207+ InfographicColorTheme redTheme(red, red, red);
1208+ InfographicColorTheme darkPurpleTheme(darkPurple, darkPurple, darkPurple);
1209+ InfographicColorTheme lightPurpleTheme(lightPurple, lightPurple,
1210+ lightPurple);
1211+ InfographicColorTheme pinkTheme(pink, pink, pink);
1212+
1213+ {
1214+ QVariantList firstMonth;
1215+ while (firstMonth.size() < 17)
1216+ firstMonth.push_back(QVariant(rand()));
1217+ while (firstMonth.size() < 31)
1218+ firstMonth.push_back(QVariant());
1219+ QVariantList secondMonth;
1220+ while (secondMonth.size() < 31)
1221+ secondMonth.push_back(QVariant(rand()));
1222+ QSharedPointer<InfographicData> data(
1223+ new InfographicData("<b>5km</b> travelled", yellowTheme,
1224+ firstMonth, orangeTheme, secondMonth, this));
1225+ m_fakeData.insert("has-pin", data);
1226+ }
1227+}
1228+
1229+}
1230
1231=== added file 'tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp'
1232--- tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp 1970-01-01 00:00:00 +0000
1233+++ tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp 2013-06-03 18:14:27 +0000
1234@@ -0,0 +1,33 @@
1235+/*
1236+ * Copyright (C) 2013 Canonical, Ltd.
1237+ *
1238+ * This program is free software; you can redistribute it and/or modify
1239+ * it under the terms of the GNU General Public License as published by
1240+ * the Free Software Foundation; version 3.
1241+ *
1242+ * This program is distributed in the hope that it will be useful,
1243+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1244+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1245+ * GNU General Public License for more details.
1246+ *
1247+ * You should have received a copy of the GNU General Public License
1248+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1249+ *
1250+ * Author: Michael Terry <michael.terry@canonical.com>
1251+ */
1252+
1253+#include "../UsersModelPrivate.h"
1254+
1255+namespace QLightDM
1256+{
1257+
1258+UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
1259+ : q_ptr(parent)
1260+{
1261+ entries =
1262+ {
1263+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
1264+ };
1265+}
1266+
1267+}
1268
1269=== added directory 'tests/mocks/LightDM/single-pin'
1270=== added file 'tests/mocks/LightDM/single-pin/CMakeLists.txt'
1271--- tests/mocks/LightDM/single-pin/CMakeLists.txt 1970-01-01 00:00:00 +0000
1272+++ tests/mocks/LightDM/single-pin/CMakeLists.txt 2013-06-03 18:14:27 +0000
1273@@ -0,0 +1,21 @@
1274+set(LibLightDM_SOURCES
1275+ ../Greeter.cpp
1276+ ../UsersModel.cpp
1277+ ../InfographicModel.cpp
1278+ GreeterPrivate.cpp
1279+ UsersModelPrivate.cpp
1280+ InfographicModelPrivate.cpp
1281+ ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
1282+ )
1283+
1284+
1285+add_library(MockLightDM-single-pin SHARED ${LibLightDM_SOURCES})
1286+
1287+qt5_use_modules(MockLightDM-single-pin Gui)
1288+
1289+set_target_properties(MockLightDM-single-pin PROPERTIES
1290+ OUTPUT_NAME lightdm-qt5-2)
1291+
1292+install(TARGETS MockLightDM-single-pin
1293+ DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/single-pin
1294+ )
1295
1296=== added file 'tests/mocks/LightDM/single-pin/GreeterPrivate.cpp'
1297--- tests/mocks/LightDM/single-pin/GreeterPrivate.cpp 1970-01-01 00:00:00 +0000
1298+++ tests/mocks/LightDM/single-pin/GreeterPrivate.cpp 2013-06-03 18:14:27 +0000
1299@@ -0,0 +1,53 @@
1300+/*
1301+ * Copyright (C) 2013 Canonical, Ltd.
1302+ *
1303+ * This program is free software; you can redistribute it and/or modify
1304+ * it under the terms of the GNU General Public License as published by
1305+ * the Free Software Foundation; version 3.
1306+ *
1307+ * This program is distributed in the hope that it will be useful,
1308+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1309+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1310+ * GNU General Public License for more details.
1311+ *
1312+ * You should have received a copy of the GNU General Public License
1313+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1314+ *
1315+ * Author: Michael Terry <michael.terry@canonical.com>
1316+ */
1317+
1318+#include "../Greeter.h"
1319+#include "../GreeterPrivate.h"
1320+
1321+#include <QDebug>
1322+
1323+namespace QLightDM
1324+{
1325+
1326+GreeterPrivate::GreeterPrivate(Greeter* parent)
1327+ : authenticated(false),
1328+ authenticationUser(),
1329+ q_ptr(parent)
1330+{
1331+}
1332+
1333+void GreeterPrivate::handleAuthenticate()
1334+{
1335+ Q_Q(Greeter);
1336+
1337+ qDebug() << "handleAuthentication called!" << authenticationUser;
1338+
1339+ Q_EMIT q->showPrompt("PIN:", Greeter::PromptTypeSecret);
1340+}
1341+
1342+void GreeterPrivate::handleRespond(const QString &response)
1343+{
1344+ Q_Q(Greeter);
1345+
1346+
1347+ authenticated = (response == "1234");
1348+ qDebug() << "responding" << response << authenticated;
1349+ Q_EMIT q->authenticationComplete();
1350+}
1351+
1352+}
1353
1354=== added file 'tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp'
1355--- tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp 1970-01-01 00:00:00 +0000
1356+++ tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp 2013-06-03 18:14:27 +0000
1357@@ -0,0 +1,61 @@
1358+/*
1359+ * Copyright (C) 2013 Canonical, Ltd.
1360+ *
1361+ * This program is free software; you can redistribute it and/or modify
1362+ * it under the terms of the GNU General Public License as published by
1363+ * the Free Software Foundation; version 3.
1364+ *
1365+ * This program is distributed in the hope that it will be useful,
1366+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1367+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1368+ * GNU General Public License for more details.
1369+ *
1370+ * You should have received a copy of the GNU General Public License
1371+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1372+ *
1373+ * Author: Pete Woods <pete.woods@canonical.com>
1374+ */
1375+
1376+#include "../InfographicModelPrivate.h"
1377+
1378+namespace QLightDM
1379+{
1380+
1381+void InfographicModelPrivate::generateFakeData()
1382+{
1383+ std::default_random_engine generator;
1384+ std::normal_distribution<qreal> distribution(0.5, 0.2);
1385+ auto rand = std::bind(distribution, generator);
1386+
1387+ QColor orange = QColor::fromRgbF(0.9, 0.3, 0.1, 1.0);
1388+ QColor yellow = QColor::fromRgbF(1.0, 0.6, 0.0, 1.0);
1389+ QColor red = QColor::fromRgbF(0.8, 0.0, 0.0, 1.0);
1390+ QColor darkPurple = QColor::fromRgbF(0.5, 0.2, 0.3, 1.0);
1391+ QColor lightPurple = QColor::fromRgbF(0.8, 0.1, 0.8, 1.0);
1392+ QColor pink(QColor::fromRgbF(0.75, 0.13, 0.75));
1393+
1394+ InfographicColorTheme orangeTheme(orange, orange, orange);
1395+ InfographicColorTheme yellowTheme(yellow, yellow, yellow);
1396+ InfographicColorTheme redTheme(red, red, red);
1397+ InfographicColorTheme darkPurpleTheme(darkPurple, darkPurple, darkPurple);
1398+ InfographicColorTheme lightPurpleTheme(lightPurple, lightPurple,
1399+ lightPurple);
1400+ InfographicColorTheme pinkTheme(pink, pink, pink);
1401+
1402+ {
1403+ QVariantList firstMonth;
1404+ while (firstMonth.size() < 17)
1405+ firstMonth.push_back(QVariant(rand()));
1406+ while (firstMonth.size() < 31)
1407+ firstMonth.push_back(QVariant());
1408+ QVariantList secondMonth;
1409+ while (secondMonth.size() < 31)
1410+ secondMonth.push_back(QVariant(rand()));
1411+ QSharedPointer<InfographicData> data(
1412+ new InfographicData("<b>5km</b> travelled", yellowTheme,
1413+ firstMonth, orangeTheme, secondMonth, this));
1414+ m_fakeData.insert("has-pin", data);
1415+ }
1416+}
1417+
1418+}
1419
1420=== added file 'tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp'
1421--- tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp 1970-01-01 00:00:00 +0000
1422+++ tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp 2013-06-03 18:14:27 +0000
1423@@ -0,0 +1,33 @@
1424+/*
1425+ * Copyright (C) 2013 Canonical, Ltd.
1426+ *
1427+ * This program is free software; you can redistribute it and/or modify
1428+ * it under the terms of the GNU General Public License as published by
1429+ * the Free Software Foundation; version 3.
1430+ *
1431+ * This program is distributed in the hope that it will be useful,
1432+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1433+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1434+ * GNU General Public License for more details.
1435+ *
1436+ * You should have received a copy of the GNU General Public License
1437+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1438+ *
1439+ * Author: Michael Terry <michael.terry@canonical.com>
1440+ */
1441+
1442+#include "../UsersModelPrivate.h"
1443+
1444+namespace QLightDM
1445+{
1446+
1447+UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
1448+ : q_ptr(parent)
1449+{
1450+ entries =
1451+ {
1452+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
1453+ };
1454+}
1455+
1456+}
1457
1458=== added file 'tests/mocks/LightDM/single/CMakeLists.txt'
1459--- tests/mocks/LightDM/single/CMakeLists.txt 1970-01-01 00:00:00 +0000
1460+++ tests/mocks/LightDM/single/CMakeLists.txt 2013-06-03 18:14:27 +0000
1461@@ -0,0 +1,20 @@
1462+set(LibLightDM_SOURCES
1463+ ../Greeter.cpp
1464+ ../InfographicModel.cpp
1465+ ../UsersModel.cpp
1466+ GreeterPrivate.cpp
1467+ InfographicModelPrivate.cpp
1468+ UsersModelPrivate.cpp
1469+ ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
1470+ )
1471+
1472+add_library(MockLightDM-single SHARED ${LibLightDM_SOURCES})
1473+
1474+qt5_use_modules(MockLightDM-single Gui)
1475+
1476+set_target_properties(MockLightDM-single PROPERTIES
1477+ OUTPUT_NAME lightdm-qt5-2)
1478+
1479+install(TARGETS MockLightDM-single
1480+ DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/single
1481+ )
1482
1483=== added file 'tests/mocks/LightDM/single/GreeterPrivate.cpp'
1484--- tests/mocks/LightDM/single/GreeterPrivate.cpp 1970-01-01 00:00:00 +0000
1485+++ tests/mocks/LightDM/single/GreeterPrivate.cpp 2013-06-03 18:14:27 +0000
1486@@ -0,0 +1,48 @@
1487+/*
1488+ * Copyright (C) 2013 Canonical, Ltd.
1489+ *
1490+ * This program is free software; you can redistribute it and/or modify
1491+ * it under the terms of the GNU General Public License as published by
1492+ * the Free Software Foundation; version 3.
1493+ *
1494+ * This program is distributed in the hope that it will be useful,
1495+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1496+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1497+ * GNU General Public License for more details.
1498+ *
1499+ * You should have received a copy of the GNU General Public License
1500+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1501+ *
1502+ * Author: Michael Terry <michael.terry@canonical.com>
1503+ */
1504+
1505+#include "../Greeter.h"
1506+#include "../GreeterPrivate.h"
1507+
1508+namespace QLightDM
1509+{
1510+
1511+GreeterPrivate::GreeterPrivate(Greeter* parent)
1512+ : authenticated(false),
1513+ authenticationUser(),
1514+ twoFactorDone(false),
1515+ q_ptr(parent)
1516+{
1517+}
1518+
1519+void GreeterPrivate::handleAuthenticate()
1520+{
1521+ Q_Q(Greeter);
1522+
1523+ if (authenticationUser == "one") {
1524+ authenticated = true;
1525+ Q_EMIT q->authenticationComplete();
1526+ }
1527+}
1528+
1529+void GreeterPrivate::handleRespond(QString const &response)
1530+{
1531+ Q_UNUSED(response)
1532+}
1533+
1534+}
1535
1536=== added file 'tests/mocks/LightDM/single/InfographicModelPrivate.cpp'
1537--- tests/mocks/LightDM/single/InfographicModelPrivate.cpp 1970-01-01 00:00:00 +0000
1538+++ tests/mocks/LightDM/single/InfographicModelPrivate.cpp 2013-06-03 18:14:27 +0000
1539@@ -0,0 +1,28 @@
1540+/*
1541+ * Copyright (C) 2013 Canonical, Ltd.
1542+ *
1543+ * This program is free software; you can redistribute it and/or modify
1544+ * it under the terms of the GNU General Public License as published by
1545+ * the Free Software Foundation; version 3.
1546+ *
1547+ * This program is distributed in the hope that it will be useful,
1548+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1549+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1550+ * GNU General Public License for more details.
1551+ *
1552+ * You should have received a copy of the GNU General Public License
1553+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1554+ *
1555+ * Author: Pete Woods <pete.woods@canonical.com>
1556+ */
1557+
1558+#include "../InfographicModelPrivate.h"
1559+
1560+namespace QLightDM
1561+{
1562+
1563+void InfographicModelPrivate::generateFakeData()
1564+{
1565+}
1566+
1567+}
1568
1569=== added file 'tests/mocks/LightDM/single/UsersModelPrivate.cpp'
1570--- tests/mocks/LightDM/single/UsersModelPrivate.cpp 1970-01-01 00:00:00 +0000
1571+++ tests/mocks/LightDM/single/UsersModelPrivate.cpp 2013-06-03 18:14:27 +0000
1572@@ -0,0 +1,33 @@
1573+/*
1574+ * Copyright (C) 2013 Canonical, Ltd.
1575+ *
1576+ * This program is free software; you can redistribute it and/or modify
1577+ * it under the terms of the GNU General Public License as published by
1578+ * the Free Software Foundation; version 3.
1579+ *
1580+ * This program is distributed in the hope that it will be useful,
1581+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1582+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1583+ * GNU General Public License for more details.
1584+ *
1585+ * You should have received a copy of the GNU General Public License
1586+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1587+ *
1588+ * Author: Michael Terry <michael.terry@canonical.com>
1589+ */
1590+
1591+#include "../UsersModelPrivate.h"
1592+
1593+namespace QLightDM
1594+{
1595+
1596+UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
1597+ : q_ptr(parent)
1598+{
1599+ entries =
1600+ {
1601+ { "one", "Only User", 0, 0, false, false, 0, 0 },
1602+ };
1603+}
1604+
1605+}
1606
1607=== modified file 'tests/qmltests/CMakeLists.txt'
1608--- tests/qmltests/CMakeLists.txt 2013-06-03 11:35:43 +0000
1609+++ tests/qmltests/CMakeLists.txt 2013-06-03 18:14:27 +0000
1610@@ -45,8 +45,12 @@
1611 ${CMAKE_BINARY_DIR}/tests/mocks)
1612 add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
1613 add_qml_test(Dash/People PeopleFilterGrid IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
1614-add_qml_test(Greeter Greeter IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
1615+add_qml_test(Greeter Lockscreen IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
1616 PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
1617+add_qml_test(Greeter Tablet IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
1618+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
1619+add_qml_test(Greeter Phone IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
1620+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
1621 add_qml_test(Greeter Infographics IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
1622 add_qml_test(Hud Hud)
1623 add_qml_test(Hud Result)
1624
1625=== added file 'tests/qmltests/Greeter/tst_Lockscreen.qml'
1626--- tests/qmltests/Greeter/tst_Lockscreen.qml 1970-01-01 00:00:00 +0000
1627+++ tests/qmltests/Greeter/tst_Lockscreen.qml 2013-06-03 18:14:27 +0000
1628@@ -0,0 +1,205 @@
1629+/*
1630+ * Copyright 2013 Canonical Ltd.
1631+ *
1632+ * This program is free software; you can redistribute it and/or modify
1633+ * it under the terms of the GNU General Public License as published by
1634+ * the Free Software Foundation; version 3.
1635+ *
1636+ * This program is distributed in the hope that it will be useful,
1637+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1638+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1639+ * GNU General Public License for more details.
1640+ *
1641+ * You should have received a copy of the GNU General Public License
1642+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1643+ */
1644+
1645+import QtQuick 2.0
1646+import QtTest 1.0
1647+import ".."
1648+import "../../../Greeter"
1649+import Ubuntu.Components 0.1
1650+import LightDM 0.1 as LightDM
1651+import Unity.Test 0.1 as UT
1652+
1653+Rectangle {
1654+ width: units.gu(60)
1655+ height: units.gu(80)
1656+ color: "orange"
1657+
1658+ Lockscreen {
1659+ id: lockscreen
1660+ anchors.fill: parent
1661+ anchors.rightMargin: units.gu(18)
1662+ placeholderText: "Please enter your PIN"
1663+ alphaNumeric: pinPadCheckBox.checked
1664+ pinLength: pinLengthTextField.text
1665+ username: "Lola"
1666+ }
1667+
1668+ Connections {
1669+ target: lockscreen
1670+
1671+ onEmergencyCall: emergencyCheckBox.checked = true
1672+ onUnlocked: unlockedCheckBox.checked = true
1673+ }
1674+
1675+ Connections {
1676+ target: LightDM.Greeter
1677+
1678+ onShowPrompt: {
1679+ if (text.indexOf("PIN") >= 0) {
1680+ lockscreen.alphaNumeric = false
1681+ } else {
1682+ lockscreen.alphaNumeric = true
1683+ }
1684+ lockscreen.placeholderText = text;
1685+ }
1686+ }
1687+
1688+ Rectangle {
1689+ anchors.fill: parent
1690+ anchors.leftMargin: lockscreen.width
1691+ color: "lightgray"
1692+
1693+ Column {
1694+ anchors.fill: parent
1695+ anchors.margins: units.gu(1)
1696+
1697+ Row {
1698+ CheckBox {
1699+ id: pinPadCheckBox
1700+ }
1701+ Label {
1702+ text: "Alphanumeric"
1703+ anchors.verticalCenter: parent.verticalCenter
1704+ }
1705+ }
1706+ Row {
1707+ CheckBox {
1708+ id: emergencyCheckBox
1709+ }
1710+ Label {
1711+ text: "Emergency Call"
1712+ anchors.verticalCenter: parent.verticalCenter
1713+ }
1714+ }
1715+ Row {
1716+ TextField {
1717+ id: pinLengthTextField
1718+ width: units.gu(7)
1719+ text: "4"
1720+ }
1721+ Label {
1722+ text: "PIN length"
1723+ }
1724+ }
1725+ Label {
1726+ id: pinLabel
1727+ anchors.verticalCenter: parent.verticalCenter
1728+ }
1729+ Row {
1730+ CheckBox {
1731+ id: unlockedCheckBox
1732+ }
1733+ Label {
1734+ text: "Unlocked signal"
1735+ anchors.verticalCenter: parent.verticalCenter
1736+ }
1737+ }
1738+ Button {
1739+ text: "start auth (1234)"
1740+ onClicked: LightDM.Greeter.authenticate("has-pin")
1741+ }
1742+ Button {
1743+ text: "start auth (password)"
1744+ onClicked: LightDM.Greeter.authenticate("has-password")
1745+ }
1746+ }
1747+ }
1748+
1749+ UT.UnityTestCase {
1750+ name: "Lockscreen"
1751+ when: windowShown
1752+
1753+ function test_loading_data() {
1754+ return [
1755+ {tag: "numeric", alphanumeric: false, pinPadAvailable: true },
1756+ {tag: "alphanumeric", alphanumeric: true, pinPadAvailable: false }
1757+ ]
1758+ }
1759+
1760+ function test_loading(data) {
1761+ lockscreen.alphaNumeric = data.alphanumeric
1762+ waitForRendering(lockscreen)
1763+ if (data.pinPadAvailable) {
1764+ compare(findChild(lockscreen, "pinPadButton8").text, "8", "Could not find number 8 on PinPad")
1765+ } else {
1766+ compare(findChild(lockscreen, "pinPadButton8"), undefined, "Could find number 8 on PinPad even though it should be only OSK")
1767+ }
1768+ }
1769+
1770+ function test_emergency_call_data() {
1771+ return [
1772+ {tag: "numeric", alphanumeric: false },
1773+ {tag: "alphanumeric", alphanumeric: true }
1774+ ]
1775+ }
1776+
1777+ function test_emergency_call(data) {
1778+ emergencyCheckBox.checked = false
1779+ lockscreen.alphaNumeric = data.alphanumeric
1780+ waitForRendering(lockscreen)
1781+ var emergencyButton = findChild(lockscreen, "emergencyCallIcon")
1782+ mouseClick(emergencyButton, units.gu(1), units.gu(1))
1783+ tryCompare(emergencyCheckBox, "checked", true)
1784+
1785+ }
1786+
1787+ function test_labels_data() {
1788+ return [
1789+ {tag: "numeric", alphanumeric: false, placeholderText: "Please enter your PIN", username: "foobar" },
1790+ {tag: "alphanumeric", alphanumeric: true, placeholderText: "Please enter your password", username: "Lola" }
1791+ ]
1792+ }
1793+
1794+ function test_labels(data) {
1795+ lockscreen.alphaNumeric = data.alphanumeric
1796+ lockscreen.placeholderText = data.placeholderText
1797+ waitForRendering(lockscreen)
1798+ compare(findChild(lockscreen, "pinentryField").placeholderText, data.placeholderText, "Placeholdertext is not what it should be")
1799+ if (data.alphanumeric) {
1800+ compare(findChild(lockscreen, "greeterLabel").text, "Hello " + data.username, "Greeter is not set correctly")
1801+ }
1802+ }
1803+
1804+
1805+ function test_unlock_data() {
1806+ return [
1807+ {tag: "numeric", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true},
1808+ {tag: "alphanumeric", alphanumeric: true, username: "has-password", password: "password", unlockedSignal: true},
1809+ {tag: "numeric (wrong)", alphanumeric: false, username: "has-pin", password: "4321", unlockedSignal: false},
1810+ {tag: "alphanumeric (wrong)", alphanumeric: true, username: "has-password", password: "drowssap", unlockedSignal: false},
1811+ ]
1812+ }
1813+
1814+ function test_unlock(data) {
1815+ unlockedCheckBox.checked = false
1816+ LightDM.Greeter.authenticate(data.username)
1817+
1818+ if (data.alphanumeric) {
1819+ var inputField = findChild(lockscreen, "pinentryField")
1820+ mouseClick(inputField, units.gu(1), units.gu(1))
1821+ typeString(data.password)
1822+ keyClick(Qt.Key_Enter)
1823+ } else {
1824+ for (var i = 0; i < data.password.length; ++i) {
1825+ var character = data.password.charAt(i)
1826+ var button = findChild(lockscreen, "pinPadButton" + character)
1827+ mouseClick(button, units.gu(1), units.gu(1))
1828+ }
1829+ }
1830+ tryCompare(unlockedCheckBox, "checked", data.unlockedSignal)
1831+ }
1832+ }
1833+}
1834
1835=== added file 'tests/qmltests/Greeter/tst_Phone.qml'
1836--- tests/qmltests/Greeter/tst_Phone.qml 1970-01-01 00:00:00 +0000
1837+++ tests/qmltests/Greeter/tst_Phone.qml 2013-06-03 18:14:27 +0000
1838@@ -0,0 +1,62 @@
1839+/*
1840+ * Copyright 2013 Canonical Ltd.
1841+ *
1842+ * This program is free software; you can redistribute it and/or modify
1843+ * it under the terms of the GNU General Public License as published by
1844+ * the Free Software Foundation; version 3.
1845+ *
1846+ * This program is distributed in the hope that it will be useful,
1847+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1848+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1849+ * GNU General Public License for more details.
1850+ *
1851+ * You should have received a copy of the GNU General Public License
1852+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1853+ */
1854+
1855+import QtQuick 2.0
1856+import QtTest 1.0
1857+import ".."
1858+import "../../../Greeter"
1859+import Ubuntu.Components 0.1
1860+import LightDM 0.1 as LightDM
1861+import Unity.Test 0.1 as UT
1862+
1863+Item {
1864+ width: units.gu(60)
1865+ height: units.gu(80)
1866+
1867+ Greeter {
1868+ id: greeter
1869+ anchors.fill: parent
1870+ }
1871+
1872+ SignalSpy {
1873+ id: unlockSpy
1874+ target: greeter
1875+ signalName: "unlocked"
1876+ }
1877+
1878+ UT.UnityTestCase {
1879+ name: "Greeter"
1880+ when: windowShown
1881+
1882+ function test_properties() {
1883+ compare(greeter.multiUser, false)
1884+ compare(greeter.narrowMode, true)
1885+ }
1886+
1887+ function test_teasingArea() {
1888+ tryCompare(greeter, "leftTeaserPressed", false)
1889+ mousePress(greeter, units.gu(2), greeter.height - units.gu(1))
1890+ tryCompare(greeter, "leftTeaserPressed", true)
1891+ mouseRelease(greeter, units.gu(2), greeter.height - units.gu(1))
1892+ tryCompare(greeter, "leftTeaserPressed", false)
1893+
1894+ mousePress(greeter, greeter.width - units.gu(2), greeter.height - units.gu(1))
1895+ tryCompare(greeter, "leftTeaserPressed", false)
1896+ mouseRelease(greeter, units.gu(2), greeter.height - units.gu(1))
1897+ tryCompare(greeter, "leftTeaserPressed", false)
1898+ }
1899+ }
1900+}
1901
1902=== renamed file 'tests/qmltests/Greeter/tst_Greeter.qml' => 'tests/qmltests/Greeter/tst_Tablet.qml'
1903--- tests/qmltests/Greeter/tst_Greeter.qml 2013-06-03 11:35:43 +0000
1904+++ tests/qmltests/Greeter/tst_Tablet.qml 2013-06-03 18:14:27 +0000
1905@@ -79,6 +79,11 @@
1906 return i
1907 }
1908
1909+ function test_properties() {
1910+ compare(greeter.multiUser, true)
1911+ compare(greeter.narrowMode, false)
1912+ }
1913+
1914 function test_cycle_data() {
1915 var data = new Array()
1916 for (var i = 0; i < greeter.model.count; i++) {
1917@@ -148,19 +153,6 @@
1918 fail("Didn't find empty-name")
1919 }
1920
1921- function test_teasingArea() {
1922- tryCompare(greeter, "leftTeaserPressed", false)
1923- mousePress(greeter, units.gu(2), greeter.height - units.gu(1))
1924- tryCompare(greeter, "leftTeaserPressed", true)
1925- mouseRelease(greeter, units.gu(2), greeter.height - units.gu(1))
1926- tryCompare(greeter, "leftTeaserPressed", false)
1927-
1928- mousePress(greeter, greeter.width - units.gu(2), greeter.height - units.gu(1))
1929- tryCompare(greeter, "leftTeaserPressed", false)
1930- mouseRelease(greeter, units.gu(2), greeter.height - units.gu(1))
1931- tryCompare(greeter, "leftTeaserPressed", false)
1932- }
1933-
1934 function test_auth_error() {
1935 select_user("auth-error")
1936 var passwordInput = findChild(greeter, "passwordInput")

Subscribers

People subscribed via source and target branches