~mterry/telephony-service/start-on

« back to all changes in this revision

Viewing changes to handler/tests/mock/conferencecallchannel.cpp

  • Committer: CI bot
  • Author(s): Gustavo Pichorim Boiko
  • Date: 2014-04-02 12:41:29 UTC
  • mfrom: (765.2.24 telephony-service-conf_call)
  • Revision ID: ps-jenkins@lists.canonical.com-20140402124129-oywt8u6u9f4253bg
Add support for handling conference calls. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Copyright (C) 2013 Canonical, Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it under
 
5
 * the terms of the GNU Lesser General Public License version 3, as published by
 
6
 * the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
 
9
 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
 
10
 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
 * Lesser General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authors:
 
17
 *     Tiago Salem Herrmann <tiago.herrmann@canonical.com>
 
18
 *     Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
 
19
 */
 
20
 
 
21
#include "conferencecallchannel.h"
 
22
#include "callchannel.h"
 
23
 
 
24
 
 
25
MockConferenceCallChannel::MockConferenceCallChannel(MockConnection *conn, QList<QDBusObjectPath> callChannels, QObject *parent):
 
26
    mRequestedHangup(false),
 
27
    mConnection(conn),
 
28
    mDtmfLock(false),
 
29
    mCallChannels(callChannels)
 
30
{
 
31
 
 
32
    Q_FOREACH(MockCallChannel *channel, mConnection->callChannels().values()) {
 
33
        if (channel->callState() == Tp::CallStateActive) {
 
34
            QDBusObjectPath path(channel->baseChannel()->objectPath());
 
35
            mCallChannels << path;
 
36
        }
 
37
    }
 
38
 
 
39
    Tp::BaseChannelPtr baseChannel = Tp::BaseChannel::create(mConnection, TP_QT_IFACE_CHANNEL_TYPE_CALL, 0, Tp::HandleTypeNone);
 
40
    Tp::BaseChannelCallTypePtr callType = Tp::BaseChannelCallType::create(baseChannel.data(),
 
41
                                                                          true,
 
42
                                                                          Tp::StreamTransportTypeUnknown,
 
43
                                                                          true,
 
44
                                                                          false, "","");
 
45
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(callType));
 
46
 
 
47
    mHoldIface = Tp::BaseChannelHoldInterface::create();
 
48
    mHoldIface->setSetHoldStateCallback(Tp::memFun(this,&MockConferenceCallChannel::onHoldStateChanged));
 
49
 
 
50
    mMuteIface = Tp::BaseCallMuteInterface::create();
 
51
    mMuteIface->setSetMuteStateCallback(Tp::memFun(this,&MockConferenceCallChannel::onMuteStateChanged));
 
52
 
 
53
    mSpeakerIface = BaseChannelSpeakerInterface::create();
 
54
    mSpeakerIface->setTurnOnSpeakerCallback(Tp::memFun(this,&MockConferenceCallChannel::onTurnOnSpeaker));
 
55
 
 
56
    mConferenceIface = Tp::BaseChannelConferenceInterface::create(mCallChannels);
 
57
 
 
58
    mMergeableIface = Tp::BaseChannelMergeableConferenceInterface::create();
 
59
    mMergeableIface->setMergeCallback(Tp::memFun(this,&MockConferenceCallChannel::onMerge));
 
60
 
 
61
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mHoldIface));
 
62
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMuteIface));
 
63
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mSpeakerIface));
 
64
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mConferenceIface));
 
65
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMergeableIface));
 
66
 
 
67
    mBaseChannel = baseChannel;
 
68
    mCallChannel = Tp::BaseChannelCallTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_CALL));
 
69
 
 
70
    mCallChannel->setHangupCallback(Tp::memFun(this,&MockConferenceCallChannel::onHangup));
 
71
 
 
72
    Tp::CallStateReason reason;
 
73
    QVariantMap stateDetails;
 
74
    reason.actor =  0;
 
75
    reason.reason = Tp::CallStateChangeReasonUserRequested;
 
76
    reason.message = "";
 
77
    reason.DBusReason = "";
 
78
 
 
79
    mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails);
 
80
 
 
81
    QObject::connect(mConnection, SIGNAL(channelSplitted(QDBusObjectPath)), SLOT(onChannelSplitted(QDBusObjectPath)));
 
82
 
 
83
    // init must be called after initialization, otherwise we will have no object path registered.
 
84
    QTimer::singleShot(0, this, SLOT(init()));
 
85
}
 
86
 
 
87
Tp::BaseChannelPtr MockConferenceCallChannel::baseChannel()
 
88
{
 
89
    return mBaseChannel;
 
90
}
 
91
 
 
92
void MockConferenceCallChannel::onMerge(const QDBusObjectPath &channel, Tp::DBusError *error)
 
93
{
 
94
    if (!mCallChannels.contains(channel)) {
 
95
        mCallChannels << channel;
 
96
        mConferenceIface->mergeChannel(channel, 0, QVariantMap());
 
97
        Q_EMIT channelMerged(channel.path());
 
98
    }
 
99
}
 
100
 
 
101
void MockConferenceCallChannel::onChannelSplitted(const QDBusObjectPath &path)
 
102
{
 
103
    if (mCallChannels.contains(path)) {
 
104
        mCallChannels.removeAll(path);
 
105
        mConferenceIface->removeChannel(path, QVariantMap());
 
106
    }
 
107
    if (mCallChannels.size() == 1) {
 
108
        // remove the call channel from the conference before closing it.
 
109
        mConferenceIface->removeChannel(mCallChannels.takeFirst(), QVariantMap());
 
110
 
 
111
        Tp::CallStateReason reason;
 
112
        QVariantMap stateDetails;
 
113
        reason.actor =  0;
 
114
        reason.reason = Tp::CallStateChangeReasonUserRequested;
 
115
        reason.message = "";
 
116
        reason.DBusReason = "";
 
117
 
 
118
        mCallChannel->setCallState(Tp::CallStateEnded, 0, reason, stateDetails);
 
119
        mBaseChannel->close();
 
120
    }
 
121
}
 
122
 
 
123
void MockConferenceCallChannel::onTurnOnSpeaker(bool active, Tp::DBusError *error)
 
124
{
 
125
    //mConnection->setSpeakerMode(active);
 
126
    // FIXME: reimplement
 
127
}
 
128
 
 
129
void MockConferenceCallChannel::onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError *error)
 
130
{
 
131
    //FIXME: reimplement
 
132
    Tp::CallStateReason theReason;
 
133
    QVariantMap stateDetails;
 
134
    theReason.actor =  0;
 
135
    theReason.reason = reason;
 
136
    theReason.message = message;
 
137
    theReason.DBusReason = "";
 
138
 
 
139
    mCallChannel->setCallState(Tp::CallStateEnded, 0, theReason, stateDetails);
 
140
    mBaseChannel->close();
 
141
}
 
142
 
 
143
void MockConferenceCallChannel::init()
 
144
{
 
145
    QVariantMap stateDetails;
 
146
    Tp::CallStateReason reason;
 
147
 
 
148
    mObjPath = mBaseChannel->objectPath();
 
149
 
 
150
    reason.actor =  0;
 
151
    reason.reason = Tp::CallStateChangeReasonProgressMade;
 
152
    reason.message = "";
 
153
    reason.DBusReason = "";
 
154
 
 
155
    mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails);
 
156
 
 
157
    mDTMFIface = Tp::BaseCallContentDTMFInterface::create();
 
158
 
 
159
    mDTMFIface->setStartToneCallback(Tp::memFun(this,&MockConferenceCallChannel::onDTMFStartTone));
 
160
    mDTMFIface->setStopToneCallback(Tp::memFun(this,&MockConferenceCallChannel::onDTMFStopTone));
 
161
 
 
162
    QObject::connect(mBaseChannel.data(), SIGNAL(closed()), this, SLOT(deleteLater()));
 
163
    //QObject::connect(mConnection->callVolume(), SIGNAL(mutedChanged(bool)), SLOT(onOfonoMuteChanged(bool)));
 
164
    QObject::connect(mConnection, SIGNAL(speakerModeChanged(bool)), mSpeakerIface.data(), SLOT(setSpeakerMode(bool)));
 
165
    //QObject::connect(mConnection->voiceCallManager(), SIGNAL(sendTonesComplete(bool)), SLOT(onDtmfComplete(bool)));
 
166
 
 
167
    //mSpeakerIface->setSpeakerMode(mConnection->speakerMode());
 
168
    QObject::connect(mConnection, SIGNAL(channelSplitted(const QDBusObjectPath&)), this, SLOT(onChannelSplitted(const QDBusObjectPath&)));
 
169
    QObject::connect(mConnection, SIGNAL(channelHangup(const QDBusObjectPath&)), this, SLOT(onChannelSplitted(const QDBusObjectPath&)));
 
170
 
 
171
    Q_EMIT initialized();
 
172
}
 
173
 
 
174
void MockConferenceCallChannel::onOfonoMuteChanged(bool mute)
 
175
{
 
176
    Tp::LocalMuteState state = mute ? Tp::LocalMuteStateMuted : Tp::LocalMuteStateUnmuted;
 
177
    mMuteIface->setMuteState(state);
 
178
}
 
179
 
 
180
void MockConferenceCallChannel::setConferenceActive(bool active)
 
181
{
 
182
    if (active) {
 
183
        mHoldIface->setHoldState(Tp::LocalHoldStateUnheld, Tp::LocalHoldStateReasonNone);
 
184
    } else {
 
185
        mHoldIface->setHoldState(Tp::LocalHoldStateHeld, Tp::LocalHoldStateReasonNone);
 
186
    }
 
187
}
 
188
 
 
189
void MockConferenceCallChannel::onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error)
 
190
{
 
191
    /*if (state == Tp::LocalHoldStateHeld && mHoldIface->getHoldState() == Tp::LocalHoldStateUnheld) {
 
192
        mConnection->voiceCallManager()->swapCalls();
 
193
    } else if (state == Tp::LocalHoldStateUnheld && mHoldIface->getHoldState() == Tp::LocalHoldStateHeld) {
 
194
        mConnection->voiceCallManager()->swapCalls();
 
195
    }*/
 
196
 
 
197
    // FIXME: reimplement
 
198
}
 
199
 
 
200
void MockConferenceCallChannel::onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error)
 
201
{
 
202
    /*if (state == Tp::LocalMuteStateMuted) {
 
203
        mConnection->callVolume()->setMuted(true);
 
204
    } else if (state == Tp::LocalMuteStateUnmuted) {
 
205
        mConnection->callVolume()->setMuted(false);
 
206
    }*/
 
207
 
 
208
    // FIXME: reimplement
 
209
}
 
210
 
 
211
void MockConferenceCallChannel::sendNextDtmf()
 
212
{
 
213
    /*if (mDtmfLock) {
 
214
        return;
 
215
    }
 
216
    if (!mDtmfPendingStrings.isEmpty()) {
 
217
        mDtmfLock = true;
 
218
        mConnection->voiceCallManager()->sendTones(mDtmfPendingStrings.front());
 
219
    }*/
 
220
    // FIXME: reimplement
 
221
}
 
222
 
 
223
void MockConferenceCallChannel::onDtmfComplete(bool success)
 
224
{
 
225
    mDtmfLock = false;
 
226
    if (success) {
 
227
        mDtmfPendingStrings.removeFirst();
 
228
       if (mDtmfPendingStrings.isEmpty()) {
 
229
           return;
 
230
       }
 
231
       sendNextDtmf();
 
232
    } else {
 
233
        QTimer::singleShot(1000, this, SLOT(sendNextDtmf()));
 
234
    }
 
235
}
 
236
 
 
237
void MockConferenceCallChannel::onDTMFStartTone(uchar event, Tp::DBusError *error)
 
238
{
 
239
    QString finalString;
 
240
    if (event == 10) {
 
241
        finalString = "*";
 
242
    } else if (event == 11) {
 
243
        finalString = "#";
 
244
    } else {
 
245
        finalString = QString::number(event);
 
246
    }
 
247
 
 
248
    qDebug() << "start tone" << finalString;
 
249
    // we can't append to the first item in the queue as it is being sent and
 
250
    // we dont know yet if it will succeed or not.
 
251
    if (mDtmfPendingStrings.count() > 1) {
 
252
        mDtmfPendingStrings[1] += finalString;
 
253
    } else {
 
254
        mDtmfPendingStrings << finalString;
 
255
    }
 
256
    sendNextDtmf();
 
257
}
 
258
 
 
259
void MockConferenceCallChannel::onDTMFStopTone(Tp::DBusError *error)
 
260
{
 
261
}
 
262
 
 
263
MockConferenceCallChannel::~MockConferenceCallChannel()
 
264
{
 
265
    qDebug() << "conference call channel closed";
 
266
    // TODO - for some reason the object is not being removed
 
267
    mConnection->dbusConnection().unregisterObject(mObjPath, QDBusConnection::UnregisterTree);
 
268
}