Merge lp:~tiagosh/telephony-service/ussd into lp:telephony-service

Proposed by Tiago Salem Herrmann
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 793
Merged at revision: 797
Proposed branch: lp:~tiagosh/telephony-service/ussd
Merge into: lp:telephony-service
Diff against target: 883 lines (+760/-0)
14 files modified
CMakeLists.txt (+1/-0)
Ubuntu/Telephony/components.cpp (+2/-0)
data/org.freedesktop.Notifications.xml (+47/-0)
indicator/CMakeLists.txt (+14/-0)
indicator/DBusTypes.h (+36/-0)
indicator/main.cpp (+4/-0)
indicator/ussdindicator.cpp (+132/-0)
indicator/ussdindicator.h (+54/-0)
indicator/ussdmenu.cpp (+143/-0)
indicator/ussdmenu.h (+41/-0)
libtelephonyservice/CMakeLists.txt (+1/-0)
libtelephonyservice/telepathyhelper.h (+1/-0)
libtelephonyservice/ussdmanager.cpp (+194/-0)
libtelephonyservice/ussdmanager.h (+90/-0)
To merge this branch: bzr merge lp:~tiagosh/telephony-service/ussd
Reviewer Review Type Date Requested Status
Gustavo Pichorim Boiko (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+213935@code.launchpad.net

Commit message

Add initial USSD support

Description of the change

Add initial USSD support

-----
Are there any related MPs required for this MP to build/function as expected? Please list.
https://code.launchpad.net/~tiagosh/telepathy-ofono/ussd/+merge/213936
https://code.launchpad.net/~tiagosh/dialer-app/ussd/+merge/213934

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/telephony-service) on device or emulator?
Yes

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

If you changed the packaging (debian), did you subscribe a core-dev 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)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (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.
Yes

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

Code 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 'CMakeLists.txt'
2--- CMakeLists.txt 2014-03-11 21:18:38 +0000
3+++ CMakeLists.txt 2014-04-02 22:00:02 +0000
4@@ -74,6 +74,7 @@
5
6 add_definitions(-std=c++11)
7
8+set(DATA_DIR "${CMAKE_SOURCE_DIR}/data")
9 # install assets
10 set(ASSETS_DIR assets)
11 install(DIRECTORY ${ASSETS_DIR} DESTINATION ${TELEPHONY_SERVICE_DIR})
12
13=== modified file 'Ubuntu/Telephony/components.cpp'
14--- Ubuntu/Telephony/components.cpp 2014-01-20 12:57:43 +0000
15+++ Ubuntu/Telephony/components.cpp 2014-04-02 22:00:02 +0000
16@@ -24,6 +24,7 @@
17 #include "telepathyhelper.h"
18 #include "callentry.h"
19 #include "callmanager.h"
20+#include "ussdmanager.h"
21 #include "channelobserver.h"
22 #include "chatmanager.h"
23 #include "contactwatcher.h"
24@@ -53,6 +54,7 @@
25 mRootContext->setContextProperty("telepathyHelper", TelepathyHelper::instance());
26 mRootContext->setContextProperty("chatManager", ChatManager::instance());
27 mRootContext->setContextProperty("callManager", CallManager::instance());
28+ mRootContext->setContextProperty("ussdManager", USSDManager::instance());
29
30 }
31
32
33=== added directory 'data'
34=== added file 'data/org.freedesktop.Notifications.xml'
35--- data/org.freedesktop.Notifications.xml 1970-01-01 00:00:00 +0000
36+++ data/org.freedesktop.Notifications.xml 2014-04-02 22:00:02 +0000
37@@ -0,0 +1,47 @@
38+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
39+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
40+<node>
41+ <interface name="org.freedesktop.Notifications">
42+ <signal name="NotificationClosed">
43+ <arg name="id" type="u" direction="out"/>
44+ <arg name="reason" type="u" direction="out"/>
45+ </signal>
46+ <signal name="ActionInvoked">
47+ <arg name="id" type="u" direction="out"/>
48+ <arg name="action_key" type="s" direction="out"/>
49+ </signal>
50+ <signal name="dataChanged">
51+ <arg name="id" type="u" direction="out"/>
52+ </signal>
53+ <method name="CloseNotification">
54+ <arg name="id" type="u" direction="in"/>
55+ </method>
56+ <method name="GetServerInformation">
57+ <arg name="name" type="s" direction="out"/>
58+ <arg name="vendor" type="s" direction="out"/>
59+ <arg name="version" type="s" direction="out"/>
60+ <arg name="specVersion" type="s" direction="out"/>
61+ </method>
62+ <method name="GetCapabilities">
63+ <arg type="as" direction="out"/>
64+ </method>
65+ <method name="Notify">
66+ <arg type="u" direction="out"/>
67+ <arg name="app_name" type="s" direction="in"/>
68+ <arg name="replaces_id" type="u" direction="in"/>
69+ <arg name="app_icon" type="s" direction="in"/>
70+ <arg name="summary" type="s" direction="in"/>
71+ <arg name="body" type="s" direction="in"/>
72+ <arg name="actions" type="as" direction="in"/>
73+ <arg name="hints" type="a{sv}" direction="in"/>
74+ <annotation name="org.qtproject.QtDBus.QtTypeName.In6" value="QVariantMap"/>
75+ <arg name="expire_timeout" type="i" direction="in"/>
76+ </method>
77+ <method name="onDataChanged">
78+ <arg name="id" type="u" direction="in"/>
79+ </method>
80+ <method name="onCompleted">
81+ <arg name="id" type="u" direction="in"/>
82+ </method>
83+ </interface>
84+</node>
85
86=== modified file 'indicator/CMakeLists.txt'
87--- indicator/CMakeLists.txt 2014-01-13 12:10:12 +0000
88+++ indicator/CMakeLists.txt 2014-04-02 22:00:02 +0000
89@@ -4,9 +4,23 @@
90 messagingmenu.cpp
91 metrics.cpp
92 textchannelobserver.cpp
93+ ussdindicator.cpp
94+ ussdmenu.cpp
95 voicemailindicator.cpp
96 )
97
98+set_source_files_properties(
99+ "${DATA_DIR}/org.freedesktop.Notifications.xml"
100+ PROPERTIES
101+ INCLUDE "${CMAKE_SOURCE_DIR}/indicator/DBusTypes.h"
102+)
103+
104+qt5_add_dbus_interface(
105+ qt_SRCS
106+ "${DATA_DIR}/org.freedesktop.Notifications.xml"
107+ NotificationsInterface
108+)
109+
110 set(indicator_SRCS main.cpp ${qt_SRCS})
111
112 include_directories(
113
114=== added file 'indicator/DBusTypes.h'
115--- indicator/DBusTypes.h 1970-01-01 00:00:00 +0000
116+++ indicator/DBusTypes.h 2014-04-02 22:00:02 +0000
117@@ -0,0 +1,36 @@
118+/*
119+ * Copyright (C) 2013 Canonical, Ltd.
120+ *
121+ * This program is free software: you can redistribute it and/or modify it
122+ * under the terms of the GNU General Public License version 3, as published
123+ * by the Free Software Foundation.
124+ *
125+ * This program is distributed in the hope that it will be useful, but
126+ * WITHOUT ANY WARRANTY; without even the implied warranties of
127+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
128+ * PURPOSE. See the GNU General Public License for more details.
129+ *
130+ * You should have received a copy of the GNU General Public License along
131+ * with this program. If not, see <http://www.gnu.org/licenses/>.
132+ *
133+ * Author: Pete Woods <pete.woods@canonical.com>
134+ */
135+
136+#ifndef DBUSTYPES_H_
137+#define DBUSTYPES_H_
138+
139+#include <QDBusMetaType>
140+#include <QMap>
141+
142+typedef QMap<QString, QVariantMap> QVariantDictMap;
143+Q_DECLARE_METATYPE(QVariantDictMap)
144+
145+class DBusTypes {
146+public:
147+ static void registerMetaTypes() {
148+ qRegisterMetaType<QVariantDictMap>("QVariantDictMap");
149+ qDBusRegisterMetaType<QVariantDictMap>();
150+ }
151+};
152+
153+#endif /* DBUSTYPES_H_ */
154
155=== modified file 'indicator/main.cpp'
156--- indicator/main.cpp 2013-09-25 21:18:46 +0000
157+++ indicator/main.cpp 2014-04-02 22:00:02 +0000
158@@ -28,6 +28,7 @@
159 #include "telepathyhelper.h"
160 #include "textchannelobserver.h"
161 #include "voicemailindicator.h"
162+#include "ussdindicator.h"
163 #include <QCoreApplication>
164 #include <TelepathyQt/ClientRegistrar>
165 #include <TelepathyQt/AbstractClient>
166@@ -70,6 +71,9 @@
167 VoiceMailIndicator voiceMailIndicator;
168 Q_UNUSED(voiceMailIndicator);
169
170+ USSDIndicator ussdIndicator;
171+ Q_UNUSED(ussdIndicator);
172+
173 // instanciate the metrics helper
174 Metrics::instance();
175
176
177=== added file 'indicator/ussdindicator.cpp'
178--- indicator/ussdindicator.cpp 1970-01-01 00:00:00 +0000
179+++ indicator/ussdindicator.cpp 2014-04-02 22:00:02 +0000
180@@ -0,0 +1,132 @@
181+/*
182+ * Copyright (C) 2014 Canonical, Ltd.
183+ *
184+ * Authors:
185+ * Tiago Salem Herrmann <tiago.herrmann@canonical.com>
186+ *
187+ * This file is part of telephony-service.
188+ *
189+ * telephony-service is free software; you can redistribute it and/or modify
190+ * it under the terms of the GNU General Public License as published by
191+ * the Free Software Foundation; version 3.
192+ *
193+ * telephony-service is distributed in the hope that it will be useful,
194+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
195+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
196+ * GNU General Public License for more details.
197+ *
198+ * You should have received a copy of the GNU General Public License
199+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
200+ */
201+
202+namespace C {
203+#include <libintl.h>
204+}
205+
206+#include <QDebug>
207+#include <libnotify/notify.h>
208+#include "ringtone.h"
209+#include "ussdindicator.h"
210+
211+USSDIndicator::USSDIndicator(QObject *parent)
212+: QObject(parent),
213+ m_menuRequest(true),
214+ m_menuNotification(false),
215+ m_notifications("org.freedesktop.Notifications",
216+ "/org/freedesktop/Notifications", QDBusConnection::sessionBus())
217+{
218+ connect(USSDManager::instance(), SIGNAL(notificationReceived(const QString &)), SLOT(onNotificationReceived(const QString &)));
219+ connect(USSDManager::instance(), SIGNAL(requestReceived(const QString &)), SLOT(onRequestReceived(const QString &)));
220+ connect(USSDManager::instance(), SIGNAL(initiateUSSDComplete(const QString &)), SLOT(onInitiateUSSDComplete(const QString &)));
221+ connect(USSDManager::instance(), SIGNAL(respondComplete(bool, const QString &)), SLOT(onRespondComplete(bool, const QString &)));
222+ connect(USSDManager::instance(), SIGNAL(stateChanged(const QString &)), SLOT(onStateChanged(const QString &)));
223+
224+ connect(&m_notifications, SIGNAL(ActionInvoked(uint, const QString &)), this, SLOT(actionInvoked(uint, const QString &)));
225+ connect(&m_notifications, SIGNAL(NotificationClosed(uint, uint)), this, SLOT(notificationClosed(uint, uint)));
226+}
227+
228+void USSDIndicator::onNotificationReceived(const QString &message)
229+{
230+ showUSSDNotification(message, false);
231+}
232+
233+void USSDIndicator::onRequestReceived(const QString &message)
234+{
235+ showUSSDNotification(message, true);
236+}
237+
238+void USSDIndicator::onInitiateUSSDComplete(const QString &ussdResp)
239+{
240+ showUSSDNotification(ussdResp, (USSDManager::instance()->state() == "user-response"));
241+}
242+
243+void USSDIndicator::onRespondComplete(bool success, const QString &ussdResp)
244+{
245+ if (success) {
246+ showUSSDNotification(ussdResp, (USSDManager::instance()->state() == "user-response"));
247+ }
248+}
249+
250+void USSDIndicator::onStateChanged(const QString &state)
251+{
252+ // TODO: check if we should close notifications when the state is idle
253+}
254+
255+void USSDIndicator::showUSSDNotification(const QString &message, bool replyRequired)
256+{
257+ USSDMenu *menu = replyRequired ? &m_menuRequest : &m_menuNotification;
258+ QString actionId = "ok_id";
259+ QString actionLabel = C::gettext("Ok");
260+ if (replyRequired) {
261+ actionId = "reply_id";
262+ actionLabel = C::gettext("Reply");
263+ }
264+
265+ // indicate to the notification-daemon, that we want to use snap-decisions
266+ QVariantMap notificationHints;
267+ notificationHints["x-canonical-snap-decisions"] = "true";
268+ notificationHints["x-canonical-private-button-tint"] = "true";
269+
270+ QVariantMap menuModelActions;
271+ menuModelActions["notifications"] = menu->actionPath();
272+
273+ QVariantMap menuModelPaths;
274+ menuModelPaths["busName"] = menu->busName();
275+ menuModelPaths["menuPath"] = menu->menuPath();
276+ menuModelPaths["actions"] = menuModelActions;
277+
278+ notificationHints["x-canonical-private-menu-model"] = menuModelPaths;
279+
280+ m_notificationId = m_notifications.Notify("telephony-service-indicator",
281+ 0, "",
282+ "", message,
283+ QStringList() << actionId << actionLabel << "cancel_id"
284+ << C::gettext("Cancel"), notificationHints, 0);
285+
286+
287+ Ringtone::instance()->playIncomingMessageSound();
288+}
289+
290+void USSDIndicator::actionInvoked(uint id, const QString &actionKey)
291+{
292+ if (id != m_notificationId) {
293+ return;
294+ }
295+
296+ m_notificationId = 0;
297+
298+ if (actionKey == "reply_id") {
299+ USSDManager::instance()->respond(m_menuRequest.response(), USSDManager::instance()->activeAccountId());
300+ } else if (actionKey == "cancel_id") {
301+ USSDManager::instance()->cancel(USSDManager::instance()->activeAccountId());
302+ }
303+ m_menuRequest.clearResponse();
304+}
305+
306+void USSDIndicator::notificationClosed(uint id, uint reason) {
307+ if (id != m_notificationId) {
308+ return;
309+ }
310+ m_notifications.CloseNotification(m_notificationId);
311+ m_notificationId = 0;
312+}
313
314=== added file 'indicator/ussdindicator.h'
315--- indicator/ussdindicator.h 1970-01-01 00:00:00 +0000
316+++ indicator/ussdindicator.h 2014-04-02 22:00:02 +0000
317@@ -0,0 +1,54 @@
318+/*
319+ * Copyright (C) 2014 Canonical, Ltd.
320+ *
321+ * Authors:
322+ * Tiago Salem Herrmann <tiago.herrmann@canonical.com>
323+ *
324+ * This file is part of telephony-service.
325+ *
326+ * telephony-service is free software; you can redistribute it and/or modify
327+ * it under the terms of the GNU General Public License as published by
328+ * the Free Software Foundation; version 3.
329+ *
330+ * telephony-service is distributed in the hope that it will be useful,
331+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
332+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
333+ * GNU General Public License for more details.
334+ *
335+ * You should have received a copy of the GNU General Public License
336+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
337+ */
338+
339+#ifndef USSDINDICATOR_H
340+#define USSDINDICATOR_H
341+
342+#include <QDBusInterface>
343+#include <QVariantMap>
344+#include "indicator/NotificationsInterface.h"
345+#include "ussdmanager.h"
346+#include "ussdmenu.h"
347+
348+class USSDIndicator : public QObject
349+{
350+ Q_OBJECT
351+public:
352+ explicit USSDIndicator(QObject *parent = 0);
353+ void showUSSDNotification(const QString &message, bool replyRequired);
354+
355+public Q_SLOTS:
356+ void onNotificationReceived(const QString &message);
357+ void onRequestReceived(const QString &message);
358+ void onInitiateUSSDComplete(const QString &ussdResp);
359+ void onRespondComplete(bool success, const QString &ussdResp);
360+ void onStateChanged(const QString &state);
361+ void actionInvoked(uint id, const QString &actionKey);
362+ void notificationClosed(uint id, uint reason);
363+private:
364+ unsigned int m_notificationId;
365+ USSDMenu m_menuRequest;
366+ USSDMenu m_menuNotification;
367+ QString mPendingMessage;
368+ org::freedesktop::Notifications m_notifications;
369+};
370+
371+#endif // USSDINDICATOR_H
372
373=== added file 'indicator/ussdmenu.cpp'
374--- indicator/ussdmenu.cpp 1970-01-01 00:00:00 +0000
375+++ indicator/ussdmenu.cpp 2014-04-02 22:00:02 +0000
376@@ -0,0 +1,143 @@
377+/*
378+ * Copyright (C) 2013 Canonical, Ltd.
379+ *
380+ * This program is free software: you can redistribute it and/or modify it
381+ * under the terms of the GNU General Public License version 3, as published
382+ * by the Free Software Foundation.
383+ *
384+ * This program is distributed in the hope that it will be useful, but
385+ * WITHOUT ANY WARRANTY; without even the implied warranties of
386+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
387+ * PURPOSE. See the GNU General Public License for more details.
388+ *
389+ * You should have received a copy of the GNU General Public License along
390+ * with this program. If not, see <http://www.gnu.org/licenses/>.
391+ *
392+ * Author: Pete Woods <pete.woods@canonical.com>
393+ * Author: Tiago Salem Herrmann <tiago.herrmann@canonical.com>
394+ */
395+
396+#include "ussdmenu.h"
397+#include <gio/gio.h>
398+
399+#include <QString>
400+#include <QDebug>
401+
402+static const QString USSD_ACTION_PATH("/action/%1");
403+static const QString USSD_MENU_PATH("/menu/%1");
404+
405+class USSDMenuPriv {
406+public:
407+ USSDMenuPriv() :
408+ m_connection(g_bus_get_sync(G_BUS_TYPE_SESSION, NULL,
409+ NULL)), m_exportedActionGroupId(0), m_exportedMenuModelId(0) {
410+ }
411+
412+ ~USSDMenuPriv() {
413+ g_object_unref(m_connection);
414+ }
415+
416+ static void responseChangedCallback(GAction *responseAction,
417+ GVariant *variant, gpointer userData) {
418+ USSDMenuPriv *self(reinterpret_cast<USSDMenuPriv*>(userData));
419+ self->m_response = QString::fromUtf8(g_variant_get_string(variant, 0));
420+ }
421+
422+ GDBusConnection *m_connection;
423+ QString m_busName;
424+ QString m_actionPath;
425+ QString m_menuPath;
426+ unsigned int m_exportedActionGroupId;
427+ unsigned int m_exportedMenuModelId;
428+ QString m_response;
429+};
430+
431+USSDMenu::USSDMenu(bool needsResponse) :
432+ p(new USSDMenuPriv()) {
433+ int exportrev;
434+
435+ p->m_busName = QString::fromUtf8(
436+ g_dbus_connection_get_unique_name(p->m_connection));
437+
438+ // menu
439+ GMenu *menu(g_menu_new());
440+
441+ GMenuItem *ussdItem(g_menu_item_new("", "notifications.ussd"));
442+ if (needsResponse) {
443+ g_menu_item_set_attribute_value(ussdItem, "x-canonical-type",
444+ g_variant_new_string("com.canonical.snapdecision.textfield"));
445+ g_menu_item_set_attribute_value(ussdItem, "x-echo-mode-password",
446+ g_variant_new_boolean(false));
447+ g_menu_append_item(menu, ussdItem);
448+ }
449+
450+ // actions
451+ GActionGroup *actions(G_ACTION_GROUP(g_simple_action_group_new()));
452+ GAction *ussdAction(G_ACTION(
453+ g_simple_action_new_stateful("ussd", G_VARIANT_TYPE_STRING,
454+ g_variant_new_string(""))));
455+
456+ g_signal_connect(G_OBJECT(ussdAction), "change-state",
457+ G_CALLBACK(USSDMenuPriv::responseChangedCallback),
458+ reinterpret_cast<gpointer>(p.data()));
459+
460+ g_action_map_add_action(G_ACTION_MAP(actions), ussdAction);
461+
462+ /* Export the actions group. If we can't get a name, keep trying to
463+ use increasing numbers. There is possible races on fast import/exports.
464+ They're rare, but worth protecting against. */
465+ exportrev = 0;
466+ do {
467+ exportrev++;
468+ p->m_actionPath = USSD_ACTION_PATH.arg(exportrev);
469+ p->m_exportedActionGroupId = g_dbus_connection_export_action_group(
470+ p->m_connection, p->m_actionPath.toUtf8().data(), actions, NULL);
471+ } while (p->m_exportedActionGroupId == 0 && exportrev < 128);
472+
473+ /* Export the menu. If we can't get a name, keep trying to
474+ use increasing numbers. There is possible races on fast import/exports.
475+ They're rare, but worth protecting against. */
476+ exportrev = 0;
477+ do {
478+ exportrev++;
479+ p->m_menuPath = USSD_MENU_PATH.arg(exportrev);
480+ p->m_exportedMenuModelId = g_dbus_connection_export_menu_model(
481+ p->m_connection, p->m_menuPath.toUtf8().data(),
482+ G_MENU_MODEL(menu), NULL);
483+ } while (p->m_exportedMenuModelId == 0 && exportrev < 128);
484+
485+ /* Unref the objects as a reference is maintained by the fact that they're
486+ exported onto the bus. */
487+ g_object_unref(menu);
488+ g_object_unref(ussdItem);
489+
490+ g_object_unref(actions);
491+ g_object_unref(ussdAction);
492+}
493+
494+USSDMenu::~USSDMenu() {
495+ g_dbus_connection_unexport_action_group(p->m_connection,
496+ p->m_exportedActionGroupId);
497+ g_dbus_connection_unexport_menu_model(p->m_connection,
498+ p->m_exportedMenuModelId);
499+}
500+
501+const QString & USSDMenu::busName() const {
502+ return p->m_busName;
503+}
504+
505+const QString & USSDMenu::response() const {
506+ return p->m_response;
507+}
508+
509+const QString & USSDMenu::actionPath() const {
510+ return p->m_actionPath;
511+}
512+
513+const QString & USSDMenu::menuPath() const {
514+ return p->m_menuPath;
515+}
516+
517+void USSDMenu::clearResponse() {
518+ p->m_response.clear();
519+}
520
521=== added file 'indicator/ussdmenu.h'
522--- indicator/ussdmenu.h 1970-01-01 00:00:00 +0000
523+++ indicator/ussdmenu.h 2014-04-02 22:00:02 +0000
524@@ -0,0 +1,41 @@
525+/*
526+ * Copyright (C) 2013 Canonical, Ltd.
527+ *
528+ * This program is free software: you can redistribute it and/or modify it
529+ * under the terms of the GNU General Public License version 3, as published
530+ * by the Free Software Foundation.
531+ *
532+ * This program is distributed in the hope that it will be useful, but
533+ * WITHOUT ANY WARRANTY; without even the implied warranties of
534+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
535+ * PURPOSE. See the GNU General Public License for more details.
536+ *
537+ * You should have received a copy of the GNU General Public License along
538+ * with this program. If not, see <http://www.gnu.org/licenses/>.
539+ *
540+ * Author: Pete Woods <pete.woods@canonical.com>
541+ * Author: Tiago Salem Herrmann <tiago.herrmann@canonical.com>
542+ */
543+
544+#ifndef USSDMENU_H_
545+#define USSDMENU_H_
546+
547+#include <QString>
548+#include <QScopedPointer>
549+
550+class USSDMenuPriv;
551+
552+class USSDMenu {
553+public:
554+ USSDMenu(bool needsResponse = false);
555+ virtual ~USSDMenu();
556+ const QString & busName() const;
557+ const QString & response() const;
558+ const QString & actionPath() const;
559+ const QString & menuPath() const;
560+ void clearResponse();
561+protected:
562+ QScopedPointer<USSDMenuPriv> p;
563+};
564+
565+#endif /* USSDMENU_H_ */
566
567=== modified file 'libtelephonyservice/CMakeLists.txt'
568--- libtelephonyservice/CMakeLists.txt 2014-03-11 21:51:57 +0000
569+++ libtelephonyservice/CMakeLists.txt 2014-04-02 22:00:02 +0000
570@@ -10,6 +10,7 @@
571 phoneutils.cpp
572 ringtone.cpp
573 telepathyhelper.cpp
574+ ussdmanager.cpp
575 )
576
577 include_directories(
578
579=== modified file 'libtelephonyservice/telepathyhelper.h'
580--- libtelephonyservice/telepathyhelper.h 2014-03-13 18:07:04 +0000
581+++ libtelephonyservice/telepathyhelper.h 2014-04-02 22:00:02 +0000
582@@ -33,6 +33,7 @@
583
584 #define CANONICAL_TELEPHONY_VOICEMAIL_IFACE "com.canonical.Telephony.Voicemail"
585 #define CANONICAL_TELEPHONY_SPEAKER_IFACE "com.canonical.Telephony.Speaker"
586+#define CANONICAL_TELEPHONY_USSD_IFACE "com.canonical.Telephony.USSD"
587
588 class TelepathyHelper : public QObject
589 {
590
591=== added file 'libtelephonyservice/ussdmanager.cpp'
592--- libtelephonyservice/ussdmanager.cpp 1970-01-01 00:00:00 +0000
593+++ libtelephonyservice/ussdmanager.cpp 2014-04-02 22:00:02 +0000
594@@ -0,0 +1,194 @@
595+/*
596+ * Copyright (C) 2012 Canonical, Ltd.
597+ *
598+ * Authors:
599+ * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
600+ * Tiago Salem Herrmann <tiago.herrmann@canonical.com>
601+ *
602+ * This file is part of telephony-service.
603+ *
604+ * telephony-service is free software; you can redistribute it and/or modify
605+ * it under the terms of the GNU General Public License as published by
606+ * the Free Software Foundation; version 3.
607+ *
608+ * telephony-service is distributed in the hope that it will be useful,
609+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
610+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
611+ * GNU General Public License for more details.
612+ *
613+ * You should have received a copy of the GNU General Public License
614+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
615+ */
616+
617+#include "ussdmanager.h"
618+#include "telepathyhelper.h"
619+
620+#include <TelepathyQt/ContactManager>
621+#include <QDBusInterface>
622+
623+typedef QMap<QString, QVariant> dbusQMap;
624+Q_DECLARE_METATYPE(dbusQMap)
625+
626+USSDManager *USSDManager::instance()
627+{
628+ static USSDManager *self = new USSDManager();
629+ return self;
630+}
631+
632+USSDManager::USSDManager(QObject *parent)
633+: QObject(parent), mActive(false)
634+{
635+ connect(TelepathyHelper::instance(), SIGNAL(connectedChanged()), SLOT(onConnectedChanged()));
636+}
637+
638+void USSDManager::initiate(const QString &command, const QString &accountId)
639+{
640+ Tp::AccountPtr account;
641+ if (accountId.isNull()) {
642+ account = TelepathyHelper::instance()->accounts()[0];
643+ } else {
644+ account = TelepathyHelper::instance()->accountForId(accountId);
645+ }
646+
647+ Tp::ConnectionPtr conn(account->connection());
648+ QString busName = conn->busName();
649+ QString objectPath = conn->objectPath();
650+ QDBusInterface ussdIface(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE);
651+ ussdIface.asyncCall("Initiate", command);
652+}
653+
654+void USSDManager::respond(const QString &reply, const QString &accountId)
655+{
656+ Tp::AccountPtr account;
657+ if (accountId.isNull()) {
658+ account = TelepathyHelper::instance()->accounts()[0];
659+ } else {
660+ account = TelepathyHelper::instance()->accountForId(accountId);
661+ }
662+
663+ Tp::ConnectionPtr conn(account->connection());
664+ QString busName = conn->busName();
665+ QString objectPath = conn->objectPath();
666+ QDBusInterface ussdIface(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE);
667+ ussdIface.asyncCall("Respond", reply);
668+}
669+
670+void USSDManager::cancel(const QString &accountId)
671+{
672+ Tp::AccountPtr account;
673+ if (accountId.isNull()) {
674+ account = TelepathyHelper::instance()->accounts()[0];
675+ } else {
676+ account = TelepathyHelper::instance()->accountForId(accountId);
677+ }
678+
679+ Tp::ConnectionPtr conn(account->connection());
680+ QString busName = conn->busName();
681+ QString objectPath = conn->objectPath();
682+ QDBusInterface ussdIface(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE);
683+ ussdIface.asyncCall("Cancel");
684+}
685+
686+void USSDManager::disconnectAllSignals(const Tp::ConnectionPtr& conn)
687+{
688+ QString busName = conn->busName();
689+ QString objectPath = conn->objectPath();
690+
691+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "StateChanged", this, SLOT(onStateChanged(QString)));
692+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RequestReceived", this, SIGNAL(requestReceived(QString)));
693+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "NotificationReceived", this, SIGNAL(notificationReceived(QString)));
694+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateUSSDComplete", this, SIGNAL(initiateUSSDComplete(QString)));
695+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RespondComplete", this, SIGNAL(respondComplete(bool, QString)));
696+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "BarringComplete", this, SIGNAL(barringComplete(QString, QString, QVariantMap)));
697+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ForwardingComplete", this, SIGNAL(forwardingComplete(QString, QString, QVariantMap)));
698+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "WaitingComplete", this, SIGNAL(waitingComplete(QString, QVariantMap)));
699+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLinePresentationComplete", this, SIGNAL(callingLinePresentationComplete(QString, QString)));
700+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLineRestrictionComplete", this, SIGNAL(callingLineRestrictionComplete(QString, QString)));
701+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLineRestrictionComplete", this, SIGNAL(connectedLineRestrictionComplete(QString, QString)));
702+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLinePresentationComplete", this, SIGNAL(connectedLinePresentationComplete(QString, QString)));
703+ QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateFailed", this, SIGNAL(initiateFailed()));
704+}
705+void USSDManager::connectAllSignals(const Tp::ConnectionPtr& conn)
706+{
707+ QString busName = conn->busName();
708+ QString objectPath = conn->objectPath();
709+
710+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "StateChanged", this, SLOT(onStateChanged(QString)));
711+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RequestReceived", this, SIGNAL(requestReceived(QString)));
712+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "NotificationReceived", this, SIGNAL(notificationReceived(QString)));
713+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateUSSDComplete", this, SIGNAL(initiateUSSDComplete(QString)));
714+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RespondComplete", this, SIGNAL(respondComplete(bool, QString)));
715+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "BarringComplete", this, SIGNAL(barringComplete(QString, QString, QVariantMap)));
716+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ForwardingComplete", this, SIGNAL(forwardingComplete(QString, QString, QVariantMap)));
717+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "WaitingComplete", this, SIGNAL(waitingComplete(QString, QVariantMap)));
718+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLinePresentationComplete", this, SIGNAL(callingLinePresentationComplete(QString, QString)));
719+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLineRestrictionComplete", this, SIGNAL(callingLineRestrictionComplete(QString, QString)));
720+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLineRestrictionComplete", this, SIGNAL(connectedLineRestrictionComplete(QString, QString)));
721+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLinePresentationComplete", this, SIGNAL(connectedLinePresentationComplete(QString, QString)));
722+ QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateFailed", this, SIGNAL(initiateFailed()));
723+}
724+
725+
726+void USSDManager::onConnectedChanged()
727+{
728+ // everytime the connection changes we need to check if there is any ongoing ussd session
729+ mActive = false;
730+ mActiveAccountId = QString::null;
731+ mState = QString("idle");
732+
733+ if (!TelepathyHelper::instance()->connected()) {
734+ Q_EMIT stateChanged(mState);
735+ Q_EMIT activeChanged();
736+ Q_EMIT activeAccountIdChanged();
737+ return;
738+ }
739+
740+ Q_FOREACH (const Tp::AccountPtr &account, TelepathyHelper::instance()->accounts()) {
741+ // disconnect all and reconnect only the online accounts
742+ Tp::ConnectionPtr conn(account->connection());
743+ disconnectAllSignals(conn);
744+
745+ if (TelepathyHelper::instance()->isAccountConnected(account)) {
746+ QString busName = conn->busName();
747+ QString objectPath = conn->objectPath();
748+
749+ connectAllSignals(conn);
750+
751+ QDBusInterface ussdIface(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE);
752+ mState = ussdIface.property("State").toString();
753+ mSerials[account->uniqueIdentifier()] = ussdIface.property("Serial").toString();
754+ if (active()) {
755+ mActiveAccountId = account->uniqueIdentifier();
756+ }
757+ }
758+ }
759+ Q_EMIT stateChanged(mState);
760+ Q_EMIT activeChanged();
761+ Q_EMIT activeAccountIdChanged();
762+}
763+
764+void USSDManager::onStateChanged(const QString &state)
765+{
766+ mState = state;
767+ Q_EMIT stateChanged(state);
768+}
769+
770+bool USSDManager::active() const
771+{
772+ return mState != "idle" && !mState.isEmpty();
773+}
774+
775+QString USSDManager::activeAccountId() const
776+{
777+ return mActiveAccountId;
778+}
779+
780+QString USSDManager::state() const
781+{
782+ return mState;
783+}
784+
785+QString USSDManager::serial(const QString &accountId) const
786+{
787+ return mSerials[accountId];
788+}
789
790=== added file 'libtelephonyservice/ussdmanager.h'
791--- libtelephonyservice/ussdmanager.h 1970-01-01 00:00:00 +0000
792+++ libtelephonyservice/ussdmanager.h 2014-04-02 22:00:02 +0000
793@@ -0,0 +1,90 @@
794+/*
795+ * Copyright (C) 2012-2013 Canonical, Ltd.
796+ *
797+ * Authors:
798+ * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
799+ * Tiago Salem Herrmann <tiago.herrmann@canonical.com>
800+ *
801+ * This file is part of telephony-service.
802+ *
803+ * telephony-service is free software; you can redistribute it and/or modify
804+ * it under the terms of the GNU General Public License as published by
805+ * the Free Software Foundation; version 3.
806+ *
807+ * telephony-service is distributed in the hope that it will be useful,
808+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
809+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
810+ * GNU General Public License for more details.
811+ *
812+ * You should have received a copy of the GNU General Public License
813+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
814+ */
815+
816+#ifndef USSDMANAGER_H
817+#define USSDMANAGER_H
818+
819+#include <QtCore/QMap>
820+#include <QDBusInterface>
821+#include <TelepathyQt/Connection>
822+
823+class TelepathyHelper;
824+
825+class USSDManager : public QObject
826+{
827+ Q_OBJECT
828+ Q_PROPERTY(bool active
829+ READ active
830+ NOTIFY activeChanged)
831+ Q_PROPERTY(QString activeAccountId
832+ READ activeAccountId
833+ NOTIFY activeAccountIdChanged)
834+ Q_PROPERTY(QString state
835+ READ state
836+ NOTIFY stateChanged)
837+public:
838+ static USSDManager *instance();
839+ Q_INVOKABLE void initiate(const QString &command, const QString &accountId = QString::null);
840+ Q_INVOKABLE void respond(const QString &reply, const QString &accountId = QString::null);
841+ Q_INVOKABLE void cancel(const QString &accountId = QString::null);
842+ Q_INVOKABLE QString serial(const QString& accountId) const;
843+
844+ bool active() const;
845+ QString activeAccountId() const;
846+ QString state() const;
847+
848+public Q_SLOTS:
849+ void onConnectedChanged();
850+ void onStateChanged(const QString &state);
851+
852+Q_SIGNALS:
853+ void activeChanged();
854+ void activeAccountIdChanged();
855+ void stateChanged(const QString &state);
856+
857+ void notificationReceived(const QString &message);
858+ void requestReceived(const QString &message);
859+
860+ void initiateUSSDComplete(const QString &ussdResp);
861+ void respondComplete(bool success, const QString &ussdResp);
862+ void barringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap);
863+ void forwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap);
864+ void waitingComplete(const QString &ssOp, const QVariantMap &cwMap);
865+ void callingLinePresentationComplete(const QString &ssOp, const QString &status);
866+ void connectedLinePresentationComplete(const QString &ssOp, const QString &status);
867+ void callingLineRestrictionComplete(const QString &ssOp, const QString &status);
868+ void connectedLineRestrictionComplete(const QString &ssOp, const QString &status);
869+ void initiateFailed();
870+
871+private:
872+ explicit USSDManager(QObject *parent = 0);
873+
874+ void disconnectAllSignals(const Tp::ConnectionPtr& conn);
875+ void connectAllSignals(const Tp::ConnectionPtr& conn);
876+
877+ bool mActive;
878+ QString mActiveAccountId;
879+ QString mState;
880+ QMap<QString, QString> mSerials;
881+};
882+
883+#endif // USSDMANAGER_H

Subscribers

People subscribed via source and target branches