diff -r cfcbf08528c4 -r 2b40d63a9c3d qtmobility/src/sensors/qsensormanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qtmobility/src/sensors/qsensormanager.cpp Fri Apr 16 15:51:22 2010 +0300 @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsensormanager.h" +#include +#include "qsensorpluginloader_p.h" +#include "qsensorplugin.h" +#include + +//#define LOG() if (1); else qDebug() + +QTM_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC_WITH_ARGS(QSensorPluginLoader, pluginLoader, (QSensorPluginInterface_iid, QLatin1String("/sensors"))) + +typedef QHash FactoryForIdentifierMap; +typedef QHash BackendIdentifiersForTypeMap; + +class QSensorManagerPrivate +{ +public: + QSensorManagerPrivate() + : pluginsLoaded(false) + { + } + + bool pluginsLoaded; + + QList staticRegistrations; + + // Holds a mapping from type to available identifiers (and from there to the factory) + BackendIdentifiersForTypeMap backendsByType; + + // Holds the first identifier for each type + QHash firstIdentifierForType; +}; + +Q_GLOBAL_STATIC(QSensorManagerPrivate, sensorManagerPrivate) + +static void loadPlugins() +{ + QSensorManagerPrivate *d = sensorManagerPrivate(); + d->pluginsLoaded = true; + + qDebug() << "initializing static plugins"; + Q_FOREACH (CreatePluginFunc func, d->staticRegistrations) { + QSensorPluginInterface *plugin = func(); + plugin->registerSensors(); + } + + qDebug() << "initializing plugins"; + Q_FOREACH (QSensorPluginInterface *plugin, pluginLoader()->plugins()) { + plugin->registerSensors(); + } +} + +// ===================================================================== + +/*! + \class QSensorManager + \ingroup sensors_backend + + \preliminary + \brief The QSensorManager class returns the sensors on a device. + + A given device will have a variety of sensors. The sensors are + categorized by type. +*/ + +/*! + Register a sensor for \a type. The \a identifier must be unique. + + The \a factory will be asked to create instances of the backend. +*/ +void QSensorManager::registerBackend(const QByteArray &type, const QByteArray &identifier, QSensorBackendFactory *factory) +{ + QSensorManagerPrivate *d = sensorManagerPrivate(); + if (!d->backendsByType.contains(type)) { + (void)d->backendsByType[type]; + d->firstIdentifierForType[type] = identifier; + } + qDebug() << "registering backend for type" << type << "identifier" << identifier;// << "factory" << QString().sprintf("0x%08x", (unsigned int)factory); + FactoryForIdentifierMap &factoryByIdentifier = d->backendsByType[type]; + factoryByIdentifier[identifier] = factory; +} + +/*! + \internal +*/ +void QSensorManager::registerStaticPlugin(CreatePluginFunc func) +{ + QSensorManagerPrivate *d = sensorManagerPrivate(); + d->staticRegistrations.append(func); +} + +/*! + Create a backend for \a sensor. Returns null if no suitable backend exists. +*/ +QSensorBackend *QSensorManager::createBackend(QSensor *sensor) +{ + Q_ASSERT(sensor); + + QSensorManagerPrivate *d = sensorManagerPrivate(); + if (!d->pluginsLoaded) + loadPlugins(); + + //LOG() << "QSensorManager::createBackend" << "type" << sensor->type() << "identifier" << sensor->identifier(); + + if (!d->backendsByType.contains(sensor->type())) { + qDebug() << "no backends of type" << sensor->type() << "have been registered."; + return 0; + } + + const FactoryForIdentifierMap &factoryByIdentifier = d->backendsByType[sensor->type()]; + QSensorBackendFactory *factory; + QSensorBackend *backend; + + if (sensor->identifier().isEmpty()) { + QByteArray defaultIdentifier = QSensor::defaultSensorForType(sensor->type()); + //LOG() << "Trying the default" << defaultIdentifier; + // No identifier set, try the default + factory = factoryByIdentifier[defaultIdentifier]; + //LOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory); + sensor->setIdentifier(defaultIdentifier); // the factory requires this + backend = factory->createBackend(sensor); + if (backend) return backend; // Got it! + + // The default failed to instantiate so try any other registered sensors for this type + Q_FOREACH (const QByteArray &identifier, factoryByIdentifier.keys()) { + //LOG() << "Trying" << identifier; + if (identifier == defaultIdentifier) continue; // Don't do the default one again + factory = factoryByIdentifier[identifier]; + //LOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory); + sensor->setIdentifier(identifier); // the factory requires this + backend = factory->createBackend(sensor); + if (backend) return backend; // Got it! + } + //LOG() << "FAILED"; + sensor->setIdentifier(QByteArray()); // clear the identifier + } else { + if (!factoryByIdentifier.contains(sensor->identifier())) { + qDebug() << "no backend with identifier" << sensor->identifier() << "for type" << sensor->type(); + return 0; + } + + // We were given an explicit identifier so don't substitute other backends if it fails to instantiate + factory = factoryByIdentifier[sensor->identifier()]; + //LOG() << "factory" << QString().sprintf("0x%08x", (unsigned int)factory); + backend = factory->createBackend(sensor); + if (backend) return backend; // Got it! + } + + qDebug() << "no suitable backend found for requested identifier" << sensor->identifier() << "and type" << sensor->type(); + return 0; +} + +// ===================================================================== + +/*! + Returns a list of all sensor types. +*/ +QList QSensor::sensorTypes() +{ + QSensorManagerPrivate *d = sensorManagerPrivate(); + if (!d->pluginsLoaded) + loadPlugins(); + + return d->backendsByType.keys(); +} + +/*! + Returns a list of ids for each of the sensors for \a type. + If there are no sensors of that type available the list will be empty. +*/ +QList QSensor::sensorsForType(const QByteArray &type) +{ + QSensorManagerPrivate *d = sensorManagerPrivate(); + if (!d->pluginsLoaded) + loadPlugins(); + + return d->backendsByType[type].keys(); +} + +/*! + Returns the default sensor identifier for \a type. + This is set in a config file and can be overridden if required. + If no default is available the system will return the first registered + sensor for \a type. +*/ +QByteArray QSensor::defaultSensorForType(const QByteArray &type) +{ + QSensorManagerPrivate *d = sensorManagerPrivate(); + if (!d->pluginsLoaded) + loadPlugins(); + + // no sensors of that type exist + if (!d->backendsByType.contains(type)) + return QByteArray(); + + QSettings settings(QLatin1String("Nokia"), QLatin1String("Sensors")); + QVariant value = settings.value(QString(QLatin1String("Default/%1")).arg(QString::fromLatin1(type))); + if (!value.isNull()) { + QByteArray defaultIdentifier = value.toByteArray(); + if (d->backendsByType[type].contains(defaultIdentifier)) // Don't return a value that we can't use! + return defaultIdentifier; + } + + // This is our fallback + return d->firstIdentifierForType[type]; +} + +// ===================================================================== + +/*! + \class QSensorBackendFactory + \ingroup sensors_backend + + \preliminary + \brief The QSensorBackendFactory class instantiates instances of + QSensorBackend. + + This interface must be implemented in order to register a sensor backend. + + \sa {Creating a sensor plugin} +*/ + +/*! + \fn QSensorBackendFactory::~QSensorBackendFactory() + \internal +*/ + +/*! + \fn QSensorBackendFactory::createBackend(QSensor *sensor) + + Instantiate a backend. If the factory handles multiple identifiers + it should check with the \a sensor to see which one is requested. + + If the factory cannot create a backend it should return 0. +*/ + +/*! + \macro REGISTER_STATIC_PLUGIN(pluginname) + \relates QSensorManager + + Registers a static plugin, \a pluginname. + + Note that this macro relies on static initialization so it may not be appropriate + for use in a library and may not work on all platforms. + + \sa {Creating a sensor plugin} +*/ + +QTM_END_NAMESPACE +