qtmobility/src/sensors/qsensormanager.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 
       
    48 //#define LOG() if (1); else qDebug()
       
    49 
       
    50 QTM_BEGIN_NAMESPACE
       
    51 
       
    52 Q_GLOBAL_STATIC_WITH_ARGS(QSensorPluginLoader, pluginLoader, (QSensorPluginInterface_iid, QLatin1String("/sensors")))
       
    53 
       
    54 typedef QHash<QByteArray,QSensorBackendFactory*> FactoryForIdentifierMap;
       
    55 typedef QHash<QByteArray,FactoryForIdentifierMap> BackendIdentifiersForTypeMap;
       
    56 
       
    57 class QSensorManagerPrivate
       
    58 {
       
    59 public:
       
    60     QSensorManagerPrivate()
       
    61         : pluginsLoaded(false)
       
    62     {
       
    63     }
       
    64 
       
    65     bool pluginsLoaded;
       
    66 
       
    67     QList<CreatePluginFunc> staticRegistrations;
       
    68 
       
    69     // Holds a mapping from type to available identifiers (and from there to the factory)
       
    70     BackendIdentifiersForTypeMap backendsByType;
       
    71 
       
    72     // Holds the first identifier for each type
       
    73     QHash<QByteArray, QByteArray> firstIdentifierForType;
       
    74 };
       
    75 
       
    76 Q_GLOBAL_STATIC(QSensorManagerPrivate, sensorManagerPrivate)
       
    77 
       
    78 static void loadPlugins()
       
    79 {
       
    80     QSensorManagerPrivate *d = sensorManagerPrivate();
       
    81     d->pluginsLoaded = true;
       
    82 
       
    83     qDebug() << "initializing static plugins";
       
    84     Q_FOREACH (CreatePluginFunc func, d->staticRegistrations) {
       
    85         QSensorPluginInterface *plugin = func();
       
    86         plugin->registerSensors();
       
    87     }
       
    88 
       
    89     qDebug() << "initializing plugins";
       
    90     Q_FOREACH (QSensorPluginInterface *plugin, pluginLoader()->plugins()) {
       
    91         plugin->registerSensors();
       
    92     }
       
    93 }
       
    94 
       
    95 // =====================================================================
       
    96 
       
    97 /*!
       
    98     \class QSensorManager
       
    99     \ingroup sensors_backend
       
   100 
       
   101     \preliminary
       
   102     \brief The QSensorManager class returns the sensors on a device.
       
   103 
       
   104     A given device will have a variety of sensors. The sensors are
       
   105     categorized by type.
       
   106 */
       
   107 
       
   108 /*!
       
   109     Register a sensor for \a type. The \a identifier must be unique.
       
   110 
       
   111     The \a factory will be asked to create instances of the backend.
       
   112 */
       
   113 void QSensorManager::registerBackend(const QByteArray &type, const QByteArray &identifier, QSensorBackendFactory *factory)
       
   114 {
       
   115     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   116     if (!d->backendsByType.contains(type)) {
       
   117         (void)d->backendsByType[type];
       
   118         d->firstIdentifierForType[type] = identifier;
       
   119     }
       
   120     qDebug() << "registering backend for type" << type << "identifier" << identifier;// << "factory" << QString().sprintf("0x%08x", (unsigned int)factory);
       
   121     FactoryForIdentifierMap &factoryByIdentifier = d->backendsByType[type];
       
   122     factoryByIdentifier[identifier] = factory;
       
   123 }
       
   124 
       
   125 /*!
       
   126     \internal
       
   127 */
       
   128 void QSensorManager::registerStaticPlugin(CreatePluginFunc func)
       
   129 {
       
   130     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   131     d->staticRegistrations.append(func);
       
   132 }
       
   133 
       
   134 /*!
       
   135     Create a backend for \a sensor. Returns null if no suitable backend exists.
       
   136 */
       
   137 QSensorBackend *QSensorManager::createBackend(QSensor *sensor)
       
   138 {
       
   139     Q_ASSERT(sensor);
       
   140 
       
   141     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   142     if (!d->pluginsLoaded)
       
   143         loadPlugins();
       
   144 
       
   145     //LOG() << "QSensorManager::createBackend" << "type" << sensor->type() << "identifier" << sensor->identifier();
       
   146 
       
   147     if (!d->backendsByType.contains(sensor->type())) {
       
   148         qDebug() << "no backends of type" << sensor->type() << "have been registered.";
       
   149         return 0;
       
   150     }
       
   151 
       
   152     const FactoryForIdentifierMap &factoryByIdentifier = d->backendsByType[sensor->type()];
       
   153     QSensorBackendFactory *factory;
       
   154     QSensorBackend *backend;
       
   155 
       
   156     if (sensor->identifier().isEmpty()) {
       
   157         QByteArray defaultIdentifier = QSensor::defaultSensorForType(sensor->type());
       
   158         //LOG() << "Trying the default" << defaultIdentifier;
       
   159         // No identifier set, try the default
       
   160         factory = factoryByIdentifier[defaultIdentifier];
       
   161         //LOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory);
       
   162         sensor->setIdentifier(defaultIdentifier); // the factory requires this
       
   163         backend = factory->createBackend(sensor);
       
   164         if (backend) return backend; // Got it!
       
   165 
       
   166         // The default failed to instantiate so try any other registered sensors for this type
       
   167         Q_FOREACH (const QByteArray &identifier, factoryByIdentifier.keys()) {
       
   168             //LOG() << "Trying" << identifier;
       
   169             if (identifier == defaultIdentifier) continue; // Don't do the default one again
       
   170             factory = factoryByIdentifier[identifier];
       
   171             //LOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory);
       
   172             sensor->setIdentifier(identifier); // the factory requires this
       
   173             backend = factory->createBackend(sensor);
       
   174             if (backend) return backend; // Got it!
       
   175         }
       
   176         //LOG() << "FAILED";
       
   177         sensor->setIdentifier(QByteArray()); // clear the identifier
       
   178     } else {
       
   179         if (!factoryByIdentifier.contains(sensor->identifier())) {
       
   180             qDebug() << "no backend with identifier" << sensor->identifier() << "for type" << sensor->type();
       
   181             return 0;
       
   182         }
       
   183 
       
   184         // We were given an explicit identifier so don't substitute other backends if it fails to instantiate
       
   185         factory = factoryByIdentifier[sensor->identifier()];
       
   186         //LOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory);
       
   187         backend = factory->createBackend(sensor);
       
   188         if (backend) return backend; // Got it!
       
   189     }
       
   190 
       
   191     qDebug() << "no suitable backend found for requested identifier" << sensor->identifier() << "and type" << sensor->type();
       
   192     return 0;
       
   193 }
       
   194 
       
   195 // =====================================================================
       
   196 
       
   197 /*!
       
   198     Returns a list of all sensor types.
       
   199 */
       
   200 QList<QByteArray> QSensor::sensorTypes()
       
   201 {
       
   202     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   203     if (!d->pluginsLoaded)
       
   204         loadPlugins();
       
   205 
       
   206     return d->backendsByType.keys();
       
   207 }
       
   208 
       
   209 /*!
       
   210     Returns a list of ids for each of the sensors for \a type.
       
   211     If there are no sensors of that type available the list will be empty.
       
   212 */
       
   213 QList<QByteArray> QSensor::sensorsForType(const QByteArray &type)
       
   214 {
       
   215     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   216     if (!d->pluginsLoaded)
       
   217         loadPlugins();
       
   218 
       
   219     return d->backendsByType[type].keys();
       
   220 }
       
   221 
       
   222 /*!
       
   223     Returns the default sensor identifier for \a type.
       
   224     This is set in a config file and can be overridden if required.
       
   225     If no default is available the system will return the first registered
       
   226     sensor for \a type.
       
   227 */
       
   228 QByteArray QSensor::defaultSensorForType(const QByteArray &type)
       
   229 {
       
   230     QSensorManagerPrivate *d = sensorManagerPrivate();
       
   231     if (!d->pluginsLoaded)
       
   232         loadPlugins();
       
   233 
       
   234     // no sensors of that type exist
       
   235     if (!d->backendsByType.contains(type))
       
   236         return QByteArray();
       
   237 
       
   238     QSettings settings(QLatin1String("Nokia"), QLatin1String("Sensors"));
       
   239     QVariant value = settings.value(QString(QLatin1String("Default/%1")).arg(QString::fromLatin1(type)));
       
   240     if (!value.isNull()) {
       
   241         QByteArray defaultIdentifier = value.toByteArray();
       
   242         if (d->backendsByType[type].contains(defaultIdentifier)) // Don't return a value that we can't use!
       
   243             return defaultIdentifier;
       
   244     }
       
   245 
       
   246     // This is our fallback
       
   247     return d->firstIdentifierForType[type];
       
   248 }
       
   249 
       
   250 // =====================================================================
       
   251 
       
   252 /*!
       
   253     \class QSensorBackendFactory
       
   254     \ingroup sensors_backend
       
   255 
       
   256     \preliminary
       
   257     \brief The QSensorBackendFactory class instantiates instances of
       
   258            QSensorBackend.
       
   259 
       
   260     This interface must be implemented in order to register a sensor backend.
       
   261 
       
   262     \sa {Creating a sensor plugin}
       
   263 */
       
   264 
       
   265 /*!
       
   266     \fn QSensorBackendFactory::~QSensorBackendFactory()
       
   267     \internal
       
   268 */
       
   269 
       
   270 /*!
       
   271     \fn QSensorBackendFactory::createBackend(QSensor *sensor)
       
   272 
       
   273     Instantiate a backend. If the factory handles multiple identifiers
       
   274     it should check with the \a sensor to see which one is requested.
       
   275 
       
   276     If the factory cannot create a backend it should return 0.
       
   277 */
       
   278 
       
   279 /*!
       
   280     \macro REGISTER_STATIC_PLUGIN(pluginname)
       
   281     \relates QSensorManager
       
   282 
       
   283     Registers a static plugin, \a pluginname.
       
   284 
       
   285     Note that this macro relies on static initialization so it may not be appropriate
       
   286     for use in a library and may not work on all platforms.
       
   287 
       
   288     \sa {Creating a sensor plugin}
       
   289 */
       
   290 
       
   291 QTM_END_NAMESPACE
       
   292