1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "QtMultimedia/private/qtmultimediaglobal_p.h"
41#include "camerabinresourcepolicy.h"
42//#define DEBUG_RESOURCE_POLICY
43#include <QtCore/qdebug.h>
44#include <QtCore/qset.h>
45
46#if QT_CONFIG(resourcepolicy)
47#include <policy/resource.h>
48#include <policy/resources.h>
49#include <policy/resource-set.h>
50#endif
51
52QT_BEGIN_NAMESPACE
53
54CamerabinResourcePolicy::CamerabinResourcePolicy(QObject *parent) :
55 QObject(parent),
56 m_resourceSet(NoResources),
57 m_releasingResources(false),
58 m_canCapture(false)
59{
60#if QT_CONFIG(resourcepolicy)
61 //loaded resource set is also kept requested for image and video capture sets
62 m_resource = new ResourcePolicy::ResourceSet("camera");
63 m_resource->setAlwaysReply();
64 m_resource->initAndConnect();
65
66 connect(m_resource, SIGNAL(resourcesGranted(QList<ResourcePolicy::ResourceType>)),
67 SLOT(handleResourcesGranted()));
68 connect(m_resource, SIGNAL(resourcesDenied()), SIGNAL(resourcesDenied()));
69 connect(m_resource, SIGNAL(lostResources()), SLOT(handleResourcesLost()));
70 connect(m_resource, SIGNAL(resourcesReleased()), SLOT(handleResourcesReleased()));
71 connect(m_resource, SIGNAL(resourcesBecameAvailable(QList<ResourcePolicy::ResourceType>)),
72 this, SLOT(resourcesAvailable()));
73 connect(m_resource, SIGNAL(updateOK()), this, SLOT(updateCanCapture()));
74#endif
75}
76
77CamerabinResourcePolicy::~CamerabinResourcePolicy()
78{
79#if QT_CONFIG(resourcepolicy)
80 //ensure the resources are released
81 if (m_resourceSet != NoResources)
82 setResourceSet(NoResources);
83
84 //don't delete the resource set until resources are released
85 if (m_releasingResources) {
86 m_resource->connect(m_resource, SIGNAL(resourcesReleased()),
87 SLOT(deleteLater()));
88 } else {
89 delete m_resource;
90 m_resource = 0;
91 }
92#endif
93}
94
95CamerabinResourcePolicy::ResourceSet CamerabinResourcePolicy::resourceSet() const
96{
97 return m_resourceSet;
98}
99
100void CamerabinResourcePolicy::setResourceSet(CamerabinResourcePolicy::ResourceSet set)
101{
102 CamerabinResourcePolicy::ResourceSet oldSet = m_resourceSet;
103 m_resourceSet = set;
104
105#ifdef DEBUG_RESOURCE_POLICY
106 qDebug() << Q_FUNC_INFO << set;
107#endif
108
109#if QT_CONFIG(resourcepolicy)
110 QSet<ResourcePolicy::ResourceType> requestedTypes;
111
112 switch (set) {
113 case NoResources:
114 break;
115 case LoadedResources:
116 requestedTypes << ResourcePolicy::LensCoverType //to detect lens cover is opened/closed
117 << ResourcePolicy::VideoRecorderType; //to open camera device
118 break;
119 case ImageCaptureResources:
120 requestedTypes << ResourcePolicy::LensCoverType
121 << ResourcePolicy::VideoPlaybackType
122 << ResourcePolicy::VideoRecorderType
123 << ResourcePolicy::LedsType;
124 break;
125 case VideoCaptureResources:
126 requestedTypes << ResourcePolicy::LensCoverType
127 << ResourcePolicy::VideoPlaybackType
128 << ResourcePolicy::VideoRecorderType
129 << ResourcePolicy::AudioPlaybackType
130 << ResourcePolicy::AudioRecorderType
131 << ResourcePolicy::LedsType;
132 break;
133 }
134
135 QSet<ResourcePolicy::ResourceType> currentTypes;
136 const auto resources = m_resource->resources();
137 currentTypes.reserve(resources.size());
138 for (ResourcePolicy::Resource *resource : resources)
139 currentTypes << resource->type();
140
141 const auto diffCurrentWithRequested = currentTypes - requestedTypes;
142 for (ResourcePolicy::ResourceType resourceType : diffCurrentWithRequested)
143 m_resource->deleteResource(resourceType);
144
145 const auto diffRequestedWithCurrent = requestedTypes - currentTypes;
146 for (ResourcePolicy::ResourceType resourceType : diffRequestedWithCurrent) {
147 if (resourceType == ResourcePolicy::LensCoverType) {
148 ResourcePolicy::LensCoverResource *lensCoverResource = new ResourcePolicy::LensCoverResource;
149 lensCoverResource->setOptional(true);
150 m_resource->addResourceObject(lensCoverResource);
151 } else if (resourceType == ResourcePolicy::AudioPlaybackType) {
152 ResourcePolicy::Resource *resource = new ResourcePolicy::AudioResource;
153 resource->setOptional(true);
154 m_resource->addResourceObject(resource);
155 } else if (resourceType == ResourcePolicy::AudioRecorderType) {
156 ResourcePolicy::Resource *resource = new ResourcePolicy::AudioRecorderResource;
157 resource->setOptional(true);
158 m_resource->addResourceObject(resource);
159 } else {
160 m_resource->addResource(resourceType);
161 }
162 }
163
164 m_resource->update();
165 if (set != NoResources) {
166 m_resource->acquire();
167 } else {
168 if (oldSet != NoResources) {
169 m_releasingResources = true;
170 m_resource->release();
171 }
172 }
173#else
174 Q_UNUSED(oldSet);
175 updateCanCapture();
176#endif
177}
178
179bool CamerabinResourcePolicy::isResourcesGranted() const
180{
181#if QT_CONFIG(resourcepolicy)
182 const auto resources = m_resource->resources();
183 for (ResourcePolicy::Resource *resource : resources)
184 if (!resource->isOptional() && !resource->isGranted())
185 return false;
186#endif
187 return true;
188}
189
190void CamerabinResourcePolicy::handleResourcesLost()
191{
192 updateCanCapture();
193 emit resourcesLost();
194}
195
196void CamerabinResourcePolicy::handleResourcesGranted()
197{
198 updateCanCapture();
199 emit resourcesGranted();
200}
201
202void CamerabinResourcePolicy::handleResourcesReleased()
203{
204#if QT_CONFIG(resourcepolicy)
205#ifdef DEBUG_RESOURCE_POLICY
206 qDebug() << Q_FUNC_INFO;
207#endif
208 m_releasingResources = false;
209#endif
210 updateCanCapture();
211}
212
213void CamerabinResourcePolicy::resourcesAvailable()
214{
215#if QT_CONFIG(resourcepolicy)
216 if (m_resourceSet != NoResources) {
217 m_resource->acquire();
218 }
219#endif
220}
221
222bool CamerabinResourcePolicy::canCapture() const
223{
224 return m_canCapture;
225}
226
227void CamerabinResourcePolicy::updateCanCapture()
228{
229 const bool wasAbleToRecord = m_canCapture;
230 m_canCapture = (m_resourceSet == VideoCaptureResources) || (m_resourceSet == ImageCaptureResources);
231#if QT_CONFIG(resourcepolicy)
232 const auto resources = m_resource->resources();
233 for (ResourcePolicy::Resource *resource : resources) {
234 if (resource->type() != ResourcePolicy::LensCoverType)
235 m_canCapture = m_canCapture && resource->isGranted();
236 }
237#endif
238 if (wasAbleToRecord != m_canCapture)
239 emit canCaptureChanged();
240}
241
242QT_END_NAMESPACE
243

source code of qtmultimedia/src/plugins/gstreamer/camerabin/camerabinresourcepolicy.cpp