X-Git-Url: http://cgit.sxemacs.org/?p=harmattan%2Fcameraplus;a=blobdiff_plain;f=src%2Fcameraresources.cpp;h=cbaed5c9a708ceeda88203da7203e386d9f4f10e;hp=b28cc52bd616cd6c1120c2d5794557ec3be0e7a9;hb=dbaa2edf6d8c6b29c5d899c7f98ac2f42472c3e1;hpb=8fda608e8809c2b5c1b0db2a10e6099b73759ce8 diff --git a/src/cameraresources.cpp b/src/cameraresources.cpp index b28cc52..cbaed5c 100644 --- a/src/cameraresources.cpp +++ b/src/cameraresources.cpp @@ -1,7 +1,7 @@ /*! * This file is part of CameraPlus. * - * Copyright (C) 2012 Mohammed Sameer + * Copyright (C) 2012-2013 Mohammed Sameer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,153 +19,317 @@ */ #include "cameraresources.h" +#if defined(QT4) +#include +#endif #include -using namespace ResourcePolicy; +#define APPLICATION_CLASS "camera" CameraResources::CameraResources(QObject *parent) : QObject(parent), - m_set(new ResourceSet("camera", this, true, true)), - m_mode(None), m_acquired(false) { + m_worker(new CameraResourcesWorker) { + + m_worker->moveToThread(&m_thread); + +#if defined(QT4) + DBUSConnectionEventLoop::getInstance().moveToThread(&m_thread); +#endif + + QObject::connect(&m_thread, SIGNAL(started()), m_worker, SLOT(init())); + m_thread.start(); + + qRegisterMetaType("CameraResources::Mode"); + qRegisterMetaType("bool *"); + + QObject::connect(m_worker, SIGNAL(acquiredChanged()), this, SIGNAL(acquiredChanged())); + QObject::connect(m_worker, SIGNAL(hijackedChanged()), this, SIGNAL(hijackedChanged())); + QObject::connect(m_worker, SIGNAL(updated()), this, SIGNAL(updated())); + QObject::connect(m_worker, SIGNAL(acquiredChanged()), this, SIGNAL(scaleAcquisitionChanged())); + QObject::connect(m_worker, SIGNAL(hijackedChanged()), this, SIGNAL(scaleAcquisitionChanged())); + QObject::connect(m_worker, SIGNAL(updated()), this, SIGNAL(scaleAcquisitionChanged())); +} + +CameraResources::~CameraResources() { + acquire(CameraResources::None); + m_thread.exit(0); + + while (m_thread.isRunning()) { + m_thread.wait(10); + } + + delete m_worker; + m_worker = 0; +} + +bool CameraResources::isResourceGranted(const ResourcePolicy::ResourceType& resource) const { + bool ok = false; + + QMetaObject::invokeMethod(m_worker, "isResourceGranted", Qt::BlockingQueuedConnection, + Q_ARG(bool *, &ok), Q_ARG(int, resource)); + + return ok; +} + +bool CameraResources::acquire(const Mode& mode) { + bool ok = false; + + QMetaObject::invokeMethod(m_worker, "acquire", Qt::BlockingQueuedConnection, + Q_ARG(bool *, &ok), Q_ARG(CameraResources::Mode, mode)); + + return ok; +} + +bool CameraResources::acquired() const { + bool ok = false; + + QMetaObject::invokeMethod(m_worker, "acquired", Qt::BlockingQueuedConnection, + Q_ARG(bool *, &ok)); + + return ok; +} + +bool CameraResources::hijacked() const { + bool ok = false; + + QMetaObject::invokeMethod(m_worker, "hijacked", Qt::BlockingQueuedConnection, + Q_ARG(bool *, &ok)); + + return ok; +} + +bool CameraResources::isScaleAcquired() const { + return isResourceGranted(ResourcePolicy::ScaleButtonType); +} + +CameraResourcesWorker::CameraResourcesWorker(QObject *parent) : + QObject(parent), + m_set(0), + m_mode(CameraResources::None), + m_acquired(false), + m_acquiring(false), + m_hijacked(false) { + +} + +CameraResourcesWorker::~CameraResourcesWorker() { + +} + +void CameraResourcesWorker::init() { + m_set = new ResourcePolicy::ResourceSet(APPLICATION_CLASS, this); + m_set->setAlwaysReply(); QObject::connect(m_set, SIGNAL(resourcesReleased()), this, SLOT(resourcesReleased())); QObject::connect(m_set, SIGNAL(lostResources()), this, SLOT(lostResources())); QObject::connect(m_set, SIGNAL(resourcesGranted(const QList&)), this, SLOT(resourcesGranted(const QList&))); - QObject::connect(m_set, SIGNAL(updateOK()), this, SLOT(updateOK())); + QObject::connect(m_set, SIGNAL(resourcesDenied()), this, SLOT(resourcesDenied())); if (!m_set->initAndConnect()) { qCritical() << "Failed to connect to resource policy engine"; } } -CameraResources::~CameraResources() { - acquire(None); +void CameraResourcesWorker::resourcesReleased() { + setHijacked(false); + setAcquired(false); + + m_acquiring = false; +} + +void CameraResourcesWorker::lostResources() { + setAcquired(false); + setHijacked(true); + + m_acquiring = false; +} + +void CameraResourcesWorker::resourcesGranted(const QList& optional) { + Q_UNUSED(optional); + + if (!m_acquiring) { + // This can happen when: + // 1) We lose/gain optional resources. + // 2) A higher priority application releases resources back. + emit updated(); + } + + m_acquiring = false; + + setAcquired(true); + setHijacked(false); +} + +void CameraResourcesWorker::resourcesDenied() { + setAcquired(false); + setHijacked(true); + + m_acquiring = false; } -void CameraResources::acquire(const CameraResources::Mode& mode) { +QList CameraResourcesWorker::listSet() { + QList resources = m_set->resources(); + + QList set; + + foreach (ResourcePolicy::Resource *r, resources) { + set << r->type(); + } + + return set; +} + +void CameraResourcesWorker::acquire(bool *ok, const CameraResources::Mode& mode) { if (mode == m_mode) { - // We need to emit this because the UI migh be waiting - emit acquiredChanged(); + *ok = true; return; } m_mode = mode; + *ok = false; + switch (m_mode) { - case None: - m_set->release(); + case CameraResources::None: + *ok = release(); break; - case Image: - updateSet(QList() - << ResourcePolicy::VideoPlaybackType - << ResourcePolicy::VideoRecorderType - << ResourcePolicy::ScaleButtonType - << ResourcePolicy::SnapButtonType); + case CameraResources::Image: + *ok = updateSet(QList() + << ResourcePolicy::VideoPlaybackType + << ResourcePolicy::VideoRecorderType, + QList() + << ResourcePolicy::ScaleButtonType); break; - case Video: - updateSet(QList() - << ResourcePolicy::VideoPlaybackType - << ResourcePolicy::VideoRecorderType - << ResourcePolicy::ScaleButtonType - << ResourcePolicy::SnapButtonType); + case CameraResources::Video: + *ok = updateSet(QList() + << ResourcePolicy::VideoPlaybackType + << ResourcePolicy::VideoRecorderType, + QList() + << ResourcePolicy::ScaleButtonType); break; - case Recording: - updateSet(QList() - << ResourcePolicy::VideoPlaybackType - << ResourcePolicy::VideoRecorderType - << ResourcePolicy::ScaleButtonType - << ResourcePolicy::SnapButtonType - << ResourcePolicy::AudioRecorderType, - QList() - << ResourcePolicy::AudioPlaybackType); + case CameraResources::Recording: + *ok = updateSet(QList() + << ResourcePolicy::VideoPlaybackType + << ResourcePolicy::VideoRecorderType, + QList() + << ResourcePolicy::ScaleButtonType + << ResourcePolicy::AudioRecorderType + << ResourcePolicy::AudioPlaybackType); break; - case PostCapture: - updateSet(QList() - << ResourcePolicy::VideoPlaybackType - << ResourcePolicy::ScaleButtonType, - QList() - << ResourcePolicy::AudioPlaybackType); - + case CameraResources::Player: + *ok = updateSet(QList() + << ResourcePolicy::VideoPlaybackType + << ResourcePolicy::AudioPlaybackType, + QList() + << ResourcePolicy::ScaleButtonType); break; default: qWarning() << "Unknown mode" << mode; - break; + *ok = false; } } -bool CameraResources::acquired() const { - return m_acquired; +void CameraResourcesWorker::acquired(bool *ok) { + *ok = m_acquired; } -void CameraResources::resourcesReleased() { - m_mode = None; - m_acquired = false; - emit acquiredChanged(); +void CameraResourcesWorker::hijacked(bool *ok) { + *ok = m_hijacked; } -void CameraResources::lostResources() { - m_mode = None; - m_acquired = false; - emit acquiredChanged(); -} +bool CameraResourcesWorker::updateSet(const QList& required, + const QList& optional) { -void CameraResources::resourcesGranted(const QList& optional) { - Q_UNUSED(optional); - m_acquired = true; - emit acquiredChanged(); -} + QList set = listSet(); -void CameraResources::updateOK() { - m_acquired = true; - emit acquiredChanged(); -} + foreach (ResourcePolicy::ResourceType r, set) { + if (required.indexOf(r) != -1) { + m_set->resource(r)->setOptional(false); + } + else if (optional.indexOf(r) != -1) { + m_set->resource(r)->setOptional(true); + } + else { + m_set->deleteResource(r); + } + } -QList CameraResources::listSet() { - QList resources = m_set->resources(); - QList set; + foreach (ResourcePolicy::ResourceType r, required) { + m_set->addResource(r); + } - foreach (Resource *r, resources) { - set << r->type(); + foreach (ResourcePolicy::ResourceType r, optional) { + m_set->addResource(r); + ResourcePolicy::Resource *res = m_set->resource(r); + if (res) { + res->setOptional(true); + } } - return set; -} + if (m_set->contains(ResourcePolicy::AudioPlaybackType)) { + bool isOptional = m_set->resource(ResourcePolicy::AudioPlaybackType)->isOptional(); -void CameraResources::updateSet(const QList& required, - const QList& optional) { + ResourcePolicy::AudioResource *audio = new ResourcePolicy::AudioResource(APPLICATION_CLASS); + audio->setProcessID(QCoreApplication::applicationPid()); + audio->setStreamTag("media.name", "*"); + audio->setOptional(isOptional); + m_set->addResourceObject(audio); + } - bool isEmpty = m_set->resources().isEmpty(); + m_acquiring = true; - QList set = listSet(); + m_set->update(); + m_set->acquire(); - foreach (ResourceType r, set) { - // Check for acquired resources that should be dropped. - if (required.indexOf(r) == -1) { - m_set->deleteResource(r); - } + while (m_acquiring) { + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); } - foreach (ResourceType r, required) { - // TODO: AudioPlayback needs special handling - m_set->addResource(r); + return m_acquired; +} + +bool CameraResourcesWorker::release() { + m_acquiring = true; + + m_set->release(); + + while (m_acquiring) { + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); } - // TODO: optional resources + m_mode = CameraResources::None; - // Odd. If we don't do it that way then policy ignores our requests - // when we get minimized then maximized. - if (isEmpty) { - m_set->update(); + return true; +} + +void CameraResourcesWorker::setAcquired(bool acquired) { + if (m_acquired != acquired) { + m_acquired = acquired; + emit acquiredChanged(); } - else { - m_set->acquire(); +} + +void CameraResourcesWorker::setHijacked(bool hijacked) { + if (m_hijacked != hijacked) { + m_hijacked = hijacked; + emit hijackedChanged(); + } +} + +void CameraResourcesWorker::isResourceGranted(bool *ok, int resource) { + + ResourcePolicy::ResourceType rt = (ResourcePolicy::ResourceType)resource; + + ResourcePolicy::Resource *r = m_set->resource(rt); + if (r) { + *ok = r->isGranted(); } }