2 * hfdialer - Hands Free Voice Call Manager
3 * Copyright (c) 2012, Intel Corporation.
5 * This program is licensed under the terms and conditions of the
6 * Apache License, version 2.0. The full text of the Apache License is at
7 * http://www.apache.org/licenses/LICENSE-2.0
12 #include "callmanager.h"
14 class CallManagerPrivate
17 //ResourceProxy *resource;
18 QHash<QString, CallItem *> callItems;
21 CallManager::CallManager(const QString &modemPath, QObject *parent)
22 : OfonoVoiceCallManager(OfonoModem::AutomaticSelect, modemPath, parent),
23 d(new CallManagerPrivate)
27 // Transform existing calls list, into list of CallItems
30 // Begin tracking calls
31 connect(this, SIGNAL(callAdded(const QString)),
32 this, SLOT(addCall(const QString)));
33 connect(this, SIGNAL(callRemoved(const QString)),
34 this, SLOT(removeCall(const QString)));
36 // Hook into parent class signals
37 connect(this, SIGNAL(dialComplete(const bool)),
38 this, SLOT(dialFinished(const bool)));
39 connect(this, SIGNAL(swapCallsComplete(const bool)),
40 this, SLOT(swapFinished(const bool)));
41 connect(this, SIGNAL(hangupAllComplete(const bool)),
42 this, SLOT(hangupAllFinished(const bool)));
43 connect(this, SIGNAL(sendTonesComplete(const bool)),
44 this, SLOT(sendTonesFinished(const bool)));
45 connect(this, SIGNAL(holdAndAnswerComplete(const bool)),
46 this, SLOT(holdAndAnswerFinished(const bool)));
47 connect(this, SIGNAL(transferComplete(const bool)),
48 this, SLOT(transferFinished(const bool)));
49 connect(this, SIGNAL(releaseAndAnswerComplete(const bool)),
50 this, SLOT(releaseAndAnswerFinished(const bool)));
51 connect(this, SIGNAL(privateChatComplete(const bool)),
52 this, SLOT(privateChatFinished(const bool)));
53 connect(this, SIGNAL(createMultipartyComplete(const bool)),
54 this, SLOT(createMultipartyFinished(const bool)));
55 connect(this, SIGNAL(hangupMultipartyComplete(const bool)),
56 this, SLOT(hangupMultipartyFinished(const bool)));
58 connect(this,SIGNAL(callsChanged()),this,SLOT(callChangedSlot()));
60 connect(this, SIGNAL(validityChanged(bool)), this, SLOT(modemValidityChanged(bool)) );
66 CallManager::~CallManager()
69 // FIXME: Do something here!!!
70 qDebug() << QString("Destroying VoiceCallManager");
71 qDebug() << QString("Purging all CallItems");
72 foreach (CallItem *item, d->callItems) {
73 disconnect(item, SIGNAL(stateChanged()));
74 disconnect(item, SIGNAL(dataChanged()));
77 if (d->callItems.size() > 0)
82 void CallManager::modemValidityChanged(bool valid)
89 QList<CallItem *> CallManager::getCallItems() const
92 return d->callItems.values();
95 int CallManager::callCount() const
98 qDebug()<<"call count is currently = "<<d->callItems.size();
99 return d->callItems.size();
102 int CallManager::multipartyCallCount() const
106 foreach (CallItem *c, d->callItems) {
107 if(c->multiparty()) {
114 CallItem *CallManager::activeCall() const
117 if (d->callItems.size())
118 foreach (CallItem *c, d->callItems)
119 if (c->state() == STATE_ACTIVE)
124 CallItem *CallManager::heldCall() const
127 if (d->callItems.size())
128 foreach (CallItem *c, d->callItems)
129 if (c->state() == STATE_HELD)
134 CallItem *CallManager::dialingCall() const
137 if (d->callItems.size())
138 foreach (CallItem *c, d->callItems)
139 if (c->state() == STATE_DIALING)
144 CallItem *CallManager::incomingCall() const
147 if (d->callItems.size())
148 foreach (CallItem *c, d->callItems)
149 if (c->state() == STATE_INCOMING)
154 CallItem *CallManager::waitingCall() const
157 if (d->callItems.size())
158 foreach (CallItem *c, d->callItems)
159 if (c->state() == STATE_WAITING)
164 CallItem *CallManager::alertingCall() const
167 if (d->callItems.size())
168 foreach (CallItem *c, d->callItems)
169 if (c->state() == STATE_ALERTING)
174 void CallManager::setActiveCall(const CallItem &call)
180 void CallManager::dial(const QString &number)
183 // Nothing to do if the modem is not powered up
185 if(!modem()->powered()) {
190 // If not online (flight mode?), check if the requested number is
191 // one of the allowed EmergencyNumbers, in which case, continue.
192 // Otherwise, notify that only Emergency calls are permitted.
193 if(!modem()->online()) {
194 if(modem()->powered() && !emergencyNumbers().contains(number)) {
196 emit onlyEmergencyCalls();
201 proceedCallDial(number);
204 void CallManager::privateChat(const CallItem &call)
210 * Resource Policy Manager Handler slots
212 void CallManager::deniedCallDial()
215 qCritical() << QString("Denied: Dial resource");
218 void CallManager::lostCallDial()
221 qCritical() << QString("Lost: Dial resource");
225 void CallManager::proceedCallDial(const QString number)
228 OfonoVoiceCallManager::dial(stripLineID(number), QString());
231 void CallManager::deniedCallAnswer()
234 qCritical() << QString("Denied: Call resource");
238 void CallManager::deniedIncomingCall(CallItem *call)
242 qCritical() << QString("Denied: Incoming Call resource");
243 qDebug() << QString("Insert new CallItem %1").arg(call->path());
245 emit incomingCall(call);
248 void CallManager::lostIncomingCall(CallItem *call)
252 qCritical() << QString("Lost: Incoming Call resource");
255 void CallManager::proceedIncomingCall(CallItem *call)
258 qDebug() << QString("Acquired: Incoming Call resource");
259 qDebug() << QString("Insert new CallItem %1").arg(call->path());
261 emit incomingCall(call);
265 * Private slots for async replies
268 void CallManager::updateCallItems()
271 bool changed = false;
273 // If ofono call list is empty (no calls), empty our CallItem list too.
274 if (getCalls().isEmpty() && !d->callItems.isEmpty()) {
275 qDebug() << QString("Purging all CallItems");
276 foreach (CallItem *item, d->callItems)
278 d->callItems.clear();
283 // Remove CallItems that are not in the ofono "calls" list
284 QMutableHashIterator<QString, CallItem*> iter(d->callItems);
285 while (iter.hasNext()) {
286 CallItem *item = iter.next().value();
287 // This item is not in the ofono list, remove it
288 if (!getCalls().contains(item->path())) {
289 qDebug() << QString("Removing old CallItem %1").arg(item->path());
296 // Insert new CallItems for paths in the ofono "calls" list we are missing
297 foreach (QString path, getCalls()) {
298 // Insert a new CallItem
299 if (!d->callItems.contains(path)) {
300 qDebug() << QString("Inserting new CallItem %1").arg(path);
301 CallItem *call = new CallItem(path);
302 connect (call, SIGNAL(stateChanged()),
303 this, SLOT(callStateChanged()));
304 connect (call, SIGNAL(multipartyChanged()),
305 this, SLOT(callMultipartyChanged()));
306 d->callItems.insert(path, call);
308 // NOTE: Must explicity bubble this up since incoming and waiting
309 // calls do not "changeState" unless they are handled or
311 if ((call->state() == STATE_INCOMING) ||
312 (call->state() == STATE_WAITING)) {
313 proceedIncomingCall(call);
324 void CallManager::addCall(const QString &path)
327 qDebug() << QString("CallAdded: \"%1\"").arg(path);
328 qDebug() <<"Call number is now "<< callCount();
330 emit callCountChanged(callCount());
333 void CallManager::removeCall(const QString &path)
336 qDebug() << QString("CallRemoved: \"%1\"").arg(path);
337 qDebug() <<"Call number is now "<< callCount();
339 emit callCountChanged(callCount());
342 void CallManager::dialFinished(const bool status)
345 qDebug() <<"Call number is now "<< callCount();
348 qCritical() << QString("dial() Failed: %1 - %2")
350 .arg(errorMessage());
352 // Notify that state of the call has changed when the dialing fails
357 void CallManager::hangupAllFinished(const bool status)
361 qCritical() << QString("hangupAll() Failed: %1 - %2")
363 .arg(errorMessage());
365 //If there are still calls for some reason, delete them.
368 foreach (CallItem *item, d->callItems) {
369 disconnect(item, SIGNAL(stateChanged()));
370 disconnect(item, SIGNAL(dataChanged()));
374 d->callItems.clear();
381 void CallManager::swapFinished(const bool status)
385 qCritical() << QString("swapCalls() Failed: %1 - %2")
387 .arg(errorMessage());
390 void CallManager::holdAndAnswerFinished(const bool status)
394 qCritical() << QString("HoldAndAnswer() Failed: %1 - %2")
396 .arg(errorMessage());
399 void CallManager::transferFinished(const bool status)
403 qCritical() << QString("Transfer() Failed: %1 - %2")
405 .arg(errorMessage());
408 void CallManager::releaseAndAnswerFinished(const bool status)
412 qCritical() << QString("ReleaseAndAnswer() Failed: %1 - %2")
414 .arg(errorMessage());
417 void CallManager::privateChatFinished(const bool status)
421 qCritical() << QString("PrivateChat() Failed: %1 - %2")
423 .arg(errorMessage());
426 void CallManager::createMultipartyFinished(const bool status)
430 qCritical() << QString("CreateMultiparty() Failed: %1 - %2")
432 .arg(errorMessage());
435 void CallManager::hangupMultipartyFinished(const bool status)
439 qCritical() << QString("HangupMultiparty() Failed: %1 - %2")
441 .arg(errorMessage());
444 void CallManager::sendTonesFinished(const bool status)
448 qCritical() << QString("SendTones() Failed: %1 - %2")
450 .arg(errorMessage());
453 void CallManager::callStateChanged()
455 CallItem *call = dynamic_cast<CallItem *>(sender());
456 qDebug() << QString("%1 (%2) state has changed to %3")
460 qDebug() << "number of calls "<< callCount();
464 void CallManager::callMultipartyChanged()
468 emit multipartyCallCountChanged(multipartyCallCount());
471 void CallManager::callChangedSlot()
474 qDebug()<<"callChanged called!";
477 /* Local Variables: */
479 /* c-basic-offset:4 */
480 /* indent-tabs-mode: nil */