on xenial help sign in
new lockscreen design
commit48075704c4367ba40edec67972fbc848a9a59224 authorMichael Zanetti <michael.zanetti@canonical.com> dateFri 15 Aug 2014, 12:54 (12 years ago) parent5613e47
7 files changed+256−333
qml/Components/Lockscreen.qml+29−75 qml/Components/PassphraseLockscreen.qml+2−3 qml/Components/PinLockscreen.qml+133−157 qml/Components/PinPadButton.qml+31−45 qml/Notifications/NotificationMenuItemFactory.qml+4−1 qml/Shell.qml+2−4 tests/qmltests/Greeter/tst_Lockscreen.qml+55−48
qml/Components/Lockscreen.qml+29−75
@@ -24,15 +24,14 @@ Showable {
2424 // Determine if a numeric or alphanumeric pad is used.
2525 property bool alphaNumeric: false
2626
27− // Placeholder text
28− property string placeholderText: ""
29− // Placeholder text while shaking (e.g. Incorrect passprase)
30− property string wrongPlaceholderText: ""
27+ // Informational text. (e.g. some text to tell which domain this is pin is entered for)
28+ property string infoText: ""
29+
3130 // Retries text (e.g. 3 retries left)
3231 property string retryText: ""
3332
34− // Informational text. (e.g. some text to tell which domain this is pin is entered for.
35− property string infoText: ""
33+ // The text to be displayed in case the login failed
34+ property string errorText: ""
3635
3736 // In case the Lockscreen can show a greeter message, this is the username
3837 property string username: ""
@@ -41,10 +40,7 @@ Showable {
4140 // If both are unset, the Lockscreen will show a confirm button and allow typing any length of pin before
4241 // confirming. If minPinLength is set to a value > 0, the confirm button will only become active when the
4342 // entered pin is at least that long. If maxPinLength is set, the lockscreen won't allow entering any
44− // more numbers than that. If both are set to the same value, the lockscreen will enter auto confirming
45− // behavior, hiding the confirmation button and triggering that automatically when the entered pin reached
46− // that length. This is ignored by the alphaNumeric lockscreen as that one is always confirmed by pressing
47− // enter on the OSK.
43+ // more numbers than that.
4844 property int minPinLength: -1
4945 property int maxPinLength: -1
5046
@@ -110,41 +106,6 @@ Showable {
110106 anchors.fill: root
111107 }
112108
113− Column {
114− spacing: units.gu(2)
115− anchors {
116− left: parent.left
117− right: parent.right
118− bottom: pinPadLoader.top
119− bottomMargin: units.gu(2)
120− }
121− Label {
122− objectName: "retryCountLabel"
123− anchors {
124− left: parent.left
125− right: parent.right
126− }
127− text: root.retryText
128− horizontalAlignment: Text.AlignHCenter
129− color: "#f3f3e7"
130− opacity: 0.6
131− visible: root.retryText.length > 0
132− }
133− Label {
134− id: infoTextLabel
135− objectName: "infoTextLabel"
136− anchors {
137− left: parent.left
138− right: parent.right
139− }
140− text: root.infoText
141− horizontalAlignment: Text.AlignHCenter
142− color: "#f3f3e7"
143− opacity: 0.6
144− visible: root.infoText.length > 0
145− }
146− }
147−
148109 Loader {
149110 id: pinPadLoader
150111 objectName: "pinPadLoader"
@@ -152,7 +113,7 @@ Showable {
152113 left: parent.left
153114 right: parent.right
154115 verticalCenter: parent.verticalCenter
155− verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : -units.gu(4)
116+ verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : 0
156117 }
157118 property bool resetting: false
158119 property bool waiting: false
@@ -193,10 +154,18 @@ Showable {
193154 }
194155 Binding {
195156 target: pinPadLoader.item
196− property: "placeholderText"
197− value: forcedDelayTimer.running ? pinPadLoader.forcedDelayText :
198− (pinPadLoader.showWrongText ? root.wrongPlaceholderText :
199− root.placeholderText)
157+ property: "infoText"
158+ value: root.infoText
159+ }
160+ Binding {
161+ target: pinPadLoader.item
162+ property: "retryText"
163+ value: root.retryText
164+ }
165+ Binding {
166+ target: pinPadLoader.item
167+ property: "errorText"
168+ value: root.errorText
200169 }
201170 Binding {
202171 target: pinPadLoader.item
@@ -210,8 +179,9 @@ Showable {
210179 }
211180 }
212181
213− Column {
214− id: emergencyCallColumn
182+ Label {
183+ id: emergencyCallLabel
184+ objectName: "emergencyCallLabel"
215185
216186 // FIXME: We *should* show emergency dialer if there is a SIM present,
217187 // regardless of whether the side stage is enabled. But right now,
@@ -223,37 +193,21 @@ Showable {
223193 visible: !shell.sideStageEnabled
224194
225195 anchors {
226− left: parent.left
227196 bottom: parent.bottom
228197 bottomMargin: units.gu(4)
229− right: parent.right
230− }
231− height: childrenRect.height
232− spacing: units.gu(1)
233−
234− Icon {
235− objectName: "emergencyCallIcon"
236− height: units.gu(3)
237− width: height
238− anchors.horizontalCenter: parent.horizontalCenter
239− name: "phone-app-call-symbolic"
240− color: "#f3f3e7"
241− opacity: 0.6
198+ horizontalCenter: parent.horizontalCenter
242199 }
243200
244− Label {
245− text: i18n.tr("Emergency Call")
246− color: "#f3f3e7"
247− opacity: 0.6
248− fontSize: "medium"
249− anchors.horizontalCenter: parent.horizontalCenter
250− }
201+ text: i18n.tr("Emergency Call")
202+ color: "#f3f3e7"
203+ opacity: 0.6
204+ fontSize: "small"
251205 }
252206
253207 MouseArea {
254− anchors.fill: emergencyCallColumn
208+ anchors.fill: emergencyCallLabel
255209 onClicked: root.emergencyCall()
256− enabled: emergencyCallColumn.visible
210+ enabled: emergencyCallLabel.visible
257211 }
258212
259213 Component {
qml/Components/PassphraseLockscreen.qml+2−3
@@ -22,7 +22,7 @@ Item {
2222 id: root
2323 height: highlightItem.height
2424
25− property string placeholderText
25+ property string infoText
2626 property string username: ""
2727 property bool entryEnabled: true
2828
@@ -75,8 +75,7 @@ Item {
7575 echoMode: TextInput.Password
7676 opacity: 0.9
7777 hasClearButton: false
78− enabled: entryEnabled
79− placeholderText: root.placeholderText
78+ placeholderText: root.infoText
8079
8180 onAccepted: {
8281 if (pinentryField.text) {
qml/Components/PinLockscreen.qml+133−157
@@ -22,9 +22,11 @@ import "../Components"
2222Column {
2323 id: root
2424 anchors.centerIn: parent
25− spacing: units.gu(3.5)
25+ spacing: units.gu(2)
2626
27− property alias placeholderText: pinentryField.placeholderText
27+ property string infoText
28+ property string retryText
29+ property string errorText
2830 property int padWidth: units.gu(34)
2931 property int padHeight: units.gu(28)
3032 property int minPinLength: -1
@@ -35,199 +37,173 @@ Column {
3537
3638 property bool entryEnabled: true
3739
38− function clear(playAnimation) {
40+ function clear(showAnimation) {
3941 pinentryField.text = "";
40− if (playAnimation) {
42+ if (showAnimation) {
43+ pinentryField.incorrectOverride = true;
4144 wrongPasswordAnimation.start();
4245 }
4346 }
4447
45− QtObject {
46− id: priv
47− property bool autoConfirm: root.minPinLength == root.maxPinLength && root.minPinLength != -1
48+ Label {
49+ id: infoField
50+ objectName: "infoTextLabel"
51+ fontSize: "large"
52+ color: "#f3f3e7"
53+ anchors.horizontalCenter: parent.horizontalCenter
54+ text: root.infoText
4855 }
4956
50− UbuntuShape {
51− id: pinentryField
52− objectName: "pinentryField"
53− anchors.horizontalCenter: parent.horizontalCenter
54− color: "#55000000"
55− width:root.padWidth
56− height: units.gu(5)
57− radius: "medium"
58− property string text: ""
59− property string placeholderText: ""
60−
61− function appendChar(character) {
62− if (root.maxPinLength == -1 || pinentryField.text.length < root.maxPinLength) {
63− pinentryField.text = pinentryField.text + character;
64− }
65− }
57+ Item {
58+ id: pinContainer
59+ anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
60+ height: units.gu(4)
6661
67− onTextChanged: {
68− pinentryFieldLabel.text = "";
69− for (var i = 0; i < text.length; ++i) {
70− pinentryFieldLabel.text += "•";
62+ Row {
63+ id: pinentryField
64+ objectName: "pinentryField"
65+ anchors.horizontalCenter: parent.horizontalCenter
66+ anchors.verticalCenter: parent.verticalCenter
67+ spacing: Math.max(0, Math.min(units.gu(3), (parent.width / root.maxPinLength) - units.gu(3)))
68+
69+ property string text
70+ property bool incorrectOverride: false
71+
72+ Repeater {
73+ model: pinentryField.text.length
74+ delegate: Rectangle {
75+ color: "#f3f3e7"
76+ width: Math.min(units.gu(2), (pinContainer.width - pinContainer.height*2 ) / (root.maxPinLength >= 0 ? root.maxPinLength : 16))
77+ height: width
78+ radius: width / 2
79+ }
7180 }
72− if (priv.autoConfirm && text.length === root.maxPinLength) {
73− root.entered(text);
81+
82+ function appendNumber(number) {
83+ if (incorrectOverride) {
84+ incorrectOverride = false;
85+ }
86+
87+ pinentryField.text = pinentryField.text + number
7488 }
75− }
7689
77− Label {
78− id: pinentryFieldLabel
79− anchors.centerIn: parent
80− width: parent.width - (backspaceIcon.width + backspaceIcon.anchors.rightMargin) * 2
81− elide: Text.ElideMiddle
82− horizontalAlignment: Text.AlignHCenter
83− font.pixelSize: units.dp(44)
84− color: "#f3f3e7"
85− opacity: 0.6
90+ function backspace() {
91+ pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
92+ }
8693 }
8794 Label {
88− id: pinentryFieldPlaceHolder
89− objectName: "pinentryFieldPlaceHolder"
90− anchors.centerIn: parent
91− horizontalAlignment: Text.AlignHCenter
95+ id: wrongNoticeLabel
96+ objectName: "wrongNoticeLabel"
97+ fontSize: "x-large"
9298 color: "#f3f3e7"
93− opacity: 0.6
94− text: parent.placeholderText
95− visible: pinentryFieldLabel.text.length == 0
99+ anchors.horizontalCenter: parent.horizontalCenter
100+ text: root.errorText
101+ visible: pinentryField.incorrectOverride
96102 }
97103
98− Icon {
99− id: backspaceIcon
104+ AbstractButton {
100105 objectName: "backspaceIcon"
101− anchors {
102− top: parent.top
103− topMargin: units.gu(1)
104− right: parent.right
105− rightMargin: units.gu(2)
106− bottom: parent.bottom
107− bottomMargin: units.gu(1)
108− }
109− visible: entryEnabled && !priv.autoConfirm
106+ anchors { right: parent.right; top: parent.top; bottom: parent.bottom }
110107 width: height
111− name: "erase"
112− color: "#f3f3e7"
113− opacity: 0.6
114− MouseArea {
108+
109+ Icon {
115110 anchors.fill: parent
116− onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
111+ name: "erase"
112+ color: "#f3f3e7"
117113 }
118− }
119− }
120114
121− UbuntuShape {
122− anchors {
123− left: parent.left
124− right: parent.right
125− margins: (parent.width - root.padWidth) / 2
126− }
127− height: root.padHeight
128− color: "#55000000"
129− radius: "medium"
130−
131− ThinDivider {
132− anchors {
133− left: parent.left
134− right: parent.right
135− top: parent.top
136− topMargin: root.padHeight / 4
137− }
138− }
139− ThinDivider {
140− anchors {
141− left: parent.left
142− right: parent.right
143− verticalCenter: parent.verticalCenter
144− }
145− }
146− ThinDivider {
147− anchors {
148− left: parent.left
149− right: parent.right
150− bottom: parent.bottom
151− bottomMargin: root.padHeight / 4
115+ opacity: (pinentryField.text.length && !pinentryField.incorrectOverride) > 0 ? 1 : 0
116+
117+ Behavior on opacity {
118+ UbuntuNumberAnimation {}
152119 }
153− }
154120
155− ThinDivider {
156− anchors.centerIn: parent
157− anchors.horizontalCenterOffset: -root.padWidth / 6
158− width: root.padHeight
159− rotation: -90
160− }
161− ThinDivider {
162− anchors.centerIn: parent
163− anchors.horizontalCenterOffset: root.padWidth / 6
164− width: root.padHeight
165− rotation: -90
121+ onClicked: pinentryField.backspace()
166122 }
123+ }
167124
168− Grid {
169− anchors {
170− left: parent.left
171− right: parent.right
172− margins: (parent.width - root.padWidth) / 2
173− }
174125
175− columns: 3
126+ Label {
127+ objectName: "retryLabel"
128+ fontSize: "x-small"
129+ color: "#f3f3e7"
130+ anchors.horizontalCenter: parent.horizontalCenter
131+ text: root.retryText
132+ }
176133
177− Repeater {
178− model: 9
179−
180− PinPadButton {
181− objectName: "pinPadButton" + (index + 1)
182− width: root.padWidth / 3
183− height: root.padHeight / 4
184− text: index + 1
185− enabled: entryEnabled
186−
187− onClicked: {
188− pinentryField.appendChar(text);
189− }
190− }
191− }
134+ ThinDivider {
135+ anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
136+ }
192137
193− PinPadButton {
194− objectName: "pinPadButtonBack"
195− width: root.padWidth / 3
196− height: root.padHeight / 4
197− subText: i18n.tr("CANCEL")
198− onClicked: root.cancel();
199− }
138+ Grid {
139+ id: numbersGrid
140+ anchors { horizontalCenter: parent.horizontalCenter }
141+ columns: 3
200142
201− PinPadButton {
202− objectName: "pinPadButton0"
203− width: root.padWidth / 3
204− height: root.padHeight / 4
205− text: "0"
206− onClicked: pinentryField.appendChar(text);
207− enabled: entryEnabled
208− }
143+ property int buttonHeight: units.gu(8)
144+ property int buttonWidth: units.gu(12)
145+
146+ Repeater {
147+ model: 9
209148
210149 PinPadButton {
211− objectName: "pinPadButtonErase"
212− width: root.padWidth / 3
213− height: root.padHeight / 4
214− iconName: priv.autoConfirm ? "erase" : ""
215− subText: priv.autoConfirm ? "" : i18n.tr("DONE")
150+ objectName: "pinPadButton" + text
151+ text: index + 1
152+ height: numbersGrid.buttonHeight
153+ width: numbersGrid.buttonWidth
154+ enabled: root.maxPinLength == -1 ||
155+ pinentryField.text.length < root.maxPinLength ||
156+ pinentryField.incorrectOverride
157+
216158 onClicked: {
217− if (priv.autoConfirm) {
218− pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
219− } else {
220− root.entered(pinentryField.text);
221− }
159+ pinentryField.appendNumber(index + 1)
222160 }
223− enabled: priv.autoConfirm ? entryEnabled : pinentryField.text.length >= root.minPinLength
224161 }
225162 }
226− }
163+ Item {
164+ height: numbersGrid.buttonHeight
165+ width: numbersGrid.buttonWidth
166+ }
167+ PinPadButton {
168+ text: "0"
169+ height: numbersGrid.buttonHeight
170+ width: numbersGrid.buttonWidth
171+ enabled: root.maxPinLength == -1 ||
172+ pinentryField.text.length < root.maxPinLength ||
173+ pinentryField.incorrectOverride
174+
175+ onClicked: {
176+ pinentryField.appendNumber(0)
177+ }
178+ }
179+ Item {
180+ height: numbersGrid.buttonHeight
181+ width: numbersGrid.buttonWidth
182+ }
183+ PinPadButton {
184+ iconName: "close"
185+ height: numbersGrid.buttonHeight
186+ width: numbersGrid.buttonWidth
227187
188+ onClicked: root.cancel()
189+ }
190+ Item {
191+ height: numbersGrid.buttonHeight
192+ width: numbersGrid.buttonWidth
193+ }
194+ PinPadButton {
195+ iconName: "tick"
196+ objectName: "confirmButton"
197+ height: numbersGrid.buttonHeight
198+ width: numbersGrid.buttonWidth
199+ enabled: pinentryField.text.length >= root.minPinLength
200+
201+ onClicked: root.entered(pinentryField.text)
202+ }
203+ }
228204 WrongPasswordAnimation {
229205 id: wrongPasswordAnimation
230206 objectName: "wrongPasswordAnimation"
231− target: pinentryField
207+ target: root
232208 }
233209}
qml/Components/PinPadButton.qml+31−45
@@ -15,62 +15,48 @@
1515 */
1616
1717import QtQuick 2.0
18−import Ubuntu.Components 0.1
18+import Ubuntu.Components 1.1
1919
20−Item {
20+AbstractButton {
2121 id: root
2222 opacity: enabled ? 1 : 0.6
2323
2424 property alias text: label.text
25− property alias subText: subTextLabel.text
2625 property string iconName
2726
28− signal clicked()
27+ UbuntuShape {
28+ anchors.fill: parent
29+ opacity: root.pressed ? 1 : 0
30+ Behavior on opacity {
31+ UbuntuNumberAnimation {}
32+ }
33+ }
2934
30− Column {
35+ Label {
36+ id: label
3137 anchors.centerIn: parent
32− width: parent.width
33− height: childrenRect.height
34−
35− Item {
36− anchors {
37− left: parent.left
38− right: parent.right
39− }
40− height: label.visible || icon.visible ? Math.max(label.height, icon.height) : 0
41−
42− Label {
43− id: label
44− anchors.centerIn: parent
45− width: parent.width
46− horizontalAlignment: Text.AlignHCenter
47− color: "#f3f3e7"
48− fontSize: "large"
49− font.weight: Font.DemiBold
50− visible: text.length > 0
51− }
52−
53− Icon {
54− id: icon
55− height: units.gu(3)
56− width: height
57− anchors.centerIn: parent
58− name: root.iconName
59− color: "#f3f3e7"
60− visible: name.length > 0
61− }
62− }
63− Label {
64− id: subTextLabel
65− fontSize: "small"
66− color: "#f3f3e7"
67− anchors.horizontalCenter: parent.horizontalCenter
68− visible: text.length > 0
38+ horizontalAlignment: Text.AlignHCenter
39+ color: "#f3f3e7"
40+ fontSize: "x-large"
41+ font.weight: Font.DemiBold
42+ visible: text.length > 0
43+ scale: root.pressed ? 0.9 : 1
44+ Behavior on scale {
45+ UbuntuNumberAnimation {}
6946 }
7047 }
7148
72− MouseArea {
73− anchors.fill: parent
74− onClicked: root.clicked()
49+ Icon {
50+ id: icon
51+ height: units.gu(3)
52+ width: height
53+ anchors.centerIn: parent
54+ name: root.iconName
55+ color: "#f3f3e7"
56+ visible: name.length > 0
57+ scale: root.pressed ? 0.9 : 1
58+ Behavior on scale {
59+ UbuntuNumberAnimation { duration: UbuntuAnimation.SlowDuration }
60+ }
7561 }
7662}
qml/Notifications/NotificationMenuItemFactory.qml+4−1
@@ -117,7 +117,10 @@ Loader {
117117 right: parent.right
118118 }
119119 height: menuFactory.maxHeight
120− placeholderText: i18n.tr("Please enter SIM PIN")
120+ infoText: i18n.tr("Please enter SIM PIN")
121+ errorText: i18n.tr("Sorry, incorrect PIN")
122+ minPinLength: 4
123+ maxPinLength: 8
121124 background: shell.background
122125
123126 onEntered: {
qml/Shell.qml+2−4
@@ -266,10 +266,8 @@ Item {
266266 promptText = lockscreen.alphaNumeric ?
267267 i18n.tr("passphrase") : i18n.tr("passcode")
268268 }
269− lockscreen.placeholderText = i18n.tr("Enter your %1").arg(promptText)
270− lockscreen.wrongPlaceholderText = i18n.tr("Incorrect %1").arg(promptText) +
271− "\n" +
272− i18n.tr("Please re-enter")
269+ lockscreen.infoText = i18n.tr("Enter your %1").arg(promptText)
270+ lockscreen.errorText = i18n.tr("Incorrect %1").arg(promptText)
273271 lockscreen.show();
274272 }
275273 }
tests/qmltests/Greeter/tst_Lockscreen.qml+55−48
@@ -26,22 +26,21 @@ import Unity.Test 0.1 as UT
2626Rectangle {
2727 id: root
2828 width: units.gu(80)
29− height: units.gu(80)
29+ height: units.gu(70)
3030 color: "orange"
3131
3232 Lockscreen {
3333 id: lockscreen
3434 anchors.fill: parent
35− anchors.rightMargin: units.gu(30)
36− placeholderText: "Please enter your PIN"
37− wrongPlaceholderText: "Incorrect PIN"
35+ anchors.rightMargin: units.gu(40)
36+ infoText: infoTextTextField.text
3837 retryText: retryCountTextField.text
38+ errorText: errorTextTextField.text
3939 alphaNumeric: pinPadCheckBox.checked
4040 minPinLength: minPinLengthTextField.text
4141 maxPinLength: maxPinLengthTextField.text
4242 username: "Lola"
4343 background: "../../../qml/graphics/phone_background.jpg"
44− infoText: infoTextTextField.text
4544 }
4645
4746 Connections {
@@ -68,7 +67,7 @@ Rectangle {
6867 } else {
6968 pinPadCheckBox.checked = true
7069 }
71− lockscreen.placeholderText = text;
70+ lockscreen.infoText = text;
7271 }
7372 }
7473
@@ -157,7 +156,14 @@ Rectangle {
157156 id: infoTextTextField
158157 width: parent.width
159158 placeholderText: "Infotext"
160− text: "+49 179 3253553"
159+ text: "Enter SIM1 PIN"
160+ }
161+
162+ TextField {
163+ id: errorTextTextField
164+ width: parent.width
165+ placeholderText: "Error text"
166+ text: "Sorry, incorrect PIN"
161167 }
162168
163169 TextField {
@@ -223,7 +229,7 @@ Rectangle {
223229 emergencyCheckBox.checked = false
224230 pinPadCheckBox.checked = data.alphanumeric
225231 waitForLockscreenReady();
226− var emergencyButton = findChild(lockscreen, "emergencyCallIcon")
232+ var emergencyButton = findChild(lockscreen, "emergencyCallLabel")
227233 mouseClick(emergencyButton, units.gu(1), units.gu(1))
228234 tryCompare(emergencyCheckBox, "checked", true)
229235
@@ -231,18 +237,20 @@ Rectangle {
231237
232238 function test_labels_data() {
233239 return [
234− {tag: "numeric", alphanumeric: false, placeholderText: "Please enter your PIN", username: "foobar" },
235− {tag: "alphanumeric", alphanumeric: true, placeholderText: "Please enter your password", username: "Lola" }
240+ {tag: "numeric", alphanumeric: false, infoText: "Please enter your PIN", username: "foobar" },
241+ {tag: "alphanumeric", alphanumeric: true, infoText: "Please enter your password", username: "Lola" }
236242 ]
237243 }
238244
239245 function test_labels(data) {
240246 pinPadCheckBox.checked = data.alphanumeric
241− lockscreen.placeholderText = data.placeholderText
247+ lockscreen.infoText = data.infoText
242248 waitForLockscreenReady();
243− compare(findChild(lockscreen, "pinentryField").placeholderText, data.placeholderText, "Placeholdertext is not what it should be")
244249 if (data.alphanumeric) {
250+ compare(findChild(lockscreen, "pinentryField").placeholderText, data.infoText, "Placeholdertext is not what it should be")
245251 compare(findChild(lockscreen, "greeterLabel").text, "Hello " + data.username, "Greeter is not set correctly")
252+ } else {
253+ compare(findChild(lockscreen, "infoTextLabel").text, data.infoText, "Placeholdertext is not what it should be")
246254 }
247255 }
248256
@@ -276,10 +284,8 @@ Rectangle {
276284 var button = findChild(lockscreen, "pinPadButton" + character)
277285 mouseClick(button, units.gu(1), units.gu(1))
278286 }
279− if (data.minPinLength !== data.maxPinLength || data.minPinLength == -1) {
280− var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
281− mouseClick(pinPadButtonErase, units.gu(1), units.gu(1));
282− }
287+ var confirmButton = findChild(lockscreen, "confirmButton");
288+ mouseClick(confirmButton, units.gu(1), units.gu(1));
283289 }
284290 tryCompare(enteredLabel, "text", data.password)
285291 }
@@ -317,11 +323,9 @@ Rectangle {
317323 wait(0) // Trigger event loop to make sure the animation would start running
318324 compare(animation.running, data.animation)
319325 if (data.animation) {
320− if (data.alphanumeric) {
321− tryCompare(inputField, "placeholderText", lockscreen.wrongPlaceholderText)
322− } else {
323− var label = findChild(lockscreen, "pinentryFieldPlaceHolder");
324− tryCompare(label, "text", lockscreen.wrongPlaceholderText)
326+ if (!data.alphanumeric) {
327+ var label = findChild(lockscreen, "wrongNoticeLabel");
328+ tryCompare(label, "visible", true)
325329 }
326330 }
327331
@@ -343,24 +347,21 @@ Rectangle {
343347 maxPinLengthTextField.text = data.maxPinLength
344348 waitForLockscreenReady();
345349
346− var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
347350 var backspaceIcon = findChild(lockscreen, "backspaceIcon");
348351 var pinEntryField = findChild(lockscreen, "pinentryField");
349352
350− var autoConfirmEnabled = data.minPinLength === data.maxPinLength && data.minPinLength !== -1;
351− compare(pinPadButtonErase.iconName, autoConfirmEnabled ? "erase" : "");
352− compare(backspaceIcon.visible, !autoConfirmEnabled);
353+ compare(backspaceIcon.opacity, 0);
353354
354355 var pinPadButton5 = findChild(lockscreen, "pinPadButton5");
355356 mouseClick(pinPadButton5, units.gu(1), units.gu(1));
356357 compare(pinEntryField.text, "5");
357358
358− if (data.minPinLength !== data.maxPinLength) {
359− mouseClick(backspaceIcon, units.gu(1), units.gu(1));
360− } else {
361− mouseClick(pinPadButtonErase, units.gu(1), units.gu(1));
362− }
359+ tryCompare(backspaceIcon, "opacity", 1);
360+
361+ mouseClick(backspaceIcon, units.gu(1), units.gu(1));
363362 compare(pinEntryField.text, "");
363+
364+ tryCompare(backspaceIcon, "opacity", 0);
364365 }
365366
366367 function test_minMaxLength_data() {
@@ -378,32 +379,38 @@ Rectangle {
378379 waitForLockscreenReady();
379380
380381 var pinPadButton5 = findChild(lockscreen, "pinPadButton5");
381− var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
382+ var backspaceButton = findChild(lockscreen, "backspaceIcon");
383+ var confirmButton = findChild(lockscreen, "confirmButton");
382384 var inputField = findChild(lockscreen, "pinentryField")
383385
386+ tryCompare(backspaceButton, "opacity", 0)
387+
384388 for (var i = 0; i < 10; i++) {
385389 mouseClick(pinPadButton5, units.gu(1), units.gu(1));
390+ tryCompare(backspaceButton, "opacity", 1)
386391
387− if (data.minPinLength == data.maxPinLength && data.minPinLength != -1) {
388− // auto confirm mode...
389− compare(inputField.text.length, (i+1) % data.minPinLength);
392+ if (data.maxPinLength == -1) {
393+ // Undefined maxLength... make sure all presses are recorded
394+ compare(inputField.text.length, i+1);
390395 } else {
391− // manual confirm mode
392− tryCompare(pinPadButtonErase, "enabled", (i+1) >= data.minPinLength)
393− if (data.maxPinLength == -1) {
394− compare(inputField.text.length, i+1);
395− } else {
396− compare(inputField.text.length, Math.min(data.maxPinLength, i+1));
397− }
396+ // We have a max length. Make sure we're only accepting maxLength presses
397+ compare(inputField.text.length, Math.min(data.maxPinLength, i+1));
398+ }
398399
400+ if (data.minPinLength == -1) {
401+ // Undefined minLength. Make sure confirm button is always enabled
402+ compare(confirmButton.enabled, true);
403+ } else {
404+ // We have a min length. Make sure the confirm button is only enabled when met.
405+ compare(confirmButton.enabled, (i+1) >= data.minPinLength);
399406 }
400407 }
401408 }
402409
403410 function test_retryDisplay_data() {
404411 return [
405− {tag: "empty", retryText: "", shown: false},
406− {tag: "3 retries left", retryText: "3 retries left", shown: true},
412+ {tag: "empty", retryText: ""},
413+ {tag: "3 retries left", retryText: "3 retries left"},
407414 ]
408415 }
409416
@@ -412,8 +419,8 @@ Rectangle {
412419 waitForLockscreenReady();
413420
414421 retryCountTextField.text = data.retryText;
415− var label = findChild(lockscreen, "retryCountLabel")
416− compare(label.visible, data.shown);
422+ var label = findChild(lockscreen, "retryLabel")
423+ compare(label.text, data.retryText);
417424 }
418425
419426 function test_infoPopup() {
@@ -438,8 +445,8 @@ Rectangle {
438445
439446 function test_infoTextDisplay_data() {
440447 return [
441− {tag: "empty string", text: "", shown: false},
442− {tag: "hello world", text: "hello world", shown: true},
448+ {tag: "empty string", text: ""},
449+ {tag: "hello world", text: "hello world"},
443450 ]
444451 }
445452
@@ -449,7 +456,7 @@ Rectangle {
449456
450457 infoTextTextField.text = data.text;
451458 var label = findChild(lockscreen, "infoTextLabel")
452− compare(label.visible, data.shown);
459+ compare(label.text, data.text);
453460 }
454461 }
455462