diff options
-rw-r--r-- | libresourceqt/include/qt4/policy/resource-set.h | 22 | ||||
-rw-r--r-- | libresourceqt/src/resource-engine.cpp | 38 | ||||
-rw-r--r-- | libresourceqt/src/resource-engine.h | 2 | ||||
-rw-r--r-- | libresourceqt/src/resource-set.cpp | 28 | ||||
-rw-r--r-- | resourceqt-client/client.cpp | 165 | ||||
-rw-r--r-- | resourceqt-client/client.h | 3 |
6 files changed, 192 insertions, 66 deletions
diff --git a/libresourceqt/include/qt4/policy/resource-set.h b/libresourceqt/include/qt4/policy/resource-set.h index dad892e..a36254d 100644 --- a/libresourceqt/include/qt4/policy/resource-set.h +++ b/libresourceqt/include/qt4/policy/resource-set.h @@ -104,6 +104,10 @@ USA. * So it is important that you connect to it. * * To modify the properties of the resources you can use the ResourcePolicy::ResourceSet::resource() method. + * + * \section see_devel_doc See Also + * For a more detailed guide see the + * <a href="https://projects.maemo.org/mediawiki/index.php/Maemo_Developer_Guide/Developing_Harmattan_applications/Application_policy_guidelines">Application policy guidelines</a>. */ /** @@ -209,6 +213,13 @@ public: QString applicationClass(); /** + * Initialize and connect the ResourceEngine of this ResourceSet. + * Use this method after adding resources to the ResourceSet initially. + * \return true if the method succeeds without encountering errors. + */ + bool initAndConnect(); + + /** * Try to acquire the \ref ResourceSet. The resourcesGranted() or * resourcesDenied() signal will be emited depending on whether the * requested resources could be acquired or not. @@ -280,6 +291,12 @@ signals: */ void resourcesReleased(); /** + * This signal is emited when the manager releases our acquired resources, + * so that we have to acquire them again when the user wishes to interact + * with us. + */ + void resourcesReleasedByManager(); + /** * This signal is emitted when some other program with a higher priority * supersedes 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 @@ -293,6 +310,11 @@ signals: */ void errorCallback(quint32, const char*); + /** + * This signals that we have connected to the Resource Manager. + */ + void connectedToManager(); + private: bool initialize(); diff --git a/libresourceqt/src/resource-engine.cpp b/libresourceqt/src/resource-engine.cpp index b9d9ee2..accb3a0 100644 --- a/libresourceqt/src/resource-engine.cpp +++ b/libresourceqt/src/resource-engine.cpp @@ -39,6 +39,7 @@ static void statusCallbackHandler(resset_t *rset, resmsg_t *msg); static void handleUnregisterMessage(resmsg_t *, resset_t *, void *data); static void handleGrantMessage(resmsg_t *msg, resset_t *rs, void *data); static void handleAdviceMessage(resmsg_t *msg, resset_t *rs, void *data); +static void handleReleaseMessage(resmsg_t *message, resset_t *rs, void *data); ResourceEngine::ResourceEngine(ResourceSet *resourceSet) : QObject(), connected(false), resourceSet(resourceSet), @@ -111,6 +112,7 @@ bool ResourceEngine::initialize() resproto_set_handler(ResourceEngine::libresourceConnection, RESMSG_UNREGISTER, handleUnregisterMessage); resproto_set_handler(ResourceEngine::libresourceConnection, RESMSG_GRANT, handleGrantMessage); resproto_set_handler(ResourceEngine::libresourceConnection, RESMSG_ADVICE, handleAdviceMessage); + resproto_set_handler(ResourceEngine::libresourceConnection, RESMSG_RELEASE, handleReleaseMessage); engineMap.insert(ResourceEngine::libresourceConnection, this); } else { @@ -186,12 +188,12 @@ void ResourceEngine::receivedGrant(resmsg_notify_t *notifyMessage) emit resourcesLost(allResourcesToBitmask(resourceSet)); } else if (originaloriginalMessageType == RESMSG_ACQUIRE) { - qDebug("ResourceEngine(%d) - request DENIED!", identifier); - emit resourcesDenied(); + qDebug("ResourceEngine(%d) - request DENIED!", identifier); + emit resourcesDenied(); } else if (originaloriginalMessageType == RESMSG_RELEASE) { - qDebug("ResourceEngine(%d) - confirmation to release", identifier); - emit resourcesReleased(); + qDebug("ResourceEngine(%d) - confirmation to release", identifier); + emit resourcesReleased(); } else { qDebug("ResourceEngine(%d) - Ignoring the receivedGrant", identifier); @@ -205,6 +207,34 @@ void ResourceEngine::receivedGrant(resmsg_notify_t *notifyMessage) messageMap.remove(notifyMessage->reqno); } +static void handleReleaseMessage(resmsg_t *message, resset_t *rs, void *) +{ + qDebug("**************** %s() - locking....", __FUNCTION__); + QMutexLocker locker(&mutex); + if (NULL == rs->userdata) { + qDebug("IGNORING release, no context"); + return; + } + ResourceEngine *engine = reinterpret_cast<ResourceEngine *>(rs->userdata); + qDebug("recv: release: type=%d, id=%d, reqno=%d, resc=0x%04x engine->id() = %d", + message->notify.type, message->notify.id, message->notify.reqno, + message->notify.resrc, engine->id()); + if(engine->id() != message->any.id) { + qDebug("Received an advice message, but it is not for us. Ignoring (%d != %d)", + engine->id(), message->any.id); + return; + } + + engine->receivedRelease(&(message->notify)); +} + +void ResourceEngine::receivedRelease(resmsg_notify_t *message) +{ + uint32_t allResources = allResourcesToBitmask(resourceSet); + qDebug("ResourceEngine(%d) - %s: have: %02x got %02x", identifier, __FUNCTION__, allResources, message->resrc); + emit resourcesReleasedByManager(); +} + static void handleAdviceMessage(resmsg_t *message, resset_t *libresourceSet, void *) { qDebug("**************** %s() - locking....", __FUNCTION__); diff --git a/libresourceqt/src/resource-engine.h b/libresourceqt/src/resource-engine.h index 66b37bd..e3e29c7 100644 --- a/libresourceqt/src/resource-engine.h +++ b/libresourceqt/src/resource-engine.h @@ -65,6 +65,7 @@ public: void disconnected(); void receivedGrant(resmsg_notify_t *notifyMessage); void receivedAdvice(resmsg_notify_t *notifyMessage); + void receivedRelease(resmsg_notify_t *notifyMessage); void handleStatusMessage(quint32 requestNo); void handleError(quint32 requestNo, qint32 code, const char *message); @@ -81,6 +82,7 @@ signals: void connectedToManager(); void disconnectedFromManager(); void errorCallback(quint32 code, const char* ); + void resourcesReleasedByManager(); private: bool connected; diff --git a/libresourceqt/src/resource-set.cpp b/libresourceqt/src/resource-set.cpp index 8b46664..190df5e 100644 --- a/libresourceqt/src/resource-set.cpp +++ b/libresourceqt/src/resource-set.cpp @@ -80,6 +80,8 @@ bool ResourceSet::initialize() this, SLOT(handleResourcesBecameAvailable(quint32))); QObject::connect(resourceEngine, SIGNAL(errorCallback(quint32, const char*)), this, SIGNAL(errorCallback(quint32, const char*))); + QObject::connect(resourceEngine, SIGNAL(resourcesReleasedByManager()), + this, SIGNAL(resourcesReleasedByManager())); qDebug("initializing resource engine..."); if (!resourceEngine->initialize()) { @@ -228,21 +230,32 @@ Resource * ResourceSet::resource(ResourceType type) const return resourceSet[type]; } -bool ResourceSet::acquire() +bool ResourceSet::initAndConnect() { - if (!initialized) { + if ( !initialized ) { qDebug("ResourceSet::%s().... initializing...", __FUNCTION__); - pendingAcquire = true; return initialize(); } - if (!resourceEngine->isConnectedToManager()) { + if ( !resourceEngine->isConnectedToManager() ) { qDebug("ResourceSet::%s().... connecting...", __FUNCTION__); + return resourceEngine->connectToManager(); + } + else + qDebug("ResourceSet::%s(): already connected", __FUNCTION__); + + return true; +} + +bool ResourceSet::acquire() +{ + if ( !initialized || !resourceEngine->isConnectedToManager() ) + { pendingAcquire = true; - resourceEngine->connectToManager(); - return true; + return initAndConnect(); } - else { + else + { qDebug("ResourceSet::%s().... acquiring", __FUNCTION__); return resourceEngine->acquireResources(); } @@ -309,6 +322,7 @@ void ResourceSet::connectedHandler() qDebug("**************** ResourceSet::%s().... %d", __FUNCTION__, __LINE__); if (resourceEngine->isConnectedToManager()) { qDebug("ResourceSet::%s() Connected to manager!", __FUNCTION__); + emit connectedToManager(); if (pendingAudioProperties) { registerAudioProperties(); diff --git a/resourceqt-client/client.cpp b/resourceqt-client/client.cpp index 7fdb2f6..fcfe36c 100644 --- a/resourceqt-client/client.cpp +++ b/resourceqt-client/client.cpp @@ -60,9 +60,8 @@ Client::Client() commandList["free"] = CommandListArgs("", "destroy and free the resources"); commandList["acquire"] = CommandListArgs("", "acquire required resources"); commandList["release"] = CommandListArgs("", "release resources"); - commandList["update"] = CommandListArgs("", "update modified resource set after add or remove command"); - commandList["add"] = CommandListArgs("reslist [-o]", "add resource list, if -o provided, set as optional"); - commandList["remove"] = CommandListArgs("reslist [-o]", "remove resource list, if -o provided, removed only optional flag"); + commandList["update"] = CommandListArgs("update <all>[:opt] where 'all' and 'opt' are comma separated resources", + "update the resource set by specifying the new set"); commandList["audio"] = CommandListArgs("pid <pid> | group <audio group> | tag <name> <value>", "set audio properties"); commandList["addaudio"] = CommandListArgs("<audio group> <pid> <tag name> <tag value>", "Add an audio resource and set the properties"); commandList["show"] = CommandListArgs("", "show resources"); @@ -130,16 +129,25 @@ bool Client::initialize(const CommandLineParser &parser) this, SLOT(resourcesBecameAvailableHandler(const QList<ResourcePolicy::ResourceType> &)))) { return false; } + if (!connect(resourceSet, SIGNAL(resourcesReleasedByManager()), + this, SLOT(resourceReleasedByManagerHandler()))) { + return false; + } if (!connect(&stdInNotifier, SIGNAL(activated(int)), this, SLOT(readLine(int)))) { return false; } + if (!connect(resourceSet , SIGNAL(connectedToManager()), this, SLOT(stopConnectTimerHandler()))) { + return false; + } if (!connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(doExit()))) { return false; } + + startTimer(); + resourceSet->initAndConnect(); OUTPUT << "accepting input" << endl; showPrompt(); - return true; } @@ -149,6 +157,73 @@ void Client::doExit() resourceSet->release(); } + +void Client::modifyResources(const QString &resString) +{ + //resString example: [mand_resources:opt_resources] res1,res2,res3:res1,res3 + if ( resString.isEmpty() || resString.isNull()){ + qDebug("Client::modifyResources(): no resources in string."); + return; + } + QStringList newAllAndOpt = resString.split(":"); + + if (newAllAndOpt.size()==1) + qDebug("There are only mandatory resources."); + + //Every optional res. is also in allSet + QSet<ResourcePolicy::ResourceType> newAllSet; + QSet<ResourcePolicy::ResourceType> newOptSet; + + if ( !CommandLineParser::parseResourceList(newAllAndOpt.at(0), newAllSet) ) { + qDebug("Client::modifyResources(): could not parse all resources."); + return; + } + + if (newAllAndOpt.size()>1) { + if ( !CommandLineParser::parseResourceList(newAllAndOpt.at(1), newOptSet) ){ + qDebug("Client::modifyResources(): could not parse optional resources."); + return; + } + bool optNotInAll = false; + //If the user forgot to add resource to all when specifying optional -> add to all. + foreach(ResourceType newOptRes, newOptSet){ + if ( !newAllSet.contains(newOptRes) ){ + optNotInAll = true; + newAllSet.insert(newOptRes); + } + } + if (optNotInAll) + qDebug("Client::modifyResources(): optional resources should be added to all as well."); + } + + //Check if new resources are in current resource set. + foreach ( ResourceType newRes, newAllSet) { + if ( resourceSet->contains(newRes) ){ + if ( resourceSet->resource(newRes)->isOptional() && !newOptSet.contains(newRes) ) { + //New mandatory is in set, but is not optional in the new set. + resourceSet->resource(newRes)->setOptional(false); + } + else if ( !resourceSet->resource(newRes)->isOptional() && newOptSet.contains(newRes) ){ + //New mandatory is in set, but is optional. + resourceSet->resource(newRes)->setOptional(true); + } + } + else { //Add new resource. + resourceSet->addResource(newRes); + + if ( newOptSet.contains(newRes) ) + resourceSet->resource(newRes)->setOptional(true); + } + } + QList<Resource*> resList = resourceSet->resources(); + //Check if there are current resources not in the new set (i.e. removed). + foreach(Resource* resource, resList) + if ( !newAllSet.contains(resource->type()) ) + resourceSet->deleteResource(resource->type()); + +} + + const char * resourceTypeToString(ResourceType type) { switch (type) { @@ -204,6 +279,11 @@ void Client::showResources(const QList<Resource*> &resList) } } +void Client::stopConnectTimerHandler() +{ + stopTimer(); +} + void Client::resourceAcquiredHandler(const QList<ResourceType>&) { stopTimer(); @@ -250,6 +330,15 @@ void Client::resourceReleasedHandler() showPrompt(); } +void Client::resourceReleasedByManagerHandler() +{ + stopTimer(); + + QList<Resource*> allResources = resourceSet->resources(); + outputln << "mgr-released:"<< allResources << endl; + showPrompt(); +} + void Client::resourcesBecameAvailableHandler(const QList<ResourcePolicy::ResourceType> &availableResources) { if (pendingAddAudio) { @@ -320,60 +409,26 @@ void Client::readLine(int) qCritical("%s failed!", qPrintable(command)); } } - else if (command == "add") { - QString resourceList, flag; - input >> resourceList >> flag; - if (!resourceSet) { - qCritical("%s%s failed!", qPrintable(prefix), qPrintable(command)); - } - else if (resourceList.isEmpty() || resourceList.isNull()) { - OUTPUT << "List of desired resources is missing. Use help."; - } - else { - bool optional = false; - QSet<ResourcePolicy::ResourceType> resToAdd; - CommandLineParser::parseResourceList(resourceList, resToAdd); - if (flag == "-o") { - optional = true; - } - foreach(ResourcePolicy::ResourceType resource, resToAdd) { - if (!resourceSet->contains(resource)) { - resourceSet->addResource(resource); - } - if (optional) { - resourceSet->resource(resource)->setOptional(); - } - } - } - } - else if (command == "remove") { - QString resourceList, flag; - input >> resourceList >> flag; - if (!resourceSet) { - qCritical("%s%s failed!", qPrintable(prefix), qPrintable(command)); - } - else if (resourceList.isEmpty() || resourceList.isNull()) { - OUTPUT << "List of desired resources is missing. Use help."; + else if (command == "update") { + + QString resourceList; + input >> resourceList; + + if (!resourceSet) + qCritical("%s failed!", qPrintable(command)); + + if (resourceList.isEmpty() || resourceList.isNull()) { + qCritical("%s failed! List of desired resources is missing. Use help.", + qPrintable(command)); } else { - QSet<ResourcePolicy::ResourceType> resToRemove; - CommandLineParser::parseResourceList(resourceList, resToRemove); - if (flag == "-o") { - foreach(ResourcePolicy::ResourceType resource, resToRemove) { - resourceSet->resource(resource)->setOptional(false); - } - } - else { - foreach(ResourcePolicy::ResourceType resource, resToRemove) { - resourceSet->deleteResource(resource); - } - } - } - } - else if (command == "update") { - if (!resourceSet || !resourceSet->update()) { - qCritical("%s%s failed!", qPrintable(prefix), qPrintable(command)); + startTimer(); + modifyResources(resourceList); + + if (!resourceSet->update()) + qCritical("%s failed!", qPrintable(command)); } + } else if (command == "audio") { QString what, group, tagName, tagValue; diff --git a/resourceqt-client/client.h b/resourceqt-client/client.h index 3967fee..6d92a30 100644 --- a/resourceqt-client/client.h +++ b/resourceqt-client/client.h @@ -59,9 +59,11 @@ private slots: void resourceDeniedHandler(); void resourceLostHandler(); void resourceReleasedHandler(); + void resourceReleasedByManagerHandler(); void resourcesBecameAvailableHandler(const QList<ResourcePolicy::ResourceType> &availableResources); void readLine(int); void doExit(); + void stopConnectTimerHandler(); private: QTextStream standardInput; @@ -81,6 +83,7 @@ private: void showPrompt(); void showResources(const QList<ResourcePolicy::ResourceType> &resList); void showResources(const QList<ResourcePolicy::Resource*> &resList); + void modifyResources(const QString &resString); inline void startTimer(); inline void stopTimer(); }; |