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 |