Diff
Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/ChangeLog (164808 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/ChangeLog 2014-02-27 17:59:16 UTC (rev 164808)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/ChangeLog 2014-02-27 18:07:12 UTC (rev 164809)
@@ -1,3 +1,37 @@
+2014-02-27 Carlos Garcia Campos <[email protected]>
+
+ [GTK][WK2] Blocks when fetching plugins information
+ https://bugs.webkit.org/show_bug.cgi?id=115650
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Use a persistent cache to store the plugins metadata to avoid
+ having to load all the plugins everytime a plugin is used for the
+ first time.
+
+ * GNUmakefile.am:
+ * GNUmakefile.list.am:
+ * PlatformGTK.cmake:
+ * Shared/Plugins/Netscape/NetscapePluginModule.h:
+ * Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
+ (WebKit::NetscapePluginModule::parseMIMEDescription): Make this
+ method public.
+ (WebKit::NetscapePluginModule::buildMIMEDescription): Added this
+ helper to build the MIME description string.
+ * UIProcess/Plugins/gtk/PluginInfoCache.cpp: Added.
+ (WebKit::PluginInfoCache::shared):
+ (WebKit::PluginInfoCache::PluginInfoCache):
+ (WebKit::PluginInfoCache::~PluginInfoCache):
+ (WebKit::PluginInfoCache::saveToFileIdleCallback):
+ (WebKit::PluginInfoCache::saveToFile):
+ (WebKit::PluginInfoCache::getPluginInfo):
+ (WebKit::PluginInfoCache::updatePluginInfo):
+ * UIProcess/Plugins/gtk/PluginInfoCache.h: Added.
+ * UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp:
+ (WebKit::PluginInfoStore::getPluginInfo): Check first if we have
+ metadata of the plugin in the cache and update the cache if we
+ loaded the plugin to get its metadata.
+
2014-02-27 Ryan Lortie <[email protected]>
need to #include <libgen.h> for basename
Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/GNUmakefile.am (164808 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/GNUmakefile.am 2014-02-27 17:59:16 UTC (rev 164808)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/GNUmakefile.am 2014-02-27 18:07:12 UTC (rev 164809)
@@ -126,6 +126,7 @@
-I$(srcdir)/Source/WebKit2/UIProcess/Network/CustomProtocols/soup \
-I$(srcdir)/Source/WebKit2/UIProcess/Notifications \
-I$(srcdir)/Source/WebKit2/UIProcess/Plugins \
+ -I$(srcdir)/Source/WebKit2/UIProcess/Plugins/gtk \
-I$(srcdir)/Source/WebKit2/UIProcess/Plugins/unix \
-I$(srcdir)/Source/WebKit2/UIProcess/Storage \
-I$(srcdir)/Source/WebKit2/UIProcess/soup \
Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/GNUmakefile.list.am (164808 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/GNUmakefile.list.am 2014-02-27 17:59:16 UTC (rev 164808)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/GNUmakefile.list.am 2014-02-27 18:07:12 UTC (rev 164809)
@@ -870,6 +870,8 @@
Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h \
Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h \
Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp \
+ Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp \
+ Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h \
Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp \
Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp \
Source/WebKit2/UIProcess/ProcessModel.h \
Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/PlatformGTK.cmake (164808 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/PlatformGTK.cmake 2014-02-27 17:59:16 UTC (rev 164808)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/PlatformGTK.cmake 2014-02-27 18:07:12 UTC (rev 164809)
@@ -246,6 +246,8 @@
UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.cpp
UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.cpp
+ UIProcess/Plugins/gtk/PluginInfoCache.cpp
+
UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
@@ -407,6 +409,7 @@
"${WEBKIT2_DIR}/UIProcess/API/cpp/gtk"
"${WEBKIT2_DIR}/UIProcess/API/gtk"
"${WEBKIT2_DIR}/UIProcess/Network/CustomProtocols/soup"
+ "${WEBKIT2_DIR}/UIProcess/Plugins/gtk"
"${WEBKIT2_DIR}/UIProcess/gtk"
"${WEBKIT2_DIR}/UIProcess/soup"
"${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk"
Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h (164808 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h 2014-02-27 17:59:16 UTC (rev 164808)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h 2014-02-27 18:07:12 UTC (rev 164809)
@@ -35,6 +35,10 @@
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
+namespace WebCore {
+struct MimeClassInfo;
+}
+
namespace WebKit {
class RawPluginMetaData;
@@ -67,6 +71,8 @@
#if PLUGIN_ARCHITECTURE(X11)
static bool scanPlugin(const String& pluginPath);
+ static void parseMIMEDescription(const String& mimeDescription, Vector<WebCore::MimeClassInfo>& result);
+ static String buildMIMEDescription(const Vector<WebCore::MimeClassInfo>&);
#endif
private:
Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp (164808 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp 2014-02-27 17:59:16 UTC (rev 164808)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp 2014-02-27 18:07:12 UTC (rev 164809)
@@ -36,6 +36,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <wtf/text/StringBuilder.h>
using namespace WebCore;
@@ -67,7 +68,7 @@
}
-static void parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
+void NetscapePluginModule::parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
{
ASSERT_ARG(result, result.isEmpty());
@@ -94,6 +95,32 @@
}
}
+String NetscapePluginModule::buildMIMEDescription(const Vector<MimeClassInfo>& mimeDescription)
+{
+ StringBuilder builder;
+
+ size_t mimeInfoCount = mimeDescription.size();
+ for (size_t i = 0; i < mimeInfoCount; ++i) {
+ const MimeClassInfo& mimeInfo = mimeDescription[i];
+ builder.append(mimeInfo.type);
+ builder.append(':');
+
+ size_t extensionsCount = mimeInfo.extensions.size();
+ for (size_t j = 0; j < extensionsCount; ++j) {
+ builder.append(mimeInfo.extensions[j]);
+ if (j != extensionsCount - 1)
+ builder.append(',');
+ }
+ builder.append(':');
+
+ builder.append(mimeInfo.desc);
+ if (i != mimeInfoCount - 1)
+ builder.append(';');
+ }
+
+ return builder.toString();
+}
+
bool NetscapePluginModule::getPluginInfoForLoadedPlugin(RawPluginMetaData& metaData)
{
ASSERT(m_isInitialized);
Added: releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp (0 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp (rev 0)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp 2014-02-27 18:07:12 UTC (rev 164809)
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginInfoCache.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapePluginModule.h"
+#include <WebCore/FileSystem.h>
+#include <wtf/text/CString.h>
+
+namespace WebKit {
+
+static const unsigned gSchemaVersion = 1;
+
+PluginInfoCache& PluginInfoCache::shared()
+{
+ static NeverDestroyed<PluginInfoCache> pluginInfoCache;
+ return pluginInfoCache;
+}
+
+PluginInfoCache::PluginInfoCache()
+ : m_cacheFile(g_key_file_new())
+ , m_cachePath(g_build_filename(g_get_user_cache_dir(), "webkitgtk", "plugins", nullptr))
+ , m_saveToFileIdleId(0)
+{
+ g_key_file_load_from_file(m_cacheFile.get(), m_cachePath.get(), G_KEY_FILE_NONE, nullptr);
+
+ if (g_key_file_has_group(m_cacheFile.get(), "schema")) {
+ unsigned schemaVersion = static_cast<unsigned>(g_key_file_get_integer(m_cacheFile.get(), "schema", "version", nullptr));
+ if (schemaVersion == gSchemaVersion)
+ return;
+
+ // Cache file using an old schema, create a new empty file.
+ m_cacheFile.reset(g_key_file_new());
+ }
+
+ g_key_file_set_integer(m_cacheFile.get(), "schema", "version", static_cast<unsigned>(gSchemaVersion));
+}
+
+PluginInfoCache::~PluginInfoCache()
+{
+ if (m_saveToFileIdleId) {
+ g_source_remove(m_saveToFileIdleId);
+ saveToFile();
+ }
+}
+
+gboolean PluginInfoCache::saveToFileIdleCallback(PluginInfoCache* cache)
+{
+ cache->saveToFile();
+ return FALSE;
+}
+
+void PluginInfoCache::saveToFile()
+{
+ std::lock_guard<std::mutex> lock(m_mutex);
+ m_saveToFileIdleId = 0;
+
+ gsize dataLength;
+ GUniquePtr<char> data(g_key_file_to_data(m_cacheFile.get(), &dataLength, nullptr));
+ if (!data)
+ return;
+
+ g_file_set_contents(m_cachePath.get(), data.get(), dataLength, nullptr);
+}
+
+bool PluginInfoCache::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
+{
+ CString pluginGroup = pluginPath.utf8();
+ if (!g_key_file_has_group(m_cacheFile.get(), pluginGroup.data()))
+ return false;
+
+ time_t lastModified;
+ if (!WebCore::getFileModificationTime(pluginPath, lastModified))
+ return false;
+ time_t cachedLastModified = static_cast<time_t>(g_key_file_get_uint64(m_cacheFile.get(), pluginGroup.data(), "mtime", nullptr));
+ if (lastModified != cachedLastModified)
+ return false;
+
+ plugin.path = pluginPath;
+ plugin.info.file = WebCore::pathGetFileName(pluginPath);
+
+ GUniquePtr<char> stringValue(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "name", nullptr));
+ plugin.info.name = String::fromUTF8(stringValue.get());
+
+ stringValue.reset(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "description", nullptr));
+ plugin.info.desc = String::fromUTF8(stringValue.get());
+
+ stringValue.reset(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", nullptr));
+ NetscapePluginModule::parseMIMEDescription(String::fromUTF8(stringValue.get()), plugin.info.mimes);
+
+ return true;
+}
+
+void PluginInfoCache::updatePluginInfo(const String& pluginPath, const PluginModuleInfo& plugin)
+{
+ time_t lastModified;
+ if (!WebCore::getFileModificationTime(pluginPath, lastModified))
+ return;
+
+ CString pluginGroup = pluginPath.utf8();
+ g_key_file_set_uint64(m_cacheFile.get(), pluginGroup.data(), "mtime", static_cast<guint64>(lastModified));
+ g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "name", plugin.info.name.utf8().data());
+ g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "description", plugin.info.desc.utf8().data());
+
+ String mimeDescription = NetscapePluginModule::buildMIMEDescription(plugin.info.mimes);
+ g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", mimeDescription.utf8().data());
+
+ // Save the cache file in an idle to make sure it happens in the main thread and
+ // it's done only once when this is called multiple times in a very short time.
+ std::lock_guard<std::mutex> lock(m_mutex);
+ if (m_saveToFileIdleId)
+ return;
+
+ m_saveToFileIdleId = g_idle_add(reinterpret_cast<GSourceFunc>(PluginInfoCache::saveToFileIdleCallback), this);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
Added: releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h (0 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h (rev 0)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h 2014-02-27 18:07:12 UTC (rev 164809)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginInfoCache_h
+#define PluginInfoCache_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginModuleInfo.h"
+#include <mutex>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/gobject/GUniquePtr.h>
+
+namespace WebKit {
+
+class PluginInfoCache {
+ WTF_MAKE_NONCOPYABLE(PluginInfoCache);
+ friend class NeverDestroyed<PluginInfoCache>;
+public:
+ static PluginInfoCache& shared();
+
+ bool getPluginInfo(const String& pluginPath, PluginModuleInfo&);
+ void updatePluginInfo(const String& pluginPath, const PluginModuleInfo&);
+
+private:
+ PluginInfoCache();
+ ~PluginInfoCache();
+
+ void saveToFile();
+ static gboolean saveToFileIdleCallback(PluginInfoCache*);
+
+ GUniquePtr<GKeyFile> m_cacheFile;
+ GUniquePtr<char> m_cachePath;
+ unsigned m_saveToFileIdleId;
+ std::mutex m_mutex;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // PluginInfoCache_h
Modified: releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp (164808 => 164809)
--- releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp 2014-02-27 17:59:16 UTC (rev 164808)
+++ releases/WebKitGTK/webkit-2.4/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp 2014-02-27 18:07:12 UTC (rev 164809)
@@ -35,6 +35,10 @@
#include "PluginDatabase.h"
#include <WebCore/FileSystem.h>
+#if PLATFORM(GTK)
+#include "PluginInfoCache.h"
+#endif
+
using namespace WebCore;
namespace WebKit {
@@ -98,7 +102,18 @@
bool PluginInfoStore::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
{
+#if PLATFORM(GTK)
+ if (PluginInfoCache::shared().getPluginInfo(pluginPath, plugin))
+ return true;
+
+ if (NetscapePluginModule::getPluginInfo(pluginPath, plugin)) {
+ PluginInfoCache::shared().updatePluginInfo(pluginPath, plugin);
+ return true;
+ }
+ return false;
+#else
return NetscapePluginModule::getPluginInfo(pluginPath, plugin);
+#endif
}
bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& /*alreadyLoadedPlugins*/, const PluginModuleInfo& /*plugin*/)