summaryrefslogtreecommitdiffstats
path: root/src/multimedia/qmediapluginloader.cpp
diff options
context:
space:
mode:
authorJonas Rabbe <jonas.rabbe@nokia.com>2012-03-14 13:02:32 +1000
committerQt by Nokia <qt-info@nokia.com>2012-03-20 23:39:45 +0100
commita8ba6e3c7f181e387eb53b122d58c433b5784319 (patch)
tree8a090349fa2698f879085380e6daa625ad979bdf /src/multimedia/qmediapluginloader.cpp
parent61c09d1614c560de9514ac0fd3344bf0280fca33 (diff)
Updated plugins to use new plugin architecture
Changed QMediaPluginLoader to use QFactoryLoader instead of QPluginLoader and used metadata to get keys. Removed QAudioPluginLoader and changed audio classes to use instead use QMediaPluginLoader. The plugins must include the Q_PLUGIN_METADATA macro, and no longer use the Q_PLUGIN_EXPORT/Q_PLUGIN_EXPORT2 macros. A json file has been added for each plugin which can contain metadata which is available to the plugin loader before the plugin is actually loaded, and is used to read the keys for the plugin, e.g. supported services. QFactoryInterface will be deprecated and has been removed from all plugins. Change-Id: I035b82f9c9c65717bebf704d560ea8f891df21da Reviewed-by: Michael Goddard <michael.goddard@nokia.com> Reviewed-by: Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>
Diffstat (limited to 'src/multimedia/qmediapluginloader.cpp')
-rw-r--r--src/multimedia/qmediapluginloader.cpp196
1 files changed, 55 insertions, 141 deletions
diff --git a/src/multimedia/qmediapluginloader.cpp b/src/multimedia/qmediapluginloader.cpp
index 2fc8aba62..42787fdd2 100644
--- a/src/multimedia/qmediapluginloader.cpp
+++ b/src/multimedia/qmediapluginloader.cpp
@@ -41,191 +41,105 @@
#include "qmediapluginloader_p.h"
#include <QtCore/qcoreapplication.h>
-#include <QtCore/qpluginloader.h>
-#include <QtCore/qdir.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qjsonarray.h>
+#include <private/qfactoryloader_p.h>
#include "qmediaserviceproviderplugin.h"
-#if defined(Q_OS_MAC)
-# include <CoreFoundation/CoreFoundation.h>
-#endif
-
QT_BEGIN_NAMESPACE
-typedef QMap<QString,QObjectList> ObjectListMap;
-Q_GLOBAL_STATIC(ObjectListMap, staticMediaPlugins);
-
-
-QMediaPluginLoader::QMediaPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity):
+QMediaPluginLoader::QMediaPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity caseSensitivity):
m_iid(iid)
{
m_location = QString::fromLatin1("/%1").arg(location);
- load();
+ m_factoryLoader = new QFactoryLoader(m_iid, m_location, caseSensitivity);
+ loadMetadata();
}
-QStringList QMediaPluginLoader::keys() const
+QMediaPluginLoader::~QMediaPluginLoader()
{
- return m_instances.keys();
+ delete m_factoryLoader;
}
-QObject* QMediaPluginLoader::instance(QString const &key)
+QStringList QMediaPluginLoader::keys() const
{
- return m_instances.value(key).value(0);
+ return m_metadata.keys();
}
-QList<QObject*> QMediaPluginLoader::instances(QString const &key)
+QObject* QMediaPluginLoader::instance(QString const &key)
{
- return m_instances.value(key);
-}
+ if (!m_metadata.contains(key))
+ return 0;
-//to be used for testing purposes only
-void QMediaPluginLoader::setStaticPlugins(const QString &location, const QObjectList& objects)
-{
- staticMediaPlugins()->insert(QString::fromLatin1("/%1").arg(location), objects);
+ int idx = m_metadata.value(key).first().value(QStringLiteral("index")).toDouble();
+ if (idx < 0)
+ return 0;
+
+ return m_factoryLoader->instance(idx);
}
-QStringList QMediaPluginLoader::availablePlugins() const
+QList<QObject*> QMediaPluginLoader::instances(QString const &key)
{
- QStringList paths;
- QStringList plugins;
-
-#if defined(Q_OS_MAC)
- QString imageSuffix(qgetenv("DYLD_IMAGE_SUFFIX"));
-
- // Bundle plugin directory
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- if (mainBundle != 0) {
- CFURLRef baseUrl = CFBundleCopyBundleURL(mainBundle);
- CFURLRef pluginUrlPart = CFBundleCopyBuiltInPlugInsURL(mainBundle);
- CFStringRef pluginPathPart = CFURLCopyFileSystemPath(pluginUrlPart, kCFURLPOSIXPathStyle);
- CFURLRef pluginUrl = CFURLCreateCopyAppendingPathComponent(0, baseUrl, pluginPathPart, true);
- CFStringRef pluginPath = CFURLCopyFileSystemPath(pluginUrl, kCFURLPOSIXPathStyle);
-
- CFIndex length = CFStringGetLength(pluginPath);
- UniChar buffer[length];
- CFStringGetCharacters(pluginPath, CFRangeMake(0, length), buffer);
-
- paths << QString(reinterpret_cast<const QChar *>(buffer), length);
-
- CFRelease(pluginPath);
- CFRelease(pluginUrl);
- CFRelease(pluginPathPart);
- CFRelease(pluginUrlPart);
- CFRelease(baseUrl);
- }
-#endif
-
- // Qt paths
- paths << QCoreApplication::libraryPaths();
-
- foreach (const QString &path, paths) {
- QDir typeDir(path + m_location);
- foreach (const QString &file, typeDir.entryList(QDir::Files, QDir::Name)) {
-#if defined(Q_OS_MAC)
- if (!imageSuffix.isEmpty()) { // Only add appropriate images
- if (file.lastIndexOf(imageSuffix, -6) == -1)
- continue;
- } else {
- int foundSuffix = file.lastIndexOf(QLatin1String("_debug.dylib"));
- if (foundSuffix == -1) {
- foundSuffix = file.lastIndexOf(QLatin1String("_profile.dylib"));
- }
- if (foundSuffix != -1) {
- /*
- If this is a "special" version of the plugin, prefer the release
- version, where available.
- Avoids warnings like:
-
- objc[23101]: Class TransparentQTMovieView is implemented in both
- libqqt7engine_debug.dylib and libqqt7engine.dylib. One of the two
- will be used. Which one is undefined.
-
- Note, this code relies on QDir::Name sorting!
- */
-
- QString preferred =
- typeDir.absoluteFilePath(file.left(foundSuffix) + QLatin1String(".dylib"));
-
- if (plugins.contains(preferred)) {
- continue;
- }
- }
- }
-#elif defined(Q_OS_UNIX)
- // Ignore separate debug files
- if (file.endsWith(QLatin1String(".debug")))
- continue;
-#elif defined(Q_OS_WIN)
- // Ignore non-dlls
- if (!file.endsWith(QLatin1String(".dll"), Qt::CaseInsensitive))
- continue;
-#endif
- plugins << typeDir.absoluteFilePath(file);
+ if (!m_metadata.contains(key))
+ return QList<QObject*>();
+
+ QList<QObject *> objects;
+ foreach (QJsonObject jsonobj, m_metadata.value(key)) {
+ int idx = jsonobj.value(QStringLiteral("index")).toDouble();
+ if (idx < 0)
+ continue;
+
+ QObject *object = m_factoryLoader->instance(idx);
+ if (!objects.contains(object)) {
+ objects.append(object);
}
}
- return plugins;
+ return objects;
}
-void QMediaPluginLoader::load()
+void QMediaPluginLoader::loadMetadata()
{
- if (!m_instances.isEmpty())
- return;
-
#if !defined QT_NO_DEBUG
const bool showDebug = qgetenv("QT_DEBUG_PLUGINS").toInt() > 0;
#endif
- if (staticMediaPlugins() && staticMediaPlugins()->contains(m_location)) {
- foreach(QObject *o, staticMediaPlugins()->value(m_location)) {
- if (o != 0 && o->qt_metacast(m_iid) != 0) {
- QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
- if (p != 0) {
- foreach (QString const &key, p->keys())
- m_instances[key].append(o);
- }
- }
- }
- } else {
- QSet<QString> loadedPlugins;
-
- foreach (const QString &plugin, availablePlugins()) {
- QString fileName = QFileInfo(plugin).fileName();
- //don't try to load plugin with the same name if it's already loaded
- if (loadedPlugins.contains(fileName)) {
#if !defined QT_NO_DEBUG
- if (showDebug)
- qDebug() << "Skip loading plugin" << plugin;
+ if (showDebug)
+ qDebug() << "QMediaPluginLoader: loading metadata for iid " << m_iid << " at location " << m_location;
#endif
- continue;
- }
-
- QPluginLoader loader(plugin);
- QObject *o = loader.instance();
- if (o != 0 && o->qt_metacast(m_iid) != 0) {
- QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
- if (p != 0) {
- foreach (const QString &key, p->keys())
- m_instances[key].append(o);
+ if (!m_metadata.isEmpty()) {
+#if !defined QT_NO_DEBUG
+ if (showDebug)
+ qDebug() << "QMediaPluginLoader: already loaded metadata, returning";
+#endif
+ return;
+ }
- loadedPlugins.insert(fileName);
+ QList<QJsonObject> meta = m_factoryLoader->metaData();
+ for (int i = 0; i < meta.size(); i++) {
+ QJsonObject jsonobj = meta.at(i).value(QStringLiteral("MetaData")).toObject();
+ jsonobj.insert(QStringLiteral("index"), i);
#if !defined QT_NO_DEBUG
- if (showDebug)
- qDebug() << "Loaded plugin" << plugin << "services:" << p->keys();
+ if (showDebug)
+ qDebug() << "QMediaPluginLoader: Inserted index " << i << " into metadata: " << jsonobj;
#endif
- }
- continue;
- } else {
+ QJsonArray arr = jsonobj.value(QStringLiteral("Keys")).toArray();
+ foreach (QJsonValue value, arr) {
+ QString key = value.toString();
+
+ if (!m_metadata.contains(key)) {
#if !defined QT_NO_DEBUG
if (showDebug)
- qWarning() << "QMediaPluginLoader: Failed to load plugin: " << plugin << loader.errorString();
+ qDebug() << "QMediaPluginLoader: Inserting new list for key: " << key;
#endif
+ m_metadata.insert(key, QList<QJsonObject>());
}
- loader.unload();
+ m_metadata[key].append(jsonobj);
}
}
}