2
* Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
17
* Tiago Salem Herrmann <tiago.herrmann@canonical.com>
18
* Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
21
#include "conferencecallchannel.h"
22
#include "callchannel.h"
25
MockConferenceCallChannel::MockConferenceCallChannel(MockConnection *conn, QList<QDBusObjectPath> callChannels, QObject *parent):
26
mRequestedHangup(false),
29
mCallChannels(callChannels)
32
Q_FOREACH(MockCallChannel *channel, mConnection->callChannels().values()) {
33
if (channel->callState() == Tp::CallStateActive) {
34
QDBusObjectPath path(channel->baseChannel()->objectPath());
35
mCallChannels << path;
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(),
42
Tp::StreamTransportTypeUnknown,
45
baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(callType));
47
mHoldIface = Tp::BaseChannelHoldInterface::create();
48
mHoldIface->setSetHoldStateCallback(Tp::memFun(this,&MockConferenceCallChannel::onHoldStateChanged));
50
mMuteIface = Tp::BaseCallMuteInterface::create();
51
mMuteIface->setSetMuteStateCallback(Tp::memFun(this,&MockConferenceCallChannel::onMuteStateChanged));
53
mSpeakerIface = BaseChannelSpeakerInterface::create();
54
mSpeakerIface->setTurnOnSpeakerCallback(Tp::memFun(this,&MockConferenceCallChannel::onTurnOnSpeaker));
56
mConferenceIface = Tp::BaseChannelConferenceInterface::create(mCallChannels);
58
mMergeableIface = Tp::BaseChannelMergeableConferenceInterface::create();
59
mMergeableIface->setMergeCallback(Tp::memFun(this,&MockConferenceCallChannel::onMerge));
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));
67
mBaseChannel = baseChannel;
68
mCallChannel = Tp::BaseChannelCallTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_CALL));
70
mCallChannel->setHangupCallback(Tp::memFun(this,&MockConferenceCallChannel::onHangup));
72
Tp::CallStateReason reason;
73
QVariantMap stateDetails;
75
reason.reason = Tp::CallStateChangeReasonUserRequested;
77
reason.DBusReason = "";
79
mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails);
81
QObject::connect(mConnection, SIGNAL(channelSplitted(QDBusObjectPath)), SLOT(onChannelSplitted(QDBusObjectPath)));
83
// init must be called after initialization, otherwise we will have no object path registered.
84
QTimer::singleShot(0, this, SLOT(init()));
87
Tp::BaseChannelPtr MockConferenceCallChannel::baseChannel()
92
void MockConferenceCallChannel::onMerge(const QDBusObjectPath &channel, Tp::DBusError *error)
94
if (!mCallChannels.contains(channel)) {
95
mCallChannels << channel;
96
mConferenceIface->mergeChannel(channel, 0, QVariantMap());
97
Q_EMIT channelMerged(channel.path());
101
void MockConferenceCallChannel::onChannelSplitted(const QDBusObjectPath &path)
103
if (mCallChannels.contains(path)) {
104
mCallChannels.removeAll(path);
105
mConferenceIface->removeChannel(path, QVariantMap());
107
if (mCallChannels.size() == 1) {
108
// remove the call channel from the conference before closing it.
109
mConferenceIface->removeChannel(mCallChannels.takeFirst(), QVariantMap());
111
Tp::CallStateReason reason;
112
QVariantMap stateDetails;
114
reason.reason = Tp::CallStateChangeReasonUserRequested;
116
reason.DBusReason = "";
118
mCallChannel->setCallState(Tp::CallStateEnded, 0, reason, stateDetails);
119
mBaseChannel->close();
123
void MockConferenceCallChannel::onTurnOnSpeaker(bool active, Tp::DBusError *error)
125
//mConnection->setSpeakerMode(active);
126
// FIXME: reimplement
129
void MockConferenceCallChannel::onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError *error)
132
Tp::CallStateReason theReason;
133
QVariantMap stateDetails;
135
theReason.reason = reason;
136
theReason.message = message;
137
theReason.DBusReason = "";
139
mCallChannel->setCallState(Tp::CallStateEnded, 0, theReason, stateDetails);
140
mBaseChannel->close();
143
void MockConferenceCallChannel::init()
145
QVariantMap stateDetails;
146
Tp::CallStateReason reason;
148
mObjPath = mBaseChannel->objectPath();
151
reason.reason = Tp::CallStateChangeReasonProgressMade;
153
reason.DBusReason = "";
155
mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails);
157
mDTMFIface = Tp::BaseCallContentDTMFInterface::create();
159
mDTMFIface->setStartToneCallback(Tp::memFun(this,&MockConferenceCallChannel::onDTMFStartTone));
160
mDTMFIface->setStopToneCallback(Tp::memFun(this,&MockConferenceCallChannel::onDTMFStopTone));
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)));
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&)));
171
Q_EMIT initialized();
174
void MockConferenceCallChannel::onOfonoMuteChanged(bool mute)
176
Tp::LocalMuteState state = mute ? Tp::LocalMuteStateMuted : Tp::LocalMuteStateUnmuted;
177
mMuteIface->setMuteState(state);
180
void MockConferenceCallChannel::setConferenceActive(bool active)
183
mHoldIface->setHoldState(Tp::LocalHoldStateUnheld, Tp::LocalHoldStateReasonNone);
185
mHoldIface->setHoldState(Tp::LocalHoldStateHeld, Tp::LocalHoldStateReasonNone);
189
void MockConferenceCallChannel::onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error)
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();
197
// FIXME: reimplement
200
void MockConferenceCallChannel::onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error)
202
/*if (state == Tp::LocalMuteStateMuted) {
203
mConnection->callVolume()->setMuted(true);
204
} else if (state == Tp::LocalMuteStateUnmuted) {
205
mConnection->callVolume()->setMuted(false);
208
// FIXME: reimplement
211
void MockConferenceCallChannel::sendNextDtmf()
216
if (!mDtmfPendingStrings.isEmpty()) {
218
mConnection->voiceCallManager()->sendTones(mDtmfPendingStrings.front());
220
// FIXME: reimplement
223
void MockConferenceCallChannel::onDtmfComplete(bool success)
227
mDtmfPendingStrings.removeFirst();
228
if (mDtmfPendingStrings.isEmpty()) {
233
QTimer::singleShot(1000, this, SLOT(sendNextDtmf()));
237
void MockConferenceCallChannel::onDTMFStartTone(uchar event, Tp::DBusError *error)
242
} else if (event == 11) {
245
finalString = QString::number(event);
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;
254
mDtmfPendingStrings << finalString;
259
void MockConferenceCallChannel::onDTMFStopTone(Tp::DBusError *error)
263
MockConferenceCallChannel::~MockConferenceCallChannel()
265
qDebug() << "conference call channel closed";
266
// TODO - for some reason the object is not being removed
267
mConnection->dbusConnection().unregisterObject(mObjPath, QDBusConnection::UnregisterTree);