Merge lp:~boiko/telephony-service/prevent_automatic_answering_calls into lp:telephony-service/rtm-15.04

Proposed by Gustavo Pichorim Boiko
Status: Merged
Approved by: Tiago Salem Herrmann
Approved revision: 1104
Merged at revision: 1096
Proposed branch: lp:~boiko/telephony-service/prevent_automatic_answering_calls
Merge into: lp:telephony-service/rtm-15.04
Prerequisite: lp:~tiagosh/telephony-service/fix-1453004
Diff against target: 780 lines (+376/-31)
23 files modified
.bzrignore (+1/-0)
CMakeLists.txt (+3/-0)
approver/approver.cpp (+17/-3)
approver/approver.h (+1/-0)
cmake/modules/GenerateTest.cmake (+7/-3)
handler/callhandler.cpp (+0/-2)
handler/handler.cpp (+30/-3)
handler/handler.h (+1/-0)
libtelephonyservice/applicationutils.cpp (+9/-7)
libtelephonyservice/telepathyhelper.cpp (+1/-0)
tests/CMakeLists.txt (+1/-0)
tests/approver/ApproverTest.cpp (+107/-0)
tests/approver/CMakeLists.txt (+16/-0)
tests/approver/approvercontroller.cpp (+49/-0)
tests/approver/approvercontroller.h (+41/-0)
tests/common/NotificationsMock.cpp (+10/-2)
tests/common/mock/callchannel.cpp (+11/-1)
tests/handler/HandlerTest.cpp (+50/-7)
tests/handler/approver.cpp (+7/-1)
tests/handler/approver.h (+1/-1)
tests/handler/handlercontroller.cpp (+6/-0)
tests/handler/handlercontroller.h (+1/-0)
tests/libtelephonyservice/CallEntryTest.cpp (+6/-1)
To merge this branch: bzr merge lp:~boiko/telephony-service/prevent_automatic_answering_calls
Reviewer Review Type Date Requested Status
Tiago Salem Herrmann (community) Approve
Review via email: mp+263705@code.launchpad.net

Commit message

Prevent telephony-service from auto-accepting calls in the case of an approver failure.

Description of the change

Prevent telephony-service from auto-accepting calls in the case of an approver failure.

== Checklist ==
Are there any related MPs required for this MP to build/function as expected? Please list.
No

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.
1103. By Gustavo Pichorim Boiko

Disable approver test on arm64.

1104. By Gustavo Pichorim Boiko

Another try at disabling the tests.

Revision history for this message
Tiago Salem Herrmann (tiagosh) wrote :

Looks good.

--Checklist--
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.
CI is not configured for the targeted branch.

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

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2015-05-21 18:02:42 +0000
3+++ .bzrignore 2015-07-03 18:36:10 +0000
4@@ -47,6 +47,7 @@
5
6 tests/*/*Test
7 tests/common/dbus-test-wrapper.sh
8+tests/common/NotificationsMock
9 tests/common/MockConnectionInterface.*
10 tests/common/mock/mockconnectionadaptor.*
11 tests/common/mock/telepathy-mock
12
13=== modified file 'CMakeLists.txt'
14--- CMakeLists.txt 2015-06-10 21:05:50 +0000
15+++ CMakeLists.txt 2015-07-03 18:36:10 +0000
16@@ -12,6 +12,9 @@
17 # Instruct CMake to run moc automatically when needed.
18 set(CMAKE_AUTOMOC ON)
19
20+# just to make debug easier, print the system processor
21+message(STATUS "System processor: ${CMAKE_SYSTEM_PROCESSOR}")
22+
23 # Check if should build using ubuntu platform api
24 check_include_file_cxx("ubuntu/application/init.h" USE_UBUNTU_PLATFORM_API)
25
26
27=== modified file 'approver/approver.cpp'
28--- approver/approver.cpp 2015-07-03 18:36:10 +0000
29+++ approver/approver.cpp 2015-07-03 18:36:10 +0000
30@@ -334,8 +334,8 @@
31 request->setFilter(QContactPhoneNumber::match(contact->id()));
32
33 // lambda function to update the notification
34- QObject::connect(request, &QContactAbstractRequest::stateChanged, [this, request, dispatchOp, channel]() {
35- if (!request || request->state() != QContactAbstractRequest::FinishedState) {
36+ QObject::connect(request, &QContactAbstractRequest::stateChanged, [this, request, dispatchOp, channel](QContactAbstractRequest::State state) {
37+ if (!request || state != QContactAbstractRequest::FinishedState) {
38 return;
39 }
40
41@@ -349,7 +349,6 @@
42 // Also notify greeter via AccountsService
43 GreeterContacts::emitContact(contact);
44 }
45-
46 showSnapDecision(dispatchOp, channel, contact);
47 });
48
49@@ -368,6 +367,8 @@
50 {
51 closeSnapDecision();
52
53+ acceptCallChannels(dispatchOp);
54+
55 // forward the channel to the handler
56 dispatchOp->handleWith(TELEPHONY_SERVICE_HANDLER);
57
58@@ -386,6 +387,8 @@
59 CallManager::instance()->foregroundCall()->endCall();
60 }
61
62+ acceptCallChannels(dispatchOp);
63+
64 // forward the channel to the handler
65 dispatchOp->handleWith(TELEPHONY_SERVICE_HANDLER);
66
67@@ -554,6 +557,17 @@
68 return true;
69 }
70
71+void Approver::acceptCallChannels(const Tp::ChannelDispatchOperationPtr dispatchOp)
72+{
73+ // accept all channels
74+ Q_FOREACH(Tp::ChannelPtr channel, dispatchOp->channels()) {
75+ Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel);
76+ if (callChannel) {
77+ callChannel->accept();
78+ }
79+ }
80+}
81+
82 Tp::ChannelDispatchOperationPtr Approver::dispatchOperationForIncomingCall()
83 {
84 Tp::ChannelDispatchOperationPtr callDispatchOp;
85
86=== modified file 'approver/approver.h'
87--- approver/approver.h 2015-01-20 12:46:29 +0000
88+++ approver/approver.h 2015-07-03 18:36:10 +0000
89@@ -56,6 +56,7 @@
90 bool showSnapDecision(const Tp::ChannelDispatchOperationPtr dispatchOperation,
91 const Tp::ChannelPtr channel,
92 const QContact &contact = QContact());
93+ void acceptCallChannels(const Tp::ChannelDispatchOperationPtr dispatchOp);
94 bool handleMediaKey(bool doubleClick);
95
96 protected:
97
98=== modified file 'cmake/modules/GenerateTest.cmake'
99--- cmake/modules/GenerateTest.cmake 2015-07-03 18:36:10 +0000
100+++ cmake/modules/GenerateTest.cmake 2015-07-03 18:36:10 +0000
101@@ -77,7 +77,8 @@
102 HISTORY_SQLITE_DBPATH=:memory:
103 MC_ACCOUNT_DIR=${TMPDIR}
104 MC_MANAGER_DIR=${TMPDIR}
105- MC_CLIENTS_DIR=${TMPDIR})
106+ MC_CLIENTS_DIR=${TMPDIR}
107+ TELEPHONY_SERVICE_TEST=1)
108 endif ()
109
110 set(TEST_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME} ${PLATFORM} -p -o -p -,txt -p -o -p ${CMAKE_BINARY_DIR}/test_${TESTNAME}.xml,xunitxml)
111@@ -105,7 +106,7 @@
112
113 function(generate_telepathy_test TESTNAME)
114 set(options "")
115- set(oneValueArgs "")
116+ set(oneValueArgs WAIT_FOR)
117 set(multiValueArgs TASKS LIBRARIES QT5_MODULES)
118 cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
119
120@@ -126,10 +127,13 @@
121 if (NOT DEFINED ARG_QT5_MODULES)
122 set(ARG_QT5_MODULES Core DBus Test Qml)
123 endif (NOT DEFINED ARG_QT5_MODULES)
124+ if (NOT DEFINED ARG_WAIT_FOR)
125+ set(ARG_WAIT_FOR org.freedesktop.Telepathy.Client.TelephonyServiceHandler)
126+ endif (NOT DEFINED ARG_WAIT_FOR)
127 generate_test(${TESTNAME} ${ARGN}
128 TASKS ${TASKS}
129 LIBRARIES ${ARG_LIBRARIES}
130 QT5_MODULES ${ARG_QT5_MODULES}
131 USE_DBUS USE_UI
132- WAIT_FOR org.freedesktop.Telepathy.Client.TelephonyServiceHandler)
133+ WAIT_FOR ${ARG_WAIT_FOR})
134 endfunction(generate_telepathy_test)
135
136=== modified file 'handler/callhandler.cpp'
137--- handler/callhandler.cpp 2015-03-04 18:02:13 +0000
138+++ handler/callhandler.cpp 2015-07-03 18:36:10 +0000
139@@ -264,8 +264,6 @@
140
141 void CallHandler::onCallChannelAvailable(Tp::CallChannelPtr channel)
142 {
143- channel->accept();
144-
145 QDBusInterface callChannelIface(channel->busName(), channel->objectPath(), DBUS_PROPERTIES_IFACE);
146 QDBusMessage reply = callChannelIface.call("GetAll", CANONICAL_TELEPHONY_AUDIOOUTPUTS_IFACE);
147 QVariantList args = reply.arguments();
148
149=== modified file 'handler/handler.cpp'
150--- handler/handler.cpp 2015-06-10 21:05:50 +0000
151+++ handler/handler.cpp 2015-07-03 18:36:10 +0000
152@@ -21,6 +21,7 @@
153 */
154
155 #include "handler.h"
156+#include "accountentry.h"
157 #include "protocolmanager.h"
158 #include "telepathyhelper.h"
159
160@@ -60,6 +61,7 @@
161
162
163 Q_FOREACH(const Tp::ChannelPtr channel, channels) {
164+ mContexts[channel.data()] = context;
165 Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel);
166 if (textChannel) {
167 Tp::PendingReady *pr = textChannel->becomeReady(Tp::Features()
168@@ -89,7 +91,6 @@
169 }
170
171 }
172- context->setFinished();
173 }
174
175 Tp::ChannelClassSpecList Handler::channelFilters()
176@@ -121,6 +122,10 @@
177 }
178
179 mReadyRequests.remove(pr);
180+ Tp::MethodInvocationContextPtr<> context = mContexts.take(textChannel.data());
181+ if (context) {
182+ context->setFinished();
183+ }
184
185 Q_EMIT textChannelAvailable(textChannel);
186 }
187@@ -134,15 +139,37 @@
188 return;
189 }
190
191- Tp::ChannelPtr channel = mReadyRequests[pr];
192+ Tp::ChannelPtr channel = mReadyRequests.take(pr);
193 Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel);
194+ Tp::MethodInvocationContextPtr<> context = mContexts.take(channel.data());
195
196 if(!callChannel) {
197+ if (context) {
198+ context->setFinishedWithError(TP_QT_ERROR_CONFUSED, "Channel was not a call channel");
199+ }
200 qCritical() << "The saved channel is not a Tp::CallChannel";
201 return;
202 }
203
204- mReadyRequests.remove(pr);
205+ // if the call is neither Accepted nor Active, it means it got dispatched directly to the handler without passing
206+ // through any approver. For phone calls, this would mean calls getting auto-accepted which is not desirable
207+ // so we return an error here
208+ bool incoming = false;
209+ AccountEntry *accountEntry = TelepathyHelper::instance()->accountForConnection(callChannel->connection());
210+ if (accountEntry) {
211+ incoming = callChannel->initiatorContact() != accountEntry->account()->connection()->selfContact();
212+ }
213+ if (incoming && callChannel->callState() != Tp::CallStateAccepted && callChannel->callState() != Tp::CallStateActive) {
214+ qWarning() << "Available channel was not approved by telephony-service-approver, ignoring it.";
215+ if (context) {
216+ context->setFinishedWithError(TP_QT_ERROR_NOT_CAPABLE, "Only channels approved and accepted by telephony-service-approver are supported");
217+ }
218+ return;
219+ }
220+
221+ if (context) {
222+ context->setFinished();
223+ }
224
225 Q_EMIT callChannelAvailable(callChannel);
226 }
227
228=== modified file 'handler/handler.h'
229--- handler/handler.h 2013-07-18 17:02:10 +0000
230+++ handler/handler.h 2015-07-03 18:36:10 +0000
231@@ -56,6 +56,7 @@
232
233 private:
234 QMap<Tp::PendingReady*, Tp::ChannelPtr> mReadyRequests;
235+ QMap<Tp::Channel*, Tp::MethodInvocationContextPtr<> > mContexts;
236 };
237
238 #endif // HANDLER_H
239
240=== modified file 'libtelephonyservice/applicationutils.cpp'
241--- libtelephonyservice/applicationutils.cpp 2015-05-21 18:02:42 +0000
242+++ libtelephonyservice/applicationutils.cpp 2015-07-03 18:36:10 +0000
243@@ -60,13 +60,15 @@
244 bool ApplicationUtils::openUrl(const QUrl &url)
245 {
246 #ifdef USE_UBUNTU_PLATFORM_API
247- UAUrlDispatcherSession* session = ua_url_dispatcher_session();
248- if (!session)
249- return false;
250-
251- ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL);
252-
253- free(session);
254+ if (qgetenv("TELEPHONY_SERVICE_TEST").isEmpty()) {
255+ UAUrlDispatcherSession* session = ua_url_dispatcher_session();
256+ if (!session)
257+ return false;
258+
259+ ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL);
260+
261+ free(session);
262+ }
263 #endif
264 return true;
265 }
266
267=== modified file 'libtelephonyservice/telepathyhelper.cpp'
268--- libtelephonyservice/telepathyhelper.cpp 2015-06-11 16:48:18 +0000
269+++ libtelephonyservice/telepathyhelper.cpp 2015-07-03 18:36:10 +0000
270@@ -466,6 +466,7 @@
271 }
272
273 if (mAccounts.count() == 0) {
274+ mFirstTime = false;
275 Q_EMIT setupReady();
276 return;
277 }
278
279=== modified file 'tests/CMakeLists.txt'
280--- tests/CMakeLists.txt 2015-05-21 18:02:42 +0000
281+++ tests/CMakeLists.txt 2015-07-03 18:36:10 +0000
282@@ -1,6 +1,7 @@
283 include (GenerateTest)
284
285 add_subdirectory(common)
286+add_subdirectory(approver)
287 add_subdirectory(handler)
288 add_subdirectory(indicator)
289 add_subdirectory(libtelephonyservice)
290
291=== added directory 'tests/approver'
292=== added file 'tests/approver/ApproverTest.cpp'
293--- tests/approver/ApproverTest.cpp 1970-01-01 00:00:00 +0000
294+++ tests/approver/ApproverTest.cpp 2015-07-03 18:36:10 +0000
295@@ -0,0 +1,107 @@
296+/*
297+ * Copyright (C) 2013-2015 Canonical, Ltd.
298+ *
299+ * This file is part of telephony-service.
300+ *
301+ * telephony-service is free software; you can redistribute it and/or modify
302+ * it under the terms of the GNU General Public License as published by
303+ * the Free Software Foundation; version 3.
304+ *
305+ * telephony-service is distributed in the hope that it will be useful,
306+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
307+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
308+ * GNU General Public License for more details.
309+ *
310+ * You should have received a copy of the GNU General Public License
311+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
312+ */
313+
314+#include <QtCore/QObject>
315+#include <QtTest/QtTest>
316+#include "telepathytest.h"
317+#include "approvercontroller.h"
318+#include "mockcontroller.h"
319+#include "accountentry.h"
320+#include "accountentryfactory.h"
321+#include "telepathyhelper.h"
322+
323+class ApproverTest : public TelepathyTest
324+{
325+ Q_OBJECT
326+
327+private Q_SLOTS:
328+ void initTestCase();
329+ void init();
330+ void cleanup();
331+ void testSnapDecisionTimeout();
332+ void testAcceptCall();
333+
334+private:
335+ void waitForCallActive(const QString &callerId);
336+ MockController *mMockController;
337+ Tp::AccountPtr mTpAccount;
338+};
339+
340+void ApproverTest::initTestCase()
341+{
342+ initialize();
343+
344+ QSignalSpy setupReadySpy(TelepathyHelper::instance(), SIGNAL(setupReady()));
345+ TRY_COMPARE(setupReadySpy.count(), 1);
346+}
347+
348+void ApproverTest::init()
349+{
350+ mTpAccount = addAccount("mock", "mock", "the account");
351+
352+ // and create the mock controller
353+ mMockController = new MockController("mock", this);
354+}
355+
356+void ApproverTest::cleanup()
357+{
358+ doCleanup();
359+ mMockController->deleteLater();
360+}
361+
362+void ApproverTest::testSnapDecisionTimeout()
363+{
364+ QString callerId("12345");
365+ QVariantMap properties;
366+ properties["Caller"] = callerId;
367+ properties["State"] = "incoming";
368+
369+ QDBusInterface notificationsMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications");
370+ QSignalSpy notificationSpy(&notificationsMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int)));
371+ mMockController->placeCall(properties);
372+ TRY_COMPARE(notificationSpy.count(), 1);
373+ QVariantMap hints = notificationSpy.first()[6].toMap();
374+ QVERIFY(hints.contains("x-canonical-snap-decisions-timeout"));
375+ QCOMPARE(hints["x-canonical-snap-decisions-timeout"].toInt(), -1);
376+}
377+
378+void ApproverTest::testAcceptCall()
379+{
380+ QString callerId("7654321");
381+
382+ QVariantMap properties;
383+ properties["Caller"] = callerId;
384+ properties["State"] = "incoming";
385+
386+ QDBusInterface notificationsMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications");
387+ QSignalSpy notificationSpy(&notificationsMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int)));
388+ QString objectPath = mMockController->placeCall(properties);
389+ TRY_COMPARE(notificationSpy.count(), 1);
390+
391+ // at this point we are already sure the approver has the call, as the notification was placed
392+ QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString)));
393+ ApproverController::instance()->acceptCall();
394+ TRY_COMPARE(callStateSpy.count(), 1);
395+ QCOMPARE(callStateSpy.first()[0].toString(), callerId);
396+ QCOMPARE(callStateSpy.first()[1].toString(), objectPath);
397+ QCOMPARE(callStateSpy.first()[2].toString(), QString("accepted"));
398+ mMockController->HangupCall(callerId);
399+}
400+
401+QTEST_MAIN(ApproverTest)
402+#include "ApproverTest.moc"
403
404=== added file 'tests/approver/CMakeLists.txt'
405--- tests/approver/CMakeLists.txt 1970-01-01 00:00:00 +0000
406+++ tests/approver/CMakeLists.txt 2015-07-03 18:36:10 +0000
407@@ -0,0 +1,16 @@
408+include_directories(
409+ ${CMAKE_CURRENT_BINARY_DIR}
410+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
411+ ${CMAKE_SOURCE_DIR}
412+ ${CMAKE_SOURCE_DIR}/libtelephonyservice
413+ ${CMAKE_BINARY_DIR}/tests/common
414+ ${TP_QT5_INCLUDE_DIRS}
415+ ${GSETTINGS_QT_INCLUDE_DIRS}
416+ )
417+
418+if (NOT ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64"))
419+ generate_telepathy_test(ApproverTest
420+ SOURCES ApproverTest.cpp approvercontroller.cpp
421+ TASKS --task ${CMAKE_BINARY_DIR}/approver/telephony-service-approver --task-name telephony-service-approver --wait-for com.canonical.TelephonyServiceHandler --ignore-return
422+ WAIT_FOR org.freedesktop.Telepathy.Client.TelephonyServiceApprover)
423+endif()
424
425=== added file 'tests/approver/approvercontroller.cpp'
426--- tests/approver/approvercontroller.cpp 1970-01-01 00:00:00 +0000
427+++ tests/approver/approvercontroller.cpp 2015-07-03 18:36:10 +0000
428@@ -0,0 +1,49 @@
429+/**
430+ * Copyright (C) 2013-2015 Canonical, Ltd.
431+ *
432+ * This program is free software: you can redistribute it and/or modify it under
433+ * the terms of the GNU General Public License version 3, as published by
434+ * the Free Software Foundation.
435+ *
436+ * This program is distributed in the hope that it will be useful, but WITHOUT
437+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
438+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
439+ * General Public License for more details.
440+ *
441+ * You should have received a copy of the GNU General Public License
442+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
443+ *
444+ * Authors:
445+ * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
446+ */
447+
448+#include <QStringList>
449+#include "approvercontroller.h"
450+#include <QDBusReply>
451+#include <QDebug>
452+
453+#define APPROVER_SERVICE "com.canonical.Approver"
454+#define APPROVER_OBJECT "/com/canonical/Approver"
455+#define APPROVER_INTERFACE "com.canonical.TelephonyServiceApprover"
456+
457+ApproverController *ApproverController::instance()
458+{
459+ static ApproverController *self = new ApproverController();
460+ return self;
461+}
462+
463+ApproverController::ApproverController(QObject *parent) :
464+ QObject(parent),
465+ mApproverInterface(APPROVER_SERVICE, APPROVER_OBJECT, APPROVER_INTERFACE)
466+{
467+}
468+
469+void ApproverController::acceptCall()
470+{
471+ mApproverInterface.call("AcceptCall");
472+}
473+
474+void ApproverController::hangUpAndAcceptCall()
475+{
476+ mApproverInterface.call("HangUpAndAcceptCall");
477+}
478
479=== added file 'tests/approver/approvercontroller.h'
480--- tests/approver/approvercontroller.h 1970-01-01 00:00:00 +0000
481+++ tests/approver/approvercontroller.h 2015-07-03 18:36:10 +0000
482@@ -0,0 +1,41 @@
483+/**
484+ * Copyright (C) 2013-2015 Canonical, Ltd.
485+ *
486+ * This program is free software: you can redistribute it and/or modify it under
487+ * the terms of the GNU General Public License version 3, as published by
488+ * the Free Software Foundation.
489+ *
490+ * This program is distributed in the hope that it will be useful, but WITHOUT
491+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
492+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
493+ * General Public License for more details.
494+ *
495+ * You should have received a copy of the GNU General Public License
496+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
497+ *
498+ * Authors:
499+ * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
500+ */
501+
502+#ifndef APPROVERCONTROLLER_H
503+#define APPROVERCONTROLLER_H
504+
505+#include <QObject>
506+#include <QDBusInterface>
507+
508+class ApproverController : public QObject
509+{
510+ Q_OBJECT
511+public:
512+ static ApproverController *instance();
513+
514+public Q_SLOTS:
515+ void acceptCall();
516+ void hangUpAndAcceptCall();
517+
518+private:
519+ explicit ApproverController(QObject *parent = 0);
520+ QDBusInterface mApproverInterface;
521+};
522+
523+#endif // ApproverController_H
524
525=== modified file 'tests/common/NotificationsMock.cpp'
526--- tests/common/NotificationsMock.cpp 2015-07-03 18:36:10 +0000
527+++ tests/common/NotificationsMock.cpp 2015-07-03 18:36:10 +0000
528@@ -32,8 +32,9 @@
529 Q_CLASSINFO("D-Bus Interface", NOTIFICATIONS_DBUS_SERVICE_NAME)
530
531 public:
532- Q_SCRIPTABLE void Notify(QString app_name, uint replaces_id, QString app_icon, QString summary, QString body, QStringList actions, QVariantMap hints, int expire_timeout);
533+ Q_SCRIPTABLE uint Notify(QString app_name, uint replaces_id, QString app_icon, QString summary, QString body, QStringList actions, QVariantMap hints, int expire_timeout);
534 Q_SCRIPTABLE void CloseNotification(uint id);
535+ Q_SCRIPTABLE QString GetServerInformation(QString& vendor, QString& version, QString& spec_version);
536
537 // Mock specific method
538 Q_SCRIPTABLE void MockInvokeAction(uint id, QString action_key);
539@@ -46,9 +47,11 @@
540 Q_SCRIPTABLE void MockNotificationReceived(QString app_name, uint replaces_id, QString app_icon, QString summary, QString body, QStringList actions, QVariantMap hints, int expire_timeout);
541 };
542
543-void NotificationsMock::Notify(QString app_name, uint replaces_id, QString app_icon, QString summary, QString body, QStringList actions, QVariantMap hints, int expire_timeout)
544+uint NotificationsMock::Notify(QString app_name, uint replaces_id, QString app_icon, QString summary, QString body, QStringList actions, QVariantMap hints, int expire_timeout)
545 {
546 Q_EMIT MockNotificationReceived(app_name, replaces_id, app_icon, summary, body, actions, hints, expire_timeout);
547+ static uint id = 1;
548+ return (replaces_id != 0 ? replaces_id : id++);
549 }
550
551 void NotificationsMock::MockInvokeAction(uint id, QString action_key)
552@@ -62,6 +65,11 @@
553 Q_EMIT NotificationClosed(id, 3); // 3 is closed by a CloseNotification() call
554 }
555
556+QString NotificationsMock::GetServerInformation(QString &vendor, QString &version, QString &spec_version)
557+{
558+ return QString();
559+}
560+
561 int main(int argc, char **argv)
562 {
563 QCoreApplication a(argc, argv);
564
565=== modified file 'tests/common/mock/callchannel.cpp'
566--- tests/common/mock/callchannel.cpp 2015-03-23 19:59:50 +0000
567+++ tests/common/mock/callchannel.cpp 2015-07-03 18:36:10 +0000
568@@ -68,7 +68,15 @@
569
570 void MockCallChannel::onAccept(Tp::DBusError*)
571 {
572- setCallState("active");
573+ setCallState("accepted");
574+ QTimer *timer = new QTimer(this);
575+ timer->setSingleShot(true);
576+ timer->setInterval(100);
577+ connect(timer, &QTimer::timeout, [this, timer]() {
578+ setCallState("active");
579+ timer->deleteLater();
580+ });
581+ timer->start();
582 }
583
584 void MockCallChannel::init()
585@@ -195,6 +203,8 @@
586 }
587 mCallChannel->setCallState(Tp::CallStateEnded, 0, reason, stateDetails);
588 mBaseChannel->close();
589+ } else if (state == "accepted") {
590+ mCallChannel->setCallState(Tp::CallStateAccepted, 0, reason, stateDetails);
591 } else if (state == "active") {
592 qDebug() << "active";
593 mHoldIface->setHoldState(Tp::LocalHoldStateUnheld, Tp::LocalHoldStateReasonNone);
594
595=== modified file 'tests/handler/HandlerTest.cpp'
596--- tests/handler/HandlerTest.cpp 2015-05-07 16:44:43 +0000
597+++ tests/handler/HandlerTest.cpp 2015-07-03 18:36:10 +0000
598@@ -41,8 +41,11 @@
599 void testConferenceCall();
600 void testSendMessage();
601 void testActiveCallIndicator();
602+ void testNotApprovedChannels();
603
604 private:
605+ void registerApprover();
606+ void unregisterApprover();
607 void waitForCallActive(const QString &callerId);
608 Approver *mApprover;
609 MockController *mMockController;
610@@ -56,11 +59,7 @@
611 QSignalSpy setupReadySpy(TelepathyHelper::instance(), SIGNAL(setupReady()));
612 TRY_COMPARE(setupReadySpy.count(), 1);
613
614- // register the approver
615- mApprover = new Approver(this);
616- TelepathyHelper::instance()->registerClient(mApprover, "TelephonyTestApprover");
617- // Tp-qt does not set registered status to approvers
618- TRY_VERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered(TELEPHONY_SERVICE_APPROVER));
619+ registerApprover();
620 }
621
622 void HandlerTest::init()
623@@ -163,6 +162,8 @@
624 TRY_COMPARE(approverCallSpy.count(), 1);
625 mApprover->acceptCall();
626
627+ waitForCallActive(callerId);
628+
629 // wait until the call properties are changed
630 TRY_VERIFY(handlerCallPropertiesSpy.count() > 0);
631 QString objectPath = handlerCallPropertiesSpy.last()[0].toString();
632@@ -302,21 +303,63 @@
633 QVERIFY(!HandlerController::instance()->callIndicatorVisible());
634 }
635
636+void HandlerTest::testNotApprovedChannels()
637+{
638+ QVariantMap properties;
639+ properties["Caller"] = "123456";
640+ properties["State"] = "incoming";
641+
642+ QSignalSpy approverCallSpy(mApprover, SIGNAL(newCall()));
643+
644+ QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString)));
645+ QString objectPath = mMockController->placeCall(properties);
646+ QVERIFY(!objectPath.isEmpty());
647+
648+ // wait for the channel to hit the approver
649+ TRY_COMPARE(approverCallSpy.count(), 1);
650+
651+ // accept the call but do not call callChannel->accept() on the channel
652+ mApprover->acceptCall(false);
653+
654+ // wait for a few seconds
655+ QTest::qWait(3000);
656+
657+ // no state changes should happen, as the channel was not accepted
658+ QVERIFY(callStateSpy.isEmpty());
659+}
660+
661+void HandlerTest::registerApprover()
662+{
663+ // register the approver
664+ mApprover = new Approver();
665+ QVERIFY(TelepathyHelper::instance()->registerClient(mApprover, "TelephonyTestApprover"));
666+ // Tp-qt does not set registered status to approvers
667+ TRY_VERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered(TELEPHONY_SERVICE_APPROVER));
668+}
669+
670+void HandlerTest::unregisterApprover()
671+{
672+ QVERIFY(TelepathyHelper::instance()->unregisterClient(mApprover));
673+ mApprover->deleteLater();
674+ mApprover = NULL;
675+ TRY_VERIFY(!QDBusConnection::sessionBus().interface()->isServiceRegistered(TELEPHONY_SERVICE_APPROVER));
676+}
677+
678 void HandlerTest::waitForCallActive(const QString &callerId)
679 {
680- // wait until the call state is "accepted"
681 QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString)));
682 QString state;
683 QString objectPath;
684 QString caller;
685 int tries = 0;
686- while (state != "active" && caller != callerId && tries < 5) {
687+ while ((state != "active" || caller != callerId) && tries < 5) {
688 TRY_COMPARE(callStateSpy.count(), 1);
689 caller = callStateSpy.first()[0].toString();
690 objectPath = callStateSpy.first()[1].toString();
691 state = callStateSpy.first()[2].toString();
692 callStateSpy.clear();
693 tries++;
694+ qDebug() << "Waiting for call active, try " << tries << " failed.";
695 }
696
697 QCOMPARE(caller, callerId);
698
699=== modified file 'tests/handler/approver.cpp'
700--- tests/handler/approver.cpp 2015-03-23 19:59:50 +0000
701+++ tests/handler/approver.cpp 2015-07-03 18:36:10 +0000
702@@ -107,11 +107,17 @@
703 }
704 }
705
706-void Approver::acceptCall()
707+void Approver::acceptCall(bool callAcceptOnChannel)
708 {
709 Q_FOREACH (Tp::ChannelDispatchOperationPtr dispatchOperation, mDispatchOps) {
710 QList<Tp::ChannelPtr> channels = dispatchOperation->channels();
711 Q_FOREACH (Tp::ChannelPtr channel, channels) {
712+ if (callAcceptOnChannel) {
713+ Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel);
714+ if (callChannel) {
715+ callChannel->accept();
716+ }
717+ }
718 if (dispatchOperation->possibleHandlers().contains(TELEPHONY_SERVICE_HANDLER)) {
719 dispatchOperation->handleWith(TELEPHONY_SERVICE_HANDLER);
720 mDispatchOps.removeAll(dispatchOperation);
721
722=== modified file 'tests/handler/approver.h'
723--- tests/handler/approver.h 2014-01-07 19:53:45 +0000
724+++ tests/handler/approver.h 2015-07-03 18:36:10 +0000
725@@ -44,7 +44,7 @@
726 void newCall();
727
728 public Q_SLOTS:
729- void acceptCall();
730+ void acceptCall(bool callAcceptOnChannel = true);
731 void rejectCall();
732
733 private Q_SLOTS:
734
735=== modified file 'tests/handler/handlercontroller.cpp'
736--- tests/handler/handlercontroller.cpp 2014-06-17 17:46:07 +0000
737+++ tests/handler/handlercontroller.cpp 2015-07-03 18:36:10 +0000
738@@ -99,6 +99,12 @@
739 mHandlerInterface.call("SendDTMF", objectPath, key);
740 }
741
742+bool HandlerController::hasCalls()
743+{
744+ QDBusReply<bool> reply = mHandlerInterface.call("HasCalls");
745+ return reply.isValid() && reply.value();
746+}
747+
748 void HandlerController::createConferenceCall(const QStringList &objectPaths)
749 {
750 mHandlerInterface.call("CreateConferenceCall", objectPaths);
751
752=== modified file 'tests/handler/handlercontroller.h'
753--- tests/handler/handlercontroller.h 2014-06-17 17:46:07 +0000
754+++ tests/handler/handlercontroller.h 2015-07-03 18:36:10 +0000
755@@ -40,6 +40,7 @@
756 void setMuted(const QString &objectPath, bool muted);
757 void setSpeakerMode(const QString &objectPath, bool enabled);
758 void sendDTMF(const QString &objectPath, const QString &key);
759+ bool hasCalls();
760
761 // conference call methods
762 void createConferenceCall(const QStringList &objectPaths);
763
764=== modified file 'tests/libtelephonyservice/CallEntryTest.cpp'
765--- tests/libtelephonyservice/CallEntryTest.cpp 2015-05-08 21:57:06 +0000
766+++ tests/libtelephonyservice/CallEntryTest.cpp 2015-07-03 18:36:10 +0000
767@@ -122,7 +122,12 @@
768
769 void CallEntryTest::onCallChannelAvailable(const Tp::CallChannelPtr &channel)
770 {
771- mCallChannel = channel;
772+ channel->accept();
773+ connect(channel->becomeReady(Tp::Features() << Tp::CallChannel::FeatureCore
774+ << Tp::CallChannel::FeatureCallState),
775+ &Tp::PendingOperation::finished, [this, channel] {
776+ mCallChannel = channel;
777+ });
778 }
779
780 QTEST_MAIN(CallEntryTest)

Subscribers

People subscribed via source and target branches