[Qt][WK2] Set up plugin process on Unix
authorkbalazs@webkit.org <kbalazs@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Apr 2012 15:35:37 +0000 (15:35 +0000)
committerkbalazs@webkit.org <kbalazs@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Apr 2012 15:35:37 +0000 (15:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=72121

Reviewed by Simon Hausmann.

.:

* Source/QtWebKit.pro: Add PluginProcess subproject.

Source/WebKit2:

Setup plugin process for Qt and move the task of querying the plugins
to this process in order to avoid crashes due to plugin bugs or library
incompatibility.

* GNUmakefile.am:
* PluginProcess.pro: Added.

* PluginProcess/gtk/PluginProcessMainGtk.cpp:
(WebKit::PluginProcessMainGtk):
* PluginProcess/qt/PluginProcessMainQt.cpp:
(WebKit::messageHandler):
(WebKit::initializeGtk):
(WebKit):
(WebKit::PluginProcessMain):
Implement entry point of the plugin process.
Handle -scanPlugin command line switch: produce meta data
of plugin on standard output and terminate. Move Gtk initialization
hack to there.

* Shared/Plugins/Netscape/NetscapePluginModule.cpp:
(WebKit::NetscapePluginModule::tryLoad):
Get rid of the Gtk initialization hack. We do not nead it here anymore.

* Shared/Plugins/Netscape/NetscapePluginModule.h:
(WebKit):
(NetscapePluginModule):
* Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
(WebKit::parseMIMEDescription):
(WebKit::NetscapePluginModule::getPluginInfoForLoadedPlugin):
(WebKit):
(WebKit::NetscapePluginModule::getPluginInfo):
Get plugin meta data via PluginProcessproxy. If a failure
happened we ignore to use the plugin. Remove the concept
of stdout redirection since we can control it when launching
the process.

(WebKit::NetscapePluginModule::determineQuirks):
(WebKit::truncateToSingleLine):
(WebKit::NetscapePluginModule::scanPlugin):
Produce plugin meta data on standard output.

* Shared/ProcessExecutablePath.h: Added.
(WebKit):
* Shared/gtk/ProcessExecutablePathGtk.cpp: Added.
(findWebKitProcess):
(executablePathOfWebProcess):
(executablePathOfPluginProcess):
* Shared/qt/ProcessExecutablePathQt.cpp: Copied from Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp.
(WebKit):
(WebKit::executablePath):
(WebKit::executablePathOfWebProcess):
(WebKit::executablePathOfPluginProcess):
Factored the executable path determination into free functions
to avoid code duplication.

* Shared/qt/ShareableBitmapQt.cpp:
(WebKit::ShareableBitmap::paint):
Added implementation for the override with the scale factor because
it is called from PluginProxy. It does not actually handle the case
when the scale factor is not 1. However it's ok because it can only
happen on Mac in the moment.

* Target.pri:
* UIProcess/Launcher/ProcessLauncher.h:
(ProcessLauncher):
* UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp:
(WebKit::ProcessLauncher::launchProcess):
* UIProcess/Launcher/qt/ProcessLauncherQt.cpp:
(WebKit::ProcessLauncher::launchProcess):
Use the new functions to determine the executable path.

* UIProcess/Plugins/PluginProcessProxy.h:
(WebKit):
(RawPluginMetaData):
(PluginProcessProxy):
* UIProcess/Plugins/gtk/PluginProcessProxyGtk.cpp:
(WebKit::PluginProcessProxy::platformInitializePluginProcess):
(WebKit):
(WebKit::PluginProcessProxy::scanPlugin):
* UIProcess/Plugins/qt/PluginProcessProxyQt.cpp:
(WebKit):
(WebKit::PluginProcessProxy::platformInitializePluginProcess):
(WebKit::PluginProcessProxy::scanPlugin):
Launch plugin process and parse it's output to get the meta data
for the plugin.

* WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp:
(WebKit::NPN_GetValue):
Changed according to the removing of the flash hack. Do not try
to decide whether the plugin needs Gtk by it's name but instead
always get back the expected Gtk version (2). Only Gtk plugins
should ask for this anyway.

* qt/PluginMainQt.cpp: Copied from Source/WebKit2/UIProcess/Plugins/gtk/PluginProcessProxyGtk.cpp.
(WebKit):
(main):

Tools:

* qmake/mkspecs/features/features.prf: Reenable plugins
and turn on plugin process.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@112889 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
ChangeLog
Source/QtWebKit.pro
Source/WebKit2/ChangeLog
Source/WebKit2/GNUmakefile.am
Source/WebKit2/PluginProcess.pro [new file with mode: 0644]
Source/WebKit2/PluginProcess/gtk/PluginProcessMainGtk.cpp
Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp
Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.cpp
Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h
Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp
Source/WebKit2/Shared/ProcessExecutablePath.h [new file with mode: 0644]
Source/WebKit2/Shared/gtk/ProcessExecutablePathGtk.cpp [new file with mode: 0644]
Source/WebKit2/Shared/qt/ProcessExecutablePathQt.cpp [new file with mode: 0644]
Source/WebKit2/Shared/qt/ShareableBitmapQt.cpp
Source/WebKit2/Target.pri
Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h
Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp
Source/WebKit2/UIProcess/Launcher/qt/ProcessLauncherQt.cpp
Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h
Source/WebKit2/UIProcess/Plugins/gtk/PluginProcessProxyGtk.cpp
Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp
Source/WebKit2/qt/PluginMainQt.cpp [new file with mode: 0644]
Tools/ChangeLog
Tools/MiniBrowser/gtk/GNUmakefile.am
Tools/qmake/mkspecs/features/features.prf

index adfb8dc..5378a07 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-04-02  Balazs Kelemen  <kbalazs@webkit.org>
+
+        [Qt][WK2] Set up plugin process on Unix
+        https://bugs.webkit.org/show_bug.cgi?id=72121
+
+        Reviewed by Simon Hausmann.
+
+        * Source/QtWebKit.pro: Add PluginProcess subproject.
+
 2012-04-02  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r112868, r112879, and r112881.
index 02fc9e1..bbbfc41 100644 (file)
@@ -4,6 +4,8 @@
 # See 'Tools/qmake/README' for an overview of the build system
 # -------------------------------------------------------------------
 
+load(features)
+
 TEMPLATE = subdirs
 CONFIG += ordered
 
@@ -13,6 +15,10 @@ SUBDIRS += api
 !no_webkit2 {
     webprocess.file = WebKit2/WebProcess.pro
     SUBDIRS += webprocess
+    contains(DEFINES, ENABLE_PLUGIN_PROCESS=1) {
+        pluginprocess.file = WebKit2/PluginProcess.pro
+        SUBDIRS += pluginprocess
+    }
 }
 
 include(WebKit/qt/docs/docs.pri)
index b0308f9..0010181 100644 (file)
@@ -1,3 +1,107 @@
+2012-04-02  Balazs Kelemen  <kbalazs@webkit.org>
+
+        [Qt][WK2] Set up plugin process on Unix
+        https://bugs.webkit.org/show_bug.cgi?id=72121
+
+        Reviewed by Simon Hausmann.
+
+        Setup plugin process for Qt and move the task of querying the plugins
+        to this process in order to avoid crashes due to plugin bugs or library
+        incompatibility.
+
+        * GNUmakefile.am:
+        * PluginProcess.pro: Added.
+
+        * PluginProcess/gtk/PluginProcessMainGtk.cpp:
+        (WebKit::PluginProcessMainGtk):
+        * PluginProcess/qt/PluginProcessMainQt.cpp:
+        (WebKit::messageHandler):
+        (WebKit::initializeGtk):
+        (WebKit):
+        (WebKit::PluginProcessMain):
+        Implement entry point of the plugin process.
+        Handle -scanPlugin command line switch: produce meta data
+        of plugin on standard output and terminate. Move Gtk initialization
+        hack to there.
+
+        * Shared/Plugins/Netscape/NetscapePluginModule.cpp:
+        (WebKit::NetscapePluginModule::tryLoad):
+        Get rid of the Gtk initialization hack. We do not nead it here anymore.
+
+        * Shared/Plugins/Netscape/NetscapePluginModule.h:
+        (WebKit):
+        (NetscapePluginModule):
+        * Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
+        (WebKit::parseMIMEDescription):
+        (WebKit::NetscapePluginModule::getPluginInfoForLoadedPlugin):
+        (WebKit):
+        (WebKit::NetscapePluginModule::getPluginInfo):
+        Get plugin meta data via PluginProcessproxy. If a failure
+        happened we ignore to use the plugin. Remove the concept
+        of stdout redirection since we can control it when launching
+        the process.
+
+        (WebKit::NetscapePluginModule::determineQuirks):
+        (WebKit::truncateToSingleLine):
+        (WebKit::NetscapePluginModule::scanPlugin):
+        Produce plugin meta data on standard output.
+
+        * Shared/ProcessExecutablePath.h: Added.
+        (WebKit):
+        * Shared/gtk/ProcessExecutablePathGtk.cpp: Added.
+        (findWebKitProcess):
+        (executablePathOfWebProcess):
+        (executablePathOfPluginProcess):
+        * Shared/qt/ProcessExecutablePathQt.cpp: Copied from Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp.
+        (WebKit):
+        (WebKit::executablePath):
+        (WebKit::executablePathOfWebProcess):
+        (WebKit::executablePathOfPluginProcess):
+        Factored the executable path determination into free functions
+        to avoid code duplication.
+
+        * Shared/qt/ShareableBitmapQt.cpp:
+        (WebKit::ShareableBitmap::paint):
+        Added implementation for the override with the scale factor because
+        it is called from PluginProxy. It does not actually handle the case
+        when the scale factor is not 1. However it's ok because it can only
+        happen on Mac in the moment.
+
+        * Target.pri:
+        * UIProcess/Launcher/ProcessLauncher.h:
+        (ProcessLauncher):
+        * UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp:
+        (WebKit::ProcessLauncher::launchProcess):
+        * UIProcess/Launcher/qt/ProcessLauncherQt.cpp:
+        (WebKit::ProcessLauncher::launchProcess):
+        Use the new functions to determine the executable path.
+
+        * UIProcess/Plugins/PluginProcessProxy.h:
+        (WebKit):
+        (RawPluginMetaData):
+        (PluginProcessProxy):
+        * UIProcess/Plugins/gtk/PluginProcessProxyGtk.cpp:
+        (WebKit::PluginProcessProxy::platformInitializePluginProcess):
+        (WebKit):
+        (WebKit::PluginProcessProxy::scanPlugin):
+        * UIProcess/Plugins/qt/PluginProcessProxyQt.cpp:
+        (WebKit):
+        (WebKit::PluginProcessProxy::platformInitializePluginProcess):
+        (WebKit::PluginProcessProxy::scanPlugin):
+        Launch plugin process and parse it's output to get the meta data
+        for the plugin.
+
+        * WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp:
+        (WebKit::NPN_GetValue):
+        Changed according to the removing of the flash hack. Do not try
+        to decide whether the plugin needs Gtk by it's name but instead
+        always get back the expected Gtk version (2). Only Gtk plugins
+        should ask for this anyway.
+
+        * qt/PluginMainQt.cpp: Copied from Source/WebKit2/UIProcess/Plugins/gtk/PluginProcessProxyGtk.cpp.
+        (WebKit):
+        (main):
+
 2012-04-02  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r112868, r112879, and r112881.
index 364d3d1..588e6a6 100644 (file)
@@ -331,6 +331,7 @@ webkit2_sources += \
        Source/WebKit2/Shared/EditorState.cpp \
        Source/WebKit2/Shared/EditorState.h \
        Source/WebKit2/Shared/FontSmoothingLevel.h \
+       Source/WebKit2/Shared/ProcessExecutablePath.h \
        Source/WebKit2/Shared/cairo/LayerTreeContextCairo.cpp \
        Source/WebKit2/Shared/cairo/ShareableBitmapCairo.cpp \
        Source/WebKit2/Shared/gtk/ArgumentCodersGtk.h \
@@ -340,6 +341,7 @@ webkit2_sources += \
        Source/WebKit2/Shared/gtk/NativeWebWheelEventGtk.cpp \
        Source/WebKit2/Shared/gtk/PlatformCertificateInfo.h \
        Source/WebKit2/Shared/gtk/PrintInfoGtk.cpp \
+       Source/WebKit2/Shared/gtk/ProcessExecutablePathGtk.cpp \
        Source/WebKit2/Shared/gtk/WebCoreArgumentCodersGtk.cpp \
        Source/WebKit2/Shared/gtk/WebEventFactory.cpp \
        Source/WebKit2/Shared/gtk/WebEventFactory.h \
@@ -1369,6 +1371,7 @@ Programs_WebKitPluginProcess_CPPFLAGS = \
        -I$(srcdir)/Source/WebKit2/Shared/Plugins \
        -I$(srcdir)/Source/WebKit2/Shared/Plugins/Netscape/ \
        -I$(srcdir)/Source/WebKit2/UIProcess/Plugins/ \
+       -I$(srcdir)/Source/WebKit2/UIProcess/Launcher \
        -I$(srcdir)/Source/WebKit2/WebProcess/Plugins/ \
        -I$(srcdir)/Source/WebKit2/WebProcess/Plugins/Netscape/ \
        -I$(top_builddir)/DerivedSources/WebKit2 \
@@ -1379,6 +1382,7 @@ Programs_WebKitPluginProcess_CPPFLAGS = \
        -DBUILDING_WEBKIT \
        -DGTK_API_VERSION_2=1 \
        -DENABLE_PLUGIN_PROCESS=1 \
+       -DLIBEXECDIR=\""$(libexecdir)"\" \
        $(global_cppflags) \
        $(webcore_cppflags) \
        $(webcoregtk_cppflags) \
@@ -1461,6 +1465,7 @@ webkit2_plugin_process_sources += \
        Source/WebKit2/PluginProcess/gtk/PluginProcessMainGtk.cpp \
        Source/WebKit2/Shared/ChildProcess.cpp \
        Source/WebKit2/Shared/ChildProcess.h \
+       Source/WebKit2/Shared/ProcessExecutablePath.h \
        Source/WebKit2/Shared/Plugins/NPIdentifierData.cpp \
        Source/WebKit2/Shared/Plugins/NPIdentifierData.h \
        Source/WebKit2/Shared/Plugins/NPObjectMessageReceiver.cpp \
@@ -1487,8 +1492,10 @@ webkit2_plugin_process_sources += \
        Source/WebKit2/Shared/gtk/NativeWebKeyboardEventGtk.cpp \
        Source/WebKit2/Shared/gtk/NativeWebWheelEventGtk.cpp \
        Source/WebKit2/Shared/gtk/NativeWebMouseEventGtk.cpp \
+       Source/WebKit2/Shared/gtk/ProcessExecutablePathGtk.cpp \
        Source/WebKit2/Shared/gtk/WebEventFactory.cpp \
        Source/WebKit2/Shared/cairo/ShareableBitmapCairo.cpp \
+       Source/WebKit2/UIProcess/Plugins/gtk/PluginProcessProxyGtk.cpp \
        Source/WebKit2/WebProcess/Plugins/Plugin.cpp \
        Source/WebKit2/WebProcess/Plugins/Plugin.h \
        Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp \
diff --git a/Source/WebKit2/PluginProcess.pro b/Source/WebKit2/PluginProcess.pro
new file mode 100644 (file)
index 0000000..8113afd
--- /dev/null
@@ -0,0 +1,27 @@
+# -------------------------------------------------------------------
+# Project file for the WebKit2 plugin process binary
+#
+# See 'Tools/qmake/README' for an overview of the build system
+# -------------------------------------------------------------------
+
+TEMPLATE = app
+
+QT += webkit
+
+TARGET = QtWebPluginProcess
+DESTDIR = $${ROOT_BUILD_DIR}/bin
+
+SOURCES += qt/PluginMainQt.cpp
+
+INCLUDEPATH = \
+    $$PWD/../JavaScriptCore \
+    $$PWD/../WTF \
+    $$INCLUDEPATH
+
+INSTALLS += target
+
+isEmpty(INSTALL_BINS) {
+    target.path = $$[QT_INSTALL_BINS]
+} else {
+    target.path = $$INSTALL_BINS
+}
index 992d740..870c01c 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "PluginProcessMainGtk.h"
 
+#include "NetscapePlugin.h"
 #include "PluginProcess.h"
 #include <WebCore/RunLoop.h>
 #include <gdk/gdkx.h>
@@ -53,12 +54,22 @@ static int webkitgtkXError(Display* xdisplay, XErrorEvent* error)
 
 WK_EXPORT int PluginProcessMainGtk(int argc, char* argv[])
 {
-    ASSERT(argc == 2);
+    ASSERT(argc == 2 || argc == 3);
+    bool scanPlugin = !strcmp(argv[1], "-scanPlugin");
+    ASSERT(argc == 2 || (argc == 3 && scanPlugin));
 
     gtk_init(&argc, &argv);
 
     JSC::initializeThreading();
     WTF::initializeMainThread();
+
+    if (scanPlugin) {
+        String pluginPath(argv[2]);
+        if (!NetscapePluginModule::scanPlugin(pluginPath))
+            return EXIT_FAILURE;
+        return EXIT_SUCCESS;
+    }
+
     RunLoop::initializeMainRunLoop();
 
     // Plugins can produce X errors that are handled by the GDK X error handler, which
index d3a0ec3..bc487e1 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010, 2011 Nokia Inc. All rights reserved.
+ * Copyright (C) 2011 University of Szeged. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  */
 
 #include "config.h"
-#include "PluginProcessMain.h"
 
 #if ENABLE(PLUGIN_PROCESS)
+#include "PluginProcessMain.h"
 
-#include "CommandLine.h"
+#include "NetscapePluginModule.h"
 #include "PluginProcess.h"
-#include <WebCore/NotImplemented.h>
+#include <QDebug>
+#include <QGuiApplication>
+#include <QStringList>
 #include <WebCore/RunLoop.h>
 #include <runtime/InitializeThreading.h>
 #include <wtf/MainThread.h>
-#include <wtf/RetainPtr.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
-
-#define SHOW_CRASH_REPORTER 1
+#include <wtf/Threading.h>
 
 using namespace WebCore;
 
 namespace WebKit {
 
-int PluginProcessMain(const CommandLine& commandLine)
+static void messageHandler(QtMsgType type, const char* message)
 {
-    String serviceName = commandLine["servicename"];
-    if (serviceName.isEmpty())
-        return EXIT_FAILURE;
+    if (type == QtCriticalMsg) {
+        fprintf(stderr, "%s\n", message);
+        return;
+    }
+
+    // Do nothing
+}
 
-#if !SHOW_CRASH_REPORTER
-    // Installs signal handlers that exit on a crash so that CrashReporter does not show up.
-    signal(SIGILL, _exit);
-    signal(SIGFPE, _exit);
-    signal(SIGBUS, _exit);
-    signal(SIGSEGV, _exit);
-#endif
+static bool initializeGtk()
+{
+    QLibrary gtkLibrary(QLatin1String("libgtk-x11-2.0"), 0);
+    if (!gtkLibrary.load())
+        return false;
+    typedef void* (*gtk_init_ptr)(void*, void*);
+    gtk_init_ptr gtkInit = reinterpret_cast<gtk_init_ptr>(gtkLibrary.resolve("gtk_init"));
+    if (!gtkInit)
+        return false;
+    gtkInit(0, 0);
+    return true;
+}
+
+int PluginProcessMain(int argc, char** argv)
+{
+    QByteArray suppressOutput = qgetenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT");
+    if (!suppressOutput.isEmpty() && suppressOutput != "0")
+        qInstallMsgHandler(messageHandler);
+
+    QGuiApplication app(argc, argv);
+
+    // Workaround the issue that some versions of flash does not initialize Gtk properly.
+    if (!initializeGtk())
+        return EXIT_FAILURE;
 
     JSC::initializeThreading();
     WTF::initializeMainThread();
+
+    if (argc <= 1)
+        return EXIT_FAILURE;
+
+    if (app.arguments().at(1) == QLatin1String("-scanPlugin")) {
+        if (argc != 3)
+            return EXIT_FAILURE;
+        String pluginPath(app.arguments().at(2));
+        if (!NetscapePluginModule::scanPlugin(pluginPath))
+            return EXIT_FAILURE;
+        return EXIT_SUCCESS;
+    }
+
     RunLoop::initializeMainRunLoop();
 
+    // Create the connection.
+    bool isNumber = false;
+    int identifier = app.arguments().at(1).toInt(&isNumber, 10);
+    if (!isNumber)
+        return EXIT_FAILURE;
+    WebKit::PluginProcess::shared().initialize(identifier, RunLoop::main());
+
     RunLoop::run();
 
     return 0;
index e5f8dc2..c1874d9 100644 (file)
@@ -197,10 +197,6 @@ bool NetscapePluginModule::load()
 
 bool NetscapePluginModule::tryLoad()
 {
-#if PLUGIN_ARCHITECTURE(X11)
-    applyX11QuirksBeforeLoad();
-#endif
-
     m_module = adoptPtr(new Module(m_pluginPath));
     if (!m_module->load())
         return false;
index f80a0a1..e96bd2d 100644 (file)
@@ -35,6 +35,8 @@
 
 namespace WebKit {
 
+class RawPluginMetaData;
+
 class NetscapePluginModule : public RefCounted<NetscapePluginModule> {
 public:
     static PassRefPtr<NetscapePluginModule> getOrCreate(const String& pluginPath);
@@ -61,15 +63,17 @@ public:
     static bool createPluginMIMETypesPreferences(const String& pluginPath);
 #endif
 
+#if PLUGIN_ARCHITECTURE(X11)
+    static bool scanPlugin(const String& pluginPath);
+#endif
+
 private:
     explicit NetscapePluginModule(const String& pluginPath);
 
     void determineQuirks();
 
 #if PLUGIN_ARCHITECTURE(X11)
-    void applyX11QuirksBeforeLoad();
-    static void setMIMEDescription(const String& mimeDescription, PluginModuleInfo&);
-    bool getPluginInfoForLoadedPlugin(PluginModuleInfo&);
+    bool getPluginInfoForLoadedPlugin(RawPluginMetaData&);
 #endif
 
     bool tryGetSitesWithData(Vector<String>&);
index 866833c..d2e3ec9 100644 (file)
 
 #include "NetscapePluginModule.h"
 
+#include "PluginProcessProxy.h"
 #include "NetscapeBrowserFuncs.h"
 #include <WebCore/FileSystem.h>
-
-#if PLATFORM(QT)
-#include <QLibrary>
-#endif
-
+#include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -44,60 +41,13 @@ using namespace WebCore;
 
 namespace WebKit {
 
-class StdoutDevNullRedirector {
-public:
-    StdoutDevNullRedirector();
-    ~StdoutDevNullRedirector();
-
-private:
-    int m_savedStdout;
-};
-
-StdoutDevNullRedirector::StdoutDevNullRedirector()
-    : m_savedStdout(-1)
+static void parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
 {
-    int newStdout = open("/dev/null", O_WRONLY);
-    if (newStdout == -1)
-        return;
-    m_savedStdout = dup(STDOUT_FILENO);
-    dup2(newStdout, STDOUT_FILENO);
-}
-
-StdoutDevNullRedirector::~StdoutDevNullRedirector()
-{
-    if (m_savedStdout != -1)
-        dup2(m_savedStdout, STDOUT_FILENO);
-}
-
-#if PLATFORM(QT)
-static void initializeGTK()
-{
-    QLibrary library(QLatin1String("libgtk-x11-2.0.so.0"));
-    if (library.load()) {
-        typedef void *(*gtk_init_check_ptr)(int*, char***);
-        gtk_init_check_ptr gtkInitCheck = reinterpret_cast<gtk_init_check_ptr>(library.resolve("gtk_init_check"));
-        // NOTE: We're using gtk_init_check() since gtk_init() calls exit() on failure.
-        if (gtkInitCheck)
-            (void) gtkInitCheck(0, 0);
-    }
-}
-#endif
+    ASSERT_ARG(result, result.isEmpty());
 
-void NetscapePluginModule::applyX11QuirksBeforeLoad()
-{
-#if PLATFORM(QT)
-    if (m_pluginPath.contains("npwrapper") || m_pluginPath.contains("flashplayer")) {
-        initializeGTK();
-        m_pluginQuirks.add(PluginQuirks::RequiresGTKToolKit);
-    }
-#endif
-}
-
-void NetscapePluginModule::setMIMEDescription(const String& mimeDescription, PluginModuleInfo& plugin)
-{
     Vector<String> types;
     mimeDescription.lower().split(UChar(';'), false, types);
-    plugin.info.mimes.reserveCapacity(types.size());
+    result.reserveInitialCapacity(types.size());
 
     size_t mimeInfoCount = 0;
     for (size_t i = 0; i < types.size(); ++i) {
@@ -106,8 +56,8 @@ void NetscapePluginModule::setMIMEDescription(const String& mimeDescription, Plu
         if (mimeTypeParts.size() <= 0)
             continue;
 
-        plugin.info.mimes.uncheckedAppend(MimeClassInfo());
-        MimeClassInfo& mimeInfo = plugin.info.mimes[mimeInfoCount++];
+        result.uncheckedAppend(MimeClassInfo());
+        MimeClassInfo& mimeInfo = result[mimeInfoCount++];
         mimeInfo.type = mimeTypeParts[0];
 
         if (mimeTypeParts.size() > 1)
@@ -118,13 +68,10 @@ void NetscapePluginModule::setMIMEDescription(const String& mimeDescription, Plu
     }
 }
 
-bool NetscapePluginModule::getPluginInfoForLoadedPlugin(PluginModuleInfo& plugin)
+bool NetscapePluginModule::getPluginInfoForLoadedPlugin(RawPluginMetaData& metaData)
 {
     ASSERT(m_isInitialized);
 
-    plugin.path = m_pluginPath;
-    plugin.info.file = pathGetFileName(m_pluginPath);
-
     Module* module = m_module.get();
     NPP_GetValueProcPtr NPP_GetValue = module->functionPointer<NPP_GetValueProcPtr>("NP_GetValue");
     if (!NPP_GetValue)
@@ -137,47 +84,45 @@ bool NetscapePluginModule::getPluginInfoForLoadedPlugin(PluginModuleInfo& plugin
     char* buffer;
     NPError error = NPP_GetValue(0, NPPVpluginNameString, &buffer);
     if (error == NPERR_NO_ERROR)
-        plugin.info.name = String::fromUTF8(buffer);
+        metaData.name = String::fromUTF8(buffer);
 
     error = NPP_GetValue(0, NPPVpluginDescriptionString, &buffer);
     if (error == NPERR_NO_ERROR)
-        plugin.info.desc = String::fromUTF8(buffer);
+        metaData.description = String::fromUTF8(buffer);
 
     String mimeDescription = String::fromUTF8(NP_GetMIMEDescription());
     if (mimeDescription.isNull())
         return false;
 
-    setMIMEDescription(mimeDescription, plugin);
+    metaData.mimeDescription = mimeDescription;
 
     return true;
 }
+
 bool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
 {
-    // Tempararily suppress stdout in this function as plugins will be loaded and shutdown and debug info
-    // is leaked to layout test output.
-    StdoutDevNullRedirector stdoutDevNullRedirector;
-
-    // We are loading the plugin here since it does not seem to be a standardized way to
-    // get the needed informations from a UNIX plugin without loading it.
-    RefPtr<NetscapePluginModule> pluginModule = NetscapePluginModule::getOrCreate(pluginPath);
-    if (!pluginModule)
+    RawPluginMetaData metaData;
+    if (!PluginProcessProxy::scanPlugin(pluginPath, metaData))
         return false;
 
-    pluginModule->incrementLoadCount();
-    bool returnValue = pluginModule->getPluginInfoForLoadedPlugin(plugin);
-    pluginModule->decrementLoadCount();
+    plugin.path = pluginPath;
+    plugin.info.file = pathGetFileName(pluginPath);
+    plugin.info.name = metaData.name;
+    plugin.info.desc = metaData.description;
+    parseMIMEDescription(metaData.mimeDescription, plugin.info.mimes);
 
-    return returnValue;
+    return true;
 }
 
 void NetscapePluginModule::determineQuirks()
 {
 #if CPU(X86_64)
-    PluginModuleInfo plugin;
-    if (!getPluginInfoForLoadedPlugin(plugin))
+    RawPluginMetaData metaData;
+    if (!getPluginInfoForLoadedPlugin(metaData))
         return;
 
-    Vector<MimeClassInfo> mimeTypes = plugin.info.mimes;
+    Vector<MimeClassInfo> mimeTypes;
+    parseMIMEDescription(metaData.mimeDescription, mimeTypes);
     for (size_t i = 0; i < mimeTypes.size(); ++i) {
         if (mimeTypes[i].type == "application/x-shockwave-flash") {
             m_pluginQuirks.add(PluginQuirks::IgnoreRightClickInWindowlessMode);
@@ -187,6 +132,65 @@ void NetscapePluginModule::determineQuirks()
 #endif
 }
 
+static String truncateToSingleLine(const String& string)
+{
+    ASSERT_ARG(string, !string.is8Bit());
+
+    unsigned oldLength = string.length();
+    UChar* buffer;
+    String stringBuffer(StringImpl::createUninitialized(oldLength + 1, buffer));
+
+    unsigned newLength = 0;
+    for (const UChar* c = string.characters16(); c < string.characters16() + oldLength; ++c) {
+        if (*c != UChar('\n'))
+            buffer[newLength++] = *c;
+    }
+    buffer[newLength++] = UChar('\n');
+
+    if (newLength == oldLength + 1)
+        return stringBuffer;
+    return String(stringBuffer.characters16(), newLength);
+}
+
+bool NetscapePluginModule::scanPlugin(const String& pluginPath)
+{
+    // We are loading the plugin here since it does not seem to be a standardized way to
+    // get the needed informations from a UNIX plugin without loading it.
+    RefPtr<NetscapePluginModule> pluginModule = NetscapePluginModule::getOrCreate(pluginPath);
+    if (!pluginModule)
+        return false;
+
+    pluginModule->incrementLoadCount();
+    RawPluginMetaData metaData;
+    bool success = pluginModule->getPluginInfoForLoadedPlugin(metaData);
+    pluginModule->decrementLoadCount();
+
+    if (!success)
+        return false;
+
+    // Write data to standard output for the UI process.
+    String output[3] = {
+        truncateToSingleLine(metaData.name),
+        truncateToSingleLine(metaData.description),
+        truncateToSingleLine(metaData.mimeDescription)
+    };
+    for (unsigned i = 0; i < 3; ++i) {
+        const String& line = output[i];
+        const char* current = reinterpret_cast<const char*>(line.characters16());
+        const char* end = reinterpret_cast<const char*>(line.characters16()) + (line.length() * sizeof(UChar));
+        while (current < end) {
+            int result;
+            while ((result = fputc(*current, stdout)) == EOF && errno == EINTR) { }
+            ASSERT(result != EOF);
+            ++current;
+        }
+    }
+
+    fflush(stdout);
+
+    return true;
+}
+
 } // namespace WebKit
 
 #endif // PLUGIN_ARCHITECTURE(X11)
diff --git a/Source/WebKit2/Shared/ProcessExecutablePath.h b/Source/WebKit2/Shared/ProcessExecutablePath.h
new file mode 100644 (file)
index 0000000..5fbf320
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 University of Szeged. All rights reserved.
+ *
+ * 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED OR
+ * 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 <wtf/text/WTFString.h>
+
+#ifndef ProcessExecutablePath_h
+#define ProcessExecutablePath_h
+
+namespace WebKit {
+
+String executablePathOfWebProcess();
+String executablePathOfPluginProcess();
+
+}
+
+#endif
diff --git a/Source/WebKit2/Shared/gtk/ProcessExecutablePathGtk.cpp b/Source/WebKit2/Shared/gtk/ProcessExecutablePathGtk.cpp
new file mode 100644 (file)
index 0000000..5e15029
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
+ *
+ * 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 MOTOROLA 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 MOTOROLA 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 "ProcessExecutablePath.h"
+
+#include <WebCore/FileSystem.h>
+#include <glib.h>
+#include <wtf/gobject/GlibUtilities.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+const char* gWebKitWebProcessName = "WebKitWebProcess";
+const char* gWebKitPluginProcessName = "WebKitPluginProcess";
+
+static String findWebKitProcess(const char* processName)
+{
+    const char* execDirectory = g_getenv("WEBKIT_EXEC_PATH");
+    if (execDirectory) {
+        String processPath = pathByAppendingComponent(filenameToString(execDirectory), processName);
+        if (fileExists(processPath))
+            return processPath;
+    }
+
+    static bool gotExecutablePath = false;
+    static String executablePath;
+    if (!gotExecutablePath) {
+        gotExecutablePath = true;
+
+        CString executableFile = getCurrentExecutablePath();
+        if (!executableFile.isNull())
+            executablePath = directoryName(filenameToString(executableFile.data()));
+    }
+
+    if (!executablePath.isNull()) {
+        String processPath = pathByAppendingComponent(executablePath, processName);
+        if (fileExists(processPath))
+            return processPath;
+    }
+
+    return pathByAppendingComponent(filenameToString(LIBEXECDIR), processName);
+}
+
+String executablePathOfWebProcess()
+{
+    return findWebKitProcess(gWebKitWebProcessName);
+}
+
+String executablePathOfPluginProcess()
+{
+    return findWebKitProcess(gWebKitPluginProcessName);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/Shared/qt/ProcessExecutablePathQt.cpp b/Source/WebKit2/Shared/qt/ProcessExecutablePathQt.cpp
new file mode 100644 (file)
index 0000000..4b4f824
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 "ProcessExecutablePath.h"
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QFile>
+
+namespace WebKit {
+
+static String executablePath(QLatin1String baseName)
+{
+    QString expectedPath = QCoreApplication::applicationDirPath() + QDir::separator() + baseName;
+    if (QFile::exists(expectedPath))
+        return String(expectedPath);
+    return String(QString(baseName));
+}
+
+String executablePathOfWebProcess()
+{
+    return executablePath(QStringLiteral("QtWebProcess"));
+}
+
+String executablePathOfPluginProcess()
+{
+    return executablePath(QStringLiteral("QtWebPluginProcess"));
+}
+
+} // namespace WebKit
index 0c8be07..778bcfc 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <QImage>
 #include <QPainter>
+#include <QtGlobal>
 #include <WebCore/BitmapImage.h>
 #include <WebCore/GraphicsContext.h>
 #include <WebCore/NotImplemented.h>
@@ -71,8 +72,13 @@ void ShareableBitmap::paint(GraphicsContext& context, const IntPoint& dstPoint,
     painter->drawImage(dstPoint, image, QRect(srcRect));
 }
 
-void ShareableBitmap::paint(GraphicsContext& /*context*/, float /*scaleFactor*/, const IntPoint& /*dstPoint*/, const IntRect& /*srcRect*/)
+void ShareableBitmap::paint(GraphicsContext& context, float scaleFactor, const IntPoint& dstPoint, const IntRect& srcRect)
 {
+    if (qFuzzyCompare(scaleFactor, 1)) {
+        paint(context, dstPoint, srcRect);
+        return;
+    }
+
     // See <https://bugs.webkit.org/show_bug.cgi?id=64663>.
     notImplemented();
 }
index 16fbad4..0749738 100644 (file)
@@ -34,6 +34,7 @@ HEADERS += \
     Platform/SharedMemory.h \
     Platform/WorkQueue.h \
     PluginProcess/PluginControllerProxy.h \
+    PluginProcess/PluginCreationParameters.h \
     PluginProcess/PluginProcess.h \
     PluginProcess/WebProcessConnection.h \
     Shared/API/c/WKBase.h \
@@ -81,6 +82,7 @@ HEADERS += \
     Shared/OriginAndDatabases.h \
     Shared/PlatformPopupMenuData.h \
     Shared/PrintInfo.h \
+    Shared/ProcessExecutablePath.h \
     Shared/SameDocumentNavigationType.h \
     Shared/SecurityOriginData.h \
     Shared/SessionState.h \
@@ -382,6 +384,7 @@ SOURCES += \
     Platform/WorkQueue.cpp \
     Platform/qt/ModuleQt.cpp \
     PluginProcess/PluginControllerProxy.cpp \
+    PluginProcess/PluginCreationParameters.cpp \
     PluginProcess/PluginProcess.cpp \
     PluginProcess/WebProcessConnection.cpp \
     PluginProcess/qt/PluginControllerProxyQt.cpp \
@@ -474,6 +477,7 @@ SOURCES += \
     Shared/qt/NativeWebKeyboardEventQt.cpp \
     Shared/qt/NativeWebMouseEventQt.cpp \
     Shared/qt/NativeWebWheelEventQt.cpp \
+    Shared/qt/ProcessExecutablePathQt.cpp \
     Shared/qt/WebCoreArgumentCodersQt.cpp \
     Shared/qt/WebEventFactoryQt.cpp \
     Shared/qt/QtNetworkReplyData.cpp \
@@ -769,6 +773,7 @@ contains(DEFINES, ENABLE_GEOLOCATION=1): QT += location
 
 plugin_backend_xlib {
     DEFINES += XP_UNIX
+    PKGCONFIG += x11
 }
 
 include(DerivedSources.pri)
index 09c5589..bc1f867 100644 (file)
@@ -68,7 +68,6 @@ public:
     void invalidate();
 
     static bool getProcessTypeFromString(const char*, ProcessType&);
-
 private:
     ProcessLauncher(Client*, const LaunchOptions& launchOptions);
 
index 94cad5f..8fb619e 100644 (file)
@@ -28,6 +28,7 @@
 #include "ProcessLauncher.h"
 
 #include "Connection.h"
+#include "ProcessExecutablePath.h"
 #include <WebCore/FileSystem.h>
 #include <WebCore/ResourceHandle.h>
 #include <WebCore/RunLoop.h>
@@ -52,9 +53,6 @@ using namespace WebCore;
 
 namespace WebKit {
 
-const char* gWebKitWebProcessName = "WebKitWebProcess";
-const char* gWebKitPluginProcessName = "WebKitPluginProcess";
-
 static void childSetupFunction(gpointer userData)
 {
     int socket = GPOINTER_TO_INT(userData);
@@ -77,34 +75,6 @@ static void childFinishedFunction(GPid, gint status, gpointer userData)
     close(GPOINTER_TO_INT(userData));
 }
 
-static CString findWebKitProcess(const char* processName)
-{
-    const char* execDirectory = g_getenv("WEBKIT_EXEC_PATH");
-    if (execDirectory) {
-        String processPath = pathByAppendingComponent(filenameToString(execDirectory), processName);
-        if (fileExists(processPath))
-            return fileSystemRepresentation(processPath);
-    }
-
-    static bool gotExecutablePath = false;
-    static String executablePath;
-    if (!gotExecutablePath) {
-        gotExecutablePath = true;
-
-        CString executableFile = getCurrentExecutablePath();
-        if (!executableFile.isNull())
-            executablePath = directoryName(filenameToString(executableFile.data()));
-    }
-
-    if (!executablePath.isNull()) {
-        String processPath = pathByAppendingComponent(executablePath, processName);
-        if (fileExists(processPath))
-            return fileSystemRepresentation(processPath);
-    }
-
-    return fileSystemRepresentation(pathByAppendingComponent(filenameToString(LIBEXECDIR), processName));
-}
-
 void ProcessLauncher::launchProcess()
 {
     GPid pid = 0;
@@ -116,7 +86,9 @@ void ProcessLauncher::launchProcess()
         return;
     }
 
-    CString binaryPath = findWebKitProcess(m_launchOptions.processType == ProcessLauncher::WebProcess ? gWebKitWebProcessName : gWebKitPluginProcessName);
+    String executablePath = m_launchOptions.processType == WebProcess ?
+                            executablePathOfWebProcess() : executablePathOfPluginProcess();
+    CString binaryPath = fileSystemRepresentation(executablePath);
     GOwnPtr<gchar> socket(g_strdup_printf("%d", sockets[0]));
     char* argv[3];
     argv[0] = const_cast<char*>(binaryPath.data());
index 8e82620..c5c3f71 100644 (file)
 #include "ProcessLauncher.h"
 
 #include "Connection.h"
+#include "ProcessExecutablePath.h"
 #include "WebProcess.h"
-#include <QCoreApplication>
 #include <QDebug>
-#include <QFile>
 #include <QLocalServer>
 #include <QMetaType>
 #include <QProcess>
@@ -102,13 +101,9 @@ void QtWebProcess::setupChildProcess()
 
 void ProcessLauncher::launchProcess()
 {
-    QString applicationPath = QLatin1String("%1 %2");
-
-    if (QFile::exists(QCoreApplication::applicationDirPath() + QLatin1String("/QtWebProcess"))) {
-        applicationPath = applicationPath.arg(QCoreApplication::applicationDirPath() + QLatin1String("/QtWebProcess"));
-    } else {
-        applicationPath = applicationPath.arg(QLatin1String("QtWebProcess"));
-    }
+    QString commandLine = QLatin1String("%1 %2");
+    commandLine = commandLine.arg(m_launchOptions.processType == WebProcess ?
+                                  executablePathOfWebProcess() : executablePathOfPluginProcess());
 
 #if OS(DARWIN)
     // Create the listening port.
@@ -124,7 +119,7 @@ void ProcessLauncher::launchProcess()
     kern_return_t kr = bootstrap_register2(bootstrap_port, const_cast<char*>(serviceName.toUtf8().data()), connector, 0);
     ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
 
-    QString program(applicationPath.arg(serviceName));
+    commandLine = commandLine.arg(serviceName);
 #else
     int sockets[2];
     if (socketpair(AF_UNIX, SOCKET_TYPE, 0, sockets) == -1) {
@@ -144,12 +139,12 @@ void ProcessLauncher::launchProcess()
     }
 
     int connector = sockets[1];
-    QString program(applicationPath.arg(sockets[0]));
+    commandLine = commandLine.arg(sockets[0]);
 #endif
 
     QProcess* webProcess = new QtWebProcess();
     webProcess->setProcessChannelMode(QProcess::ForwardedChannels);
-    webProcess->start(program);
+    webProcess->start(commandLine);
 
 #if !OS(DARWIN)
     // Don't expose the web socket to possible future web processes
@@ -163,7 +158,7 @@ void ProcessLauncher::launchProcess()
 #endif
 
     if (!webProcess->waitForStarted()) {
-        qDebug() << "Failed to start" << program;
+        qDebug() << "Failed to start" << commandLine;
         ASSERT_NOT_REACHED();
 #if OS(DARWIN)
         mach_port_deallocate(mach_task_self(), connector);
index e509e97..0a51d9b 100644 (file)
@@ -52,6 +52,14 @@ class WebPluginSiteDataManager;
 class WebProcessProxy;
 struct PluginProcessCreationParameters;
 
+#if PLUGIN_ARCHITECTURE(X11)
+struct RawPluginMetaData {
+    String name;
+    String description;
+    String mimeDescription;
+};
+#endif
+
 class PluginProcessProxy : public RefCounted<PluginProcessProxy>, CoreIPC::Connection::Client, ProcessLauncher::Client {
 public:
     static PassRefPtr<PluginProcessProxy> create(PluginProcessManager*, const PluginModuleInfo&);
@@ -80,6 +88,10 @@ public:
     static bool createPropertyListFile(const PluginModuleInfo&);
 #endif
 
+#if PLUGIN_ARCHITECTURE(X11)
+    static bool scanPlugin(const String& pluginPath, RawPluginMetaData& result);
+#endif
+
 private:
     PluginProcessProxy(PluginProcessManager*, const PluginModuleInfo&);
 
index 4c85772..653c729 100644 (file)
 #if ENABLE(PLUGIN_PROCESS)
 
 #include "PluginProcessCreationParameters.h"
-#include <WebCore/NotImplemented.h>
+#include "ProcessExecutablePath.h"
+#include <WebCore/FileSystem.h>
+#include <glib.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+using namespace WebCore;
 
 namespace WebKit {
 
-void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters& parameters)
+void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters&)
+{
+}
+
+bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& result)
 {
-    notImplemented();
+    CString binaryPath = fileSystemRepresentation(executablePathOfPluginProcess());
+    CString pluginPathCString = fileSystemRepresentation(pluginPath);
+    char* argv[4];
+    argv[0] = const_cast<char*>(binaryPath.data());
+    argv[1] = const_cast<char*>("-scanPlugin");
+    argv[2] = const_cast<char*>(pluginPathCString.data());
+    argv[3] = 0;
+
+    gint status;
+    gchar* stdOut;
+    if (!g_spawn_sync(0, argv, 0, G_SPAWN_STDERR_TO_DEV_NULL, 0, 0, &stdOut, 0, &status, 0))
+        return false;
+    if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS)
+        return false;
+
+    const unsigned kNumLinesExpected = 3;
+    String lines[kNumLinesExpected];
+    unsigned lineIndex = 0;
+    const UChar* current = reinterpret_cast<const UChar*>(stdOut);
+    while (lineIndex < kNumLinesExpected) {
+        const UChar* start = current;
+        while (*current++ != UChar('\n')) { }
+        lines[lineIndex++] = String(start, current - start - 1);
+    }
+
+    result.name.swap(lines[0]);
+    result.description.swap(lines[1]);
+    result.mimeDescription.swap(lines[2]);
+    return !result.mimeDescription.isEmpty();
 }
 
 } // namespace WebKit
index cc521e0..9b7f2b2 100644 (file)
 
 #if ENABLE(PLUGIN_PROCESS)
 
-#include "PluginProcessCreationParameters.h"
-#include <WebCore/NotImplemented.h>
+#include "ProcessExecutablePath.h"
+#include <QByteArray>
+#include <QCoreApplication>
+#include <QDir>
+#include <QEventLoop>
+#include <QProcess>
+#include <QString>
 
 namespace WebKit {
 
-void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters& parameters)
+class PluginProcessCreationParameters;
+
+void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters&)
 {
-    notImplemented();
+}
+
+bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& result)
+{
+    QString commandLine = QLatin1String("%1 %2 %3");
+    commandLine = commandLine.arg(executablePathOfPluginProcess());
+    commandLine = commandLine.arg(QStringLiteral("-scanPlugin")).arg(static_cast<QString>(pluginPath));
+
+    QProcess process;
+    process.setReadChannel(QProcess::StandardOutput);
+    process.start(commandLine);
+
+    if (!process.waitForFinished()
+        || process.exitStatus() != QProcess::NormalExit
+        || process.exitCode() != EXIT_SUCCESS) {
+        process.kill();
+        return false;
+    }
+
+    QByteArray outputBytes = process.readAll();
+    ASSERT(!(outputBytes.size() % sizeof(UChar)));
+
+    String output(reinterpret_cast<const UChar*>(outputBytes.constData()), outputBytes.size() / sizeof(UChar));
+    Vector<String> lines;
+    output.split(UChar('\n'), lines);
+    ASSERT(lines.size() == 3);
+
+    result.name.swap(lines[0]);
+    result.description.swap(lines[1]);
+    result.mimeDescription.swap(lines[2]);
+    return !result.mimeDescription.isEmpty();
 }
 
 } // namespace WebKit
index 64c624f..12a58d2 100644 (file)
@@ -551,23 +551,9 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value)
            break;
 
        case NPNVToolkit: {
-#if PLATFORM(GTK)
-           *reinterpret_cast<uint32_t*>(value) = 2;
-#else
-           const uint32_t expectedGTKToolKitVersion = 2;
-
-           // Set the expected GTK version if we know that this plugin needs it or if the plugin call us
-           // with a null instance. The latter is the case with NSPluginWrapper plugins.
-           bool requiresGTKToolKitVersion;
-           if (!npp)
-               requiresGTKToolKitVersion = true;
-           else {
-               RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
-               requiresGTKToolKitVersion = plugin->quirks().contains(PluginQuirks::RequiresGTKToolKit);
-           }
-
-           *reinterpret_cast<uint32_t*>(value) = requiresGTKToolKitVersion ? expectedGTKToolKitVersion : 0;
-#endif
+           // Gtk based plugins need to be assured about the toolkit version.
+           const uint32_t expectedGtkToolKitVersion = 2;
+           *reinterpret_cast<uint32_t*>(value) = expectedGtkToolKitVersion;
            break;
        }
 
diff --git a/Source/WebKit2/qt/PluginMainQt.cpp b/Source/WebKit2/qt/PluginMainQt.cpp
new file mode 100644 (file)
index 0000000..3d5c93b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 University of Szeged. All rights reserved.
+ *
+ * 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 <QLibrary>
+#include <QtGlobal>
+
+namespace WebKit {
+Q_DECL_IMPORT int PluginProcessMain(int argc, char** argv);
+}
+
+int main(int argc, char** argv)
+{
+    return WebKit::PluginProcessMain(argc, argv);
+}
index 7db0d51..7aa4a69 100644 (file)
@@ -1,3 +1,13 @@
+2012-04-02  Balazs Kelemen  <kbalazs@webkit.org>
+
+        [Qt][WK2] Set up plugin process on Unix
+        https://bugs.webkit.org/show_bug.cgi?id=72121
+
+        Reviewed by Simon Hausmann.
+
+        * qmake/mkspecs/features/features.prf: Reenable plugins
+        and turn on plugin process.
+
 2012-04-02  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r112868, r112879, and r112881.
index d28d9e4..3388290 100644 (file)
@@ -32,7 +32,8 @@ nodist_Programs_MiniBrowser_SOURCES = \
 Programs_MiniBrowser_LDADD = \
        libwebkit2gtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \
        $(GLIB_LIBS) \
-       $(GTK_LIBS)
+       $(GTK_LIBS) \
+       $(LIBSOUP_LIBS)
 
 Programs_MiniBrowser_LDFLAGS = \
        -no-fast-install \
index d85c7dc..2ec07e0 100644 (file)
@@ -127,12 +127,11 @@ haveQt(5) {
     no_webkit2 {
         DEFINES += PLUGIN_ARCHITECTURE_UNSUPPORTED=1
     } else {
-        # Disable xlib plugins while they're in-process, because they crash
-        # as soon as an installed npapi plugin uses Qt 4.
-        false:contains(QT_CONFIG, xcb-xlib) {
+        contains(QT_CONFIG, xcb-xlib) {
             CONFIG += plugin_backend_xlib
             DEFINES += PLUGIN_ARCHITECTURE_X11=1 \
-                       PLUGIN_ARCHITECTURE_UNSUPPORTED=0
+                       PLUGIN_ARCHITECTURE_UNSUPPORTED=0 \
+                       ENABLE_PLUGIN_PROCESS=1
         } else {
             DEFINES += PLUGIN_ARCHITECTURE_UNSUPPORTED=1
         }