src/multimedia/qmediapluginloader.cpp
changeset 5 603d3f8b6302
parent 0 876b1a06bc25
equal deleted inserted replaced
3:e4ebb16b39ea 5:603d3f8b6302
    44 #include <QtCore/qpluginloader.h>
    44 #include <QtCore/qpluginloader.h>
    45 #include <QtCore/qdir.h>
    45 #include <QtCore/qdir.h>
    46 #include <QtCore/qdebug.h>
    46 #include <QtCore/qdebug.h>
    47 
    47 
    48 #include "qmediaserviceproviderplugin.h"
    48 #include "qmediaserviceproviderplugin.h"
    49 #include "qmobilitypluginsearch.h"
    49 
       
    50 #if defined(Q_OS_SYMBIAN)
       
    51 # include <f32file.h>
       
    52 #endif
       
    53 
       
    54 #if defined(Q_OS_MAC)
       
    55 # include <CoreFoundation/CoreFoundation.h>
       
    56 #endif
    50 
    57 
    51 QT_BEGIN_NAMESPACE
    58 QT_BEGIN_NAMESPACE
    52 
    59 
    53 typedef QMap<QString,QObjectList> ObjectListMap;
    60 typedef QMap<QString,QObjectList> ObjectListMap;
    54 Q_GLOBAL_STATIC(ObjectListMap, staticMediaPlugins);
    61 Q_GLOBAL_STATIC(ObjectListMap, staticMediaPlugins);
    55 
    62 
       
    63 
       
    64 #if defined(Q_OS_SYMBIAN)
       
    65 // XXX: Copied over from Mobility, hopefully to be removed at some point
       
    66 class DirChecker
       
    67 {
       
    68 public:
       
    69     DirChecker();
       
    70     ~DirChecker();
       
    71     bool checkDir(const QDir& dir);
       
    72 
       
    73 private:
       
    74     RFs rfs;
       
    75 };
       
    76 
       
    77 DirChecker::DirChecker()
       
    78 {
       
    79     qt_symbian_throwIfError(rfs.Connect());
       
    80 }
       
    81 
       
    82 bool DirChecker::checkDir(const QDir& dir)
       
    83 {
       
    84     bool pathFound = false;
       
    85     // In Symbian, going cdUp() in a c:/private/<uid3>/ will result in *platsec* error at fileserver (requires AllFiles capability)
       
    86     // Also, trying to cd() to a nonexistent directory causes *platsec* error. This does not cause functional harm, but should
       
    87     // nevertheless be changed to use native Symbian methods to avoid unnecessary platsec warnings (as per qpluginloader.cpp).
       
    88     // Use native Symbian code to check for directory existence, because checking
       
    89     // for files from under non-existent protected dir like E:/private/<uid> using
       
    90     // QDir::exists causes platform security violations on most apps.
       
    91     QString nativePath = QDir::toNativeSeparators(dir.absolutePath());
       
    92     TPtrC ptr = TPtrC16(static_cast<const TUint16*>(nativePath.utf16()), nativePath.length());
       
    93     TUint attributes;
       
    94     TInt err = rfs.Att(ptr, attributes);
       
    95     if (err == KErrNone) {
       
    96         // yes, the directory exists.
       
    97         pathFound = true;
       
    98     }
       
    99     return pathFound;
       
   100 }
       
   101 
       
   102 DirChecker::~DirChecker()
       
   103 {
       
   104     rfs.Close();
       
   105 }
       
   106 #endif
       
   107 
       
   108 
    56 QMediaPluginLoader::QMediaPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity):
   109 QMediaPluginLoader::QMediaPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity):
    57     m_iid(iid)
   110     m_iid(iid)
    58 {
   111 {
    59     m_location = location + "/";
   112     m_location = QString::fromLatin1("/%1").arg(location);
    60     load();
   113     load();
    61 }
   114 }
    62 
   115 
    63 QStringList QMediaPluginLoader::keys() const
   116 QStringList QMediaPluginLoader::keys() const
    64 {
   117 {
    76 }
   129 }
    77 
   130 
    78 //to be used for testing purposes only
   131 //to be used for testing purposes only
    79 void QMediaPluginLoader::setStaticPlugins(const QString &location, const QObjectList& objects)
   132 void QMediaPluginLoader::setStaticPlugins(const QString &location, const QObjectList& objects)
    80 {
   133 {
    81     staticMediaPlugins()->insert(location+"/", objects);
   134     staticMediaPlugins()->insert(QString::fromLatin1("/%1").arg(location), objects);
       
   135 }
       
   136 
       
   137 QStringList QMediaPluginLoader::availablePlugins() const
       
   138 {
       
   139     QStringList paths;
       
   140     QStringList plugins;
       
   141 
       
   142 #if defined(Q_OS_SYMBIAN)
       
   143     DirChecker dirChecker;
       
   144 #endif
       
   145 
       
   146 #if defined(Q_OS_MAC)
       
   147     QString imageSuffix(qgetenv("DYLD_IMAGE_SUFFIX"));
       
   148 
       
   149     // Bundle plugin directory
       
   150     CFBundleRef mainBundle = CFBundleGetMainBundle();
       
   151     if (mainBundle != 0) {
       
   152         CFURLRef baseUrl = CFBundleCopyBundleURL(mainBundle);
       
   153         CFURLRef pluginUrlPart = CFBundleCopyBuiltInPlugInsURL(mainBundle);
       
   154         CFStringRef pluginPathPart = CFURLCopyFileSystemPath(pluginUrlPart, kCFURLPOSIXPathStyle);
       
   155         CFURLRef pluginUrl = CFURLCreateCopyAppendingPathComponent(0, baseUrl, pluginPathPart, true);
       
   156         CFStringRef pluginPath = CFURLCopyFileSystemPath(pluginUrl, kCFURLPOSIXPathStyle);
       
   157 
       
   158         CFIndex length = CFStringGetLength(pluginPath);
       
   159         UniChar buffer[length];
       
   160         CFStringGetCharacters(pluginPath, CFRangeMake(0, length), buffer);
       
   161 
       
   162         paths << QString(reinterpret_cast<const QChar *>(buffer), length);
       
   163 
       
   164         CFRelease(pluginPath);
       
   165         CFRelease(pluginUrl);
       
   166         CFRelease(pluginPathPart);
       
   167         CFRelease(pluginUrlPart);
       
   168         CFRelease(baseUrl);
       
   169     }
       
   170 #endif
       
   171 
       
   172 #ifdef QTM_PLUGIN_PATH
       
   173     // Mobility's plugin directory
       
   174     paths << QLatin1String(QTM_PLUGIN_PATH);
       
   175 #endif
       
   176 
       
   177     // Qt paths
       
   178     paths << QCoreApplication::libraryPaths();
       
   179 
       
   180     foreach (const QString &path, paths) {
       
   181         QDir typeDir(path + m_location);
       
   182 #if defined(Q_OS_SYMBIAN)
       
   183         if (dirChecker.checkDir(typeDir))
       
   184 #endif
       
   185         {
       
   186             foreach (const QString &file, typeDir.entryList(QDir::Files)) {
       
   187 #if defined(Q_OS_MAC)
       
   188                 if (!imageSuffix.isEmpty()) {   // Only add appropriate images
       
   189                     if (file.lastIndexOf(imageSuffix, -6) == -1)
       
   190                         continue;
       
   191                 } else {  // Ignore any images with common suffixes
       
   192                     if (file.endsWith(QLatin1String("_debug.dylib")) ||
       
   193                         file.endsWith(QLatin1String("_profile.dylib")))
       
   194                         continue;
       
   195                 }
       
   196 #elif defined(Q_OS_UNIX)
       
   197                 // Ignore separate debug files
       
   198                 if (file.endsWith(QLatin1String(".debug")))
       
   199                     continue;
       
   200 #elif defined(Q_OS_WIN)
       
   201                 // Ignore non-dlls
       
   202                 if (!file.endsWith(QLatin1String(".dll"), Qt::CaseInsensitive))
       
   203                     continue;
       
   204 #endif
       
   205                 plugins << typeDir.absoluteFilePath(file);
       
   206             }
       
   207         }
       
   208     }
       
   209 
       
   210     return  plugins;
    82 }
   211 }
    83 
   212 
    84 void QMediaPluginLoader::load()
   213 void QMediaPluginLoader::load()
    85 {
   214 {
    86     if (!m_instances.isEmpty())
   215     if (!m_instances.isEmpty())
    95                         m_instances.insertMulti(key, o);
   224                         m_instances.insertMulti(key, o);
    96                 }
   225                 }
    97             }
   226             }
    98         }
   227         }
    99     } else {
   228     } else {
   100         QStringList plugins = QTM_PREPEND_NAMESPACE(mobilityPlugins)(m_location);
   229         foreach (const QString &plugin, availablePlugins()) {
   101         for (int i=0; i < plugins.count(); i++) {
   230             QPluginLoader   loader(plugin);
   102             QPluginLoader   loader(plugins.at(i));
   231 
   103             QObject *o = loader.instance();
   232             QObject *o = loader.instance();
   104             if (o != 0 && o->qt_metacast(m_iid) != 0) {
   233             if (o != 0 && o->qt_metacast(m_iid) != 0) {
   105                 QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
   234                 QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
   106                 if (p != 0) {
   235                 if (p != 0) {
   107                     foreach (QString const &key, p->keys())
   236                     foreach (const QString &key, p->keys())
   108                         m_instances.insertMulti(key, o);
   237                         m_instances.insertMulti(key, o);
   109                 }
   238                 }
   110 
   239 
   111                 continue;
   240                 continue;
   112             } else {
   241             } else {
   113                 qWarning() << "QMediaPluginLoader: Failed to load plugin: " << plugins.at(i) << loader.errorString();
   242                 qWarning() << "QMediaPluginLoader: Failed to load plugin: " << plugin << loader.errorString();
   114             }
   243             }
       
   244 
   115             delete o;
   245             delete o;
   116             loader.unload();
   246             loader.unload();
   117         }
   247         }
   118     }
   248     }
   119 }
   249 }
       
   250 
   120 QT_END_NAMESPACE
   251 QT_END_NAMESPACE
   121 
   252