Skip to content

Commit

Permalink
Implement more full resource policy features.
Browse files Browse the repository at this point in the history
 * Handle released by manager properly.

Signal resourcesReleasedByManager is different from signal
handleResourcesLost and needs to be handled separately.
Signal handleResourcesLost means some other client has acquired the
resources, thus the resources are lost from us, but if the other client
frees the resources, we will automatically get the resources back.
With resourcesReleasedByManager we lose the resources, and resource
manager releases them as well (same as if client would call release()),
so only way to re-acquire resources in latter case is calling acquire()
again.

This distinction is useful for example in cases where user is listening
to music with headphones connected and removes the headphones, then the
music player shouldn't continue playback until user requests so. But if
user is listening to music when phone call is received, it is convenient
to resume the playback automatically after the call.

 * Implement availability changed.

Availability changed is information whether resources the client is
interested in are available (no higher priority resource classes have
acquired the resources).

 * Implement missing resources released.

Emit resourcesReleased signal when receiving corresponding signal from
libresource-qt.

 * Add mechanism to change used resource class.

Check for environment for special variable, and if the variable has
proper data, use that as the resource class. Can be set with for example
qputenv("NEMO_RESOURCE_CLASS_OVERRIDE", "game");

Change-Id: I8e92f40cc5c01b6b94f54c3fa0f7a07775e87df0
Done-with: Juho Hämäläinen <juho.hamalainen@tieto.com>
Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
  • Loading branch information
rburchell authored and Robin Burchell committed Aug 4, 2014
1 parent 0ed18d8 commit 1c5ea95
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 18 deletions.
3 changes: 2 additions & 1 deletion src/plugins/resourcepolicy/resourcepolicyimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ ResourcePolicyImpl::ResourcePolicyImpl(QObject *parent)
ResourcePolicyImpl::~ResourcePolicyImpl()
{
ResourcePolicyInt *set = globalResourcePolicyInt;
set->removeClient(this);
if (!globalResourcePolicyInt.isDestroyed())
set->removeClient(this);
}

bool ResourcePolicyImpl::isVideoEnabled() const
Expand Down
130 changes: 113 additions & 17 deletions src/plugins/resourcepolicy/resourcepolicyint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
#include "resourcepolicyimpl.h"

#include <QMap>
#include <QByteArray>
#include <QString>

static int clientid = 0;

Expand All @@ -57,26 +59,51 @@ ResourcePolicyInt::ResourcePolicyInt(QObject *parent)
, m_acquired(0)
, m_status(Initial)
, m_video(0)
, m_available(false)
, m_resourceSet(0)
{
m_resourceSet = new ResourcePolicy::ResourceSet("player", this);
m_resourceSet->setAlwaysReply();
const char *resourceClass = "player";

QByteArray envVar = qgetenv("NEMO_RESOURCE_CLASS_OVERRIDE");
if (!envVar.isEmpty()) {
QString data(envVar);
// Only allow few resource classes
if (data == "navigator" ||
data == "call" ||
data == "camera" ||
data == "game" ||
data == "player" ||
data == "event")
resourceClass = envVar.constData();
}

ResourcePolicy::AudioResource *audioResource = new ResourcePolicy::AudioResource("player");
audioResource->setProcessID(QCoreApplication::applicationPid());
audioResource->setStreamTag("media.name", "*");
m_resourceSet->addResourceObject(audioResource);
#ifdef RESOURCE_DEBUG
qDebug() << "##### Using resource class " << resourceClass;
#endif

m_resourceSet->update();
m_resourceSet = new ResourcePolicy::ResourceSet(resourceClass, this);
m_resourceSet->setAlwaysReply();

connect(m_resourceSet, SIGNAL(resourcesGranted(QList<ResourcePolicy::ResourceType>)),
this, SLOT(handleResourcesGranted()));
connect(m_resourceSet, SIGNAL(resourcesDenied()),
this, SLOT(handleResourcesDenied()));
connect(m_resourceSet, SIGNAL(resourcesReleased()),
this, SLOT(handleResourcesReleased()));
connect(m_resourceSet, SIGNAL(lostResources()),
this, SLOT(handleResourcesLost()));
connect(m_resourceSet, SIGNAL(resourcesReleasedByManager()),
this, SLOT(handleResourcesLost()));
this, SLOT(handleResourcesReleasedByManager()));

connect(m_resourceSet, SIGNAL(resourcesBecameAvailable(const QList<ResourcePolicy::ResourceType>)),
this, SLOT(handleResourcesBecameAvailable(const QList<ResourcePolicy::ResourceType>)));

ResourcePolicy::AudioResource *audioResource = new ResourcePolicy::AudioResource(resourceClass);

audioResource->setProcessID(QCoreApplication::applicationPid());
audioResource->setStreamTag("media.name", "*");
m_resourceSet->addResourceObject(audioResource);
m_resourceSet->update();
}

ResourcePolicyInt::~ResourcePolicyInt()
Expand Down Expand Up @@ -113,7 +140,7 @@ void ResourcePolicyInt::removeClient(ResourcePolicyImpl *client)
m_clients.erase(i);
}

if (m_acquired == 0) {
if (m_acquired == 0 && m_status != Initial) {
#ifdef RESOURCE_DEBUG
qDebug() << "##### Remove client, acquired = 0, release";
#endif
Expand Down Expand Up @@ -221,10 +248,11 @@ void ResourcePolicyInt::release(const ResourcePolicyImpl *client)
#ifdef RESOURCE_DEBUG
qDebug() << "##### " << i.value().id << ": RELEASE, acquired (" << m_acquired << ")";
#endif
emit i.value().client->resourcesReleased();
}
}

if (m_acquired == 0) {
if (m_acquired == 0 && m_status != Initial) {
#ifdef RESOURCE_DEBUG
qDebug() << "##### " << i.value().id << ": RELEASE call resourceSet->release()";
#endif
Expand All @@ -248,9 +276,10 @@ bool ResourcePolicyInt::isGranted(const ResourcePolicyImpl *client) const

bool ResourcePolicyInt::isAvailable() const
{
// TODO: is this used? what is it for?
qWarning() << Q_FUNC_INFO << "Stub";
return true;
#ifdef RESOURCE_DEBUG
qDebug() << "##### isAvailable " << m_available;
#endif
return m_available;
}

void ResourcePolicyInt::handleResourcesGranted()
Expand Down Expand Up @@ -288,24 +317,91 @@ void ResourcePolicyInt::handleResourcesDenied()
}
}

void ResourcePolicyInt::handleResourcesReleased()
{
m_status = Initial;
m_acquired = 0;
QMap<const ResourcePolicyImpl*, clientEntry>::iterator i = m_clients.begin();
while (i != m_clients.end()) {
if (i.value().status == GrantedResource) {
#ifdef RESOURCE_DEBUG
qDebug() << "##### " << i.value().id << ": HANDLE RELEASED, acquired (" << m_acquired << ") emitting resourcesReleased()";
#endif
i.value().status = Initial;
emit i.value().client->resourcesReleased();
}
++i;
}
}

void ResourcePolicyInt::handleResourcesLost()
{
if (m_status != Initial) {
m_status = Initial;
// If resources were granted switch to acquiring state,
// so that if the resources are freed elsewhere we
// will acquire them again properly.
if (m_status == GrantedResource)
m_status = RequestedResource;

m_acquired = 0;

QMap<const ResourcePolicyImpl*, clientEntry>::iterator i = m_clients.begin();
while (i != m_clients.end()) {
if (i.value().status == GrantedResource) {
#ifdef RESOURCE_DEBUG
qDebug() << "##### " << i.value().id << ": HANDLE LOST, acquired (" << m_acquired << ") emitting resourcesLost()";
#endif
i.value().status = RequestedResource;
emit i.value().client->resourcesLost();
}
++i;
}
}

void ResourcePolicyInt::handleResourcesReleasedByManager()
{
if (m_status != Initial)
m_status = Initial;

m_acquired = 0;
m_resourceSet->release();

QMap<const ResourcePolicyImpl*, clientEntry>::iterator i = m_clients.begin();
while (i != m_clients.end()) {
if (i.value().status != Initial) {
#ifdef RESOURCE_DEBUG
qDebug() << "##### " << i.value().id << ": HANDLE LOST, acquired (" << m_acquired << ") emitting resourcesLost()";
qDebug() << "##### " << i.value().id << ": HANDLE RELEASEDBYMANAGER, acquired (" << m_acquired << ") emitting resourcesLost()";
#endif
i.value().status = Initial;
emit i.value().client->resourcesLost();
}
++i;
}
}

void ResourcePolicyInt::handleResourcesBecameAvailable(const QList<ResourcePolicy::ResourceType> &resources)
{
bool available = false;

for (int i = 0; i < resources.size(); ++i) {
if (resources.at(i) == ResourcePolicy::AudioPlaybackType)
available = true;
}

availabilityChanged(available);
}

void ResourcePolicyInt::availabilityChanged(bool available)
{
if (available == m_available)
return;

m_available = available;

QMap<const ResourcePolicyImpl*, clientEntry>::const_iterator i = m_clients.constBegin();
while (i != m_clients.constEnd()) {
#ifdef RESOURCE_DEBUG
qDebug() << "##### " << i.value().id << ": emitting availabilityChanged(" << m_available << ")";
#endif
emit i.value().client->availabilityChanged(m_available);
++i;
}
}
8 changes: 8 additions & 0 deletions src/plugins/resourcepolicy/resourcepolicyint.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
#include <QObject>
#include <QMap>

#include <policy/resource-set.h>
#include <policy/resource.h>
#include <private/qmediaresourceset_p.h>
#include "resourcepolicyimpl.h"

Expand Down Expand Up @@ -86,14 +88,20 @@ class ResourcePolicyInt : public QObject
private slots:
void handleResourcesGranted();
void handleResourcesDenied();
void handleResourcesReleased();
void handleResourcesLost();
void handleResourcesReleasedByManager();
void handleResourcesBecameAvailable(const QList<ResourcePolicy::ResourceType> &resources);

private:
void availabilityChanged(bool available);

QMap<const ResourcePolicyImpl*, clientEntry> m_clients;

int m_acquired;
ResourceStatus m_status;
int m_video;
bool m_available;
ResourcePolicy::ResourceSet *m_resourceSet;
};

Expand Down

0 comments on commit 1c5ea95

Please sign in to comment.