Merge lp:~tiagosh/dialer-app/emergency-calls-libphonenumber into lp:dialer-app

Proposed by Tiago Salem Herrmann
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 445
Merged at revision: 453
Proposed branch: lp:~tiagosh/dialer-app/emergency-calls-libphonenumber
Merge into: lp:dialer-app
Diff against target: 455 lines (+203/-35)
8 files modified
debian/control (+0/-1)
src/dialerapplication.cpp (+1/-1)
src/qml/DialerPage/DialerPage.qml (+42/-12)
src/qml/Dialogs/NoDefaultSIMCardDialog.qml (+2/-2)
src/qml/LiveCallPage/LiveCall.qml (+6/-0)
src/qml/dialer-app.qml (+26/-7)
tests/qml/CMakeLists.txt (+1/-10)
tests/qml/tst_DialerPage.qml (+125/-2)
To merge this branch: bzr merge lp:~tiagosh/dialer-app/emergency-calls-libphonenumber
Reviewer Review Type Date Requested Status
Gustavo Pichorim Boiko (community) Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+264908@code.launchpad.net

Commit message

Improve emergency number validation with libphonenumber.

Description of the change

Improve emergency number validation with libphonenumber.

--Checklist--
Are there any related MPs required for this MP to build/function as expected? Please list.
https://code.launchpad.net/~tiagosh/telephony-service/check-contact-watcher-results/+merge/266631
https://code.launchpad.net/~tiagosh/telephony-service/use-libphonenumber/+merge/264906

Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)
Yes

Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator?
Yes

Did you successfully run all tests found in your component's Test Plan (https://wiki.ubuntu.com/Process/Merges/TestPlan/<package-name>) on device or emulator?
Yes

If you changed the UI, was the change specified/approved by design?
N/A

If you changed UI labels, did you update the pot file?
N/A

If you changed the packaging (debian), did you add a core-dev as a reviewer to this MP?
N/A

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
435. By Tiago Salem Herrmann

use countryCode when checking for emergency numbers

436. By Tiago Salem Herrmann

fix comments

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
437. By Tiago Salem Herrmann

Use the selected account if available, otherwise fallback to any other account

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
438. By Tiago Salem Herrmann

Use string comparison for emergency numbers coming from the sim card

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
439. By Tiago Salem Herrmann

Keep call button always enabled
Fill entry with last called number when the entry is empty and call button is pressed

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
440. By Tiago Salem Herrmann

Allow calling any number if no sims are present

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
441. By Tiago Salem Herrmann

Provide initial status and phone to live call when making a call

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
442. By Tiago Salem Herrmann

update method signature

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

Just a couple remarks, other than that I think it would be nice to try to add some tests, maybe QML tests?

review: Needs Fixing
443. By Tiago Salem Herrmann

improve comparison

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
444. By Tiago Salem Herrmann

add tests

445. By Tiago Salem Herrmann

remove dbus-test-runner

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

Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?
Yes

Did CI run pass? If not, please explain why.
No, needs changes in telephony-service.

Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
Yes

Looks good and works as expected!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2015-05-14 17:01:14 +0000
3+++ debian/control 2015-08-07 21:34:02 +0000
4@@ -3,7 +3,6 @@
5 Priority: optional
6 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
7 Build-Depends: cmake,
8- dbus-test-runner,
9 debhelper (>= 9),
10 dh-translations,
11 pkg-config,
12
13=== modified file 'src/dialerapplication.cpp'
14--- src/dialerapplication.cpp 2015-05-12 14:33:45 +0000
15+++ src/dialerapplication.cpp 2015-08-07 21:34:02 +0000
16@@ -227,7 +227,7 @@
17 QUrlQuery query(url);
18 QString viewName = query.queryItemValue("view");
19 if (viewName == "liveCall") {
20- QMetaObject::invokeMethod(mainView, "switchToLiveCall");
21+ QMetaObject::invokeMethod(mainView, "switchToLiveCall", Q_ARG(QVariant, QVariant()), Q_ARG(QVariant, QVariant()));
22 }
23
24 }
25
26=== modified file 'src/qml/DialerPage/DialerPage.qml'
27--- src/qml/DialerPage/DialerPage.qml 2015-07-17 09:01:20 +0000
28+++ src/qml/DialerPage/DialerPage.qml 2015-08-07 21:34:02 +0000
29@@ -263,6 +263,7 @@
30
31 KeypadEntry {
32 id: keypadEntry
33+ objectName: "keypadEntry"
34
35 anchors {
36 top: parent.top
37@@ -401,20 +402,49 @@
38 horizontalCenter: parent.horizontalCenter
39 }
40 onClicked: {
41+ if (dialNumber == "") {
42+ if (mainView.greeterMode) {
43+ return;
44+ }
45+ keypadEntry.value = generalSettings.lastCalledPhoneNumber
46+ return;
47+ }
48+
49+ if (mainView.greeterMode && !mainView.isEmergencyNumber(dialNumber)) {
50+ // we only allow users to call any number in greeter mode if there are
51+ // no sim cards present. The operator will block the number if it thinks
52+ // it's necessary.
53+ // for phone accounts, active means the the status is not offline:
54+ // "nomodem", "nosim" or "flightmode"
55+
56+ var denyEmergencyCall = false
57+ // while in flight mode we can't detect if sims are present in some devices
58+ if (telepathyHelper.flightMode) {
59+ denyEmergencyCall = true
60+ } else {
61+ for (var i in telepathyHelper.activeAccounts) {
62+ var account = telepathyHelper.activeAccounts[i]
63+ if (account.type == AccountEntry.PhoneAccount) {
64+ denyEmergencyCall = true;
65+ }
66+ }
67+ }
68+ if (denyEmergencyCall) {
69+ // if there is at least one sim card present, just ignore the call
70+ showNotification(i18n.tr("Emergency call"), i18n.tr("This is not an emergency number."))
71+ keypadEntry.value = "";
72+ return;
73+ }
74+
75+ // this is a special case, we need to call using callEmergency() directly to avoid
76+ // all network and dual sim checks we have in mainView.call()
77+ mainView.callEmergency(keypadEntry.value)
78+ return;
79+ }
80+
81 console.log("Starting a call to " + keypadEntry.value);
82 mainView.call(keypadEntry.value);
83 }
84- enabled: {
85- if (dialNumber == "") {
86- return false;
87- }
88-
89- if (mainView.greeterMode) {
90- return mainView.isEmergencyNumber(dialNumber);
91- }
92-
93- return true;
94- }
95 }
96 }
97
98@@ -443,7 +473,7 @@
99 }
100 ScriptAction {
101 script: {
102- mainView.switchToLiveCall()
103+ mainView.switchToLiveCall(i18n.tr("Calling"), keypadEntry.value)
104 keypadEntry.value = ""
105 callButton.iconRotation = 0.0
106 keypadContainer.opacity = 1.0
107
108=== modified file 'src/qml/Dialogs/NoDefaultSIMCardDialog.qml'
109--- src/qml/Dialogs/NoDefaultSIMCardDialog.qml 2014-08-15 21:18:20 +0000
110+++ src/qml/Dialogs/NoDefaultSIMCardDialog.qml 2015-08-07 21:34:02 +0000
111@@ -70,7 +70,7 @@
112 text: i18n.tr("No")
113 color: UbuntuColors.orange
114 onClicked: {
115- settings.mainViewDontAskCount = 3
116+ dualSimSettings.mainViewDontAskCount = 3
117 PopupUtils.close(dialogue)
118 Qt.inputMethod.hide()
119 }
120@@ -81,7 +81,7 @@
121 color: UbuntuColors.orange
122 onClicked: {
123 PopupUtils.close(dialogue)
124- settings.mainViewDontAskCount++
125+ dualSimSettings.mainViewDontAskCount++
126 Qt.inputMethod.hide()
127 }
128 }
129
130=== modified file 'src/qml/LiveCallPage/LiveCall.qml'
131--- src/qml/LiveCallPage/LiveCall.qml 2015-07-16 21:45:42 +0000
132+++ src/qml/LiveCallPage/LiveCall.qml 2015-08-07 21:34:02 +0000
133@@ -43,6 +43,8 @@
134 property variant audioOutputs: call ? call.audioOutputs : null
135 property string phoneNumberSubTypeLabel: ""
136 property int defaultTimeout: 10000
137+ property string initialStatus: ""
138+ property string initialNumber: ""
139 property string caller: {
140 if (call && call.isConference) {
141 return i18n.tr("Conference");
142@@ -50,6 +52,8 @@
143 return contactWatcher.alias;
144 } else if (contactWatcher.identifier !== "") {
145 return contactWatcher.identifier;
146+ } else if (!call && initialNumber != "") {
147+ return initialNumber
148 } else {
149 return " "
150 }
151@@ -444,6 +448,8 @@
152 return call.held ? i18n.tr("%1 - on hold").arg(stopWatch.elapsed) : stopWatch.elapsed;
153 } else if (call && !call.incoming) {
154 return i18n.tr("Calling")
155+ } else if (!call && initialStatus !== "") {
156+ return initialStatus
157 } else {
158 return " "
159 }
160
161=== modified file 'src/qml/dialer-app.qml'
162--- src/qml/dialer-app.qml 2015-06-09 22:02:19 +0000
163+++ src/qml/dialer-app.qml 2015-08-07 21:34:02 +0000
164@@ -90,7 +90,7 @@
165 onSetupReady: {
166 telepathyReady = true
167 if (multipleAccounts && !telepathyHelper.defaultCallAccount &&
168- settings.mainViewDontAskCount < 3 && pageStackNormalMode.depth === 1 && !mainView.greeterMode) {
169+ dualSimSettings.mainViewDontAskCount < 3 && pageStackNormalMode.depth === 1 && !mainView.greeterMode) {
170 PopupUtils.open(Qt.createComponent("Dialogs/NoDefaultSIMCardDialog.qml").createObject(mainView))
171 }
172 }
173@@ -111,12 +111,17 @@
174 }
175
176 Settings {
177- id: settings
178+ id: dualSimSettings
179 category: "DualSim"
180 property bool dialPadDontAsk: false
181 property int mainViewDontAskCount: 0
182 }
183
184+ Settings {
185+ id: generalSettings
186+ property string lastCalledPhoneNumber: ""
187+ }
188+
189 PhoneUtils {
190 id: phoneUtils
191 }
192@@ -166,13 +171,21 @@
193 ]
194
195 function isEmergencyNumber(number) {
196+ // TODO should we only check for emergency numbers
197+ // in the selected account?
198+
199+ // check for specific account emergency numbers
200 for (var i in telepathyHelper.accounts) {
201 var account = telepathyHelper.accounts[i];
202 for (var j in account.emergencyNumbers) {
203- if (phoneUtils.comparePhoneNumbers(number, account.emergencyNumbers[j])) {
204+ if (number == account.emergencyNumbers[j]) {
205 return true;
206 }
207 }
208+ // then check using libphonenumber
209+ if (phoneUtils.isEmergencyNumber(number, account.countryCode)) {
210+ return true;
211+ }
212 }
213 return false;
214 }
215@@ -264,9 +277,12 @@
216
217 animateLiveCall();
218
219- // now try to use one of the connected accounts
220 var account = null;
221- if (telepathyHelper.activeAccounts.length > 0) {
222+ // check if the selected account is active and can make emergency calls
223+ if (mainView.account && mainView.account.active && mainView.account.emergencyCallsAvailable) {
224+ account = mainView.account
225+ } else if (telepathyHelper.activeAccounts.length > 0) {
226+ // now try to use one of the connected accounts
227 account = telepathyHelper.activeAccounts[0];
228 } else {
229 // if no account is active, use any account that can make emergency calls
230@@ -317,7 +333,7 @@
231 return
232 }
233
234- if (multipleAccounts && !telepathyHelper.defaultCallAccount && !settings.dialPadDontAsk && !skipDefaultSimDialog) {
235+ if (multipleAccounts && !telepathyHelper.defaultCallAccount && !dualSimSettings.dialPadDontAsk && !skipDefaultSimDialog) {
236 var properties = {}
237 properties["phoneNumber"] = number
238 properties["accountId"] = mainView.account.accountId
239@@ -359,6 +375,7 @@
240 }
241
242 if (account && account.connected) {
243+ generalSettings.lastCalledPhoneNumber = number
244 callManager.startCall(number, account.accountId);
245 }
246 }
247@@ -409,13 +426,15 @@
248 }
249 }
250
251- function switchToLiveCall() {
252+ function switchToLiveCall(initialStatus, initialNumber) {
253 if (pageStackNormalMode.depth > 2 && pageStackNormalMode.currentPage.objectName == "contactsPage") {
254 // pop contacts Page
255 pageStackNormalMode.pop();
256 }
257
258 var properties = {}
259+ properties["initialStatus"] = initialStatus
260+ properties["initialNumber"] = initialNumber
261 if (isEmergencyNumber(pendingNumberToDial)) {
262 properties["defaultTimeout"] = 30000
263 }
264
265=== modified file 'tests/qml/CMakeLists.txt'
266--- tests/qml/CMakeLists.txt 2015-05-21 18:52:21 +0000
267+++ tests/qml/CMakeLists.txt 2015-08-07 21:34:02 +0000
268@@ -15,21 +15,12 @@
269 )
270 endmacro()
271
272-macro(DECLARE_QML_DBUS_TEST TST_NAME TST_QML_FILE)
273- add_test(NAME ${TST_NAME}
274- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
275- COMMAND ${XVFB_RUN_BIN} -a -s "-screen 0 1024x768x24" dbus-test-runner --task /usr/bin/history-daemon --ignore-return --task /usr/bin/telephony-service-handler --ignore-return --task=${QMLTESTRUNNER_BIN} --parameter=-v1 --parameter=-o --parameter=-,txt --parameter=-o --parameter=${CMAKE_BINARY_DIR}/test_${TST_NAME}.xml,xunitxml --parameter=-import --parameter=${qml_BINARY_DIR} --parameter=-input --parameter=${CMAKE_CURRENT_SOURCE_DIR}/${TST_QML_FILE}
276- )
277- set_tests_properties(${TST_NAME} PROPERTIES ENVIRONMENT "QT_QPA_FONTDIR=${CMAKE_BINARY_DIR}")
278-endmacro()
279-
280 if(QMLTESTRUNNER_BIN AND XVFB_RUN_BIN)
281 declare_qml_test("keypad_button" tst_KeypadButton.qml)
282 declare_qml_test("main_view" tst_MainView.qml)
283 declare_qml_test("stopwatch" tst_StopWatch.qml)
284 declare_qml_test("historydelegate" tst_HistoryDelegate.qml)
285-# FIXME currently disabled. There is a bug when registering the telepathy observer
286-# declare_qml_dbus_test("dialer_page" tst_DialerPage.qml)
287+ declare_qml_test("dialer_page" tst_DialerPage.qml)
288 else()
289 if (NOT QMLTESTRUNNER_BIN)
290 message(WARNING "Qml tests disabled: qmltestrunner not found")
291
292=== modified file 'tests/qml/tst_DialerPage.qml'
293--- tests/qml/tst_DialerPage.qml 2015-03-30 20:09:13 +0000
294+++ tests/qml/tst_DialerPage.qml 2015-08-07 21:34:02 +0000
295@@ -19,6 +19,7 @@
296 import QtQuick 2.2
297 import QtTest 1.0
298 import Ubuntu.Test 0.1
299+import Ubuntu.Telephony 0.1
300
301 Item {
302 id: root
303@@ -38,6 +39,43 @@
304 property bool greeterActive: false
305 }
306
307+ QtObject {
308+ id: testAccount
309+ property string accountId: "ofono/ofono/account0"
310+ property var emergencyNumbers: [ "444", "555"]
311+ property int type: AccountEntry.PhoneAccount
312+ property string displayName: "SIM 1"
313+ property bool connected: true
314+ property bool emergencyCallsAvailable: true
315+ property bool active: true
316+ property string networkName: "Network name"
317+ property bool simLocked: false
318+ }
319+
320+ Item {
321+ id: telepathyHelper
322+ function registerChannelObserver() {}
323+ function unregisterChannelObserver() {}
324+ property bool emergencyCallsAvailable: true
325+ property bool flightMode: false
326+ property var activeAccounts: [testAccount]
327+ property alias accounts: telepathyHelper.activeAccounts
328+ }
329+
330+ Item {
331+ id: callManager
332+ signal callStarted
333+ function startCall(phoneNumber, accountId) {
334+ callManager.callStarted(phoneNumber, accountId)
335+ }
336+ }
337+
338+ SignalSpy {
339+ id: callSpy
340+ target: callManager
341+ signalName: "callStarted"
342+ }
343+
344 Loader {
345 id: mainViewLoader
346 property string i18nDirectory: ""
347@@ -57,15 +95,17 @@
348 }
349
350 function test_dialerPageHeaderTitleWhenAppIsInBackground() {
351+ mainViewLoader.item.switchToKeypadView()
352 tryCompare(mainViewLoader.item, 'applicationActive', true)
353 tryCompare(mainViewLoader.item.currentStack, 'depth', 1)
354
355 mainViewLoader.item.telepathyReady = true
356- tryCompare(mainViewLoader.item.currentStack.currentPage, 'title', i18n.tr('No network'))
357+ greeter.greeterActive = false
358+ tryCompare(mainViewLoader.item.currentStack.currentPage, 'title', i18n.tr('Network name'))
359
360 // we should still display the title on regular states
361 mainViewLoader.item.applicationActive = false
362- tryCompare(mainViewLoader.item.currentStack.currentPage, 'title', i18n.tr('No network'))
363+ tryCompare(mainViewLoader.item.currentStack.currentPage, 'title', i18n.tr('Network name'))
364
365 // app must always display "emergency calls" when the greeter is active and app is in foreground
366 mainViewLoader.item.applicationActive = true
367@@ -75,5 +115,88 @@
368 mainViewLoader.item.applicationActive = false
369 tryCompare(mainViewLoader.item.currentStack.currentPage, 'title', ' ')
370 }
371+
372+ function test_dialerPageEmergencyNumbers() {
373+ tryCompare(mainViewLoader.item, 'applicationActive', true)
374+ tryCompare(mainViewLoader.item.currentStack, 'depth', 1)
375+
376+ mainViewLoader.item.telepathyReady = true
377+ mainViewLoader.item.accountReady = true
378+ greeter.greeterActive = false
379+ mainViewLoader.item.switchToKeypadView()
380+
381+ var dialerPage = mainViewLoader.item.currentStack.currentPage
382+ var keypadEntry = findChild(mainViewLoader, "keypadEntry")
383+ var callButton = findChild(mainViewLoader, "callButton")
384+
385+ // regular number when connected
386+ testAccount.connected = true
387+ keypadEntry.value = "123"
388+ callButton.clicked()
389+ compare(callSpy.count, 1)
390+ callSpy.clear()
391+ mainViewLoader.item.switchToKeypadView()
392+
393+ // regular number when disconnected
394+ testAccount.connected = false
395+ keypadEntry.value = "123"
396+ callButton.clicked()
397+ compare(callSpy.count, 0)
398+ callSpy.clear()
399+ mainViewLoader.item.switchToKeypadView()
400+
401+ // regular number in greeter mode
402+ testAccount.connected = true
403+ greeter.greeterActive = true
404+ keypadEntry.value = "123"
405+ callButton.clicked()
406+ compare(callSpy.count, 0)
407+ callSpy.clear()
408+ mainViewLoader.item.switchToKeypadView()
409+
410+ // emergency number in greeter mode when connected
411+ testAccount.connected = true
412+ greeter.greeterActive = true
413+ keypadEntry.value = "444"
414+ callButton.clicked()
415+ compare(callSpy.count, 1)
416+ callSpy.clear()
417+ mainViewLoader.item.switchToKeypadView()
418+
419+ // emergency number in greeter mode when disconnected
420+ testAccount.connected = false
421+ greeter.greeterActive = true
422+ keypadEntry.value = "444"
423+ callButton.clicked()
424+ compare(callSpy.count, 1)
425+ callSpy.clear()
426+ mainViewLoader.item.switchToKeypadView()
427+
428+ // emergency number in flight mode
429+ testAccount.connected = false
430+ telepathyHelper.emergencyCallsAvailable = false
431+ telepathyHelper.flightMode = true
432+ greeter.greeterActive = false
433+ keypadEntry.value = "444"
434+ callButton.clicked()
435+ telepathyHelper.emergencyCallsAvailable = true
436+ wait(15000)
437+ compare(callSpy.count, 1)
438+ callSpy.clear()
439+ mainViewLoader.item.switchToKeypadView()
440+
441+ // emergency number in flight mode and greeter mode
442+ testAccount.connected = false
443+ telepathyHelper.emergencyCallsAvailable = false
444+ telepathyHelper.flightMode = true
445+ greeter.greeterActive = true
446+ keypadEntry.value = "444"
447+ callButton.clicked()
448+ telepathyHelper.emergencyCallsAvailable = true
449+ wait(15000)
450+ compare(callSpy.count, 1)
451+ callSpy.clear()
452+ mainViewLoader.item.switchToKeypadView()
453+ }
454 }
455 }

Subscribers

People subscribed via source and target branches