diff --git a/src/plugins/resourcepolicy/resourcepolicy.pro b/src/plugins/resourcepolicy/resourcepolicy.pro index 7aa1ced9..4805c525 100644 --- a/src/plugins/resourcepolicy/resourcepolicy.pro +++ b/src/plugins/resourcepolicy/resourcepolicy.pro @@ -13,9 +13,11 @@ INCLUDEPATH += $$PWD \ HEADERS += \ $$PWD/resourcepolicyplugin.h \ - $$PWD/resourcepolicyimpl.h + $$PWD/resourcepolicyimpl.h \ + $$PWD/resourcepolicyint.h SOURCES += \ $$PWD/resourcepolicyplugin.cpp \ - $$PWD/resourcepolicyimpl.cpp + $$PWD/resourcepolicyimpl.cpp \ + $$PWD/resourcepolicyint.cpp diff --git a/src/plugins/resourcepolicy/resourcepolicyimpl.cpp b/src/plugins/resourcepolicy/resourcepolicyimpl.cpp index 0acabc00..3ad92fa1 100644 --- a/src/plugins/resourcepolicy/resourcepolicyimpl.cpp +++ b/src/plugins/resourcepolicy/resourcepolicyimpl.cpp @@ -40,99 +40,62 @@ ** ****************************************************************************/ +#include + #include #include #include #include "resourcepolicyimpl.h" +#include "resourcepolicyint.h" + +Q_GLOBAL_STATIC(ResourcePolicyInt, globalResourcePolicyInt); ResourcePolicyImpl::ResourcePolicyImpl(QObject *parent) : QMediaPlayerResourceSetInterface(parent) - , m_status(Initial) - , m_videoEnabled(false) { - m_resourceSet = new ResourcePolicy::ResourceSet("player", this); - m_resourceSet->setAlwaysReply(); + ResourcePolicyInt *set = globalResourcePolicyInt; + set->addClient(this); +} - ResourcePolicy::AudioResource *audioResource = new ResourcePolicy::AudioResource("player"); - audioResource->setProcessID(QCoreApplication::applicationPid()); - audioResource->setStreamTag("media.name", "*"); - m_resourceSet->addResourceObject(audioResource); - - m_resourceSet->update(); - - connect(m_resourceSet, SIGNAL(resourcesGranted(QList)), - this, SLOT(handleResourcesGranted())); - connect(m_resourceSet, SIGNAL(resourcesDenied()), - this, SLOT(handleResourcesDenied())); - connect(m_resourceSet, SIGNAL(lostResources()), - this, SLOT(handleResourcesLost())); - connect(m_resourceSet, SIGNAL(resourcesReleasedByManager()), - this, SLOT(handleResourcesLost())); +ResourcePolicyImpl::~ResourcePolicyImpl() +{ + ResourcePolicyInt *set = globalResourcePolicyInt; + set->removeClient(this); } bool ResourcePolicyImpl::isVideoEnabled() const { - return m_videoEnabled; + ResourcePolicyInt *set = globalResourcePolicyInt; + return set->isVideoEnabled(this); } void ResourcePolicyImpl::setVideoEnabled(bool videoEnabled) { - if (m_videoEnabled != videoEnabled) { - m_videoEnabled = videoEnabled; - - if (videoEnabled) - m_resourceSet->addResource(ResourcePolicy::VideoPlaybackType); - else - m_resourceSet->deleteResource(ResourcePolicy::VideoPlaybackType); - - m_resourceSet->update(); - } + ResourcePolicyInt *set = globalResourcePolicyInt; + set->setVideoEnabled(this, videoEnabled); } void ResourcePolicyImpl::acquire() { - m_status = RequestedResource; - m_resourceSet->acquire(); + ResourcePolicyInt *set = globalResourcePolicyInt; + set->acquire(this); } void ResourcePolicyImpl::release() { - m_resourceSet->release(); - m_status = Initial; + ResourcePolicyInt *set = globalResourcePolicyInt; + set->release(this); } bool ResourcePolicyImpl::isGranted() const { - return m_status == GrantedResource; + ResourcePolicyInt *set = globalResourcePolicyInt; + return set->isGranted(this); } bool ResourcePolicyImpl::isAvailable() const { - // TODO: is this used? what is it for? - qWarning() << Q_FUNC_INFO << "Stub"; - return true; + ResourcePolicyInt *set = globalResourcePolicyInt; + return set->isAvailable(); } - -void ResourcePolicyImpl::handleResourcesGranted() -{ - m_status = GrantedResource; - emit resourcesGranted(); -} - -void ResourcePolicyImpl::handleResourcesDenied() -{ - m_status = Initial; - emit resourcesDenied(); -} - -void ResourcePolicyImpl::handleResourcesLost() -{ - if (m_status != Initial) { - m_status = Initial; - emit resourcesLost(); - } - - m_resourceSet->release(); -} - diff --git a/src/plugins/resourcepolicy/resourcepolicyimpl.h b/src/plugins/resourcepolicy/resourcepolicyimpl.h index 8680df86..28393b78 100644 --- a/src/plugins/resourcepolicy/resourcepolicyimpl.h +++ b/src/plugins/resourcepolicy/resourcepolicyimpl.h @@ -56,6 +56,7 @@ class ResourcePolicyImpl : public QMediaPlayerResourceSetInterface Q_OBJECT public: ResourcePolicyImpl(QObject *parent = 0); + ~ResourcePolicyImpl(); bool isVideoEnabled() const; void setVideoEnabled(bool videoEnabled); @@ -63,22 +64,6 @@ public: void release(); bool isGranted() const; bool isAvailable() const; - -private slots: - void handleResourcesGranted(); - void handleResourcesDenied(); - void handleResourcesLost(); - -private: - enum ResourceStatus { - Initial = 0, - RequestedResource, - GrantedResource - }; - - bool m_videoEnabled; - ResourcePolicy::ResourceSet *m_resourceSet; - ResourceStatus m_status; }; #endif // RESOURCEPOLICYIMPL_H diff --git a/src/plugins/resourcepolicy/resourcepolicyint.cpp b/src/plugins/resourcepolicy/resourcepolicyint.cpp new file mode 100644 index 00000000..2fff64bf --- /dev/null +++ b/src/plugins/resourcepolicy/resourcepolicyint.cpp @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Jolla Ltd, author: +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include + +#include "resourcepolicyint.h" +#include "resourcepolicyimpl.h" + +#include + +static int clientid = 0; + +ResourcePolicyInt::ResourcePolicyInt(QObject *parent) + : QObject(parent) + , m_acquired(0) + , m_status(Initial) + , m_video(0) + , m_resourceSet(0) +{ + m_resourceSet = new ResourcePolicy::ResourceSet("player", this); + m_resourceSet->setAlwaysReply(); + + ResourcePolicy::AudioResource *audioResource = new ResourcePolicy::AudioResource("player"); + audioResource->setProcessID(QCoreApplication::applicationPid()); + audioResource->setStreamTag("media.name", "*"); + m_resourceSet->addResourceObject(audioResource); + + m_resourceSet->update(); + + connect(m_resourceSet, SIGNAL(resourcesGranted(QList)), + this, SLOT(handleResourcesGranted())); + connect(m_resourceSet, SIGNAL(resourcesDenied()), + this, SLOT(handleResourcesDenied())); + connect(m_resourceSet, SIGNAL(lostResources()), + this, SLOT(handleResourcesLost())); + connect(m_resourceSet, SIGNAL(resourcesReleasedByManager()), + this, SLOT(handleResourcesLost())); +} + +ResourcePolicyInt::~ResourcePolicyInt() +{ + delete m_resourceSet; + m_resourceSet = 0; +#ifdef RESOURCE_DEBUG + qDebug() << "##### Tearing down singleton."; +#endif +} + +void ResourcePolicyInt::addClient(ResourcePolicyImpl *client) +{ + clientEntry entry; + entry.id = clientid++; + entry.client = client; + entry.status = Initial; + entry.videoEnabled = false; + m_clients.insert(entry.client, entry); +#ifdef RESOURCE_DEBUG + qDebug() << "##### Add client " << client << " : " << entry.id; +#endif +} + +void ResourcePolicyInt::removeClient(ResourcePolicyImpl *client) +{ + QMap::iterator i = m_clients.find(client); + if (i != m_clients.end()) { +#ifdef RESOURCE_DEBUG + qDebug() << "##### Remove client " << client << " : " << i.value().id; +#endif + if (i.value().status == GrantedResource) + --m_acquired; + m_clients.erase(i); + } + + if (m_acquired == 0) { +#ifdef RESOURCE_DEBUG + qDebug() << "##### Remove client, acquired = 0, release"; +#endif + m_resourceSet->release(); + m_status = Initial; + } +} + +bool ResourcePolicyInt::isVideoEnabled(const ResourcePolicyImpl *client) const +{ + QMap::const_iterator i = m_clients.find(client); + if (i != m_clients.constEnd()) + return i.value().videoEnabled; + + return false; +} + +void ResourcePolicyInt::setVideoEnabled(const ResourcePolicyImpl *client, bool videoEnabled) +{ + bool update = false; + + QMap::iterator i = m_clients.find(client); + if (i != m_clients.end()) { + if (videoEnabled == i.value().videoEnabled) + return; + + if (videoEnabled) { + if (m_video > 0) { + i.value().videoEnabled = true; + } else { + m_resourceSet->addResource(ResourcePolicy::VideoPlaybackType); + update = true; + } + ++m_video; + } else { + --m_video; + i.value().videoEnabled = false; + if (m_video == 0) { + m_resourceSet->deleteResource(ResourcePolicy::VideoPlaybackType); + update = true; + } + } + } + + if (update) + m_resourceSet->update(); +} + +void ResourcePolicyInt::acquire(const ResourcePolicyImpl *client) +{ + QMap::iterator i = m_clients.find(client); + if (i != m_clients.end()) { +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": ACQUIRE"; +#endif + if (i.value().status == Initial) { + + if (m_status == RequestedResource) { + i.value().status = RequestedResource; +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": Already requesting, set client as RequestResource and return"; +#endif + return; + } + + if (m_status == GrantedResource) { + ++m_acquired; +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": Already granted, set as GrantedResource and return"; +#endif + i.value().status = GrantedResource; + emit i.value().client->resourcesGranted(); + return; + } + } else if (i.value().status == RequestedResource) { +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": Already requesting, return"; +#endif + return; + } else { +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": Already granted, return "; +#endif + return; + } + i.value().status = RequestedResource; + m_status = RequestedResource; + +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": ACQUIRE call resourceSet->acquire()"; +#endif + // If m_status was Initial this is the first time resources are requested, + // so let's actually do the acquiring + m_resourceSet->acquire(); + } +} + +void ResourcePolicyInt::release(const ResourcePolicyImpl *client) +{ + QMap::iterator i = m_clients.find(client); + if (i != m_clients.end()) { + if (i.value().status == GrantedResource) { + i.value().status = Initial; + --m_acquired; +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": RELEASE, acquired (" << m_acquired << ")"; +#endif + } + } + + if (m_acquired == 0) { +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": RELEASE call resourceSet->release()"; +#endif + m_resourceSet->release(); + m_status = Initial; + } +} + +bool ResourcePolicyInt::isGranted(const ResourcePolicyImpl *client) const +{ + QMap::const_iterator i = m_clients.find(client); + if (i != m_clients.constEnd()) { +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": IS GRANTED, status: " << i.value().status; +#endif + return i.value().status == GrantedResource; + } + + return false; +} + +bool ResourcePolicyInt::isAvailable() const +{ + // TODO: is this used? what is it for? + qWarning() << Q_FUNC_INFO << "Stub"; + return true; +} + +void ResourcePolicyInt::handleResourcesGranted() +{ + m_status = GrantedResource; + QMap::iterator i = m_clients.begin(); + while (i != m_clients.end()) { + if (i.value().status == RequestedResource) { + ++m_acquired; +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": HANDLE GRANTED, acquired (" << m_acquired << ") emitting resourcesGranted()"; +#endif + i.value().status = GrantedResource; + emit i.value().client->resourcesGranted(); + } + ++i; + } +} + +void ResourcePolicyInt::handleResourcesDenied() +{ + m_status = Initial; + m_acquired = 0; + QMap::iterator i = m_clients.begin(); + while (i != m_clients.end()) { + if (i.value().status == RequestedResource) { +#ifdef RESOURCE_DEBUG + qDebug() << "##### " << i.value().id << ": HANDLE DENIED, acquired (" << m_acquired << ") emitting resourcesDenied()"; +#endif + i.value().status = Initial; + emit i.value().client->resourcesDenied(); + } + // Do we need to act for clients that are in granted state? + ++i; + } +} + +void ResourcePolicyInt::handleResourcesLost() +{ + if (m_status != Initial) { + m_status = Initial; + } + + m_acquired = 0; + m_resourceSet->release(); + + QMap::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()"; +#endif + i.value().status = Initial; + emit i.value().client->resourcesLost(); + } + ++i; + } +} diff --git a/src/plugins/resourcepolicy/resourcepolicyint.h b/src/plugins/resourcepolicy/resourcepolicyint.h new file mode 100644 index 00000000..39882b52 --- /dev/null +++ b/src/plugins/resourcepolicy/resourcepolicyint.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Jolla Ltd, author: +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RESOURCEPOLICYINT_H +#define RESOURCEPOLICYINT_H + +#include +#include + +#include +#include "resourcepolicyimpl.h" + +namespace ResourcePolicy { + class ResourceSet; +}; + +enum ResourceStatus { + Initial = 0, + RequestedResource, + GrantedResource +}; + +struct clientEntry { + int id; + ResourcePolicyImpl *client; + ResourceStatus status; + bool videoEnabled; +}; + +class ResourcePolicyInt : public QObject +{ + Q_OBJECT +public: + ResourcePolicyInt(QObject *parent = 0); + ~ResourcePolicyInt(); + + bool isVideoEnabled(const ResourcePolicyImpl *client) const; + void setVideoEnabled(const ResourcePolicyImpl *client, bool videoEnabled); + void acquire(const ResourcePolicyImpl *client); + void release(const ResourcePolicyImpl *client); + bool isGranted(const ResourcePolicyImpl *client) const; + bool isAvailable() const; + + void addClient(ResourcePolicyImpl *client); + void removeClient(ResourcePolicyImpl *client); + +private slots: + void handleResourcesGranted(); + void handleResourcesDenied(); + void handleResourcesLost(); + +private: + QMap m_clients; + + int m_acquired; + ResourceStatus m_status; + int m_video; + ResourcePolicy::ResourceSet *m_resourceSet; +}; + +#endif // RESOURCEPOLICYINT_H