src/sensors/qsensormanager.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qsensormanager.h"
       
    43 #include <QDebug>
       
    44 #include "qsensorpluginloader_p.h"
       
    45 #include "qsensorplugin.h"
       
    46 #include <QSettings>
       
    47 #include "sensorlog_p.h"
       
    48 
       
    49 QTM_BEGIN_NAMESPACE
       
    50 
       
    51 Q_GLOBAL_STATIC_WITH_ARGS(QSensorPluginLoader, pluginLoader, (QSensorPluginInterface_iid, QLatin1String("/sensors")))
       
    52 
       
    53 typedef QHash<QByteArray,QSensorBackendFactory*> FactoryForIdentifierMap;
       
    54 typedef QHash<QByteArray,FactoryForIdentifierMap> BackendIdentifiersForTypeMap;
       
    55 
       
    56 class QSensorManagerPrivate
       
    57 {
       
    58 public:
       
    59     QSensorManagerPrivate()
       
    60         : pluginsLoaded(false)
       
    61     {
       
    62     }
       
    63 
       
    64     bool pluginsLoaded;
       
    65 
       
    66     QList<CreatePluginFunc> staticRegistrations;
       
    67 
       
    68     // Holds a mapping from type to available identifiers (and from there to the factory)
       
    69     BackendIdentifiersForTypeMap backendsByType;
       
    70 
       
    71     // Holds the first identifier for each type
       
    72     QHash<QByteArray, QByteArray> firstIdentifierForType;
       
    73 };
       
    74 
       
    75 Q_GLOBAL_STATIC(QSensorManagerPrivate, sensorManagerPrivate)
       
    76 
       
    77 static void loadPlugins()
       
    78 {
       
    79     QSensorManagerPrivate *d = sensorManagerPrivate();
       
    80     d->pluginsLoaded = true;
       
    81 
       
    82     SENSORLOG() << "initializing static plugins";
       
    83     Q_FOREACH (CreatePluginFunc func, d->staticRegistrations) {
       
    84         QSensorPluginInterface *plugin = func();
       
    85         plugin->registerSensors();
       
    86     }
       
    87 
       
    88     SENSORLOG() << "initializing plugins";
       
    89     Q_FOREACH (QSensorPluginInterface *plugin, pluginLoader()->plugins()) {
       
    90         plugin->registerSensors();
       
    91     }
       
    92 }
       
    93 
       
    94 // =====================================================================
       
    95 
       
    96 /*!
       
    97     \class QSensorManager
       
    98     \ingroup sensors_backend
       
    99 
       
   100     \brief The QSensorManager class handles registration and creation of sensor backends.
       
   101 
       
   102     Sensor plugins register backends using the registerBackend() function.
       
   103 
       
   104     When QSensor::connectToBackend() is called, the createBackend() function will be called.
       
   105 */
       
   106 
       
   107 /*!
       
   108     Register a sensor for \a type. The \a identifier must be unique.
       
   109 
       
   110     The \a factory will be asked to create instances of the backend.
       
   111 */
       
   112 void QSensorManager::registerBackend(const QByteArray &type, const QByteArray &identifier, QSensorBackendFactory *factory)
       
   113 {
       
   114     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   115     if (!d->backendsByType.contains(type)) {
       
   116         (void)d->backendsByType[type];
       
   117         d->firstIdentifierForType[type] = identifier;
       
   118     }
       
   119     SENSORLOG() << "registering backend for type" << type << "identifier" << identifier;// << "factory" << QString().sprintf("0x%08x", (unsigned int)factory);
       
   120     FactoryForIdentifierMap &factoryByIdentifier = d->backendsByType[type];
       
   121     factoryByIdentifier[identifier] = factory;
       
   122 }
       
   123 
       
   124 /*!
       
   125     \internal
       
   126 */
       
   127 void QSensorManager::registerStaticPlugin(CreatePluginFunc func)
       
   128 {
       
   129     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   130     d->staticRegistrations.append(func);
       
   131 }
       
   132 
       
   133 /*!
       
   134     Create a backend for \a sensor. Returns null if no suitable backend exists.
       
   135 */
       
   136 QSensorBackend *QSensorManager::createBackend(QSensor *sensor)
       
   137 {
       
   138     Q_ASSERT(sensor);
       
   139 
       
   140     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   141     if (!d->pluginsLoaded)
       
   142         loadPlugins();
       
   143 
       
   144     SENSORLOG() << "QSensorManager::createBackend" << "type" << sensor->type() << "identifier" << sensor->identifier();
       
   145 
       
   146     if (!d->backendsByType.contains(sensor->type())) {
       
   147         SENSORLOG() << "no backends of type" << sensor->type() << "have been registered.";
       
   148         return 0;
       
   149     }
       
   150 
       
   151     const FactoryForIdentifierMap &factoryByIdentifier = d->backendsByType[sensor->type()];
       
   152     QSensorBackendFactory *factory;
       
   153     QSensorBackend *backend;
       
   154 
       
   155     if (sensor->identifier().isEmpty()) {
       
   156         QByteArray defaultIdentifier = QSensor::defaultSensorForType(sensor->type());
       
   157         SENSORLOG() << "Trying the default" << defaultIdentifier;
       
   158         // No identifier set, try the default
       
   159         factory = factoryByIdentifier[defaultIdentifier];
       
   160         //SENSORLOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory);
       
   161         sensor->setIdentifier(defaultIdentifier); // the factory requires this
       
   162         backend = factory->createBackend(sensor);
       
   163         if (backend) return backend; // Got it!
       
   164 
       
   165         // The default failed to instantiate so try any other registered sensors for this type
       
   166         Q_FOREACH (const QByteArray &identifier, factoryByIdentifier.keys()) {
       
   167             SENSORLOG() << "Trying" << identifier;
       
   168             if (identifier == defaultIdentifier) continue; // Don't do the default one again
       
   169             factory = factoryByIdentifier[identifier];
       
   170             //SENSORLOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory);
       
   171             sensor->setIdentifier(identifier); // the factory requires this
       
   172             backend = factory->createBackend(sensor);
       
   173             if (backend) return backend; // Got it!
       
   174         }
       
   175         SENSORLOG() << "FAILED";
       
   176         sensor->setIdentifier(QByteArray()); // clear the identifier
       
   177     } else {
       
   178         if (!factoryByIdentifier.contains(sensor->identifier())) {
       
   179             SENSORLOG() << "no backend with identifier" << sensor->identifier() << "for type" << sensor->type();
       
   180             return 0;
       
   181         }
       
   182 
       
   183         // We were given an explicit identifier so don't substitute other backends if it fails to instantiate
       
   184         factory = factoryByIdentifier[sensor->identifier()];
       
   185         //SENSORLOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory);
       
   186         backend = factory->createBackend(sensor);
       
   187         if (backend) return backend; // Got it!
       
   188     }
       
   189 
       
   190     SENSORLOG() << "no suitable backend found for requested identifier" << sensor->identifier() << "and type" << sensor->type();
       
   191     return 0;
       
   192 }
       
   193 
       
   194 // =====================================================================
       
   195 
       
   196 /*!
       
   197     Returns a list of all sensor types.
       
   198 */
       
   199 QList<QByteArray> QSensor::sensorTypes()
       
   200 {
       
   201     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   202     if (!d->pluginsLoaded)
       
   203         loadPlugins();
       
   204 
       
   205     return d->backendsByType.keys();
       
   206 }
       
   207 
       
   208 /*!
       
   209     Returns a list of ids for each of the sensors for \a type.
       
   210     If there are no sensors of that type available the list will be empty.
       
   211 */
       
   212 QList<QByteArray> QSensor::sensorsForType(const QByteArray &type)
       
   213 {
       
   214     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   215     if (!d->pluginsLoaded)
       
   216         loadPlugins();
       
   217 
       
   218     // no sensors of that type exist
       
   219     if (!d->backendsByType.contains(type))
       
   220         return QList<QByteArray>();
       
   221 
       
   222     return d->backendsByType[type].keys();
       
   223 }
       
   224 
       
   225 /*!
       
   226     Returns the default sensor identifier for \a type.
       
   227     This is set in a config file and can be overridden if required.
       
   228     If no default is available the system will return the first registered
       
   229     sensor for \a type.
       
   230 */
       
   231 QByteArray QSensor::defaultSensorForType(const QByteArray &type)
       
   232 {
       
   233     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   234     if (!d->pluginsLoaded)
       
   235         loadPlugins();
       
   236 
       
   237     // no sensors of that type exist
       
   238     if (!d->backendsByType.contains(type))
       
   239         return QByteArray();
       
   240 
       
   241     QSettings settings(QLatin1String("Nokia"), QLatin1String("Sensors"));
       
   242     QVariant value = settings.value(QString(QLatin1String("Default/%1")).arg(QString::fromLatin1(type)));
       
   243     if (!value.isNull()) {
       
   244         QByteArray defaultIdentifier = value.toByteArray();
       
   245         if (d->backendsByType[type].contains(defaultIdentifier)) // Don't return a value that we can't use!
       
   246             return defaultIdentifier;
       
   247     }
       
   248 
       
   249     // This is our fallback
       
   250     return d->firstIdentifierForType[type];
       
   251 }
       
   252 
       
   253 // =====================================================================
       
   254 
       
   255 /*!
       
   256     \class QSensorBackendFactory
       
   257     \ingroup sensors_backend
       
   258 
       
   259     \brief The QSensorBackendFactory class instantiates instances of
       
   260            QSensorBackend.
       
   261 
       
   262     This interface must be implemented in order to register a sensor backend.
       
   263 
       
   264     \sa {Creating a sensor plugin}
       
   265 */
       
   266 
       
   267 /*!
       
   268     \fn QSensorBackendFactory::~QSensorBackendFactory()
       
   269     \internal
       
   270 */
       
   271 
       
   272 /*!
       
   273     \fn QSensorBackendFactory::createBackend(QSensor *sensor)
       
   274 
       
   275     Instantiate a backend. If the factory handles multiple identifiers
       
   276     it should check with the \a sensor to see which one is requested.
       
   277 
       
   278     If the factory cannot create a backend it should return 0.
       
   279 */
       
   280 
       
   281 /*!
       
   282     \macro REGISTER_STATIC_PLUGIN(pluginname)
       
   283     \relates QSensorManager
       
   284 
       
   285     Registers a static plugin, \a pluginname.
       
   286 
       
   287     Note that this macro relies on static initialization so it may not be appropriate
       
   288     for use in a library and may not work on all platforms.
       
   289 
       
   290     \sa {Creating a sensor plugin}
       
   291 */
       
   292 
       
   293 QTM_END_NAMESPACE
       
   294