Merge lp:~ken-vandine/ubuntu-system-settings/security_panel into lp:ubuntu-system-settings

Proposed by Ken VanDine
Status: Merged
Approved by: Ken VanDine
Approved revision: 934
Merged at revision: 954
Proposed branch: lp:~ken-vandine/ubuntu-system-settings/security_panel
Merge into: lp:ubuntu-system-settings
Prerequisite: lp:~jonas-drange/ubuntu-system-settings/visual-feedback-in-grid
Diff against target: 924 lines (+743/-27)
9 files modified
plugins/security-privacy/CMakeLists.txt (+3/-0)
plugins/security-privacy/Ofono.qml (+38/-0)
plugins/security-privacy/PageComponent.qml (+52/-4)
plugins/security-privacy/SimPin.qml (+358/-0)
plugins/security-privacy/sims.js (+34/-0)
src/qml/CategoryGrid.qml (+1/-0)
tests/autopilot/ubuntu_system_settings/tests/__init__.py (+5/-22)
tests/autopilot/ubuntu_system_settings/tests/ofono.py (+34/-0)
tests/autopilot/ubuntu_system_settings/tests/test_security.py (+218/-1)
To merge this branch: bzr merge lp:~ken-vandine/ubuntu-system-settings/security_panel
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Jonas G. Drange (community) Approve
Review via email: mp+232478@code.launchpad.net

This proposal supersedes a proposal from 2014-08-27.

Commit message

SIM PIN lock implementation

Description of the change

SIM PIN lock implementation

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Jonas G. Drange (jonas-drange) wrote : Posted in a previous version of this proposal

It works beautifully.

One small issue:
When changing the pin of a locked sim I get "undefined attempts remaining" – but it seems to work just fine. Skip "n attempts remaining" when locked?

review: Needs Fixing
Revision history for this message
Sebastien Bacher (seb128) wrote : Posted in a previous version of this proposal

Thanks for the work, some issues

- you seem to have code for display effect on panel when clicked, merge error?

- clicking on the switch and doing "cancel" leads to the control going to "true", it should not

- it displays slots for non present SIMs

- toggling a SIM leads to a "Enter SIM PIN" titled dialog with a "Lock" button, the spec doesn't describe that case?

review: Needs Fixing
933. By Ken VanDine

ensure the checked state matches the locked state

934. By Ken VanDine

fixed title for unlock dialog to match design when unlocking

Revision history for this message
Jonas G. Drange (jonas-drange) wrote : Posted in a previous version of this proposal

Retries seems broken on my SIM. I'll try to dig a bit deeper and report a bug against something.

Good stuff!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

Retries seems broken on my SIM. I'll try to dig a bit deeper and report a bug against something.

Good stuff!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/security-privacy/CMakeLists.txt'
--- plugins/security-privacy/CMakeLists.txt 2014-08-11 11:05:58 +0000
+++ plugins/security-privacy/CMakeLists.txt 2014-08-27 21:27:21 +0000
@@ -22,8 +22,11 @@
22 Dash.qml22 Dash.qml
23 Location.qml23 Location.qml
24 LockSecurity.qml24 LockSecurity.qml
25 Ofono.qml
25 PageComponent.qml26 PageComponent.qml
26 PhoneLocking.qml27 PhoneLocking.qml
28 SimPin.qml
29 sims.js
27)30)
2831
29set(PANEL_SOURCES32set(PANEL_SOURCES
3033
=== added file 'plugins/security-privacy/Ofono.qml'
--- plugins/security-privacy/Ofono.qml 1970-01-01 00:00:00 +0000
+++ plugins/security-privacy/Ofono.qml 2014-08-27 21:27:21 +0000
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Jonas G. Drange <jonas.drange@canonical.com>
18 *
19*/
20import QtQuick 2.0
21import MeeGo.QOfono 0.2
22
23Item {
24 property alias simMng: simMng
25 property alias present: simMng.present
26
27 property string path
28 property string name
29 property string title: {
30 var number = simMng.subscriberNumbers[0] || simMng.subscriberIdentity;
31 return name + (number ? " (" + number + ")" : "");
32 }
33
34 OfonoSimManager {
35 id: simMng
36 modemPath: path
37 }
38}
039
=== modified file 'plugins/security-privacy/PageComponent.qml'
--- plugins/security-privacy/PageComponent.qml 2014-08-26 00:54:38 +0000
+++ plugins/security-privacy/PageComponent.qml 2014-08-27 21:27:21 +0000
@@ -27,6 +27,8 @@
27import Ubuntu.SystemSettings.Battery 1.027import Ubuntu.SystemSettings.Battery 1.0
28import Ubuntu.SystemSettings.Diagnostics 1.028import Ubuntu.SystemSettings.Diagnostics 1.0
29import Ubuntu.SystemSettings.SecurityPrivacy 1.029import Ubuntu.SystemSettings.SecurityPrivacy 1.0
30import MeeGo.QOfono 0.2
31import "sims.js" as Sims
3032
31ItemPage {33ItemPage {
32 id: root34 id: root
@@ -37,6 +39,18 @@
3739
38 property alias usePowerd: batteryBackend.powerdRunning40 property alias usePowerd: batteryBackend.powerdRunning
39 property bool lockOnSuspend41 property bool lockOnSuspend
42 property var modemsSorted: manager.modems.slice(0).sort()
43 property var sims
44 property int simsPresent: 0
45 property int simsLoaded: 0
46 property int simsLocked: {
47 var t = 0;
48 sims.forEach(function (sim) {
49 if (sim.simMng.lockedPins.length > 0)
50 t++;
51 });
52 return t;
53 }
4054
41 UbuntuDiagnostics {55 UbuntuDiagnostics {
42 id: diagnosticsWidget56 id: diagnosticsWidget
@@ -50,6 +64,33 @@
50 id: batteryBackend64 id: batteryBackend
51 }65 }
5266
67 OfonoManager {
68 id: manager
69 Component.onCompleted: {
70 // create ofono bindings for all modem paths
71 var component = Qt.createComponent("Ofono.qml");
72 modemsSorted.forEach(function (path, index) {
73 var sim = component.createObject(root, {
74 path: path,
75 name: phoneSettings.simNames[path] ?
76 phoneSettings.simNames[path] :
77 "SIM " + (index + 1)
78 });
79 if (sim === null)
80 console.warn('failed to create sim object');
81 else
82 Sims.add(sim);
83 });
84 root.sims = Sims.getAll();
85 root.simsPresent = Sims.getPresentCount();
86 }
87 }
88
89 GSettings {
90 id: phoneSettings
91 schema.id: "com.ubuntu.phone"
92 }
93
53 GSettings {94 GSettings {
54 id: unitySettings95 id: unitySettings
55 schema.id: "com.canonical.Unity.Lenses"96 schema.id: "com.canonical.Unity.Lenses"
@@ -113,12 +154,19 @@
113 }154 }
114 ListItem.SingleValue {155 ListItem.SingleValue {
115 id: simControl156 id: simControl
157 objectName: "simControl"
116 text: i18n.tr("SIM PIN")158 text: i18n.tr("SIM PIN")
117 value: "Off"159 value: {
160 if (simsLoaded === 1 && simsLocked > 0)
161 return i18n.tr("On");
162 else if (simsLoaded > 1 && simsLocked > 0)
163 return simsLocked + "/" + simsLoaded;
164 else
165 return i18n.tr("Off");
166 }
167 visible: simsPresent > 0
118 progression: true168 progression: true
119 visible: showAllUI169 onClicked: pageStack.push(Qt.resolvedUrl("SimPin.qml"), { sims: sims })
120 /* Not implemented yet */
121 //onClicked: pageStack.push(Qt.resolvedUrl("SimPin.qml"))
122 }170 }
123 ListItem.Standard {171 ListItem.Standard {
124 text: i18n.tr("Encryption")172 text: i18n.tr("Encryption")
125173
=== added file 'plugins/security-privacy/SimPin.qml'
--- plugins/security-privacy/SimPin.qml 1970-01-01 00:00:00 +0000
+++ plugins/security-privacy/SimPin.qml 2014-08-27 21:27:21 +0000
@@ -0,0 +1,358 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Ken VanDine <ken.vandine@canonical.com>
18 *
19 */
20
21import GSettings 1.0
22import QtQuick 2.0
23import QtQuick.Layouts 1.1
24import Ubuntu.Components 1.1
25import Ubuntu.Components.ListItems 0.1 as ListItem
26import Ubuntu.Components.Popups 0.1
27import SystemSettings 1.0
28import MeeGo.QOfono 0.2
29import "sims.js" as Sims
30
31
32ItemPage {
33 id: root
34 title: i18n.tr("SIM PIN")
35
36 property var sims
37 property var curSim
38
39 Component {
40 id: dialogComponent
41
42 Dialog {
43 id: changePinDialog
44 title: i18n.tr("Change SIM PIN")
45
46 property string errorText: i18n.tr(
47 "Incorrect PIN. %1 attempts remaining."
48 ).arg(curSim.pinRetries[OfonoSimManager.SimPin] || 3)
49 property int simMin: curSim.minimumPinLength(OfonoSimManager.SimPin)
50 property int simMax: curSim.maximumPinLength(OfonoSimManager.SimPin)
51
52 // This is a bit hacky, but the contents of this dialog get so tall
53 // that on a mako device, they don't fit with the OSK also visible.
54 // So we scrunch up spacing.
55 Binding {
56 target: __foreground
57 property: "itemSpacing"
58 value: units.gu(1)
59 }
60
61 Connections {
62 target: curSim
63 onChangePinComplete: {
64 if (error === OfonoSimManager.FailedError) {
65 console.warn("Change PIN failed with: " + error);
66 incorrect.visible = true;
67 changePinDialog.enabled = true;
68 currentInput.forceActiveFocus();
69 currentInput.selectAll();
70 return;
71 }
72 incorrect.visible = false;
73 changePinDialog.enabled = true;
74 PopupUtils.close(changePinDialog);
75 }
76 }
77
78 Label {
79 text: i18n.tr("Current PIN:")
80 }
81
82 TextField {
83 id: currentInput
84 echoMode: TextInput.Password
85 inputMethodHints: Qt.ImhDialableCharactersOnly
86 maximumLength: simMax
87 }
88
89 Label {
90 id: retries
91 text: i18n.tr("%1 attempts remaining").arg(
92 curSim.pinRetries[OfonoSimManager.SimPin] || 3)
93 visible: !incorrect.visible
94 }
95
96 Label {
97 id: incorrect
98 text: errorText
99 visible: false
100 color: "darkred"
101 }
102
103 Label {
104 text: i18n.tr("Choose new PIN:")
105 }
106
107 TextField {
108 id: newInput
109 echoMode: TextInput.Password
110 inputMethodHints: Qt.ImhDialableCharactersOnly
111 maximumLength: simMax
112 }
113
114 Label {
115 text: i18n.tr("Confirm new PIN:")
116 }
117
118 TextField {
119 id: confirmInput
120 echoMode: TextInput.Password
121 inputMethodHints: Qt.ImhDialableCharactersOnly
122 maximumLength: simMax
123
124 // Doesn't get updated if you set this in enabled of confirmButton
125 onTextChanged: confirmButton.enabled =
126 (acceptableInput &&
127 text.length >= simMin &&
128 (text === newInput.text))
129 }
130
131 Label {
132 id: notMatching
133 wrapMode: Text.Wrap
134 text: i18n.tr("PINs don't match. Try again.")
135 visible: false
136 color: "darkred"
137 }
138
139 RowLayout {
140 spacing: units.gu(1)
141
142 Button {
143 Layout.fillWidth: true
144 color: UbuntuColors.lightGrey
145 text: i18n.tr("Cancel")
146 onClicked: PopupUtils.close(changePinDialog)
147 }
148
149 Button {
150 id: confirmButton
151 Layout.fillWidth: true
152 color: UbuntuColors.green
153 text: i18n.tr("Change")
154 enabled: false
155 onClicked: {
156 changePinDialog.enabled = false
157 var match = (newInput.text === confirmInput.text)
158 notMatching.visible = !match
159 if (!match) {
160 changePinDialog.enabled = true
161 newInput.forceActiveFocus()
162 newInput.selectAll()
163 return
164 }
165 curSim.changePin(OfonoSimManager.SimPin, currentInput.text, newInput.text);
166 }
167 }
168 }
169 }
170 }
171
172 Component {
173 id: lockDialogComponent
174
175 Dialog {
176 id: lockPinDialog
177 objectName: "lockDialogComponent"
178 title: curSim.lockedPins.length > 0 ?
179 i18n.tr("Enter SIM PIN") :
180 i18n.tr("Enter Previous SIM PIN")
181
182 property string errorText: i18n.tr(
183 "Incorrect PIN. %1 attempts remaining."
184 ).arg(curSim.pinRetries[OfonoSimManager.SimPin] || 3)
185
186 property int simMin: curSim.minimumPinLength(OfonoSimManager.SimPin)
187 property int simMax: curSim.maximumPinLength(OfonoSimManager.SimPin)
188
189 // This is a bit hacky, but the contents of this dialog get so tall
190 // that on a mako device, they don't fit with the OSK also visible.
191 // So we scrunch up spacing.
192 Binding {
193 target: __foreground
194 property: "itemSpacing"
195 value: units.gu(1)
196 }
197
198 Connections {
199 target: curSim
200 onLockPinComplete: {
201 if (error === OfonoSimManager.FailedError) {
202 console.warn("Lock PIN failed with: " + error);
203 incorrect.visible = true;
204 lockPinDialog.enabled = true;
205 prevInput.forceActiveFocus();
206 prevInput.selectAll();
207 return;
208 }
209 incorrect.visible = false;
210 lockPinDialog.enabled = true;
211 PopupUtils.close(lockPinDialog);
212 }
213 onUnlockPinComplete: {
214 if (error === OfonoSimManager.FailedError) {
215 console.warn("Unlock PIN failed with: " + error);
216 incorrect.visible = true;
217 lockPinDialog.enabled = true;
218 prevInput.forceActiveFocus();
219 prevInput.selectAll();
220 return;
221 }
222 incorrect.visible = false;
223 lockPinDialog.enabled = true;
224 PopupUtils.close(lockPinDialog);
225 }
226 }
227
228 TextField {
229 id: prevInput
230 objectName: "prevInput"
231 echoMode: TextInput.Password
232 inputMethodHints: Qt.ImhDialableCharactersOnly
233 maximumLength: simMax
234
235 // Doesn't get updated if you set this in enabled of confirmButton
236 onTextChanged: lockButton.enabled =
237 (acceptableInput && text.length >= simMin)
238 }
239
240 Label {
241 text: i18n.tr("%1 attempts remaining").arg(
242 curSim.pinRetries[OfonoSimManager.SimPin] || 3)
243 visible: !incorrect.visible
244 }
245
246 Label {
247 id: incorrect
248 text: errorText
249 visible: false
250 color: "darkred"
251 }
252
253 RowLayout {
254 spacing: units.gu(1)
255
256 Button {
257 objectName: "cancelButton"
258 Layout.fillWidth: true
259 color: UbuntuColors.lightGrey
260 text: i18n.tr("Cancel")
261 onClicked: {
262 if (curSim.lockedPins.length < 1)
263 caller.checked = false;
264 else
265 caller.checked = true;
266 PopupUtils.close(lockPinDialog);
267 }
268 }
269
270 Button {
271 id: lockButton
272 objectName: "lockButton"
273 Layout.fillWidth: true
274 color: UbuntuColors.green
275
276 text: curSim.lockedPins.length > 0 ? i18n.tr("Unlock") : i18n.tr("Lock")
277 enabled: false
278 onClicked: {
279 lockPinDialog.enabled = false;
280 if (curSim.lockedPins.length > 0)
281 curSim.unlockPin(OfonoSimManager.SimPin, prevInput.text);
282 else
283 curSim.lockPin(OfonoSimManager.SimPin, prevInput.text);
284 }
285 }
286 }
287 }
288 }
289
290 Column {
291 anchors.left: parent.left
292 anchors.right: parent.right
293
294 Repeater {
295 model: sims.length
296 Column {
297 anchors {
298 left: parent.left
299 right: parent.right
300 }
301
302 Connections {
303 target: sims[index].simMng
304 onLockedPinsChanged: {
305 simPinSwitch.checked =
306 sims[index].simMng.lockedPins.length > 0;
307 }
308 }
309
310 ListItem.Standard {
311 text: i18n.tr("%1").arg(sims[index].title)
312 visible: sims.length > 1
313 }
314
315 ListItem.Standard {
316 text: i18n.tr("SIM PIN")
317 control: Switch {
318 id: simPinSwitch
319 objectName: "simPinSwitch"
320 checked: sims[index].simMng.lockedPins.length > 0
321 onClicked: {
322 curSim = sims[index].simMng;
323 PopupUtils.open(lockDialogComponent, simPinSwitch);
324 }
325 }
326 showDivider: index < (sims.length - 1) && simPinSwitch.checked
327 }
328
329 ListItem.SingleControl {
330 id: changeControl
331 visible: sims[index].simMng.lockedPins.length > 0
332 control: Button {
333 enabled: parent.visible
334 text: i18n.tr("Change PIN…")
335 width: parent.width - units.gu(4)
336 onClicked: {
337 curSim = sims[index].simMng;
338 PopupUtils.open(dialogComponent);
339 }
340 }
341 showDivider: false
342 }
343 ListItem.Divider {
344 visible: index < (sims.length - 1)
345 }
346
347 }
348 }
349
350 ListItem.Caption {
351 text: i18n.tr("When a SIM PIN is set, it must be entered to access cellular services after restarting the phone or swapping the SIM.")
352 }
353
354 ListItem.Caption {
355 text: i18n.tr("Entering an incorrect PIN repeatedly may lock the SIM permanently.")
356 }
357 }
358}
0359
=== added file 'plugins/security-privacy/sims.js'
--- plugins/security-privacy/sims.js 1970-01-01 00:00:00 +0000
+++ plugins/security-privacy/sims.js 2014-08-27 21:27:21 +0000
@@ -0,0 +1,34 @@
1var sims = [];
2
3function add (sim) {
4 sims.push(sim);
5 root.simsLoaded++;
6}
7
8function getAll () {
9 return sims;
10}
11
12function get (n) {
13 return getAll()[n];
14}
15
16function getCount () {
17 return getAll().length;
18}
19
20function getPresent () {
21 var present = [];
22 getAll().forEach(function (sim) {
23 if (sim.present) {
24 present.push(sim);
25 } else {
26 return;
27 }
28 });
29 return present;
30}
31
32function getPresentCount () {
33 return getPresent().length;
34}
035
=== modified file 'src/qml/CategoryGrid.qml'
--- src/qml/CategoryGrid.qml 2014-08-05 13:27:35 +0000
+++ src/qml/CategoryGrid.qml 2014-08-27 21:27:21 +0000
@@ -59,6 +59,7 @@
59 pageStack.push(model.item.pageComponent,59 pageStack.push(model.item.pageComponent,
60 { plugin: model.item, pluginManager: pluginManager })60 { plugin: model.item, pluginManager: pluginManager })
61 }61 }
62 loader.item.highlighted = false;
62 }63 }
63 }64 }
64 }65 }
6566
=== modified file 'tests/autopilot/ubuntu_system_settings/tests/__init__.py'
--- tests/autopilot/ubuntu_system_settings/tests/__init__.py 2014-08-26 15:48:32 +0000
+++ tests/autopilot/ubuntu_system_settings/tests/__init__.py 2014-08-27 21:27:21 +0000
@@ -191,23 +191,6 @@
191 "PropertyChanged", "sv", [args[0], args[1]])'191 "PropertyChanged", "sv", [args[0], args[1]])'
192 .replace('IFACE', RDO_IFACE)), ])192 .replace('IFACE', RDO_IFACE)), ])
193193
194 def mock_sim_manager(self, modem, properties=None):
195 if not properties:
196 properties = {
197 'SubscriberNumbers': ['123456', '234567']
198 }
199 modem.AddProperties(SIM_IFACE, properties)
200 modem.AddProperty(SIM_IFACE, 'Present', True)
201 modem.AddMethods(
202 SIM_IFACE,
203 [('GetProperties', '', 'a{sv}',
204 'ret = self.GetAll("%s")' % SIM_IFACE),
205 ('SetProperty', 'sv', '',
206 'self.Set("IFACE", args[0], args[1]); '
207 'self.EmitSignal("IFACE",\
208 "PropertyChanged", "sv", [args[0], args[1]])'
209 .replace('IFACE', SIM_IFACE)), ])
210
211 def mock_call_forwarding(self, modem):194 def mock_call_forwarding(self, modem):
212 modem.AddProperty(195 modem.AddProperty(
213 CALL_FWD_IFACE, 'VoiceUnconditional', '')196 CALL_FWD_IFACE, 'VoiceUnconditional', '')
@@ -241,7 +224,6 @@
241 self.mock_carriers('ril_0')224 self.mock_carriers('ril_0')
242 self.mock_radio_settings(self.modem_0)225 self.mock_radio_settings(self.modem_0)
243 self.mock_connection_manager(self.modem_0)226 self.mock_connection_manager(self.modem_0)
244 self.mock_sim_manager(self.modem_0)
245 self.mock_call_forwarding(self.modem_0)227 self.mock_call_forwarding(self.modem_0)
246 self.mock_call_settings(self.modem_0)228 self.mock_call_settings(self.modem_0)
247229
@@ -276,9 +258,10 @@
276 self.mock_call_forwarding(self.modem_1)258 self.mock_call_forwarding(self.modem_1)
277 self.mock_call_settings(self.modem_1)259 self.mock_call_settings(self.modem_1)
278260
279 self.mock_sim_manager(self.modem_1, {261 self.modem_1.Set(
280 'SubscriberNumbers': ['08123', '938762783']262 SIM_IFACE,
281 })263 'SubscriberNumbers', ['08123', '938762783']
264 )
282265
283 @classmethod266 @classmethod
284 def setUpClass(cls):267 def setUpClass(cls):
@@ -679,7 +662,7 @@
679 super(ResetBaseTestCase, self).tearDown()662 super(ResetBaseTestCase, self).tearDown()
680663
681664
682class SecurityBaseTestCase(UbuntuSystemSettingsTestCase):665class SecurityBaseTestCase(UbuntuSystemSettingsOfonoTestCase):
683 """ Base class for security and privacy settings tests"""666 """ Base class for security and privacy settings tests"""
684667
685 def setUp(self):668 def setUp(self):
686669
=== modified file 'tests/autopilot/ubuntu_system_settings/tests/ofono.py'
--- tests/autopilot/ubuntu_system_settings/tests/ofono.py 2014-08-19 12:35:00 +0000
+++ tests/autopilot/ubuntu_system_settings/tests/ofono.py 2014-08-27 21:27:21 +0000
@@ -81,6 +81,7 @@
81 ])81 ])
82 obj = dbusmock.mockobject.objects[path]82 obj = dbusmock.mockobject.objects[path]
83 obj.name = name83 obj.name = name
84 add_simmanager_api(obj)
84 add_voice_call_api(obj)85 add_voice_call_api(obj)
85 add_netreg_api(obj)86 add_netreg_api(obj)
86 self.modems.append(path)87 self.modems.append(path)
@@ -89,6 +90,39 @@
89 return path90 return path
9091
9192
93def add_simmanager_api(mock):
94 '''Add org.ofono.SimManager API to a mock'''
95
96 iface = 'org.ofono.SimManager'
97 mock.AddProperties(iface, {
98 'CardIdentifier': _parameters.get('CardIdentifier', 12345),
99 'Present': _parameters.get('Present', dbus.Boolean(True)),
100 'SubscriberNumbers': _parameters.get('SubscriberNumbers',
101 ['123456789', '234567890']),
102 'SubscriberIdentity': _parameters.get('SubscriberIdentity', 23456),
103 'LockedPins': _parameters.get('LockedPins', ['pin']),
104 'Retries': _parameters.get('Retries', {'pin': dbus.Byte(3)}),
105 'PinRequired': _parameters.get('PinRequired', 'none')
106 })
107
108 mock.AddMethods(iface, [
109 ('GetProperties', '', 'a{sv}', 'ret = self.GetAll("%s")' % iface),
110 ('SetProperty', 'sv', '', 'self.Set("%(i)s", args[0], args[1]); '
111 'self.EmitSignal("%(i)s", "PropertyChanged", "sv", [args[0], '
112 'args[1]])' % {'i': iface}),
113 ('ChangePin', 'sss', '', ''),
114 ('EnterPin', 'ss', '', ''),
115 ('ResetPin', 'sss', '', ''),
116 ('LockPin', 'ss', '', 'if args[1] == "2468": self.Set("%(i)s",'
117 '"LockedPins", dbus.Array(["pin"])); self.EmitSignal("%(i)s",'
118 '"PropertyChanged", "sv", ["LockedPins", self.Get("%(i)s", '
119 '"LockedPins")])' % {'i': iface}),
120 ('UnlockPin', 'ss', '', 'if args[1] == "2468": self.Set("%(i)s",'
121 '"LockedPins", ""); self.EmitSignal("%(i)s", "PropertyChanged", "sv",'
122 ' ["LockedPins", self.Get("%(i)s", "LockedPins")])' % {'i': iface})
123 ])
124
125
92def add_voice_call_api(mock):126def add_voice_call_api(mock):
93 '''Add org.ofono.VoiceCallManager API to a mock'''127 '''Add org.ofono.VoiceCallManager API to a mock'''
94128
95129
=== modified file 'tests/autopilot/ubuntu_system_settings/tests/test_security.py'
--- tests/autopilot/ubuntu_system_settings/tests/test_security.py 2014-08-21 21:08:31 +0000
+++ tests/autopilot/ubuntu_system_settings/tests/test_security.py 2014-08-27 21:27:21 +0000
@@ -7,10 +7,13 @@
77
8from gi.repository import Gio8from gi.repository import Gio
9from time import sleep9from time import sleep
10import unittest
10from testtools.matchers import Equals, NotEquals11from testtools.matchers import Equals, NotEquals
11from autopilot.matchers import Eventually12from autopilot.matchers import Eventually
1213
13from ubuntu_system_settings.tests import SecurityBaseTestCase14from ubuntu_system_settings.tests import (
15 SecurityBaseTestCase,
16 SIM_IFACE)
1417
15from ubuntu_system_settings.utils.i18n import ugettext as _18from ubuntu_system_settings.utils.i18n import ugettext as _
16from ubuntuuitoolkit import emulators as toolkit_emulators19from ubuntuuitoolkit import emulators as toolkit_emulators
@@ -21,6 +24,7 @@
2124
22 def setUp(self):25 def setUp(self):
23 super(SecurityTestCase, self).setUp()26 super(SecurityTestCase, self).setUp()
27 self.assertEqual(['pin'], self.modem_0.Get(SIM_IFACE, 'LockedPins'))
24 prps = self.system_settings.main_view.security_page.get_properties()28 prps = self.system_settings.main_view.security_page.get_properties()
25 self.use_powerd = prps['usePowerd']29 self.use_powerd = prps['usePowerd']
26 if self.use_powerd:30 if self.use_powerd:
@@ -64,6 +68,12 @@
64 )68 )
65 self.system_settings.main_view.scroll_to_and_click(selector)69 self.system_settings.main_view.scroll_to_and_click(selector)
6670
71 def _go_to_sim_lock(self):
72 selector = self.security_page.select_single(
73 objectName="simControl"
74 )
75 self.system_settings.main_view.scroll_to_and_click(selector)
76
67 def _go_to_sleep_values(self):77 def _go_to_sleep_values(self):
68 self._go_to_phone_lock()78 self._go_to_phone_lock()
69 selector = self.system_settings.main_view.select_single(79 selector = self.system_settings.main_view.select_single(
@@ -171,3 +181,210 @@
171 selected_delegate = selector.select_single(181 selected_delegate = selector.select_single(
172 'OptionSelectorDelegate', selected=True)182 'OptionSelectorDelegate', selected=True)
173 self.assertEquals(selected_delegate.text, 'After 4 minutes')183 self.assertEquals(selected_delegate.text, 'After 4 minutes')
184
185 def test_sim_pin_control_value(self):
186 self.assertEqual('none', self.modem_0.Get(SIM_IFACE, 'PinRequired'))
187 self.assertEqual(['pin'], self.modem_0.Get(SIM_IFACE, 'LockedPins'))
188
189 sim_pin_value = self.security_page.select_single(
190 objectName='simControl').value
191
192 self.assertThat(
193 sim_pin_value,
194 Equals(_('On'))
195 )
196
197 def test_sim_pin_lock_control(self):
198 self._go_to_sim_lock()
199 sim_lock_control = self.system_settings.main_view.select_single(
200 objectName='simPinSwitch')
201 locked = len(self.modem_0.Get(SIM_IFACE, 'LockedPins')) > 0
202 self.assertEquals(locked, sim_lock_control.checked)
203
204 def test_sim_pin_lock_control_unlock(self):
205 self._go_to_sim_lock()
206 sim_lock_control = self.system_settings.main_view.select_single(
207 objectName='simPinSwitch')
208
209 self.assertTrue(sim_lock_control.checked)
210
211 self.system_settings.main_view.scroll_to_and_click(sim_lock_control)
212
213 lock_dialog = self.system_settings.main_view.select_single(
214 objectName='lockDialogComponent')
215 self.assertEqual(
216 lock_dialog.title,
217 _("Enter SIM PIN")
218 )
219
220 prev_input = self.system_settings.main_view.select_single(
221 objectName='prevInput')
222 submit_button = self.system_settings.main_view.select_single(
223 objectName='lockButton')
224
225 self.assertEqual(
226 submit_button.text,
227 _("Unlock")
228 )
229
230 self.assertFalse(
231 submit_button.get_properties()['enabled']
232 )
233 self.system_settings.main_view.scroll_to_and_click(prev_input)
234 self.keyboard.type("246")
235 self.assertFalse(
236 submit_button.get_properties()['enabled']
237 )
238 self.keyboard.type("8")
239
240 self.assertTrue(
241 submit_button.get_properties()['enabled']
242 )
243
244 self.system_settings.main_view.scroll_to_and_click(submit_button)
245
246 self.assertFalse(sim_lock_control.checked)
247
248 locked = len(self.modem_0.Get(SIM_IFACE, 'LockedPins')) > 0
249 self.assertEquals(locked, sim_lock_control.checked)
250
251 @unittest.skip('skipped because the simPinSwitch state fails to update')
252 def test_sim_pin_lock_control_lock(self):
253 self.modem_0.Set(SIM_IFACE, 'LockedPins', "")
254 self._go_to_sim_lock()
255 sim_lock_control = self.system_settings.main_view.select_single(
256 objectName='simPinSwitch')
257
258 self.assertFalse(sim_lock_control.checked)
259
260 self.system_settings.main_view.scroll_to_and_click(sim_lock_control)
261
262 lock_dialog = self.system_settings.main_view.select_single(
263 objectName='lockDialogComponent')
264 self.assertEqual(
265 lock_dialog.title,
266 _("Enter SIM PIN")
267 )
268
269 prev_input = self.system_settings.main_view.select_single(
270 objectName='prevInput')
271 submit_button = self.system_settings.main_view.select_single(
272 objectName='lockButton')
273
274 self.assertEqual(
275 submit_button.text,
276 _("Lock")
277 )
278
279 self.assertFalse(
280 submit_button.get_properties()['enabled']
281 )
282 self.system_settings.main_view.scroll_to_and_click(prev_input)
283 self.keyboard.type("246")
284 self.assertFalse(
285 submit_button.get_properties()['enabled']
286 )
287 self.keyboard.type("8")
288
289 self.assertTrue(
290 submit_button.get_properties()['enabled']
291 )
292
293 self.system_settings.main_view.scroll_to_and_click(submit_button)
294
295 self.assertTrue(sim_lock_control.checked)
296
297 self.assertEqual(['pin'], self.modem_0.Get(SIM_IFACE, 'LockedPins'))
298 locked = len(self.modem_0.Get(SIM_IFACE, 'LockedPins')) > 0
299 self.assertEquals(locked, sim_lock_control.checked)
300
301 def test_sim_pin_lock_control_unlock_fail(self):
302 self._go_to_sim_lock()
303 sim_lock_control = self.system_settings.main_view.select_single(
304 objectName='simPinSwitch')
305
306 self.assertTrue(
307 len(self.modem_0.Get(SIM_IFACE, 'LockedPins')) > 0
308 )
309 self.assertTrue(sim_lock_control.checked)
310
311 self.system_settings.main_view.scroll_to_and_click(sim_lock_control)
312
313 lock_dialog = self.system_settings.main_view.select_single(
314 objectName='lockDialogComponent')
315 self.assertEqual(
316 lock_dialog.title,
317 _("Enter SIM PIN")
318 )
319
320 prev_input = self.system_settings.main_view.select_single(
321 objectName='prevInput')
322 submit_button = self.system_settings.main_view.select_single(
323 objectName='lockButton')
324
325 self.assertEqual(
326 submit_button.text,
327 _("Unlock")
328 )
329
330 self.assertFalse(
331 submit_button.get_properties()['enabled']
332 )
333 self.system_settings.main_view.scroll_to_and_click(prev_input)
334 self.keyboard.type("1234")
335
336 self.assertTrue(
337 submit_button.get_properties()['enabled']
338 )
339
340 self.system_settings.main_view.scroll_to_and_click(submit_button)
341
342 self.assertTrue(
343 len(self.modem_0.Get(SIM_IFACE, 'LockedPins')) > 0
344 )
345
346 @unittest.skip('skipped because the simPinSwitch state fails to update')
347 def test_sim_pin_lock_control_lock_fail(self):
348 self.modem_0.Set(SIM_IFACE, 'LockedPins', "")
349 self._go_to_sim_lock()
350 sim_lock_control = self.system_settings.main_view.select_single(
351 objectName='simPinSwitch')
352
353 self.assertFalse(
354 len(self.modem_0.Get(SIM_IFACE, 'LockedPins')) > 0
355 )
356
357 self.system_settings.main_view.scroll_to_and_click(sim_lock_control)
358
359 lock_dialog = self.system_settings.main_view.select_single(
360 objectName='lockDialogComponent')
361 self.assertEqual(
362 lock_dialog.title,
363 _("Enter SIM PIN")
364 )
365
366 prev_input = self.system_settings.main_view.select_single(
367 objectName='prevInput')
368 submit_button = self.system_settings.main_view.select_single(
369 objectName='lockButton')
370
371 self.assertEqual(
372 submit_button.text,
373 _("Lock")
374 )
375
376 self.assertFalse(
377 submit_button.get_properties()['enabled']
378 )
379 self.system_settings.main_view.scroll_to_and_click(prev_input)
380 self.keyboard.type("1234")
381
382 self.assertTrue(
383 submit_button.get_properties()['enabled']
384 )
385
386 self.system_settings.main_view.scroll_to_and_click(submit_button)
387
388 self.assertFalse(
389 len(self.modem_0.Get(SIM_IFACE, 'LockedPins')) > 0
390 )

Subscribers

People subscribed via source and target branches