Merge lp:~laney/ubuntu-system-settings/security-privacy-set-security-demo into lp:ubuntu-system-settings
- security-privacy-set-security-demo
- Merge into trunk
Proposed by
Iain Lane
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Sebastien Bacher | ||||
Approved revision: | 326 | ||||
Merged at revision: | 329 | ||||
Proposed branch: | lp:~laney/ubuntu-system-settings/security-privacy-set-security-demo | ||||
Merge into: | lp:ubuntu-system-settings | ||||
Diff against target: |
500 lines (+140/-65) 6 files modified
plugins/battery/PageComponent.qml (+6/-4) plugins/security-privacy/LockSecurity.qml (+70/-47) plugins/security-privacy/PhoneLocking.qml (+9/-8) plugins/security-privacy/securityprivacy.cpp (+39/-1) plugins/security-privacy/securityprivacy.h (+16/-0) schema/com.ubuntu.touch.system-settings.gschema.xml (+0/-5) |
||||
To merge this branch: | bzr merge lp:~laney/ubuntu-system-settings/security-privacy-set-security-demo | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sebastien Bacher (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+184330@code.launchpad.net |
Commit message
Set the unlock type in a QSettings file (~/.unity8-
Description of the change
Set the unlock type in a QSettings file
https:/
passwordValue support will come in a followup MP
To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Approve
(continuous-integration)
Revision history for this message
Sebastien Bacher (seb128) wrote : | # |
That seems to work great!
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'plugins/battery/PageComponent.qml' |
2 | --- plugins/battery/PageComponent.qml 2013-09-05 16:38:31 +0000 |
3 | +++ plugins/battery/PageComponent.qml 2013-09-06 15:14:57 +0000 |
4 | @@ -25,6 +25,8 @@ |
5 | import Ubuntu.Components 0.1 |
6 | import Ubuntu.Components.ListItems 0.1 as ListItem |
7 | import Ubuntu.SystemSettings.Battery 1.0 |
8 | +import Ubuntu.SystemSettings.SecurityPrivacy 1.0 |
9 | + |
10 | |
11 | ItemPage { |
12 | id: root |
13 | @@ -54,9 +56,8 @@ |
14 | schema.id: batteryBackend.powerdRunning ? "com.canonical.powerd" : "org.gnome.settings-daemon.plugins.power" |
15 | } |
16 | |
17 | - GSettings { |
18 | - id: settingsSchema |
19 | - schema.id: "com.ubuntu.touch.system-settings" |
20 | + UbuntuSecurityPrivacyPanel { |
21 | + id: securityPrivacy |
22 | } |
23 | |
24 | BatteryInfo { |
25 | @@ -200,7 +201,8 @@ |
26 | |
27 | ListItem.SingleValue { |
28 | property bool lockOnSuspend: |
29 | - settingsSchema.unlockMethod !== "swipe" |
30 | + securityPrivacy.securityType !== |
31 | + UbuntuSecurityPrivacyPanel.Swipe |
32 | text: lockOnSuspend ? i18n.tr("Lock when idle") : i18n.tr("Sleep when idle") |
33 | value: { |
34 | if (batteryBackend.powerdRunning ) { |
35 | |
36 | === modified file 'plugins/security-privacy/LockSecurity.qml' |
37 | --- plugins/security-privacy/LockSecurity.qml 2013-09-05 17:10:05 +0000 |
38 | +++ plugins/security-privacy/LockSecurity.qml 2013-09-06 15:14:57 +0000 |
39 | @@ -23,23 +23,23 @@ |
40 | import Ubuntu.Components 0.1 |
41 | import Ubuntu.Components.ListItems 0.1 as ListItem |
42 | import Ubuntu.Components.Popups 0.1 |
43 | +import Ubuntu.SystemSettings.SecurityPrivacy 1.0 |
44 | import SystemSettings 1.0 |
45 | |
46 | ItemPage { |
47 | title: i18n.tr("Lock security") |
48 | |
49 | - GSettings { |
50 | - id: settingsSchema |
51 | - schema.id: "com.ubuntu.touch.system-settings" |
52 | + UbuntuSecurityPrivacyPanel { |
53 | + id: securityPrivacy |
54 | } |
55 | |
56 | - function getUnlockMethod() { |
57 | - switch (settingsSchema.unlockMethod) { |
58 | - case "swipe": |
59 | + function methodToIndex(method) { |
60 | + switch (method) { |
61 | + case UbuntuSecurityPrivacyPanel.Swipe: |
62 | return 0 |
63 | - case "passcode": |
64 | + case UbuntuSecurityPrivacyPanel.Passcode: |
65 | return 1 |
66 | - case "password": |
67 | + case UbuntuSecurityPrivacyPanel.Passphrase: |
68 | return 2 |
69 | } |
70 | } |
71 | @@ -47,19 +47,19 @@ |
72 | function indexToMethod(index) { |
73 | switch (index) { |
74 | case 0: |
75 | - return "swipe" |
76 | + return UbuntuSecurityPrivacyPanel.Swipe |
77 | case 1: |
78 | - return "passcode" |
79 | + return UbuntuSecurityPrivacyPanel.Passcode |
80 | case 2: |
81 | - return "password" |
82 | + return UbuntuSecurityPrivacyPanel.Passphrase |
83 | } |
84 | } |
85 | |
86 | Dialog { |
87 | id: changeSecurityDialog |
88 | |
89 | - property string oldMethod: settingsSchema.unlockMethod |
90 | - property string newMethod: indexToMethod(unlockMethod.selectedIndex) |
91 | + property int oldMethod: securityPrivacy.securityType |
92 | + property int newMethod: indexToMethod(unlockMethod.selectedIndex) |
93 | |
94 | function clearInputs() { |
95 | currentInput.text = "" |
96 | @@ -71,18 +71,20 @@ |
97 | if (changeSecurityDialog.newMethod == |
98 | changeSecurityDialog.oldMethod) { // Changing existing |
99 | switch (changeSecurityDialog.newMethod) { |
100 | - case "passcode": |
101 | + case UbuntuSecurityPrivacyPanel.Passcode: |
102 | return i18n.tr("Change passcode") |
103 | - case "password": |
104 | + case UbuntuSecurityPrivacyPanel.Passphrase: |
105 | return i18n.tr("Change passphrase") |
106 | + default: // To stop the runtime complaining |
107 | + return i18n.tr("Change") |
108 | } |
109 | } else { |
110 | switch (changeSecurityDialog.newMethod) { |
111 | - case "swipe": |
112 | + case UbuntuSecurityPrivacyPanel.Swipe: |
113 | return i18n.tr("Switch to swipe") |
114 | - case "passcode": |
115 | + case UbuntuSecurityPrivacyPanel.Passcode: |
116 | return i18n.tr("Switch to passcode") |
117 | - case "password": |
118 | + case UbuntuSecurityPrivacyPanel.Passphrase: |
119 | return i18n.tr("Switch to passphrase") |
120 | } |
121 | } |
122 | @@ -91,9 +93,9 @@ |
123 | Label { |
124 | text: { |
125 | switch (changeSecurityDialog.oldMethod) { |
126 | - case "passcode": |
127 | + case UbuntuSecurityPrivacyPanel.Passcode: |
128 | return i18n.tr("Existing passcode") |
129 | - case "password": |
130 | + case UbuntuSecurityPrivacyPanel.Passphrase: |
131 | return i18n.tr("Existing passphrase") |
132 | // Shouldn't be reached when visible but still evaluated |
133 | default: |
134 | @@ -108,9 +110,11 @@ |
135 | id: currentInput |
136 | echoMode: TextInput.Password |
137 | inputMethodHints: { |
138 | - if (changeSecurityDialog.oldMethod === "password") |
139 | + if (changeSecurityDialog.oldMethod === |
140 | + UbuntuSecurityPrivacyPanel.Passphrase) |
141 | return Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData |
142 | - else if (changeSecurityDialog.oldMethod === "passcode") |
143 | + else if (changeSecurityDialog.oldMethod === |
144 | + UbuntuSecurityPrivacyPanel.Passcode) |
145 | return Qt.ImhNoAutoUppercase | |
146 | Qt.ImhSensitiveData | |
147 | Qt.ImhDigitsOnly |
148 | @@ -118,21 +122,24 @@ |
149 | return Qt.ImhNone |
150 | } |
151 | inputMask: { |
152 | - if (changeSecurityDialog.oldMethod === "passcode") |
153 | + if (changeSecurityDialog.oldMethod === |
154 | + UbuntuSecurityPrivacyPanel.Passcode) |
155 | return "9999" |
156 | else |
157 | return "" |
158 | } |
159 | - visible: changeSecurityDialog.oldMethod === "password" || |
160 | - changeSecurityDialog.oldMethod === "passcode" |
161 | + visible: changeSecurityDialog.oldMethod === |
162 | + UbuntuSecurityPrivacyPanel.Passphrase || |
163 | + changeSecurityDialog.oldMethod === |
164 | + UbuntuSecurityPrivacyPanel.Passcode |
165 | } |
166 | |
167 | Label { |
168 | text: { |
169 | switch (changeSecurityDialog.newMethod) { |
170 | - case "passcode": |
171 | + case UbuntuSecurityPrivacyPanel.Passcode: |
172 | return i18n.tr("Choose passcode") |
173 | - case "password": |
174 | + case UbuntuSecurityPrivacyPanel.Passphrase: |
175 | return i18n.tr("Choose passphrase") |
176 | // Shouldn't be reached when visible but still evaluated |
177 | default: |
178 | @@ -146,9 +153,11 @@ |
179 | id: newInput |
180 | echoMode: TextInput.Password |
181 | inputMethodHints: { |
182 | - if (changeSecurityDialog.newMethod === "password") |
183 | + if (changeSecurityDialog.newMethod === |
184 | + UbuntuSecurityPrivacyPanel.Passphrase) |
185 | return Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData |
186 | - else if (changeSecurityDialog.newMethod === "passcode") |
187 | + else if (changeSecurityDialog.newMethod === |
188 | + UbuntuSecurityPrivacyPanel.Passcode) |
189 | return Qt.ImhNoAutoUppercase | |
190 | Qt.ImhSensitiveData | |
191 | Qt.ImhDigitsOnly |
192 | @@ -156,21 +165,24 @@ |
193 | return Qt.ImhNone |
194 | } |
195 | inputMask: { |
196 | - if (changeSecurityDialog.newMethod === "passcode") |
197 | + if (changeSecurityDialog.newMethod === |
198 | + UbuntuSecurityPrivacyPanel.Passcode) |
199 | return "9999" |
200 | else |
201 | return "" |
202 | } |
203 | - visible: changeSecurityDialog.newMethod === "passcode" || |
204 | - changeSecurityDialog.newMethod === "password" |
205 | + visible: changeSecurityDialog.newMethod === |
206 | + UbuntuSecurityPrivacyPanel.Passcode || |
207 | + changeSecurityDialog.newMethod === |
208 | + UbuntuSecurityPrivacyPanel.Passphrase |
209 | } |
210 | |
211 | Label { |
212 | text: { |
213 | switch (changeSecurityDialog.newMethod) { |
214 | - case "passcode": |
215 | + case UbuntuSecurityPrivacyPanel.Passcode: |
216 | return i18n.tr("Confirm passcode") |
217 | - case "password": |
218 | + case UbuntuSecurityPrivacyPanel.Passphrase: |
219 | return i18n.tr("Conrifm passphrase") |
220 | // Shouldn't be reached when visible but still evaluated |
221 | default: |
222 | @@ -184,9 +196,11 @@ |
223 | id: confirmInput |
224 | echoMode: TextInput.Password |
225 | inputMethodHints: { |
226 | - if (changeSecurityDialog.newMethod === "password") |
227 | + if (changeSecurityDialog.newMethod === |
228 | + UbuntuSecurityPrivacyPanel.Passphrase) |
229 | return Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData |
230 | - else if (changeSecurityDialog.newMethod === "passcode") |
231 | + else if (changeSecurityDialog.newMethod === |
232 | + UbuntuSecurityPrivacyPanel.Passcode) |
233 | return Qt.ImhNoAutoUppercase | |
234 | Qt.ImhSensitiveData | |
235 | Qt.ImhDigitsOnly |
236 | @@ -194,24 +208,30 @@ |
237 | return Qt.ImhNone |
238 | } |
239 | inputMask: { |
240 | - if (changeSecurityDialog.newMethod === "passcode") |
241 | + if (changeSecurityDialog.newMethod === |
242 | + UbuntuSecurityPrivacyPanel.Passcode) |
243 | return "9999" |
244 | else |
245 | return "" |
246 | } |
247 | - visible: changeSecurityDialog.newMethod === "passcode" || |
248 | - changeSecurityDialog.newMethod === "password" |
249 | + visible: changeSecurityDialog.newMethod === |
250 | + UbuntuSecurityPrivacyPanel.Passcode || |
251 | + changeSecurityDialog.newMethod === |
252 | + UbuntuSecurityPrivacyPanel.Passphrase |
253 | } |
254 | |
255 | Button { |
256 | - text: changeSecurityDialog.newMethod === "swipe" ? |
257 | + text: changeSecurityDialog.newMethod === |
258 | + UbuntuSecurityPrivacyPanel.Swipe ? |
259 | i18n.tr("Unset") : |
260 | i18n.tr("Continue") |
261 | enabled: newInput.text == confirmInput.text |
262 | onClicked: { |
263 | PopupUtils.close(changeSecurityDialog) |
264 | //TODO: Check it's correct before updating and do the update |
265 | - settingsSchema.unlockMethod = changeSecurityDialog.newMethod |
266 | + securityPrivacy.securityType = |
267 | + indexToMethod(unlockMethod.selectedIndex) |
268 | + |
269 | changeSecurityDialog.clearInputs() |
270 | } |
271 | |
272 | @@ -222,7 +242,8 @@ |
273 | onClicked: { |
274 | PopupUtils.close(changeSecurityDialog) |
275 | unlockMethod.skip = true |
276 | - unlockMethod.selectedIndex = getUnlockMethod() |
277 | + unlockMethod.selectedIndex = |
278 | + methodToIndex(securityPrivacy.securityType) |
279 | changeSecurityDialog.clearInputs() |
280 | } |
281 | } |
282 | @@ -256,7 +277,8 @@ |
283 | expanded: true |
284 | onExpandedChanged: expanded = true |
285 | onSelectedIndexChanged: { |
286 | - if (getUnlockMethod() === 0 && firstRun) { // swipe |
287 | + if (securityPrivacy.securityType === |
288 | + UbuntuSecurityPrivacyPanel.Swipe && firstRun) { |
289 | changeSecurityDialog.show() |
290 | firstRun = false |
291 | } |
292 | @@ -273,19 +295,20 @@ |
293 | Binding { |
294 | target: unlockMethod |
295 | property: "selectedIndex" |
296 | - value: getUnlockMethod() |
297 | + value: methodToIndex(securityPrivacy.securityType) |
298 | } |
299 | |
300 | ListItem.SingleControl { |
301 | |
302 | - visible: settingsSchema.unlockMethod !== "swipe" // Swipe |
303 | + visible: securityPrivacy.securityType !== |
304 | + UbuntuSecurityPrivacyPanel.Swipe |
305 | |
306 | control: Button { |
307 | property string changePasscode: i18n.tr("Change passcode…") |
308 | property string changePassphrase: i18n.tr("Change passphrase…") |
309 | |
310 | - property bool passcode: |
311 | - settingsSchema.unlockMethod === "passcode" |
312 | + property bool passcode: securityPrivacy.securityType === |
313 | + UbuntuSecurityPrivacyPanel.Passcode |
314 | |
315 | enabled: parent.visible |
316 | |
317 | |
318 | === modified file 'plugins/security-privacy/PhoneLocking.qml' |
319 | --- plugins/security-privacy/PhoneLocking.qml 2013-09-04 15:00:48 +0000 |
320 | +++ plugins/security-privacy/PhoneLocking.qml 2013-09-06 15:14:57 +0000 |
321 | @@ -23,13 +23,13 @@ |
322 | import SystemSettings 1.0 |
323 | import Ubuntu.Components 0.1 |
324 | import Ubuntu.Components.ListItems 0.1 as ListItem |
325 | +import Ubuntu.SystemSettings.SecurityPrivacy 1.0 |
326 | |
327 | ItemPage { |
328 | title: i18n.tr("Phone locking") |
329 | |
330 | - GSettings { |
331 | - id: settingsSchema |
332 | - schema.id: "com.ubuntu.touch.system-settings" |
333 | + UbuntuSecurityPrivacyPanel { |
334 | + id: securityPrivacy |
335 | } |
336 | |
337 | Column { |
338 | @@ -43,12 +43,12 @@ |
339 | |
340 | text: i18n.tr("Lock security") |
341 | value: { |
342 | - switch (settingsSchema.unlockMethod) { |
343 | - case "swipe": |
344 | + switch (securityPrivacy.securityType) { |
345 | + case UbuntuSecurityPrivacyPanel.Swipe: |
346 | return swipe |
347 | - case "passcode": |
348 | + case UbuntuSecurityPrivacyPanel.Passcode: |
349 | return passcode |
350 | - case "password": |
351 | + case UbuntuSecurityPrivacyPanel.Passphrase: |
352 | return passphrase |
353 | } |
354 | } |
355 | @@ -57,7 +57,8 @@ |
356 | } |
357 | |
358 | ListItem.SingleValue { |
359 | - property bool lockOnSuspend: settingsSchema.unlockMethod !== "swipe" |
360 | + property bool lockOnSuspend: securityPrivacy.securityType !== |
361 | + UbuntuSecurityPrivacyPanel.Swipe |
362 | text: lockOnSuspend ? i18n.tr("Lock when idle") |
363 | : i18n.tr("Sleep when idle") |
364 | value: i18n.tr("1 minute", |
365 | |
366 | === modified file 'plugins/security-privacy/securityprivacy.cpp' |
367 | --- plugins/security-privacy/securityprivacy.cpp 2013-08-27 12:48:42 +0000 |
368 | +++ plugins/security-privacy/securityprivacy.cpp 2013-09-06 15:14:57 +0000 |
369 | @@ -18,6 +18,7 @@ |
370 | */ |
371 | |
372 | #include "securityprivacy.h" |
373 | +#include <QtCore/QDir> |
374 | #include <QtDBus/QDBusConnection> |
375 | #include <QtDBus/QDBusConnectionInterface> |
376 | #include <QtDBus/QDBusMessage> |
377 | @@ -36,7 +37,9 @@ |
378 | m_accountsserviceIface ("org.freedesktop.Accounts", |
379 | "/org/freedesktop/Accounts", |
380 | "org.freedesktop.Accounts", |
381 | - m_systemBusConnection) |
382 | + m_systemBusConnection), |
383 | + m_lockSettings(QDir::home().filePath(".unity8-greeter-demo"), |
384 | + QSettings::NativeFormat) |
385 | { |
386 | connect (&m_serviceWatcher, |
387 | SIGNAL (serviceOwnerChanged (QString, QString, QString)), |
388 | @@ -168,3 +171,38 @@ |
389 | setUserProperty("MessagesWelcomeScreen", QVariant::fromValue(enabled)); |
390 | Q_EMIT(messagesWelcomeScreenChanged()); |
391 | } |
392 | + |
393 | +SecurityPrivacy::SecurityType SecurityPrivacy::getSecurityType() |
394 | +{ |
395 | + QVariant password(m_lockSettings.value("password", "none")); |
396 | + |
397 | + if (password == "pin") |
398 | + return SecurityPrivacy::Passcode; |
399 | + else if (password == "keyboard") |
400 | + return SecurityPrivacy::Passphrase; |
401 | + else |
402 | + return SecurityPrivacy::Swipe; |
403 | + |
404 | +} |
405 | + |
406 | +void SecurityPrivacy::setSecurityType(SecurityType type) |
407 | +{ |
408 | + QVariant sec; |
409 | + |
410 | + switch (type) { |
411 | + case SecurityPrivacy::Passcode: |
412 | + sec = "pin"; |
413 | + break; |
414 | + case SecurityPrivacy::Passphrase: |
415 | + sec = "keyboard"; |
416 | + break; |
417 | + case SecurityPrivacy::Swipe: |
418 | + default: |
419 | + sec = "none"; |
420 | + break; |
421 | + } |
422 | + |
423 | + m_lockSettings.setValue("password", sec); |
424 | + m_lockSettings.sync(); |
425 | + Q_EMIT (securityTypeChanged()); |
426 | +} |
427 | |
428 | === modified file 'plugins/security-privacy/securityprivacy.h' |
429 | --- plugins/security-privacy/securityprivacy.h 2013-08-29 14:20:50 +0000 |
430 | +++ plugins/security-privacy/securityprivacy.h 2013-09-06 15:14:57 +0000 |
431 | @@ -25,11 +25,13 @@ |
432 | #include <QtDBus/QDBusInterface> |
433 | #include <QtCore/QMap> |
434 | #include <QtCore/QObject> |
435 | +#include <QtCore/QSettings> |
436 | #include <QtCore/QString> |
437 | |
438 | class SecurityPrivacy: public QObject |
439 | { |
440 | Q_OBJECT |
441 | + Q_ENUMS(SecurityType) |
442 | Q_PROPERTY (bool statsWelcomeScreen |
443 | READ getStatsWelcomeScreen |
444 | WRITE setStatsWelcomeScreen |
445 | @@ -38,13 +40,25 @@ |
446 | READ getMessagesWelcomeScreen |
447 | WRITE setMessagesWelcomeScreen |
448 | NOTIFY messagesWelcomeScreenChanged) |
449 | + Q_PROPERTY (SecurityType securityType |
450 | + READ getSecurityType |
451 | + WRITE setSecurityType |
452 | + NOTIFY securityTypeChanged) |
453 | |
454 | public: |
455 | + enum SecurityType { |
456 | + Swipe, |
457 | + Passcode, |
458 | + Passphrase |
459 | + }; |
460 | + |
461 | explicit SecurityPrivacy(QObject *parent = 0); |
462 | bool getStatsWelcomeScreen(); |
463 | void setStatsWelcomeScreen(bool enabled); |
464 | bool getMessagesWelcomeScreen(); |
465 | void setMessagesWelcomeScreen(bool enabled); |
466 | + SecurityType getSecurityType(); |
467 | + void setSecurityType(SecurityType type); |
468 | |
469 | public Q_SLOTS: |
470 | void slotChanged(QString, QVariantMap, QStringList); |
471 | @@ -53,12 +67,14 @@ |
472 | Q_SIGNALS: |
473 | void statsWelcomeScreenChanged(); |
474 | void messagesWelcomeScreenChanged(); |
475 | + void securityTypeChanged(); |
476 | |
477 | private: |
478 | QDBusConnection m_systemBusConnection; |
479 | QDBusServiceWatcher m_serviceWatcher; |
480 | QDBusInterface m_accountsserviceIface; |
481 | QString m_objectPath; |
482 | + QSettings m_lockSettings; |
483 | |
484 | QVariant getUserProperty(const QString &property); |
485 | void setUserProperty(const QString &property, |
486 | |
487 | === modified file 'schema/com.ubuntu.touch.system-settings.gschema.xml' |
488 | --- schema/com.ubuntu.touch.system-settings.gschema.xml 2013-09-03 16:37:26 +0000 |
489 | +++ schema/com.ubuntu.touch.system-settings.gschema.xml 2013-09-06 15:14:57 +0000 |
490 | @@ -27,10 +27,5 @@ |
491 | <summary>Whether the applications should be sorted by name.</summary> |
492 | <description>If true the applications are sorted by name, otherwise by disk size.</description> |
493 | </key> |
494 | - <key name="unlock-method" enum="enum-unlock-method"> |
495 | - <default>"swipe"</default> |
496 | - <summary>The unlocking method in use</summary> |
497 | - <description>If 'swipe', unlock by swiping the screen (no security). If 'passcode', use a 4-digit number to unlock. If 'password', use a free-text password.</description> |
498 | - </key> |
499 | </schema> |
500 | </schemalist> |
PASSED: Continuous integration, rev:326 jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- ci/297/ jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- saucy-amd64- ci/297
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ ubuntu- system- settings- ci/297/ rebuild
http://