[meego-commits] 5579: Changes to Trunk:Testing/meegotouch-feedback
Kaitlin Rupert
kaitlin.rupert at intel.com
Mon Jul 12 18:27:57 UTC 2010
Hi,
I have made the following changes to meegotouch-feedback in project Trunk:Testing. Please review and accept ASAP.
Thank You,
Kaitlin Rupert
[This message was auto-generated]
---
Request #5579:
submit: devel:nokia:trunk/meegotouch-feedback(r4) -> Trunk:Testing/meegotouch-feedback
Message:
Update to release tag 0.10.1-4. This update depends on the libmeegotouch update.
State: new 2010-07-12T06:22:59 krupert
Comment: None
changes files:
--------------
--- meegotouch-feedback.changes
+++ meegotouch-feedback.changes
@@ -0,0 +1,3 @@
+* Fri Jul 09 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> 0.10.1
+- Update to release tag 0.10.1-4
+
spec files:
-----------
other changes:
--------------
++++++ meegotouch-feedback-0.10.1.tar.bz2
--- conf/daemon.conf
+++ conf/daemon.conf
@@ -1,4 +1,6 @@
[General]
+# Feedback latency limit in microseconds
+feedback-latency-limit=2000
# Feedback length limit in milliseconds
feedback-length-limit=1000
--- debian/changelog
+++ debian/changelog
@@ -1,3 +1,11 @@
+meegofeedbackd (0.10.1-4) unstable; urgency=low
+
+ * Added dropping of feedbacks with high latency
+ * Added possibility to call backend play() methods in separate threads
+ * Implemented: SWP#FEFRA-387, SWP#FEFRA-374
+
+ -- Antti Pulakka <ext-antti.j.pulakka at nokia.com> Thu, 10 Jun 2010 15:02:24 +0200
+
meegofeedbackd (0.10.1-3) unstable; urgency=low
* Fixed functional test
--- debian/meegofeedback-dummy.postinst
+++ debian/meegofeedback-dummy.postinst
+#! /bin/sh
+# postinst script for MeeGo Touch Feedback Framework dummy backend
+
+set -e
+
+case "$1" in
+ configure)
+ mkdir -p /usr/lib/meegofeedbackd/non-threaded-backends
+ if ! [ -e "/usr/lib/meegofeedbackd/non-threaded-backends/02-libmeegofeedback-dummy.so" ]; then
+ ln -s /usr/lib/meegofeedbackd/libmeegofeedback-dummy.so /usr/lib/meegofeedbackd/non-threaded-backends/02-libmeegofeedback-dummy.so
+ fi
+ ;;
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
--- debian/meegofeedback-dummy.postrm
+++ debian/meegofeedback-dummy.postrm
+#!/bin/sh
+set -e
+
+if [ "$1" = "remove" ] ; then
+ rm -f /usr/lib/meegofeedbackd/non-threaded-backends/02-libmeegofeedback-dummy.so
+fi
+
+#DEBHELPER#
+
+exit 0
+
--- src/daemon/mfconnection.cpp
+++ src/daemon/mfconnection.cpp
@@ -92,7 +92,7 @@
return;
}
- session->feedbackHash.value(feedbackName)->play();
+ session->feedbackHash.value(feedbackName)->emitPlay(getTimestamp());
}
void MfConnection::terminate()
--- src/lib/mfconfig.cpp
+++ src/lib/mfconfig.cpp
@@ -16,11 +16,22 @@
#include "mfconfig.h"
+#include <QDebug>
#include <QSettings>
+qint64 MfConfig::_feedbackLatencyLimit = -1;
int MfConfig::_feedbackLengthLimit = -1;
bool MfConfig::_loaded = false;
+qint64 MfConfig::feedbackLatencyLimit()
+{
+ if (!_loaded) {
+ load();
+ }
+
+ return _feedbackLatencyLimit;
+}
+
int MfConfig::feedbackLengthLimit()
{
if (!_loaded) {
@@ -35,5 +46,8 @@
QSettings settings("/etc/meegofeedbackd/daemon.conf", QSettings::NativeFormat);
_loaded = true;
+ _feedbackLatencyLimit = (qint64)settings.value("feedback-latency-limit", QVariant(2000)).toInt();
_feedbackLengthLimit = settings.value("feedback-length-limit", QVariant(1000)).toInt();
+ qDebug() << "Loaded feedback latency limit:" << _feedbackLatencyLimit;
+ qDebug() << "Loaded feedback length limit:" << _feedbackLengthLimit;
}
--- src/lib/mfconfig.h
+++ src/lib/mfconfig.h
@@ -17,13 +17,17 @@
#ifndef MFCONFIG_H
#define MFCONFIG_H
+#include <QtGlobal>
+
class MfConfig {
public:
+ static qint64 feedbackLatencyLimit();
static int feedbackLengthLimit();
private:
static void load();
+ static qint64 _feedbackLatencyLimit;
static int _feedbackLengthLimit;
static bool _loaded;
};
--- src/lib/mffeedback.cpp
+++ src/lib/mffeedback.cpp
@@ -18,9 +18,12 @@
#include <QDir>
#include <QDebug>
+#include <QtConcurrentRun>
-#include "mfmanager.h"
+#include "mfconfig.h"
#include "mffeedbackhandle.h"
+#include "mfmanager.h"
+#include "mfutil.h"
MfManager* MfFeedback::manager = 0;
@@ -38,6 +41,14 @@
for (int i = 0; i < manager->backendList.size(); ++i) {
feedbackHandles << QPointer<MfFeedbackHandle>();
}
+
+ // Set correct amount of QFuture placeholders for concurrent playing
+ for (int i = 0; i < (manager->backendList.size() - manager->nonThreadedBackendCount); ++i) {
+ concurrentPlayers << QFuture<void>();
+ }
+
+ connect(this, SIGNAL(startPlay(qint64)), this,
+ SLOT(play(qint64)), Qt::QueuedConnection);
}
MfFeedback::~MfFeedback()
@@ -139,14 +150,47 @@
return feedbackName;
}
-void MfFeedback::play()
+void MfFeedback::emitPlay(qint64 timestamp)
{
- for (int i = 0; i < feedbackHandles.size(); i++) {
+ emit startPlay(timestamp);
+}
+
+void MfFeedback::play(qint64 timestamp)
+{
+ int playerCount = 0;
+
+ if (timestamp != -1) {
+ long int timeDiff = getTimestamp()-timestamp;
+
+ if (timeDiff > MfConfig::feedbackLatencyLimit()) {
+ qDebug() << "Skip the feedback because of too much latency: " <<
+ timeDiff << "usec";
+ return;
+ }
+ }
+
+ // Play feedbacks using non-threaded backend interfaces
+ for (int i = 0; i < manager->nonThreadedBackendCount; ++i) {
if (feedbackHandles[i].isNull() == false &&
feedbackHandles[i]->state() == MfFeedbackHandle::Ready) {
feedbackHandles[i]->play();
}
}
+
+ // Play the rest of the feedbacks in separate threads
+ for (int i = manager->nonThreadedBackendCount; i < feedbackHandles.size(); ++i) {
+ if (feedbackHandles[i].isNull() == false &&
+ feedbackHandles[i]->state() == MfFeedbackHandle::Ready) {
+ concurrentPlayers[playerCount] = QtConcurrent::run(feedbackHandles[i].data(), &MfFeedbackHandle::play);
+ playerCount++;
+ }
+ }
+
+ // Wait until the playing has stopped to avoid concurrency problems
+ // in main thread.
+ for (int i = 0; i < playerCount; ++i) {
+ concurrentPlayers[i].waitForFinished();
+ }
}
const QList<QPointer<MfFeedbackHandle> >& MfFeedback::fbHandles()
--- src/lib/mffeedback.h
+++ src/lib/mffeedback.h
@@ -21,6 +21,7 @@
#include <QList>
#include <QString>
#include <QPointer>
+#include <QFuture>
class MfFeedbackHandle;
class MfManager;
@@ -45,8 +46,13 @@
const QList<QPointer<MfFeedbackHandle> > &fbHandles();
-public slots:
- void play();
+ void emitPlay(qint64 timestamp);
+
+signals:
+ void startPlay(qint64 timestamp);
+
+private slots:
+ void play(qint64 timestamp);
protected:
void unload();
@@ -54,7 +60,12 @@
static MfManager *manager;
QString feedbackName;
+
+ // The size of feedbackHandles must always match the size of
+ // loaded backend interfaces.
QList<QPointer<MfFeedbackHandle> > feedbackHandles;
+
+ QList<QFuture<void> > concurrentPlayers;
};
#endif
--- src/lib/mfmanager.cpp
+++ src/lib/mfmanager.cpp
@@ -17,6 +17,7 @@
#include "mfmanager.h"
#include <QDir>
+#include <QThreadPool>
#include "mfbackendbase.h"
#include "mfconfig.h"
@@ -25,13 +26,18 @@
#include "mflog.h"
#include "mfsourceinterface.h"
+#define MFMANAGER_MAX_THREADS 2
+
// TODO: Take directory from header file made at configuration time?
-static const char gLibDir[] = "/usr/lib/meegofeedbackd";
+static const char gLibDirPrefix[] = "/usr/lib/meegofeedbackd";
+static const char gThreadedBackendsDir[] = "/threaded-backends";
+static const char gNonThreadedBackendsDir[] = "/non-threaded-backends";
+static const char gSourcesDir[] = "/sources";
static MfManager *gInstance = NULL;
MfManager::MfManager(QObject *parent)
- : QObject(parent)
+ : QObject(parent), nonThreadedBackendCount(0)
{
if (gInstance) {
qCritical("MfManager: Creating an instance but another one already exists");
@@ -45,10 +51,22 @@
{
deleteCache();
- qDeleteAll(sourceList);
+ // Unload the sources and delete QPluginLoaders. Note that
+ // QPluginLoader will delete the source instances when unloading.
+ for (int i = 0; i < sourceLoaderList.size(); ++i) {
+ sourceLoaderList[i]->unload();
+ delete sourceLoaderList[i];
+ sourceLoaderList[i] = NULL;
+ }
sourceList.clear();
- qDeleteAll(backendList);
+ // Unload the backends and delete QPluginLoaders. Note that
+ // QPluginLoader will delete the backend instances when unloading.
+ for (int i = 0; i < backendLoaderList.size(); ++i) {
+ backendLoaderList[i]->unload();
+ delete backendLoaderList[i];
+ backendLoaderList[i] = NULL;
+ }
backendList.clear();
gInstance = NULL;
@@ -62,17 +80,49 @@
bool MfManager::init(const QString &theme, const QMap<QString, MfBackendInterface::playbackVolume> &volumes)
{
bool ok = true;
+ QString pluginPath;
+ QThreadPool *globalThreadPool = QThreadPool::globalInstance();
// Store the current theme name
currentThemeName = theme;
- loadPlugins(gLibDir);
+ // Load non-threaded backend plugins
+ pluginPath = gLibDirPrefix;
+ pluginPath.append(gNonThreadedBackendsDir);
+ loadBackendPlugins(pluginPath);
+
+ // Store the number of non-threaded backends for later use
+ nonThreadedBackendCount = backendList.size();
+
+ // Load threaded backend plugins
+ pluginPath = gLibDirPrefix;
+ pluginPath.append(gThreadedBackendsDir);
+ loadBackendPlugins(pluginPath);
if (backendList.size() == 0) {
qCritical("MfManager: No backend library found!");
return false;
}
+ // Load source plugins
+ pluginPath = gLibDirPrefix;
+ pluginPath.append(gSourcesDir);
+ loadSourcePlugins(pluginPath);
+
+ if (sourceList.size() == 0) {
+ qCritical("MfManager: No source library found!");
+ }
+
+ // Adjust amount of QThreads in QThreadPool to match the amount of
+ // threaded backend but no more than MFMANAGER_MAX_THREADS.
+ if (globalThreadPool) {
+ int targetThreadCount = qBound(0, backendList.size() - nonThreadedBackendCount, MFMANAGER_MAX_THREADS);
+
+ if (globalThreadPool->maxThreadCount() < targetThreadCount) {
+ globalThreadPool->setMaxThreadCount(targetThreadCount);
+ }
+ }
+
// Set initial volumes for the backends
for (int i = 0; i < backendList.size(); ++i) {
if (volumes.contains(backendList[i]->name()) == true) {
@@ -82,6 +132,7 @@
backendList[i]->setVolume(MfBackendInterface::VolumeMedium);
}
}
+
// Listen to the lost/established connections
for (int i = 0; i < backendList.size(); ++i) {
connect(backendList[i], SIGNAL(lostConnection()), this, SLOT(backendDisconnected()),
@@ -94,21 +145,16 @@
Qt::QueuedConnection);
}
- if (sourceList.size() == 0) {
- qCritical("MfManager: No source library found!");
- }
-
return ok;
}
-void MfManager::loadPlugins(const QString &libDir)
+void MfManager::loadSourcePlugins(const QString &libDir)
{
QDir dir;
QStringList fileList;
QString fileName;
QPluginLoader *pluginLoader;
QObject *rootComponent = 0;
- MfBackendBase *backend = 0;
MfSourceInterface *source = 0;
dir.setPath(libDir);
@@ -123,73 +169,167 @@
for (int i = 0; i < fileList.size(); i++) {
fileName = fileList[i];
- // Search source or backend libraries with a pattern
+ // Search source libraries with a pattern
if (fileName.startsWith(QLatin1String("libmeegofeedback-")) && fileName.endsWith(QLatin1String(".so"))) {
- backend = 0;
source = 0;
QString filePath = dir.filePath(fileName);
- qDebug() << "MfManager: found source or backend library file" << fileName;
+ qDebug() << "MfManager: found source library file" << fileName;
pluginLoader = new QPluginLoader(filePath, this);
rootComponent = pluginLoader->instance();
if (!rootComponent) {
- qWarning() << "MfManager: Unable to instantiate backend" << filePath;
+ qWarning() << "MfManager: Unable to instantiate source plugin" << filePath;
if (!pluginLoader->errorString().isEmpty()) {
qWarning() << "Detailed error message:" << pluginLoader->errorString();
}
goto FAILED;
}
- backend = qobject_cast<MfBackendBase*>(rootComponent);
source = qobject_cast<MfSourceInterface*>(rootComponent);
- if (!source && !backend) {
+
+ if (!source) {
qWarning() << "MfManager:"
- << filePath << "does not implement MfSourceInterface nor MfBackendBase.";
+ << filePath << "does not implement MfSourceInterface.";
goto FAILED;
}
- if (backend) {
- backend->reconnect();
+ // Make sure the same source doesn't get loaded more than
+ // once. It is possible to load the same plugin more than
+ // once if symlinks are used. In this case QPluginLoader
+ // will return the same instance that was loaded before. We
+ // don't want that here.
+ for (int i2 = 0; i2 < sourceList.size(); ++i2) {
+ if (source == sourceList[i2]) {
+ qWarning() << "MfManager: Source library"
+ << filePath << "already loaded.";
+ goto FAILED;
+ }
}
+
if (source && !source->init()) {
qWarning() << "MfManager:" << filePath << "failed to initialize.";
goto FAILED;
}
- mfLog() << "Loaded backend" << filePath;
+ mfLog() << "Loaded source plugin" << filePath;
- // Add the backend to the backend list
- if (backend) {
- backendList << backend;
- }
// Add the source to the source list
if (source) {
sourceList << source;
}
- // Delete the plugin loader instance
+
+ // Add the plugin loader instance to source loader list
if (pluginLoader) {
- delete pluginLoader;
+ sourceLoaderList << pluginLoader;
}
- // If we reached that point, everything went just fine.
+ // If we reached this point, everything went just fine.
continue;
+
FAILED:
+ // Calling unload() will delete the instanciated source
+ // if the source hasn't been loaded before.
+ if (pluginLoader) {
+ if (pluginLoader->isLoaded()) {
+ pluginLoader->unload();
+ }
+ delete pluginLoader;
+ pluginLoader = NULL;
+ }
+ }
+ }
+}
+
+void MfManager::loadBackendPlugins(const QString &libDir)
+{
+ QDir dir;
+ QStringList fileList;
+ QString fileName;
+ QPluginLoader *pluginLoader;
+ QObject *rootComponent = 0;
+ MfBackendBase *backend = 0;
+
+ dir.setPath(libDir);
+
+ if (!dir.exists()) {
+ qCritical() << "MfManager: Lib directory" << libDir << "doesn't exist.";
+ return;
+ }
+
+ fileList = dir.entryList(QDir::Files, QDir::Name);
+
+ for (int i1 = 0; i1 < fileList.size(); i1++) {
+ fileName = fileList[i1];
+
+ // Search source or backend libraries with a pattern
+ if (fileName.contains(QLatin1String("libmeegofeedback-")) && fileName.endsWith(QLatin1String(".so"))) {
+ backend = NULL;
+ QString filePath = dir.filePath(fileName);
+
+ qDebug() << "MfManager: found backend library file" << fileName;
+
+ pluginLoader = new QPluginLoader(filePath, this);
+
+ rootComponent = pluginLoader->instance();
+ if (!rootComponent) {
+ qWarning() << "MfManager: Unable to instantiate backend plugin" << filePath;
+ if (!pluginLoader->errorString().isEmpty()) {
+ qWarning() << "Detailed error message:" << pluginLoader->errorString();
+ }
+ goto FAILED;
+ }
+
+ backend = qobject_cast<MfBackendBase*>(rootComponent);
+
+ if (!backend) {
+ qWarning() << "MfManager:"
+ << filePath << "does not implement MfBackendBase.";
+ goto FAILED;
+ }
+
+ // Make sure the same backend doesn't get loaded more than
+ // once. It is possible to load the same plugin more than
+ // once if symlinks are used. In this case QPluginLoader
+ // will return the same instance that was loaded before. We
+ // don't want that here.
+ for (int i2 = 0; i2 < backendList.size(); ++i2) {
+ if (backend == backendList[i2]) {
+ qWarning() << "MfManager: Backend library"
+ << filePath << "already loaded.";
+ goto FAILED;
+ }
+ }
+
if (backend) {
- delete backend;
- backend = NULL;
+ backend->reconnect();
}
- if (source) {
- delete source;
- source = NULL;
+
+ mfLog() << "Loaded backend plugin" << filePath;
+
+ // Add the backend to the backend list
+ if (backend) {
+ backendList << backend;
+ }
+
+ // Add the plugin loader instance to backend loader list
+ if (pluginLoader) {
+ backendLoaderList << pluginLoader;
}
+ // If we reached that point, everything went just fine.
+ continue;
+
+ FAILED:
+ // Calling unload() will delete the instanciated backend
+ // if the backend hasn't been loaded before.
if (pluginLoader) {
if (pluginLoader->isLoaded()) {
pluginLoader->unload();
}
delete pluginLoader;
+ pluginLoader = NULL;
}
}
}
--- src/lib/mfmanager.h
+++ src/lib/mfmanager.h
@@ -45,7 +45,8 @@
bool init(const QString &theme, const QMap<QString, MfBackendInterface::playbackVolume> &volumes);
- virtual void loadPlugins(const QString &libDir);
+ virtual void loadBackendPlugins(const QString &libDir);
+ virtual void loadSourcePlugins(const QString &libDir);
QPointer<MfFeedbackHandle> searchFromCache(const QString &feedbackDir, const int &backendInterfaceIndex);
void addToCache(MfFeedbackHandle* feedbackHandle);
@@ -72,12 +73,15 @@
void unloadHandlesForABackend(MfBackendBase* backend);
public:
+ int nonThreadedBackendCount;
QList<MfBackendBase*> backendList;
QList<MfSourceInterface*> sourceList;
protected:
QString currentThemeName;
QHash<QString, QPointer<MfFeedbackHandle> > feedbackHandleHash;
+ QList<QPluginLoader*> backendLoaderList;
+ QList<QPluginLoader*> sourceLoaderList;
};
#endif
--- src/lib/mfutil.h
+++ src/lib/mfutil.h
@@ -63,4 +63,14 @@
*/
void writeTimestamp(const char* message);
+/* Get the current timestamp in microseconds.
+ */
+inline qint64 getTimestamp()
+{
+ struct timespec time;
+
+ clock_gettime(CLOCK_MONOTONIC, &time);
+ return (qint64)time.tv_sec*1000000+time.tv_nsec/1000;
+}
+
#endif
--- tests/ft_configuration/gconf_mock.cpp
+++ tests/ft_configuration/gconf_mock.cpp
@@ -1,7 +1,24 @@
+/* This file is part of meegofeedbackd
+ *
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * Contact: Nokia Corporation (directui at nokia.com)
+ *
+ * If you have questions regarding the use of this file, please contact
+ * Nokia at directui at nokia.com.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it 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.
+ */
+
+#include "gconf_mock.h"
+
#include <QtGlobal>
#include <QtDebug>
-#include "gconf_mock.h"
#include "globals.h"
G_DEFINE_TYPE (GConfClient, gconf_client, G_TYPE_OBJECT);
--- tests/ft_configuration/gconf_mock.h
+++ tests/ft_configuration/gconf_mock.h
@@ -1,3 +1,19 @@
+/* This file is part of meegofeedbackd
+ *
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * Contact: Nokia Corporation (directui at nokia.com)
+ *
+ * If you have questions regarding the use of this file, please contact
+ * Nokia at directui at nokia.com.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it 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.
+ */
+
#ifndef GCONF_MOCK_H
#define GCONF_MOCK_H
--- tests/ft_configuration/mfmanagertest.h
+++ tests/ft_configuration/mfmanagertest.h
@@ -37,15 +37,20 @@
MfManagerTest() {};
~MfManagerTest() {};
- void loadPlugins(const QString &libDir)
+ void loadBackendPlugins(const QString &libDir)
{
- Q_UNUSED(libDir);
-
- audioBackend = (MfBackendDummyAudio *)new MfBackendDummyAudio();
- backendList.append(dynamic_cast<MfBackendBase*>(audioBackend));
+ if (libDir == "/usr/lib/meegofeedbackd/non-threaded-backends") {
+ audioBackend = (MfBackendDummyAudio *)new MfBackendDummyAudio();
+ backendList.append(dynamic_cast<MfBackendBase*>(audioBackend));
+ } else if (libDir == "/usr/lib/meegofeedbackd/threaded-backends") {
+ vibraBackend = new MfBackendDummyVibra();
+ backendList.append(dynamic_cast<MfBackendBase*>(vibraBackend));
+ }
+ };
- vibraBackend = new MfBackendDummyVibra();
- backendList.append(dynamic_cast<MfBackendBase*>(vibraBackend));
+ void loadSourcePlugins(const QString &libDir)
+ {
+ Q_UNUSED(libDir);
};
QHash<QString, QPointer<MfFeedbackHandle> > feedbackCache()
--- tests/ft_reconnection/mfconfig_mock.cpp
+++ tests/ft_reconnection/mfconfig_mock.cpp
@@ -14,13 +14,18 @@
* of this file.
*/
-#include <mfconfig.h>
-
#include "mfconfig_mock.h"
+#include <mfconfig.h>
+
int feedbackLimit = 1000;
int MfConfig::feedbackLengthLimit()
{
return feedbackLimit;
}
+
+qint64 MfConfig::feedbackLatencyLimit()
+{
+ return 2000;
+}
--- tests/ft_reconnection/mfmanagerhandlestest.h
+++ tests/ft_reconnection/mfmanagerhandlestest.h
@@ -14,8 +14,8 @@
* of this file.
*/
-#ifndef MFMANAGERHANDLETEST_H
-#define MFMANAGERHANDLETEST_H
+#ifndef MFMANAGERHANDLESTEST_H
+#define MFMANAGERHANDLESTEST_H
#include <mffeedbackhandle.h>
#include <mfmanager.h>
@@ -35,16 +35,22 @@
MfManagerHandlesTest() {};
~MfManagerHandlesTest() {};
- void loadPlugins(const QString &libDir)
+ void loadBackendPlugins(const QString &libDir)
+ {
+ if (libDir == "/usr/lib/meegofeedbackd/non-threaded-backends") {
+ audioBackend = (MfBackendDummyAudio *)new MfBackendDummyAudio();
+ audioBackend->init(0);
+ backendList.append(dynamic_cast<MfBackendBase*>(audioBackend));
+ } else if (libDir == "/usr/lib/meegofeedbackd/threaded-backends") {
+ vibraBackend = new MfBackendDummyVibra();
+ vibraBackend->init(0);
+ backendList.append(dynamic_cast<MfBackendBase*>(vibraBackend));
+ }
+ };
+
+ void loadSourcePlugins(const QString &libDir)
{
Q_UNUSED(libDir);
- audioBackend = new MfBackendDummyAudio();
- audioBackend->init(0);
- backendList.append(dynamic_cast<MfBackendBase*>(audioBackend));
-
- vibraBackend = new MfBackendDummyVibra();
- vibraBackend->init(0);
- backendList.append(dynamic_cast<MfBackendBase*>(vibraBackend));
};
bool checkHandleCache(MfBackendBase* backend)
--- tests/ft_reconnection/mfmanagertest.h
+++ tests/ft_reconnection/mfmanagertest.h
@@ -35,16 +35,22 @@
MfManagerTest() {};
~MfManagerTest() {};
- void loadPlugins(const QString &libDir)
+ void loadBackendPlugins(const QString &libDir)
{
- Q_UNUSED(libDir);
- audioBackend = new MfBackendDummyAudio();
- audioBackend->reconnect();
- backendList.append(dynamic_cast<MfBackendBase*>(audioBackend));
+ if (libDir == "/usr/lib/meegofeedbackd/non-threaded-backends") {
+ audioBackend = (MfBackendDummyAudio *)new MfBackendDummyAudio();
+ backendList.append(dynamic_cast<MfBackendBase*>(audioBackend));
+ audioBackend->reconnect();
+ } else if (libDir == "/usr/lib/meegofeedbackd/threaded-backends") {
+ vibraBackend = new MfBackendDummyVibra();
+ vibraBackend->reconnect();
+ backendList.append(dynamic_cast<MfBackendBase*>(vibraBackend));
+ }
+ };
- vibraBackend = new MfBackendDummyVibra();
- vibraBackend->reconnect();
- backendList.append(dynamic_cast<MfBackendBase*>(vibraBackend));
+ void loadSourcePlugins(const QString &libDir)
+ {
+ Q_UNUSED(libDir);
};
MfBackendDummyAudio *audioBackend;
--- tests/ft_theming/main.cpp
+++ tests/ft_theming/main.cpp
@@ -138,7 +138,8 @@
manager->vibraBackend->playList.clear();
// Play feedback
- feedback->play();
+ feedback->emitPlay(-1);
+ QCoreApplication::processEvents();
const QList<QPointer<MfFeedbackHandle> >& feedbackHandles = feedback->fbHandles();
if (feedbackHandles.size() != feedbackHandleStates[i1].size()) {
@@ -204,10 +205,9 @@
appName = lineStr.section(',', 1, 1);
qDebug() << "Test case: theme:" << themeName << "app:" << appName;
manager->loadTheme(themeName);
- // Run a small event loop to process the theme loading because
- // it uses queued connection.
- QTimer::singleShot(50, QCoreApplication::instance(), SLOT(quit()));
- QCoreApplication::instance()->exec();
+ // Process events because the theme loading uses
+ // signals/slots with queued connection.
+ QCoreApplication::processEvents();
if (session != NULL && oldAppName == appName) {
qDebug() << "Application name remained the same, reusing MfSession instance.";
} else {
@@ -350,10 +350,9 @@
}
qDebug() << "Test case: theme:" << themeName << "apps:" << lineStr.section(',', 1);
manager->loadTheme(themeName);
- // Run a small event loop to process the theme loading because
- // it uses queued connection.
- QTimer::singleShot(50, QCoreApplication::instance(), SLOT(quit()));
- QCoreApplication::instance()->exec();
+ // Process events because the theme loading uses
+ // signals/slots with queued connection.
+ QCoreApplication::processEvents();
cacheContent.clear();
} else {
// Parse cache entry
--- tests/ft_theming/mfmanagertest.h
+++ tests/ft_theming/mfmanagertest.h
@@ -37,14 +37,20 @@
MfManagerTest() {};
~MfManagerTest() {};
- void loadPlugins(const QString &libDir)
+ void loadBackendPlugins(const QString &libDir)
{
- Q_UNUSED(libDir);
- audioBackend = new MfBackendDummyAudio();
- backendList.append(dynamic_cast<MfBackendBase*>(audioBackend));
+ if (libDir == "/usr/lib/meegofeedbackd/non-threaded-backends") {
+ audioBackend = (MfBackendDummyAudio *)new MfBackendDummyAudio();
+ backendList.append(dynamic_cast<MfBackendBase*>(audioBackend));
+ } else if (libDir == "/usr/lib/meegofeedbackd/threaded-backends") {
+ vibraBackend = new MfBackendDummyVibra();
+ backendList.append(dynamic_cast<MfBackendBase*>(vibraBackend));
+ }
+ };
- vibraBackend = new MfBackendDummyVibra();
- backendList.append(dynamic_cast<MfBackendBase*>(vibraBackend));
+ void loadSourcePlugins(const QString &libDir)
+ {
+ Q_UNUSED(libDir);
};
QHash<QString, QPointer<MfFeedbackHandle> > feedbackCache()
--- tests/ut_mffeedback/mfmanager_mock.cpp
+++ tests/ut_mffeedback/mfmanager_mock.cpp
@@ -70,6 +70,8 @@
backendInstance = new MfBackendFoo();
backendList.append(qobject_cast<MfBackendInterface*>(backendInstance));
+ nonThreadedBackendCount = 1;
+
backendInstance = new MfBackendFoo();
backendList.append(qobject_cast<MfBackendInterface*>(backendInstance));
--- tests/ut_mffeedback/mfmanager_mock.h
+++ tests/ut_mffeedback/mfmanager_mock.h
@@ -61,6 +61,7 @@
void loadTheme(const QString& themeName);
public:
+ int nonThreadedBackendCount;
QList<MfBackendInterface*> backendList;
QList<MfSourceInterface*> sourceList;
--- tests/ut_mffeedback/ut_mffeedback.cpp
+++ tests/ut_mffeedback/ut_mffeedback.cpp
@@ -70,7 +70,8 @@
QCOMPARE(feedback->name().isEmpty(), true);
// Play should succeed even in this case
- feedback->play();
+ feedback->emitPlay(-1);
+ QCoreApplication::processEvents();
// Nothing should have been actually played
QCOMPARE(MfFeedbackHandle::playedPaths.size(), 0);
@@ -114,7 +115,8 @@
QCOMPARE(feedback->name(), QString("foo"));
// Play should succeed even in this case
- feedback->play();
+ feedback->emitPlay(-1);
+ QCoreApplication::processEvents();
// Nothing should have been actually played
QCOMPARE(MfFeedbackHandle::playedPaths.size(), 0);
@@ -146,7 +148,8 @@
// Name should be the last part of first path
QCOMPARE(feedback->name(), QString("foo"));
- feedback->play();
+ feedback->emitPlay(-1);
+ QCoreApplication::processEvents();
// Played paths should contain 2 paths
QCOMPARE(MfFeedbackHandle::playedPaths.size(), 2);
@@ -184,7 +187,8 @@
// Name should be the last part of first path
QCOMPARE(feedback->name(), QString("foo"));
- feedback->play();
+ feedback->emitPlay(-1);
+ QCoreApplication::processEvents();
// Played paths should contain 0 paths
QCOMPARE(MfFeedbackHandle::playedPaths.size(), 0);
@@ -219,7 +223,8 @@
// Name should be the last part of first path
QCOMPARE(feedback->name(), QString("foo"));
- feedback->play();
+ feedback->emitPlay(-1);
+ QCoreApplication::processEvents();
// Cached handle should have been played twice
QCOMPARE(MfFeedbackHandle::playedPaths.size(), 2);
@@ -266,7 +271,8 @@
QCOMPARE(testHandles[i].isNull(), false);
}
- feedback->play();
+ feedback->emitPlay(-1);
+ QCoreApplication::processEvents();
// Load second set
feedback->load(dirList2);
@@ -276,7 +282,8 @@
QCOMPARE(testHandles[i].isNull(), false);
}
- feedback->play();
+ feedback->emitPlay(-1);
+ QCoreApplication::processEvents();
// Played paths should contain 3 paths
QCOMPARE(MfFeedbackHandle::playedPaths.size(), 3);
--- tests/ut_mffeedback/ut_mffeedback.pro
+++ tests/ut_mffeedback/ut_mffeedback.pro
@@ -2,7 +2,7 @@
TARGET = ut_mffeedback
-COPY_TESTED_SOURCES = $$FMSRCDIR/lib/mffeedback.cpp
+COPY_TESTED_SOURCES = $$FMSRCDIR/lib/mffeedback.cpp $$FMSRCDIR/lib/mfconfig.cpp
copysourcefiles.input = COPY_TESTED_SOURCES
copysourcefiles.output = ${QMAKE_FILE_BASE}.cpp
copysourcefiles.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_BASE}.cpp
--- tests/ut_mfmanager/globals.cpp
+++ tests/ut_mfmanager/globals.cpp
@@ -16,6 +16,11 @@
#include "globals.h"
+QList< QPointer<MfBackendFoo> > g_threadedBackendFooInstances;
+QList< QPointer<MfBackendFoo> > g_nonThreadedBackendFooInstances;
QList< QPointer<MfSourceFoo> > g_sourceFooInstances;
-QList< QPointer<MfBackendFoo> > g_backendFooInstances;
-QStringList g_directoryEntryList;
+QStringList g_threadedBackendsDirectoryEntryList;
+QStringList g_nonThreadedBackendsDirectoryEntryList;
+QStringList g_sourcesDirectoryEntryList;
+QStringList g_loadedInstances;
+
--- tests/ut_mfmanager/globals.h
+++ tests/ut_mfmanager/globals.h
@@ -24,9 +24,15 @@
#include "mfsourcefoo.h"
#include "mfbackendfoo.h"
+extern QList< QPointer<MfBackendFoo> > g_threadedBackendFooInstances;
+extern QList< QPointer<MfBackendFoo> > g_nonThreadedBackendFooInstances;
extern QList< QPointer<MfSourceFoo> > g_sourceFooInstances;
-extern QList< QPointer<MfBackendFoo> > g_backendFooInstances;
-// What files are present in meegofeedbackd's lib dir
-extern QStringList g_directoryEntryList;
+// What files are present in meegofeedbackd's lib dirs
+extern QStringList g_threadedBackendsDirectoryEntryList;
+extern QStringList g_nonThreadedBackendsDirectoryEntryList;
+extern QStringList g_sourcesDirectoryEntryList;
+
+// Used by mocked QPluginLoader to keep track of loaded instances
+extern QStringList g_loadedInstances;
#endif
--- tests/ut_mfmanager/mfbackendfoo.cpp
+++ tests/ut_mfmanager/mfbackendfoo.cpp
@@ -18,7 +18,11 @@
MfBackendFoo::MfBackendFoo() : limit(0)
{
- initCalled = false;
+ initCalled = 0;
+}
+
+MfBackendFoo::~MfBackendFoo()
+{
}
QString MfBackendFoo::name() const
@@ -28,7 +32,7 @@
bool MfBackendFoo::init(int lengthLimit)
{
- initCalled = true;
+ initCalled++;;
limit = lengthLimit;
return true;
--- tests/ut_mfmanager/mfbackendfoo.h
+++ tests/ut_mfmanager/mfbackendfoo.h
@@ -27,6 +27,7 @@
public:
MfBackendFoo();
+ ~MfBackendFoo();
// Implementation of MfBackendInterface methods
QString name() const;
@@ -37,7 +38,7 @@
void play(void *feedbackHandle);
bool isReady();
- bool initCalled;
+ int initCalled;
int limit;
};
--- tests/ut_mfmanager/mfsourcefoo.cpp
+++ tests/ut_mfmanager/mfsourcefoo.cpp
@@ -15,15 +15,20 @@
*/
#include "mfsourcefoo.h"
+#include <QDebug>
MfSourceFoo::MfSourceFoo(QObject *parent)
: QObject(parent)
{
- initCalled = false;
+ initCalled = 0;
+}
+
+MfSourceFoo::~MfSourceFoo()
+{
}
bool MfSourceFoo::init()
{
- initCalled = true;
+ initCalled++;
return true;
}
--- tests/ut_mfmanager/mfsourcefoo.h
+++ tests/ut_mfmanager/mfsourcefoo.h
@@ -26,9 +26,11 @@
public:
MfSourceFoo(QObject *parent = 0);
+ ~MfSourceFoo();
+
bool init();
- bool initCalled;
+ int initCalled;
};
#endif
--- tests/ut_mfmanager/qdir_mock.cpp
+++ tests/ut_mfmanager/qdir_mock.cpp
@@ -15,12 +15,15 @@
*/
#include <QDir>
+#include <QString>
#include "globals.h"
+static QString g_path;
+
void QDir::setPath(const QString &path)
{
- Q_UNUSED(path);
+ g_path = path;
}
bool QDir::exists() const
@@ -33,10 +36,18 @@
Q_UNUSED(filters);
Q_UNUSED(sort);
- return g_directoryEntryList;
+ if (g_path == "/usr/lib/meegofeedbackd/threaded-backends") {
+ return g_threadedBackendsDirectoryEntryList;
+ } else if (g_path == "/usr/lib/meegofeedbackd/non-threaded-backends") {
+ return g_nonThreadedBackendsDirectoryEntryList;
+ } else if (g_path == "/usr/lib/meegofeedbackd/sources") {
+ return g_sourcesDirectoryEntryList;
+ } else {
+ return QStringList();
+ }
}
QString QDir::filePath(const QString &fileName) const
{
- return "/usr/lib/meegofeedbackd/" + fileName;
+ return g_path + "/" + fileName;
}
--- tests/ut_mfmanager/qpluginloader_mock.cpp
+++ tests/ut_mfmanager/qpluginloader_mock.cpp
@@ -23,18 +23,23 @@
QPluginLoader::QPluginLoader(QObject *parent)
: QObject(parent)
{
+ m_instance = NULL;
m_isLoaded = false;
}
QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent)
: QObject(parent)
{
+ m_instance = NULL;
m_fileName = fileName;
m_isLoaded = false;
}
QPluginLoader::~QPluginLoader()
{
+ if (m_isLoaded) {
+ unload();
+ }
}
QObject *QPluginLoader::instance()
@@ -55,12 +60,38 @@
{
bool ok = true;
- if (m_fileName == "/usr/lib/meegofeedbackd/libmeegofeedback-befoo.so") {
- m_instance = new MfBackendFoo();
- g_backendFooInstances.append((MfBackendFoo*)m_instance);
- } else if (m_fileName == "/usr/lib/meegofeedbackd/libmeegofeedback-srcfoo.so") {
- m_instance = new MfSourceFoo();
+ if (m_fileName == "/usr/lib/meegofeedbackd/threaded-backends/libmeegofeedback-befoo1.so" ||
+ m_fileName == "/usr/lib/meegofeedbackd/threaded-backends/libmeegofeedback-befoo2.so") {
+ if (!g_loadedInstances.contains(m_fileName)) {
+ // First creation of this backend
+ m_instance = new MfBackendFoo();
+ } else {
+ // This backend has been instanciated before
+ m_instance = g_threadedBackendFooInstances[0];
+ }
+ g_threadedBackendFooInstances.append((MfBackendFoo*)m_instance);
+ g_loadedInstances.append(m_fileName);
+ } else if (m_fileName == "/usr/lib/meegofeedbackd/non-threaded-backends/libmeegofeedback-befoo1.so" ||
+ m_fileName == "/usr/lib/meegofeedbackd/non-threaded-backends/libmeegofeedback-befoo2.so") {
+ if (!g_loadedInstances.contains(m_fileName)) {
+ // First creation of this backend
+ m_instance = new MfBackendFoo();
+ } else {
+ // This backend has been instanciated before
+ m_instance = g_nonThreadedBackendFooInstances[0];
+ }
+ g_nonThreadedBackendFooInstances.append((MfBackendFoo*)m_instance);
+ g_loadedInstances.append(m_fileName);
+ } else if (m_fileName == "/usr/lib/meegofeedbackd/sources/libmeegofeedback-srcfoo.so") {
+ if (!g_loadedInstances.contains(m_fileName)) {
+ // First creation of this backend
+ m_instance = new MfSourceFoo();
+ } else {
+ // This backend has been instanciated before
+ m_instance = g_sourceFooInstances[0];
+ }
g_sourceFooInstances.append((MfSourceFoo*)m_instance);
+ g_loadedInstances.append(m_fileName);
} else {
ok = false;
}
@@ -72,7 +103,14 @@
{
if (m_instance)
{
- delete m_instance;
+ // g_loadedInstances is used as a reference count of created instances.
+ // Instance will be removed only when it is the last existing instance.
+ if (g_loadedInstances.count(m_fileName) <= 1) {
+ delete m_instance;
+ }
+ if (g_loadedInstances.contains(m_fileName)) {
+ g_loadedInstances.removeAt(g_loadedInstances.indexOf(m_fileName));
+ }
m_instance = 0;
m_isLoaded = false;
}
--- tests/ut_mfmanager/ut_mfmanager.cpp
+++ tests/ut_mfmanager/ut_mfmanager.cpp
@@ -33,9 +33,13 @@
void Ut_MfManager::cleanup()
{
+ g_threadedBackendFooInstances.clear();
+ g_nonThreadedBackendFooInstances.clear();
g_sourceFooInstances.clear();
- g_backendFooInstances.clear();
- g_directoryEntryList.clear();
+ g_threadedBackendsDirectoryEntryList.clear();
+ g_nonThreadedBackendsDirectoryEntryList.clear();
+ g_sourcesDirectoryEntryList.clear();
+ g_loadedInstances.clear();
}
void Ut_MfManager::initNoSourcesOneBackend()
@@ -45,8 +49,8 @@
QMap<QString, MfBackendInterface::playbackVolume> emptyMap;
bool ok;
- // There's only one backend there and nothing more.
- g_directoryEntryList << "libmeegofeedback-befoo.so";
+ // There's only one non-threaded backend there and nothing more.
+ g_nonThreadedBackendsDirectoryEntryList << "libmeegofeedback-befoo1.so";
// Initialization should not fail if there is backend
// but no source. Sources are optional.
@@ -55,18 +59,19 @@
QVERIFY(ok);
// Get the loaded backend
- QCOMPARE(g_backendFooInstances.size(), 1);
- fooBackend = g_backendFooInstances.at(0);
+ QCOMPARE(g_nonThreadedBackendFooInstances.size(), 1);
+ fooBackend = g_nonThreadedBackendFooInstances.at(0);
- // Run a small event loop to process the backend initialization because
- // it uses queued connection.
- QTimer::singleShot(50, QCoreApplication::instance(), SLOT(quit()));
- QCoreApplication::instance()->exec();
+ // Wait a while to get backend initialised. Backend initalization
+ // uses queued signals/slots so this gives some time to process
+ // those events.
+ QTest::qWait(50);
// Check that MfBackendFoo was properly initialized
- QVERIFY(fooBackend->initCalled);
+ QCOMPARE(fooBackend->initCalled, 1);
- // No sources loaded, naturally
+ // Make sure nothing extra was created
+ QCOMPARE(g_threadedBackendFooInstances.size(), 0);
QCOMPARE(g_sourceFooInstances.size(), 0);
delete manager;
@@ -84,7 +89,8 @@
// It can't init if there's no backend library available.
QCOMPARE(ok, false);
- QCOMPARE(g_backendFooInstances.size(), 0);
+ QCOMPARE(g_threadedBackendFooInstances.size(), 0);
+ QCOMPARE(g_nonThreadedBackendFooInstances.size(), 0);
QCOMPARE(g_sourceFooInstances.size(), 0);
delete manager;
@@ -99,24 +105,22 @@
bool ok;
// Put one source library and one backend library there
- g_directoryEntryList << "libmeegofeedback-befoo.so";
- g_directoryEntryList << "libmeegofeedback-srcfoo.so";
+ g_threadedBackendsDirectoryEntryList << "libmeegofeedback-befoo1.so";
+ g_sourcesDirectoryEntryList << "libmeegofeedback-srcfoo.so";
manager = new MfManager();
ok = manager->init(MeegoDefaultTheme, emptyMap);
QVERIFY(ok);
// Get the loaded backend
- QCOMPARE(g_backendFooInstances.size(), 1);
- fooBackend = g_backendFooInstances.at(0);
+ QCOMPARE(g_threadedBackendFooInstances.size(), 1);
+ fooBackend = g_threadedBackendFooInstances.at(0);
- // Run a small event loop to process the backend initialization because
- // it uses queued connection.
- QTimer::singleShot(50, QCoreApplication::instance(), SLOT(quit()));
- QCoreApplication::instance()->exec();
+ // Wait a while to get backend initialised
+ QTest::qWait(50);
// Check that MfBackendFoo was properly initialized
- QVERIFY(fooBackend->initCalled);
+ QCOMPARE(fooBackend->initCalled, 1);
QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
// Get the loaded source
@@ -124,7 +128,199 @@
fooSource = g_sourceFooInstances.at(0);
// Check that MfSourceFoo was properly initialized
- QVERIFY(fooSource->initCalled);
+ QCOMPARE(fooSource->initCalled, 1);
+
+ // Make sure nothing extra was created
+ QCOMPARE(g_nonThreadedBackendFooInstances.size(), 0);
+
+ delete manager;
+}
+
+void Ut_MfManager::initOneSourceTwoBackends()
+{
+ MfManager *manager;
+ MfBackendFoo *fooBackend = 0;
+ MfSourceFoo *fooSource = 0;
+ QMap<QString, MfBackendInterface::playbackVolume> emptyMap;
+ bool ok;
+
+ // Put one source library and one backend library there
+ g_threadedBackendsDirectoryEntryList << "libmeegofeedback-befoo1.so";
+ g_nonThreadedBackendsDirectoryEntryList << "libmeegofeedback-befoo1.so";
+ g_sourcesDirectoryEntryList << "libmeegofeedback-srcfoo.so";
+
+ manager = new MfManager();
+ ok = manager->init(MeegoDefaultTheme, emptyMap);
+ QVERIFY(ok);
+
+ // Wait a while to get backend initialised
+ QTest::qWait(50);
+
+ // Get the loaded backend
+ QCOMPARE(g_threadedBackendFooInstances.size(), 1);
+ fooBackend = g_threadedBackendFooInstances.at(0);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // Get the loaded backend
+ QCOMPARE(g_nonThreadedBackendFooInstances.size(), 1);
+ fooBackend = g_nonThreadedBackendFooInstances.at(0);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // Get the loaded source
+ QCOMPARE(g_sourceFooInstances.size(), 1);
+ fooSource = g_sourceFooInstances.at(0);
+
+ // Check that MfSourceFoo was properly initialized
+ QCOMPARE(fooSource->initCalled, 1);
+
+ delete manager;
+}
+
+void Ut_MfManager::initFourBackends()
+{
+ MfManager *manager;
+ MfBackendFoo *fooBackend = 0;
+ QMap<QString, MfBackendInterface::playbackVolume> emptyMap;
+ bool ok;
+
+ // Put one source library and one backend library there
+ g_threadedBackendsDirectoryEntryList << "libmeegofeedback-befoo1.so" << "libmeegofeedback-befoo2.so";
+ g_nonThreadedBackendsDirectoryEntryList << "libmeegofeedback-befoo1.so" << "libmeegofeedback-befoo2.so";
+
+ manager = new MfManager();
+ ok = manager->init(MeegoDefaultTheme, emptyMap);
+ QVERIFY(ok);
+
+ // Wait a while to get backend initialised
+ QTest::qWait(50);
+
+ // Get the loaded backend #1
+ QCOMPARE(g_threadedBackendFooInstances.size(), 2);
+ fooBackend = g_threadedBackendFooInstances.at(0);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // Get the loaded backend #2
+ fooBackend = g_threadedBackendFooInstances.at(1);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // Get the loaded backend #3
+ QCOMPARE(g_nonThreadedBackendFooInstances.size(), 2);
+ fooBackend = g_nonThreadedBackendFooInstances.at(0);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // Get the loaded backend #4
+ fooBackend = g_nonThreadedBackendFooInstances.at(1);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // Make sure nothing extra was created
+ QCOMPARE(g_sourceFooInstances.size(), 0);
+
+ delete manager;
+}
+
+void Ut_MfManager::initTwoBackendsTwice()
+{
+ MfManager *manager;
+ MfBackendFoo *fooBackend = 0;
+ QMap<QString, MfBackendInterface::playbackVolume> emptyMap;
+ bool ok;
+
+ // Put one source library and one backend library there
+ g_threadedBackendsDirectoryEntryList << "libmeegofeedback-befoo1.so" << "libmeegofeedback-befoo1.so";
+ g_nonThreadedBackendsDirectoryEntryList << "libmeegofeedback-befoo2.so" << "libmeegofeedback-befoo2.so";
+
+ manager = new MfManager();
+ ok = manager->init(MeegoDefaultTheme, emptyMap);
+ QVERIFY(ok);
+
+ // Wait a while to get backend initialised
+ QTest::qWait(50);
+
+ // The two backend instances should be the same and
+ // the init method should be called only once.
+ QCOMPARE(g_threadedBackendFooInstances.size(), 2);
+ QCOMPARE(g_threadedBackendFooInstances.at(0),
+ g_threadedBackendFooInstances.at(1));
+ fooBackend = g_threadedBackendFooInstances.at(0);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // The two backend instances should be the same and
+ // the init method should be called only once.
+ QCOMPARE(g_nonThreadedBackendFooInstances.size(), 2);
+ QCOMPARE(g_nonThreadedBackendFooInstances.at(0),
+ g_nonThreadedBackendFooInstances.at(1));
+ fooBackend = g_nonThreadedBackendFooInstances.at(0);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // Make sure nothing extra was created
+ QCOMPARE(g_sourceFooInstances.size(), 0);
+
+ delete manager;
+}
+
+void Ut_MfManager::initTwoSourcesTwice()
+{
+ MfManager *manager;
+ MfSourceFoo *fooSource = 0;
+ MfBackendFoo *fooBackend = 0;
+ QMap<QString, MfBackendInterface::playbackVolume> emptyMap;
+ bool ok;
+
+ // Put one source library and one backend library there
+ g_threadedBackendsDirectoryEntryList << "libmeegofeedback-befoo1.so";
+ g_sourcesDirectoryEntryList << "libmeegofeedback-srcfoo.so" << "libmeegofeedback-srcfoo.so";
+
+ manager = new MfManager();
+ ok = manager->init(MeegoDefaultTheme, emptyMap);
+ QVERIFY(ok);
+
+ // Wait a while to get backend initialised
+ QTest::qWait(50);
+
+ // Get the loaded backend
+ QCOMPARE(g_threadedBackendFooInstances.size(), 1);
+ fooBackend = g_threadedBackendFooInstances.at(0);
+
+ // Check that MfBackendFoo was properly initialized
+ QCOMPARE(fooBackend->initCalled, 1);
+ QVERIFY(fooBackend->limit == MfConfig::feedbackLengthLimit());
+
+ // The two source instances should be the same and
+ // the init method should be called only once.
+ QCOMPARE(g_sourceFooInstances.size(), 2);
+ QCOMPARE(g_sourceFooInstances.at(0),
+ g_sourceFooInstances.at(1));
+ fooSource = g_sourceFooInstances.at(0);
+
+ // Check that MfSourceFoo was properly initialized
+ QCOMPARE(fooSource->initCalled, 1);
+
+ // Make sure nothing extra was created
+ QCOMPARE(g_nonThreadedBackendsDirectoryEntryList.size(), 0);
delete manager;
}
--- tests/ut_mfmanager/ut_mfmanager.h
+++ tests/ut_mfmanager/ut_mfmanager.h
@@ -33,6 +33,10 @@
void initNoSourcesOneBackend();
void initNoSourcesNoBackend();
void initOneSourceOneBackend();
+ void initOneSourceTwoBackends();
+ void initFourBackends();
+ void initTwoBackendsTwice();
+ void initTwoSourcesTwice();
};
#endif
More information about the MeeGo-commits
mailing list