diff options
author | Jonas Rabbe <jonas.rabbe@nokia.com> | 2012-03-14 13:02:32 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-20 23:39:45 +0100 |
commit | a8ba6e3c7f181e387eb53b122d58c433b5784319 (patch) | |
tree | 8a090349fa2698f879085380e6daa625ad979bdf /src/multimedia/qmediapluginloader.cpp | |
parent | 61c09d1614c560de9514ac0fd3344bf0280fca33 (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.cpp | 196 |
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); } } } |