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 QtSensors module 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 <QDir>
41 #include <QLibraryInfo>
42 
43 #include <QtCore/private/qfactoryloader_p.h>
44 
45 #include "qsensorgesturerecognizer.h"
46 #include "qsensorgesturemanagerprivate_p.h"
47 #include "qsensorgestureplugininterface.h"
48 
49 #ifdef SIMULATOR_BUILD
50 #include "simulatorgesturescommon_p.h"
51 #endif
52 
Q_GLOBAL_STATIC(QSensorGestureManagerPrivate,sensorGestureManagerPrivate)53 Q_GLOBAL_STATIC(QSensorGestureManagerPrivate, sensorGestureManagerPrivate)
54 
55 QT_BEGIN_NAMESPACE
56 
57 QSensorGestureManagerPrivate::QSensorGestureManagerPrivate(QObject *parent) :
58     QObject(parent)
59 {
60 #ifdef SIMULATOR_BUILD
61     SensorGesturesConnection *connection =  new SensorGesturesConnection(this);
62     connect(connection,SIGNAL(sensorGestureDetected()),
63             this,SLOT(sensorGestureDetected()));
64 
65     connect(this,SIGNAL(newSensorGestures(QStringList)),
66             connection,SLOT(newSensorGestures(QStringList)));
67 
68     connect(this,SIGNAL(removeSensorGestures(QStringList)),
69             connection,SLOT(removeSensorGestures(QStringList)));
70 #endif
71 
72     loader = new QFactoryLoader("org.qt-project.QSensorGesturePluginInterface", QLatin1String("/sensorgestures"));
73     loadPlugins();
74 }
75 
~QSensorGestureManagerPrivate()76 QSensorGestureManagerPrivate::~QSensorGestureManagerPrivate()
77 {
78 //    qDeleteAll(registeredSensorGestures);
79 //    delete loader;
80 }
81 
82 
initPlugin(QObject * plugin)83  void QSensorGestureManagerPrivate::initPlugin(QObject *plugin)
84 {
85     if (QSensorGesturePluginInterface *pInterface
86             = qobject_cast<QSensorGesturePluginInterface *>(plugin)) {
87 
88         Q_FOREACH (const QString &id, pInterface->supportedIds()) {
89 
90             if (!knownIds.contains(id))
91                 knownIds.append(id);
92             else
93                 qWarning() << id <<"from the plugin"
94                            << pInterface->name()
95                            << "is already known.";
96 
97         }
98         plugins << plugin;
99     } else {
100         qWarning() << "Could not load "<< plugin;
101     }
102 }
103 
104 
105 /*!
106   Internal
107   Loads the sensorgesture plugins.
108   */
loadPlugins()109 void QSensorGestureManagerPrivate::loadPlugins()
110 {
111     Q_FOREACH (QObject *plugin, QPluginLoader::staticInstances()) {
112         initPlugin(plugin);
113     }
114     QList<QJsonObject> meta = loader->metaData();
115     for (int i = 0; i < meta.count(); i++) {
116         QObject *plugin = loader->instance(i);
117         initPlugin(plugin);
118     }
119 }
120 
121 
122 /*!
123   Internal
124   creates the requested  recognizer.
125   */
126 
loadRecognizer(const QString & recognizerId)127 bool QSensorGestureManagerPrivate::loadRecognizer(const QString &recognizerId)
128 {
129     //if no plugin is used return true if this is a registered recognizer
130 
131     if (registeredSensorGestures.contains(recognizerId))
132         return true;
133 
134     for (int i= 0; i < plugins.count(); i++) {
135 
136         if (QSensorGesturePluginInterface *pInterface
137                 = qobject_cast<QSensorGesturePluginInterface *>(plugins.at(i))) {
138 
139             if (pInterface->supportedIds().contains(recognizerId)) {
140 
141                 if (!registeredSensorGestures.contains(recognizerId)) {
142                     //create these recognizers
143                     QList <QSensorGestureRecognizer *> recognizers = pInterface->createRecognizers();
144 
145                     Q_FOREACH (QSensorGestureRecognizer *recognizer, recognizers) {
146 
147                         if (registeredSensorGestures.contains(recognizer->id())) {
148                            qWarning() << "Ignoring recognizer " << recognizer->id() << "from plugin" << pInterface->name() << "because it is already registered";
149                             delete recognizer;
150                         } else {
151                             registeredSensorGestures.insert(recognizer->id(),recognizer);
152                         }
153                     }
154                 }
155                 return true;
156             }
157         }
158     }
159     return false;
160 }
161 
registerSensorGestureRecognizer(QSensorGestureRecognizer * recognizer)162 bool QSensorGestureManagerPrivate::registerSensorGestureRecognizer(QSensorGestureRecognizer *recognizer)
163 {
164     if (!knownIds.contains(recognizer->id())) {
165         knownIds.append(recognizer->id());
166         Q_ASSERT (!registeredSensorGestures.contains(recognizer->id()));
167         recognizer->setParent(0);
168         registeredSensorGestures.insert(recognizer->id(),recognizer);
169         Q_EMIT newSensorGestureAvailable();
170 
171         return true;
172     }
173     return false;
174 }
175 
sensorGestureRecognizer(const QString & id)176 QSensorGestureRecognizer *QSensorGestureManagerPrivate::sensorGestureRecognizer(const QString &id)
177 {
178     QSensorGestureRecognizer *recognizer = 0;
179 
180     if (loadRecognizer(id)) {
181         recognizer= registeredSensorGestures.value(id);
182     }
183 
184     return recognizer;
185 }
186 
gestureIds()187 QStringList QSensorGestureManagerPrivate::gestureIds()
188 {
189     return knownIds;
190 }
191 
192 #ifdef SIMULATOR_BUILD
sensorGestureDetected()193 void QSensorGestureManagerPrivate::sensorGestureDetected()
194 {
195     QString str = get_qtSensorGestureData();
196 
197     Q_FOREACH (const QString &id, gestureIds()) {
198         QSensorGestureRecognizer *recognizer = sensorGestureRecognizer(id);
199         if (recognizer != 0) {
200             Q_FOREACH (const QString &sig,  recognizer->gestureSignals()) {
201                 if (!sig.contains(QLatin1String("detected"))) { //weed out detected signals
202                     QString tmp;
203                         tmp = sig.left(sig.length() - 2);
204                     if (str == tmp) {
205                         // named signal for c++
206                         QMetaObject::invokeMethod(recognizer, str.toLocal8Bit(), Qt::DirectConnection);
207                         // detected signal for qml and c++
208                         QMetaObject::invokeMethod(recognizer, "detected", Qt::DirectConnection,
209                                                   Q_ARG(QString, str));
210                         break;
211 
212                     }
213                 }
214             }
215         }
216     }
217 }
218 
recognizerStarted(const QSensorGestureRecognizer * recognizer)219 void QSensorGestureManagerPrivate::recognizerStarted(const QSensorGestureRecognizer *recognizer)
220 {
221     QStringList list = recognizer->gestureSignals();
222     list.removeOne(QLatin1String("detected(QString)"));
223     Q_EMIT newSensorGestures(list);
224 }
225 
recognizerStopped(const QSensorGestureRecognizer * recognizer)226 void QSensorGestureManagerPrivate::recognizerStopped(const QSensorGestureRecognizer *recognizer)
227 {
228     QStringList list = recognizer->gestureSignals();
229     list.removeOne(QLatin1String("detected(QString)"));
230     Q_EMIT removeSensorGestures(list);
231 }
232 
233 #endif
234 
instance()235 QSensorGestureManagerPrivate * QSensorGestureManagerPrivate::instance()
236 {
237     QSensorGestureManagerPrivate *priv = sensorGestureManagerPrivate();
238     // It's safe to return 0 because this is checked when used
239     //if (!priv) qFatal("Cannot return from QSensorGestureManagerPrivate::instance() because sensorGestureManagerPrivate() returned 0.");
240     return priv;
241 }
242 
243 
244 QT_END_NAMESPACE
245