2 * This file is part of CameraPlus.
4 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "cameraresources.h"
23 #include <dbusconnectioneventloop.h>
27 #define APPLICATION_CLASS "camera"
29 CameraResources::CameraResources(QObject *parent) :
31 m_worker(new CameraResourcesWorker) {
33 m_worker->moveToThread(&m_thread);
36 DBUSConnectionEventLoop::getInstance().moveToThread(&m_thread);
39 QObject::connect(&m_thread, SIGNAL(started()), m_worker, SLOT(init()));
42 qRegisterMetaType<CameraResources::Mode>("CameraResources::Mode");
43 qRegisterMetaType<bool *>("bool *");
45 QObject::connect(m_worker, SIGNAL(acquiredChanged()), this, SIGNAL(acquiredChanged()));
46 QObject::connect(m_worker, SIGNAL(hijackedChanged()), this, SIGNAL(hijackedChanged()));
47 QObject::connect(m_worker, SIGNAL(updated()), this, SIGNAL(updated()));
48 QObject::connect(m_worker, SIGNAL(acquiredChanged()), this, SIGNAL(scaleAcquisitionChanged()));
49 QObject::connect(m_worker, SIGNAL(hijackedChanged()), this, SIGNAL(scaleAcquisitionChanged()));
50 QObject::connect(m_worker, SIGNAL(updated()), this, SIGNAL(scaleAcquisitionChanged()));
53 CameraResources::~CameraResources() {
54 acquire(CameraResources::None);
57 while (m_thread.isRunning()) {
65 bool CameraResources::isResourceGranted(const ResourcePolicy::ResourceType& resource) const {
68 QMetaObject::invokeMethod(m_worker, "isResourceGranted", Qt::BlockingQueuedConnection,
69 Q_ARG(bool *, &ok), Q_ARG(int, resource));
74 bool CameraResources::acquire(const Mode& mode) {
77 QMetaObject::invokeMethod(m_worker, "acquire", Qt::BlockingQueuedConnection,
78 Q_ARG(bool *, &ok), Q_ARG(CameraResources::Mode, mode));
83 bool CameraResources::acquired() const {
86 QMetaObject::invokeMethod(m_worker, "acquired", Qt::BlockingQueuedConnection,
92 bool CameraResources::hijacked() const {
95 QMetaObject::invokeMethod(m_worker, "hijacked", Qt::BlockingQueuedConnection,
101 bool CameraResources::isScaleAcquired() const {
102 return isResourceGranted(ResourcePolicy::ScaleButtonType);
105 CameraResourcesWorker::CameraResourcesWorker(QObject *parent) :
108 m_mode(CameraResources::None),
115 CameraResourcesWorker::~CameraResourcesWorker() {
119 void CameraResourcesWorker::init() {
120 m_set = new ResourcePolicy::ResourceSet(APPLICATION_CLASS, this);
121 m_set->setAlwaysReply();
123 QObject::connect(m_set, SIGNAL(resourcesReleased()), this, SLOT(resourcesReleased()));
124 QObject::connect(m_set, SIGNAL(lostResources()), this, SLOT(lostResources()));
125 QObject::connect(m_set, SIGNAL(resourcesGranted(const QList<ResourcePolicy::ResourceType>&)),
126 this, SLOT(resourcesGranted(const QList<ResourcePolicy::ResourceType>&)));
127 QObject::connect(m_set, SIGNAL(resourcesDenied()), this, SLOT(resourcesDenied()));
129 if (!m_set->initAndConnect()) {
130 qCritical() << "Failed to connect to resource policy engine";
134 void CameraResourcesWorker::resourcesReleased() {
141 void CameraResourcesWorker::lostResources() {
148 void CameraResourcesWorker::resourcesGranted(const QList<ResourcePolicy::ResourceType>& optional) {
152 // This can happen when:
153 // 1) We lose/gain optional resources.
154 // 2) A higher priority application releases resources back.
164 void CameraResourcesWorker::resourcesDenied() {
171 QList<ResourcePolicy::ResourceType> CameraResourcesWorker::listSet() {
172 QList<ResourcePolicy::Resource *> resources = m_set->resources();
174 QList<ResourcePolicy::ResourceType> set;
176 foreach (ResourcePolicy::Resource *r, resources) {
183 void CameraResourcesWorker::acquire(bool *ok, const CameraResources::Mode& mode) {
184 if (mode == m_mode) {
194 case CameraResources::None:
198 case CameraResources::Image:
199 *ok = updateSet(QList<ResourcePolicy::ResourceType>()
200 << ResourcePolicy::VideoPlaybackType
201 << ResourcePolicy::VideoRecorderType,
202 QList<ResourcePolicy::ResourceType>()
203 << ResourcePolicy::ScaleButtonType);
206 case CameraResources::Video:
207 *ok = updateSet(QList<ResourcePolicy::ResourceType>()
208 << ResourcePolicy::VideoPlaybackType
209 << ResourcePolicy::VideoRecorderType,
210 QList<ResourcePolicy::ResourceType>()
211 << ResourcePolicy::ScaleButtonType);
214 case CameraResources::Recording:
215 *ok = updateSet(QList<ResourcePolicy::ResourceType>()
216 << ResourcePolicy::VideoPlaybackType
217 << ResourcePolicy::VideoRecorderType,
218 QList<ResourcePolicy::ResourceType>()
219 << ResourcePolicy::ScaleButtonType
220 << ResourcePolicy::AudioRecorderType
221 << ResourcePolicy::AudioPlaybackType);
224 case CameraResources::Player:
225 *ok = updateSet(QList<ResourcePolicy::ResourceType>()
226 << ResourcePolicy::VideoPlaybackType
227 << ResourcePolicy::AudioPlaybackType,
228 QList<ResourcePolicy::ResourceType>());
232 qWarning() << "Unknown mode" << mode;
238 void CameraResourcesWorker::acquired(bool *ok) {
242 void CameraResourcesWorker::hijacked(bool *ok) {
246 bool CameraResourcesWorker::updateSet(const QList<ResourcePolicy::ResourceType>& required,
247 const QList<ResourcePolicy::ResourceType>& optional) {
250 QList<ResourcePolicy::ResourceType> set = listSet();
252 foreach (ResourcePolicy::ResourceType r, set) {
253 if (required.indexOf(r) != -1) {
254 m_set->resource(r)->setOptional(false);
256 else if (optional.indexOf(r) != -1) {
257 m_set->resource(r)->setOptional(true);
260 m_set->deleteResource(r);
264 foreach (ResourcePolicy::ResourceType r, required) {
265 m_set->addResource(r);
268 foreach (ResourcePolicy::ResourceType r, optional) {
269 m_set->addResource(r);
270 ResourcePolicy::Resource *res = m_set->resource(r);
272 res->setOptional(true);
276 if (m_set->contains(ResourcePolicy::AudioPlaybackType)) {
277 bool isOptional = m_set->resource(ResourcePolicy::AudioPlaybackType)->isOptional();
279 ResourcePolicy::AudioResource *audio = new ResourcePolicy::AudioResource(APPLICATION_CLASS);
280 audio->setProcessID(QCoreApplication::applicationPid());
281 audio->setOptional(isOptional);
282 m_set->addResourceObject(audio);
290 while (m_acquiring) {
291 QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
297 bool CameraResourcesWorker::release() {
302 while (m_acquiring) {
303 QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
306 m_mode = CameraResources::None;
311 void CameraResourcesWorker::setAcquired(bool acquired) {
312 if (m_acquired != acquired) {
313 m_acquired = acquired;
314 emit acquiredChanged();
318 void CameraResourcesWorker::setHijacked(bool hijacked) {
319 if (m_hijacked != hijacked) {
320 m_hijacked = hijacked;
321 emit hijackedChanged();
325 void CameraResourcesWorker::isResourceGranted(bool *ok, int resource) {
327 ResourcePolicy::ResourceType rt = (ResourcePolicy::ResourceType)resource;
329 ResourcePolicy::Resource *r = m_set->resource(rt);
331 *ok = r->isGranted();