Merge lp:~jonas-drange/ubuntu-system-settings/1357393-fix into lp:ubuntu-system-settings
- 1357393-fix
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Ken VanDine |
Approved revision: | 922 |
Merged at revision: | 932 |
Proposed branch: | lp:~jonas-drange/ubuntu-system-settings/1357393-fix |
Merge into: | lp:ubuntu-system-settings |
Prerequisite: | lp:~jonas-drange/ubuntu-system-settings/1355053-fix-2g-bug |
Diff against target: |
1330 lines (+695/-218) 16 files modified
plugins/cellular/CMakeLists.txt (+1/-0) plugins/cellular/Components/CMakeLists.txt (+4/-1) plugins/cellular/Components/CellularMultiSim.qml (+16/-18) plugins/cellular/Components/CellularSingleSim.qml (+13/-14) plugins/cellular/Components/DefaultSim.qml (+3/-4) plugins/cellular/Components/MultiSim.qml (+120/-0) plugins/cellular/Components/NoSim.qml (+51/-0) plugins/cellular/Components/Sim.qml (+2/-0) plugins/cellular/Components/SimEditor.qml (+8/-8) plugins/cellular/Components/SingleSim.qml (+76/-0) plugins/cellular/PageChooseCarriers.qml (+9/-10) plugins/cellular/PageComponent.qml (+42/-159) plugins/cellular/sims.js (+34/-0) tests/autopilot/ubuntu_system_settings/tests/__init__.py (+5/-3) tests/autopilot/ubuntu_system_settings/tests/ofono.py (+215/-0) tests/autopilot/ubuntu_system_settings/tests/test_cellular.py (+96/-1) |
To merge this branch: | bzr merge lp:~jonas-drange/ubuntu-system-settings/1357393-fix |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ken VanDine | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+231347@code.launchpad.net |
This proposal supersedes a proposal from 2014-08-17.
Commit message
[cellular] displays cellular UIs based on how many SIMs are present.
Description of the change
Hi,
this creates three states for the cellular UI to be in:
* noSim
* singleSim
* multiSim
It also adds some logic for an arbitrary number of SIMs, however, the multiSim UI currently only supports two.
In addition to all of the above, this branch will be ready for SIM hotswapping, even though re-inserting SIMs currently does not work (broken at lower levels).
Thanks
* Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)
yes
* Did you build your software in a clean sbuild/pbuilder chroot or ppa?
jenkins
* Did you build your software in a clean sbuild/pbuilder armhf chroot or ppa?
jenkins
* Has your component "TestPlan” been executed successfully on emulator, N4?
n4 and other device
* Has a 5 minute exploratory testing run been executed on N4?
no/jenkins?
* If you changed the packaging (debian), did you subscribe a core-dev to this MP?
N/A
* If you changed the UI, did you subscribe the design-reviewers to this MP?
How?
* What components might get impacted by your changes?
USS Phone panel
* Have you requested review by the teams of these owning components?
Yes
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:916
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
None: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
None: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:917
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:918
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 919. By Jonas G. Drange
-
fix small rendering issues
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:919
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 920. By Jonas G. Drange
-
merge trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:920
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Ken VanDine (ken-vandine) wrote : | # |
Works well on my dual sim device. One small nit pick thing inlineh
- 921. By Jonas G. Drange
-
merge trunk
- 922. By Jonas G. Drange
-
cleanup of extra lines
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:922
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'plugins/cellular/CMakeLists.txt' |
2 | --- plugins/cellular/CMakeLists.txt 2014-07-17 20:59:15 +0000 |
3 | +++ plugins/cellular/CMakeLists.txt 2014-08-22 10:53:29 +0000 |
4 | @@ -9,6 +9,7 @@ |
5 | PageComponent.qml |
6 | Hotspot.qml |
7 | HotspotSetup.qml |
8 | + sims.js |
9 | ) |
10 | |
11 | |
12 | |
13 | === modified file 'plugins/cellular/Components/CMakeLists.txt' |
14 | --- plugins/cellular/Components/CMakeLists.txt 2014-07-31 20:10:40 +0000 |
15 | +++ plugins/cellular/Components/CMakeLists.txt 2014-08-22 10:53:29 +0000 |
16 | @@ -1,6 +1,9 @@ |
17 | set(QML_SOURCES |
18 | + NoSim.qml |
19 | + SingleSim.qml |
20 | + MultiSim.qml |
21 | CellularSingleSim.qml |
22 | - CellularDualSim.qml |
23 | + CellularMultiSim.qml |
24 | data-helpers.js |
25 | DefaultSim.qml |
26 | Sim.qml |
27 | |
28 | === renamed file 'plugins/cellular/Components/CellularDualSim.qml' => 'plugins/cellular/Components/CellularMultiSim.qml' |
29 | --- plugins/cellular/Components/CellularDualSim.qml 2014-08-14 13:59:57 +0000 |
30 | +++ plugins/cellular/Components/CellularMultiSim.qml 2014-08-22 10:53:29 +0000 |
31 | @@ -24,20 +24,18 @@ |
32 | |
33 | Column { |
34 | id: root |
35 | - property var sim1 |
36 | - property var sim2 |
37 | property var selector: selector |
38 | property var prefMap: ['gsm', 'umts'] |
39 | |
40 | function getNameFromIndex (index) { |
41 | - return [i18n.tr("Off"), sim1.title, sim2.title][index]; |
42 | + return [i18n.tr("Off"), sims[0].title, sims[1].title][index]; |
43 | } |
44 | |
45 | function getUsedSim () { |
46 | if (state === "sim1Online") { |
47 | - return sim1; |
48 | + return sims[0]; |
49 | } else if (state === "sim2Online") { |
50 | - return sim2; |
51 | + return sims[1]; |
52 | } else { |
53 | return null; |
54 | } |
55 | @@ -47,7 +45,7 @@ |
56 | states: [ |
57 | State { |
58 | name: "sim1Online" |
59 | - when: sim1.connMan.powered && !sim2.connMan.powered |
60 | + when: sims[0].connMan.powered && !sims[1].connMan.powered |
61 | StateChangeScript { script: { |
62 | selector.selectedIndex = |
63 | DataHelpers.dualSimKeyToIndex( |
64 | @@ -56,7 +54,7 @@ |
65 | }, |
66 | State { |
67 | name: "sim2Online" |
68 | - when: sim2.connMan.powered && !sim1.connMan.powered |
69 | + when: sims[1].connMan.powered && !sims[0].connMan.powered |
70 | StateChangeScript { script: { |
71 | selector.selectedIndex = |
72 | DataHelpers.dualSimKeyToIndex( |
73 | @@ -65,9 +63,9 @@ |
74 | }, |
75 | State { |
76 | name: "bothOnline" |
77 | - when: sim1.connMan.powered && sim2.connMan.powered |
78 | + when: sims[0].connMan.powered && sims[1].connMan.powered |
79 | StateChangeScript { script: { |
80 | - sim2.connMan.powered = false; |
81 | + sims[1].connMan.powered = false; |
82 | }} |
83 | } |
84 | ] |
85 | @@ -82,16 +80,16 @@ |
86 | objectName: "use" + modelData |
87 | text: getNameFromIndex(index) |
88 | } |
89 | - selectedIndex: [true, sim1.connMan.powered, sim2.connMan.powered] |
90 | + selectedIndex: [true, sims[0].connMan.powered, sims[1].connMan.powered] |
91 | .lastIndexOf(true) |
92 | onDelegateClicked: { |
93 | - sim1.connMan.powered = (index === 1) |
94 | - sim2.connMan.powered = (index === 2) |
95 | + sims[0].connMan.powered = (index === 1) |
96 | + sims[1].connMan.powered = (index === 2) |
97 | } |
98 | } |
99 | |
100 | Connections { |
101 | - target: sim1.connMan |
102 | + target: sims[0].connMan |
103 | onPoweredChanged: { |
104 | if (powered) { |
105 | use.selectedIndex = 1; |
106 | @@ -100,7 +98,7 @@ |
107 | } |
108 | |
109 | Connections { |
110 | - target: sim2.connMan |
111 | + target: sims[1].connMan |
112 | onPoweredChanged: { |
113 | if (powered) { |
114 | use.selectedIndex = 2; |
115 | @@ -124,9 +122,9 @@ |
116 | } |
117 | |
118 | Connections { |
119 | - target: sim1.radioSettings |
120 | + target: sims[0].radioSettings |
121 | onTechnologyPreferenceChanged: { |
122 | - if (sim1.connMan.powered) { |
123 | + if (sims[0].connMan.powered) { |
124 | selector.selectedIndex = |
125 | DataHelpers.dualSimKeyToIndex(preference); |
126 | } |
127 | @@ -134,9 +132,9 @@ |
128 | } |
129 | |
130 | Connections { |
131 | - target: sim2.radioSettings |
132 | + target: sims[1].radioSettings |
133 | onTechnologyPreferenceChanged: { |
134 | - if (sim2.connMan.powered) { |
135 | + if (sims[1].connMan.powered) { |
136 | selector.selectedIndex = |
137 | DataHelpers.dualSimKeyToIndex(preference); |
138 | } |
139 | |
140 | === modified file 'plugins/cellular/Components/CellularSingleSim.qml' |
141 | --- plugins/cellular/Components/CellularSingleSim.qml 2014-08-14 13:59:57 +0000 |
142 | +++ plugins/cellular/Components/CellularSingleSim.qml 2014-08-22 10:53:29 +0000 |
143 | @@ -25,7 +25,6 @@ |
144 | Column { |
145 | height: childrenRect.height |
146 | |
147 | - property var sim1 |
148 | property var selector: selector |
149 | |
150 | ListItem.ItemSelector { |
151 | @@ -33,15 +32,15 @@ |
152 | objectName: "technologyPreferenceSelector" |
153 | text: i18n.tr("Cellular data:") |
154 | expanded: true |
155 | - enabled: sim1.radioSettings.technologyPreference !== "" |
156 | + enabled: sim.radioSettings.technologyPreference !== "" |
157 | model: [ |
158 | i18n.tr("Off"), |
159 | i18n.tr("2G only (saves battery)"), |
160 | i18n.tr("2G/3G/4G (faster)")] |
161 | selectedIndex: { |
162 | - if (sim1.connMan.powered) { |
163 | + if (sim.connMan.powered) { |
164 | return DataHelpers.singleSimKeyToIndex( |
165 | - sim1.radioSettings.technologyPreference); |
166 | + sim.radioSettings.technologyPreference); |
167 | } else { |
168 | return 0; |
169 | } |
170 | @@ -52,20 +51,20 @@ |
171 | id: dataRoamingItem |
172 | objectName: "dataRoamingSwitch" |
173 | text: i18n.tr("Data roaming") |
174 | - enabled: sim1.connMan.powered |
175 | + enabled: sim.connMan.powered |
176 | control: Switch { |
177 | id: dataRoamingControl |
178 | - checked: sim1.connMan.roamingAllowed |
179 | - onClicked: sim1.connMan.roamingAllowed = checked |
180 | + checked: sim.connMan.roamingAllowed |
181 | + onClicked: sim.connMan.roamingAllowed = checked |
182 | } |
183 | } |
184 | |
185 | Connections { |
186 | - target: sim1.connMan |
187 | + target: sim.connMan |
188 | onPoweredChanged: { |
189 | if (powered) { |
190 | selector.selectedIndex = DataHelpers.singleSimKeyToIndex( |
191 | - sim1.radioSettings.technologyPreference); |
192 | + sim.radioSettings.technologyPreference); |
193 | } else { |
194 | selector.selectedIndex = 0; |
195 | } |
196 | @@ -73,24 +72,24 @@ |
197 | } |
198 | |
199 | Connections { |
200 | - target: sim1.radioSettings |
201 | + target: sim.radioSettings |
202 | onTechnologyPreferenceChanged: { |
203 | var selIndex = selector.selectedIndex; |
204 | if (selIndex > 0) { |
205 | - sim1.radioSettings.technologyPreference = |
206 | + sim.radioSettings.technologyPreference = |
207 | DataHelpers.singleSimIndexToKey(selIndex); |
208 | } |
209 | } |
210 | } |
211 | |
212 | Binding { |
213 | - target: sim1.connMan |
214 | + target: sim.connMan |
215 | property: "powered" |
216 | value: selector.selectedIndex !== 0 |
217 | } |
218 | |
219 | Binding { |
220 | - target: sim1.radioSettings |
221 | + target: sim.radioSettings |
222 | property: "technologyPreference" |
223 | value: { |
224 | var i = selector.selectedIndex; |
225 | @@ -99,7 +98,7 @@ |
226 | } else if (i === 2) { |
227 | return 'umts'; |
228 | } else { |
229 | - return sim1.radioSettings.technologyPreference |
230 | + return sim.radioSettings.technologyPreference |
231 | } |
232 | } |
233 | } |
234 | |
235 | === modified file 'plugins/cellular/Components/DefaultSim.qml' |
236 | --- plugins/cellular/Components/DefaultSim.qml 2014-08-14 09:59:56 +0000 |
237 | +++ plugins/cellular/Components/DefaultSim.qml 2014-08-22 10:53:29 +0000 |
238 | @@ -23,10 +23,10 @@ |
239 | |
240 | Column { |
241 | |
242 | - property var m: ["ask", sim1.path, sim2.path] |
243 | + property var m: ["ask", sims[0].path, sims[1].path] |
244 | |
245 | function getNameFromIndex (index) { |
246 | - return [i18n.tr("Ask me each time"), sim1.title, sim2.title][index]; |
247 | + return [i18n.tr("Ask me each time"), sims[0].title, sims[1].title][index]; |
248 | } |
249 | |
250 | ListItem.ItemSelector { |
251 | @@ -45,8 +45,7 @@ |
252 | } |
253 | |
254 | ListItem.Caption { |
255 | - text: i18n.tr("You can change the SIM for individual calls, |
256 | - or for contacts in the address book.") |
257 | + text: i18n.tr("You can change the SIM for individual calls, or for contacts in the address book.") |
258 | } |
259 | |
260 | ListItem.Divider {} |
261 | |
262 | === added file 'plugins/cellular/Components/MultiSim.qml' |
263 | --- plugins/cellular/Components/MultiSim.qml 1970-01-01 00:00:00 +0000 |
264 | +++ plugins/cellular/Components/MultiSim.qml 2014-08-22 10:53:29 +0000 |
265 | @@ -0,0 +1,120 @@ |
266 | +/* |
267 | + * Copyright (C) 2014 Canonical Ltd |
268 | + * |
269 | + * This program is free software: you can redistribute it and/or modify |
270 | + * it under the terms of the GNU General Public License version 3 as |
271 | + * published by the Free Software Foundation. |
272 | + * |
273 | + * This program is distributed in the hope that it will be useful, |
274 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
275 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
276 | + * GNU General Public License for more details. |
277 | + * |
278 | + * You should have received a copy of the GNU General Public License |
279 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
280 | + * |
281 | + * Authors: |
282 | + * Jonas G. Drange <jonas.drange@canonical.com> |
283 | + * |
284 | +*/ |
285 | +import QtQuick 2.0 |
286 | +import GSettings 1.0 |
287 | +import Ubuntu.Components 0.1 |
288 | +import Ubuntu.Components.ListItems 0.1 as ListItem |
289 | + |
290 | +Column { |
291 | + |
292 | + objectName: "multiSim" |
293 | + |
294 | + property var sims |
295 | + property var modems |
296 | + |
297 | + // make settings available to all children of root |
298 | + property var settings: phoneSettings |
299 | + |
300 | + CellularMultiSim { |
301 | + anchors {Â left: parent.left; right: parent.right } |
302 | + } |
303 | + |
304 | + ListItem.Divider {} |
305 | + |
306 | + ListItem.SingleValue { |
307 | + text : i18n.tr("Hotspot disabled because Wi-Fi is off.") |
308 | + visible: showAllUI && !hotspotItem.visible |
309 | + } |
310 | + |
311 | + ListItem.SingleValue { |
312 | + id: hotspotItem |
313 | + text: i18n.tr("Wi-Fi hotspot") |
314 | + progression: true |
315 | + onClicked: { |
316 | + pageStack.push(Qt.resolvedUrl("Hotspot.qml")) |
317 | + } |
318 | + visible: showAllUI && (actionGroup.actionObject.valid ? actionGroup.actionObject.state : false) |
319 | + } |
320 | + |
321 | + ListItem.Standard { |
322 | + id: dataUsage |
323 | + text: i18n.tr("Data usage statistics") |
324 | + progression: true |
325 | + visible: showAllUI |
326 | + } |
327 | + |
328 | + ListItem.Divider { |
329 | + visible: hotspotItem.visible || dataUsage.visible |
330 | + } |
331 | + |
332 | + ListItem.SingleValue { |
333 | + text: i18n.tr("Carriers") |
334 | + id: chooseCarrier |
335 | + objectName: "chooseCarrier" |
336 | + progression: enabled |
337 | + onClicked: { |
338 | + pageStack.push(Qt.resolvedUrl("../PageChooseCarriers.qml"), { |
339 | + sims: sims |
340 | + }); |
341 | + } |
342 | + } |
343 | + |
344 | + ListItem.Divider {} |
345 | + |
346 | + SimEditor { |
347 | + anchors {Â left: parent.left; right: parent.right } |
348 | + } |
349 | + |
350 | + ListItem.Divider {} |
351 | + |
352 | + DefaultSim { |
353 | + anchors {Â left: parent.left; right: parent.right } |
354 | + } |
355 | + |
356 | + GSettings { |
357 | + id: phoneSettings |
358 | + schema.id: "com.ubuntu.phone" |
359 | + Component.onCompleted: { |
360 | + // set default names |
361 | + var simNames = phoneSettings.simNames; |
362 | + var m0 = modems[0]; |
363 | + var m1 = modems[1]; |
364 | + if (!simNames[m0]) { |
365 | + simNames[m0] = "SIM 1"; |
366 | + } |
367 | + if (!simNames[m1])Â { |
368 | + simNames[m1] = "SIM 2"; |
369 | + } |
370 | + phoneSettings.simNames = simNames; |
371 | + } |
372 | + } |
373 | + |
374 | + Binding { |
375 | + target: sims[0] |
376 | + property: "name" |
377 | + value: phoneSettings.simNames[modems[0]] |
378 | + } |
379 | + |
380 | + Binding { |
381 | + target: sims[1] |
382 | + property: "name" |
383 | + value: phoneSettings.simNames[modems[1]] |
384 | + } |
385 | +} |
386 | |
387 | === added file 'plugins/cellular/Components/NoSim.qml' |
388 | --- plugins/cellular/Components/NoSim.qml 1970-01-01 00:00:00 +0000 |
389 | +++ plugins/cellular/Components/NoSim.qml 2014-08-22 10:53:29 +0000 |
390 | @@ -0,0 +1,51 @@ |
391 | +/* |
392 | + * Copyright (C) 2014 Canonical Ltd |
393 | + * |
394 | + * This program is free software: you can redistribute it and/or modify |
395 | + * it under the terms of the GNU General Public License version 3 as |
396 | + * published by the Free Software Foundation. |
397 | + * |
398 | + * This program is distributed in the hope that it will be useful, |
399 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
400 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
401 | + * GNU General Public License for more details. |
402 | + * |
403 | + * You should have received a copy of the GNU General Public License |
404 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
405 | + * |
406 | + * Authors: |
407 | + * Jonas G. Drange <jonas.drange@canonical.com> |
408 | + * |
409 | +*/ |
410 | +import QtQuick 2.0 |
411 | +import Ubuntu.Components 0.1 |
412 | +import Ubuntu.Components.ListItems 0.1 as ListItem |
413 | + |
414 | +Column { |
415 | + |
416 | + objectName: "noSim" |
417 | + |
418 | + ListItem.ItemSelector { |
419 | + text: i18n.tr("Cellular data:") |
420 | + expanded: true |
421 | + enabled: false |
422 | + model: [i18n.tr("Off"), i18n.tr("2G only (saves battery)"), i18n.tr("2G/3G/4G (faster)")] |
423 | + selectedIndex: -1 |
424 | + } |
425 | + |
426 | + ListItem.Standard { |
427 | + text: i18n.tr("Data roaming") |
428 | + enabled: false |
429 | + control: Switch { |
430 | + checked: false |
431 | + } |
432 | + } |
433 | + |
434 | + ListItem.Divider {} |
435 | + |
436 | + ListItem.SingleValue { |
437 | + text: i18n.tr("Carrier"); |
438 | + value: i18n.tr("N/A") |
439 | + enabled: false |
440 | + } |
441 | +} |
442 | |
443 | === modified file 'plugins/cellular/Components/Sim.qml' |
444 | --- plugins/cellular/Components/Sim.qml 2014-07-25 13:33:36 +0000 |
445 | +++ plugins/cellular/Components/Sim.qml 2014-08-22 10:53:29 +0000 |
446 | @@ -21,12 +21,14 @@ |
447 | import MeeGo.QOfono 0.2 |
448 | |
449 | Item { |
450 | + id: root |
451 | property alias modem: modem |
452 | property alias netReg: netReg |
453 | property alias radioSettings: radioSettings |
454 | property alias simMng: simMng |
455 | property alias connMan: connMan |
456 | |
457 | + property alias present: simMng.present |
458 | property string path |
459 | property string name |
460 | property string title: { |
461 | |
462 | === modified file 'plugins/cellular/Components/SimEditor.qml' |
463 | --- plugins/cellular/Components/SimEditor.qml 2014-08-15 19:58:34 +0000 |
464 | +++ plugins/cellular/Components/SimEditor.qml 2014-08-22 10:53:29 +0000 |
465 | @@ -44,7 +44,7 @@ |
466 | name: "editingSim1" |
467 | PropertyChanges { |
468 | target: nameField |
469 | - text: sim1.name |
470 | + text: sims[0].name |
471 | } |
472 | ParentChange { |
473 | target: editor |
474 | @@ -60,7 +60,7 @@ |
475 | name: "editingSim2" |
476 | PropertyChanges { |
477 | target: nameField |
478 | - text: sim2.name |
479 | + text: sims[1].name |
480 | } |
481 | ParentChange { |
482 | target: editor |
483 | @@ -108,7 +108,7 @@ |
484 | right: parent.right |
485 | verticalCenter: parent.verticalCenter |
486 | } |
487 | - text: sim1.title |
488 | + text: sims[0].title |
489 | } |
490 | } |
491 | Column { |
492 | @@ -144,7 +144,7 @@ |
493 | right: parent.right |
494 | verticalCenter: parent.verticalCenter |
495 | } |
496 | - text: sim2.title |
497 | + text: sims[1].title |
498 | } |
499 | } |
500 | Column { |
501 | @@ -213,11 +213,11 @@ |
502 | onTriggered: { |
503 | var tmpSimNames = {}; |
504 | if (simList.state === "editingSim1") { |
505 | - tmpSimNames[sim1.path] = nameField.text; |
506 | - tmpSimNames[sim2.path] = sim2.name; |
507 | + tmpSimNames[sims[0].path] = nameField.text; |
508 | + tmpSimNames[sims[1].path] = sims[1].name; |
509 | } else if (simList.state === "editingSim2") { |
510 | - tmpSimNames[sim1.path] = sim1.name; |
511 | - tmpSimNames[sim2.path] = nameField.text; |
512 | + tmpSimNames[sims[0].path] = sims[0].name; |
513 | + tmpSimNames[sims[1].path] = nameField.text; |
514 | } |
515 | phoneSettings.simNames = tmpSimNames; |
516 | simList.state = ""; |
517 | |
518 | === added file 'plugins/cellular/Components/SingleSim.qml' |
519 | --- plugins/cellular/Components/SingleSim.qml 1970-01-01 00:00:00 +0000 |
520 | +++ plugins/cellular/Components/SingleSim.qml 2014-08-22 10:53:29 +0000 |
521 | @@ -0,0 +1,76 @@ |
522 | +/* |
523 | + * Copyright (C) 2014 Canonical Ltd |
524 | + * |
525 | + * This program is free software: you can redistribute it and/or modify |
526 | + * it under the terms of the GNU General Public License version 3 as |
527 | + * published by the Free Software Foundation. |
528 | + * |
529 | + * This program is distributed in the hope that it will be useful, |
530 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
531 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
532 | + * GNU General Public License for more details. |
533 | + * |
534 | + * You should have received a copy of the GNU General Public License |
535 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
536 | + * |
537 | + * Authors: |
538 | + * Jonas G. Drange <jonas.drange@canonical.com> |
539 | + * |
540 | +*/ |
541 | +import QtQuick 2.0 |
542 | +import Ubuntu.Components 0.1 |
543 | +import Ubuntu.Components.ListItems 0.1 as ListItem |
544 | + |
545 | +Column { |
546 | + |
547 | + objectName: "singleSim" |
548 | + |
549 | + property var sim |
550 | + |
551 | + CellularSingleSim { |
552 | + anchors {Â left: parent.left; right: parent.right } |
553 | + } |
554 | + |
555 | + ListItem.Divider {} |
556 | + |
557 | + ListItem.SingleValue { |
558 | + text : i18n.tr("Hotspot disabled because Wi-Fi is off.") |
559 | + visible: showAllUI && !hotspotItem.visible |
560 | + } |
561 | + |
562 | + ListItem.SingleValue { |
563 | + id: hotspotItem |
564 | + text: i18n.tr("Wi-Fi hotspot") |
565 | + progression: true |
566 | + onClicked: { |
567 | + pageStack.push(Qt.resolvedUrl("Hotspot.qml")) |
568 | + } |
569 | + visible: showAllUI && (actionGroup.actionObject.valid ? actionGroup.actionObject.state : false) |
570 | + } |
571 | + |
572 | + ListItem.Standard { |
573 | + text: i18n.tr("Data usage statistics") |
574 | + progression: true |
575 | + visible: showAllUI |
576 | + } |
577 | + |
578 | + ListItem.SingleValue { |
579 | + text: i18n.tr("Carrier"); |
580 | + id: chooseCarrier |
581 | + objectName: "chooseCarrier" |
582 | + progression: enabled |
583 | + value: sim.netReg.name || i18n.tr("N/A") |
584 | + onClicked: { |
585 | + pageStack.push(Qt.resolvedUrl("../PageChooseCarrier.qml"), { |
586 | + netReg: sim.netReg, |
587 | + title: i18n.tr("Carrier") |
588 | + }) |
589 | + } |
590 | + } |
591 | + |
592 | + ListItem.Standard { |
593 | + text: i18n.tr("APN") |
594 | + progression: true |
595 | + visible: showAllUI |
596 | + } |
597 | +} |
598 | |
599 | === modified file 'plugins/cellular/PageChooseCarriers.qml' |
600 | --- plugins/cellular/PageChooseCarriers.qml 2014-07-24 19:00:45 +0000 |
601 | +++ plugins/cellular/PageChooseCarriers.qml 2014-08-22 10:53:29 +0000 |
602 | @@ -28,8 +28,7 @@ |
603 | title: i18n.tr("Carriers") |
604 | objectName: "chooseCarriersPage" |
605 | |
606 | - property var sim1 |
607 | - property var sim2 |
608 | + property var sims |
609 | |
610 | Flickable { |
611 | anchors.fill: parent |
612 | @@ -42,33 +41,33 @@ |
613 | anchors.right: parent.right |
614 | |
615 | ListItem.Standard { |
616 | - text: sim1.title |
617 | + text: sims[0].title |
618 | } |
619 | |
620 | ListItem.SingleValue { |
621 | objectName: "chooseCarrierSim1" |
622 | - value: sim1.netReg.name ? sim1.netReg.name : i18n.tr("N/A") |
623 | + value: sims[0].netReg.name ? sims[0].netReg.name : i18n.tr("N/A") |
624 | progression: true |
625 | onClicked: { |
626 | pageStack.push(Qt.resolvedUrl("PageChooseCarrier.qml"), { |
627 | - netReg: sim1.netReg, |
628 | - title: sim1.title |
629 | + netReg: sims[0].netReg, |
630 | + title: sims[0].title |
631 | }) |
632 | } |
633 | } |
634 | |
635 | ListItem.Standard { |
636 | - text: sim2.title |
637 | + text: sims[1].title |
638 | } |
639 | |
640 | ListItem.SingleValue { |
641 | objectName: "chooseCarrierSim2" |
642 | - value: sim2.netReg.name ? sim2.netReg.name : i18n.tr("N/A") |
643 | + value: sims[1].netReg.name ? sims[1].netReg.name : i18n.tr("N/A") |
644 | progression: true |
645 | onClicked: { |
646 | pageStack.push(Qt.resolvedUrl("PageChooseCarrier.qml"), { |
647 | - netReg: sim2.netReg, |
648 | - title: sim2.title |
649 | + netReg: sims[1].netReg, |
650 | + title: sims[1].title |
651 | }) |
652 | } |
653 | } |
654 | |
655 | === modified file 'plugins/cellular/PageComponent.qml' |
656 | --- plugins/cellular/PageComponent.qml 2014-08-12 16:25:26 +0000 |
657 | +++ plugins/cellular/PageComponent.qml 2014-08-22 10:53:29 +0000 |
658 | @@ -19,53 +19,69 @@ |
659 | */ |
660 | |
661 | import QtQuick 2.0 |
662 | -import GSettings 1.0 |
663 | import SystemSettings 1.0 |
664 | import Ubuntu.Components 0.1 |
665 | import Ubuntu.Components.ListItems 0.1 as ListItem |
666 | import MeeGo.QOfono 0.2 |
667 | import QMenuModel 0.1 |
668 | -import "Components" |
669 | +import "Components" as LocalComponents |
670 | +import "sims.js" as Sims |
671 | |
672 | ItemPage { |
673 | id: root |
674 | title: i18n.tr("Cellular") |
675 | objectName: "cellularPage" |
676 | |
677 | - // pointers to sim 1 and 2, lazy loaded |
678 | - property alias sim1: simOneLoader.item |
679 | - property alias sim2: simTwoLoader.item |
680 | property var modemsSorted: manager.modems.slice(0).sort() |
681 | + property int simsLoaded: 0 |
682 | |
683 | states: [ |
684 | State { |
685 | + name: "noSim" |
686 | + when: (simsLoaded === 0) || (Sims.getPresentCount() === 0) |
687 | + StateChangeScript { |
688 | + script: loader.source = "Components/NoSim.qml" |
689 | + } |
690 | + }, |
691 | + State { |
692 | name: "singleSim" |
693 | StateChangeScript { |
694 | - name: "loadSim" |
695 | - script: { |
696 | - var p = modemsSorted[0]; |
697 | - simOneLoader.setSource("Components/Sim.qml", { |
698 | - path: p |
699 | - }); |
700 | - } |
701 | + script: loader.setSource("Components/SingleSim.qml", { |
702 | + sim: Sims.get(0) |
703 | + }) |
704 | } |
705 | + when: simsLoaded && (Sims.getPresentCount() === 1) |
706 | }, |
707 | State { |
708 | - name: "dualSim" |
709 | - extend: "singleSim" |
710 | + name: "multiSim" |
711 | StateChangeScript { |
712 | - name: "loadSecondSim" |
713 | - script: { |
714 | - var p = modemsSorted[1]; |
715 | - simTwoLoader.setSource("Components/Sim.qml", { |
716 | - path: p |
717 | - }); |
718 | - defaultSimLoader.source = "Components/DefaultSim.qml"; |
719 | - } |
720 | + script: loader.setSource("Components/MultiSim.qml", { |
721 | + sims: Sims.getAll(), |
722 | + modems: modemsSorted |
723 | + }) |
724 | } |
725 | + when: simsLoaded && (Sims.getPresentCount() > 1) |
726 | } |
727 | ] |
728 | |
729 | + OfonoManager { |
730 | + id: manager |
731 | + Component.onCompleted: { |
732 | + var component = Qt.createComponent("Components/Sim.qml"); |
733 | + modemsSorted.forEach(function (path) { |
734 | + console.warn('creating sim object for', path) |
735 | + var sim = component.createObject(root, { |
736 | + path: path |
737 | + }); |
738 | + if (sim === null) { |
739 | + console.warn('failed to create sim object'); |
740 | + } else { |
741 | + Sims.add(sim); |
742 | + } |
743 | + }); |
744 | + } |
745 | + } |
746 | + |
747 | QDBusActionGroup { |
748 | id: actionGroup |
749 | busType: 1 |
750 | @@ -78,42 +94,6 @@ |
751 | start() |
752 | } |
753 | } |
754 | - |
755 | - OfonoManager { |
756 | - id: manager |
757 | - Component.onCompleted: { |
758 | - if (modems.length === 1) { |
759 | - root.state = "singleSim"; |
760 | - } else if (modems.length === 2) { |
761 | - root.state = "dualSim"; |
762 | - } |
763 | - } |
764 | - } |
765 | - |
766 | - Loader { |
767 | - id: simOneLoader |
768 | - onLoaded: { |
769 | - if (parent.state === "singleSim") { |
770 | - cellData.setSource("Components/CellularSingleSim.qml", { |
771 | - sim1: sim1 |
772 | - }); |
773 | - } |
774 | - } |
775 | - } |
776 | - |
777 | - Loader { |
778 | - id: simTwoLoader |
779 | - onLoaded: { |
780 | - // unload any single sim setup |
781 | - cellData.source = ""; |
782 | - cellData.setSource("Components/CellularDualSim.qml", { |
783 | - sim1: sim1, |
784 | - sim2: sim2 |
785 | - }); |
786 | - simEditorLoader.source = "Components/SimEditor.qml"; |
787 | - } |
788 | - } |
789 | - |
790 | Flickable { |
791 | anchors.fill: parent |
792 | contentWidth: parent.width |
793 | @@ -124,106 +104,9 @@ |
794 | anchors {Â left: parent.left; right: parent.right } |
795 | |
796 | Loader { |
797 | - id: cellData |
798 | - anchors {Â left: parent.left; right: parent.right } |
799 | - } |
800 | - |
801 | - ListItem.SingleValue { |
802 | - text : i18n.tr("Hotspot disabled because Wi-Fi is off.") |
803 | - visible: showAllUI && !hotspotItem.visible |
804 | - } |
805 | - |
806 | - ListItem.SingleValue { |
807 | - id: hotspotItem |
808 | - text: i18n.tr("Wi-Fi hotspot") |
809 | - progression: true |
810 | - onClicked: { |
811 | - pageStack.push(Qt.resolvedUrl("Hotspot.qml")) |
812 | - } |
813 | - visible: showAllUI && (actionGroup.actionObject.valid ? actionGroup.actionObject.state : false) |
814 | - } |
815 | - |
816 | - ListItem.Standard { |
817 | - text: i18n.tr("Data usage statistics") |
818 | - progression: true |
819 | - visible: showAllUI |
820 | - } |
821 | - |
822 | - ListItem.SingleValue { |
823 | - text: i18n.tr("Carrier", "Carriers", manager.modems.length); |
824 | - id: chooseCarrier |
825 | - objectName: "chooseCarrier" |
826 | - progression: enabled |
827 | - onClicked: { |
828 | - if (root.state === 'singleSim') { |
829 | - pageStack.push(Qt.resolvedUrl("PageChooseCarrier.qml"), { |
830 | - netReg: sim1.netReg, |
831 | - title: i18n.tr("Carrier") |
832 | - }) |
833 | - } else if (root.state === 'dualSim') { |
834 | - pageStack.push(Qt.resolvedUrl("PageChooseCarriers.qml"), { |
835 | - sim1: sim1, |
836 | - sim2: sim2 |
837 | - }); |
838 | - } |
839 | - } |
840 | - } |
841 | - |
842 | - Binding { |
843 | - target: chooseCarrier |
844 | - property: "value" |
845 | - value: sim1.netReg.name || i18n.tr("N/A") |
846 | - when: (simOneLoader.status === Loader.Ready) && root.state === "singleSim" |
847 | - } |
848 | - |
849 | - ListItem.Standard { |
850 | - text: i18n.tr("APN") |
851 | - progression: true |
852 | - visible: showAllUI |
853 | - } |
854 | - |
855 | - Loader { |
856 | - id: simEditorLoader |
857 | - anchors {Â left: parent.left; right: parent.right } |
858 | - } |
859 | - |
860 | - ListItem.Divider {} |
861 | - |
862 | - Loader { |
863 | - id: defaultSimLoader |
864 | - anchors.left: parent.left |
865 | - anchors.right: parent.right |
866 | - } |
867 | - } |
868 | - } |
869 | - |
870 | - GSettings { |
871 | - id: phoneSettings |
872 | - schema.id: "com.ubuntu.phone" |
873 | - Component.onCompleted: { |
874 | - // set default names |
875 | - var simNames = phoneSettings.simNames; |
876 | - var m0 = modemsSorted[0]; |
877 | - var m1 = modemsSorted[1]; |
878 | - if (!simNames[m0]) { |
879 | - simNames[m0] = "SIM 1"; |
880 | - } |
881 | - if (!simNames[m1])Â { |
882 | - simNames[m1] = "SIM 2"; |
883 | - } |
884 | - phoneSettings.simNames = simNames; |
885 | - } |
886 | - } |
887 | - |
888 | - Binding { |
889 | - target: sim1 |
890 | - property: "name" |
891 | - value: phoneSettings.simNames[modemsSorted[0]] |
892 | - } |
893 | - |
894 | - Binding { |
895 | - target: sim2 |
896 | - property: "name" |
897 | - value: phoneSettings.simNames[modemsSorted[1]] |
898 | + id: loader |
899 | + anchors {Â left: parent.left; right: parent.right } |
900 | + } |
901 | + } |
902 | } |
903 | } |
904 | |
905 | === added file 'plugins/cellular/sims.js' |
906 | --- plugins/cellular/sims.js 1970-01-01 00:00:00 +0000 |
907 | +++ plugins/cellular/sims.js 2014-08-22 10:53:29 +0000 |
908 | @@ -0,0 +1,34 @@ |
909 | +var sims = []; |
910 | + |
911 | +function add (sim) { |
912 | + sims.push(sim); |
913 | + root.simsLoaded++; |
914 | +} |
915 | + |
916 | +function getAll () { |
917 | + return sims; |
918 | +} |
919 | + |
920 | +function get (n) { |
921 | + return getAll()[n]; |
922 | +} |
923 | + |
924 | +function getCount () { |
925 | + return getAll().length; |
926 | +} |
927 | + |
928 | +function getPresent () { |
929 | + var present = []; |
930 | + getAll().forEach(function (sim) { |
931 | + if (sim.present) { |
932 | + present.push(sim); |
933 | + } else { |
934 | + return; |
935 | + } |
936 | + }); |
937 | + return present; |
938 | +} |
939 | + |
940 | +function getPresentCount () { |
941 | + return getPresent().length; |
942 | +} |
943 | |
944 | === modified file 'tests/autopilot/ubuntu_system_settings/tests/__init__.py' |
945 | --- tests/autopilot/ubuntu_system_settings/tests/__init__.py 2014-08-19 15:26:07 +0000 |
946 | +++ tests/autopilot/ubuntu_system_settings/tests/__init__.py 2014-08-22 10:53:29 +0000 |
947 | @@ -125,7 +125,7 @@ |
948 | 'for m in objects if "%s/operator/" in m]' % name |
949 | |
950 | def mock_connection_manager(self, modem): |
951 | - modem.AddProperty(CONNMAN_IFACE, 'Powered', True) |
952 | + modem.AddProperty(CONNMAN_IFACE, 'Powered', dbus.Boolean(1)) |
953 | modem.AddProperty(CONNMAN_IFACE, 'RoamingAllowed', False) |
954 | modem.AddMethods( |
955 | CONNMAN_IFACE, |
956 | @@ -194,6 +194,7 @@ |
957 | 'SubscriberNumbers': ['123456', '234567'] |
958 | } |
959 | modem.AddProperties(SIM_IFACE, properties) |
960 | + modem.AddProperty(SIM_IFACE, 'Present', True) |
961 | modem.AddMethods( |
962 | SIM_IFACE, |
963 | [('GetProperties', '', 'a{sv}', |
964 | @@ -208,7 +209,6 @@ |
965 | # create modem_0 proxy |
966 | self.modem_0 = self.dbus_con.get_object('org.ofono', '/ril_0') |
967 | |
968 | - # Add an available carrier |
969 | self.mock_carriers('ril_0') |
970 | |
971 | self.mock_radio_settings(self.modem_0) |
972 | @@ -232,6 +232,7 @@ |
973 | self.dbusmock.AddModem(second_modem, {'Powered': True}) |
974 | self.modem_1 = self.dbus_con.get_object( |
975 | 'org.ofono', '/%s' % second_modem) |
976 | + |
977 | self.modem_1.AddMethods(NETREG_IFACE, [ |
978 | ('GetProperties', '', 'a{sv}', |
979 | 'ret = self.GetAll("org.ofono.NetworkRegistration")'), |
980 | @@ -253,9 +254,10 @@ |
981 | def setUpClass(cls): |
982 | cls.start_system_bus() |
983 | cls.dbus_con = cls.get_dbus(True) |
984 | + template = os.path.join(os.path.dirname(__file__), 'ofono.py') |
985 | # Add a mock Ofono environment so we get consistent results |
986 | (cls.p_mock, cls.obj_ofono) = cls.spawn_server_template( |
987 | - 'ofono', stdout=subprocess.PIPE) |
988 | + template, stdout=subprocess.PIPE) |
989 | cls.dbusmock = dbus.Interface(cls.obj_ofono, dbusmock.MOCK_IFACE) |
990 | |
991 | def setUp(self, panel=None): |
992 | |
993 | === added file 'tests/autopilot/ubuntu_system_settings/tests/ofono.py' |
994 | --- tests/autopilot/ubuntu_system_settings/tests/ofono.py 1970-01-01 00:00:00 +0000 |
995 | +++ tests/autopilot/ubuntu_system_settings/tests/ofono.py 2014-08-22 10:53:29 +0000 |
996 | @@ -0,0 +1,215 @@ |
997 | +'''ofonod D-BUS mock template''' |
998 | + |
999 | +# This program is free software; you can redistribute it and/or modify it under |
1000 | +# the terms of the GNU Lesser General Public License as published by the Free |
1001 | +# Software Foundation; either version 3 of the License, or (at your option) any |
1002 | +# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text |
1003 | +# of the license. |
1004 | + |
1005 | +__author__ = 'Martin Pitt' |
1006 | +__email__ = 'martin.pitt@ubuntu.com' |
1007 | +__copyright__ = '(c) 2013 Canonical Ltd.' |
1008 | +__license__ = 'LGPL 3+' |
1009 | + |
1010 | + |
1011 | +import dbus |
1012 | + |
1013 | +import dbusmock |
1014 | + |
1015 | +BUS_NAME = 'org.ofono' |
1016 | +MAIN_OBJ = '/' |
1017 | +MAIN_IFACE = 'org.ofono.Manager' |
1018 | +SYSTEM_BUS = True |
1019 | + |
1020 | +NOT_IMPLEMENTED = '''raise dbus.exceptions.DBusException( |
1021 | + "org.ofono.Error.NotImplemented")''' |
1022 | + |
1023 | +_parameters = {} |
1024 | + |
1025 | + |
1026 | +def load(mock, parameters): |
1027 | + global _parameters |
1028 | + mock.modems = [] # object paths |
1029 | + _parameters = parameters |
1030 | + mock.AddMethod(MAIN_IFACE, 'GetModems', '', 'a(oa{sv})', |
1031 | + 'ret = [(m, objects[m].GetAll(\ |
1032 | + "org.ofono.Modem")) for m in self.modems]') |
1033 | + |
1034 | + if not parameters.get('no_modem', False): |
1035 | + mock.AddModem(parameters.get('ModemName', 'ril_0'), {}) |
1036 | + |
1037 | + |
1038 | +@dbus.service.method(dbusmock.MOCK_IFACE, |
1039 | + in_signature='sa{sv}', out_signature='s') |
1040 | +def AddModem(self, name, properties): |
1041 | + '''Convenience method to add a modem |
1042 | + |
1043 | + You have to specify a device name which must be a valid part of an object |
1044 | + path, e. g. "mock_ac". For future extensions you can specify a "properties" |
1045 | + array, but no extra properties are supported for now. |
1046 | + |
1047 | + Returns the new object path. |
1048 | + ''' |
1049 | + path = '/' + name |
1050 | + self.AddObject( |
1051 | + path, |
1052 | + 'org.ofono.Modem', |
1053 | + { |
1054 | + 'Online': dbus.Boolean(True, variant_level=1), |
1055 | + 'Powered': dbus.Boolean(True, variant_level=1), |
1056 | + 'Lockdown': dbus.Boolean(False, variant_level=1), |
1057 | + 'Emergency': dbus.Boolean(False, variant_level=1), |
1058 | + 'Manufacturer': dbus.String('Fakesys', variant_level=1), |
1059 | + 'Model': dbus.String('Mock Modem', variant_level=1), |
1060 | + 'Revision': dbus.String('0815.42', variant_level=1), |
1061 | + 'Type': dbus.String('hardware', variant_level=1), |
1062 | + 'Interfaces': [ |
1063 | + 'org.ofono.CallVolume', |
1064 | + 'org.ofono.VoiceCallManager', |
1065 | + 'org.ofono.NetworkRegistration', |
1066 | + 'org.ofono.SimManager'], |
1067 | + 'Features': ['gprs', 'net'], |
1068 | + }, |
1069 | + [ |
1070 | + ('GetProperties', '', 'a{sv}', |
1071 | + 'ret = self.GetAll("org.ofono.Modem")'), |
1072 | + ( |
1073 | + 'SetProperty', 'sv', '', |
1074 | + 'self.Set("org.ofono.Modem", args[0], args[1]); ' |
1075 | + 'self.EmitSignal("org.ofono.Modem", "PropertyChanged",' |
1076 | + '"sv", [args[0], args[1]])'), |
1077 | + ]) |
1078 | + obj = dbusmock.mockobject.objects[path] |
1079 | + obj.name = name |
1080 | + add_voice_call_api(obj) |
1081 | + add_netreg_api(obj) |
1082 | + self.modems.append(path) |
1083 | + props = obj.GetAll('org.ofono.Modem', dbus_interface=dbus.PROPERTIES_IFACE) |
1084 | + self.EmitSignal(MAIN_IFACE, 'ModemAdded', 'oa{sv}', [path, props]) |
1085 | + return path |
1086 | + |
1087 | + |
1088 | +def add_voice_call_api(mock): |
1089 | + '''Add org.ofono.VoiceCallManager API to a mock''' |
1090 | + |
1091 | + # also add an emergency number which is not a real one, in case one runs a |
1092 | + # test case against a production ofono :-) |
1093 | + mock.AddProperty( |
1094 | + 'org.ofono.VoiceCallManager', 'EmergencyNumbers', ['911', '13373']) |
1095 | + |
1096 | + mock.calls = [] # object paths |
1097 | + |
1098 | + mock.AddMethods('org.ofono.VoiceCallManager', [ |
1099 | + ( |
1100 | + 'GetProperties', '', 'a{sv}', |
1101 | + 'ret = self.GetAll("org.ofono.VoiceCallManager")'), |
1102 | + ('Transfer', '', '', ''), |
1103 | + ('SwapCalls', '', '', ''), |
1104 | + ('ReleaseAndAnswer', '', '', ''), |
1105 | + ('ReleaseAndSwap', '', '', ''), |
1106 | + ('HoldAndAnswer', '', '', ''), |
1107 | + ('SendTones', 's', '', ''), |
1108 | + ('PrivateChat', 'o', 'ao', NOT_IMPLEMENTED), |
1109 | + ('CreateMultiparty', '', 'o', NOT_IMPLEMENTED), |
1110 | + ('HangupMultiparty', '', '', NOT_IMPLEMENTED), |
1111 | + ( |
1112 | + 'GetCalls', '', 'a(oa{sv})', |
1113 | + 'ret = [(c, objects[c].GetAll("org.ofono.VoiceCall"))\ |
1114 | + for c in self.calls]') |
1115 | + ]) |
1116 | + |
1117 | + |
1118 | +@dbus.service.method('org.ofono.VoiceCallManager', |
1119 | + in_signature='ss', out_signature='s') |
1120 | +def Dial(self, number, hide_callerid): |
1121 | + path = self._object_path + '/voicecall%02i' % (len(self.calls) + 1) |
1122 | + self.AddObject( |
1123 | + path, 'org.ofono.VoiceCall', |
1124 | + { |
1125 | + 'State': dbus.String('dialing', variant_level=1), |
1126 | + 'LineIdentification': dbus.String(number, variant_level=1), |
1127 | + 'Name': dbus.String('', variant_level=1), |
1128 | + 'Multiparty': dbus.Boolean(False, variant_level=1), |
1129 | + 'Multiparty': dbus.Boolean(False, variant_level=1), |
1130 | + 'RemoteHeld': dbus.Boolean(False, variant_level=1), |
1131 | + 'RemoteMultiparty': dbus.Boolean(False, variant_level=1), |
1132 | + 'Emergency': dbus.Boolean(False, variant_level=1), |
1133 | + }, |
1134 | + [ |
1135 | + ( |
1136 | + 'GetProperties', '', 'a{sv}', |
1137 | + 'ret = self.GetAll("org.ofono.VoiceCall")'), |
1138 | + ('Deflect', 's', '', NOT_IMPLEMENTED), |
1139 | + ( |
1140 | + 'Hangup', '', '', |
1141 | + 'self.parent.calls.remove(self._object_path);' |
1142 | + 'self.parent.RemoveObject(self._object_path);' |
1143 | + 'self.EmitSignal("org.ofono.VoiceCallManager",\ |
1144 | + "CallRemoved", "o", [self._object_path])'), |
1145 | + ('Answer', '', '', NOT_IMPLEMENTED), |
1146 | + ]) |
1147 | + obj = dbusmock.mockobject.objects[path] |
1148 | + obj.parent = self |
1149 | + self.calls.append(path) |
1150 | + self.EmitSignal('org.ofono.VoiceCallManager', 'CallAdded', 'oa{sv}', |
1151 | + [path, obj.GetProperties()]) |
1152 | + return path |
1153 | + |
1154 | + |
1155 | +@dbus.service.method('org.ofono.VoiceCallManager', |
1156 | + in_signature='', out_signature='') |
1157 | +def HangupAll(self): |
1158 | + print('XXX HangupAll', self.calls) |
1159 | + for c in list(self.calls): # needs a copy |
1160 | + dbusmock.mockobject.objects[c].Hangup() |
1161 | + assert self.calls == [] |
1162 | + |
1163 | + |
1164 | +def get_all_operators(mock): |
1165 | + return 'ret = [(m, objects[m].GetAll("org.ofono.NetworkOperator")) ' \ |
1166 | + 'for m in objects if "%s/operator/" in m]' % mock.name |
1167 | + |
1168 | + |
1169 | +def add_netreg_api(mock): |
1170 | + '''Add org.ofono.NetworkRegistration API to a mock''' |
1171 | + |
1172 | + # also add an emergency number which is not a real one, in case one runs a |
1173 | + # test case against a production ofono :-) |
1174 | + mock.AddProperties('org.ofono.NetworkRegistration', { |
1175 | + 'Mode': 'auto', |
1176 | + 'Status': 'registered', |
1177 | + 'LocationAreaCode': _parameters.get('LocationAreaCode', 987), |
1178 | + 'CellId': _parameters.get('CellId', 10203), |
1179 | + 'MobileCountryCode': _parameters.get('MobileCountryCode', '777'), |
1180 | + 'MobileNetworkCode': _parameters.get('MobileNetworkCode', '11'), |
1181 | + 'Technology': _parameters.get('Technology', 'gsm'), |
1182 | + 'Name': _parameters.get('Name', 'fake.tel'), |
1183 | + 'Strength': _parameters.get('Strength', dbus.Byte(80)), |
1184 | + 'BaseStation': _parameters.get('BaseStation', ''), |
1185 | + }) |
1186 | + |
1187 | + mock.AddObject( |
1188 | + '/%s/operator/op1' % mock.name, |
1189 | + 'org.ofono.NetworkOperator', |
1190 | + { |
1191 | + 'Name': _parameters.get('Name', 'fake.tel'), |
1192 | + 'Status': 'current', |
1193 | + 'MobileCountryCode': _parameters.get('MobileCountryCode', '777'), |
1194 | + 'MobileNetworkCode': _parameters.get('MobileNetworkCode', '11'), |
1195 | + 'Technologies': [_parameters.get('Technology', 'gsm')], |
1196 | + }, |
1197 | + [ |
1198 | + ( |
1199 | + 'GetProperties', '', 'a{sv}', |
1200 | + 'ret = self.GetAll("org.ofono.NetworkOperator")'), |
1201 | + ('Register', '', '', ''), |
1202 | + ]) |
1203 | + |
1204 | + mock.AddMethods('org.ofono.NetworkRegistration', [ |
1205 | + ( |
1206 | + 'GetProperties', '', 'a{sv}', |
1207 | + 'ret = self.GetAll("org.ofono.NetworkRegistration")'), |
1208 | + ('Register', '', '', ''), |
1209 | + ('GetOperators', '', 'a(oa{sv})', get_all_operators(mock)), |
1210 | + ('Scan', '', 'a(oa{sv})', get_all_operators(mock)), |
1211 | + ]) |
1212 | |
1213 | === modified file 'tests/autopilot/ubuntu_system_settings/tests/test_cellular.py' |
1214 | --- tests/autopilot/ubuntu_system_settings/tests/test_cellular.py 2014-08-14 14:18:17 +0000 |
1215 | +++ tests/autopilot/ubuntu_system_settings/tests/test_cellular.py 2014-08-22 10:53:29 +0000 |
1216 | @@ -15,7 +15,7 @@ |
1217 | from unittest import skip |
1218 | |
1219 | from ubuntu_system_settings.tests import ( |
1220 | - CellularBaseTestCase, CONNMAN_IFACE, RDO_IFACE) |
1221 | + CellularBaseTestCase, CONNMAN_IFACE, RDO_IFACE, SIM_IFACE) |
1222 | from ubuntu_system_settings.utils.i18n import ugettext as _ |
1223 | |
1224 | from ubuntuuitoolkit import emulators as toolkit_emulators |
1225 | @@ -92,6 +92,14 @@ |
1226 | Equals(_('Cellular')) |
1227 | ) |
1228 | |
1229 | + def test_single_sim_layout(self): |
1230 | + self.system_settings.main_view.cellular_page.\ |
1231 | + select_single(objectName="singleSim") |
1232 | + self.assertThat(lambda: self.system_settings.main_view.select_single( |
1233 | + objectName='multiSim'), raises(StateNotFoundError)) |
1234 | + self.assertThat(lambda: self.system_settings.main_view.select_single( |
1235 | + objectName='noSim'), raises(StateNotFoundError)) |
1236 | + |
1237 | def test_current_network(self): |
1238 | """ Tests whether the current network is visible and selected """ |
1239 | self.navigate_to_carrier_page() |
1240 | @@ -592,3 +600,90 @@ |
1241 | self.assertEqual( |
1242 | gsettings.get_value('default-sim-for-messages').get_string(), |
1243 | '/ril_1') |
1244 | + |
1245 | + def test_multi_sim_layout(self): |
1246 | + self.system_settings.main_view.cellular_page.\ |
1247 | + select_single(objectName="multiSim") |
1248 | + self.assertThat(lambda: self.system_settings.main_view.select_single( |
1249 | + objectName='singleSim'), raises(StateNotFoundError)) |
1250 | + self.assertThat(lambda: self.system_settings.main_view.select_single( |
1251 | + objectName='noSim'), raises(StateNotFoundError)) |
1252 | + |
1253 | + def test_remove_one_sim(self): |
1254 | + self.modem_0.EmitSignal( |
1255 | + SIM_IFACE, |
1256 | + 'PropertyChanged', |
1257 | + 'sv', |
1258 | + ['Present', 'False']) |
1259 | + |
1260 | + self.system_settings.main_view.cellular_page.\ |
1261 | + select_single(objectName="singleSim") |
1262 | + self.assertThat(lambda: self.system_settings.main_view.select_single( |
1263 | + objectName='multiSim'), raises(StateNotFoundError)) |
1264 | + self.assertThat(lambda: self.system_settings.main_view.select_single( |
1265 | + objectName='noSim'), raises(StateNotFoundError)) |
1266 | + |
1267 | + def test_remove_two_sims(self): |
1268 | + self.modem_0.EmitSignal( |
1269 | + SIM_IFACE, |
1270 | + 'PropertyChanged', |
1271 | + 'sv', |
1272 | + ['Present', 'False']) |
1273 | + |
1274 | + self.modem_1.EmitSignal( |
1275 | + SIM_IFACE, |
1276 | + 'PropertyChanged', |
1277 | + 'sv', |
1278 | + ['Present', 'False']) |
1279 | + |
1280 | + self.system_settings.main_view.cellular_page.\ |
1281 | + wait_select_single(objectName="noSim") |
1282 | + self.assertThat( |
1283 | + lambda: self.system_settings.main_view.select_single( |
1284 | + objectName='multiSim'), raises(StateNotFoundError)) |
1285 | + self.assertThat( |
1286 | + lambda: self.system_settings.main_view.select_single( |
1287 | + objectName='singleSim'), raises(StateNotFoundError)) |
1288 | + |
1289 | + def test_remove_and_insert_sims(self): |
1290 | + self.modem_0.EmitSignal( |
1291 | + SIM_IFACE, |
1292 | + 'PropertyChanged', |
1293 | + 'sv', |
1294 | + ['Present', 'False']) |
1295 | + |
1296 | + self.modem_1.EmitSignal( |
1297 | + SIM_IFACE, |
1298 | + 'PropertyChanged', |
1299 | + 'sv', |
1300 | + ['Present', 'False']) |
1301 | + |
1302 | + self.system_settings.main_view.cellular_page.\ |
1303 | + wait_select_single(objectName="noSim") |
1304 | + self.assertThat( |
1305 | + lambda: self.system_settings.main_view.select_single( |
1306 | + objectName='multiSim'), raises(StateNotFoundError)) |
1307 | + self.assertThat( |
1308 | + lambda: self.system_settings.main_view.select_single( |
1309 | + objectName='singleSim'), raises(StateNotFoundError)) |
1310 | + |
1311 | + self.modem_0.EmitSignal( |
1312 | + SIM_IFACE, |
1313 | + 'PropertyChanged', |
1314 | + 'sv', |
1315 | + ['Present', 'True']) |
1316 | + |
1317 | + self.modem_1.EmitSignal( |
1318 | + SIM_IFACE, |
1319 | + 'PropertyChanged', |
1320 | + 'sv', |
1321 | + ['Present', 'True']) |
1322 | + |
1323 | + self.system_settings.main_view.cellular_page.\ |
1324 | + wait_select_single(objectName="multiSim") |
1325 | + self.assertThat( |
1326 | + lambda: self.system_settings.main_view.select_single( |
1327 | + objectName='noSim'), raises(StateNotFoundError)) |
1328 | + self.assertThat( |
1329 | + lambda: self.system_settings.main_view.select_single( |
1330 | + objectName='singleSim'), raises(StateNotFoundError)) |
FAILED: Continuous integration, rev:913 /code.launchpad .net/~jonas- drange/ ubuntu- system- settings/ 1357393- fix/+merge/ 231136/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- ci/1243/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/3725 jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 2870 jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- utopic- amd64-ci/ 436 jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- utopic- armhf-ci/ 432 jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- utopic- armhf-ci/ 432/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- utopic- i386-ci/ 435 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/3601 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4972 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4972/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 11690 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-utopic/ 2330 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/3154 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/3154/ artifact/ work/output/ *zip*/output. zip
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- system- settings- ci/1243/ rebuild
http://