2 * This file is part of CameraPlus.
4 * Copyright (C) 2012 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"
22 #include <dbusconnectioneventloop.h>
25 // TODO: video recording ?
26 // TODO: more resources ?
27 CameraResources::CameraResources(QObject *parent) :
29 m_worker(new CameraResourcesWorker) {
31 m_worker->moveToThread(&m_thread);
32 DBUSConnectionEventLoop::getInstance().moveToThread(&m_thread);
34 QObject::connect(&m_thread, SIGNAL(started()), m_worker, SLOT(init()));
37 qRegisterMetaType<CameraResources::Mode>("CameraResources::Mode");
38 qRegisterMetaType<CameraResources::ResourceType>("CameraResources::ResourceType");
39 qRegisterMetaType<bool *>("bool *");
41 QObject::connect(m_worker, SIGNAL(acquiredChanged()), this, SIGNAL(acquiredChanged()));
42 QObject::connect(m_worker, SIGNAL(hijackedChanged()), this, SIGNAL(hijackedChanged()));
43 QObject::connect(m_worker, SIGNAL(updated()), this, SIGNAL(updated()));
46 CameraResources::~CameraResources() {
54 bool CameraResources::isResourceGranted(const ResourceType& resource) {
57 QMetaObject::invokeMethod(m_worker, "isResourceGranted", Qt::BlockingQueuedConnection,
58 Q_ARG(bool *, &ok), Q_ARG(CameraResources::ResourceType, resource));
63 bool CameraResources::acquire(const Mode& mode) {
66 QMetaObject::invokeMethod(m_worker, "acquire", Qt::BlockingQueuedConnection,
67 Q_ARG(bool *, &ok), Q_ARG(CameraResources::Mode, mode));
72 bool CameraResources::acquired() const {
75 QMetaObject::invokeMethod(m_worker, "acquired", Qt::BlockingQueuedConnection,
81 bool CameraResources::hijacked() const {
84 QMetaObject::invokeMethod(m_worker, "hijacked", Qt::BlockingQueuedConnection,
90 CameraResourcesWorker::CameraResourcesWorker(QObject *parent) :
93 m_mode(CameraResources::None),
100 CameraResourcesWorker::~CameraResourcesWorker() {
103 acquire(&ok, CameraResources::None);
106 void CameraResourcesWorker::init() {
107 m_set = new ResourcePolicy::ResourceSet("camera", this);
108 m_set->setAlwaysReply();
110 QObject::connect(m_set, SIGNAL(resourcesReleased()), this, SLOT(resourcesReleased()));
111 QObject::connect(m_set, SIGNAL(lostResources()), this, SLOT(lostResources()));
112 QObject::connect(m_set, SIGNAL(resourcesGranted(const QList<ResourcePolicy::ResourceType>&)),
113 this, SLOT(resourcesGranted(const QList<ResourcePolicy::ResourceType>&)));
114 QObject::connect(m_set, SIGNAL(resourcesDenied()), this, SLOT(resourcesDenied()));
116 if (!m_set->initAndConnect()) {
117 qCritical() << "Failed to connect to resource policy engine";
121 void CameraResourcesWorker::resourcesReleased() {
128 void CameraResourcesWorker::lostResources() {
135 void CameraResourcesWorker::resourcesGranted(const QList<ResourcePolicy::ResourceType>& optional) {
139 // This can happen when:
140 // 1) We lose/gain optional resources.
141 // 2) A higher priority application releases resources back.
151 void CameraResourcesWorker::resourcesDenied() {
158 QList<ResourcePolicy::ResourceType> CameraResourcesWorker::listSet() {
159 QList<ResourcePolicy::Resource *> resources = m_set->resources();
161 QList<ResourcePolicy::ResourceType> set;
163 foreach (ResourcePolicy::Resource *r, resources) {
170 void CameraResourcesWorker::acquire(bool *ok, const CameraResources::Mode& mode) {
171 if (mode == m_mode) {
181 case CameraResources::None:
185 case CameraResources::Image:
186 *ok = updateSet(QList<ResourcePolicy::ResourceType>()
187 << ResourcePolicy::VideoPlaybackType
188 << ResourcePolicy::VideoRecorderType
189 << ResourcePolicy::ScaleButtonType
190 << ResourcePolicy::SnapButtonType);
193 case CameraResources::Video:
194 *ok = updateSet(QList<ResourcePolicy::ResourceType>()
195 << ResourcePolicy::VideoPlaybackType
196 << ResourcePolicy::VideoRecorderType
197 << ResourcePolicy::ScaleButtonType
198 << ResourcePolicy::SnapButtonType);
201 case CameraResources::Recording:
202 *ok = updateSet(QList<ResourcePolicy::ResourceType>()
203 << ResourcePolicy::VideoPlaybackType
204 << ResourcePolicy::VideoRecorderType
205 << ResourcePolicy::ScaleButtonType
206 << ResourcePolicy::SnapButtonType,
207 QList<ResourcePolicy::ResourceType>()
208 << ResourcePolicy::AudioRecorderType
209 << ResourcePolicy::AudioPlaybackType);
212 case CameraResources::PostCapture:
213 *ok = updateSet(QList<ResourcePolicy::ResourceType>()
214 << ResourcePolicy::VideoPlaybackType
215 << ResourcePolicy::ScaleButtonType,
216 QList<ResourcePolicy::ResourceType>()
217 << ResourcePolicy::AudioPlaybackType);
221 qWarning() << "Unknown mode" << mode;
227 void CameraResourcesWorker::acquired(bool *ok) {
231 void CameraResourcesWorker::hijacked(bool *ok) {
235 bool CameraResourcesWorker::updateSet(const QList<ResourcePolicy::ResourceType>& required,
236 const QList<ResourcePolicy::ResourceType>& optional) {
239 QList<ResourcePolicy::ResourceType> set = listSet();
241 foreach (ResourcePolicy::ResourceType r, set) {
242 if (required.indexOf(r) != -1) {
243 m_set->resource(r)->setOptional(false);
245 else if (optional.indexOf(r) != -1) {
246 m_set->resource(r)->setOptional(true);
249 m_set->deleteResource(r);
253 foreach (ResourcePolicy::ResourceType r, required) {
254 m_set->addResource(r);
257 foreach (ResourcePolicy::ResourceType r, optional) {
258 m_set->addResource(r);
259 ResourcePolicy::Resource *res = m_set->resource(r);
261 res->setOptional(true);
265 if (m_set->contains(ResourcePolicy::AudioPlaybackType)) {
266 bool isOptional = m_set->resource(ResourcePolicy::AudioPlaybackType)->isOptional();
268 ResourcePolicy::AudioResource *audio = new ResourcePolicy::AudioResource("camera");
269 audio->setProcessID(QCoreApplication::applicationPid());
270 audio->setOptional(isOptional);
271 m_set->addResourceObject(audio);
279 while (m_acquiring) {
280 QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
286 bool CameraResourcesWorker::release() {
291 while (m_acquiring) {
292 QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
295 m_mode = CameraResources::None;
300 void CameraResourcesWorker::setAcquired(bool acquired) {
301 if (m_acquired != acquired) {
302 m_acquired = acquired;
303 emit acquiredChanged();
307 void CameraResourcesWorker::setHijacked(bool hijacked) {
308 if (m_hijacked != hijacked) {
309 m_hijacked = hijacked;
310 emit hijackedChanged();
314 void CameraResourcesWorker::isResourceGranted(bool *ok,
315 const CameraResources::ResourceType& resource) {
317 ResourcePolicy::ResourceType rt = (ResourcePolicy::ResourceType)resource;
319 ResourcePolicy::Resource *r = m_set->resource(rt);
321 *ok = r->isGranted();