summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libresourceqt/include/qt4/policy/resource-set.h22
-rw-r--r--libresourceqt/src/resource-engine.cpp38
-rw-r--r--libresourceqt/src/resource-engine.h2
-rw-r--r--libresourceqt/src/resource-set.cpp28
-rw-r--r--resourceqt-client/client.cpp165
-rw-r--r--resourceqt-client/client.h3
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();
};