diff options
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); } } } |