2 * Copyright (C) 2011, BMW AG
6 * \file AudioManagerCore.cpp
9 * \author Christian Müller (christian.ei.mueller@bmw.de)
12 * GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
13 * Copyright (C) 2011, BMW AG – Christian Müller Christian.ei.mueller@bmw.de
15 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
16 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License, version 2.1, for more details.
17 * You should have received a copy of the GNU Lesser General Public License, version 2.1, along with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
18 * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may also be applicable to programs even in cases in which the program is not a library in the technical sense.
19 * Linking AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. You may license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to license your linked modules under the GNU Lesser General Public License, version 2.1, you may use the program under the following exception.
20 * As a special exception, the copyright holders of AudioManager give you permission to combine AudioManager with software programs or libraries that are released under any license unless such a combination is not permitted by the license of such a software program or library. You may copy and distribute such a system following the terms of the GNU Lesser General Public License, version 2.1, including this special exception, for AudioManager and the licenses of the other code concerned.
21 * Note that people who make modified versions of AudioManager are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, version 2.1, gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception.
26 #include "AudioManagerCore.h"
34 Task::Task(AudioManagerCore* core) {
38 TaskAsyncConnect::TaskAsyncConnect(AudioManagerCore* core, sink_t sink,
40 Task(core), m_ParamSink(sink), m_ParamSource(source) {
43 TaskAsyncConnect::~TaskAsyncConnect() {
46 void TaskAsyncConnect::executeTask(Queue* queue) {
47 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
48 (const QObject*) queue, SLOT(slot_nextTask()));
49 QObject::connect((const QObject*) m_core->returnReceiver(),
50 SIGNAL(signal_ackConnect(genHandle_t, genError_t)),
51 (const QObject*) this,
52 SLOT(slot_connect_finished(genHandle_t, genError_t)));
53 m_timer = new QTimer();
54 m_timer->setSingleShot(true);
55 QObject::connect(m_timer, SIGNAL(timeout()), (const QObject*) this,
56 SLOT(slot_timeout()));
57 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Started Connect"));
58 m_timer->start(CONNECT_TIMEOUT);
59 m_core->connect(m_ParamSource, m_ParamSink, &m_handle);
62 void TaskAsyncConnect::setSink(sink_t sink) {
66 void TaskAsyncConnect::setSource(source_t source) {
67 m_ParamSource = source;
70 sink_t TaskAsyncConnect::getSink() {
74 source_t TaskAsyncConnect::getSource() {
78 void TaskAsyncConnect::slot_connect_finished(genHandle_t handle,
80 if (handle == m_handle && error == GEN_OK) {
84 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Connect returned"));
85 emit signal_nextTask();
87 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Somethings wrong with the connection"));
92 * \todo handle this event better.
94 void TaskAsyncConnect::slot_timeout() {
95 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Connection timed out"));
98 TaskConnect::TaskConnect(AudioManagerCore* core, sink_t sink, source_t source) :
99 Task(core), m_ParamSink(sink), m_ParamSource(source) {
102 TaskConnect::~TaskConnect() {
105 void TaskConnect::executeTask(Queue* queue) {
106 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
107 (const QObject*) queue, SLOT(slot_nextTask()));
108 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Started Syncronous Connect"));
109 m_core->connect(m_ParamSource, m_ParamSink);
110 emit signal_nextTask();
113 TaskDisconnect::TaskDisconnect(AudioManagerCore* core, connection_t ID) :
114 Task(core), m_ParamConnectionID(ID) {
117 TaskDisconnect::~TaskDisconnect() {
120 void TaskDisconnect::executeTask(Queue* queue) {
121 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
122 (const QObject*) queue, SLOT(slot_nextTask()));
123 m_core->disconnect(m_ParamConnectionID);
124 emit signal_nextTask();
127 TaskInterruptWait::TaskInterruptWait(AudioManagerCore* core,
128 genInt_t interruptID) :
129 Task(core), m_interruptID(interruptID) {
132 TaskInterruptWait::~TaskInterruptWait() {
136 void TaskInterruptWait::executeTask(Queue* queue) {
137 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
138 (const QObject*) queue, SLOT(slot_nextTask()));
139 QObject::connect((const QObject*) m_core->returnCommandInterface(),
140 SIGNAL(signal_interruptResume(genInt_t)), (const QObject*) this,
141 SLOT(slot_interrupt_ready(genInt_t)));
144 void TaskInterruptWait::slot_interrupt_ready(genInt_t ID) {
145 if (ID == m_interruptID) {
146 emit signal_nextTask();
150 TaskSetVolume::TaskSetVolume(AudioManagerCore* core, volume_t newVolume,
152 Task(core), m_volume(newVolume), m_sink(sink) {
156 TaskSetVolume::~TaskSetVolume() {
159 void TaskSetVolume::setVolume(volume_t newVolume) {
160 m_volume = newVolume;
163 void TaskSetVolume::setSink(sink_t sink) {
167 volume_t TaskSetVolume::getVolume() {
171 sink_t TaskSetVolume::getSink() {
175 void TaskSetVolume::executeTask(Queue* queue) {
176 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
177 (const QObject*) queue, SLOT(slot_nextTask()));
178 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Started Changed Volume"));
179 m_core->setVolume(m_sink, m_volume);
180 emit signal_nextTask();
183 TaskSetSourceVolume::TaskSetSourceVolume(AudioManagerCore* core,
184 volume_t newVolume, source_t source) :
185 Task(core), m_volume(newVolume), m_source(source) {
189 TaskSetSourceVolume::~TaskSetSourceVolume() {
193 void TaskSetSourceVolume::setVolume(volume_t newVolume) {
194 m_volume = newVolume;
197 void TaskSetSourceVolume::setSource(source_t source) {
201 volume_t TaskSetSourceVolume::getVolume() {
204 source_t TaskSetSourceVolume::getSource() {
208 void TaskSetSourceVolume::executeTask(Queue* queue) {
209 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
210 (const QObject*) queue, SLOT(slot_nextTask()));
211 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Started Changed Source Volume"));
212 m_core->setSourceVolume(m_source, m_volume);
213 emit signal_nextTask();
216 TaskWait::TaskWait(AudioManagerCore* core, int mseconds) :
217 Task(core), m_ParamMSeconds(mseconds) {
220 TaskWait::~TaskWait() {
223 void TaskWait::setTime(int mseconds) {
224 m_ParamMSeconds = mseconds;
227 int TaskWait::getTime() {
228 return m_ParamMSeconds;
231 void TaskWait::executeTask(Queue* queue) {
232 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
233 (const QObject*) queue, SLOT(slot_nextTask()));
234 m_timer = new QTimer();
235 m_timer->setSingleShot(true);
236 QObject::connect(m_timer, SIGNAL(timeout()), (const QObject*) this,
237 SLOT(slot_timeIsup()));
238 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Start Sleep "));
239 m_timer->start(m_ParamMSeconds);
242 void TaskWait::slot_timeIsup() {
243 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Stop Sleep "));
245 emit signal_nextTask();
248 TaskEnterUserConnect::TaskEnterUserConnect(AudioManagerCore* core,
249 genRoute_t route, connection_t connID) :
250 Task(core), m_route(route), m_connectionID(connID) {
253 TaskEnterUserConnect::~TaskEnterUserConnect() {
256 void TaskEnterUserConnect::setConnection(genRoute_t route, connection_t connID) {
258 m_connectionID = connID;
261 genRoute_t TaskEnterUserConnect::returnConnection() {
265 void TaskEnterUserConnect::executeTask(Queue* queue) {
266 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
267 (const QObject*) queue, SLOT(slot_nextTask()));
268 m_core->returnDatabaseHandler()->updateMainConnection(m_connectionID,
270 emit signal_nextTask();
273 TaskRemoveUserConnect::TaskRemoveUserConnect(AudioManagerCore* core,
274 connection_t connID) :
275 Task(core), m_connectionID(connID) {
278 TaskRemoveUserConnect::~TaskRemoveUserConnect() {
282 void TaskRemoveUserConnect::setConnectionID(connection_t connID) {
283 m_connectionID = connID;
286 connection_t TaskRemoveUserConnect::returnConnectionID() {
287 return m_connectionID;
290 void TaskRemoveUserConnect::executeTask(Queue* queue) {
291 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
292 (const QObject*) queue, SLOT(slot_nextTask()));
293 m_core->returnDatabaseHandler()->removeMainConnection(m_connectionID);
294 emit signal_nextTask();
297 TaskEnterInterrupt::TaskEnterInterrupt(AudioManagerCore* core, genInt_t ID,
298 bool mixed, connection_t connID, QList<source_t> listInterruptedSources) :
299 Task(core), m_intID(ID), m_mixed(mixed), m_connectionID(connID),
300 m_interruptedSourcesList(listInterruptedSources) {
303 TaskEnterInterrupt::~TaskEnterInterrupt() {
306 void TaskEnterInterrupt::executeTask(Queue* queue) {
307 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
308 (const QObject*) queue, SLOT(slot_nextTask()));
309 m_core->returnDatabaseHandler()->updateInterrupt(m_intID, m_connectionID,
310 m_mixed, m_interruptedSourcesList);
311 emit signal_nextTask();
314 TaskRemoveInterrupt::TaskRemoveInterrupt(AudioManagerCore* core, genInt_t ID) :
315 Task(core), m_intID(ID) {
318 TaskRemoveInterrupt::~TaskRemoveInterrupt() {
321 void TaskRemoveInterrupt::executeTask(Queue* queue) {
322 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
323 (const QObject*) queue, SLOT(slot_nextTask()));
324 m_core->returnDatabaseHandler()->removeInterrupt(m_intID);
325 emit signal_nextTask();
328 TaskSetSourceMute::TaskSetSourceMute(AudioManagerCore* core, source_t source) :
329 Task(core), m_source(source) {
332 TaskSetSourceMute::~TaskSetSourceMute() {
335 void TaskSetSourceMute::executeTask(Queue* queue) {
336 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
337 (const QObject*) queue, SLOT(slot_nextTask()));
338 m_core->setSourceMute(m_source);
339 emit signal_nextTask();
342 TaskSetSourceUnmute::TaskSetSourceUnmute(AudioManagerCore* core,
344 Task(core), m_source(source) {
347 TaskSetSourceUnmute::~TaskSetSourceUnmute() {
350 void TaskSetSourceUnmute::executeTask(Queue* queue) {
351 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
352 (const QObject*) queue, SLOT(slot_nextTask()));
353 m_core->setSourceUnMute(m_source);
354 emit signal_nextTask();
357 TaskEmitSignalConnect::TaskEmitSignalConnect(AudioManagerCore* core) :
361 TaskEmitSignalConnect::~TaskEmitSignalConnect() {
364 void TaskEmitSignalConnect::executeTask(Queue* queue) {
365 QObject::connect((const QObject*) this, SIGNAL(signal_nextTask()),
366 (const QObject*) queue, SLOT(slot_nextTask()));
367 m_core->emitSignalConnect();
368 emit signal_nextTask();
371 Queue::Queue(AudioManagerCore* core, QString name) :
372 m_core(core), m_currentIndex(0), m_name(name), m_taskList(QList<Task*> ()) {
373 m_core->addQueue(this);
377 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("shoot all tasks"));
378 foreach (Task* task, m_taskList) {
381 m_core->removeQueue(this);
385 if (m_taskList.isEmpty() == false) {
386 Task* task = m_taskList.first();
387 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Started to execute Task"));
388 task->executeTask(this);
390 DLT_LOG(AudioManager,DLT_LOG_ERROR, DLT_STRING("empty tasklist was attempted to run "));
395 void Queue::slot_nextTask() {
397 if (m_currentIndex < m_taskList.length()) {
398 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Task "),DLT_INT(m_currentIndex),DLT_STRING(" out of ") ,DLT_INT(m_taskList.length()));
399 m_taskList.at(m_currentIndex)->executeTask(this);
401 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Finished all Tasks"));
406 void Queue::addTask(Task* task) {
407 m_taskList.append(task);
410 genError_t Queue::removeTask(Task* task) {
411 if (m_taskList.removeAll(task) > 0) {
414 return GEN_OUTOFRANGE;
415 void addQueue(Queue* queue);
419 QList<Task*> Queue::getTaskList() {
423 QString Queue::returnName() {
427 AudioManagerCore::AudioManagerCore() :
428 m_queueList(QList<Queue*> ()) {
431 AudioManagerCore::~AudioManagerCore() {
432 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("delete all running queues"));
433 foreach (Queue* queue, m_queueList) {
438 Router* AudioManagerCore::returnRouter() {
442 DataBaseHandler* AudioManagerCore::returnDatabaseHandler() {
443 return m_databaseHandler;
446 RoutingReceiver* AudioManagerCore::returnReceiver() {
450 DBusCommandInterface* AudioManagerCore::returnCommandInterface() {
454 void AudioManagerCore::registerBushandler(Bushandler* handler) {
455 m_busHandler = handler;
458 void AudioManagerCore::registerDatabasehandler(DataBaseHandler* handler) {
459 m_databaseHandler = handler;
462 void AudioManagerCore::registerRouter(Router* router) {
466 void AudioManagerCore::registerHookEngine(HookHandler* handler) {
467 m_hookHandler = handler;
470 void AudioManagerCore::registerReceiver(RoutingReceiver* receiver) {
471 m_receiver = receiver;
474 void AudioManagerCore::registerCommandInterface(DBusCommandInterface* command) {
478 genError_t AudioManagerCore::UserConnect(source_t source, sink_t sink) {
479 Queue* userConnectionRequestQ = new Queue(this, "User Connect");
480 m_hookHandler->fireHookUserConnectionRequest(userConnectionRequestQ,
482 userConnectionRequestQ->run();
486 genError_t AudioManagerCore::UserDisconnect(connection_t connID) {
487 Queue* userDisconnectionRequestQ = new Queue(this, "User Disconnect");
488 m_hookHandler->fireHookUserDisconnectionRequest(userDisconnectionRequestQ,
490 userDisconnectionRequestQ->run();
494 genError_t AudioManagerCore::UserSetVolume(sink_t sink, volume_t volume) {
495 m_hookHandler->fireHookVolumeChange(volume, sink);
499 QList<ConnectionType> AudioManagerCore::getListConnections() {
500 return m_databaseHandler->getListAllMainConnections();
503 QList<SinkType> AudioManagerCore::getListSinks() {
504 QList<SinkType> sinkList;
505 m_databaseHandler->getListofSinks(&sinkList);
509 QList<SourceType> AudioManagerCore::getListSources() {
510 QList<SourceType> sourceList;
511 m_databaseHandler->getListofSources(&sourceList);
515 void AudioManagerCore::emitSignalConnect() {
516 emit signal_connectionChanged();
519 genError_t AudioManagerCore::connect(source_t source, sink_t sink,
520 genHandle_t* handle) {
521 genHandle_t localhandle;
522 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Connect"), DLT_INT(source), DLT_STRING(" to "), DLT_INT(sink));
523 domain_t domainID = m_databaseHandler->get_Domain_ID_from_Source_ID(source);
524 RoutingSendInterface* iface = m_busHandler->getInterfaceforBus(
525 m_databaseHandler->get_Bus_from_Domain_ID(domainID));
526 localhandle = m_databaseHandler->insertConnection(source, sink);
529 *handle = localhandle;
531 iface->connect(source, sink, localhandle);
532 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Connect finished"));
535 * \todo implement error handling
539 genError_t AudioManagerCore::disconnect(connection_t ID) {
540 domain_t domainID = m_databaseHandler->get_Domain_ID_from_Connection_ID(ID);
541 RoutingSendInterface* iface = m_busHandler->getInterfaceforBus(
542 m_databaseHandler->get_Bus_from_Domain_ID(domainID));
543 iface->disconnect(ID);
544 m_databaseHandler->removeConnection(ID);
547 * \todo failure handling
551 genError_t AudioManagerCore::setVolume(sink_t sink, volume_t volume) {
552 RoutingSendInterface* iface = m_busHandler->getInterfaceforBus(
553 m_databaseHandler->get_Bus_from_Domain_ID(
554 m_databaseHandler->get_Domain_ID_from_Sink_ID(sink)));
555 iface->setSinkVolume(volume, sink);
558 * \todo failure handling
562 genError_t AudioManagerCore::interruptRequest(source_t interruptSource,
563 sink_t sink, genInt_t* interrupt) {
564 Queue* interruptRequestQ = new Queue(this, "Interrupt Request");
565 m_hookHandler->fireHookInterruptRequest(interruptRequestQ, interruptSource,
567 interruptRequestQ->run();
571 genError_t AudioManagerCore::setSourceVolume(source_t source, volume_t volume) {
572 RoutingSendInterface* iface = m_busHandler->getInterfaceforBus(
573 m_databaseHandler->get_Bus_from_Domain_ID(
574 m_databaseHandler->get_Domain_ID_from_Source_ID(source)));
575 iface->setSourceVolume(volume, source);
579 genError_t AudioManagerCore::setSourceMute(source_t source) {
580 RoutingSendInterface* iface = m_busHandler->getInterfaceforBus(
581 m_databaseHandler->get_Bus_from_Domain_ID(
582 m_databaseHandler->get_Domain_ID_from_Source_ID(source)));
583 iface->muteSource(source);
587 genError_t AudioManagerCore::setSourceUnMute(source_t source) {
588 RoutingSendInterface* iface = m_busHandler->getInterfaceforBus(
589 m_databaseHandler->get_Bus_from_Domain_ID(
590 m_databaseHandler->get_Domain_ID_from_Source_ID(source)));
591 iface->unmuteSource(source);
595 genError_t AudioManagerCore::getRoute(const bool onlyfree,
596 const source_t source, const sink_t sink, QList<genRoute_t>* ReturnList) {
597 m_hookHandler->fireHookRoutingRequest(onlyfree, source, sink, ReturnList);
601 connection_t AudioManagerCore::returnConnectionIDforSinkSource(sink_t sink,
603 return m_databaseHandler->getConnectionID(source, sink);
606 genError_t AudioManagerCore::removeQueue(Queue* queue) {
607 if (m_queueList.removeAll(queue)) {
610 return GEN_OUTOFRANGE;
614 source_t AudioManagerCore::returnSourceIDfromName(const QString name) {
615 return m_databaseHandler->get_Source_ID_from_Name(name);
618 sink_t AudioManagerCore::returnSinkIDfromName(const QString name) {
619 return m_databaseHandler->get_Sink_ID_from_Name(name);
622 void AudioManagerCore::addQueue(Queue* queue) {
623 m_queueList.append(queue);