*/
#include "cameraresources.h"
+#include <dbusconnectioneventloop.h>
#include <QDebug>
-using namespace ResourcePolicy;
-
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);
+ DBUSConnectionEventLoop::getInstance().moveToThread(&m_thread);
+
+ QObject::connect(&m_thread, SIGNAL(started()), m_worker, SLOT(init()));
+ m_thread.start();
+
+ qRegisterMetaType<CameraResources::Mode>("CameraResources::Mode");
+ qRegisterMetaType<CameraResources::ResourceType>("CameraResources::ResourceType");
+ qRegisterMetaType<bool *>("bool *");
+
+ QObject::connect(m_worker, SIGNAL(acquiredChanged()), this, SIGNAL(acquiredChanged()));
+ QObject::connect(m_worker, SIGNAL(hijackedChanged()), this, SIGNAL(hijackedChanged()));
+}
+
+CameraResources::~CameraResources() {
+ m_thread.quit();
+ m_thread.wait();
+
+ delete m_worker;
+ m_worker = 0;
+}
+
+bool CameraResources::isResourceGranted(const ResourceType& resource) {
+ bool ok = false;
+
+ QMetaObject::invokeMethod(m_worker, "isResourceGranted", Qt::BlockingQueuedConnection,
+ Q_ARG(bool *, &ok), Q_ARG(CameraResources::ResourceType, 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;
+}
+
+CameraResourcesWorker::CameraResourcesWorker(QObject *parent) :
+ QObject(parent),
+ m_set(0),
+ m_mode(CameraResources::None),
+ m_acquired(false),
+ m_acquiring(false),
+ m_hijacked(false) {
+
+}
+
+CameraResourcesWorker::~CameraResourcesWorker() {
+ bool ok;
+
+ acquire(&ok, CameraResources::None);
+}
+
+void CameraResourcesWorker::init() {
+ m_set = new ResourcePolicy::ResourceSet("camera", 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<ResourcePolicy::ResourceType>&)),
this, SLOT(resourcesGranted(const QList<ResourcePolicy::ResourceType>&)));
- 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 CameraResources::acquire(const CameraResources::Mode& mode) {
+void CameraResourcesWorker::lostResources() {
+ setAcquired(false);
+ setHijacked(true);
+
+ m_acquiring = false;
+}
+
+void CameraResourcesWorker::resourcesGranted(const QList<ResourcePolicy::ResourceType>& optional) {
+ Q_UNUSED(optional);
+
+ m_acquiring = false;
+
+ setAcquired(true);
+ setHijacked(false);
+}
+
+void CameraResourcesWorker::resourcesDenied() {
+ setAcquired(false);
+ setHijacked(true);
+
+ m_acquiring = false;
+}
+
+QList<ResourcePolicy::ResourceType> CameraResourcesWorker::listSet() {
+ QList<ResourcePolicy::Resource *> resources = m_set->resources();
+
+ QList<ResourcePolicy::ResourceType> 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::ResourceType>()
- << ResourcePolicy::VideoPlaybackType
- << ResourcePolicy::VideoRecorderType
- << ResourcePolicy::ScaleButtonType
- << ResourcePolicy::SnapButtonType);
+ case CameraResources::Image:
+ *ok = updateSet(QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::VideoPlaybackType
+ << ResourcePolicy::VideoRecorderType
+ << ResourcePolicy::ScaleButtonType
+ << ResourcePolicy::SnapButtonType);
break;
- case Video:
- updateSet(QList<ResourcePolicy::ResourceType>()
- << ResourcePolicy::VideoPlaybackType
- << ResourcePolicy::VideoRecorderType
- << ResourcePolicy::ScaleButtonType
- << ResourcePolicy::SnapButtonType);
+ case CameraResources::Video:
+ *ok = updateSet(QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::VideoPlaybackType
+ << ResourcePolicy::VideoRecorderType
+ << ResourcePolicy::ScaleButtonType
+ << ResourcePolicy::SnapButtonType);
break;
- case Recording:
- updateSet(QList<ResourcePolicy::ResourceType>()
- << ResourcePolicy::VideoPlaybackType
- << ResourcePolicy::VideoRecorderType
- << ResourcePolicy::ScaleButtonType
- << ResourcePolicy::SnapButtonType
- << ResourcePolicy::AudioRecorderType,
- QList<ResourcePolicy::ResourceType>()
- << ResourcePolicy::AudioPlaybackType);
+ case CameraResources::Recording:
+ *ok = updateSet(QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::VideoPlaybackType
+ << ResourcePolicy::VideoRecorderType
+ << ResourcePolicy::ScaleButtonType
+ << ResourcePolicy::SnapButtonType,
+ QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::AudioRecorderType
+ << ResourcePolicy::AudioPlaybackType);
break;
- case PostCapture:
- updateSet(QList<ResourcePolicy::ResourceType>()
- << ResourcePolicy::VideoPlaybackType
- << ResourcePolicy::ScaleButtonType,
- QList<ResourcePolicy::ResourceType>()
- << ResourcePolicy::AudioPlaybackType);
-
+ case CameraResources::PostCapture:
+ *ok = updateSet(QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::VideoPlaybackType
+ << ResourcePolicy::ScaleButtonType,
+ QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::AudioPlaybackType);
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<ResourcePolicy::ResourceType>& required,
+ const QList<ResourcePolicy::ResourceType>& optional) {
-void CameraResources::resourcesGranted(const QList<ResourcePolicy::ResourceType>& optional) {
- Q_UNUSED(optional);
- m_acquired = true;
- emit acquiredChanged();
-}
+ QList<ResourcePolicy::ResourceType> 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<ResourcePolicy::ResourceType> CameraResources::listSet() {
- QList<Resource *> resources = m_set->resources();
- QList<ResourcePolicy::ResourceType> 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();
+
+ ResourcePolicy::AudioResource *audio = new ResourcePolicy::AudioResource("camera");
+ audio->setProcessID(QCoreApplication::applicationPid());
+ audio->setOptional(isOptional);
+ m_set->addResourceObject(audio);
+ }
+
+ m_acquiring = true;
+
+ m_set->update();
+ m_set->acquire();
+
+ while (m_acquiring) {
+ QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
+ }
+
+ return m_acquired;
}
-void CameraResources::updateSet(const QList<ResourcePolicy::ResourceType>& required,
- const QList<ResourcePolicy::ResourceType>& optional) {
+bool CameraResourcesWorker::release() {
+ m_acquiring = true;
- Q_UNUSED(optional);
+ m_set->release();
- bool isEmpty = m_set->resources().isEmpty();
+ while (m_acquiring) {
+ QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
+ }
- QList<ResourcePolicy::ResourceType> set = listSet();
+ m_mode = CameraResources::None;
- foreach (ResourceType r, set) {
- // Check for acquired resources that should be dropped.
- if (required.indexOf(r) == -1) {
- m_set->deleteResource(r);
- }
+ return true;
+}
+
+void CameraResourcesWorker::setAcquired(bool acquired) {
+ if (m_acquired != acquired) {
+ m_acquired = acquired;
+ emit acquiredChanged();
}
+}
- foreach (ResourceType r, required) {
- // TODO: AudioPlayback needs special handling
- m_set->addResource(r);
+void CameraResourcesWorker::setHijacked(bool hijacked) {
+ if (m_hijacked != hijacked) {
+ m_hijacked = hijacked;
+ emit hijackedChanged();
}
+}
- // TODO: optional resources
+void CameraResourcesWorker::isResourceGranted(bool *ok,
+ const CameraResources::ResourceType& resource) {
- // 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();
- }
- else {
- m_set->acquire();
+ ResourcePolicy::ResourceType rt = (ResourcePolicy::ResourceType)resource;
+
+ ResourcePolicy::Resource *r = m_set->resource(rt);
+ if (r) {
+ *ok = r->isGranted();
}
}
#define CAMERA_RESOURCES_H
#include <QObject>
+#include <QThread>
#include <policy/resource-set.h>
+class CameraResourcesWorker;
class CameraResources : public QObject {
Q_OBJECT
Q_PROPERTY(bool acquired READ acquired NOTIFY acquiredChanged);
+ Q_PROPERTY(bool hijacked READ hijacked NOTIFY hijackedChanged);
Q_ENUMS(Mode);
+ Q_ENUMS(ResourceType);
public:
typedef enum {
PostCapture,
} Mode;
+ typedef enum {
+ AudioPlaybackType = ResourcePolicy::AudioPlaybackType,
+ VideoPlaybackType = ResourcePolicy::VideoPlaybackType,
+ AudioRecorderType = ResourcePolicy::AudioRecorderType,
+ VideoRecorderType = ResourcePolicy::VideoRecorderType,
+ ScaleButtonType = ResourcePolicy::ScaleButtonType,
+ SnapButtonType = ResourcePolicy::SnapButtonType,
+ LensCoverType = ResourcePolicy::LensCoverType,
+ } ResourceType;
+
CameraResources(QObject *parent = 0);
~CameraResources();
+ Q_INVOKABLE bool acquire(const Mode& mode);
+
+ Q_INVOKABLE bool isResourceGranted(const ResourceType& resource);
+
bool acquired() const;
+ bool hijacked() const;
+
+signals:
+ void acquiredChanged();
+ void hijackedChanged();
+
+private:
+ CameraResourcesWorker *m_worker;
+ QThread m_thread;
+};
+
+class CameraResourcesWorker : public QObject {
+ Q_OBJECT
+
+public:
+ CameraResourcesWorker(QObject *parent = 0);
+ ~CameraResourcesWorker();
public slots:
- void acquire(const Mode& mode);
+ void acquire(bool *ok, const CameraResources::Mode& mode);
+ void acquired(bool *ok);
+ void hijacked(bool *ok);
+ void isResourceGranted(bool *ok, const CameraResources::ResourceType& resource);
signals:
void acquiredChanged();
+ void hijackedChanged();
private slots:
+ void init();
+
void resourcesReleased();
void lostResources();
void resourcesGranted(const QList<ResourcePolicy::ResourceType>& optional);
- void updateOK();
+ void resourcesDenied();
private:
- void updateSet(const QList<ResourcePolicy::ResourceType>& required,
+ bool release();
+
+ bool updateSet(const QList<ResourcePolicy::ResourceType>& required,
const QList<ResourcePolicy::ResourceType>& optional =
QList<ResourcePolicy::ResourceType>());
QList<ResourcePolicy::ResourceType> listSet();
+ void setAcquired(bool acquired);
+ void setHijacked(bool hijacked);
+
ResourcePolicy::ResourceSet *m_set;
- Mode m_mode;
+
+ CameraResources::Mode m_mode;
+ QMutex m_mutex;
bool m_acquired;
+ bool m_acquiring;
+ bool m_hijacked;
};
#endif /* CAMERA_RESOURCES_H */