[GStreamer] Crashes during plugin installation
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Jul 2015 12:06:34 +0000 (12:06 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Jul 2015 12:06:34 +0000 (12:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144099

Reviewed by Philippe Normand.

Source/WebCore:

Add new methods to MediaPlayerClient and ChromeClient to request
the API layer to start the installer when there are missing media
plugins.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::requestInstallMissingPlugins): Pass
the request to the ChromeClient.
* html/HTMLMediaElement.h:
* page/ChromeClient.h:
* platform/graphics/MediaPlayer.h:
(WebCore::MediaPlayerClient::requestInstallMissingPlugins):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer):
Invalidate any pending request to install missing media plugins.
(WebCore::MediaPlayerPrivateGStreamer::handleMessage): In case of
missing plugins message, start a request to install them if
supported by GST.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
(WebCore::MediaPlayerRequestInstallMissingPluginsCallback::create):
(WebCore::MediaPlayerRequestInstallMissingPluginsCallback::MediaPlayerRequestInstallMissingPluginsCallback):
(WebCore::MediaPlayerRequestInstallMissingPluginsCallback::invalidate):
(WebCore::MediaPlayerRequestInstallMissingPluginsCallback::complete):

Source/WebKit2:

Move the missing plugins installation to the UI process, ensuring
there's a single installer running and cancelling the request when
the page is closed or the media player is deleted.

* PlatformEfl.cmake: Add new files to compilation.
* PlatformGTK.cmake: Ditto.
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in: Add
RequestInstallMissingMediaPlugins message.
* UIProcess/gstreamer/WebPageProxyGStreamer.cpp: Added.
(WebKit::WebPageProxy::requestInstallMissingMediaPlugins): Call
gst_install_plugins_async() and send
DidEndRequestInstallMissingMediaPlugins message back to the web
process when done.
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::requestInstallMissingMediaPlugins): Call
WebPage::requestInstallMissingMediaPlugins().
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::close): Invalidate the install missing plugins
request callback.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in: Add
DidEndRequestInstallMissingMediaPlugins message.
* WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp: Added.
(WebKit::WebPage::requestInstallMissingMediaPlugins): Send
RequestInstallMissingMediaPlugins to the UI process or complete
the request early if there's already a request in progress.
(WebKit::WebPage::didEndRequestInstallMissingMediaPlugins):
Complete the request.

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

20 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/page/ChromeClient.h
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
Source/WebCore/platform/graphics/gstreamer/MediaPlayerRequestInstallMissingPluginsCallback.h [new file with mode: 0644]
Source/WebKit2/ChangeLog
Source/WebKit2/PlatformEfl.cmake
Source/WebKit2/PlatformGTK.cmake
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/UIProcess/gstreamer/WebPageProxyGStreamer.cpp [new file with mode: 0644]
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Source/WebKit2/WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp [new file with mode: 0644]

index 880ba18..c7ad3c8 100644 (file)
@@ -1,3 +1,33 @@
+2015-07-24  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GStreamer] Crashes during plugin installation
+        https://bugs.webkit.org/show_bug.cgi?id=144099
+
+        Reviewed by Philippe Normand.
+
+        Add new methods to MediaPlayerClient and ChromeClient to request
+        the API layer to start the installer when there are missing media
+        plugins.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::requestInstallMissingPlugins): Pass
+        the request to the ChromeClient.
+        * html/HTMLMediaElement.h:
+        * page/ChromeClient.h:
+        * platform/graphics/MediaPlayer.h:
+        (WebCore::MediaPlayerClient::requestInstallMissingPlugins):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer):
+        Invalidate any pending request to install missing media plugins.
+        (WebCore::MediaPlayerPrivateGStreamer::handleMessage): In case of
+        missing plugins message, start a request to install them if
+        supported by GST.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+        (WebCore::MediaPlayerRequestInstallMissingPluginsCallback::create):
+        (WebCore::MediaPlayerRequestInstallMissingPluginsCallback::MediaPlayerRequestInstallMissingPluginsCallback):
+        (WebCore::MediaPlayerRequestInstallMissingPluginsCallback::invalidate):
+        (WebCore::MediaPlayerRequestInstallMissingPluginsCallback::complete):
+
 2015-07-23  Alex Christensen  <achristensen@webkit.org>
 
         [Win] Unreviewed build fix after r187245.
index 7b2deaa..fad5fe2 100644 (file)
@@ -6066,6 +6066,16 @@ double HTMLMediaElement::mediaPlayerRequestedPlaybackRate() const
     return potentiallyPlaying() ? requestedPlaybackRate() : 0;
 }
 
+#if USE(GSTREAMER)
+void HTMLMediaElement::requestInstallMissingPlugins(const String& details, MediaPlayerRequestInstallMissingPluginsCallback& callback)
+{
+    if (!document().page())
+        return;
+
+    document().page()->chrome().client().requestInstallMissingMediaPlugins(details, callback);
+}
+#endif
+
 void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
 {
     MediaElementSession::BehaviorRestrictions restrictionsToRemove = MediaElementSession::RequireUserGestureForLoad
index 940b615..cf7b82e 100644 (file)
@@ -610,6 +610,10 @@ private:
     virtual double mediaPlayerRequestedPlaybackRate() const override final;
     virtual VideoFullscreenMode mediaPlayerFullscreenMode() const override final { return fullscreenMode(); }
 
+#if USE(GSTREAMER)
+    virtual void requestInstallMissingPlugins(const String&, MediaPlayerRequestInstallMissingPluginsCallback&) override final;
+#endif
+
     void pendingActionTimerFired();
     void progressEventTimerFired();
     void playbackProgressTimerFired();
index 5fc116e..abc6b94 100644 (file)
@@ -91,6 +91,10 @@ class SecurityOrigin;
 class ViewportConstraints;
 class Widget;
 
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+class MediaPlayerRequestInstallMissingPluginsCallback;
+#endif
+
 struct DateTimeChooserParameters;
 struct FrameLoadRequest;
 struct GraphicsDeviceAdapter;
@@ -451,6 +455,9 @@ public:
 
 #if ENABLE(VIDEO)
     virtual void mediaDocumentNaturalSizeChanged(const WebCore::IntSize&) { }
+#if USE(GSTREAMER)
+    virtual void requestInstallMissingMediaPlugins(const String& /*details*/, MediaPlayerRequestInstallMissingPluginsCallback&) { };
+#endif
 #endif
 
 protected:
index df0bcd8..00380f2 100644 (file)
@@ -148,6 +148,10 @@ struct MediaPlayerFactory;
 struct GraphicsDeviceAdapter;
 #endif
 
+#if USE(GSTREAMER)
+class MediaPlayerRequestInstallMissingPluginsCallback;
+#endif
+
 class MediaPlayerClient {
 public:
     virtual ~MediaPlayerClient() { }
@@ -278,6 +282,10 @@ public:
     virtual double mediaPlayerRequestedPlaybackRate() const { return 0; }
     virtual MediaPlayerEnums::VideoFullscreenMode mediaPlayerFullscreenMode() const { return MediaPlayerEnums::VideoFullscreenModeNone; }
     virtual Vector<String> mediaPlayerPreferredAudioCharacteristics() const { return Vector<String>(); }
+
+#if USE(GSTREAMER)
+    virtual void requestInstallMissingPlugins(const String&, MediaPlayerRequestInstallMissingPluginsCallback&) { };
+#endif
 };
 
 class MediaPlayerSupportsTypeClient {
index ffc946e..8929f2e 100644 (file)
@@ -31,6 +31,7 @@
 #include "URL.h"
 #include "MIMETypeRegistry.h"
 #include "MediaPlayer.h"
+#include "MediaPlayerRequestInstallMissingPluginsCallback.h"
 #include "NotImplemented.h"
 #include "SecurityOrigin.h"
 #include "TimeRanges.h"
@@ -123,12 +124,6 @@ static GstFlowReturn mediaPlayerPrivateNewTextSampleCallback(GObject*, MediaPlay
 }
 #endif
 
-static void mediaPlayerPrivatePluginInstallerResultFunction(GstInstallPluginsReturn result, gpointer userData)
-{
-    MediaPlayerPrivateGStreamer* player = reinterpret_cast<MediaPlayerPrivateGStreamer*>(userData);
-    player->handlePluginInstallerResult(result);
-}
-
 void MediaPlayerPrivateGStreamer::setAudioStreamProperties(GObject* object)
 {
     if (g_strcmp0(G_OBJECT_TYPE_NAME(object), "GstPulseSink"))
@@ -216,7 +211,6 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player)
     , m_audioSourceProvider(std::make_unique<AudioSourceProviderGStreamer>())
 #endif
     , m_requestedState(GST_STATE_VOID_PENDING)
-    , m_missingPlugins(false)
 {
 }
 
@@ -245,6 +239,10 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
             reinterpret_cast<gpointer>(setAudioStreamPropertiesCallback), this);
 
     m_readyTimerHandler.cancel();
+    if (m_missingPluginsCallback) {
+        m_missingPluginsCallback->invalidate();
+        m_missingPluginsCallback = nullptr;
+    }
 
     if (m_pipeline) {
         GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline.get())));
@@ -934,7 +932,7 @@ gboolean MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
     case GST_MESSAGE_ERROR:
         if (m_resetPipeline)
             break;
-        if (m_missingPlugins)
+        if (m_missingPluginsCallback)
             break;
         gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
         ERROR_MEDIA_MESSAGE("Error %d: %s (url=%s)", err->code, err->message, m_url.string().utf8().data());
@@ -1029,11 +1027,18 @@ gboolean MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
         break;
     case GST_MESSAGE_ELEMENT:
         if (gst_is_missing_plugin_message(message)) {
-            gchar* detail = gst_missing_plugin_message_get_installer_detail(message);
-            gchar* detailArray[2] = {detail, 0};
-            GstInstallPluginsReturn result = gst_install_plugins_async(detailArray, 0, mediaPlayerPrivatePluginInstallerResultFunction, this);
-            m_missingPlugins = result == GST_INSTALL_PLUGINS_STARTED_OK;
-            g_free(detail);
+            GUniquePtr<char> detail(gst_missing_plugin_message_get_installer_detail(message));
+            if (gst_install_plugins_supported()) {
+                m_missingPluginsCallback = MediaPlayerRequestInstallMissingPluginsCallback::create([this](uint32_t result) {
+                    m_missingPluginsCallback = nullptr;
+                    if (result != GST_INSTALL_PLUGINS_SUCCESS)
+                        return;
+
+                    changePipelineState(GST_STATE_READY);
+                    changePipelineState(GST_STATE_PAUSED);
+                });
+                m_player->client().requestInstallMissingPlugins(String::fromUTF8(detail.get()), *m_missingPluginsCallback);
+            }
         }
 #if ENABLE(VIDEO_TRACK) && USE(GSTREAMER_MPEGTS)
         else {
@@ -1058,15 +1063,6 @@ gboolean MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
     return TRUE;
 }
 
-void MediaPlayerPrivateGStreamer::handlePluginInstallerResult(GstInstallPluginsReturn result)
-{
-    m_missingPlugins = false;
-    if (result == GST_INSTALL_PLUGINS_SUCCESS) {
-        changePipelineState(GST_STATE_READY);
-        changePipelineState(GST_STATE_PAUSED);
-    }
-}
-
 void MediaPlayerPrivateGStreamer::processBufferingStats(GstMessage* message)
 {
     m_buffering = true;
index 8909d3b..2641847 100644 (file)
@@ -58,6 +58,7 @@ class AudioSourceProviderGStreamer;
 class AudioTrackPrivateGStreamer;
 class InbandMetadataTextTrackPrivateGStreamer;
 class InbandTextTrackPrivateGStreamer;
+class MediaPlayerRequestInstallMissingPluginsCallback;
 class VideoTrackPrivateGStreamer;
 
 class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateGStreamerBase {
@@ -234,7 +235,7 @@ private:
 #endif
     GstState m_requestedState;
     GRefPtr<GstElement> m_autoAudioSink;
-    bool m_missingPlugins;
+    RefPtr<MediaPlayerRequestInstallMissingPluginsCallback> m_missingPluginsCallback;
 #if ENABLE(VIDEO_TRACK)
     Vector<RefPtr<AudioTrackPrivateGStreamer>> m_audioTracks;
     Vector<RefPtr<InbandTextTrackPrivateGStreamer>> m_textTracks;
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerRequestInstallMissingPluginsCallback.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerRequestInstallMissingPluginsCallback.h
new file mode 100644 (file)
index 0000000..d867e91
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * aint with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef MediaPlayerRequestInstallMissingPluginsCallback_h
+#define MediaPlayerRequestInstallMissingPluginsCallback_h
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class MediaPlayerRequestInstallMissingPluginsCallback : public RefCounted<MediaPlayerRequestInstallMissingPluginsCallback> {
+    WTF_MAKE_FAST_ALLOCATED();
+public:
+    static Ref<MediaPlayerRequestInstallMissingPluginsCallback> create(std::function<void (uint32_t)>&& function)
+    {
+        return adoptRef(*new MediaPlayerRequestInstallMissingPluginsCallback(WTF::move(function)));
+    }
+
+    void invalidate()
+    {
+        m_function = nullptr;
+    }
+
+    void complete(uint32_t result)
+    {
+        if (!m_function)
+            return;
+        m_function(result);
+        m_function = nullptr;
+    }
+
+private:
+    MediaPlayerRequestInstallMissingPluginsCallback(std::function<void (uint32_t)>&& function)
+        : m_function(WTF::move(function))
+    {
+    }
+
+    std::function<void (uint32_t)> m_function;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(VIDEO) && USE(GSTREAMER)
+#endif // MediaPlayerRequestInstallMissingPluginsCallback_h
index 6c2eef2..d433627 100644 (file)
@@ -1,5 +1,43 @@
 2015-07-24  Carlos Garcia Campos  <cgarcia@igalia.com>
 
+        [GStreamer] Crashes during plugin installation
+        https://bugs.webkit.org/show_bug.cgi?id=144099
+
+        Reviewed by Philippe Normand.
+
+        Move the missing plugins installation to the UI process, ensuring
+        there's a single installer running and cancelling the request when
+        the page is closed or the media player is deleted.
+
+        * PlatformEfl.cmake: Add new files to compilation.
+        * PlatformGTK.cmake: Ditto.
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in: Add
+        RequestInstallMissingMediaPlugins message.
+        * UIProcess/gstreamer/WebPageProxyGStreamer.cpp: Added.
+        (WebKit::WebPageProxy::requestInstallMissingMediaPlugins): Call
+        gst_install_plugins_async() and send
+        DidEndRequestInstallMissingMediaPlugins message back to the web
+        process when done.
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::requestInstallMissingMediaPlugins): Call
+        WebPage::requestInstallMissingMediaPlugins().
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::close): Invalidate the install missing plugins
+        request callback.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in: Add
+        DidEndRequestInstallMissingMediaPlugins message.
+        * WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp: Added.
+        (WebKit::WebPage::requestInstallMissingMediaPlugins): Send
+        RequestInstallMissingMediaPlugins to the UI process or complete
+        the request early if there's already a request in progress.
+        (WebKit::WebPage::didEndRequestInstallMissingMediaPlugins):
+        Complete the request.
+
+2015-07-24  Carlos Garcia Campos  <cgarcia@igalia.com>
+
         Unreviewed. Fix the build with MEDIA_STREAM disabled after r187282.
 
         RealtimeMediaSource is only defined when MEDIA_STREAM is enabled.
index e872da7..adbbf34 100644 (file)
@@ -183,6 +183,8 @@ list(APPEND WebKit2_SOURCES
     UIProcess/efl/WebUIPopupMenuClient.cpp
     UIProcess/efl/WebViewEfl.cpp
 
+    UIProcess/gstreamer/WebPageProxyGStreamer.cpp
+
     UIProcess/soup/WebCookieManagerProxySoup.cpp
     UIProcess/soup/WebProcessPoolSoup.cpp
 
@@ -216,6 +218,8 @@ list(APPEND WebKit2_SOURCES
     WebProcess/WebPage/efl/WebInspectorUIEfl.cpp
     WebProcess/WebPage/efl/WebPageEfl.cpp
 
+    WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp
+
     WebProcess/efl/ExtensionManagerEfl.cpp
     WebProcess/efl/SeccompFiltersWebProcessEfl.cpp
     WebProcess/efl/WebProcessMainEfl.cpp
@@ -286,6 +290,7 @@ list(APPEND WebKit2_SYSTEM_INCLUDE_DIRECTORIES
     ${EO_INCLUDE_DIRS}
     ${EVAS_INCLUDE_DIRS}
     ${GLIB_INCLUDE_DIRS}
+    ${GSTREAMER_INCLUDE_DIRS}
     ${HARFBUZZ_INCLUDE_DIRS}
     ${LIBSOUP_INCLUDE_DIRS}
     ${LIBXML2_INCLUDE_DIR}
index 41dd445..6113e61 100644 (file)
@@ -290,6 +290,8 @@ list(APPEND WebKit2_SOURCES
 
     UIProcess/cairo/BackingStoreCairo.cpp
 
+    UIProcess/gstreamer/WebPageProxyGStreamer.cpp
+
     UIProcess/gtk/DragAndDropHandler.cpp
     UIProcess/gtk/ExperimentalFeatures.cpp
     UIProcess/gtk/GestureController.cpp
@@ -341,6 +343,8 @@ list(APPEND WebKit2_SOURCES
 
     WebProcess/WebPage/atk/WebPageAccessibilityObjectAtk.cpp
 
+    WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp
+
     WebProcess/WebPage/gtk/PrinterListGtk.cpp
     WebProcess/WebPage/gtk/WebInspectorUIGtk.cpp
     WebProcess/WebPage/gtk/WebPageGtk.cpp
@@ -515,6 +519,7 @@ list(APPEND WebKit2_SYSTEM_INCLUDE_DIRECTORIES
     ${CAIRO_INCLUDE_DIRS}
     ${ENCHANT_INCLUDE_DIRS}
     ${GEOCLUE_INCLUDE_DIRS}
+    ${GSTREAMER_INCLUDE_DIRS}
     ${HARFBUZZ_INCLUDE_DIRS}
     ${LIBSOUP_INCLUDE_DIRS}
 )
index 21d2288..38d3c8e 100644 (file)
@@ -1479,6 +1479,9 @@ private:
 
 #if ENABLE(VIDEO)
     void mediaDocumentNaturalSizeChanged(const WebCore::IntSize&);
+#if USE(GSTREAMER)
+    void requestInstallMissingMediaPlugins(const String& details);
+#endif
 #endif
 
     void handleAutoFillButtonClick(const UserData&);
index f32bb7a..42fc961 100644 (file)
@@ -450,4 +450,8 @@ messages -> WebPageProxy {
 
     UseFixedLayoutDidChange(bool useFixedLayout)
     FixedLayoutSizeDidChange(WebCore::IntSize fixedLayoutSize)
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+    RequestInstallMissingMediaPlugins(String details)
+#endif
 }
diff --git a/Source/WebKit2/UIProcess/gstreamer/WebPageProxyGStreamer.cpp b/Source/WebKit2/UIProcess/gstreamer/WebPageProxyGStreamer.cpp
new file mode 100644 (file)
index 0000000..0739fbb
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 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 "WebPageProxy.h"
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+
+#include "WebPageMessages.h"
+#include <gst/pbutils/install-plugins.h>
+
+namespace WebKit {
+
+void WebPageProxy::requestInstallMissingMediaPlugins(const String& details)
+{
+    CString detail = details.utf8();
+    const char* detailArray[2] = { detail.data(), nullptr };
+    ref();
+    // FIXME: Use a proper GstInstallPluginsContext instead of nullptr.
+    GstInstallPluginsReturn result = gst_install_plugins_async(detailArray, nullptr, [](GstInstallPluginsReturn result, gpointer userData) {
+        RefPtr<WebPageProxy> page = adoptRef(static_cast<WebPageProxy*>(userData));
+        if (page->isValid())
+            page->send(Messages::WebPage::DidEndRequestInstallMissingMediaPlugins(static_cast<uint32_t>(result)));
+    }, this);
+
+    if (result != GST_INSTALL_PLUGINS_STARTED_OK) {
+        // If the installer didn't start, the callback will not be called, so remove the ref manually.
+        deref();
+        send(Messages::WebPage::DidEndRequestInstallMissingMediaPlugins(static_cast<uint32_t>(result)));
+        WTFLogAlways("Missing GStreamer Plugin: %s\n", detail.data());
+    }
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(VIDEO) && USE(GSTREAMER)
index 5dfb18b..1b2f3e2 100644 (file)
@@ -1163,6 +1163,13 @@ void WebChromeClient::mediaDocumentNaturalSizeChanged(const WebCore::IntSize& ne
 {
     m_page->mediaDocumentNaturalSizeChanged(newSize);
 }
+
+#if USE(GSTREAMER)
+void WebChromeClient::requestInstallMissingMediaPlugins(const String& details, WebCore::MediaPlayerRequestInstallMissingPluginsCallback& callback)
+{
+    m_page->requestInstallMissingMediaPlugins(details, callback);
+}
 #endif
+#endif // ENABLE(VIDEO)
 
 } // namespace WebKit
index 8af49b1..280e0b0 100644 (file)
@@ -325,6 +325,9 @@ private:
 
 #if ENABLE(VIDEO)
     virtual void mediaDocumentNaturalSizeChanged(const WebCore::IntSize&) override;
+#if USE(GSTREAMER)
+    virtual void requestInstallMissingMediaPlugins(const String&, WebCore::MediaPlayerRequestInstallMissingPluginsCallback&) override;
+#endif
 #endif
 
     String m_cachedToolTip;
index 94684d4..aa20dc4 100644 (file)
 #include "CoordinatedLayerTreeHostMessages.h"
 #endif
 
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+#include <WebCore/MediaPlayerRequestInstallMissingPluginsCallback.h>
+#endif
+
 using namespace JSC;
 using namespace WebCore;
 
@@ -964,6 +968,13 @@ void WebPage::close()
     }
 #endif
 
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+    if (m_installMediaPluginsCallback) {
+        m_installMediaPluginsCallback->invalidate();
+        m_installMediaPluginsCallback = nullptr;
+    }
+#endif
+
     m_sandboxExtensionTracker.invalidate();
 
 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
index f46fda6..bc87c6a 100644 (file)
@@ -139,6 +139,10 @@ struct Highlight;
 struct KeypressCommand;
 struct MediaPlaybackTargetContext;
 struct TextCheckingResult;
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+class MediaPlayerRequestInstallMissingPluginsCallback;
+#endif
 }
 
 namespace WebKit {
@@ -904,6 +908,9 @@ public:
 
 #if ENABLE(VIDEO)
     void mediaDocumentNaturalSizeChanged(const WebCore::IntSize&);
+#if USE(GSTREAMER)
+    void requestInstallMissingMediaPlugins(const String& details, WebCore::MediaPlayerRequestInstallMissingPluginsCallback&);
+#endif
 #endif
 
 private:
@@ -1153,6 +1160,10 @@ private:
 
     void pageStoppedScrolling();
 
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+    void didEndRequestInstallMissingMediaPlugins(uint32_t result);
+#endif
+
     uint64_t m_pageID;
 
     std::unique_ptr<WebCore::Page> m_page;
@@ -1402,6 +1413,10 @@ private:
 #if PLATFORM(GTK)
     bool m_inputMethodEnabled { false };
 #endif
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+    RefPtr<WebCore::MediaPlayerRequestInstallMissingPluginsCallback> m_installMediaPluginsCallback;
+#endif
 };
 
 } // namespace WebKit
index 918e7de..c420cd3 100644 (file)
@@ -435,4 +435,8 @@ messages -> WebPage LegacyReceiver {
     ClearWheelEventTestTrigger()
     SetShouldScaleViewToFitDocument(bool shouldScaleViewToFitDocument)
     SetUserContentExtensionsEnabled(bool userContentExtensionsEnabled)
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+    DidEndRequestInstallMissingMediaPlugins(uint32_t result)
+#endif
 }
diff --git a/Source/WebKit2/WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp b/Source/WebKit2/WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp
new file mode 100644 (file)
index 0000000..f5a45ff
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 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 "WebPage.h"
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+
+#include "WebPageProxyMessages.h"
+#include <WebCore/MediaPlayerRequestInstallMissingPluginsCallback.h>
+#include <gst/pbutils/install-plugins.h>
+
+namespace WebKit {
+
+void WebPage::requestInstallMissingMediaPlugins(const String& details, WebCore::MediaPlayerRequestInstallMissingPluginsCallback& callback)
+{
+    if (m_installMediaPluginsCallback) {
+        callback.complete(GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS);
+        return;
+    }
+
+    m_installMediaPluginsCallback = &callback;
+    send(Messages::WebPageProxy::RequestInstallMissingMediaPlugins(details));
+}
+
+void WebPage::didEndRequestInstallMissingMediaPlugins(uint32_t result)
+{
+    if (!m_installMediaPluginsCallback)
+        return;
+
+    m_installMediaPluginsCallback->complete(result);
+    m_installMediaPluginsCallback = nullptr;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(VIDEO) && USE(GSTREAMER)