diff options
author | Wolf Bergenheim <ext-wolf.2.bergenheim@nokia.com> | 2010-02-17 11:40:38 +0200 |
---|---|---|
committer | Wolf Bergenheim <ext-wolf.2.bergenheim@nokia.com> | 2010-02-17 11:40:38 +0200 |
commit | 28aaf4eb7d89bba113d27a9a39fc787a03a05e31 (patch) | |
tree | 67f353cda2b44b419d108f5c91e0cf5d1fa27f7a | |
parent | e288abf93cc33ce7f6d535e1e5d887e8f9628119 (diff) |
Implemented release, update and related callbacks (grant, release, lost
resources). Initial implementation of audio (group only at this stage).
-rw-r--r-- | libresourceqt/include/qt4/policy/audio-resource.h | 42 | ||||
-rw-r--r-- | libresourceqt/include/qt4/policy/resource-set.h | 26 | ||||
-rw-r--r-- | libresourceqt/include/qt4/policy/resources.h | 35 | ||||
-rw-r--r-- | libresourceqt/libresourceqt.pro | 8 | ||||
-rw-r--r-- | libresourceqt/src/audio-resource.cpp | 63 | ||||
-rw-r--r-- | libresourceqt/src/resource-engine.cpp | 222 | ||||
-rw-r--r-- | libresourceqt/src/resource-engine.h | 17 | ||||
-rw-r--r-- | libresourceqt/src/resource-set.cpp | 152 | ||||
-rw-r--r-- | libresourceqt/src/resources.cpp | 83 | ||||
-rw-r--r-- | resourceqt-client/client.cpp | 53 | ||||
-rw-r--r-- | resourceqt-client/client.h | 1 | ||||
-rw-r--r-- | tests/test-resource-engine/test-resource-engine.cpp | 15 | ||||
-rw-r--r-- | tests/test-resource-engine/test-resource-engine.pro | 2 | ||||
-rw-r--r-- | tests/test-resource-set/test-resource-set.pro | 3 | ||||
-rw-r--r-- | tests/test-resource/test-resource.h | 1 | ||||
-rw-r--r-- | tests/test-resource/test-resource.pro | 7 |
16 files changed, 508 insertions, 222 deletions
diff --git a/libresourceqt/include/qt4/policy/audio-resource.h b/libresourceqt/include/qt4/policy/audio-resource.h new file mode 100644 index 0000000..1736fdb --- /dev/null +++ b/libresourceqt/include/qt4/policy/audio-resource.h @@ -0,0 +1,42 @@ +#ifndef AUDIO_RESOURCE_H +#define AUDIO_RESOURCE_H + +#include <QObject> +#include <QString> +#include <policy/resource.h> + +namespace ResourcePolicy +{ + +class AudioResource: public QObject, public Resource +{ + Q_OBJECT +public: + AudioResource(const QString &audioGroup = QString()); + AudioResource(const AudioResource &other); + virtual ~AudioResource(); + + QString audioGroup() const; + void setAudioGroup(const QString & newGroup); + + quint32 processID() const; + void setProcessID(quint32 newPID); + + QString streamTag() const; + void setStreamTag(const QString & newStreamTag); + + virtual ResourceType type() const; + virtual Resource * clone() const; +private: + QString group; + quint32 pid; + QString stream; +signals: + void pidChanged(quint32 newPid); + void audioGroupChanged(const QString &newGroup); + void streamTagChanged(const QString &newTag); +}; +} + +#endif + diff --git a/libresourceqt/include/qt4/policy/resource-set.h b/libresourceqt/include/qt4/policy/resource-set.h index 447dc8b..1f38c11 100644 --- a/libresourceqt/include/qt4/policy/resource-set.h +++ b/libresourceqt/include/qt4/policy/resource-set.h @@ -6,6 +6,7 @@ #include <QVector> #include <QList> #include <policy/resources.h> +#include <policy/audio-resource.h> /** * \mainpage Resource Policy Library @@ -88,7 +89,7 @@ public: * \param resource The resource to add to the set. A copy of this object * is stored in the Set. */ - void addResource(const Resource *resource); + void addResource(Resource *resource); /** * This method adds all resources in the list to the set. * A set contains only a single instance of a given resource. If the @@ -193,10 +194,14 @@ signals: */ void resourcesDenied(); /** + * This signal is emited as a response to the release() request. + */ + void resourcesReleased(); + /** * This signal is emited when some other program with a higher priority - * superseeds us, and as a result we loose our resources. + * superseeds us, and as a result we loose (some of) our resources. * It is very important to connect to this signal as it is signaling when - * the acquired resources can't be used anymore. + * the acquired resources shouldn't be used anymore. */ void lostResources(); @@ -208,16 +213,27 @@ private: const QString resourceClass; Resource* resourceSet[NumberOfTypes]; ResourceEngine *resourceEngine; + AudioResource *audioResource; bool autoRelease; bool alwaysReply; bool initialized; bool pendingAcquire; + bool pendingUpdate; + bool pendingAudioGroup; + bool pendingAudioStream; + bool pendingAudioPid; private slots: void connectedHandler(); - void handleAcquire(quint32); + void handleGranted(quint32); void handleDeny(); - + void handleReleased(); + void handleResourcesLost(quint32); + void handleResourcesBecameAvailable(quint32); + + void handleAudioPidChange(quint32 newPid); + void handleAudioGroupChange(const QString &newGroup); + void handleAudioStreamTagChanged(const QString &newGroup); }; } diff --git a/libresourceqt/include/qt4/policy/resources.h b/libresourceqt/include/qt4/policy/resources.h index f00cc2e..26ce014 100644 --- a/libresourceqt/include/qt4/policy/resources.h +++ b/libresourceqt/include/qt4/policy/resources.h @@ -8,46 +8,13 @@ namespace ResourcePolicy { -class AudioResource: public Resource -{ -public: - AudioResource(const QString &audioGroup = QString()); - AudioResource(const AudioResource &other); - virtual ~AudioResource(); - - QString audioGroup() const; - void setAudioGroup(const QString & newGroup); - - quint32 processID() const; - void setProcessID(quint32 newPID); - - QString streamTag() const; - void setStreamTag(const QString & newStreamTag); - - virtual ResourceType type() const; - virtual Resource * clone() const; -private: - QString group; - quint32 pid; - QString stream; -}; - class AudioRecorderResource: public Resource { public: - AudioRecorderResource(const QString & audioGroup = QString()); + AudioRecorderResource(); AudioRecorderResource(const AudioRecorderResource &other); virtual ~AudioRecorderResource(); - QString audioGroup() const; - void setAudioGroup(const QString & newGroup); - - quint32 processID() const; - void setProcessID(quint32 newPID); - - QString streamTag() const; - void setStreamTag(const QString & newStreamTag); - virtual ResourceType type() const; virtual Resource * clone() const; private: diff --git a/libresourceqt/libresourceqt.pro b/libresourceqt/libresourceqt.pro index 1fa80c2..428208d 100644 --- a/libresourceqt/libresourceqt.pro +++ b/libresourceqt/libresourceqt.pro @@ -6,14 +6,18 @@ DEPENDPATH += $${POLICY} src INCLUDEPATH += $${LIBRESOURCEINC} $${LIBDBUSQEVENTLOOP} src # Input -PUBLIC_HEADERS = $${POLICY}/resource.h $${POLICY}/resource-set.h $${POLICY}/resources.h +PUBLIC_HEADERS = $${POLICY}/resource.h \ + $${POLICY}/resource-set.h \ + $${POLICY}/resources.h \ + $${POLICY}/audio-resource.h HEADERS += $${PUBLIC_HEADERS} src/resource-engine.h SOURCES += src/resource.cpp \ src/resource-set.cpp \ src/resource-engine.cpp \ - src/resources.cpp + src/resources.cpp \ + src/audio-resource.cpp QMAKE_CXXFLAGS += -Wall LIBS += -L$${LIBDBUSQEVENTLOOP}/build -ldbus-qeventloop diff --git a/libresourceqt/src/audio-resource.cpp b/libresourceqt/src/audio-resource.cpp new file mode 100644 index 0000000..79587ff --- /dev/null +++ b/libresourceqt/src/audio-resource.cpp @@ -0,0 +1,63 @@ +#include <policy/audio-resource.h> + +using namespace ResourcePolicy; + +AudioResource::AudioResource(const QString &audioGroup) + : QObject(), Resource(), group(audioGroup), pid(0), stream(QString()) +{ +} + +AudioResource::AudioResource(const AudioResource &other) + : QObject(), Resource(other), group(other.group), pid(other.pid), stream(other.stream) +{ +} + +Resource * AudioResource::clone() const +{ + return new AudioResource(*this); +} + +AudioResource::~AudioResource() +{ +} + +QString AudioResource::audioGroup() const +{ + return group; +} + +void AudioResource::setAudioGroup(const QString &newGroup) +{ + qDebug("this = %p", this); + group = newGroup; + qDebug() << "Audio group changed! New group is: " << newGroup; + emit audioGroupChanged(group); +} + +quint32 AudioResource::processID() const +{ + return pid; +} + +void AudioResource::setProcessID(quint32 newPID) +{ + pid = newPID; + emit pidChanged(pid); +} + +QString AudioResource::streamTag() const +{ + return stream; +} + +void AudioResource::setStreamTag(const QString & newStreamTag) +{ + stream = newStreamTag; + emit streamTagChanged(stream); +} + +ResourceType AudioResource::type() const +{ + return AudioPlaybackType; +} + diff --git a/libresourceqt/src/resource-engine.cpp b/libresourceqt/src/resource-engine.cpp index 2c5c1f8..2704235 100644 --- a/libresourceqt/src/resource-engine.cpp +++ b/libresourceqt/src/resource-engine.cpp @@ -21,6 +21,10 @@ ResourceEngine::ResourceEngine(ResourceSet *resourceSet) ResourceEngine::~ResourceEngine() { + delete dbusEngine; + if (libresourceSet != NULL) + libresourceSet->userdata = NULL; + //need to destroy all libresource structures, but how? } bool ResourceEngine::initialize() @@ -53,9 +57,13 @@ bool ResourceEngine::initialize() return true; } -static void handleUnregisterMessage(resmsg_t *, resset_t *resSet, void *) +static void handleUnregisterMessage(resmsg_t *, resset_t *libresourceSet, void *) { - ResourceEngine *engine = reinterpret_cast<ResourceEngine *>(resSet->userdata); + if (NULL == libresourceSet->userdata) { + qDebug("IGNORING unregister, no context"); + return; + } + ResourceEngine *engine = reinterpret_cast<ResourceEngine *>(libresourceSet->userdata); engine->disconnected(); } @@ -67,43 +75,78 @@ void ResourceEngine::disconnected() emit disconnectedFromManager(); } -static void handleGrantMessage(resmsg_t *msg, resset_t *resSet, void *) +static void handleGrantMessage(resmsg_t *message, resset_t *libresourceSet, void *) { - ResourceEngine *engine = reinterpret_cast<ResourceEngine *>(resSet->userdata); - - engine->receivedGrant(&(msg->notify)); + if (NULL == libresourceSet->userdata) { + qDebug("IGNORING grant, no context: type=0x%04x, id=0x%04x, reqno=0x%04x, resc=0x%04x", + message->notify.type, message->notify.id, message->notify.reqno, message->notify.resrc); + return; + } + ResourceEngine *engine = reinterpret_cast<ResourceEngine *>(libresourceSet->userdata); + engine->receivedGrant(&(message->notify)); } void ResourceEngine::receivedGrant(resmsg_notify_t *notifyMessage) { - qDebug("received a grant message for request %u", notifyMessage->reqno); - if(notifyMessage->resrc == 0) { - qDebug("request DENIED!"); - emit resourcesDenied(); + qDebug("receivedGrant: type=0x%04x, id=0x%04x, reqno=0x%04x, resc=0x%04x", + notifyMessage->type, notifyMessage->id, notifyMessage->reqno, notifyMessage->resrc); + if (notifyMessage->resrc == 0) { + bool unkownRequest = !messageMap.contains(notifyMessage->reqno); + resmsg_type_t originaloriginalMessageType = messageMap.take(notifyMessage->reqno); + qDebug("lost resources, originaloriginalMessageType=%u", originaloriginalMessageType); + if (unkownRequest) { + //we don't know this req number => it must be a server override. + qDebug("emiting signal resourcesLost()"); + emit resourcesLost(allResourcesToBitmask(resourceSet)); + } + else if (originaloriginalMessageType == RESMSG_ACQUIRE) { + qDebug("request DENIED!"); + emit resourcesDenied(); + } + else if (originaloriginalMessageType == RESMSG_RELEASE) { + qDebug("confirmnation to release"); + emit resourcesReleased(); + } + else { + qDebug("Ignoring the receivedGrant"); + } } else { - qDebug("emiting signal resourcesAcquired(%02x), this=%p", notifyMessage->resrc, this); - emit resourcesAcquired(notifyMessage->resrc); + qDebug("emiting signal resourcesGranted(%02x)", notifyMessage->resrc); + emit resourcesGranted(notifyMessage->resrc); } } -static void handleAdviceMessage(resmsg_t *msg, resset_t *resSet, void *) +static void handleAdviceMessage(resmsg_t *message, resset_t *libresourceSet, void *) { - ResourceEngine *engine = reinterpret_cast<ResourceEngine *>(resSet->userdata); + qDebug("ADVICE: type=0x%04x, id=0x%04x, reqno=0x%04x, resc=0x%04x", + message->notify.type, message->notify.id, message->notify.reqno, message->notify.resrc); + + if (NULL == libresourceSet->userdata) { + qDebug("IGNORING advice, no context"); + return; + } + ResourceEngine *engine = reinterpret_cast<ResourceEngine *>(libresourceSet->userdata); - engine->receivedAdvice(&(msg->notify)); + engine->receivedAdvice(&(message->notify)); } -void ResourceEngine::receivedAdvice(resmsg_notify_t *notifyMessage) +void ResourceEngine::receivedAdvice(resmsg_notify_t *message) { - char buf[80]; - resmsg_res_str(notifyMessage->resrc, buf, sizeof(buf)); - qDebug("%s: %s", __FUNCTION__, buf); + qDebug("%s: %04x", __FUNCTION__, message->resrc); + uint32_t allResources = allResourcesToBitmask(resourceSet); + if(message->resrc < allResources) { + emit resourcesLost(allResources-message->resrc); + } + else { + emit resourcesBecameAvailable(message->resrc); + } } -bool ResourceEngine::connect() +bool ResourceEngine::connectToManager() { resmsg_t resourceMessage; + memset(&resourceMessage, 0, sizeof(resmsg_t)); resourceMessage.record.type = RESMSG_REGISTER; resourceMessage.record.id = resourceSet->id(); resourceMessage.record.reqno = ++requestId; @@ -132,29 +175,19 @@ bool ResourceEngine::connect() return true; } -bool ResourceEngine::disconnect() +bool ResourceEngine::disconnectFromManager() { resmsg_t resourceMessage; + memset(&resourceMessage, 0, sizeof(resmsg_t)); + + qDebug("disconnecting from manager"); + resourceMessage.record.type = RESMSG_UNREGISTER; resourceMessage.record.id = resourceSet->id(); resourceMessage.record.reqno = ++requestId; messageMap.insert(requestId, RESMSG_UNREGISTER); - uint32_t allResources, optionalResources; - allResources = allResourcesToBitmask(resourceSet); - optionalResources = optionalResourcesToBitmask(resourceSet); - - resourceMessage.record.rset.all = allResources; - resourceMessage.record.rset.opt = optionalResources; - resourceMessage.record.rset.share = 0; - resourceMessage.record.rset.mask = mode; - - QByteArray ba = resourceSet->applicationClass().toLatin1(); - resourceMessage.record.klass = ba.data(); - - resourceMessage.record.mode = 0; //No auto release - int r = resconn_disconnect(libresourceSet, &resourceMessage, statusCallbackHandler); connected = false; @@ -220,6 +253,11 @@ static inline quint32 optionalResourcesToBitmask(const ResourceSet *resourceSet) static void statusCallbackHandler(resset_t *libresourceSet, resmsg_t *message) { + if (NULL == libresourceSet->userdata) { + qDebug("IGNORING status message, no context: type=0x%04x, id=0x%04x, reqno=0x%04x, errcod=%d", + message->status.type, message->status.id, message->status.reqno, message->status.errcod); + return; + } ResourceEngine *resourceEngine = reinterpret_cast<ResourceEngine *>(libresourceSet->userdata); qDebug("Received a status notification"); if (message->type != RESMSG_STATUS) { @@ -237,27 +275,38 @@ static void statusCallbackHandler(resset_t *libresourceSet, resmsg_t *message) void ResourceEngine::handleStatusMessage(quint32 requestNo) { - resmsg_type_t messageType = messageMap.take(requestNo); - qDebug("Received a status message: %u(0x%02x)", requestNo, messageType); - if (messageType == RESMSG_REGISTER) { + resmsg_type_t originalMessageType = messageMap.value(requestNo); + qDebug("Received a status message: %u(0x%02x)", requestNo, originalMessageType); + if (originalMessageType == RESMSG_REGISTER) { qDebug("connected!"); connected = true; emit connectedToManager(); + messageMap.remove(requestNo); } - else if (messageType == RESMSG_UNREGISTER) { + else if (originalMessageType == RESMSG_UNREGISTER) { qDebug("disconnected!"); connected = false; emit disconnectedFromManager(); + messageMap.remove(requestNo); + } + else if(originalMessageType == RESMSG_UPDATE) { + qDebug("Update status"); + } + else if(originalMessageType == RESMSG_ACQUIRE) { + qDebug("Acquire status"); + } + else if(originalMessageType == RESMSG_RELEASE) { + qDebug("Release status"); } } void ResourceEngine::handleError(quint32 requestNo, qint32 code, const char *message) { - resmsg_type_t messageType = messageMap.take(requestNo); - qDebug("Error on request %u(0x%02x): %d - %s", requestNo, messageType, code, message); + resmsg_type_t originalMessageType = messageMap.take(requestNo); + qDebug("Error on request %u(0x%02x): %d - %s", requestNo, originalMessageType, code, message); } -bool ResourceEngine::isConnected() +bool ResourceEngine::isConnectedToManager() { return connected; } @@ -268,8 +317,8 @@ bool ResourceEngine::acquireResources() memset(&message, 0, sizeof(resmsg_t)); message.possess.type = RESMSG_ACQUIRE; - message.any.id = resourceSet->id(); - message.any.reqno = ++requestId; + message.possess.id = resourceSet->id(); + message.possess.reqno = ++requestId; messageMap.insert(requestId, RESMSG_ACQUIRE); @@ -284,21 +333,102 @@ bool ResourceEngine::acquireResources() bool ResourceEngine::releaseResources() { - return false; + resmsg_t message; + memset(&message, 0, sizeof(resmsg_t)); + + message.possess.type = RESMSG_RELEASE; + message.possess.id = resourceSet->id(); + message.possess.reqno = ++requestId; + + messageMap.insert(requestId, RESMSG_RELEASE); + qDebug("release %u:%u", resourceSet->id(), requestId); + int success = resproto_send_message(libresourceSet, &message, statusCallbackHandler); + + if(!success) + return false; + else + return true; } bool ResourceEngine::updateResources() { + resmsg_t message; + memset(&message, 0, sizeof(resmsg_t)); + message.record.type = RESMSG_UPDATE; + message.record.id = resourceSet->id(); + message.record.reqno = ++requestId; + + uint32_t allResources, optionalResources; + allResources = allResourcesToBitmask(resourceSet); + optionalResources = optionalResourcesToBitmask(resourceSet); + + message.record.rset.all = allResources; + message.record.rset.opt = optionalResources; + message.record.rset.share = 0; + message.record.rset.mask = 0; + + QByteArray ba = resourceSet->applicationClass().toLatin1(); + message.record.klass = ba.data(); + + messageMap.insert(requestId, RESMSG_UPDATE); + + qDebug("update %u:%u", resourceSet->id(), requestId); + int success = resproto_send_message(libresourceSet, &message, statusCallbackHandler); + + if(!success) + return false; + else + return true; +} + +bool ResourceEngine::registerAudioPid(quint32) +{ return false; } -bool ResourceEngine::registerAudioProperties(quint32 pid, QString streamName) +bool ResourceEngine::registerAudioStreamTag(const QString &) { return false; } +bool ResourceEngine::registerAudioGroup(const QString &audioGroup) +{ + resmsg_t message; + memset(&message, 0, sizeof(resmsg_t)); + + QByteArray ba = resourceSet->applicationClass().toLatin1(); + message.audio.group = ba.data(); + + message.audio.type = RESMSG_AUDIO; + message.audio.id = resourceSet->id(); + message.audio.reqno = ++requestId; + + message.audio.type = RESMSG_AUDIO; + +// msg.audio.pid = pid; +//stream tag is a name:value pair +// msg.audio.property.name = name; +// msg.audio.property.match.method = resmsg_method_equals; +// msg.audio.property.match.pattern = value; + + messageMap.insert(requestId, RESMSG_AUDIO); + + qDebug("audio %u:%u", resourceSet->id(), requestId); + int success = resproto_send_message(libresourceSet, &message, statusCallbackHandler); + + if(!success) + return false; + else + return true; + +} + static void connectionIsUp(resconn_t *connection) { + if (NULL == connection->dbus.rsets->userdata) { + qDebug("IGNORING connectionIsUp"); + return; + } ResourceEngine *resourceEngine; resourceEngine = reinterpret_cast<ResourceEngine *>(connection->dbus.rsets->userdata); diff --git a/libresourceqt/src/resource-engine.h b/libresourceqt/src/resource-engine.h index 34f416a..c966144 100644 --- a/libresourceqt/src/resource-engine.h +++ b/libresourceqt/src/resource-engine.h @@ -27,15 +27,17 @@ public: bool initialize(); - bool connect(); - bool disconnect(); - bool isConnected(); + bool connectToManager(); + bool disconnectFromManager(); + bool isConnectedToManager(); bool acquireResources(); bool releaseResources(); bool updateResources(); - bool registerAudioProperties(quint32 pid, QString streamName); + bool registerAudioPid(quint32 pid); + bool registerAudioStreamTag(const QString &streamName); + bool registerAudioGroup(const QString &); void handleConnectionIsUp(); @@ -49,9 +51,11 @@ public: void setMode(quint32 newMode); signals: - void resourcesBecameAvailable(QList<ResourceType> availableResources); - void resourcesAcquired(quint32 bitmaskOfGrantedResources); + void resourcesBecameAvailable(quint32 bitmaskOfAvailableResources); + void resourcesGranted(quint32 bitmaskOfGrantedResources); void resourcesDenied(); + void resourcesReleased(); + void resourcesLost(quint32 bitmaskOfGrantedResources); void connectedToManager(); void disconnectedFromManager(); @@ -70,3 +74,4 @@ private: } #endif + diff --git a/libresourceqt/src/resource-set.cpp b/libresourceqt/src/resource-set.cpp index 7960fad..3652939 100644 --- a/libresourceqt/src/resource-set.cpp +++ b/libresourceqt/src/resource-set.cpp @@ -5,11 +5,12 @@ using namespace ResourcePolicy; ResourceSet::ResourceSet(const QString &applicationClass, QObject * parent) : QObject(parent), resourceClass(applicationClass), resourceEngine(NULL), - autoRelease(false), alwaysReply(false), initialized(false), - pendingAcquire(false) + audioResource(NULL), autoRelease(false), alwaysReply(false), + initialized(false), pendingAcquire(false), pendingUpdate(false), + pendingAudioGroup(true), pendingAudioStream(true), pendingAudioPid(true) { identifier = (quint32)this; - memset(resourceSet, 0, sizeof(QPointer<Resource *>)*NumberOfTypes); + memset(resourceSet, 0, sizeof(QPointer<Resource *>)*NumberOfTypes); } ResourceSet::~ResourceSet() @@ -17,6 +18,9 @@ ResourceSet::~ResourceSet() for (int i = 0;i < NumberOfTypes;i++) { delete resourceSet[i]; } + resourceEngine->disconnect(this); + resourceEngine->disconnectFromManager(); + delete resourceEngine; } bool ResourceSet::initialize() @@ -27,14 +31,20 @@ bool ResourceSet::initialize() } QObject::connect(resourceEngine, SIGNAL(connectedToManager()), this, SLOT(connectedHandler())); - QObject::connect(resourceEngine, SIGNAL(resourcesAcquired(quint32)), - this, SLOT(handleAcquire(quint32))); + QObject::connect(resourceEngine, SIGNAL(resourcesGranted(quint32)), + this, SLOT(handleGranted(quint32))); QObject::connect(resourceEngine, SIGNAL(resourcesDenied()), this, SLOT(handleDeny())); + QObject::connect(resourceEngine, SIGNAL(resourcesReleased()), + this, SLOT(handleReleased())); + QObject::connect(resourceEngine, SIGNAL(resourcesLost(quint32)), + this, SLOT(handleResourcesLost(quint32))); + QObject::connect(resourceEngine, SIGNAL(resourcesBecameAvailable(quint32)), + this, SLOT(handleResourcesBecameAvailable(quint32))); if (!resourceEngine->initialize()) { return false; } - if (!resourceEngine->connect()) { + if (!resourceEngine->connectToManager()) { return false; } qDebug("ResourceSet is initialized engine=%p", resourceEngine); @@ -42,13 +52,23 @@ bool ResourceSet::initialize() return true; } -void ResourceSet::addResource(const Resource *resource) +void ResourceSet::addResource(Resource *resource) { - if ((resource->type() == AudioPlaybackType) || (resource->type() == AudioRecorderType)) { - qDebug("audioResource..."); + if (resource->type() == AudioPlaybackType) { + qDebug("audioResource... %p", resource); + audioResource = static_cast<AudioResource *>(resource); + QObject::connect(audioResource, SIGNAL(pidChanged(quint32)), + this, SLOT(handleAudioPidChange(quint32))); + QObject::connect(audioResource, SIGNAL(audioGroupChanged(const QString &)), + this, SLOT(handleAudioGroupChange(QString))); + QObject::connect(audioResource, SIGNAL(streamTagChanged(const QString &)), + this, SLOT(handleAudioStreamTagChanged(const QString &))); + pendingAudioStream = true; + pendingAudioGroup = true; + pendingAudioPid = true; } delete resourceSet[resource->type()]; - resourceSet[resource->type()] = resource->clone(); + resourceSet[resource->type()] = resource; } void ResourceSet::addResources(const QList<Resource *>resources) @@ -60,6 +80,10 @@ void ResourceSet::addResources(const QList<Resource *>resources) void ResourceSet::deleteResource(ResourceType type) { + if(type == AudioPlaybackType) { + audioResource->disconnect(); + audioResource = NULL; + } delete resourceSet[type]; resourceSet[type] = NULL; } @@ -102,18 +126,20 @@ QList<Resource *> ResourceSet::resources() const Resource * ResourceSet::resource(ResourceType type) const { + qDebug("returning %p (%p), audioResource = %p", resourceSet[type], &resourceSet[type], audioResource); return resourceSet[type]; } bool ResourceSet::acquire() { - if(!initialized) { + if (!initialized) { pendingAcquire = true; return initialize(); } - else if (!resourceEngine->isConnected()) { + + if (!resourceEngine->isConnectedToManager()) { pendingAcquire = true; - resourceEngine->connect(); + resourceEngine->connectToManager(); return true; } else { @@ -123,12 +149,24 @@ bool ResourceSet::acquire() bool ResourceSet::release() { - return false; + if (!initialized || !resourceEngine->isConnectedToManager()) { + return true; + } + + return resourceEngine->releaseResources(); } bool ResourceSet::update() { - return false; + if (!initialized) { + return true; + } + + if (!resourceEngine->isConnectedToManager()) { + pendingUpdate = true; + return true; + } + return resourceEngine->updateResources(); } QString ResourceSet::applicationClass() @@ -148,31 +186,56 @@ void ResourceSet::setAlwaysReply() void ResourceSet::connectedHandler() { + if (pendingAudioGroup) { + qDebug() << "registering audio group: " << audioResource->audioGroup(); + resourceEngine->registerAudioGroup(audioResource->audioGroup()); + pendingAudioGroup = false; + } + if (pendingUpdate) { + resourceEngine->updateResources(); + pendingUpdate = false; + } if (pendingAcquire) { resourceEngine->acquireResources(); + pendingAcquire = false; } } -void ResourceSet::handleAcquire(quint32 bitmaskOfGrantedResources) +void ResourceSet::handleGranted(quint32 bitmaskOfGrantedResources) { qDebug("in %s",__FUNCTION__); QList<ResourceType> optionalResources; qDebug("Acquired resources: 0x%04x", bitmaskOfGrantedResources); for(int i=0;i < NumberOfTypes; i++) { + if(resourceSet[i] == NULL) + continue; ResourceType type = (ResourceType)i; quint32 bitmask = resourceTypeToLibresourceType(type); - qDebug("Checking if resource %x(%x) is in the set", i, bitmask); + qDebug("Checking if resource 0x%04x is in the set", bitmask); if ((bitmask & bitmaskOfGrantedResources) == bitmask) { if (resourceSet[i]->isOptional()) { optionalResources << type; } resourceSet[i]->setGranted(); - qDebug("Resource %02x is now granted", i); + qDebug("Resource 0x%04x is now granted", i); + } + else { + resourceSet[i]->unsetGranted(); } } emit resourcesGranted(optionalResources); } +void ResourceSet::handleReleased() +{ + for(int i=0;i < NumberOfTypes; i++) { + if(resourceSet[i] != NULL) { + resourceSet[i]->unsetGranted(); + } + } + emit resourcesReleased(); +} + void ResourceSet::handleDeny() { for(int i=0;i < NumberOfTypes; i++) { @@ -180,5 +243,58 @@ void ResourceSet::handleDeny() resourceSet[i]->unsetGranted(); } } + emit resourcesDenied(); +} + +void ResourceSet::handleResourcesLost(quint32 lostResourcesBitmask) +{ + for(int i=0;i < NumberOfTypes; i++) { + quint32 bitmask = resourceTypeToLibresourceType((ResourceType)i); + if ((bitmask & lostResourcesBitmask) == bitmask) { + resourceSet[i]->unsetGranted(); + qDebug("Resource %04x is now lost", bitmask); + } + } + emit lostResources(); +} + +void ResourceSet::handleResourcesBecameAvailable(quint32 availableResources) +{ + QList<ResourceType> listOfResources; + for(int i=0;i < NumberOfTypes; i++) { + ResourceType type = (ResourceType)i; + quint32 bitmask = resourceTypeToLibresourceType(type); + if ((bitmask & availableResources) == bitmask) { + listOfResources.append(type); + } + } + emit resourcesBecameAvailable(listOfResources); +} + +void ResourceSet::handleAudioPidChange(quint32 newPid) +{ + if(initialized && resourceEngine->isConnectedToManager()) { + resourceEngine->registerAudioPid(newPid); + } +} + +void ResourceSet::handleAudioGroupChange(const QString &newGroup) +{ + qDebug() << "Audio group changed to: " << newGroup; + if(initialized && resourceEngine->isConnectedToManager()) { + qDebug("registering new audio group"); + resourceEngine->registerAudioGroup(newGroup); + } + else { + qDebug("registering new audio group LATER"); + pendingAudioGroup = true; + } +} + +void ResourceSet::handleAudioStreamTagChanged(const QString &newTag) +{ + if(initialized && resourceEngine->isConnectedToManager()) { + resourceEngine->registerAudioStreamTag(newTag); + } } diff --git a/libresourceqt/src/resources.cpp b/libresourceqt/src/resources.cpp index 12d9492..f6a54d8 100644 --- a/libresourceqt/src/resources.cpp +++ b/libresourceqt/src/resources.cpp @@ -2,62 +2,8 @@ using namespace ResourcePolicy; -AudioResource::AudioResource(const QString &audioGroup) - : Resource(), group(audioGroup), pid(0), stream(QString()) -{ -} - -AudioResource::AudioResource(const AudioResource &other) - : Resource(other), group(other.group), pid(other.pid), stream(other.stream) -{ -} - -Resource * AudioResource::clone() const -{ - return new AudioResource(*this); -} - -AudioResource::~AudioResource() -{ -} - -QString AudioResource::audioGroup() const -{ - return group; -} - -void AudioResource::setAudioGroup(const QString &newGroup) -{ - group = newGroup; -} - -quint32 AudioResource::processID() const -{ - return pid; -} - -void AudioResource::setProcessID(quint32 newPID) -{ - pid = newPID; -} - -QString AudioResource::streamTag() const -{ - return stream; -} - -void AudioResource::setStreamTag(const QString & newStreamTag) -{ - stream = newStreamTag; -} - -ResourceType AudioResource::type() const -{ - return AudioPlaybackType; -} - -AudioRecorderResource::AudioRecorderResource(const QString & audioGroup) - : Resource(), group(audioGroup), pid(0), stream(QString()) +AudioRecorderResource::AudioRecorderResource() + : Resource() { } @@ -75,31 +21,6 @@ AudioRecorderResource::~AudioRecorderResource() { } -void AudioRecorderResource::setAudioGroup(const QString & newGroup) -{ - group = newGroup; -} - -quint32 AudioRecorderResource::processID() const -{ - return pid; -} - -void AudioRecorderResource::setProcessID(quint32 newPID) -{ - pid = newPID; -} - -QString AudioRecorderResource::streamTag() const -{ - return stream; -} - -void AudioRecorderResource::setStreamTag(const QString & newStreamTag) -{ - stream = newStreamTag; -} - ResourceType AudioRecorderResource::type() const { return AudioRecorderType; diff --git a/resourceqt-client/client.cpp b/resourceqt-client/client.cpp index a276e88..ec8d4a1 100644 --- a/resourceqt-client/client.cpp +++ b/resourceqt-client/client.cpp @@ -193,6 +193,7 @@ bool Client::initialize(uint32_t all, uint32_t optional, bool alwaysReply, bool { return false; } + connect(resourceSet, SIGNAL(resourcesReleased()), this, SLOT(resourceReleasedHandler())); showPrompt(); @@ -351,6 +352,12 @@ void Client::resourceLostHandler() showPrompt(); } +void Client::resourceReleasedHandler() +{ + printf("\nAll resources released\n"); + showPrompt(); +} + void Client::timerEvent(QTimerEvent*) { bool quitFlag = false; @@ -384,7 +391,7 @@ void Client::timerEvent(QTimerEvent*) printf("\t update\tupdate modified resource set after add or remove command\n"); printf("\t add reslist [-o]\tadd reosurce list, if -o provided, set as optional\n"); printf("\t remove reslist [-o]\tremove reosurce list, if -o provided, removed only optional flag\n"); - printf("\t audio \tnot implemented ....\n"); + printf("\t audio pid <pid>|group <audio group>|tag <name:value>\tset audio properties"); printf("\t show \tshow resources\n"); } else if( params[0] == "show" ) @@ -482,30 +489,38 @@ void Client::timerEvent(QTimerEvent*) } else { - AudioResource* p = reinterpret_cast<AudioResource*>(resourceSet->resource(AudioPlaybackType)); - if( p == NULL ) + Resource *resource = resourceSet->resource(AudioPlaybackType); + AudioResource *audioResource = static_cast<AudioResource*>(resource); + qDebug("resource = %p audioResource = %p", resource, audioResource); + if( audioResource == NULL ) { printf("No AudioResource available in set!\n"); } else { - p->setAudioGroup(params[1]); - - bool ok; - quint32 pid = (quint32)params[2].toInt(&ok, 10); - if( ok && pid != 0 ) - { - p->setProcessID(pid); - } - else - { - printf("Ignoring pid parameter!\n"); - } - - if( params.count() > 3 ) - { - p->setStreamTag(params[3]); + if( params[1] == "group" ) + { + audioResource->setAudioGroup(params[2]); + } + else if( params[1] == "pid" ) + { + bool ok; + quint32 pid = (quint32)params[2].toInt(&ok, 10); + if( ok && pid != 0 ) + { + audioResource->setProcessID(pid); + } + else + { + printf("Bad pid parameter!\n"); + } + } + else if( params[1] == "tag" ) { + audioResource->setStreamTag(params[2]); } + else { + printf("Unknown audio command!\n"); + } } } } diff --git a/resourceqt-client/client.h b/resourceqt-client/client.h index 39615ef..81461c5 100644 --- a/resourceqt-client/client.h +++ b/resourceqt-client/client.h @@ -36,6 +36,7 @@ private slots: void resourceAcquiredHandler(const QList<ResourceType>& grantedResList); void resourceDeniedHandler(); void resourceLostHandler(); + void resourceReleasedHandler(); protected: void timerEvent(QTimerEvent *e); diff --git a/tests/test-resource-engine/test-resource-engine.cpp b/tests/test-resource-engine/test-resource-engine.cpp index 15858da..b80beec 100644 --- a/tests/test-resource-engine/test-resource-engine.cpp +++ b/tests/test-resource-engine/test-resource-engine.cpp @@ -52,29 +52,29 @@ void TestResourceEngine::init() resourceEngine = new ResourceEngine(resourceSet); bool initializeSucceeded = resourceEngine->initialize(); acquireOrDenyWasCalled = false; - QVERIFY(!resourceEngine->isConnected()); + QVERIFY(!resourceEngine->isConnectedToManager()); QVERIFY(initializeSucceeded); } void TestResourceEngine::testConnect() { - bool connectIsSuccessful = resourceEngine->connect(); + bool connectIsSuccessful = resourceEngine->connectToManager(); QVERIFY(connectIsSuccessful); } void TestResourceEngine::testDisconnect() { - resourceEngine->connect(); + resourceEngine->connectToManager(); - bool disconnectIsSuccessful = resourceEngine->disconnect(); + bool disconnectIsSuccessful = resourceEngine->disconnectFromManager(); QVERIFY(disconnectIsSuccessful); } void TestResourceEngine::testStatusMessage() { - resourceEngine->connect(); + resourceEngine->connectToManager(); resourceEngine->messageMap.insert(1, RESMSG_REGISTER); QObject::connect(resourceEngine, SIGNAL(connectedToManager()), this, SLOT(connectedHandler())); @@ -84,7 +84,7 @@ void TestResourceEngine::testStatusMessage() void TestResourceEngine::connectedHandler() { - QVERIFY(resourceEngine->isConnected()); + QVERIFY(resourceEngine->isConnectedToManager()); } void TestResourceEngine::testAcquire_data() @@ -113,7 +113,7 @@ void TestResourceEngine::testAcquire() acquireShouldSucceed = acquireSucceeds; QFETCH(ResourceType, optionalTypeAvailable); optionalType = optionalTypeAvailable; - resourceEngine->connect(); + resourceEngine->connectToManager(); QFETCH(bool, requestFails); requestShouldFail = requestFails; QFETCH(QString, errorMessage); @@ -219,7 +219,6 @@ resset_t *resconn_connect(resconn_t *connection, resmsg_t *message, statusMessage.status.errmsg = 0; statusMessage.record.id = 11; statusMessage.record.reqno = message->record.reqno; - callbackFunction(resSet, &statusMessage); return resSet; } diff --git a/tests/test-resource-engine/test-resource-engine.pro b/tests/test-resource-engine/test-resource-engine.pro index d558bc2..6084df7 100644 --- a/tests/test-resource-engine/test-resource-engine.pro +++ b/tests/test-resource-engine/test-resource-engine.pro @@ -10,12 +10,14 @@ HEADERS += $${POLICY}/resource.h \ $${POLICY}/resources.h \ $${POLICY}/resource-set.h \ $${LIBRESOURCEQT}/src/resource-engine.h \ + $${POLICY}/audio-resource.h \ test-resource-engine.h SOURCES += $${LIBRESOURCEQT}/src/resource.cpp \ $${LIBRESOURCEQT}/src/resources.cpp \ $${LIBRESOURCEQT}/src/resource-set.cpp \ $${LIBRESOURCEQT}/src/resource-engine.cpp \ + $${LIBRESOURCEQT}/src/audio-resource.cpp \ test-resource-engine.cpp OBJECTS_DIR = build diff --git a/tests/test-resource-set/test-resource-set.pro b/tests/test-resource-set/test-resource-set.pro index 84bed87..81b028f 100644 --- a/tests/test-resource-set/test-resource-set.pro +++ b/tests/test-resource-set/test-resource-set.pro @@ -7,10 +7,11 @@ INCLUDEPATH += $${LIBRESOURCEQT}/src $${LIBRESOURCEINC} $${LIBDBUSQEVENTLOOP} # Input HEADERS += $${POLICY}/resources.h $${POLICY}/resource-set.h test-resource-set.h \ - $${LIBRESOURCEQT}/src/resource-engine.h + $${POLICY}/audio-resource.h $${LIBRESOURCEQT}/src/resource-engine.h SOURCES += $${LIBRESOURCEQT}/src/resource.cpp $${LIBRESOURCEQT}/src/resources.cpp \ $${LIBRESOURCEQT}/src/resource-engine.cpp \ + $${LIBRESOURCEQT}/src/audio-resource.cpp \ $${LIBRESOURCEQT}/src/resource-set.cpp test-resource-set.cpp OBJECTS_DIR = build diff --git a/tests/test-resource/test-resource.h b/tests/test-resource/test-resource.h index d37dce4..6545d79 100644 --- a/tests/test-resource/test-resource.h +++ b/tests/test-resource/test-resource.h @@ -4,6 +4,7 @@ #include <QtTest/QTest> #include <QMetaType> #include <policy/resources.h> +#include <policy/audio-resource.h> Q_DECLARE_METATYPE(ResourcePolicy::ResourceType) diff --git a/tests/test-resource/test-resource.pro b/tests/test-resource/test-resource.pro index b103412..5d185ce 100644 --- a/tests/test-resource/test-resource.pro +++ b/tests/test-resource/test-resource.pro @@ -6,8 +6,11 @@ DEPENDPATH += $${POLICY} $${LIBRESOURCEQT}/src . INCLUDEPATH += $${LIBRESOURCEQT}/src $${LIBRESOURCEINC} # Input -HEADERS += $${POLICY}/resource.h $${POLICY}/resources.h test-resource.h -SOURCES += $${LIBRESOURCEQT}/src/resource.cpp $${LIBRESOURCEQT}/src/resources.cpp test-resource.cpp +HEADERS += $${POLICY}/resource.h $${POLICY}/resources.h $${POLICY}/audio-resource.h test-resource.h +SOURCES += $${LIBRESOURCEQT}/src/resource.cpp \ + $${LIBRESOURCEQT}/src/resources.cpp \ + $${LIBRESOURCEQT}/src/audio-resource.cpp \ + test-resource.cpp OBJECTS_DIR = build MOC_DIR = build |