Merge lp:~phablet-team/ubuntu-settings-components/fingerprint into lp:ubuntu-settings-components
- fingerprint
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Ken VanDine | ||||
Approved revision: | 168 | ||||
Merged at revision: | 151 | ||||
Proposed branch: | lp:~phablet-team/ubuntu-settings-components/fingerprint | ||||
Merge into: | lp:ubuntu-settings-components | ||||
Diff against target: |
4441 lines (+4059/-19) 56 files modified
debian/changelog (+8/-1) debian/control (+5/-2) examples/Fingerprint.qml (+43/-0) plugins/Ubuntu/Settings/CMakeLists.txt (+1/-0) plugins/Ubuntu/Settings/Fingerprint/CMakeLists.txt (+15/-0) plugins/Ubuntu/Settings/Fingerprint/CircularSegment.qml (+64/-0) plugins/Ubuntu/Settings/Fingerprint/DirectionVisual.qml (+103/-0) plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml (+133/-0) plugins/Ubuntu/Settings/Fingerprint/FingerprintVisual.qml (+72/-0) plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml (+439/-0) plugins/Ubuntu/Settings/Fingerprint/SegmentBoundingBoxes.qml (+81/-0) plugins/Ubuntu/Settings/Fingerprint/SegmentRenderer.qml (+95/-0) plugins/Ubuntu/Settings/Fingerprint/SegmentedImage.qml (+52/-0) plugins/Ubuntu/Settings/Fingerprint/Setup.qml (+387/-0) plugins/Ubuntu/Settings/Fingerprint/StatusLabel.qml (+84/-0) plugins/Ubuntu/Settings/Fingerprint/assets.qrc (+11/-0) plugins/Ubuntu/Settings/Fingerprint/assets/fingerprint_boxes.json (+1/-0) plugins/Ubuntu/Settings/Fingerprint/assets/shape-down@27.sci (+7/-0) plugins/Ubuntu/Settings/Fingerprint/assets/shape-up@27.sci (+7/-0) plugins/Ubuntu/Settings/Fingerprint/plugin.cpp (+35/-0) plugins/Ubuntu/Settings/Fingerprint/plugin.h (+30/-0) plugins/Ubuntu/Settings/Fingerprint/qmldir (+7/-0) plugins/Ubuntu/Settings/Fingerprint/ubuntusettingsfingerprint.cpp (+39/-0) plugins/Ubuntu/Settings/Fingerprint/ubuntusettingsfingerprint.h (+37/-0) plugins/Ubuntu/Settings/Fingerprint/utils/segment.py (+84/-0) po/ubuntu-settings-components.pot (+101/-16) tests/qmltests/CMakeLists.txt (+7/-0) tests/qmltests/Fingerprint/tst_FingerprintNames.qml (+364/-0) tests/qmltests/Fingerprint/tst_FingerprintSetup.qml (+236/-0) tests/qmltests/Fingerprint/tst_FingerprintVisual.qml (+132/-0) tests/qmltests/Fingerprint/tst_Fingerprints.qml (+230/-0) tests/qmltests/mocks/Biometryd/CMakeLists.txt (+20/-0) tests/qmltests/mocks/Biometryd/MockDevice.cpp (+30/-0) tests/qmltests/mocks/Biometryd/MockDevice.h (+38/-0) tests/qmltests/mocks/Biometryd/MockFingerprintReader.cpp (+49/-0) tests/qmltests/mocks/Biometryd/MockFingerprintReader.h (+65/-0) tests/qmltests/mocks/Biometryd/MockObserver.cpp (+88/-0) tests/qmltests/mocks/Biometryd/MockObserver.h (+52/-0) tests/qmltests/mocks/Biometryd/MockOperation.cpp (+34/-0) tests/qmltests/mocks/Biometryd/MockOperation.h (+36/-0) tests/qmltests/mocks/Biometryd/MockService.cpp (+42/-0) tests/qmltests/mocks/Biometryd/MockService.h (+46/-0) tests/qmltests/mocks/Biometryd/MockTemplateStore.cpp (+56/-0) tests/qmltests/mocks/Biometryd/MockTemplateStore.h (+86/-0) tests/qmltests/mocks/Biometryd/MockUser.cpp (+33/-0) tests/qmltests/mocks/Biometryd/MockUser.h (+38/-0) tests/qmltests/mocks/Biometryd/plugin.cpp (+60/-0) tests/qmltests/mocks/Biometryd/plugin.h (+31/-0) tests/qmltests/mocks/Biometryd/qmldir (+2/-0) tests/qmltests/mocks/CMakeLists.txt (+32/-0) tests/qmltests/mocks/GSettings.1.0/CMakeLists.txt (+20/-0) tests/qmltests/mocks/GSettings.1.0/fake_gsettings.cpp (+124/-0) tests/qmltests/mocks/GSettings.1.0/fake_gsettings.h (+101/-0) tests/qmltests/mocks/GSettings.1.0/plugin.cpp (+33/-0) tests/qmltests/mocks/GSettings.1.0/plugin.h (+31/-0) tests/qmltests/mocks/GSettings.1.0/qmldir (+2/-0) |
||||
To merge this branch: | bzr merge lp:~phablet-team/ubuntu-settings-components/fingerprint | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Approve | |
Ken VanDine | Needs Fixing | ||
PS Jenkins bot | continuous-integration | Pending | |
Review via email:
|
Commit message
components for allowing a user to manage fingerprints
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
Yes, fingerprint bindings, see silo 41
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Done
* If you changed the UI, has there been a design review?
TBD
* If you changed localized strings, has the POT file been updated?
Yes
Rationale: https:/
- 164. By Jonas G. Drange
-
bump version
- 165. By Jonas G. Drange
-
clearer cancel logic
- 166. By Jonas G. Drange
-
remove brackets in changelog
- 167. By Jonas G. Drange
-
readd silly space
- 168. By Jonas G. Drange
-
update pot
- 169. By Ken VanDine
-
removed commented out code
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 170. By Jonas G. Drange
-
change the arrow so that it points outwards
- 171. By Jonas G. Drange
-
rename initial label, as well as the one showing during the enrollment
- 172. By Jonas G. Drange
-
sync with trunk, udpate pot
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2016-06-17 13:02:38 +0000 |
3 | +++ debian/changelog 2016-06-20 13:58:28 +0000 |
4 | @@ -1,3 +1,10 @@ |
5 | +ubuntu-settings-components (0.8+16.10.20160615-0ubuntu1) UNRELEASED; urgency=medium |
6 | + |
7 | + jonas-drange |
8 | + * Add components for Fingerprint management. |
9 | + |
10 | + -- Jonas G. Drange <jonas.drange@canonical.com> Wed, 15 June 2016 13:17:23 +0200 |
11 | + |
12 | ubuntu-settings-components (0.7+16.10.20160617-0ubuntu1) yakkety; urgency=medium |
13 | |
14 | [ Lukáš Tinkl ] |
15 | @@ -239,7 +246,7 @@ |
16 | ubuntu-settings-components (0.2+14.10.20140701.2-0ubuntu2) utopic; urgency=medium |
17 | |
18 | * debian/control: |
19 | - list qtdeclarative5-ubuntu-ui-toolkit-plugin-gles as an alternative |
20 | + list qtdeclarative5-ubuntu-ui-toolkit-plugin-gles as an alternative |
21 | choice, since provides are not versionned, should restore installability |
22 | on amd64 and i386 |
23 | |
24 | |
25 | === modified file 'debian/control' |
26 | --- debian/control 2016-03-01 15:37:36 +0000 |
27 | +++ debian/control 2016-06-20 13:58:28 +0000 |
28 | @@ -27,7 +27,10 @@ |
29 | Architecture: any |
30 | Multi-Arch: same |
31 | Pre-Depends: dpkg (>= 1.15.6~) |
32 | -Depends: qml-module-qtquick-layouts, |
33 | +Depends: gsettings-ubuntu-schemas (>= 0.0.7), |
34 | + qml-module-biometryd, |
35 | + qml-module-qtquick-layouts, |
36 | + qtdeclarative5-gsettings1.0 (>=0.1+14.10.20140801.1), |
37 | qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.1) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.1), |
38 | suru-icon-theme, |
39 | ${misc:Depends}, |
40 | @@ -35,4 +38,4 @@ |
41 | Breaks: qtdeclarative5-ubuntu-settings-components-assets (<< 0.3), |
42 | Replaces: qtdeclarative5-ubuntu-settings-components-assets (<< 0.3), |
43 | Description: Ubuntu Settings Components |
44 | - Ubuntu settings components for Unity |
45 | \ No newline at end of file |
46 | + Ubuntu settings components for Unity |
47 | |
48 | === added file 'examples/Fingerprint.qml' |
49 | --- examples/Fingerprint.qml 1970-01-01 00:00:00 +0000 |
50 | +++ examples/Fingerprint.qml 2016-06-20 13:58:28 +0000 |
51 | @@ -0,0 +1,43 @@ |
52 | +/* |
53 | + * Copyright 2016 Canonical Ltd. |
54 | + * |
55 | + * This program is free software; you can redistribute it and/or modify |
56 | + * it under the terms of the GNU Lesser General Public License as published by |
57 | + * the Free Software Foundation; version 3. |
58 | + * |
59 | + * This program is distributed in the hope that it will be useful, |
60 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
61 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
62 | + * GNU Lesser General Public License for more details. |
63 | + * |
64 | + * You should have received a copy of the GNU Lesser General Public License |
65 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
66 | + * |
67 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
68 | + */ |
69 | + |
70 | +import QtQuick 2.4 |
71 | +import QtQuick.Layouts 1.2 |
72 | +import Ubuntu.Components 1.3 |
73 | +import Ubuntu.Components.Popups 1.3 |
74 | +import Ubuntu.Components.ListItems 1.3 as ListItems |
75 | +import Ubuntu.Settings.Components 0.1 |
76 | +import Ubuntu.Settings.Fingerprint 0.1 |
77 | + |
78 | +MainView { |
79 | + width: units.gu(50) |
80 | + height: units.gu(90) |
81 | + |
82 | + PageStack { |
83 | + id: pageStack |
84 | + |
85 | + Component.onCompleted: push(fingerprintPage) |
86 | + |
87 | + Component { |
88 | + id: fingerprintPage |
89 | + Fingerprints { |
90 | + onRequestPasscode: passcodeSet = !passcodeSet |
91 | + } |
92 | + } |
93 | + } |
94 | +} |
95 | |
96 | === modified file 'plugins/Ubuntu/Settings/CMakeLists.txt' |
97 | --- plugins/Ubuntu/Settings/CMakeLists.txt 2016-02-05 23:42:02 +0000 |
98 | +++ plugins/Ubuntu/Settings/CMakeLists.txt 2016-06-20 13:58:28 +0000 |
99 | @@ -1,3 +1,4 @@ |
100 | add_subdirectory(Components) |
101 | +add_subdirectory(Fingerprint) |
102 | add_subdirectory(Menus) |
103 | add_subdirectory(Vpn) |
104 | |
105 | === added directory 'plugins/Ubuntu/Settings/Fingerprint' |
106 | === added file 'plugins/Ubuntu/Settings/Fingerprint/CMakeLists.txt' |
107 | --- plugins/Ubuntu/Settings/Fingerprint/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
108 | +++ plugins/Ubuntu/Settings/Fingerprint/CMakeLists.txt 2016-06-20 13:58:28 +0000 |
109 | @@ -0,0 +1,15 @@ |
110 | +project(UbuntuSettingsFingerprintQml) |
111 | + |
112 | +include_directories( |
113 | + ${CMAKE_CURRENT_SOURCE_DIR} |
114 | + ${CMAKE_CURRENT_BINARY_DIR} |
115 | +) |
116 | +add_definitions(-DUBUNTUSETTINGSFINGERPRINT_LIBRARY) |
117 | +QT5_ADD_RESOURCES(assets assets.qrc) |
118 | +add_library(UbuntuSettingsFingerprintQml MODULE |
119 | + plugin.cpp |
120 | + ubuntusettingsfingerprint.cpp |
121 | + ${assets} |
122 | +) |
123 | +qt5_use_modules(UbuntuSettingsFingerprintQml Core Qml Quick) |
124 | +add_usc_plugin(Ubuntu.Settings.Fingerprint 0.1 Ubuntu/Settings/Fingerprint TARGETS UbuntuSettingsFingerprintQml) |
125 | |
126 | === added file 'plugins/Ubuntu/Settings/Fingerprint/CircularSegment.qml' |
127 | --- plugins/Ubuntu/Settings/Fingerprint/CircularSegment.qml 1970-01-01 00:00:00 +0000 |
128 | +++ plugins/Ubuntu/Settings/Fingerprint/CircularSegment.qml 2016-06-20 13:58:28 +0000 |
129 | @@ -0,0 +1,64 @@ |
130 | +/* |
131 | + * Copyright 2016 Canonical Ltd. |
132 | + * |
133 | + * This program is free software; you can redistribute it and/or modify |
134 | + * it under the terms of the GNU Lesser General Public License as published by |
135 | + * the Free Software Foundation; version 3. |
136 | + * |
137 | + * This program is distributed in the hope that it will be useful, |
138 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
139 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
140 | + * GNU Lesser General Public License for more details. |
141 | + * |
142 | + * You should have received a copy of the GNU Lesser General Public License |
143 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
144 | + * |
145 | + * Authored by Florian Boucault <florian.boucault@canonical.com> |
146 | + */ |
147 | + |
148 | +import QtQuick 2.4 |
149 | +import Ubuntu.Components 1.3 |
150 | + |
151 | +ShaderEffect { |
152 | + implicitWidth: units.gu(20) |
153 | + implicitHeight: units.gu(20) |
154 | + height: width |
155 | + |
156 | + property color color: "#3EB34F" |
157 | + property real thickness: units.dp(3) |
158 | + property real angleStop: 90 |
159 | + |
160 | + property real _texturePixel: 1/width |
161 | + property real _thicknessTex: thickness/width |
162 | + property real _angleStopRadians: angleStop * (Math.PI / 180) |
163 | + |
164 | + fragmentShader: " |
165 | + varying mediump vec2 qt_TexCoord0; |
166 | + uniform lowp float qt_Opacity; |
167 | + uniform lowp vec4 color; |
168 | + uniform lowp float _texturePixel; |
169 | + uniform lowp float _thicknessTex; |
170 | + uniform lowp float _angleStopRadians; |
171 | + |
172 | + void main() { |
173 | + mediump vec2 center = vec2(0.5); |
174 | + mediump float circleX = (qt_TexCoord0.x - center.x); |
175 | + mediump float circleY = (qt_TexCoord0.y - center.y); |
176 | + mediump float distanceToCenter = circleX*circleX + circleY*circleY; |
177 | + const mediump float PI = 3.1415926535897932384626433832795; |
178 | + mediump float angle = atan(-circleX, circleY) + PI; |
179 | + |
180 | + mediump float radius = 0.5; |
181 | + mediump float radiusSquare = radius * radius; |
182 | + mediump float radiusInner = radius - _thicknessTex; |
183 | + mediump float radiusInnerSquare = radiusInner * radiusInner; |
184 | + |
185 | + lowp vec4 fillColor = mix(vec4(0), |
186 | + mix(color, vec4(0), smoothstep(distanceToCenter-_texturePixel, distanceToCenter+_texturePixel, radiusInnerSquare)), |
187 | + smoothstep(distanceToCenter-_texturePixel, distanceToCenter+_texturePixel, radiusSquare)); |
188 | + fillColor = mix(fillColor, vec4(0), step(_angleStopRadians, angle)); |
189 | + gl_FragColor = fillColor * qt_Opacity; |
190 | + } |
191 | + " |
192 | +} |
193 | + |
194 | |
195 | === added file 'plugins/Ubuntu/Settings/Fingerprint/DirectionVisual.qml' |
196 | --- plugins/Ubuntu/Settings/Fingerprint/DirectionVisual.qml 1970-01-01 00:00:00 +0000 |
197 | +++ plugins/Ubuntu/Settings/Fingerprint/DirectionVisual.qml 2016-06-20 13:58:28 +0000 |
198 | @@ -0,0 +1,103 @@ |
199 | +/* |
200 | + * Copyright 2016 Canonical Ltd. |
201 | + * |
202 | + * This program is free software; you can redistribute it and/or modify |
203 | + * it under the terms of the GNU Lesser General Public License as published by |
204 | + * the Free Software Foundation; version 3. |
205 | + * |
206 | + * This program is distributed in the hope that it will be useful, |
207 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
208 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
209 | + * GNU Lesser General Public License for more details. |
210 | + * |
211 | + * You should have received a copy of the GNU Lesser General Public License |
212 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
213 | + * |
214 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
215 | + */ |
216 | + |
217 | +import Biometryd 0.0 |
218 | +import QtQuick 2.4 |
219 | +import Ubuntu.Components 1.3 |
220 | +import Ubuntu.Settings.Fingerprint 0.1 |
221 | + |
222 | +Item { |
223 | + property int direction: FingerprintReader.NotAvailable |
224 | + opacity: direction !== FingerprintReader.NotAvailable ? 1 : 0 |
225 | + Behavior on opacity { UbuntuNumberAnimation {} } |
226 | + |
227 | + UbuntuNumberAnimation { |
228 | + id: rotationAnimation |
229 | + alwaysRunToEnd: true |
230 | + |
231 | + target: directionContainer |
232 | + property: "rotation" |
233 | + |
234 | + function normalizeAngle(v) { |
235 | + if (v < 0) |
236 | + return 360 + v; |
237 | + else |
238 | + return v % 360; |
239 | + } |
240 | + |
241 | + onStopped: { |
242 | + directionContainer.rotation = normalizeAngle(directionContainer.rotation); |
243 | + } |
244 | + } |
245 | + |
246 | + onDirectionChanged: { |
247 | + var v1 = rotation; |
248 | + var v2; |
249 | + var length; |
250 | + |
251 | + switch (direction) { |
252 | + case FingerprintReader.North: |
253 | + v2 = 0; break; |
254 | + case FingerprintReader.NorthEast: |
255 | + v2 = 45; break; |
256 | + case FingerprintReader.East: |
257 | + v2 = 90; break; |
258 | + case FingerprintReader.SouthEast: |
259 | + v2 = 135; break; |
260 | + case FingerprintReader.South: |
261 | + v2 = 180; break; |
262 | + case FingerprintReader.SouthWest: |
263 | + v2 = 225; break; |
264 | + case FingerprintReader.West: |
265 | + v2 = 270; break; |
266 | + case FingerprintReader.NorthWest: |
267 | + v2 = 315; break; |
268 | + } |
269 | + |
270 | + length = Math.min(Math.abs(v1 - v2), |
271 | + Math.abs(v1 - 360 - v2), |
272 | + Math.abs(v1 + 360 - v2)); |
273 | + |
274 | + if (length !== 180) |
275 | + length = length % 180; |
276 | + |
277 | + if (((length + v1) % 360) === v2) |
278 | + v1 = v1 + length; |
279 | + else |
280 | + v1 = v1 -length; |
281 | + |
282 | + rotationAnimation.from = rotation; |
283 | + rotationAnimation.to = v1; |
284 | + rotationAnimation.start(); |
285 | + } |
286 | + |
287 | + Icon { |
288 | + id: directionArrow |
289 | + objectName: "fingerprintDirectionLabel" |
290 | + anchors { |
291 | + top: parent.top |
292 | + topMargin: -units.gu(2) |
293 | + horizontalCenter: parent.horizontalCenter |
294 | + } |
295 | + width: units.gu(5) |
296 | + height: width |
297 | + |
298 | + name: "up" |
299 | + color: theme.palette.normal.activity |
300 | + } |
301 | +} |
302 | |
303 | === added file 'plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml' |
304 | --- plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml 1970-01-01 00:00:00 +0000 |
305 | +++ plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml 2016-06-20 13:58:28 +0000 |
306 | @@ -0,0 +1,133 @@ |
307 | +/* |
308 | + * Copyright 2016 Canonical Ltd. |
309 | + * |
310 | + * This program is free software; you can redistribute it and/or modify |
311 | + * it under the terms of the GNU Lesser General Public License as published by |
312 | + * the Free Software Foundation; version 3. |
313 | + * |
314 | + * This program is distributed in the hope that it will be useful, |
315 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
316 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
317 | + * GNU Lesser General Public License for more details. |
318 | + * |
319 | + * You should have received a copy of the GNU Lesser General Public License |
320 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
321 | + * |
322 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
323 | + */ |
324 | + |
325 | +import QtQuick 2.4 |
326 | +import Ubuntu.Components 1.3 |
327 | +import Ubuntu.Components.Popups 1.3 |
328 | +import Ubuntu.Components.Themes.Ambiance 1.3 |
329 | + |
330 | +Page { |
331 | + id: root |
332 | + property string name |
333 | + property string templateId |
334 | + |
335 | + signal requestDeletion(string templateId) |
336 | + signal requestRename(string templateId, string name) |
337 | + |
338 | + function deletionFailed() { |
339 | + PopupUtils.open(deletionFailed); |
340 | + state = ""; |
341 | + } |
342 | + |
343 | + header: PageHeader { |
344 | + objectName: "templateHeader" |
345 | + title: nameInput.text.length > 0 ? nameInput.text : name |
346 | + flickable: flickable |
347 | + } |
348 | + |
349 | + states: [ |
350 | + State { |
351 | + name: "deleting" |
352 | + PropertyChanges { |
353 | + target: nameInput |
354 | + enabled: false |
355 | + } |
356 | + PropertyChanges { |
357 | + target: deleteButton |
358 | + enabled: false |
359 | + } |
360 | + } |
361 | + ] |
362 | + |
363 | + Flickable { |
364 | + id: flickable |
365 | + anchors { |
366 | + fill: parent |
367 | + topMargin: units.gu(2) |
368 | + } |
369 | + boundsBehavior: (contentHeight > root.height) ? |
370 | + Flickable.DragAndOvershootBounds : |
371 | + Flickable.StopAtBounds |
372 | + contentHeight: contentItem.childrenRect.height |
373 | + |
374 | + Column { |
375 | + spacing: units.gu(2) |
376 | + anchors { |
377 | + left: parent.left |
378 | + right: parent.right |
379 | + margins: units.gu(3) |
380 | + } |
381 | + |
382 | + Label { |
383 | + id: nameLabel |
384 | + anchors.left: parent.left |
385 | + anchors.right: parent.right |
386 | + text: i18n.dtr("ubuntu-settings-components", "Fingerprint Name") |
387 | + font.weight: Font.Light |
388 | + } |
389 | + |
390 | + TextField { |
391 | + id: nameInput |
392 | + objectName: "nameInput" |
393 | + anchors.left: parent.left |
394 | + anchors.right: parent.right |
395 | + inputMethodHints: Qt.ImhNoPredictiveText |
396 | + style: TextFieldStyle {} |
397 | + text: name |
398 | + onTextChanged: { |
399 | + if (text) |
400 | + requestRename(templateId, text) |
401 | + } |
402 | + onAccepted: { |
403 | + if (text) { |
404 | + requestRename(templateId, text); |
405 | + pageStack.pop(); |
406 | + } |
407 | + } |
408 | + } |
409 | + |
410 | + Button { |
411 | + id: deleteButton |
412 | + objectName: "templateDelete" |
413 | + text: i18n.dtr("ubuntu-settings-components", "Delete Fingerprint") |
414 | + onClicked: { |
415 | + root.state = "deleting"; |
416 | + requestDeletion(templateId) |
417 | + } |
418 | + width: parent.width |
419 | + } |
420 | + } |
421 | + } |
422 | + |
423 | + Component { |
424 | + id: deletionFailed |
425 | + |
426 | + Dialog { |
427 | + id: deletionFailedDialog |
428 | + objectName: "fingerprintDeletionFailedDialog" |
429 | + text: i18n.dtr("ubuntu-settings-components", |
430 | + "Sorry, the fingerprint could not be deleted.") |
431 | + |
432 | + Button { |
433 | + objectName: "fingerprintDeleteionFailedOk" |
434 | + onClicked: PopupUtils.close(deletionFailedDialog) |
435 | + text: i18n.dtr("ubuntu-settings-components", "OK") |
436 | + } |
437 | + } |
438 | + } |
439 | +} |
440 | |
441 | === added file 'plugins/Ubuntu/Settings/Fingerprint/FingerprintVisual.qml' |
442 | --- plugins/Ubuntu/Settings/Fingerprint/FingerprintVisual.qml 1970-01-01 00:00:00 +0000 |
443 | +++ plugins/Ubuntu/Settings/Fingerprint/FingerprintVisual.qml 2016-06-20 13:58:28 +0000 |
444 | @@ -0,0 +1,72 @@ |
445 | +/* |
446 | + * Copyright 2016 Canonical Ltd. |
447 | + * |
448 | + * This program is free software; you can redistribute it and/or modify |
449 | + * it under the terms of the GNU Lesser General Public License as published by |
450 | + * the Free Software Foundation; version 3. |
451 | + * |
452 | + * This program is distributed in the hope that it will be useful, |
453 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
454 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
455 | + * GNU Lesser General Public License for more details. |
456 | + * |
457 | + * You should have received a copy of the GNU Lesser General Public License |
458 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
459 | + * |
460 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
461 | + * Florian Boucault <florian.boucault@canonical.com> |
462 | + */ |
463 | + |
464 | +import QtQuick 2.4 |
465 | +import Ubuntu.Settings.Fingerprint 0.1 |
466 | + |
467 | +SegmentedImage { |
468 | + id: segmentedImage |
469 | + |
470 | + property var masks: [] |
471 | + |
472 | + // http://stackoverflow.com/a/1830844/538866 |
473 | + function isNumeric (n) { |
474 | + return !isNaN(parseFloat(n)) && isFinite(n); |
475 | + } |
476 | + |
477 | + function getMasksToEnroll () { |
478 | + var outMasks = []; |
479 | + if (masks && masks.length) { |
480 | + masks.forEach(function (mask, i) { |
481 | + // Format is "<source>/[x1,y1,w1,h1],…,[xn,yn,wn,hn]" |
482 | + // If any value is non-numeric, we drop the mask. |
483 | + if (!isNumeric(mask.x) || !isNumeric(mask.y) || !isNumeric(mask.width) |
484 | + || !isNumeric(mask.height)) |
485 | + return; |
486 | + |
487 | + // Translate the box so as to mirror the mask |
488 | + mask.x = (1 - (mask.x + mask.width)); |
489 | + |
490 | + outMasks.push(mask); |
491 | + }); |
492 | + } |
493 | + return outMasks; |
494 | + } |
495 | + |
496 | + onMasksChanged: segmentedImage.enrollMasks(getMasksToEnroll()) |
497 | + |
498 | + textureSource: "qrc:/assets/fingerprint_segmented.png" |
499 | + boxesSource: "qrc:/assets/fingerprint_boxes.json" |
500 | + |
501 | + Repeater { |
502 | + model: segmentedImage.masks |
503 | + |
504 | + Rectangle { |
505 | + visible: UbuntuSettingsFingerprint.debug |
506 | + color: "red" |
507 | + opacity: 0.25 |
508 | + x: modelData.x * segmentedImage.implicitWidth |
509 | + y: modelData.y * segmentedImage.implicitHeight |
510 | + width: modelData.width * segmentedImage.implicitWidth |
511 | + height: modelData.height * segmentedImage.implicitHeight |
512 | + |
513 | + Component.onCompleted: console.log('Scanner mask (x, y, w, h):', x, y, width, height) |
514 | + } |
515 | + } |
516 | +} |
517 | |
518 | === added file 'plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml' |
519 | --- plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml 1970-01-01 00:00:00 +0000 |
520 | +++ plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml 2016-06-20 13:58:28 +0000 |
521 | @@ -0,0 +1,439 @@ |
522 | +/* |
523 | + * Copyright 2016 Canonical Ltd. |
524 | + * |
525 | + * This program is free software; you can redistribute it and/or modify |
526 | + * it under the terms of the GNU Lesser General Public License as published by |
527 | + * the Free Software Foundation; version 3. |
528 | + * |
529 | + * This program is distributed in the hope that it will be useful, |
530 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
531 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
532 | + * GNU Lesser General Public License for more details. |
533 | + * |
534 | + * You should have received a copy of the GNU Lesser General Public License |
535 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
536 | + * |
537 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
538 | + */ |
539 | + |
540 | +import QtQuick 2.4 |
541 | +import QtQuick.Layouts 1.1 |
542 | +import Biometryd 0.0 |
543 | +import GSettings 1.0 |
544 | +import Ubuntu.Components 1.3 |
545 | +import Ubuntu.Components.Popups 1.3 |
546 | +import Ubuntu.Settings.Fingerprint 0.1 |
547 | + |
548 | +Page { |
549 | + id: root |
550 | + objectName: "fingerprintPage" |
551 | + |
552 | + header: PageHeader { |
553 | + title: i18n.dtr("ubuntu-settings-components", "Fingerprint ID") |
554 | + flickable: content |
555 | + } |
556 | + |
557 | + property var _ts: Biometryd.defaultDevice.templateStore |
558 | + property var _enrollmentOperation: null |
559 | + property var _clearanceOperation: null |
560 | + property var _removalOperation: null |
561 | + property var _listOperation: null |
562 | + property var _setupPage: null |
563 | + property var _fpInstancePage: null |
564 | + property var _settings: sysSettings |
565 | + |
566 | + property Dialog _diag: null |
567 | + property bool passcodeSet: false |
568 | + |
569 | + function enroll () { |
570 | + _enrollmentOperation = _ts.enroll(user); |
571 | + _enrollmentOperation.start(enrollmentObserver); |
572 | + } |
573 | + |
574 | + function cancel () { |
575 | + if (_enrollmentOperation) |
576 | + _enrollmentOperation.cancel(); |
577 | + } |
578 | + |
579 | + function clear() { |
580 | + _clearanceOperation = _ts.clear(user); |
581 | + _clearanceOperation.start(clearanceObserver); |
582 | + } |
583 | + |
584 | + function removeTemplate(templateId) { |
585 | + var names = sysSettings.fingerprintNames; |
586 | + delete names[templateId]; |
587 | + sysSettings.fingerprintNames = names; |
588 | + } |
589 | + |
590 | + function renameTemplate(templateId, newName) { |
591 | + var names = sysSettings.fingerprintNames; |
592 | + names[templateId] = newName; |
593 | + sysSettings.fingerprintNames = names; |
594 | + } |
595 | + |
596 | + function addTemplate(templateId, name) { |
597 | + var names = sysSettings.fingerprintNames; |
598 | + names[templateId] = name; |
599 | + sysSettings.fingerprintNames = names; |
600 | + } |
601 | + |
602 | + function createTemplateName() { |
603 | + var map = sysSettings.fingerprintNames; |
604 | + var currentNames = []; |
605 | + var newName; |
606 | + for (var k in map) { |
607 | + if (map.hasOwnProperty(k)) |
608 | + currentNames.push(map[k]); |
609 | + } |
610 | + |
611 | + var i = 0; |
612 | + do { |
613 | + newName = i18n.dtr("ubuntu-settings-components", |
614 | + "Finger %1").arg(++i); // Start at 1 |
615 | + } while (currentNames.indexOf(newName) >= 0); |
616 | + return newName; |
617 | + } |
618 | + |
619 | + // Assign names to unnamed fingerprints. This exist because we can't |
620 | + // guarantee that all fingerprints get names (i.e. enrollment can complete |
621 | + // after System Settings closes). |
622 | + function assignNames(templateIds) { |
623 | + var names = sysSettings.fingerprintNames; |
624 | + for (var i = 0; i < templateIds.length; i++) { |
625 | + if ( !(templateIds[i] in names) || !names[templateIds[i]]) |
626 | + names[templateIds[i]] = createTemplateName(); |
627 | + sysSettings.fingerprintNames = names; |
628 | + } |
629 | + } |
630 | + |
631 | + signal requestPasscode() |
632 | + |
633 | + Component.onCompleted: { |
634 | + // Start a list operation immediately. |
635 | + if (Biometryd.available) { |
636 | + _listOperation = _ts.list(user); |
637 | + _listOperation.start(listObserver); |
638 | + } |
639 | + } |
640 | + |
641 | + Component.onDestruction: { |
642 | + if (_enrollmentOperation) |
643 | + _enrollmentOperation.cancel(); |
644 | + |
645 | + if (_clearanceOperation) |
646 | + _clearanceOperation.cancel(); |
647 | + |
648 | + if (_removalOperation) |
649 | + _removalOperation.cancel(); |
650 | + |
651 | + if (_listOperation) |
652 | + _listOperation.cancel(); |
653 | + } |
654 | + |
655 | + states: [ |
656 | + State { |
657 | + name: "noPasscode" |
658 | + PropertyChanges { |
659 | + target: setupPasscode |
660 | + visible: true |
661 | + } |
662 | + PropertyChanges { |
663 | + target: setupFingerprint |
664 | + enabled: false |
665 | + } |
666 | + PropertyChanges { |
667 | + target: fingerprintsList |
668 | + enabled: false |
669 | + } |
670 | + when: !passcodeSet |
671 | + }, |
672 | + State { |
673 | + name: "noScanner" |
674 | + PropertyChanges { |
675 | + target: setupFingerprint |
676 | + enabled: false |
677 | + } |
678 | + PropertyChanges { |
679 | + target: fingerprintsList |
680 | + visible: false |
681 | + } |
682 | + when: !Biometryd.available |
683 | + } |
684 | + ] |
685 | + |
686 | + Flickable { |
687 | + id: content |
688 | + anchors.fill: parent |
689 | + boundsBehavior: (contentHeight > root.height) ? |
690 | + Flickable.DragAndOvershootBounds : |
691 | + Flickable.StopAtBounds |
692 | + contentHeight: contentItem.childrenRect.height |
693 | + |
694 | + Column { |
695 | + anchors { left: parent.left; right: parent.right } |
696 | + |
697 | + Column { |
698 | + id: setupPasscode |
699 | + anchors { left: parent.left; right: parent.right } |
700 | + visible: false |
701 | + |
702 | + ListItem { |
703 | + height: setPcodeLayout.height + (divider.visible ? divider.height : 0) |
704 | + ListItemLayout { |
705 | + id: setPcodeLayout |
706 | + title.text: i18n.dtr( |
707 | + "ubuntu-settings-components", |
708 | + "Passcode required" |
709 | + ) |
710 | + subtitle.text: i18n.dtr( |
711 | + "ubuntu-settings-components", |
712 | + "You must set a passcode to use fingerprint ID" |
713 | + ) |
714 | + Button { |
715 | + objectName: "fingerprintSetPasscodeButton" |
716 | + onClicked: root.requestPasscode() |
717 | + text: i18n.dtr( |
718 | + "ubuntu-settings-components", |
719 | + "Set Passcode…" |
720 | + ) |
721 | + } |
722 | + } |
723 | + } |
724 | + } |
725 | + |
726 | + Column { |
727 | + id: fingerprints |
728 | + anchors { left: parent.left; right: parent.right } |
729 | + |
730 | + Repeater { |
731 | + id: fingerprintsList |
732 | + property bool enabled: true |
733 | + objectName: "fingerprintsList" |
734 | + model: { |
735 | + var map = sysSettings.fingerprintNames; |
736 | + var m = []; |
737 | + for (var k in map) { |
738 | + if (map.hasOwnProperty(k)) { |
739 | + m.push({ |
740 | + templateId: k, |
741 | + name: map[k] |
742 | + }); |
743 | + } |
744 | + } |
745 | + m.sort(function (a, b) { |
746 | + if (a.name < b.name) return -1; |
747 | + if (a.name > b.name) return 1; |
748 | + if (a.name == b.name) return 0; |
749 | + }); |
750 | + return m; |
751 | + } |
752 | + |
753 | + ListItem { |
754 | + height: fpLayout.height + (divider.visible ? divider.height : 0) |
755 | + onClicked: _fpInstancePage = pageStack.push( |
756 | + Qt.resolvedUrl("Fingerprint.qml"), { |
757 | + name: modelData.name, |
758 | + templateId: modelData.templateId |
759 | + } |
760 | + ) |
761 | + enabled: fingerprintsList.enabled |
762 | + |
763 | + ListItemLayout { |
764 | + id: fpLayout |
765 | + objectName: "fingerprintInstance-" + index |
766 | + title.text: modelData.name |
767 | + |
768 | + ProgressionSlot {} |
769 | + } |
770 | + } |
771 | + } |
772 | + } |
773 | + |
774 | + Column { |
775 | + id: setupFingerprint |
776 | + |
777 | + anchors { left: parent.left; right: parent.right } |
778 | + objectName: "fingerprintSetupEntry" |
779 | + property bool enabled: true |
780 | + spacing: units.gu(2) |
781 | + |
782 | + ListItem { |
783 | + height: addFpLayout.height + (divider.visible ? divider.height : 0) |
784 | + onClicked: { |
785 | + _setupPage = pageStack.push(Qt.resolvedUrl("Setup.qml")); |
786 | + root.enroll(); |
787 | + } |
788 | + enabled: parent.enabled |
789 | + |
790 | + ListItemLayout { |
791 | + id: addFpLayout |
792 | + objectName: "fingerprintAddListItemLayout" |
793 | + title.text: i18n.dtr( |
794 | + "ubuntu-settings-components", |
795 | + "Add fingerprint" |
796 | + ) |
797 | + |
798 | + ProgressionSlot {} |
799 | + } |
800 | + } |
801 | + |
802 | + Button { |
803 | + anchors.horizontalCenter: parent.horizontalCenter |
804 | + enabled: fingerprintsList.model.length > 0 |
805 | + objectName: "fingerprintRemoveAllButton" |
806 | + onClicked: _diag = PopupUtils.open(removeAllAlert) |
807 | + text: i18n.dtr("ubuntu-settings-components", |
808 | + "Remove All…") |
809 | + } |
810 | + } |
811 | + } |
812 | + } |
813 | + |
814 | + Component { |
815 | + id: removeAllAlert |
816 | + |
817 | + Dialog { |
818 | + id: removeAllAlertDialog |
819 | + |
820 | + objectName: "fingerprintRemoveAllDialog" |
821 | + text: i18n.dtr( |
822 | + "ubuntu-settings-components", |
823 | + "Are you sure you want to forget all stored fingerprints?" |
824 | + ) |
825 | + |
826 | + RowLayout { |
827 | + anchors { left: parent.left; right: parent.right } |
828 | + spacing: units.gu(2) |
829 | + |
830 | + Button { |
831 | + onClicked: PopupUtils.close(removeAllAlertDialog) |
832 | + text: i18n.dtr("ubuntu-settings-components", "Cancel") |
833 | + Layout.fillWidth: true |
834 | + } |
835 | + |
836 | + Button { |
837 | + objectName: "fingerprintRemoveAllConfirmationButton" |
838 | + onClicked: root.clear() |
839 | + text: i18n.dtr("ubuntu-settings-components", "Remove") |
840 | + Layout.fillWidth: true |
841 | + } |
842 | + } |
843 | + } |
844 | + } |
845 | + |
846 | + Component { |
847 | + id: fingerprintReaderBroken |
848 | + |
849 | + Dialog { |
850 | + id: fingerprintReaderBrokenDialog |
851 | + objectName: "fingerprintReaderBrokenDialog" |
852 | + text: i18n.dtr("ubuntu-settings-components", |
853 | + "Sorry, the reader doesn’t seem to be working.") |
854 | + |
855 | + Button { |
856 | + objectName: "fingerprintReaderBrokenDialogOK" |
857 | + onClicked: PopupUtils.close(fingerprintReaderBrokenDialog) |
858 | + text: i18n.dtr("ubuntu-settings-components", "OK") |
859 | + } |
860 | + } |
861 | + } |
862 | + |
863 | + Connections { |
864 | + target: _setupPage |
865 | + onEnroll: root.enroll() |
866 | + onCancel: root.cancel() |
867 | + } |
868 | + |
869 | + Connections { |
870 | + target: _fpInstancePage |
871 | + |
872 | + onRequestDeletion: { |
873 | + _removalOperation = _ts.remove(user, templateId); |
874 | + _removalOperation.start(removalObserver); |
875 | + } |
876 | + onRequestRename: renameTemplate(templateId, name) |
877 | + } |
878 | + |
879 | + Observer { |
880 | + id: enrollmentObserver |
881 | + objectName: "enrollmentObserver" |
882 | + onFailed: { |
883 | + if (_setupPage) |
884 | + _setupPage.enrollmentFailed(reason); |
885 | + _enrollmentOperation = null; |
886 | + console.error("Enrollment failed", reason); |
887 | + } |
888 | + onCanceled: _enrollmentOperation = null |
889 | + onProgressed: _setupPage.enrollmentProgressed(percent, details) |
890 | + onSucceeded: { |
891 | + if (!(result in sysSettings.fingerprintNames)) |
892 | + root.addTemplate(result, root.createTemplateName()); |
893 | + if (_setupPage) |
894 | + _setupPage.enrollmentCompleted(); |
895 | + _enrollmentOperation = null; |
896 | + } |
897 | + } |
898 | + |
899 | + Observer { |
900 | + id: clearanceObserver |
901 | + objectName: "clearanceObserver" |
902 | + onFailed: { |
903 | + _clearanceOperation = null; |
904 | + if (_diag) PopupUtils.close(_diag); |
905 | + _diag = PopupUtils.open(fingerprintReaderBroken); |
906 | + console.error("Biometry clearance failed:", reason); |
907 | + } |
908 | + onCanceled: _clearanceOperation = null |
909 | + onSucceeded: { |
910 | + _clearanceOperation = null; |
911 | + if (_diag) PopupUtils.close(_diag); |
912 | + sysSettings.fingerprintNames = {}; |
913 | + } |
914 | + } |
915 | + |
916 | + Observer { |
917 | + id: removalObserver |
918 | + objectName: "removalObserver" |
919 | + onFailed: { |
920 | + _removalOperation = null; |
921 | + if (_fpInstancePage) |
922 | + _fpInstancePage.deletionFailed() |
923 | + console.error("Biometryd template deletion failed:", reason); |
924 | + } |
925 | + onCanceled: _removalOperation = null |
926 | + onSucceeded: { |
927 | + _removalOperation = null; |
928 | + if (pageStack.currentPage === _fpInstancePage) |
929 | + pageStack.pop(); |
930 | + root.removeTemplate(result); |
931 | + } |
932 | + } |
933 | + |
934 | + Observer { |
935 | + id: listObserver |
936 | + objectName: "listObserver" |
937 | + onFailed: { |
938 | + _listOperation = null; |
939 | + if (_diag) PopupUtils.close(_diag); |
940 | + _diag = PopupUtils.open(fingerprintReaderBroken); |
941 | + console.error("Biometryd list failed:", reason); |
942 | + } |
943 | + onCanceled: _listOperation = null |
944 | + onSucceeded: { |
945 | + _listOperation = null; |
946 | + root.assignNames(result); |
947 | + } |
948 | + } |
949 | + |
950 | + User { |
951 | + id: user |
952 | + uid: UbuntuSettingsFingerprint.uid |
953 | + } |
954 | + |
955 | + GSettings { |
956 | + id: sysSettings |
957 | + objectName: "systemSettings" |
958 | + schema.id: "com.ubuntu.touch.system" |
959 | + } |
960 | +} |
961 | |
962 | === added file 'plugins/Ubuntu/Settings/Fingerprint/SegmentBoundingBoxes.qml' |
963 | --- plugins/Ubuntu/Settings/Fingerprint/SegmentBoundingBoxes.qml 1970-01-01 00:00:00 +0000 |
964 | +++ plugins/Ubuntu/Settings/Fingerprint/SegmentBoundingBoxes.qml 2016-06-20 13:58:28 +0000 |
965 | @@ -0,0 +1,81 @@ |
966 | +/* |
967 | + * Copyright 2016 Canonical Ltd. |
968 | + * |
969 | + * This program is free software; you can redistribute it and/or modify |
970 | + * it under the terms of the GNU Lesser General Public License as published by |
971 | + * the Free Software Foundation; version 3. |
972 | + * |
973 | + * This program is distributed in the hope that it will be useful, |
974 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
975 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
976 | + * GNU Lesser General Public License for more details. |
977 | + * |
978 | + * You should have received a copy of the GNU Lesser General Public License |
979 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
980 | + * |
981 | + * Authored by Florian Boucault <florian.boucault@canonical.com> |
982 | + */ |
983 | + |
984 | +import QtQuick 2.4 |
985 | + |
986 | +QtObject { |
987 | + id: segmentBoundingBoxes |
988 | + |
989 | + property string source |
990 | + onSourceChanged: parseBoundingBoxes(source) |
991 | + |
992 | + property var boundingBoxes: [] |
993 | + property real width |
994 | + property real height |
995 | + property int count: boundingBoxes.length |
996 | + |
997 | + // The API cannot be used reliably before this signal has been emitted. |
998 | + signal ready() |
999 | + |
1000 | + function parseBoundingBoxes(source) { |
1001 | + var xhr = new XMLHttpRequest; |
1002 | + xhr.open("GET", source); |
1003 | + xhr.onreadystatechange = function() { |
1004 | + if (xhr.readyState == XMLHttpRequest.DONE) { |
1005 | + var b = []; |
1006 | + var json = JSON.parse(xhr.responseText); |
1007 | + boundingBoxes = json["boxes"]; |
1008 | + width = json["width"]; |
1009 | + height = json["height"]; |
1010 | + ready(); |
1011 | + } |
1012 | + } |
1013 | + xhr.send(); |
1014 | + } |
1015 | + |
1016 | + function intersects(box1, box2) { |
1017 | + // TODO: optimize |
1018 | + var x11 = box1[0]; |
1019 | + var y11 = box1[1]; |
1020 | + var x12 = box1[0] + box1[2]; |
1021 | + var y12 = box1[1] + box1[3]; |
1022 | + var x21 = box2[0]; |
1023 | + var y21 = box2[1]; |
1024 | + var x22 = box2[0] + box2[2]; |
1025 | + var y22 = box2[1] + box2[3]; |
1026 | + var x_overlap = Math.max(0, Math.min(x12,x22) - Math.max(x11,x21)); |
1027 | + var y_overlap = Math.max(0, Math.min(y12,y22) - Math.max(y11,y21)); |
1028 | + return (x_overlap / Math.min(box1[2], box2[2]) > 0.25 |
1029 | + && y_overlap / Math.min(box1[3], box2[3]) > 0.25); |
1030 | + } |
1031 | + |
1032 | + function computeIntersections(hitBox) { |
1033 | + var absoluteHitBox = [hitBox[0] * width, hitBox[1] * height, |
1034 | + hitBox[2] * width, hitBox[3] * height]; |
1035 | + |
1036 | + var intersections = []; |
1037 | + for (var i in boundingBoxes) { |
1038 | + var boundingBox = boundingBoxes[i]; |
1039 | + if (intersects(absoluteHitBox, boundingBox)) { |
1040 | + intersections.push(i); |
1041 | + } |
1042 | + } |
1043 | + |
1044 | + return intersections; |
1045 | + } |
1046 | +} |
1047 | |
1048 | === added file 'plugins/Ubuntu/Settings/Fingerprint/SegmentRenderer.qml' |
1049 | --- plugins/Ubuntu/Settings/Fingerprint/SegmentRenderer.qml 1970-01-01 00:00:00 +0000 |
1050 | +++ plugins/Ubuntu/Settings/Fingerprint/SegmentRenderer.qml 2016-06-20 13:58:28 +0000 |
1051 | @@ -0,0 +1,95 @@ |
1052 | +/* |
1053 | + * Copyright 2016 Canonical Ltd. |
1054 | + * |
1055 | + * This program is free software; you can redistribute it and/or modify |
1056 | + * it under the terms of the GNU Lesser General Public License as published by |
1057 | + * the Free Software Foundation; version 3. |
1058 | + * |
1059 | + * This program is distributed in the hope that it will be useful, |
1060 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1061 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1062 | + * GNU Lesser General Public License for more details. |
1063 | + * |
1064 | + * You should have received a copy of the GNU Lesser General Public License |
1065 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1066 | + * |
1067 | + * Authored by Florian Boucault <florian.boucault@canonical.com> |
1068 | + */ |
1069 | + |
1070 | +import QtQuick 2.4 |
1071 | +import Ubuntu.Components 1.3 |
1072 | + |
1073 | +ShaderEffect { |
1074 | + id: segmentRenderer |
1075 | + |
1076 | + implicitWidth: texture.width |
1077 | + implicitHeight: texture.height |
1078 | + |
1079 | + function animate(segments) { |
1080 | + for (var i in segments) { |
1081 | + var progressPixel = progressTexture.children[segments[i]]; |
1082 | + if (progressPixel.progress == 0.0) { |
1083 | + progressPixel.animation.start(); |
1084 | + } |
1085 | + } |
1086 | + } |
1087 | + |
1088 | + property string source |
1089 | + property int segmentsCount |
1090 | + property color backgroundColor: theme.palette.normal.base |
1091 | + property color fillColor: theme.palette.normal.activity |
1092 | + property Image texture: Image { |
1093 | + source: segmentRenderer.source |
1094 | + } |
1095 | + property var progressTexture: progressTexture |
1096 | + property int progressTextureSize: progressTexture.size |
1097 | + |
1098 | + fragmentShader: " |
1099 | + varying mediump vec2 qt_TexCoord0; |
1100 | + uniform lowp float qt_Opacity; |
1101 | + uniform lowp vec4 backgroundColor; |
1102 | + uniform lowp vec4 fillColor; |
1103 | + uniform lowp sampler2D texture; |
1104 | + uniform lowp sampler2D progressTexture; |
1105 | + uniform lowp int progressTextureSize; |
1106 | + |
1107 | + void main() { |
1108 | + lowp vec4 p = texture2D(texture, qt_TexCoord0); |
1109 | + lowp float segment = p.r * 255.0; |
1110 | + lowp vec4 segmentProgress = step(0.9, segment) * texture2D(progressTexture, vec2((segment - 1.0 + 0.5) / float(progressTextureSize), 0.5)); |
1111 | + lowp vec4 color = mix(fillColor, backgroundColor, step(segmentProgress.r, p.g)); |
1112 | + gl_FragColor = vec4(color.rgb, 1.0) * p.b * qt_Opacity; |
1113 | + } |
1114 | + " |
1115 | + |
1116 | + // TODO: not the most efficient; could be replaced with an image provider |
1117 | + Row { |
1118 | + id: progressTexture |
1119 | + |
1120 | + property int size: 128 |
1121 | + layer.enabled: true |
1122 | + layer.sourceRect: Qt.rect(0, 0, size, 1) |
1123 | + layer.textureSize: Qt.size(size, 1) |
1124 | + layer.wrapMode: ShaderEffectSource.ClampToEdge |
1125 | + visible: false |
1126 | + |
1127 | + Repeater { |
1128 | + model: segmentRenderer.segmentsCount |
1129 | + Rectangle { |
1130 | + id: progressPixel |
1131 | + width: 1 |
1132 | + height: 1 |
1133 | + color: Qt.rgba(progress, progress, progress, 1.0) |
1134 | + property real progress |
1135 | + property NumberAnimation animation: NumberAnimation { |
1136 | + target: progressPixel |
1137 | + property: "progress" |
1138 | + from: 0.0 |
1139 | + to: 1.0 |
1140 | + duration: UbuntuAnimation.SleepyDuration |
1141 | + easing: UbuntuAnimation.StandardEasing |
1142 | + } |
1143 | + } |
1144 | + } |
1145 | + } |
1146 | +} |
1147 | |
1148 | === added file 'plugins/Ubuntu/Settings/Fingerprint/SegmentedImage.qml' |
1149 | --- plugins/Ubuntu/Settings/Fingerprint/SegmentedImage.qml 1970-01-01 00:00:00 +0000 |
1150 | +++ plugins/Ubuntu/Settings/Fingerprint/SegmentedImage.qml 2016-06-20 13:58:28 +0000 |
1151 | @@ -0,0 +1,52 @@ |
1152 | +/* |
1153 | + * Copyright 2016 Canonical Ltd. |
1154 | + * |
1155 | + * This program is free software; you can redistribute it and/or modify |
1156 | + * it under the terms of the GNU Lesser General Public License as published by |
1157 | + * the Free Software Foundation; version 3. |
1158 | + * |
1159 | + * This program is distributed in the hope that it will be useful, |
1160 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1161 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1162 | + * GNU Lesser General Public License for more details. |
1163 | + * |
1164 | + * You should have received a copy of the GNU Lesser General Public License |
1165 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1166 | + * |
1167 | + * Authored by Florian Boucault <florian.boucault@canonical.com> |
1168 | + */ |
1169 | + |
1170 | +import QtQuick 2.4 |
1171 | + |
1172 | +Item { |
1173 | + id: segImg |
1174 | + property alias textureSource: segmentRenderer.source |
1175 | + property alias boxesSource: segmentBoundingBoxes.source |
1176 | + |
1177 | + implicitWidth: segmentRenderer.implicitWidth |
1178 | + implicitHeight: segmentRenderer.implicitHeight |
1179 | + |
1180 | + // Ready to enroll. |
1181 | + signal ready() |
1182 | + |
1183 | + function enrollMasks(masks) { |
1184 | + if (masks && masks.length) { |
1185 | + var segments = []; |
1186 | + masks.forEach(function (mask, i) { |
1187 | + var hitBox = [mask.x, mask.y, mask.width, mask.height]; |
1188 | + segments = segments.concat(segmentBoundingBoxes.computeIntersections(hitBox)); |
1189 | + }); |
1190 | + segmentRenderer.animate(segments); |
1191 | + } |
1192 | + } |
1193 | + |
1194 | + SegmentRenderer { |
1195 | + id: segmentRenderer |
1196 | + segmentsCount: segmentBoundingBoxes.count |
1197 | + } |
1198 | + |
1199 | + SegmentBoundingBoxes { |
1200 | + id: segmentBoundingBoxes |
1201 | + onReady: segImg.ready() |
1202 | + } |
1203 | +} |
1204 | |
1205 | === added file 'plugins/Ubuntu/Settings/Fingerprint/Setup.qml' |
1206 | --- plugins/Ubuntu/Settings/Fingerprint/Setup.qml 1970-01-01 00:00:00 +0000 |
1207 | +++ plugins/Ubuntu/Settings/Fingerprint/Setup.qml 2016-06-20 13:58:28 +0000 |
1208 | @@ -0,0 +1,387 @@ |
1209 | +/* |
1210 | + * Copyright 2016 Canonical Ltd. |
1211 | + * |
1212 | + * This program is free software; you can redistribute it and/or modify |
1213 | + * it under the terms of the GNU Lesser General Public License as published by |
1214 | + * the Free Software Foundation; version 3. |
1215 | + * |
1216 | + * This program is distributed in the hope that it will be useful, |
1217 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1218 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1219 | + * GNU Lesser General Public License for more details. |
1220 | + * |
1221 | + * You should have received a copy of the GNU Lesser General Public License |
1222 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1223 | + * |
1224 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
1225 | + */ |
1226 | + |
1227 | +import Biometryd 0.0 |
1228 | +import QtQuick 2.4 |
1229 | +import QtQuick.Layouts 1.1 |
1230 | +import Ubuntu.Components 1.3 |
1231 | +import Ubuntu.Settings.Fingerprint 0.1 |
1232 | + |
1233 | +Page { |
1234 | + id: root |
1235 | + |
1236 | + objectName: "fingerprintSetupPage" |
1237 | + |
1238 | + signal enroll() |
1239 | + signal cancel() |
1240 | + |
1241 | + function enrollmentFailed(error) { |
1242 | + root.state = "failed"; |
1243 | + } |
1244 | + |
1245 | + function enrollmentCompleted() { |
1246 | + root.state = "done"; |
1247 | + } |
1248 | + |
1249 | + function enrollmentProgressed(progress, hints) { |
1250 | + root.state = "reading"; |
1251 | + imageDefault.masks = hints[FingerprintReader.masks]; |
1252 | + progressLabel.progress = 100 * progress; |
1253 | + directionContainer.direction = hints[FingerprintReader.suggestedNextDirection] || FingerprintReader.NotAvailable; |
1254 | + } |
1255 | + |
1256 | + states: [ |
1257 | + State { |
1258 | + name: "" |
1259 | + StateChangeScript { |
1260 | + script: statusLabel.setText(statusLabel.initialText) |
1261 | + } |
1262 | + }, |
1263 | + State { |
1264 | + name: "reading" |
1265 | + StateChangeScript { |
1266 | + script: statusLabel.setText( |
1267 | + i18n.dtr("ubuntu-settings-components", |
1268 | + "Swipe your finger repeatedly over the reader.") |
1269 | + ) |
1270 | + } |
1271 | + PropertyChanges { |
1272 | + target: imageDefault |
1273 | + opacity: 1 |
1274 | + } |
1275 | + PropertyChanges { |
1276 | + target: progressLabel |
1277 | + opacity: 1 |
1278 | + } |
1279 | + }, |
1280 | + State { |
1281 | + name: "longer" |
1282 | + StateChangeScript { |
1283 | + script: statusLabel.setText( |
1284 | + i18n.dtr("ubuntu-settings-components", |
1285 | + "Keep your finger on the reader for longer.") |
1286 | + ) |
1287 | + } |
1288 | + }, |
1289 | + State { |
1290 | + name: "failed" |
1291 | + PropertyChanges { |
1292 | + target: imageDefault |
1293 | + opacity: 0 |
1294 | + } |
1295 | + PropertyChanges { |
1296 | + target: imageFailed |
1297 | + opacity: 1 |
1298 | + } |
1299 | + PropertyChanges { |
1300 | + target: cancelButton |
1301 | + text: i18n.dtr("ubuntu-settings-components", "Back"); |
1302 | + } |
1303 | + PropertyChanges { |
1304 | + target: doneButton |
1305 | + visible: false |
1306 | + } |
1307 | + StateChangeScript { |
1308 | + script: statusLabel.setText( |
1309 | + i18n.dtr("ubuntu-settings-components", |
1310 | + "Sorry, the reader doesn’t seem to be working."), |
1311 | + true // No animation |
1312 | + ) |
1313 | + } |
1314 | + StateChangeScript { |
1315 | + script: imageFailed.start() |
1316 | + } |
1317 | + PropertyChanges { |
1318 | + target: directionContainer |
1319 | + opacity: 0 |
1320 | + } |
1321 | + }, |
1322 | + State { |
1323 | + name: "done" |
1324 | + PropertyChanges { |
1325 | + target: imageDefault |
1326 | + opacity: 0 |
1327 | + } |
1328 | + PropertyChanges { |
1329 | + target: imageDone |
1330 | + opacity: 1 |
1331 | + } |
1332 | + PropertyChanges { |
1333 | + target: cancelButton |
1334 | + visible: false |
1335 | + } |
1336 | + StateChangeScript { |
1337 | + script: statusLabel.setText( |
1338 | + i18n.dtr("ubuntu-settings-components", "All done!"), |
1339 | + true // No animation |
1340 | + ) |
1341 | + } |
1342 | + PropertyChanges { |
1343 | + target: doneButton |
1344 | + enabled: true |
1345 | + text: i18n.dtr("ubuntu-settings-components", "OK") |
1346 | + } |
1347 | + StateChangeScript { |
1348 | + script: imageDone.start() |
1349 | + } |
1350 | + PropertyChanges { |
1351 | + target: directionContainer |
1352 | + opacity: 0 |
1353 | + } |
1354 | + } |
1355 | + ] |
1356 | + |
1357 | + header: PageHeader { |
1358 | + visible: false |
1359 | + } |
1360 | + |
1361 | + Item { |
1362 | + anchors.fill: parent |
1363 | + |
1364 | + Item { |
1365 | + id: fingerprintBox |
1366 | + anchors.centerIn: parent |
1367 | + width: units.gu(26) |
1368 | + height: units.gu(29) |
1369 | + |
1370 | + Item { |
1371 | + id: imageContainer |
1372 | + anchors.centerIn: parent |
1373 | + width: imageDefault.implicitWidth |
1374 | + height: imageDefault.implicitHeight |
1375 | + |
1376 | + // Default image. |
1377 | + FingerprintVisual { |
1378 | + id: imageDefault |
1379 | + objectName: "fingerprintDefaultVisual" |
1380 | + anchors.centerIn: parent |
1381 | + |
1382 | + Behavior on opacity { UbuntuNumberAnimation { |
1383 | + duration: UbuntuAnimation.SlowDuration |
1384 | + easing: UbuntuAnimation.StandardEasing |
1385 | + }} |
1386 | + } |
1387 | + |
1388 | + // Failed image. |
1389 | + CircularSegment { |
1390 | + id: imageFailed |
1391 | + objectName: "fingerprintFailedVisual" |
1392 | + opacity: 0 |
1393 | + color: "#ED3146" |
1394 | + width: directionContainer.width - units.dp(3) |
1395 | + |
1396 | + anchors.centerIn: parent |
1397 | + |
1398 | + function start () { |
1399 | + failAngstopAnim.start(); |
1400 | + failThichAnim.start(); |
1401 | + } |
1402 | + |
1403 | + NumberAnimation on angleStop { |
1404 | + id: failAngstopAnim |
1405 | + running: false |
1406 | + from: 0 |
1407 | + to: 360 |
1408 | + duration: UbuntuAnimation.SlowDuration |
1409 | + easing: UbuntuAnimation.StandardEasing |
1410 | + } |
1411 | + |
1412 | + NumberAnimation on thickness { |
1413 | + id: failThichAnim |
1414 | + running: false |
1415 | + from: 0 |
1416 | + to: units.dp(3) |
1417 | + duration: UbuntuAnimation.SlowDuration |
1418 | + easing: UbuntuAnimation.StandardEasing |
1419 | + } |
1420 | + |
1421 | + Icon { |
1422 | + name: "close" |
1423 | + color: "#ED3146" |
1424 | + width: units.gu(18) |
1425 | + anchors.centerIn: parent |
1426 | + } |
1427 | + |
1428 | + Behavior on opacity { UbuntuNumberAnimation { |
1429 | + duration: UbuntuAnimation.SlowDuration |
1430 | + easing: UbuntuAnimation.StandardEasing |
1431 | + }} |
1432 | + } |
1433 | + |
1434 | + // Done image. |
1435 | + CircularSegment { |
1436 | + id: imageDone |
1437 | + objectName: "fingerprintDoneVisual" |
1438 | + opacity: 0 |
1439 | + width: directionContainer.width - units.dp(3) |
1440 | + |
1441 | + anchors.centerIn: parent |
1442 | + |
1443 | + function start () { |
1444 | + angstopAnim.start(); |
1445 | + thickAnim.start(); |
1446 | + } |
1447 | + |
1448 | + NumberAnimation on angleStop { |
1449 | + id: angstopAnim |
1450 | + running: false |
1451 | + from: 0 |
1452 | + to: 360 |
1453 | + duration: UbuntuAnimation.SlowDuration |
1454 | + easing: UbuntuAnimation.StandardEasing |
1455 | + } |
1456 | + |
1457 | + NumberAnimation on thickness { |
1458 | + id: thickAnim |
1459 | + running: false |
1460 | + from: 0 |
1461 | + to: units.dp(3) |
1462 | + duration: UbuntuAnimation.SlowDuration |
1463 | + easing: UbuntuAnimation.StandardEasing |
1464 | + } |
1465 | + |
1466 | + Icon { |
1467 | + name: "tick" |
1468 | + color: "#3EB34F" |
1469 | + width: units.gu(18) |
1470 | + anchors.centerIn: parent |
1471 | + } |
1472 | + |
1473 | + Behavior on opacity { UbuntuNumberAnimation { |
1474 | + duration: UbuntuAnimation.SlowDuration |
1475 | + easing: UbuntuAnimation.StandardEasing |
1476 | + }} |
1477 | + } |
1478 | + |
1479 | + DirectionVisual { |
1480 | + id: directionContainer |
1481 | + objectName: "fingerprintDirectionVisual" |
1482 | + anchors.centerIn: parent |
1483 | + |
1484 | + width: Math.sqrt( |
1485 | + imageContainer.width*imageContainer.width |
1486 | + + imageContainer.height*imageContainer.height |
1487 | + ) |
1488 | + height: width |
1489 | + } |
1490 | + } |
1491 | + } |
1492 | + |
1493 | + StatusLabel { |
1494 | + id: statusLabel |
1495 | + anchors { |
1496 | + left: parent.left |
1497 | + leftMargin: units.gu(2.9) |
1498 | + right: parent.right |
1499 | + rightMargin: units.gu(2.9) |
1500 | + top: parent.top |
1501 | + topMargin: units.gu(5) |
1502 | + } |
1503 | + initialText: i18n.dtr("ubuntu-settings-components", |
1504 | + "Swipe your finger over the reader.") |
1505 | + objectName: "fingerprintStatusLabel" |
1506 | + } |
1507 | + |
1508 | + |
1509 | + Label { |
1510 | + id: progressLabel |
1511 | + objectName: "fingerprintProgressLabel" |
1512 | + property int progress: 0 |
1513 | + anchors { |
1514 | + top: fingerprintBox.bottom |
1515 | + topMargin: units.gu(1.5) |
1516 | + horizontalCenter: parent.horizontalCenter |
1517 | + } |
1518 | + text: i18n.dtr("ubuntu-settings-components", "%1%").arg((progress).toFixed()); |
1519 | + opacity: 0 |
1520 | + horizontalAlignment: Text.AlignHCenter |
1521 | + fontSize: "large" |
1522 | + color: theme.palette.normal.backgroundTertiaryText |
1523 | + |
1524 | + Behavior on opacity { UbuntuNumberAnimation {} } |
1525 | + Behavior on progress { |
1526 | + NumberAnimation { |
1527 | + duration: UbuntuAnimation.SlowDuration |
1528 | + easing: UbuntuAnimation.StandardEasing |
1529 | + } |
1530 | + } |
1531 | + } |
1532 | + |
1533 | + Rectangle { |
1534 | + id: actions |
1535 | + |
1536 | + anchors { |
1537 | + left: parent.left |
1538 | + right: parent.right |
1539 | + bottom: parent.bottom |
1540 | + } |
1541 | + |
1542 | + // Color and height values are copied from the Wizard. |
1543 | + color: "#f5f5f5" |
1544 | + height: units.gu(5) |
1545 | + |
1546 | + AbstractButton { |
1547 | + id: cancelButton |
1548 | + property alias text: cancelButtonText.text |
1549 | + objectName: "fingerprintSetupCancelButton" |
1550 | + anchors { |
1551 | + left: parent.left |
1552 | + leftMargin: units.gu(3) |
1553 | + verticalCenter: parent.verticalCenter |
1554 | + } |
1555 | + height: parent.height |
1556 | + width: units.gu(10) |
1557 | + onClicked: { |
1558 | + root.cancel(); |
1559 | + pageStack.pop(); |
1560 | + } |
1561 | + |
1562 | + Label { |
1563 | + id: cancelButtonText |
1564 | + anchors.verticalCenter: parent.verticalCenter |
1565 | + text: i18n.dtr("ubuntu-settings-components", "Cancel") |
1566 | + } |
1567 | + } |
1568 | + |
1569 | + AbstractButton { |
1570 | + id: doneButton |
1571 | + property alias text: doneButtonText.text |
1572 | + objectName: "fingerprintSetupDoneButton" |
1573 | + anchors { |
1574 | + right: parent.right |
1575 | + rightMargin: units.gu(3) |
1576 | + verticalCenter: parent.verticalCenter |
1577 | + } |
1578 | + enabled: false |
1579 | + height: parent.height |
1580 | + width: units.gu(10) |
1581 | + onClicked: pageStack.pop() |
1582 | + |
1583 | + Label { |
1584 | + id: doneButtonText |
1585 | + anchors { |
1586 | + verticalCenter: parent.verticalCenter |
1587 | + right: parent.right |
1588 | + } |
1589 | + font.bold: parent.enabled |
1590 | + text: i18n.dtr("ubuntu-settings-components", "Next") |
1591 | + } |
1592 | + } |
1593 | + } |
1594 | + } |
1595 | +} |
1596 | |
1597 | === added file 'plugins/Ubuntu/Settings/Fingerprint/StatusLabel.qml' |
1598 | --- plugins/Ubuntu/Settings/Fingerprint/StatusLabel.qml 1970-01-01 00:00:00 +0000 |
1599 | +++ plugins/Ubuntu/Settings/Fingerprint/StatusLabel.qml 2016-06-20 13:58:28 +0000 |
1600 | @@ -0,0 +1,84 @@ |
1601 | +/* |
1602 | + * Copyright 2016 Canonical Ltd. |
1603 | + * |
1604 | + * This program is free software; you can redistribute it and/or modify |
1605 | + * it under the terms of the GNU Lesser General Public License as published by |
1606 | + * the Free Software Foundation; version 3. |
1607 | + * |
1608 | + * This program is distributed in the hope that it will be useful, |
1609 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1610 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1611 | + * GNU Lesser General Public License for more details. |
1612 | + * |
1613 | + * You should have received a copy of the GNU Lesser General Public License |
1614 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1615 | + * |
1616 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
1617 | + */ |
1618 | + |
1619 | +import QtQuick 2.4 |
1620 | +import Ubuntu.Components 1.3 |
1621 | + |
1622 | +Item { |
1623 | + id: root |
1624 | + |
1625 | + property string initialText |
1626 | + property int origX: 0 |
1627 | + readonly property alias text: label.text |
1628 | + |
1629 | + signal slideStarted() |
1630 | + signal slideCompleted() |
1631 | + |
1632 | + Component.onCompleted: origX = label.x |
1633 | + |
1634 | + function setText(text, noAnimation) { |
1635 | + if (noAnimation === true) { |
1636 | + label.text = text; |
1637 | + return; |
1638 | + } |
1639 | + |
1640 | + function outStoppedHandler () { |
1641 | + label.text = text; |
1642 | + label.x = units.gu(50) |
1643 | + inAnim.start(); |
1644 | + outAnim.stopped.disconnect(outStoppedHandler); |
1645 | + } |
1646 | + outAnim.stopped.connect(outStoppedHandler); |
1647 | + outAnim.start(); |
1648 | + } |
1649 | + |
1650 | + Label { |
1651 | + id: label |
1652 | + |
1653 | + font.pixelSize: units.gu(3.3) |
1654 | + horizontalAlignment: Text.AlignLeft |
1655 | + height: units.gu(4) |
1656 | + text: initialText |
1657 | + width: parent.width |
1658 | + wrapMode: Text.WordWrap |
1659 | + } |
1660 | + |
1661 | + NumberAnimation { |
1662 | + id: outAnim |
1663 | + |
1664 | + alwaysRunToEnd: true |
1665 | + duration: UbuntuAnimation.FastDuration |
1666 | + easing: UbuntuAnimation.StandardEasing |
1667 | + onStarted: root.slideStarted() |
1668 | + property: "x" |
1669 | + target: label |
1670 | + to: -units.gu(50) |
1671 | + } |
1672 | + |
1673 | + NumberAnimation { |
1674 | + id: inAnim |
1675 | + |
1676 | + alwaysRunToEnd: true |
1677 | + duration: UbuntuAnimation.FastDuration |
1678 | + easing: UbuntuAnimation.StandardEasing |
1679 | + onStopped: root.slideCompleted() |
1680 | + property: "x" |
1681 | + target: label |
1682 | + to: root.origX |
1683 | + } |
1684 | +} |
1685 | |
1686 | === added directory 'plugins/Ubuntu/Settings/Fingerprint/assets' |
1687 | === added file 'plugins/Ubuntu/Settings/Fingerprint/assets.qrc' |
1688 | --- plugins/Ubuntu/Settings/Fingerprint/assets.qrc 1970-01-01 00:00:00 +0000 |
1689 | +++ plugins/Ubuntu/Settings/Fingerprint/assets.qrc 2016-06-20 13:58:28 +0000 |
1690 | @@ -0,0 +1,11 @@ |
1691 | +<!DOCTYPE RCC><RCC version="1.0"> |
1692 | +<qresource> |
1693 | + <file>assets/shape-up@27.png</file> |
1694 | + <file>assets/shape-up@27.sci</file> |
1695 | + <file>assets/shape-down@27.png</file> |
1696 | + <file>assets/shape-down@27.sci</file> |
1697 | + |
1698 | + <file>assets/fingerprint_segmented@27.png</file> |
1699 | + <file>assets/fingerprint_boxes.json</file> |
1700 | +</qresource> |
1701 | +</RCC> |
1702 | |
1703 | === added file 'plugins/Ubuntu/Settings/Fingerprint/assets/fingerprint_boxes.json' |
1704 | --- plugins/Ubuntu/Settings/Fingerprint/assets/fingerprint_boxes.json 1970-01-01 00:00:00 +0000 |
1705 | +++ plugins/Ubuntu/Settings/Fingerprint/assets/fingerprint_boxes.json 2016-06-20 13:58:28 +0000 |
1706 | @@ -0,0 +1,1 @@ |
1707 | +{"width": 451, "boxes": [[291, 515, 104, 50], [269, 510, 96, 34], [227, 506, 62, 16], [198, 505, 72, 60], [144, 498, 46, 67], [200, 467, 133, 32], [214, 449, 87, 28], [67, 432, 25, 104], [396, 420, 31, 89], [177, 395, 22, 103], [133, 390, 15, 96], [266, 375, 8, 31], [1, 356, 7, 42], [336, 355, 27, 114], [221, 350, 95, 105], [243, 323, 17, 106], [155, 317, 68, 248], [110, 317, 43, 243], [22, 314, 12, 155], [199, 310, 13, 127], [302, 296, 83, 223], [276, 295, 20, 136], [311, 275, 30, 189], [177, 266, 8, 114], [88, 263, 34, 287], [221, 249, 9, 86], [441, 238, 9, 169], [110, 231, 9, 70], [44, 226, 16, 280], [310, 225, 8, 181], [199, 223, 53, 86], [370, 217, 37, 288], [249, 208, 25, 153], [177, 201, 61, 49], [281, 195, 15, 85], [133, 183, 16, 196], [177, 178, 96, 29], [155, 167, 35, 134], [345, 166, 18, 173], [200, 156, 81, 31], [1, 149, 17, 192], [386, 145, 18, 60], [305, 142, 36, 118], [66, 139, 26, 277], [149, 134, 168, 77], [111, 132, 45, 85], [88, 130, 36, 120], [350, 118, 35, 162], [165, 111, 134, 28], [262, 92, 85, 64], [414, 91, 35, 133], [129, 89, 119, 36], [22, 88, 42, 211], [92, 67, 256, 62], [47, 64, 75, 149], [349, 47, 80, 360], [132, 44, 257, 90], [13, 41, 56, 95], [66, 22, 273, 60], [198, 1, 215, 76], [74, 1, 109, 39]], "height": 566} |
1708 | |
1709 | === added file 'plugins/Ubuntu/Settings/Fingerprint/assets/fingerprint_segmented@27.png' |
1710 | Binary files plugins/Ubuntu/Settings/Fingerprint/assets/fingerprint_segmented@27.png 1970-01-01 00:00:00 +0000 and plugins/Ubuntu/Settings/Fingerprint/assets/fingerprint_segmented@27.png 2016-06-20 13:58:28 +0000 differ |
1711 | === added file 'plugins/Ubuntu/Settings/Fingerprint/assets/shape-down@27.png' |
1712 | Binary files plugins/Ubuntu/Settings/Fingerprint/assets/shape-down@27.png 1970-01-01 00:00:00 +0000 and plugins/Ubuntu/Settings/Fingerprint/assets/shape-down@27.png 2016-06-20 13:58:28 +0000 differ |
1713 | === added file 'plugins/Ubuntu/Settings/Fingerprint/assets/shape-down@27.sci' |
1714 | --- plugins/Ubuntu/Settings/Fingerprint/assets/shape-down@27.sci 1970-01-01 00:00:00 +0000 |
1715 | +++ plugins/Ubuntu/Settings/Fingerprint/assets/shape-down@27.sci 2016-06-20 13:58:28 +0000 |
1716 | @@ -0,0 +1,7 @@ |
1717 | +border.top: 222 |
1718 | +border.right: 222 |
1719 | +border.bottom: 222 |
1720 | +border.left: 222 |
1721 | +horizontalTileMode: Round |
1722 | +verticalTileMode: Round |
1723 | +source: "shape-down@27.png" |
1724 | |
1725 | === added file 'plugins/Ubuntu/Settings/Fingerprint/assets/shape-up@27.png' |
1726 | Binary files plugins/Ubuntu/Settings/Fingerprint/assets/shape-up@27.png 1970-01-01 00:00:00 +0000 and plugins/Ubuntu/Settings/Fingerprint/assets/shape-up@27.png 2016-06-20 13:58:28 +0000 differ |
1727 | === added file 'plugins/Ubuntu/Settings/Fingerprint/assets/shape-up@27.sci' |
1728 | --- plugins/Ubuntu/Settings/Fingerprint/assets/shape-up@27.sci 1970-01-01 00:00:00 +0000 |
1729 | +++ plugins/Ubuntu/Settings/Fingerprint/assets/shape-up@27.sci 2016-06-20 13:58:28 +0000 |
1730 | @@ -0,0 +1,7 @@ |
1731 | +border.top: 260 |
1732 | +border.right: 260 |
1733 | +border.bottom: 260 |
1734 | +border.left: 260 |
1735 | +horizontalTileMode: Round |
1736 | +verticalTileMode: Round |
1737 | +source: "shape-up@27.png" |
1738 | |
1739 | === added file 'plugins/Ubuntu/Settings/Fingerprint/plugin.cpp' |
1740 | --- plugins/Ubuntu/Settings/Fingerprint/plugin.cpp 1970-01-01 00:00:00 +0000 |
1741 | +++ plugins/Ubuntu/Settings/Fingerprint/plugin.cpp 2016-06-20 13:58:28 +0000 |
1742 | @@ -0,0 +1,35 @@ |
1743 | +/* |
1744 | + * Copyright (C) 2016 Canonical, Ltd. |
1745 | + * |
1746 | + * This program is free software; you can redistribute it and/or modify |
1747 | + * it under the terms of the GNU Lesser General Public License as published by |
1748 | + * the Free Software Foundation; version 3. |
1749 | + * |
1750 | + * This program is distributed in the hope that it will be useful, |
1751 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1752 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1753 | + * GNU Lesser General Public License for more details. |
1754 | + * |
1755 | + * You should have received a copy of the GNU Lesser General Public License |
1756 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1757 | + */ |
1758 | + |
1759 | +#include "plugin.h" |
1760 | +#include "ubuntusettingsfingerprint.h" |
1761 | + |
1762 | +#include <QtQml/qqml.h> |
1763 | + |
1764 | +static QObject* fp_singletonprovider(QQmlEngine *engine, QJSEngine *scriptEngine) |
1765 | +{ |
1766 | + Q_UNUSED(engine) |
1767 | + Q_UNUSED(scriptEngine) |
1768 | + |
1769 | + return new UbuntuSettingsFingerprint; |
1770 | +} |
1771 | + |
1772 | +void UbuntuSettingsFingerprintPlugin::registerTypes(const char *uri) |
1773 | +{ |
1774 | + qmlRegisterSingletonType<UbuntuSettingsFingerprint>( |
1775 | + uri, 0, 1, "UbuntuSettingsFingerprint", fp_singletonprovider |
1776 | + ); |
1777 | +} |
1778 | |
1779 | === added file 'plugins/Ubuntu/Settings/Fingerprint/plugin.h' |
1780 | --- plugins/Ubuntu/Settings/Fingerprint/plugin.h 1970-01-01 00:00:00 +0000 |
1781 | +++ plugins/Ubuntu/Settings/Fingerprint/plugin.h 2016-06-20 13:58:28 +0000 |
1782 | @@ -0,0 +1,30 @@ |
1783 | +/* |
1784 | + * Copyright (C) 2016 Canonical, Ltd. |
1785 | + * |
1786 | + * This program is free software; you can redistribute it and/or modify |
1787 | + * it under the terms of the GNU Lesser General Public License as published by |
1788 | + * the Free Software Foundation; version 3. |
1789 | + * |
1790 | + * This program is distributed in the hope that it will be useful, |
1791 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1792 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1793 | + * GNU Lesser General Public License for more details. |
1794 | + * |
1795 | + * You should have received a copy of the GNU Lesser General Public License |
1796 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1797 | + */ |
1798 | + |
1799 | +#ifndef UBUNTUSETTINGSFINGERPRINT_PLUGIN_H |
1800 | +#define UBUNTUSETTINGSFINGERPRINT_PLUGIN_H |
1801 | + |
1802 | +#include <QtQml/QQmlExtensionPlugin> |
1803 | + |
1804 | +class UbuntuSettingsFingerprintPlugin : public QQmlExtensionPlugin |
1805 | +{ |
1806 | + Q_OBJECT |
1807 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
1808 | +public: |
1809 | + void registerTypes(const char *uri); |
1810 | +}; |
1811 | + |
1812 | +#endif // UBUNTUSETTINGSFINGERPRINT_PLUGIN_H |
1813 | |
1814 | === added file 'plugins/Ubuntu/Settings/Fingerprint/qmldir' |
1815 | --- plugins/Ubuntu/Settings/Fingerprint/qmldir 1970-01-01 00:00:00 +0000 |
1816 | +++ plugins/Ubuntu/Settings/Fingerprint/qmldir 2016-06-20 13:58:28 +0000 |
1817 | @@ -0,0 +1,7 @@ |
1818 | +module Ubuntu.Settings.Fingerprint |
1819 | +plugin UbuntuSettingsFingerprintQml |
1820 | + |
1821 | +Fingerprint 0.1 Fingerprint.qml |
1822 | +Fingerprints 0.1 Fingerprints.qml |
1823 | +FingerprintVisual 0.1 FingerprintVisual.qml |
1824 | +Setup 0.1 Setup.qml |
1825 | |
1826 | === added file 'plugins/Ubuntu/Settings/Fingerprint/ubuntusettingsfingerprint.cpp' |
1827 | --- plugins/Ubuntu/Settings/Fingerprint/ubuntusettingsfingerprint.cpp 1970-01-01 00:00:00 +0000 |
1828 | +++ plugins/Ubuntu/Settings/Fingerprint/ubuntusettingsfingerprint.cpp 2016-06-20 13:58:28 +0000 |
1829 | @@ -0,0 +1,39 @@ |
1830 | +/* |
1831 | + * Copyright (C) 2016 Canonical, Ltd. |
1832 | + * |
1833 | + * This program is free software; you can redistribute it and/or modify |
1834 | + * it under the terms of the GNU Lesser General Public License as published by |
1835 | + * the Free Software Foundation; version 3. |
1836 | + * |
1837 | + * This program is distributed in the hope that it will be useful, |
1838 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1839 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1840 | + * GNU Lesser General Public License for more details. |
1841 | + * |
1842 | + * You should have received a copy of the GNU Lesser General Public License |
1843 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1844 | + * |
1845 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
1846 | + */ |
1847 | +#include <unistd.h> |
1848 | +#include <sys/types.h> |
1849 | +#include <QProcessEnvironment> |
1850 | + |
1851 | +#include "ubuntusettingsfingerprint.h" |
1852 | + |
1853 | +UbuntuSettingsFingerprint::UbuntuSettingsFingerprint(QObject* parent) |
1854 | + : QObject(parent) |
1855 | +{ |
1856 | +} |
1857 | + |
1858 | +qlonglong UbuntuSettingsFingerprint::uid() const |
1859 | +{ |
1860 | + return qlonglong(getuid()); |
1861 | +} |
1862 | + |
1863 | +bool UbuntuSettingsFingerprint::debug() const |
1864 | +{ |
1865 | + return QProcessEnvironment::systemEnvironment().contains( |
1866 | + QLatin1String("USC_FINGERPRINT_DEBUG") |
1867 | + ); |
1868 | +} |
1869 | |
1870 | === added file 'plugins/Ubuntu/Settings/Fingerprint/ubuntusettingsfingerprint.h' |
1871 | --- plugins/Ubuntu/Settings/Fingerprint/ubuntusettingsfingerprint.h 1970-01-01 00:00:00 +0000 |
1872 | +++ plugins/Ubuntu/Settings/Fingerprint/ubuntusettingsfingerprint.h 2016-06-20 13:58:28 +0000 |
1873 | @@ -0,0 +1,37 @@ |
1874 | +/* |
1875 | + * Copyright (C) 2016 Canonical, Ltd. |
1876 | + * |
1877 | + * This program is free software; you can redistribute it and/or modify |
1878 | + * it under the terms of the GNU Lesser General Public License as published by |
1879 | + * the Free Software Foundation; version 3. |
1880 | + * |
1881 | + * This program is distributed in the hope that it will be useful, |
1882 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1883 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1884 | + * GNU Lesser General Public License for more details. |
1885 | + * |
1886 | + * You should have received a copy of the GNU Lesser General Public License |
1887 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1888 | + * |
1889 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
1890 | + */ |
1891 | + |
1892 | +#ifndef UBUNTUSETTINGSFINGERPRINT_H |
1893 | +#define UBUNTUSETTINGSFINGERPRINT_H |
1894 | + |
1895 | +#include <QObject> |
1896 | + |
1897 | +class UbuntuSettingsFingerprint : public QObject |
1898 | +{ |
1899 | + Q_OBJECT |
1900 | +public: |
1901 | + explicit UbuntuSettingsFingerprint(QObject* parent = 0); |
1902 | + |
1903 | + Q_PROPERTY(qlonglong uid READ uid CONSTANT) |
1904 | + Q_PROPERTY(bool debug READ debug CONSTANT) |
1905 | + |
1906 | + qlonglong uid() const; |
1907 | + bool debug() const; |
1908 | +}; |
1909 | + |
1910 | +#endif // UBUNTUSETTINGSFINGERPRINT_H |
1911 | |
1912 | === added directory 'plugins/Ubuntu/Settings/Fingerprint/utils' |
1913 | === added file 'plugins/Ubuntu/Settings/Fingerprint/utils/segment.py' |
1914 | --- plugins/Ubuntu/Settings/Fingerprint/utils/segment.py 1970-01-01 00:00:00 +0000 |
1915 | +++ plugins/Ubuntu/Settings/Fingerprint/utils/segment.py 2016-06-20 13:58:28 +0000 |
1916 | @@ -0,0 +1,84 @@ |
1917 | +#!/usr/bin/python2 |
1918 | +""" |
1919 | + * Copyright 2016 Canonical Ltd. |
1920 | + * |
1921 | + * This program is free software; you can redistribute it and/or modify |
1922 | + * it under the terms of the GNU Lesser General Public License as published by |
1923 | + * the Free Software Foundation; version 3. |
1924 | + * |
1925 | + * This program is distributed in the hope that it will be useful, |
1926 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1927 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1928 | + * GNU Lesser General Public License for more details. |
1929 | + * |
1930 | + * You should have received a copy of the GNU Lesser General Public License |
1931 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1932 | + * |
1933 | + * Authored by Florian Boucault <florian.boucault@canonical.com> |
1934 | + */ |
1935 | +""" |
1936 | + |
1937 | +import os.path |
1938 | +import argparse |
1939 | +import json |
1940 | +import cv2 |
1941 | + |
1942 | +parser = argparse.ArgumentParser( |
1943 | + description='Generates segmented version of img and extracts bbs.' |
1944 | +) |
1945 | +parser.add_argument('input_image', type=str, |
1946 | + help='path to the image to segment') |
1947 | +args = parser.parse_args() |
1948 | + |
1949 | +input_image = os.path.abspath(args.input_image) |
1950 | +print("Segmenting %s..." % input_image) |
1951 | +filename, _ = os.path.splitext(os.path.basename(input_image)) |
1952 | +split = filename.split('@') |
1953 | +if len(split) != 1: |
1954 | + output_image = "%s_segmented@%s.png" % (split[0], split[1]) |
1955 | + output_boxes = "%s_boxes.json" % split[0] |
1956 | +else: |
1957 | + output_image = "%s_segmented.png" % filename |
1958 | + output_boxes = "%s_boxes.json" % filename |
1959 | + |
1960 | +img = cv2.imread(input_image, -1) |
1961 | +img_boxes = img.copy() |
1962 | +gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
1963 | +ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) |
1964 | +contours, hierarchy = cv2.findContours( |
1965 | + thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE |
1966 | +) |
1967 | + |
1968 | +print("Detected %d segments." % len(contours)) |
1969 | + |
1970 | +bounding_boxes = [] |
1971 | +for index, contour in enumerate(contours): |
1972 | + x, y, w, h = cv2.boundingRect(contour) |
1973 | + bounding_boxes.append((x, y, w, h)) |
1974 | +# print(x, y, w, h) |
1975 | + cv2.rectangle(img_boxes, |
1976 | + (x, y), |
1977 | + (x + w, y + h), |
1978 | + (255, 20, 20, 255), 1) |
1979 | + cv2.drawContours(thresh, contours, index, (index + 1), |
1980 | + cv2.cv.CV_FILLED) |
1981 | + cv2.drawContours(thresh, contours, index, (index + 1), 2) |
1982 | + |
1983 | +b, g, r, a = cv2.split(img) |
1984 | +img = cv2.merge([a, g, thresh]) |
1985 | + |
1986 | +cv2.imwrite(output_image, img) |
1987 | +print("Written segmented version of '%s' to '%s'" % ( |
1988 | + args.input_image, output_image) |
1989 | +) |
1990 | + |
1991 | +description = {"width": img.shape[1], |
1992 | + "height": img.shape[0], |
1993 | + "boxes": bounding_boxes} |
1994 | +with open(output_boxes, 'w') as outfile: |
1995 | + json.dump(description, outfile) |
1996 | +print("Written bounding boxes to '%s'" % output_boxes) |
1997 | + |
1998 | +cv2.imshow('image', img_boxes) |
1999 | +cv2.waitKey(0) |
2000 | +cv2.destroyAllWindows() |
2001 | |
2002 | === modified file 'po/ubuntu-settings-components.pot' |
2003 | --- po/ubuntu-settings-components.pot 2016-05-19 17:52:21 +0000 |
2004 | +++ po/ubuntu-settings-components.pot 2016-06-20 13:58:28 +0000 |
2005 | @@ -8,7 +8,7 @@ |
2006 | msgstr "" |
2007 | "Project-Id-Version: ubuntu-settings-components\n" |
2008 | "Report-Msgid-Bugs-To: \n" |
2009 | -"POT-Creation-Date: 2016-04-25 15:44+0200\n" |
2010 | +"POT-Creation-Date: 2016-06-20 15:57+0200\n" |
2011 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
2012 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
2013 | "Language-Team: LANGUAGE <LL@li.org>\n" |
2014 | @@ -21,6 +21,105 @@ |
2015 | msgid "Quick reply with:" |
2016 | msgstr "" |
2017 | |
2018 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml:80 |
2019 | +msgid "Fingerprint Name" |
2020 | +msgstr "" |
2021 | + |
2022 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml:107 |
2023 | +msgid "Delete Fingerprint" |
2024 | +msgstr "" |
2025 | + |
2026 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml:124 |
2027 | +msgid "Sorry, the fingerprint could not be deleted." |
2028 | +msgstr "" |
2029 | + |
2030 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml:129 |
2031 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:337 |
2032 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:137 |
2033 | +#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:148 |
2034 | +msgid "OK" |
2035 | +msgstr "" |
2036 | + |
2037 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:32 |
2038 | +msgid "Fingerprint ID" |
2039 | +msgstr "" |
2040 | + |
2041 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:93 |
2042 | +#, qt-format |
2043 | +msgid "Finger %1" |
2044 | +msgstr "" |
2045 | + |
2046 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:187 |
2047 | +msgid "Passcode required" |
2048 | +msgstr "" |
2049 | + |
2050 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:191 |
2051 | +msgid "You must set a passcode to use fingerprint ID" |
2052 | +msgstr "" |
2053 | + |
2054 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:198 |
2055 | +msgid "Set Passcode…" |
2056 | +msgstr "" |
2057 | + |
2058 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:274 |
2059 | +msgid "Add fingerprint" |
2060 | +msgstr "" |
2061 | + |
2062 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:287 |
2063 | +msgid "Remove All…" |
2064 | +msgstr "" |
2065 | + |
2066 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:302 |
2067 | +msgid "Are you sure you want to forget all stored fingerprints?" |
2068 | +msgstr "" |
2069 | + |
2070 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:311 |
2071 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:357 |
2072 | +#: plugins/Ubuntu/Settings/Vpn/DialogFile.qml:161 |
2073 | +#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:135 |
2074 | +#: plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml:104 |
2075 | +msgid "Cancel" |
2076 | +msgstr "" |
2077 | + |
2078 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:318 |
2079 | +#: plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml:84 |
2080 | +msgid "Remove" |
2081 | +msgstr "" |
2082 | + |
2083 | +#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:332 |
2084 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:102 |
2085 | +msgid "Sorry, the reader doesn’t seem to be working." |
2086 | +msgstr "" |
2087 | + |
2088 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:60 |
2089 | +msgid "Swipe your finger repeatedly over the reader." |
2090 | +msgstr "" |
2091 | + |
2092 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:77 |
2093 | +msgid "Keep your finger on the reader for longer." |
2094 | +msgstr "" |
2095 | + |
2096 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:93 |
2097 | +msgid "Back" |
2098 | +msgstr "" |
2099 | + |
2100 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:130 |
2101 | +msgid "All done!" |
2102 | +msgstr "" |
2103 | + |
2104 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:296 |
2105 | +msgid "Swipe your finger over the reader." |
2106 | +msgstr "" |
2107 | + |
2108 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:310 |
2109 | +#, qt-format |
2110 | +msgid "%1%" |
2111 | +msgstr "" |
2112 | + |
2113 | +#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:382 |
2114 | +msgid "Next" |
2115 | +msgstr "" |
2116 | + |
2117 | #: plugins/Ubuntu/Settings/Menus/CalendarMenu.qml:57 |
2118 | #, qt-format |
2119 | msgctxt "%1=month name, %2=4-digit year" |
2120 | @@ -48,12 +147,6 @@ |
2121 | msgid "Message" |
2122 | msgstr "" |
2123 | |
2124 | -#: plugins/Ubuntu/Settings/Vpn/DialogFile.qml:161 |
2125 | -#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:134 |
2126 | -#: plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml:104 |
2127 | -msgid "Cancel" |
2128 | -msgstr "" |
2129 | - |
2130 | #: plugins/Ubuntu/Settings/Vpn/DialogFile.qml:170 |
2131 | msgid "Accept" |
2132 | msgstr "" |
2133 | @@ -358,14 +451,10 @@ |
2134 | msgid "Your Wi-Fi/mobile provider can track your use of any other services. " |
2135 | msgstr "" |
2136 | |
2137 | -#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:26 |
2138 | +#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:25 |
2139 | msgid "Set up VPN" |
2140 | msgstr "" |
2141 | |
2142 | -#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:147 |
2143 | -msgid "OK" |
2144 | -msgstr "" |
2145 | - |
2146 | #: plugins/Ubuntu/Settings/Vpn/VpnList.qml:62 |
2147 | msgid "Delete configuration" |
2148 | msgstr "" |
2149 | @@ -380,10 +469,6 @@ |
2150 | msgid "VPN" |
2151 | msgstr "" |
2152 | |
2153 | -#: plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml:84 |
2154 | -msgid "Remove" |
2155 | -msgstr "" |
2156 | - |
2157 | #: plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml:96 |
2158 | msgid "Change" |
2159 | msgstr "" |
2160 | |
2161 | === modified file 'tests/qmltests/CMakeLists.txt' |
2162 | --- tests/qmltests/CMakeLists.txt 2016-03-09 14:04:14 +0000 |
2163 | +++ tests/qmltests/CMakeLists.txt 2016-06-20 13:58:28 +0000 |
2164 | @@ -1,6 +1,8 @@ |
2165 | # add_qml_test macro |
2166 | include(QmlTest) |
2167 | |
2168 | +add_subdirectory(mocks) |
2169 | + |
2170 | set(qmltest_DEFAULT_TARGETS qmluitests) |
2171 | set(qmltest_DEFAULT_NO_ADD_TEST TRUE) |
2172 | set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C") |
2173 | @@ -40,3 +42,8 @@ |
2174 | add_qml_test(Vpn VpnPptpEditor) |
2175 | add_qml_test(Vpn VpnPreviewDialogCertificateChecks) |
2176 | add_qml_test(Vpn VpnPreviewDialog ENVIRONMENT NO_SSL_CERTIFICATE_CHECK=1) |
2177 | + |
2178 | +add_qml_test(Fingerprint Fingerprints IMPORT_PATHS ${CMAKE_CURRENT_BINARY_DIR}/mocks) |
2179 | +add_qml_test(Fingerprint FingerprintNames IMPORT_PATHS ${CMAKE_CURRENT_BINARY_DIR}/mocks) |
2180 | +add_qml_test(Fingerprint FingerprintSetup IMPORT_PATHS ${CMAKE_CURRENT_BINARY_DIR}/mocks) |
2181 | +add_qml_test(Fingerprint FingerprintVisual) |
2182 | |
2183 | === added directory 'tests/qmltests/Fingerprint' |
2184 | === added file 'tests/qmltests/Fingerprint/tst_FingerprintNames.qml' |
2185 | --- tests/qmltests/Fingerprint/tst_FingerprintNames.qml 1970-01-01 00:00:00 +0000 |
2186 | +++ tests/qmltests/Fingerprint/tst_FingerprintNames.qml 2016-06-20 13:58:28 +0000 |
2187 | @@ -0,0 +1,364 @@ |
2188 | +/* |
2189 | + * Copyright 2016 Canonical Ltd. |
2190 | + * |
2191 | + * This program is free software; you can redistribute it and/or modify |
2192 | + * it under the terms of the GNU Lesser General Public License as published by |
2193 | + * the Free Software Foundation; version 3. |
2194 | + * |
2195 | + * This program is distributed in the hope that it will be useful, |
2196 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2197 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2198 | + * GNU Lesser General Public License for more details. |
2199 | + * |
2200 | + * You should have received a copy of the GNU Lesser General Public License |
2201 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2202 | + * |
2203 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
2204 | + */ |
2205 | + |
2206 | +import QtQuick 2.4 |
2207 | +import QtTest 1.0 |
2208 | +import Ubuntu.Test 0.1 |
2209 | +import Ubuntu.Settings.Fingerprint 0.1 |
2210 | +import Ubuntu.Components 1.3 |
2211 | +import Biometryd 0.0 |
2212 | +import GSettings 1.0 |
2213 | + |
2214 | +Item { |
2215 | + id: testRoot |
2216 | + width: units.gu(50) |
2217 | + height: units.gu(90) |
2218 | + |
2219 | + PageStack { |
2220 | + id: pageStack |
2221 | + } |
2222 | + |
2223 | + Component { |
2224 | + id: fingerprintsComponent |
2225 | + |
2226 | + Fingerprints { |
2227 | + anchors.fill: parent |
2228 | + visible: false |
2229 | + } |
2230 | + } |
2231 | + |
2232 | + Component { |
2233 | + id: fingerprintComponent |
2234 | + |
2235 | + Fingerprint { |
2236 | + anchors.fill: parent |
2237 | + visible: false |
2238 | + } |
2239 | + } |
2240 | + |
2241 | + Component { |
2242 | + id: gsettingsComponent |
2243 | + |
2244 | + GSettings { |
2245 | + schema.id: "com.ubuntu.touch.system" |
2246 | + } |
2247 | + } |
2248 | + |
2249 | + UbuntuTestCase { |
2250 | + name: "TestOverview" |
2251 | + when: windowShown |
2252 | + |
2253 | + property var pageInstance: null |
2254 | + property var gsettingsInstance: null |
2255 | + |
2256 | + function getTemplateEntry(i) { |
2257 | + var id = "fingerprintInstance-" + i; |
2258 | + return findChild(pageInstance, id); |
2259 | + } |
2260 | + |
2261 | + function getListObserver() { |
2262 | + return findInvisibleChild(pageInstance, "listObserver"); |
2263 | + } |
2264 | + |
2265 | + function getRemovalObserver() { |
2266 | + return findInvisibleChild(pageInstance, "removalObserver"); |
2267 | + } |
2268 | + |
2269 | + function getClearanceObserver() { |
2270 | + return findInvisibleChild(pageInstance, "clearanceObserver"); |
2271 | + } |
2272 | + |
2273 | + function getEnrollmentObserver() { |
2274 | + return findInvisibleChild(pageInstance, "enrollmentObserver"); |
2275 | + } |
2276 | + |
2277 | + function initTestCase() { |
2278 | + Biometryd.setAvailable(true); |
2279 | + } |
2280 | + |
2281 | + function init() { |
2282 | + gsettingsInstance = gsettingsComponent.createObject(testRoot); |
2283 | + pageInstance = fingerprintsComponent.createObject(testRoot, { |
2284 | + _settings: gsettingsInstance, |
2285 | + passcodeSet: true |
2286 | + }); |
2287 | + pageStack.push(pageInstance); |
2288 | + } |
2289 | + |
2290 | + function test_listSort() { |
2291 | + GSettingsController.setFingerprintNames({ |
2292 | + "first": "A finger", |
2293 | + "second": "Big finger", |
2294 | + "last": "Zmall finger", |
2295 | + }); |
2296 | + compare(getTemplateEntry(0).title.text, "A finger"); |
2297 | + compare(getTemplateEntry(1).title.text, "Big finger"); |
2298 | + compare(getTemplateEntry(2).title.text, "Zmall finger"); |
2299 | + } |
2300 | + |
2301 | + function test_remoteRemoval() { |
2302 | + GSettingsController.setFingerprintNames({ |
2303 | + "tmplId": "name" |
2304 | + }); |
2305 | + verify(getTemplateEntry(0)); |
2306 | + |
2307 | + GSettingsController.setFingerprintNames({}); |
2308 | + verify(!getTemplateEntry(0)); |
2309 | + } |
2310 | + |
2311 | + function test_remoteAddition() { |
2312 | + GSettingsController.setFingerprintNames({ |
2313 | + "tmplId": "name" |
2314 | + }); |
2315 | + verify(getTemplateEntry(0)); |
2316 | + |
2317 | + GSettingsController.setFingerprintNames({ |
2318 | + "tmplId": "name", |
2319 | + "tmplId2": "name2" |
2320 | + }); |
2321 | + verify(getTemplateEntry(0)); |
2322 | + verify(getTemplateEntry(1)); |
2323 | + } |
2324 | + |
2325 | + function test_remoteRename() { |
2326 | + GSettingsController.setFingerprintNames({ |
2327 | + "tmplId": "My finger", |
2328 | + }); |
2329 | + compare(getTemplateEntry(0).title.text, "My finger"); |
2330 | + GSettingsController.setFingerprintNames({ |
2331 | + "tmplId": "Your finger", |
2332 | + }); |
2333 | + compare(getTemplateEntry(0).title.text, "Your finger"); |
2334 | + } |
2335 | + |
2336 | + function test_localRemoval() { |
2337 | + GSettingsController.setFingerprintNames({ |
2338 | + "tmplId": "name" |
2339 | + }); |
2340 | + verify(getTemplateEntry(0)); |
2341 | + pageInstance.removeTemplate("tmplId"); |
2342 | + verify(!getTemplateEntry(0)); |
2343 | + } |
2344 | + |
2345 | + function test_localAddition() { |
2346 | + pageInstance.addTemplate("tmplId", "My finger"); |
2347 | + verify(getTemplateEntry(0)); |
2348 | + compare(getTemplateEntry(0).title.text, "My finger"); |
2349 | + } |
2350 | + |
2351 | + function test_localRename() { |
2352 | + GSettingsController.setFingerprintNames({ |
2353 | + "tmplId": "My finger" |
2354 | + }); |
2355 | + pageInstance.renameTemplate("tmplId", "Your finger"); |
2356 | + verify(getTemplateEntry(0)); |
2357 | + compare(getTemplateEntry(0).title.text, "Your finger"); |
2358 | + } |
2359 | + |
2360 | + function test_createTemplateName() { |
2361 | + GSettingsController.setFingerprintNames({ |
2362 | + "tmplId": i18n.dtr("ubuntu-settings-components", "Finger %1").arg(1) |
2363 | + }); |
2364 | + compare(pageInstance.createTemplateName(), i18n.dtr("ubuntu-settings-components", "Finger %1").arg(2)); |
2365 | + pageInstance.renameTemplate("tmplId", i18n.dtr("ubuntu-settings-components", "Finger %1").arg(2)); |
2366 | + compare(pageInstance.createTemplateName(), i18n.dtr("ubuntu-settings-components", "Finger %1").arg(1)); |
2367 | + } |
2368 | + |
2369 | + function test_assignNames() { |
2370 | + var templateIds = ["tmplId0", "tmplId1", "tmplId2"]; |
2371 | + |
2372 | + // This name shouldn't be overwritten |
2373 | + GSettingsController.setFingerprintNames({ |
2374 | + "tmplId1": "My finger" |
2375 | + }); |
2376 | + |
2377 | + getListObserver().mockList(templateIds, ""); |
2378 | + |
2379 | + verify(getTemplateEntry(0)); |
2380 | + compare(getTemplateEntry(0).title.text, i18n.dtr("ubuntu-settings-components", "Finger %1").arg(1)); |
2381 | + |
2382 | + verify(getTemplateEntry(1)); |
2383 | + compare(getTemplateEntry(1).title.text, i18n.dtr("ubuntu-settings-components", "Finger %1").arg(2)); |
2384 | + |
2385 | + verify(getTemplateEntry(2)); |
2386 | + compare(getTemplateEntry(2).title.text, "My finger"); |
2387 | + } |
2388 | + |
2389 | + function test_serviceRemoval() { |
2390 | + GSettingsController.setFingerprintNames({ |
2391 | + "tmplId": "A finger" |
2392 | + }); |
2393 | + getRemovalObserver().mockRemoval("tmplId", ""); |
2394 | + verify(!getTemplateEntry(0)); |
2395 | + compare(GSettingsController.fingerprintNames(), {}); |
2396 | + } |
2397 | + |
2398 | + function test_serviceEnrollment() { |
2399 | + GSettingsController.setFingerprintNames({ |
2400 | + "tmplId1": "Existing finger" |
2401 | + }); |
2402 | + getEnrollmentObserver().mockEnroll("tmplId2", ""); |
2403 | + |
2404 | + verify(getTemplateEntry(0)); |
2405 | + compare(getTemplateEntry(0).title.text, "Existing finger"); |
2406 | + |
2407 | + verify(getTemplateEntry(1)); |
2408 | + compare(getTemplateEntry(1).title.text, i18n.dtr("ubuntu-settings-components", "Finger %1").arg(1)); |
2409 | + } |
2410 | + |
2411 | + function test_serviceEnrollmentFirstRun() { |
2412 | + var targetName = i18n.dtr("ubuntu-settings-components", "Finger %1").arg(1); |
2413 | + |
2414 | + // A test where the template id is 0. |
2415 | + getEnrollmentObserver().mockEnroll(0, ""); |
2416 | + |
2417 | + verify(getTemplateEntry(0)); |
2418 | + compare(getTemplateEntry(0).title.text, targetName); |
2419 | + } |
2420 | + |
2421 | + function test_serviceEnrollmentReusesId() { |
2422 | + // Test a case where enrollment processes re-uses the template id |
2423 | + // Hopefully this will never happen, but it currently does in testing, |
2424 | + // so test it. |
2425 | + var targetName = i18n.dtr("ubuntu-settings-components", "Finger %1").arg(1); |
2426 | + |
2427 | + getEnrollmentObserver().mockEnroll(0, ""); |
2428 | + verify(getTemplateEntry(0)); |
2429 | + compare(getTemplateEntry(0).title.text, targetName); |
2430 | + |
2431 | + // Re-enroll same id, make sure it doesn't change the name |
2432 | + getEnrollmentObserver().mockEnroll(0, ""); |
2433 | + verify(getTemplateEntry(0)); |
2434 | + compare(getTemplateEntry(0).title.text, targetName); |
2435 | + |
2436 | + } |
2437 | + |
2438 | + function test_serviceClearance() { |
2439 | + GSettingsController.setFingerprintNames({ |
2440 | + "tmplId1": "A finger", |
2441 | + "tmplId2": "My finger" |
2442 | + }); |
2443 | + getClearanceObserver().mockClearance(""); |
2444 | + |
2445 | + verify(!getTemplateEntry(0)); |
2446 | + compare(GSettingsController.fingerprintNames(), {}); |
2447 | + } |
2448 | + |
2449 | + function cleanup() { |
2450 | + pageStack.pop(); |
2451 | + GSettingsController.setFingerprintNames({}); |
2452 | + gsettingsInstance.destroy(); |
2453 | + gsettingsInstance = null; |
2454 | + pageInstance.destroy(); |
2455 | + pageInstance = null; |
2456 | + } |
2457 | + } |
2458 | + |
2459 | + SignalSpy { |
2460 | + id: requestDeletionSpy |
2461 | + signalName: "requestDeletion" |
2462 | + } |
2463 | + |
2464 | + SignalSpy { |
2465 | + id: requestRenameSpy |
2466 | + signalName: "requestRename" |
2467 | + } |
2468 | + |
2469 | + UbuntuTestCase { |
2470 | + name: "TestTemplate" |
2471 | + when: windowShown |
2472 | + |
2473 | + property var templateInstance: null |
2474 | + |
2475 | + function getDeleteButton() { |
2476 | + return findChild(templateInstance, "templateDelete"); |
2477 | + } |
2478 | + |
2479 | + function getHeader() { |
2480 | + return findChild(templateInstance, "templateHeader"); |
2481 | + } |
2482 | + |
2483 | + function getNameInput() { |
2484 | + return findChild(templateInstance, "nameInput"); |
2485 | + } |
2486 | + |
2487 | + function getFailedDialog() { |
2488 | + return findChild(testRoot, "fingerprintDeletionFailedDialog"); |
2489 | + } |
2490 | + |
2491 | + function getFailedDialogOk() { |
2492 | + return findChild(testRoot, "fingerprintDeleteionFailedOk"); |
2493 | + } |
2494 | + |
2495 | + function init() { |
2496 | + templateInstance = fingerprintComponent.createObject(testRoot); |
2497 | + pageStack.push(templateInstance); |
2498 | + requestRenameSpy.target = templateInstance; |
2499 | + requestDeletionSpy.target = templateInstance; |
2500 | + } |
2501 | + |
2502 | + function cleanup() { |
2503 | + requestRenameSpy.clear(); |
2504 | + requestDeletionSpy.clear(); |
2505 | + pageStack.pop(); |
2506 | + templateInstance.destroy(); |
2507 | + templateInstance = null; |
2508 | + } |
2509 | + |
2510 | + function test_name() { |
2511 | + templateInstance.name = "My finger"; |
2512 | + compare(getHeader().title, "My finger"); |
2513 | + compare(getNameInput().text, "My finger"); |
2514 | + } |
2515 | + |
2516 | + function test_requestDeletion() { |
2517 | + templateInstance.templateId = "tmplId"; |
2518 | + var button = getDeleteButton(); |
2519 | + mouseClick(button, button.width / 2, button.height / 2); |
2520 | + requestDeletionSpy.wait(); |
2521 | + compare(requestDeletionSpy.count, 1); |
2522 | + compare(requestDeletionSpy.signalArguments[0][0], "tmplId"); |
2523 | + } |
2524 | + |
2525 | + function test_requestRename() { |
2526 | + templateInstance.templateId = "tmplId"; |
2527 | + templateInstance.name = "My finger"; |
2528 | + requestRenameSpy.clear(); |
2529 | + |
2530 | + getNameInput().text = "Your finger"; |
2531 | + requestRenameSpy.wait(); |
2532 | + compare(requestRenameSpy.count, 1); |
2533 | + compare(requestRenameSpy.signalArguments[0][0], "tmplId"); |
2534 | + compare(requestRenameSpy.signalArguments[0][1], "Your finger"); |
2535 | + } |
2536 | + |
2537 | + function test_deletionFailed() { |
2538 | + templateInstance.deletionFailed(); |
2539 | + tryCompareFunction(function () { |
2540 | + return !!getFailedDialog(); |
2541 | + }, true); |
2542 | + |
2543 | + var button = getFailedDialogOk(); |
2544 | + mouseClick(button, button.width / 2, button.height / 2); |
2545 | + |
2546 | + tryCompareFunction(function () { |
2547 | + return !!getFailedDialog(); |
2548 | + }, false); |
2549 | + } |
2550 | + } |
2551 | +} |
2552 | |
2553 | === added file 'tests/qmltests/Fingerprint/tst_FingerprintSetup.qml' |
2554 | --- tests/qmltests/Fingerprint/tst_FingerprintSetup.qml 1970-01-01 00:00:00 +0000 |
2555 | +++ tests/qmltests/Fingerprint/tst_FingerprintSetup.qml 2016-06-20 13:58:28 +0000 |
2556 | @@ -0,0 +1,236 @@ |
2557 | +/* |
2558 | + * Copyright 2016 Canonical Ltd. |
2559 | + * |
2560 | + * This program is free software; you can redistribute it and/or modify |
2561 | + * it under the terms of the GNU Lesser General Public License as published by |
2562 | + * the Free Software Foundation; version 3. |
2563 | + * |
2564 | + * This program is distributed in the hope that it will be useful, |
2565 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2566 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2567 | + * GNU Lesser General Public License for more details. |
2568 | + * |
2569 | + * You should have received a copy of the GNU Lesser General Public License |
2570 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2571 | + * |
2572 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
2573 | + */ |
2574 | + |
2575 | +import QtQuick 2.4 |
2576 | +import QtTest 1.0 |
2577 | +import Ubuntu.Components 1.3 |
2578 | +import Ubuntu.Settings.Fingerprint 0.1 |
2579 | +import Ubuntu.Test 0.1 |
2580 | +import Biometryd 0.0 |
2581 | + |
2582 | +Item { |
2583 | + id: testRoot |
2584 | + width: units.gu(50) |
2585 | + height: units.gu(90) |
2586 | + |
2587 | + Component { |
2588 | + id: setupComponent |
2589 | + |
2590 | + Setup { |
2591 | + anchors.fill: parent |
2592 | + visible: false |
2593 | + } |
2594 | + } |
2595 | + |
2596 | + PageStack { |
2597 | + id: pageStack |
2598 | + } |
2599 | + |
2600 | + SignalSpy { |
2601 | + id: statusLabelSpy |
2602 | + signalName: "slideCompleted" |
2603 | + } |
2604 | + |
2605 | + SignalSpy { |
2606 | + id: enrollmentObserverProgressedSpy |
2607 | + signalName: "progressed" |
2608 | + } |
2609 | + |
2610 | + SignalSpy { |
2611 | + id: enrollmentObserverSucceededSpy |
2612 | + signalName: "succeeded" |
2613 | + } |
2614 | + |
2615 | + SignalSpy { |
2616 | + id: enrollmentObserverFailedSpy |
2617 | + signalName: "failed" |
2618 | + } |
2619 | + |
2620 | + UbuntuTestCase { |
2621 | + name: "SetupUI" |
2622 | + when: windowShown |
2623 | + |
2624 | + property var setupInstance: null |
2625 | + |
2626 | + function init() { |
2627 | + Biometryd.setAvailable(true); |
2628 | + setupInstance = setupComponent.createObject(testRoot); |
2629 | + pageStack.push(setupInstance); |
2630 | + |
2631 | + statusLabelSpy.target = getStatusLabel(); |
2632 | + } |
2633 | + |
2634 | + function cleanup() { |
2635 | + statusLabelSpy.clear(); |
2636 | + |
2637 | + pageStack.pop(); |
2638 | + setupInstance.destroy(); |
2639 | + setupInstance = null |
2640 | + } |
2641 | + |
2642 | + function getStatusLabel() { |
2643 | + return findChild(setupInstance, "fingerprintStatusLabel"); |
2644 | + } |
2645 | + |
2646 | + function getFailedVisual() { |
2647 | + return findChild(setupInstance, "fingerprintFailedVisual"); |
2648 | + } |
2649 | + |
2650 | + function getDefaultVisual() { |
2651 | + return findChild(setupInstance, "fingerprintDefaultVisual"); |
2652 | + } |
2653 | + |
2654 | + function getDoneVisual() { |
2655 | + return findChild(setupInstance, "fingerprintDoneVisual"); |
2656 | + } |
2657 | + |
2658 | + function getProgressLabel() { |
2659 | + return findChild(setupInstance, "fingerprintProgressLabel"); |
2660 | + } |
2661 | + |
2662 | + function test_initialState() { |
2663 | + var targetText = i18n.dtr("ubuntu-settings-components", "Swipe your finger over the reader."); |
2664 | + compare(getStatusLabel().text, targetText); |
2665 | + |
2666 | + tryCompare(getDefaultVisual(), "opacity", 1); |
2667 | + tryCompare(getFailedVisual(), "opacity", 0); |
2668 | + tryCompare(getDoneVisual(), "opacity", 0); |
2669 | + } |
2670 | + |
2671 | + function test_startedState() { |
2672 | + var targetText = i18n.dtr("ubuntu-settings-components", "Swipe your finger repeatedly over the reader."); |
2673 | + setupInstance.enrollmentProgressed(0.5, {}); |
2674 | + statusLabelSpy.wait(); |
2675 | + compare(getStatusLabel().text, targetText); |
2676 | + |
2677 | + tryCompare(getDefaultVisual(), "opacity", 1); |
2678 | + tryCompare(getFailedVisual(), "opacity", 0); |
2679 | + tryCompare(getDoneVisual(), "opacity", 0); |
2680 | + } |
2681 | + |
2682 | + function test_failedStatus() { |
2683 | + var targetText = i18n.dtr("ubuntu-settings-components", "Sorry, the reader doesn’t seem to be working."); |
2684 | + setupInstance.enrollmentFailed("test failure"); |
2685 | + compare(getStatusLabel().text, targetText); |
2686 | + |
2687 | + tryCompare(getDefaultVisual(), "opacity", 0); |
2688 | + tryCompare(getFailedVisual(), "opacity", 1); |
2689 | + tryCompare(getDoneVisual(), "opacity", 0); |
2690 | + } |
2691 | + |
2692 | + function test_successfulState() { |
2693 | + var targetText = i18n.dtr("ubuntu-settings-components", "All done!"); |
2694 | + |
2695 | + setupInstance.enrollmentCompleted(); |
2696 | + compare(getStatusLabel().text, targetText); |
2697 | + |
2698 | + tryCompare(getDefaultVisual(), "opacity", 0); |
2699 | + tryCompare(getFailedVisual(), "opacity", 0); |
2700 | + tryCompare(getDoneVisual(), "opacity", 1); |
2701 | + |
2702 | + var button = findChild(pageStack, "fingerprintSetupDoneButton"); |
2703 | + compare(button.enabled, true, "button was disabled when done"); |
2704 | + } |
2705 | + |
2706 | + function test_notDone() { |
2707 | + var button = findChild(pageStack, "fingerprintSetupDoneButton"); |
2708 | + compare(button.enabled, false, "button was enabled initially"); |
2709 | + } |
2710 | + |
2711 | + function test_statusLabel() { |
2712 | + getStatusLabel().setText("foo"); |
2713 | + statusLabelSpy.wait(); |
2714 | + compare(getStatusLabel().text, "foo"); |
2715 | + } |
2716 | + |
2717 | + function test_direction_data() { |
2718 | + return [ |
2719 | + { tag: "empty", visual: { visible: false, rotation: 0 }}, |
2720 | + { tag: "not available", dir: FingerprintReader.NotAvailable, visual: { visible: false, rotation: 0 }}, |
2721 | + { tag: "SouthWest", dir: FingerprintReader.SouthWest, visual: { visible: true, rotation: 225 }}, |
2722 | + { tag: "South", dir: FingerprintReader.South, visual: { visible: true, rotation: 180 }}, |
2723 | + { tag: "SouthEast", dir: FingerprintReader.SouthEast, visual: { visible: true, rotation: 135 }}, |
2724 | + { tag: "NorthWest", dir: FingerprintReader.NorthWest, visual: { visible: true, rotation: 315 }}, |
2725 | + { tag: "North", dir: FingerprintReader.North, visual: { visible: true, rotation: 0 }}, |
2726 | + { tag: "NorthEast", dir: FingerprintReader.NorthEast, visual: { visible: true, rotation: 45 }}, |
2727 | + { tag: "East", dir: FingerprintReader.East, visual: { visible: true, rotation: 90 }}, |
2728 | + { tag: "West", dir: FingerprintReader.West, visual: { visible: true, rotation: 270 }} |
2729 | + ] |
2730 | + } |
2731 | + |
2732 | + function test_direction(data) { |
2733 | + var vis = findChild(setupInstance, "fingerprintDirectionVisual"); |
2734 | + var hints = {}; |
2735 | + hints[FingerprintReader.suggestedNextDirection] = data.dir; |
2736 | + |
2737 | + setupInstance.enrollmentProgressed(0.5, hints); |
2738 | + |
2739 | + tryCompare(vis, "opacity", data.visual.visible ? 1 : 0) |
2740 | + compare(vis.opacity, data.visual.visible ? 1 : 0); |
2741 | + compare(vis.rotation, data.visual.rotation); |
2742 | + } |
2743 | + |
2744 | + function test_progressHidden() { |
2745 | + var pl = getProgressLabel(); |
2746 | + compare(pl.opacity, 0); |
2747 | + } |
2748 | + |
2749 | + function test_progressVisible() { |
2750 | + var pl = getProgressLabel(); |
2751 | + setupInstance.enrollmentProgressed(0.5, {}); |
2752 | + tryCompare(pl, "opacity", 1); |
2753 | + tryCompare(pl, "text", i18n.dtr("ubuntu-settings-components", "%1%").arg(50)); |
2754 | + } |
2755 | + |
2756 | + function test_progressReadable() { |
2757 | + setupInstance.enrollmentProgressed(0.6666666667, {}); |
2758 | + tryCompare(getProgressLabel(), "text", i18n.dtr("ubuntu-settings-components", "%1%").arg(66)); |
2759 | + } |
2760 | + |
2761 | + // This is a visual test where we can confirm that the arrow |
2762 | + // rotates using the orthodromic distance. |
2763 | + function test_directions() { |
2764 | + var hints = {}; |
2765 | + |
2766 | + hints[FingerprintReader.suggestedNextDirection] = FingerprintReader.North; |
2767 | + setupInstance.enrollmentProgressed(0.6666666667, hints); |
2768 | + wait(200) |
2769 | + hints[FingerprintReader.suggestedNextDirection] = FingerprintReader.East; |
2770 | + setupInstance.enrollmentProgressed(0.6666666667, hints); |
2771 | + wait(200) |
2772 | + hints[FingerprintReader.suggestedNextDirection] = FingerprintReader.South; |
2773 | + setupInstance.enrollmentProgressed(0.6666666667, hints); |
2774 | + wait(200) |
2775 | + hints[FingerprintReader.suggestedNextDirection] = FingerprintReader.West; |
2776 | + setupInstance.enrollmentProgressed(0.6666666667, hints); |
2777 | + wait(200) |
2778 | + hints[FingerprintReader.suggestedNextDirection] = FingerprintReader.SouthEast; |
2779 | + setupInstance.enrollmentProgressed(0.6666666667, hints); |
2780 | + wait(200) |
2781 | + hints[FingerprintReader.suggestedNextDirection] = FingerprintReader.NorthEast; |
2782 | + setupInstance.enrollmentProgressed(0.6666666667, hints); |
2783 | + wait(200) |
2784 | + hints[FingerprintReader.suggestedNextDirection] = FingerprintReader.NorthWest; |
2785 | + setupInstance.enrollmentProgressed(0.6666666667, hints); |
2786 | + wait(200) |
2787 | + hints[FingerprintReader.suggestedNextDirection] = FingerprintReader.NorthEast; |
2788 | + setupInstance.enrollmentProgressed(0.6666666667, hints); |
2789 | + wait(200) |
2790 | + } |
2791 | + } |
2792 | +} |
2793 | |
2794 | === added file 'tests/qmltests/Fingerprint/tst_FingerprintVisual.qml' |
2795 | --- tests/qmltests/Fingerprint/tst_FingerprintVisual.qml 1970-01-01 00:00:00 +0000 |
2796 | +++ tests/qmltests/Fingerprint/tst_FingerprintVisual.qml 2016-06-20 13:58:28 +0000 |
2797 | @@ -0,0 +1,132 @@ |
2798 | +/* |
2799 | + * Copyright 2016 Canonical Ltd. |
2800 | + * |
2801 | + * This program is free software; you can redistribute it and/or modify |
2802 | + * it under the terms of the GNU Lesser General Public License as published by |
2803 | + * the Free Software Foundation; version 3. |
2804 | + * |
2805 | + * This program is distributed in the hope that it will be useful, |
2806 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2807 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2808 | + * GNU Lesser General Public License for more details. |
2809 | + * |
2810 | + * You should have received a copy of the GNU Lesser General Public License |
2811 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2812 | + * |
2813 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
2814 | + */ |
2815 | + |
2816 | +import QtQuick 2.4 |
2817 | +import QtTest 1.0 |
2818 | +import Ubuntu.Components 1.3 |
2819 | +import Ubuntu.Settings.Fingerprint 0.1 |
2820 | +import Ubuntu.Test 0.1 |
2821 | + |
2822 | +Item { |
2823 | + id: testRoot |
2824 | + width: units.gu(50) |
2825 | + height: units.gu(90) |
2826 | + |
2827 | + SignalSpy { |
2828 | + id: visualReadySpy |
2829 | + signalName: "ready" |
2830 | + } |
2831 | + |
2832 | + Component { |
2833 | + id: fingerprintVisualComp |
2834 | + |
2835 | + FingerprintVisual { |
2836 | + id: vis |
2837 | + objectName: "fingerprintVisual" |
2838 | + width: 400 |
2839 | + height: width * 1.227 |
2840 | + } |
2841 | + } |
2842 | + |
2843 | + |
2844 | + UbuntuTestCase { |
2845 | + name: "FingerprintVisual" |
2846 | + when: windowShown |
2847 | + |
2848 | + function init() { |
2849 | + visualReadySpy.target = fingerprintVisualComp.createObject(testRoot); |
2850 | + visualReadySpy.wait() |
2851 | + } |
2852 | + |
2853 | + function cleanup() { |
2854 | + findChild(testRoot, "fingerprintVisual").destroy(); |
2855 | + } |
2856 | + |
2857 | + function test_masks_data() { |
2858 | + return [ |
2859 | + { masks: null, targetMasks: [], tag: "null" }, |
2860 | + { masks: [], targetMasks: [], tag: "no masks" }, |
2861 | + { |
2862 | + masks: [{x: 0, y: 0, width: 0, height: 0 }], |
2863 | + targetMasks: [{x: 0, y: 0, width: 0, height: 0}], |
2864 | + tag: "0" |
2865 | + }, |
2866 | + { |
2867 | + masks: [ |
2868 | + {x: null, y: "-a", width: "0x1", height: true }, |
2869 | + {}, |
2870 | + ], |
2871 | + targetMasks: [], |
2872 | + tag: "bad values" |
2873 | + }, |
2874 | + |
2875 | + // Masks for manual, visual checks. |
2876 | + { |
2877 | + masks: [ |
2878 | + {x: 0, y: 0, width: 0.5, height: 0.5 } |
2879 | + ], |
2880 | + visualCheck: true, |
2881 | + tag: "top right corner" |
2882 | + }, |
2883 | + { |
2884 | + masks: [ |
2885 | + {x: 0.5, y: 0, width: 0.5, height: 0.5 } |
2886 | + ], |
2887 | + visualCheck: true, |
2888 | + tag: "top left corner" |
2889 | + }, |
2890 | + { |
2891 | + masks: [ |
2892 | + {x: 0, y: 0.5, width: 0.5, height: 0.5 } |
2893 | + ], |
2894 | + visualCheck: true, |
2895 | + tag: "bottom right corner" |
2896 | + }, |
2897 | + { |
2898 | + masks: [ |
2899 | + {x: 0.5, y: 0.5, width: 0.5, height: 0.5 } |
2900 | + ], |
2901 | + visualCheck: true, |
2902 | + tag: "bottom left corner" |
2903 | + }, |
2904 | + { |
2905 | + masks: [ |
2906 | + {x: 0, y: 0, width: 0.5, height: 0.5 }, |
2907 | + {x: 0.5, y: 0, width: 0.5, height: 0.5 }, |
2908 | + {x: 0, y: 0.5, width: 0.5, height: 0.5 }, |
2909 | + {x: 0.5, y: 0.5, width: 0.5, height: 0.5 } |
2910 | + ], |
2911 | + visualCheck: true, |
2912 | + tag: "all corners" |
2913 | + } |
2914 | + ] |
2915 | + } |
2916 | + |
2917 | + function test_masks (data) { |
2918 | + var vis = findChild(testRoot, "fingerprintVisual"); |
2919 | + vis.masks = data.masks; |
2920 | + if (data.visualCheck) { |
2921 | + wait(1000); |
2922 | + } else { |
2923 | + var actualMasks = vis.getMasksToEnroll(); |
2924 | + var targetMasks = data.targetMasks; |
2925 | + compare(actualMasks.length, targetMasks.length); |
2926 | + } |
2927 | + } |
2928 | + } |
2929 | +} |
2930 | |
2931 | === added file 'tests/qmltests/Fingerprint/tst_Fingerprints.qml' |
2932 | --- tests/qmltests/Fingerprint/tst_Fingerprints.qml 1970-01-01 00:00:00 +0000 |
2933 | +++ tests/qmltests/Fingerprint/tst_Fingerprints.qml 2016-06-20 13:58:28 +0000 |
2934 | @@ -0,0 +1,230 @@ |
2935 | +/* |
2936 | + * Copyright 2016 Canonical Ltd. |
2937 | + * |
2938 | + * This program is free software; you can redistribute it and/or modify |
2939 | + * it under the terms of the GNU Lesser General Public License as published by |
2940 | + * the Free Software Foundation; version 3. |
2941 | + * |
2942 | + * This program is distributed in the hope that it will be useful, |
2943 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2944 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2945 | + * GNU Lesser General Public License for more details. |
2946 | + * |
2947 | + * You should have received a copy of the GNU Lesser General Public License |
2948 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2949 | + * |
2950 | + * Authored by Jonas G. Drange <jonas.drange@canonical.com> |
2951 | + */ |
2952 | + |
2953 | +import QtQuick 2.4 |
2954 | +import QtTest 1.0 |
2955 | +import Ubuntu.Test 0.1 |
2956 | +import Ubuntu.Settings.Fingerprint 0.1 |
2957 | +import Biometryd 0.0 |
2958 | +import GSettings 1.0 |
2959 | + |
2960 | +Item { |
2961 | + id: testRoot |
2962 | + width: units.gu(50) |
2963 | + height: units.gu(90) |
2964 | + |
2965 | + Component { |
2966 | + id: fingerprintsComponent |
2967 | + |
2968 | + Fingerprints { |
2969 | + anchors.fill: parent |
2970 | + } |
2971 | + } |
2972 | + |
2973 | + SignalSpy { |
2974 | + id: spy |
2975 | + } |
2976 | + |
2977 | + UbuntuTestCase { |
2978 | + name: "FingerprintPanel" |
2979 | + when: windowShown |
2980 | + |
2981 | + property var fingerprintsInstance: null |
2982 | + |
2983 | + function init() { |
2984 | + Biometryd.setAvailable(true); |
2985 | + fingerprintsInstance = fingerprintsComponent.createObject(testRoot); |
2986 | + } |
2987 | + |
2988 | + function cleanup() { |
2989 | + spy.clear(); |
2990 | + spy.target = null; |
2991 | + spy.signalName = ""; |
2992 | + fingerprintsInstance.destroy(); |
2993 | + GSettingsController.setFingerprintNames({}); |
2994 | + } |
2995 | + |
2996 | + function getClearanceObserver() { |
2997 | + return findInvisibleChild(fingerprintsInstance, "clearanceObserver"); |
2998 | + } |
2999 | + |
3000 | + function getListObserver() { |
3001 | + return findInvisibleChild(fingerprintsInstance, "listObserver"); |
3002 | + } |
3003 | + |
3004 | + function getEnrollmentObserver() { |
3005 | + return findInvisibleChild(fingerprintsInstance, "enrollmentObserver"); |
3006 | + } |
3007 | + |
3008 | + function getRemovalObserver() { |
3009 | + return findInvisibleChild(fingerprintsInstance, "removalObserver"); |
3010 | + } |
3011 | + |
3012 | + function getBrokenDialog() { |
3013 | + return findChild(testRoot, "fingerprintReaderBrokenDialog"); |
3014 | + } |
3015 | + |
3016 | + function getBrokenDialogOk() { |
3017 | + return findChild(testRoot, "fingerprintReaderBrokenDialogOK"); |
3018 | + } |
3019 | + |
3020 | + function getAddFingerprintItem() { |
3021 | + return findChild(fingerprintsInstance, "fingerprintAddListItemLayout"); |
3022 | + } |
3023 | + |
3024 | + function getRemoveAllButton() { |
3025 | + return findChild(fingerprintsInstance, "fingerprintRemoveAllButton"); |
3026 | + } |
3027 | + |
3028 | + function getFingerprintsList() { |
3029 | + return findChild(fingerprintsInstance, "fingerprintsList"); |
3030 | + } |
3031 | + |
3032 | + function getSetupEntry() { |
3033 | + return findChild(fingerprintsInstance, "fingerprintSetupEntry"); |
3034 | + } |
3035 | + |
3036 | + function test_failures_data() { |
3037 | + return [ |
3038 | + { tag: "clearance", observer: getClearanceObserver, mock: "mockClearance", mockArgs: ["failed"] }, |
3039 | + { tag: "list", observer: getListObserver, mock: "mockList", mockArgs: [[], "failed"] } |
3040 | + ] |
3041 | + } |
3042 | + |
3043 | + function test_failures(data) { |
3044 | + var obs = data.observer(); |
3045 | + spy.signalName = "failed"; |
3046 | + spy.target = obs; |
3047 | + obs[data.mock].apply(null, data.mockArgs); |
3048 | + spy.wait(); |
3049 | + var errorDiag = getBrokenDialog(); |
3050 | + var ok = getBrokenDialogOk(); |
3051 | + mouseClick(ok, ok.width / 2, ok.height / 2); |
3052 | + |
3053 | + // Halt testing until dialog has been destroyed. |
3054 | + tryCompareFunction(function() { |
3055 | + return getBrokenDialog(); |
3056 | + }, null); |
3057 | + } |
3058 | + |
3059 | + function test_noPasscode() { |
3060 | + fingerprintsInstance.passcodeSet = false; |
3061 | + compare(fingerprintsInstance.state, "noPasscode"); |
3062 | + |
3063 | + var setButton = findChild(fingerprintsInstance, "fingerprintSetPasscodeButton"); |
3064 | + compare(setButton.visible, true); |
3065 | + |
3066 | + var setupEntry = getSetupEntry(); |
3067 | + compare(setupEntry.enabled, false); |
3068 | + |
3069 | + var fingerprintsList = getFingerprintsList(); |
3070 | + compare(fingerprintsList.enabled, false); |
3071 | + } |
3072 | + |
3073 | + function test_noScanner() { |
3074 | + fingerprintsInstance.passcodeSet = true; |
3075 | + Biometryd.setAvailable(false); |
3076 | + compare(fingerprintsInstance.state, "noScanner"); |
3077 | + |
3078 | + var addItem = getAddFingerprintItem(); |
3079 | + compare(addItem.enabled, false); |
3080 | + |
3081 | + var removeButton = getRemoveAllButton(); |
3082 | + compare(removeButton.enabled, false); |
3083 | + |
3084 | + var fingerprintsList = getFingerprintsList(); |
3085 | + compare(fingerprintsList.visible, false); |
3086 | + } |
3087 | + |
3088 | + function test_passcode() { |
3089 | + fingerprintsInstance.passcodeSet = true; |
3090 | + compare(fingerprintsInstance.state, ""); |
3091 | + var setButton = findChild(fingerprintsInstance, "fingerprintSetPasscodeButton"); |
3092 | + compare(setButton.visible, false); |
3093 | + var setupEntry = getSetupEntry(); |
3094 | + compare(setupEntry.enabled, true); |
3095 | + } |
3096 | + |
3097 | + function test_changePasscode() { |
3098 | + fingerprintsInstance.passcodeSet = false; |
3099 | + var setButton = findChild(fingerprintsInstance, "fingerprintSetPasscodeButton"); |
3100 | + |
3101 | + spy.signalName = "requestPasscode" |
3102 | + spy.target = fingerprintsInstance; |
3103 | + mouseClick(setButton, setButton.width / 2, setButton.height / 2); |
3104 | + spy.wait(); |
3105 | + |
3106 | + compare(spy.count, 1); |
3107 | + } |
3108 | + |
3109 | + function test_setup() { |
3110 | + fingerprintsInstance.passcodeSet = false; |
3111 | + var add = getAddFingerprintItem(); |
3112 | + var remove = getRemoveAllButton(); |
3113 | + compare(add.enabled, false); |
3114 | + compare(remove.enabled, false); |
3115 | + } |
3116 | + |
3117 | + function test_noRemove() { |
3118 | + fingerprintsInstance.passcodeSet = true; |
3119 | + GSettingsController.setFingerprintNames({}); |
3120 | + var remove = getRemoveAllButton(); |
3121 | + compare(remove.enabled, false); |
3122 | + } |
3123 | + |
3124 | + function test_remove() { |
3125 | + fingerprintsInstance.passcodeSet = true; |
3126 | + GSettingsController.setFingerprintNames({"tmplId": "A Finger"}); |
3127 | + |
3128 | + var remove = getRemoveAllButton(); |
3129 | + mouseClick(remove, remove.width / 2, remove.height / 2); |
3130 | + var diag = findChild(testRoot, "fingerprintRemoveAllDialog"); |
3131 | + var confirm = findChild(diag, "fingerprintRemoveAllConfirmationButton"); |
3132 | + compare(confirm.visible, true); |
3133 | + mouseClick(confirm, confirm.width / 2, confirm.height / 2); |
3134 | + |
3135 | + var obs = getClearanceObserver(); |
3136 | + spy.signalName = "succeeded"; |
3137 | + spy.target = obs; |
3138 | + obs.mockClearance(""); |
3139 | + spy.wait(); |
3140 | + compare(spy.count, 1); |
3141 | + |
3142 | + // Wait for dialog destruction (which is required for other tests) |
3143 | + // to function. |
3144 | + tryCompareFunction(function() { |
3145 | + return findChild(testRoot, "fingerprintRemoveAllDialog"); |
3146 | + }, null); |
3147 | + } |
3148 | + |
3149 | + function test_enrollmentSucceeded() { |
3150 | + var obs = getEnrollmentObserver(); |
3151 | + var targetFingerprintName = i18n.dtr("ubuntu-settings-components", "Finger %1").arg(1); |
3152 | + spy.signalName = "succeeded"; |
3153 | + spy.target = obs; |
3154 | + obs.mockEnroll("tmplId", ""); |
3155 | + spy.wait(); |
3156 | + compare(spy.count, 1); |
3157 | + compare(spy.signalArguments[0][0], "tmplId"); |
3158 | + |
3159 | + tryCompareFunction(function() { |
3160 | + return GSettingsController.fingerprintNames()["tmplId"]; |
3161 | + }, targetFingerprintName); |
3162 | + } |
3163 | + } |
3164 | +} |
3165 | |
3166 | === added directory 'tests/qmltests/mocks' |
3167 | === added directory 'tests/qmltests/mocks/Biometryd' |
3168 | === added file 'tests/qmltests/mocks/Biometryd/CMakeLists.txt' |
3169 | --- tests/qmltests/mocks/Biometryd/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
3170 | +++ tests/qmltests/mocks/Biometryd/CMakeLists.txt 2016-06-20 13:58:28 +0000 |
3171 | @@ -0,0 +1,20 @@ |
3172 | +include_directories( |
3173 | + ${CMAKE_CURRENT_BINARY_DIR} |
3174 | +) |
3175 | + |
3176 | +set(MOCK_BIOMETRYD_SOURCES |
3177 | + plugin.cpp |
3178 | + MockDevice.cpp |
3179 | + MockFingerprintReader.cpp |
3180 | + MockObserver.cpp |
3181 | + MockOperation.cpp |
3182 | + MockService.cpp |
3183 | + MockTemplateStore.cpp |
3184 | + MockUser.cpp |
3185 | +) |
3186 | + |
3187 | +add_library(MockBiometryd MODULE ${MOCK_BIOMETRYD_SOURCES}) |
3188 | + |
3189 | +qt5_use_modules(MockBiometryd Qml Quick Core) |
3190 | + |
3191 | +add_usc_mock(Biometryd 0.0 Biometryd TARGETS MockBiometryd) |
3192 | |
3193 | === added file 'tests/qmltests/mocks/Biometryd/MockDevice.cpp' |
3194 | --- tests/qmltests/mocks/Biometryd/MockDevice.cpp 1970-01-01 00:00:00 +0000 |
3195 | +++ tests/qmltests/mocks/Biometryd/MockDevice.cpp 2016-06-20 13:58:28 +0000 |
3196 | @@ -0,0 +1,30 @@ |
3197 | +/* |
3198 | + * Copyright (C) 2016 Canonical, Ltd. |
3199 | + * |
3200 | + * This program is free software; you can redistribute it and/or modify |
3201 | + * it under the terms of the GNU General Public License as published by |
3202 | + * the Free Software Foundation; version 3. |
3203 | + * |
3204 | + * This program is distributed in the hope that it will be useful, |
3205 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3206 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3207 | + * GNU General Public License for more details. |
3208 | + * |
3209 | + * You should have received a copy of the GNU General Public License |
3210 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3211 | + */ |
3212 | + |
3213 | +#include "MockDevice.h" |
3214 | + |
3215 | +MockDevice::MockDevice(QObject *parent) |
3216 | + : QObject(parent) |
3217 | + , m_ts(new MockTemplateStore(this)) |
3218 | +{ |
3219 | +} |
3220 | + |
3221 | +MockTemplateStore* MockDevice::templateStore() |
3222 | +{ |
3223 | + return m_ts; |
3224 | +} |
3225 | + |
3226 | +#include "MockDevice.moc" |
3227 | |
3228 | === added file 'tests/qmltests/mocks/Biometryd/MockDevice.h' |
3229 | --- tests/qmltests/mocks/Biometryd/MockDevice.h 1970-01-01 00:00:00 +0000 |
3230 | +++ tests/qmltests/mocks/Biometryd/MockDevice.h 2016-06-20 13:58:28 +0000 |
3231 | @@ -0,0 +1,38 @@ |
3232 | +/* |
3233 | + * Copyright (C) 2016 Canonical, Ltd. |
3234 | + * |
3235 | + * This program is free software; you can redistribute it and/or modify |
3236 | + * it under the terms of the GNU General Public License as published by |
3237 | + * the Free Software Foundation; version 3. |
3238 | + * |
3239 | + * This program is distributed in the hope that it will be useful, |
3240 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3241 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3242 | + * GNU General Public License for more details. |
3243 | + * |
3244 | + * You should have received a copy of the GNU General Public License |
3245 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3246 | + */ |
3247 | + |
3248 | +#ifndef MOCK_DEVICE_H |
3249 | +#define MOCK_DEVICE_H |
3250 | + |
3251 | +#include <QObject> |
3252 | +#include "MockTemplateStore.h" |
3253 | + |
3254 | +class MockDevice : public QObject |
3255 | +{ |
3256 | + Q_OBJECT |
3257 | + Q_DISABLE_COPY(MockDevice) |
3258 | + |
3259 | +public: |
3260 | + explicit MockDevice(QObject *parent = 0); |
3261 | + Q_PROPERTY(MockTemplateStore* templateStore READ templateStore CONSTANT) |
3262 | + |
3263 | + MockTemplateStore* templateStore(); |
3264 | + |
3265 | +private: |
3266 | + MockTemplateStore* m_ts; |
3267 | +}; |
3268 | + |
3269 | +#endif // MOCK_DEVICE_H |
3270 | |
3271 | === added file 'tests/qmltests/mocks/Biometryd/MockFingerprintReader.cpp' |
3272 | --- tests/qmltests/mocks/Biometryd/MockFingerprintReader.cpp 1970-01-01 00:00:00 +0000 |
3273 | +++ tests/qmltests/mocks/Biometryd/MockFingerprintReader.cpp 2016-06-20 13:58:28 +0000 |
3274 | @@ -0,0 +1,49 @@ |
3275 | +/* |
3276 | + * Copyright (C) 2016 Canonical, Ltd. |
3277 | + * |
3278 | + * This program is free software; you can redistribute it and/or modify |
3279 | + * it under the terms of the GNU General Public License as published by |
3280 | + * the Free Software Foundation; version 3. |
3281 | + * |
3282 | + * This program is distributed in the hope that it will be useful, |
3283 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3284 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3285 | + * GNU General Public License for more details. |
3286 | + * |
3287 | + * You should have received a copy of the GNU General Public License |
3288 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3289 | + */ |
3290 | + |
3291 | +#include "MockFingerprintReader.h" |
3292 | + |
3293 | +MockFingerprintReader::MockFingerprintReader(QObject *parent) |
3294 | + : QObject(parent) |
3295 | +{ |
3296 | +} |
3297 | + |
3298 | +QString MockFingerprintReader::isFingerPresent() const |
3299 | +{ |
3300 | + return "isFingerPresent"; |
3301 | +} |
3302 | + |
3303 | +QString MockFingerprintReader::hasMainClusterIdentified() const |
3304 | +{ |
3305 | + return "hasMainClusterIdentified"; |
3306 | +} |
3307 | + |
3308 | +QString MockFingerprintReader::suggestedNextDirection() const |
3309 | +{ |
3310 | + return "suggestedNextDirection"; |
3311 | +} |
3312 | + |
3313 | +QString MockFingerprintReader::estimatedFingerSize() const |
3314 | +{ |
3315 | + return "estimatedFingerSize"; |
3316 | +} |
3317 | + |
3318 | +QString MockFingerprintReader::masks() const |
3319 | +{ |
3320 | + return "masks"; |
3321 | +} |
3322 | + |
3323 | +#include "MockFingerprintReader.moc" |
3324 | |
3325 | === added file 'tests/qmltests/mocks/Biometryd/MockFingerprintReader.h' |
3326 | --- tests/qmltests/mocks/Biometryd/MockFingerprintReader.h 1970-01-01 00:00:00 +0000 |
3327 | +++ tests/qmltests/mocks/Biometryd/MockFingerprintReader.h 2016-06-20 13:58:28 +0000 |
3328 | @@ -0,0 +1,65 @@ |
3329 | +/* |
3330 | + * Copyright (C) 2016 Canonical, Ltd. |
3331 | + * |
3332 | + * This program is free software; you can redistribute it and/or modify |
3333 | + * it under the terms of the GNU General Public License as published by |
3334 | + * the Free Software Foundation; version 3. |
3335 | + * |
3336 | + * This program is distributed in the hope that it will be useful, |
3337 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3338 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3339 | + * GNU General Public License for more details. |
3340 | + * |
3341 | + * You should have received a copy of the GNU General Public License |
3342 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3343 | + */ |
3344 | + |
3345 | +#ifndef MOCK_FINGERPRINTREADER_H |
3346 | +#define MOCK_FINGERPRINTREADER_H |
3347 | + |
3348 | +#include <QObject> |
3349 | +#include <QString> |
3350 | +#include <QVariant> |
3351 | +#include <QList> |
3352 | +#include <QRect> |
3353 | + |
3354 | +class MockFingerprintReader : public QObject |
3355 | + |
3356 | +{ |
3357 | + Q_OBJECT |
3358 | + Q_DISABLE_COPY(MockFingerprintReader) |
3359 | + Q_ENUMS(Direction) |
3360 | + Q_PROPERTY(QString isFingerPresent READ isFingerPresent) |
3361 | + Q_PROPERTY(QString hasMainClusterIdentified READ hasMainClusterIdentified) |
3362 | + Q_PROPERTY(QString suggestedNextDirection READ suggestedNextDirection) |
3363 | + Q_PROPERTY(QString masks READ masks) |
3364 | + |
3365 | +public: |
3366 | + explicit MockFingerprintReader(QObject *parent = 0); |
3367 | + |
3368 | + enum class Direction |
3369 | + { |
3370 | + NotAvailable, |
3371 | + SouthWest, |
3372 | + South, |
3373 | + SouthEast, |
3374 | + NorthWest, |
3375 | + North, |
3376 | + NorthEast, |
3377 | + East, |
3378 | + West |
3379 | + }; |
3380 | + |
3381 | + Q_INVOKABLE QString isFingerPresent() const; |
3382 | + Q_INVOKABLE QString hasMainClusterIdentified() const; |
3383 | + Q_INVOKABLE QString suggestedNextDirection() const; |
3384 | + Q_INVOKABLE QString estimatedFingerSize() const; |
3385 | + Q_INVOKABLE QString masks() const; |
3386 | + |
3387 | + |
3388 | +Q_SIGNALS: |
3389 | + void succeeded(const QVariant &result); |
3390 | + void failed(const QString &reason); |
3391 | +}; |
3392 | + |
3393 | +#endif // MOCK_FINGERPRINTREADER_H |
3394 | |
3395 | === added file 'tests/qmltests/mocks/Biometryd/MockObserver.cpp' |
3396 | --- tests/qmltests/mocks/Biometryd/MockObserver.cpp 1970-01-01 00:00:00 +0000 |
3397 | +++ tests/qmltests/mocks/Biometryd/MockObserver.cpp 2016-06-20 13:58:28 +0000 |
3398 | @@ -0,0 +1,88 @@ |
3399 | +/* |
3400 | + * Copyright (C) 2016 Canonical, Ltd. |
3401 | + * |
3402 | + * This program is free software; you can redistribute it and/or modify |
3403 | + * it under the terms of the GNU General Public License as published by |
3404 | + * the Free Software Foundation; version 3. |
3405 | + * |
3406 | + * This program is distributed in the hope that it will be useful, |
3407 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3408 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3409 | + * GNU General Public License for more details. |
3410 | + * |
3411 | + * You should have received a copy of the GNU General Public License |
3412 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3413 | + */ |
3414 | + |
3415 | +#include "MockObserver.h" |
3416 | + |
3417 | +class Result : public QObject |
3418 | +{ |
3419 | + Q_OBJECT |
3420 | + Q_PROPERTY(unsigned int uid READ uid CONSTANT) |
3421 | + |
3422 | +public: |
3423 | + explicit Result(unsigned int uid, QObject *parent = 0) |
3424 | + : QObject(parent), m_uid(uid) |
3425 | + {} |
3426 | + |
3427 | + unsigned int uid() const { return m_uid; } |
3428 | + |
3429 | +private: |
3430 | + unsigned int m_uid; |
3431 | +}; |
3432 | + |
3433 | +MockObserver::MockObserver(QObject *parent) |
3434 | + : QObject(parent) |
3435 | +{ |
3436 | +} |
3437 | + |
3438 | +void MockObserver::mockSize(int size, const QString &error) |
3439 | +{ |
3440 | + if (error.isEmpty()) |
3441 | + Q_EMIT succeeded(QVariant::fromValue(size)); |
3442 | + else |
3443 | + Q_EMIT failed(error); |
3444 | +} |
3445 | + |
3446 | +void MockObserver::mockEnroll(const QString &templateId, const QString &error) |
3447 | +{ |
3448 | + if (error.isEmpty()) |
3449 | + Q_EMIT succeeded(templateId); |
3450 | + else |
3451 | + Q_EMIT failed(error); |
3452 | +} |
3453 | + |
3454 | +void MockObserver::mockEnrollProgress(double percent, |
3455 | + const QVariantMap& details) |
3456 | +{ |
3457 | + Q_EMIT progressed(percent, details); |
3458 | +} |
3459 | + |
3460 | +void MockObserver::mockClearance(const QString &error) |
3461 | +{ |
3462 | + if (error.isEmpty()) |
3463 | + Q_EMIT succeeded(QVariant()); |
3464 | + else |
3465 | + Q_EMIT failed(error); |
3466 | +} |
3467 | + |
3468 | +void MockObserver::mockRemoval(const QString &templateId, |
3469 | + const QString &error) |
3470 | +{ |
3471 | + if (error.isEmpty()) |
3472 | + Q_EMIT succeeded(templateId); |
3473 | + else |
3474 | + Q_EMIT failed(error); |
3475 | +} |
3476 | + |
3477 | +void MockObserver::mockList(const QStringList &templateIds, |
3478 | + const QString &error) |
3479 | +{ |
3480 | + if (error.isEmpty()) |
3481 | + Q_EMIT succeeded(templateIds); |
3482 | + else |
3483 | + Q_EMIT failed(error); |
3484 | +} |
3485 | + |
3486 | +#include "MockObserver.moc" |
3487 | |
3488 | === added file 'tests/qmltests/mocks/Biometryd/MockObserver.h' |
3489 | --- tests/qmltests/mocks/Biometryd/MockObserver.h 1970-01-01 00:00:00 +0000 |
3490 | +++ tests/qmltests/mocks/Biometryd/MockObserver.h 2016-06-20 13:58:28 +0000 |
3491 | @@ -0,0 +1,52 @@ |
3492 | +/* |
3493 | + * Copyright (C) 2016 Canonical, Ltd. |
3494 | + * |
3495 | + * This program is free software; you can redistribute it and/or modify |
3496 | + * it under the terms of the GNU General Public License as published by |
3497 | + * the Free Software Foundation; version 3. |
3498 | + * |
3499 | + * This program is distributed in the hope that it will be useful, |
3500 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3501 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3502 | + * GNU General Public License for more details. |
3503 | + * |
3504 | + * You should have received a copy of the GNU General Public License |
3505 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3506 | + */ |
3507 | + |
3508 | +#ifndef MOCK_OBSERVER_H |
3509 | +#define MOCK_OBSERVER_H |
3510 | + |
3511 | +#include <QObject> |
3512 | +#include <QString> |
3513 | +#include <QVariant> |
3514 | + |
3515 | +class MockObserver : public QObject |
3516 | +{ |
3517 | + Q_OBJECT |
3518 | + Q_DISABLE_COPY(MockObserver) |
3519 | + |
3520 | +public: |
3521 | + explicit MockObserver(QObject *parent = 0); |
3522 | + |
3523 | + Q_INVOKABLE void mockSize(int size, const QString &error); // only in mock |
3524 | + Q_INVOKABLE void mockEnroll(const QString &templateId, |
3525 | + const QString &error); // only in mock |
3526 | + Q_INVOKABLE void mockEnrollProgress(double percent, |
3527 | + const QVariantMap& details); // only in mock |
3528 | + Q_INVOKABLE void mockClearance(const QString &error); // only in mock |
3529 | + Q_INVOKABLE void mockRemoval(const QString &templateId, |
3530 | + const QString &error); // only in mock |
3531 | + Q_INVOKABLE void mockList(const QStringList &templateIds, |
3532 | + const QString &error); // only in mock |
3533 | + |
3534 | + |
3535 | +Q_SIGNALS: |
3536 | + void progressed(double percent, const QVariantMap& details); |
3537 | + void succeeded(const QVariant &result); |
3538 | + void failed(const QString &reason); |
3539 | + void canceled(const QString& reason); |
3540 | + void started(); |
3541 | +}; |
3542 | + |
3543 | +#endif // MOCK_OBSERVER_H |
3544 | |
3545 | === added file 'tests/qmltests/mocks/Biometryd/MockOperation.cpp' |
3546 | --- tests/qmltests/mocks/Biometryd/MockOperation.cpp 1970-01-01 00:00:00 +0000 |
3547 | +++ tests/qmltests/mocks/Biometryd/MockOperation.cpp 2016-06-20 13:58:28 +0000 |
3548 | @@ -0,0 +1,34 @@ |
3549 | +/* |
3550 | + * Copyright (C) 2016 Canonical, Ltd. |
3551 | + * |
3552 | + * This program is free software; you can redistribute it and/or modify |
3553 | + * it under the terms of the GNU General Public License as published by |
3554 | + * the Free Software Foundation; version 3. |
3555 | + * |
3556 | + * This program is distributed in the hope that it will be useful, |
3557 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3558 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3559 | + * GNU General Public License for more details. |
3560 | + * |
3561 | + * You should have received a copy of the GNU General Public License |
3562 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3563 | + */ |
3564 | + |
3565 | +#include "MockOperation.h" |
3566 | + |
3567 | +MockOperation::MockOperation(QObject *parent) : QObject(parent) |
3568 | +{ |
3569 | +} |
3570 | + |
3571 | +bool MockOperation::start(MockObserver *observer) |
3572 | +{ |
3573 | + Q_UNUSED(observer); |
3574 | + return true; |
3575 | +} |
3576 | + |
3577 | +bool MockOperation::cancel() |
3578 | +{ |
3579 | + return true; |
3580 | +} |
3581 | + |
3582 | +#include "MockOperation.moc" |
3583 | |
3584 | === added file 'tests/qmltests/mocks/Biometryd/MockOperation.h' |
3585 | --- tests/qmltests/mocks/Biometryd/MockOperation.h 1970-01-01 00:00:00 +0000 |
3586 | +++ tests/qmltests/mocks/Biometryd/MockOperation.h 2016-06-20 13:58:28 +0000 |
3587 | @@ -0,0 +1,36 @@ |
3588 | +/* |
3589 | + * Copyright (C) 2016 Canonical, Ltd. |
3590 | + * |
3591 | + * This program is free software; you can redistribute it and/or modify |
3592 | + * it under the terms of the GNU General Public License as published by |
3593 | + * the Free Software Foundation; version 3. |
3594 | + * |
3595 | + * This program is distributed in the hope that it will be useful, |
3596 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3597 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3598 | + * GNU General Public License for more details. |
3599 | + * |
3600 | + * You should have received a copy of the GNU General Public License |
3601 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3602 | + */ |
3603 | + |
3604 | +#ifndef MOCK_OPERATION_H |
3605 | +#define MOCK_OPERATION_H |
3606 | + |
3607 | +#include <QObject> |
3608 | + |
3609 | +class MockObserver; |
3610 | + |
3611 | +class MockOperation : public QObject |
3612 | +{ |
3613 | + Q_OBJECT |
3614 | + Q_DISABLE_COPY(MockOperation) |
3615 | + |
3616 | +public: |
3617 | + explicit MockOperation(QObject *parent = 0); |
3618 | + |
3619 | + Q_INVOKABLE bool start(MockObserver* observer); |
3620 | + Q_INVOKABLE bool cancel(); |
3621 | +}; |
3622 | + |
3623 | +#endif // MOCK_OPERATION_H |
3624 | |
3625 | === added file 'tests/qmltests/mocks/Biometryd/MockService.cpp' |
3626 | --- tests/qmltests/mocks/Biometryd/MockService.cpp 1970-01-01 00:00:00 +0000 |
3627 | +++ tests/qmltests/mocks/Biometryd/MockService.cpp 2016-06-20 13:58:28 +0000 |
3628 | @@ -0,0 +1,42 @@ |
3629 | +/* |
3630 | + * Copyright (C) 2016 Canonical, Ltd. |
3631 | + * |
3632 | + * This program is free software; you can redistribute it and/or modify |
3633 | + * it under the terms of the GNU General Public License as published by |
3634 | + * the Free Software Foundation; version 3. |
3635 | + * |
3636 | + * This program is distributed in the hope that it will be useful, |
3637 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3638 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3639 | + * GNU General Public License for more details. |
3640 | + * |
3641 | + * You should have received a copy of the GNU General Public License |
3642 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3643 | + */ |
3644 | + |
3645 | +#include "MockService.h" |
3646 | + |
3647 | +MockService::MockService(QObject *parent) |
3648 | + : QObject(parent) |
3649 | + , m_device(new MockDevice(this)) |
3650 | + , m_available(false) |
3651 | +{ |
3652 | +} |
3653 | + |
3654 | +MockDevice* MockService::defaultDevice() |
3655 | +{ |
3656 | + return m_device; |
3657 | +} |
3658 | + |
3659 | +bool MockService::isAvailable() const |
3660 | +{ |
3661 | + return m_available; |
3662 | +} |
3663 | + |
3664 | +void MockService::setAvailable(const bool available) |
3665 | +{ |
3666 | + m_available = available; |
3667 | + Q_EMIT (availableChanged(available)); |
3668 | +} |
3669 | + |
3670 | +#include "MockService.moc" |
3671 | |
3672 | === added file 'tests/qmltests/mocks/Biometryd/MockService.h' |
3673 | --- tests/qmltests/mocks/Biometryd/MockService.h 1970-01-01 00:00:00 +0000 |
3674 | +++ tests/qmltests/mocks/Biometryd/MockService.h 2016-06-20 13:58:28 +0000 |
3675 | @@ -0,0 +1,46 @@ |
3676 | +/* |
3677 | + * Copyright (C) 2016 Canonical, Ltd. |
3678 | + * |
3679 | + * This program is free software; you can redistribute it and/or modify |
3680 | + * it under the terms of the GNU General Public License as published by |
3681 | + * the Free Software Foundation; version 3. |
3682 | + * |
3683 | + * This program is distributed in the hope that it will be useful, |
3684 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3685 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3686 | + * GNU General Public License for more details. |
3687 | + * |
3688 | + * You should have received a copy of the GNU General Public License |
3689 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3690 | + */ |
3691 | + |
3692 | +#ifndef MOCK_SERVICE_H |
3693 | +#define MOCK_SERVICE_H |
3694 | + |
3695 | +#include <QObject> |
3696 | + |
3697 | +#include "MockDevice.h" |
3698 | + |
3699 | +class MockService : public QObject |
3700 | +{ |
3701 | + Q_OBJECT |
3702 | + Q_DISABLE_COPY(MockService) |
3703 | + |
3704 | +public: |
3705 | + explicit MockService(QObject *parent = 0); |
3706 | + Q_PROPERTY(MockDevice* defaultDevice READ defaultDevice CONSTANT) |
3707 | + Q_PROPERTY(bool available READ isAvailable NOTIFY availableChanged) |
3708 | + |
3709 | + MockDevice* defaultDevice(); |
3710 | + bool isAvailable() const; |
3711 | + Q_INVOKABLE void setAvailable(const bool available); // mock only |
3712 | + |
3713 | +Q_SIGNALS: |
3714 | + void availableChanged(bool); |
3715 | + |
3716 | +private: |
3717 | + MockDevice* m_device; |
3718 | + bool m_available; |
3719 | +}; |
3720 | + |
3721 | +#endif // MOCK_SERVICE_H |
3722 | |
3723 | === added file 'tests/qmltests/mocks/Biometryd/MockTemplateStore.cpp' |
3724 | --- tests/qmltests/mocks/Biometryd/MockTemplateStore.cpp 1970-01-01 00:00:00 +0000 |
3725 | +++ tests/qmltests/mocks/Biometryd/MockTemplateStore.cpp 2016-06-20 13:58:28 +0000 |
3726 | @@ -0,0 +1,56 @@ |
3727 | +/* |
3728 | + * Copyright (C) 2016 Canonical, Ltd. |
3729 | + * |
3730 | + * This program is free software; you can redistribute it and/or modify |
3731 | + * it under the terms of the GNU General Public License as published by |
3732 | + * the Free Software Foundation; version 3. |
3733 | + * |
3734 | + * This program is distributed in the hope that it will be useful, |
3735 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3736 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3737 | + * GNU General Public License for more details. |
3738 | + * |
3739 | + * You should have received a copy of the GNU General Public License |
3740 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3741 | + */ |
3742 | + |
3743 | +#include "MockTemplateStore.h" |
3744 | + |
3745 | +MockTemplateStore::MockTemplateStore(QObject *parent) |
3746 | +{ |
3747 | + Q_UNUSED(parent); |
3748 | +} |
3749 | + |
3750 | +MockSizeQuery* MockTemplateStore::size(MockUser* user) |
3751 | +{ |
3752 | + Q_UNUSED(user); |
3753 | + return new MockSizeQuery(this); |
3754 | +} |
3755 | + |
3756 | +MockEnrollment* MockTemplateStore::enroll(MockUser* user) |
3757 | +{ |
3758 | + Q_UNUSED(user); |
3759 | + return new MockEnrollment(this); |
3760 | +} |
3761 | + |
3762 | +MockClearance* MockTemplateStore::clear(MockUser* user) |
3763 | +{ |
3764 | + Q_UNUSED(user); |
3765 | + return new MockClearance(this); |
3766 | +} |
3767 | + |
3768 | +MockRemoval* MockTemplateStore::remove(MockUser* user, |
3769 | + const QString &templateId) |
3770 | +{ |
3771 | + Q_UNUSED(user); |
3772 | + Q_UNUSED(templateId); |
3773 | + return new MockRemoval(this); |
3774 | +} |
3775 | + |
3776 | +MockList* MockTemplateStore::list(MockUser* user) |
3777 | +{ |
3778 | + Q_UNUSED(user); |
3779 | + return new MockList(this); |
3780 | +} |
3781 | + |
3782 | +#include "MockTemplateStore.moc" |
3783 | |
3784 | === added file 'tests/qmltests/mocks/Biometryd/MockTemplateStore.h' |
3785 | --- tests/qmltests/mocks/Biometryd/MockTemplateStore.h 1970-01-01 00:00:00 +0000 |
3786 | +++ tests/qmltests/mocks/Biometryd/MockTemplateStore.h 2016-06-20 13:58:28 +0000 |
3787 | @@ -0,0 +1,86 @@ |
3788 | +/* |
3789 | + * Copyright (C) 2016 Canonical, Ltd. |
3790 | + * |
3791 | + * This program is free software; you can redistribute it and/or modify |
3792 | + * it under the terms of the GNU General Public License as published by |
3793 | + * the Free Software Foundation; version 3. |
3794 | + * |
3795 | + * This program is distributed in the hope that it will be useful, |
3796 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3797 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3798 | + * GNU General Public License for more details. |
3799 | + * |
3800 | + * You should have received a copy of the GNU General Public License |
3801 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3802 | + */ |
3803 | + |
3804 | +#ifndef MOCK_TEMPLATESTORE_H |
3805 | +#define MOCK_TEMPLATESTORE_H |
3806 | + |
3807 | +#include <QObject> |
3808 | +#include "MockOperation.h" |
3809 | + |
3810 | +class MockUser; |
3811 | + |
3812 | +class MockSizeQuery : public MockOperation |
3813 | +{ |
3814 | + Q_OBJECT |
3815 | +public: |
3816 | + MockSizeQuery(QObject *parent) : MockOperation(parent) |
3817 | + { |
3818 | + } |
3819 | +}; |
3820 | + |
3821 | +class MockEnrollment : public MockOperation |
3822 | +{ |
3823 | + Q_OBJECT |
3824 | +public: |
3825 | + MockEnrollment(QObject *parent) : MockOperation(parent) |
3826 | + { |
3827 | + } |
3828 | +}; |
3829 | + |
3830 | +class MockClearance : public MockOperation |
3831 | +{ |
3832 | + Q_OBJECT |
3833 | +public: |
3834 | + MockClearance(QObject *parent) : MockOperation(parent) |
3835 | + { |
3836 | + } |
3837 | +}; |
3838 | + |
3839 | +class MockRemoval : public MockOperation |
3840 | +{ |
3841 | + Q_OBJECT |
3842 | +public: |
3843 | + MockRemoval(QObject *parent) : MockOperation(parent) |
3844 | + { |
3845 | + } |
3846 | +}; |
3847 | + |
3848 | +class MockList : public MockOperation |
3849 | +{ |
3850 | + Q_OBJECT |
3851 | +public: |
3852 | + MockList(QObject *parent) : MockOperation(parent) |
3853 | + { |
3854 | + } |
3855 | +}; |
3856 | + |
3857 | +class MockTemplateStore : public QObject |
3858 | +{ |
3859 | + Q_OBJECT |
3860 | + Q_DISABLE_COPY(MockTemplateStore) |
3861 | + |
3862 | +public: |
3863 | + explicit MockTemplateStore(QObject *parent = 0); |
3864 | + |
3865 | + Q_INVOKABLE MockSizeQuery* size(MockUser* user); |
3866 | + Q_INVOKABLE MockEnrollment* enroll(MockUser* user); |
3867 | + Q_INVOKABLE MockClearance* clear(MockUser* user); |
3868 | + Q_INVOKABLE MockRemoval* remove(MockUser* user, |
3869 | + const QString &templateId); |
3870 | + Q_INVOKABLE MockList* list(MockUser* user); |
3871 | +}; |
3872 | + |
3873 | +#endif // MOCK_TEMPLATESTORE_H |
3874 | |
3875 | === added file 'tests/qmltests/mocks/Biometryd/MockUser.cpp' |
3876 | --- tests/qmltests/mocks/Biometryd/MockUser.cpp 1970-01-01 00:00:00 +0000 |
3877 | +++ tests/qmltests/mocks/Biometryd/MockUser.cpp 2016-06-20 13:58:28 +0000 |
3878 | @@ -0,0 +1,33 @@ |
3879 | +/* |
3880 | + * Copyright (C) 2016 Canonical, Ltd. |
3881 | + * |
3882 | + * This program is free software; you can redistribute it and/or modify |
3883 | + * it under the terms of the GNU General Public License as published by |
3884 | + * the Free Software Foundation; version 3. |
3885 | + * |
3886 | + * This program is distributed in the hope that it will be useful, |
3887 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3888 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3889 | + * GNU General Public License for more details. |
3890 | + * |
3891 | + * You should have received a copy of the GNU General Public License |
3892 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3893 | + */ |
3894 | + |
3895 | +#include "MockUser.h" |
3896 | + |
3897 | +MockUser::MockUser(QObject *parent) : QObject(parent) |
3898 | +{ |
3899 | +} |
3900 | + |
3901 | +int MockUser::uid() const |
3902 | +{ |
3903 | + return m_uid; |
3904 | +} |
3905 | + |
3906 | +void MockUser::setUid(const int &uid) |
3907 | +{ |
3908 | + m_uid = uid; |
3909 | +} |
3910 | + |
3911 | +#include "MockUser.moc" |
3912 | |
3913 | === added file 'tests/qmltests/mocks/Biometryd/MockUser.h' |
3914 | --- tests/qmltests/mocks/Biometryd/MockUser.h 1970-01-01 00:00:00 +0000 |
3915 | +++ tests/qmltests/mocks/Biometryd/MockUser.h 2016-06-20 13:58:28 +0000 |
3916 | @@ -0,0 +1,38 @@ |
3917 | +/* |
3918 | + * Copyright (C) 2016 Canonical, Ltd. |
3919 | + * |
3920 | + * This program is free software; you can redistribute it and/or modify |
3921 | + * it under the terms of the GNU General Public License as published by |
3922 | + * the Free Software Foundation; version 3. |
3923 | + * |
3924 | + * This program is distributed in the hope that it will be useful, |
3925 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3926 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3927 | + * GNU General Public License for more details. |
3928 | + * |
3929 | + * You should have received a copy of the GNU General Public License |
3930 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3931 | + */ |
3932 | + |
3933 | +#ifndef MOCK_USER_H |
3934 | +#define MOCK_USER_H |
3935 | + |
3936 | +#include <QObject> |
3937 | + |
3938 | +class MockUser : public QObject |
3939 | +{ |
3940 | + Q_OBJECT |
3941 | + Q_DISABLE_COPY(MockUser) |
3942 | + |
3943 | +public: |
3944 | + explicit MockUser(QObject *parent = 0); |
3945 | + Q_PROPERTY(int uid READ uid WRITE setUid) |
3946 | + |
3947 | + int uid() const; |
3948 | + void setUid(const int &uid); |
3949 | + |
3950 | +private: |
3951 | + int m_uid = 0; |
3952 | +}; |
3953 | + |
3954 | +#endif // MOCK_USER_H |
3955 | |
3956 | === added file 'tests/qmltests/mocks/Biometryd/plugin.cpp' |
3957 | --- tests/qmltests/mocks/Biometryd/plugin.cpp 1970-01-01 00:00:00 +0000 |
3958 | +++ tests/qmltests/mocks/Biometryd/plugin.cpp 2016-06-20 13:58:28 +0000 |
3959 | @@ -0,0 +1,60 @@ |
3960 | +/* |
3961 | + * Copyright (C) 2014 Canonical, Ltd. |
3962 | + * |
3963 | + * This program is free software; you can redistribute it and/or modify |
3964 | + * it under the terms of the GNU General Public License as published by |
3965 | + * the Free Software Foundation; version 3. |
3966 | + * |
3967 | + * This program is distributed in the hope that it will be useful, |
3968 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3969 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3970 | + * GNU General Public License for more details. |
3971 | + * |
3972 | + * You should have received a copy of the GNU General Public License |
3973 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3974 | + */ |
3975 | + |
3976 | +#include "plugin.h" |
3977 | + |
3978 | +#include "MockDevice.h" |
3979 | +#include "MockFingerprintReader.h" |
3980 | +#include "MockObserver.h" |
3981 | +#include "MockOperation.h" |
3982 | +#include "MockService.h" |
3983 | +#include "MockTemplateStore.h" |
3984 | +#include "MockUser.h" |
3985 | + |
3986 | +#include <QtQml> |
3987 | + |
3988 | +void BackendPlugin::registerTypes(const char *uri) |
3989 | +{ |
3990 | + Q_ASSERT(uri == QLatin1String("Biometryd")); |
3991 | + |
3992 | + qmlRegisterType<MockObserver>(uri, 0, 0, "Observer"); |
3993 | + qmlRegisterType<MockUser>(uri, 0, 0, "User"); |
3994 | + |
3995 | + qmlRegisterUncreatableType<MockDevice>(uri, 0, 0, "Device", "Rely on Biometryd.instance"); |
3996 | + |
3997 | + qmlRegisterUncreatableType<MockOperation>(uri, 0, 0, "Operation", "Rely on Biometryd.instance"); |
3998 | + qmlRegisterUncreatableType<MockSizeQuery>(uri, 0, 0, "SizeQuery", "Rely on Biometryd.instance"); |
3999 | + qmlRegisterUncreatableType<MockEnrollment>(uri, 0, 0, "Enrollment", "Rely on Biometryd.instance"); |
4000 | + qmlRegisterUncreatableType<MockClearance>(uri, 0, 0, "Clearance", "Rely on Biometryd.instance"); |
4001 | + qmlRegisterUncreatableType<MockTemplateStore>(uri, 0, 0, "TemplateStore", "Rely on Biometryd.instance"); |
4002 | + qmlRegisterUncreatableType<MockRemoval>(uri, 0, 0, "Removal", "Rely on Biometryd.instance"); |
4003 | + qmlRegisterUncreatableType<MockList>(uri, 0, 0, "List", "Rely on Biometryd.instance"); |
4004 | + |
4005 | + qmlRegisterSingletonType<MockService>( |
4006 | + uri, 0, 0, "Biometryd", |
4007 | + [](QQmlEngine*, QJSEngine*) -> QObject* |
4008 | + { |
4009 | + return new MockService; |
4010 | + } |
4011 | + ); |
4012 | + qmlRegisterSingletonType<MockFingerprintReader>( |
4013 | + uri, 0, 0, "FingerprintReader", |
4014 | + [](QQmlEngine*, QJSEngine*) -> QObject* |
4015 | + { |
4016 | + return new MockFingerprintReader; |
4017 | + } |
4018 | + ); |
4019 | +} |
4020 | |
4021 | === added file 'tests/qmltests/mocks/Biometryd/plugin.h' |
4022 | --- tests/qmltests/mocks/Biometryd/plugin.h 1970-01-01 00:00:00 +0000 |
4023 | +++ tests/qmltests/mocks/Biometryd/plugin.h 2016-06-20 13:58:28 +0000 |
4024 | @@ -0,0 +1,31 @@ |
4025 | +/* |
4026 | + * Copyright (C) 2016 Canonical, Ltd. |
4027 | + * |
4028 | + * This program is free software; you can redistribute it and/or modify |
4029 | + * it under the terms of the GNU General Public License as published by |
4030 | + * the Free Software Foundation; version 3. |
4031 | + * |
4032 | + * This program is distributed in the hope that it will be useful, |
4033 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4034 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4035 | + * GNU General Public License for more details. |
4036 | + * |
4037 | + * You should have received a copy of the GNU General Public License |
4038 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4039 | + */ |
4040 | + |
4041 | +#ifndef MOCK_BIOMETRYD_PLUGIN_H |
4042 | +#define MOCK_BIOMETRYD_PLUGIN_H |
4043 | + |
4044 | +#include <QQmlExtensionPlugin> |
4045 | + |
4046 | +class BackendPlugin : public QQmlExtensionPlugin |
4047 | +{ |
4048 | + Q_OBJECT |
4049 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
4050 | + |
4051 | +public: |
4052 | + void registerTypes(const char *uri) override; |
4053 | +}; |
4054 | + |
4055 | +#endif // MOCK_BIOMETRYD_PLUGIN_H |
4056 | |
4057 | === added file 'tests/qmltests/mocks/Biometryd/qmldir' |
4058 | --- tests/qmltests/mocks/Biometryd/qmldir 1970-01-01 00:00:00 +0000 |
4059 | +++ tests/qmltests/mocks/Biometryd/qmldir 2016-06-20 13:58:28 +0000 |
4060 | @@ -0,0 +1,2 @@ |
4061 | +module Biometryd |
4062 | +plugin MockBiometryd |
4063 | |
4064 | === added file 'tests/qmltests/mocks/CMakeLists.txt' |
4065 | --- tests/qmltests/mocks/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
4066 | +++ tests/qmltests/mocks/CMakeLists.txt 2016-06-20 13:58:28 +0000 |
4067 | @@ -0,0 +1,32 @@ |
4068 | +include(QmlPlugins) |
4069 | + |
4070 | +# Set up and optionally install a mock plugin for ubuntu-settings-components. |
4071 | +# |
4072 | +# add_usc_mock(plugin version path |
4073 | +# [PREFIX string] # Install the plugin to the specified prefix under unity8 private plugin directory |
4074 | +# [...] # See export_qmlfiles and export_qmlplugin documentation for more options |
4075 | +# ) |
4076 | + |
4077 | +macro(add_usc_mock PLUGIN VERSION PATH) |
4078 | + set(single PREFIX) |
4079 | + cmake_parse_arguments(MOCK "" "${single}" "" ${ARGN}) |
4080 | + |
4081 | + if(MOCK_PREFIX) |
4082 | + export_qmlfiles(${PLUGIN} ${PATH} |
4083 | + DESTINATION ${SHELL_INSTALL_QML}/${MOCK_PREFIX} |
4084 | + TARGET_PREFIX ${MOCK_PREFIX}-Mock |
4085 | + ${MOCK_UNPARSED_ARGUMENTS} |
4086 | + ) |
4087 | + export_qmlplugin(${PLUGIN} ${VERSION} ${PATH} |
4088 | + DESTINATION ${SHELL_INSTALL_QML}/${MOCK_PREFIX} |
4089 | + TARGET_PREFIX ${MOCK_PREFIX}-Mock |
4090 | + ${MOCK_UNPARSED_ARGUMENTS} |
4091 | + ) |
4092 | + else() |
4093 | + export_qmlfiles(${PLUGIN} ${PATH} TARGET_PREFIX Mock ${MOCK_UNPARSED_ARGUMENTS}) |
4094 | + export_qmlplugin(${PLUGIN} ${VERSION} ${PATH} TARGET_PREFIX Mock ${MOCK_UNPARSED_ARGUMENTS}) |
4095 | + endif() |
4096 | +endmacro() |
4097 | + |
4098 | +add_subdirectory(Biometryd) |
4099 | +add_subdirectory(GSettings.1.0) |
4100 | |
4101 | === added directory 'tests/qmltests/mocks/GSettings.1.0' |
4102 | === added file 'tests/qmltests/mocks/GSettings.1.0/CMakeLists.txt' |
4103 | --- tests/qmltests/mocks/GSettings.1.0/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
4104 | +++ tests/qmltests/mocks/GSettings.1.0/CMakeLists.txt 2016-06-20 13:58:28 +0000 |
4105 | @@ -0,0 +1,20 @@ |
4106 | +include_directories( |
4107 | + ${CMAKE_CURRENT_BINARY_DIR} |
4108 | + ${Qt5Core_INCLUDE_DIRS} |
4109 | + ${Qt5Quick_INCLUDE_DIRS} |
4110 | +) |
4111 | + |
4112 | +set(GSettingsQML_SOURCES |
4113 | + fake_gsettings.cpp |
4114 | + plugin.cpp |
4115 | +) |
4116 | + |
4117 | +add_library(FakeGSettingsQml MODULE ${GSettingsQML_SOURCES}) |
4118 | +target_link_libraries(FakeGSettingsQml |
4119 | + ${Qt5Core_LIBRARIES} |
4120 | + ${Qt5Quick_LIBRARIES} |
4121 | +) |
4122 | + |
4123 | +qt5_use_modules(FakeGSettingsQml Qml) |
4124 | + |
4125 | +add_usc_mock(GSettings 1.0 GSettings.1.0 TARGETS FakeGSettingsQml) |
4126 | |
4127 | === added file 'tests/qmltests/mocks/GSettings.1.0/fake_gsettings.cpp' |
4128 | --- tests/qmltests/mocks/GSettings.1.0/fake_gsettings.cpp 1970-01-01 00:00:00 +0000 |
4129 | +++ tests/qmltests/mocks/GSettings.1.0/fake_gsettings.cpp 2016-06-20 13:58:28 +0000 |
4130 | @@ -0,0 +1,124 @@ |
4131 | +/* |
4132 | + * Copyright 2013 Canonical Ltd. |
4133 | + * |
4134 | + * This program is free software; you can redistribute it and/or modify |
4135 | + * it under the terms of the GNU Lesser General Public License as published by |
4136 | + * the Free Software Foundation; version 3. |
4137 | + * |
4138 | + * This program is distributed in the hope that it will be useful, |
4139 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4140 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4141 | + * GNU Lesser General Public License for more details. |
4142 | + * |
4143 | + * You should have received a copy of the GNU Lesser General Public License |
4144 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4145 | + */ |
4146 | + |
4147 | +#include "fake_gsettings.h" |
4148 | + |
4149 | +#include <QDebug> |
4150 | + |
4151 | +GSettingsControllerQml* GSettingsControllerQml::s_controllerInstance = 0; |
4152 | + |
4153 | +GSettingsControllerQml::GSettingsControllerQml() |
4154 | + : m_fingerprintNames() |
4155 | +{ |
4156 | +} |
4157 | + |
4158 | +GSettingsControllerQml::~GSettingsControllerQml() { |
4159 | + s_controllerInstance = 0; |
4160 | +} |
4161 | + |
4162 | +GSettingsControllerQml* GSettingsControllerQml::instance() { |
4163 | + if (!s_controllerInstance) { |
4164 | + s_controllerInstance = new GSettingsControllerQml(); |
4165 | + } |
4166 | + return s_controllerInstance; |
4167 | +} |
4168 | + |
4169 | +QVariantMap GSettingsControllerQml::fingerprintNames() const |
4170 | +{ |
4171 | + return m_fingerprintNames; |
4172 | +} |
4173 | + |
4174 | +void GSettingsControllerQml::setFingerprintNames(QVariantMap map) |
4175 | +{ |
4176 | + if (map != m_fingerprintNames) { |
4177 | + m_fingerprintNames = map; |
4178 | + Q_EMIT fingerprintNamesChanged(); |
4179 | + } |
4180 | +} |
4181 | + |
4182 | +GSettingsSchemaQml::GSettingsSchemaQml(QObject *parent): QObject(parent) { |
4183 | +} |
4184 | + |
4185 | +QByteArray GSettingsSchemaQml::id() const { |
4186 | + return m_id; |
4187 | +} |
4188 | + |
4189 | +void GSettingsSchemaQml::setId(const QByteArray &id) { |
4190 | + if (!m_id.isEmpty()) { |
4191 | + qWarning("GSettings.schema.id may only be set on construction"); |
4192 | + return; |
4193 | + } |
4194 | + |
4195 | + m_id = id; |
4196 | +} |
4197 | + |
4198 | +QByteArray GSettingsSchemaQml::path() const { |
4199 | + return m_path; |
4200 | +} |
4201 | + |
4202 | +void GSettingsSchemaQml::setPath(const QByteArray &path) { |
4203 | + if (!m_path.isEmpty()) { |
4204 | + qWarning("GSettings.schema.path may only be set on construction"); |
4205 | + return; |
4206 | + } |
4207 | + |
4208 | + m_path = path; |
4209 | +} |
4210 | + |
4211 | +GSettingsQml::GSettingsQml(QObject *parent) |
4212 | + : QObject(parent), |
4213 | + m_valid(false) |
4214 | +{ |
4215 | + m_schema = new GSettingsSchemaQml(this); |
4216 | +} |
4217 | + |
4218 | +void GSettingsQml::classBegin() |
4219 | +{ |
4220 | +} |
4221 | + |
4222 | +void GSettingsQml::componentComplete() |
4223 | +{ |
4224 | + // Emulate what the real GSettings module does, and only return undefined |
4225 | + // values until we are completed loading. |
4226 | + m_valid = true; |
4227 | + |
4228 | + // FIXME: We should make this dynamic, instead of hard-coding all possible |
4229 | + // properties in one object. We should create properties based on the schema. |
4230 | + connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::fingerprintNamesChanged, |
4231 | + this, &GSettingsQml::fingerprintNamesChanged); |
4232 | + |
4233 | + Q_EMIT fingerprintNamesChanged(); |
4234 | +} |
4235 | + |
4236 | +GSettingsSchemaQml * GSettingsQml::schema() const { |
4237 | + return m_schema; |
4238 | +} |
4239 | + |
4240 | +QVariantMap GSettingsQml::fingerprintNames() const |
4241 | +{ |
4242 | + if (m_valid && m_schema->id() == "com.ubuntu.touch.system") { |
4243 | + return GSettingsControllerQml::instance()->fingerprintNames(); |
4244 | + } else { |
4245 | + return QVariantMap(); |
4246 | + } |
4247 | +} |
4248 | + |
4249 | +void GSettingsQml::setFingerprintNames(const QVariantMap &map) |
4250 | +{ |
4251 | + if (m_valid && m_schema->id() == "com.ubuntu.touch.system") { |
4252 | + GSettingsControllerQml::instance()->setFingerprintNames(map); |
4253 | + } |
4254 | +} |
4255 | |
4256 | === added file 'tests/qmltests/mocks/GSettings.1.0/fake_gsettings.h' |
4257 | --- tests/qmltests/mocks/GSettings.1.0/fake_gsettings.h 1970-01-01 00:00:00 +0000 |
4258 | +++ tests/qmltests/mocks/GSettings.1.0/fake_gsettings.h 2016-06-20 13:58:28 +0000 |
4259 | @@ -0,0 +1,101 @@ |
4260 | +/* |
4261 | + * Copyright 2013 Canonical Ltd. |
4262 | + * |
4263 | + * This program is free software; you can redistribute it and/or modify |
4264 | + * it under the terms of the GNU Lesser General Public License as published by |
4265 | + * the Free Software Foundation; version 3. |
4266 | + * |
4267 | + * This program is distributed in the hope that it will be useful, |
4268 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4269 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4270 | + * GNU Lesser General Public License for more details. |
4271 | + * |
4272 | + * You should have received a copy of the GNU Lesser General Public License |
4273 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4274 | + */ |
4275 | + |
4276 | +#ifndef FAKE_GSETTINGS_H |
4277 | +#define FAKE_GSETTINGS_H |
4278 | + |
4279 | +#include <QList> |
4280 | +#include <QObject> |
4281 | +#include <QQmlParserStatus> |
4282 | +#include <QStringList> |
4283 | +#include <QVariant> |
4284 | + |
4285 | +class GSettingsSchemaQml: public QObject |
4286 | +{ |
4287 | + Q_OBJECT |
4288 | + |
4289 | + Q_PROPERTY(QByteArray id READ id WRITE setId) |
4290 | +public: |
4291 | + GSettingsSchemaQml(QObject *parent = nullptr); |
4292 | + |
4293 | + QByteArray id() const; |
4294 | + void setId(const QByteArray &id); |
4295 | + |
4296 | + QByteArray path() const; |
4297 | + void setPath(const QByteArray &path); |
4298 | + |
4299 | +private: |
4300 | + QByteArray m_id; |
4301 | + QByteArray m_path; |
4302 | +}; |
4303 | + |
4304 | +class GSettingsQml: public QObject, public QQmlParserStatus |
4305 | +{ |
4306 | + Q_OBJECT |
4307 | + Q_INTERFACES(QQmlParserStatus) |
4308 | + |
4309 | + Q_PROPERTY(GSettingsSchemaQml* schema READ schema NOTIFY schemaChanged) |
4310 | + Q_PROPERTY(QVariantMap fingerprintNames |
4311 | + READ fingerprintNames |
4312 | + WRITE setFingerprintNames |
4313 | + NOTIFY fingerprintNamesChanged) |
4314 | + |
4315 | +public: |
4316 | + GSettingsQml(QObject *parent = nullptr); |
4317 | + |
4318 | + void classBegin() override; |
4319 | + void componentComplete() override; |
4320 | + |
4321 | + GSettingsSchemaQml * schema() const; |
4322 | + |
4323 | + QVariantMap fingerprintNames() const; |
4324 | + void setFingerprintNames(const QVariantMap &map); |
4325 | + |
4326 | +Q_SIGNALS: |
4327 | + void fingerprintNamesChanged(); |
4328 | + void schemaChanged(); |
4329 | + |
4330 | +private: |
4331 | + GSettingsSchemaQml* m_schema; |
4332 | + bool m_valid; |
4333 | + |
4334 | + friend class GSettingsSchemaQml; |
4335 | +}; |
4336 | + |
4337 | +class GSettingsControllerQml: public QObject |
4338 | +{ |
4339 | + Q_OBJECT |
4340 | + |
4341 | +public: |
4342 | + static GSettingsControllerQml* instance(); |
4343 | + ~GSettingsControllerQml(); |
4344 | + |
4345 | + Q_INVOKABLE QVariantMap fingerprintNames() const; |
4346 | + Q_INVOKABLE void setFingerprintNames(QVariantMap map); |
4347 | + |
4348 | +Q_SIGNALS: |
4349 | + void fingerprintNamesChanged(); |
4350 | + |
4351 | +private: |
4352 | + GSettingsControllerQml(); |
4353 | + |
4354 | + QVariantMap m_fingerprintNames; |
4355 | + |
4356 | + static GSettingsControllerQml* s_controllerInstance; |
4357 | + QList<GSettingsQml *> m_registeredGSettings; |
4358 | +}; |
4359 | + |
4360 | +#endif // FAKE_GSETTINGS_H |
4361 | |
4362 | === added file 'tests/qmltests/mocks/GSettings.1.0/plugin.cpp' |
4363 | --- tests/qmltests/mocks/GSettings.1.0/plugin.cpp 1970-01-01 00:00:00 +0000 |
4364 | +++ tests/qmltests/mocks/GSettings.1.0/plugin.cpp 2016-06-20 13:58:28 +0000 |
4365 | @@ -0,0 +1,33 @@ |
4366 | +/* |
4367 | + * Copyright (C) 2013 Canonical, Ltd. |
4368 | + * |
4369 | + * This program is free software; you can redistribute it and/or modify |
4370 | + * it under the terms of the GNU General Public License as published by |
4371 | + * the Free Software Foundation; version 3. |
4372 | + * |
4373 | + * This program is distributed in the hope that it will be useful, |
4374 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4375 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4376 | + * GNU General Public License for more details. |
4377 | + * |
4378 | + * You should have received a copy of the GNU General Public License |
4379 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4380 | + */ |
4381 | + |
4382 | +#include "plugin.h" |
4383 | +#include "fake_gsettings.h" |
4384 | + |
4385 | +#include <QtQml/qqml.h> |
4386 | + |
4387 | +static QObject* controllerProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */) |
4388 | +{ |
4389 | + return GSettingsControllerQml::instance(); |
4390 | +} |
4391 | + |
4392 | +void FakeGSettingsQmlPlugin::registerTypes(const char *uri) |
4393 | +{ |
4394 | + qmlRegisterSingletonType<GSettingsControllerQml>(uri, 1, 0, "GSettingsController", controllerProvider); |
4395 | + qmlRegisterType<GSettingsQml>(uri, 1, 0, "GSettings"); |
4396 | + qmlRegisterUncreatableType<GSettingsSchemaQml>(uri, 1, 0, "GSettingsSchema", |
4397 | + "GSettingsSchema can only be used inside of a GSettings component"); |
4398 | +} |
4399 | |
4400 | === added file 'tests/qmltests/mocks/GSettings.1.0/plugin.h' |
4401 | --- tests/qmltests/mocks/GSettings.1.0/plugin.h 1970-01-01 00:00:00 +0000 |
4402 | +++ tests/qmltests/mocks/GSettings.1.0/plugin.h 2016-06-20 13:58:28 +0000 |
4403 | @@ -0,0 +1,31 @@ |
4404 | +/* |
4405 | + * Copyright (C) 2013 Canonical, Ltd. |
4406 | + * |
4407 | + * This program is free software; you can redistribute it and/or modify |
4408 | + * it under the terms of the GNU General Public License as published by |
4409 | + * the Free Software Foundation; version 3. |
4410 | + * |
4411 | + * This program is distributed in the hope that it will be useful, |
4412 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4413 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4414 | + * GNU General Public License for more details. |
4415 | + * |
4416 | + * You should have received a copy of the GNU General Public License |
4417 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4418 | + */ |
4419 | + |
4420 | +#ifndef PLUGIN_H |
4421 | +#define PLUGIN_H |
4422 | + |
4423 | +#include <QtQml/QQmlExtensionPlugin> |
4424 | + |
4425 | +class FakeGSettingsQmlPlugin : public QQmlExtensionPlugin |
4426 | +{ |
4427 | + Q_OBJECT |
4428 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
4429 | + |
4430 | +public: |
4431 | + void registerTypes(const char *uri) override; |
4432 | +}; |
4433 | + |
4434 | +#endif // PLUGIN_H |
4435 | |
4436 | === added file 'tests/qmltests/mocks/GSettings.1.0/qmldir' |
4437 | --- tests/qmltests/mocks/GSettings.1.0/qmldir 1970-01-01 00:00:00 +0000 |
4438 | +++ tests/qmltests/mocks/GSettings.1.0/qmldir 2016-06-20 13:58:28 +0000 |
4439 | @@ -0,0 +1,2 @@ |
4440 | +module GSettings |
4441 | +plugin FakeGSettingsQml |
The code looks good, but there are a few places where there is code left in commented out. Let's get that removed.