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