Changeset 251181 in webkit


Ignore:
Timestamp:
Oct 16, 2019, 12:36:24 AM (7 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK][WPE] Add user messages API
https://bugs.webkit.org/show_bug.cgi?id=202847

Reviewed by Adrian Perez de Castro.

Source/WebCore/platform/gtk/po:

  • POTFILES.in: Add new files containing translatable strings.

Source/WebKit:

We have never exposed an API to send/receive messages to/from Web extensions, to allow applications use their own
IPC. Now, with PSON enabled, it's a lot more difficult to implement the custom IPC on the application side,
because applications need to keep track of all the web processes launched, and the changes of web process in the
web view to send the messages to the right extension. That's already done internally by WebKit, so it would be
easier to provide a simple API so that apps don't need to worry about the web process being used. This patch adds
WebKitUserMessage, a simple message API consisting on a message name, parameters and file descriptors. Messages
can be sent from a WebKitWebContext to all the WebKitWebExtensions, or from a WebKitWebExtension to its
WebKitWebContext, or from a WebKitWebView to its WebKitWebPage (and vice versa).

  • PlatformGTK.cmake:
  • PlatformWPE.cmake:
  • Shared/API/glib/WebKitUserMessage.cpp: Added.

(webkitUserMessageDispose):
(webkitUserMessageGetProperty):
(webkitUserMessageSetProperty):
(webkit_user_message_class_init):
(webkitUserMessageCreate):
(webkitUserMessageGetMessage):
(webkit_user_message_new):
(webkit_user_message_new_with_fd_list):
(webkit_user_message_get_name):
(webkit_user_message_get_parameters):
(webkit_user_message_get_fd_list):
(webkit_user_message_send_reply):

  • Shared/API/glib/WebKitUserMessagePrivate.h: Added.
  • Shared/glib/ArgumentCodersGLib.cpp: Added.

(IPC::encode):
(IPC::decode):

  • Shared/glib/ArgumentCodersGLib.h: Added.
  • Shared/glib/UserMessage.cpp: Added.

(WebKit::UserMessage::encode const):
(WebKit::UserMessage::decode):

  • Shared/glib/UserMessage.h: Added.

(WebKit::UserMessage::UserMessage):

  • SourcesGTK.txt:
  • SourcesWPE.txt:
  • UIProcess/API/glib/WebKitWebContext.cpp:

(webkitWebContextConstructed):
(webkit_web_context_class_init):
(webkit_web_context_send_message_to_all_extensions):

  • UIProcess/API/glib/WebKitWebView.cpp:

(webkit_web_view_class_init):
(webkitWebViewDidReceiveUserMessage):
(webkit_web_view_send_message_to_page):
(webkit_web_view_send_message_to_page_finish):

  • UIProcess/API/glib/WebKitWebViewPrivate.h:
  • UIProcess/API/gtk/WebKitUserMessage.h: Added.
  • UIProcess/API/gtk/WebKitWebContext.h:
  • UIProcess/API/gtk/WebKitWebView.h:
  • UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
  • UIProcess/API/gtk/docs/webkit2gtk-docs.sgml:
  • UIProcess/API/gtk/webkit2.h:
  • UIProcess/API/wpe/APIViewClient.h:

(API::ViewClient::didReceiveUserMessage):

  • UIProcess/API/wpe/PageClientImpl.cpp:

(WebKit::PageClientImpl::sendMessageToWebView):

  • UIProcess/API/wpe/PageClientImpl.h:
  • UIProcess/API/wpe/WPEView.cpp:

(WKWPE::View::didReceiveUserMessage):

  • UIProcess/API/wpe/WPEView.h:
  • UIProcess/API/wpe/WebKitUserMessage.h: Added.
  • UIProcess/API/wpe/WebKitWebContext.h:
  • UIProcess/API/wpe/WebKitWebView.h:
  • UIProcess/API/wpe/docs/wpe-1.0-sections.txt:
  • UIProcess/API/wpe/docs/wpe-docs.sgml:
  • UIProcess/API/wpe/webkit.h:
  • UIProcess/WebPageProxy.h:
  • UIProcess/WebPageProxy.messages.in:
  • UIProcess/WebProcessPool.h:
  • UIProcess/WebProcessProxy.h:
  • UIProcess/WebProcessProxy.messages.in:
  • UIProcess/glib/WebProcessProxyGLib.cpp:

(WebKit::WebProcessProxy::sendMessageToWebContextWithReply):
(WebKit::WebProcessProxy::sendMessageToWebContext):

  • UIProcess/gtk/WebPageProxyGtk.cpp:

(WebKit::WebPageProxy::sendMessageToWebViewWithReply):
(WebKit::WebPageProxy::sendMessageToWebView):

  • UIProcess/wpe/WebPageProxyWPE.cpp:

(WebKit::WebPageProxy::sendMessageToWebViewWithReply):
(WebKit::WebPageProxy::sendMessageToWebView):

  • WebProcess/InjectedBundle/API/glib/WebKitExtensionManager.h:

(WebKit::WebKitExtensionManager::extension const):

  • WebProcess/InjectedBundle/API/glib/WebKitWebExtension.cpp:

(webkitWebExtensionDidReceiveUserMessage):
(webkit_web_extension_send_message_to_context):
(webkit_web_extension_send_message_to_context_finish):

  • WebProcess/InjectedBundle/API/glib/WebKitWebExtensionPrivate.h:
  • WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp:

(webkit_web_page_class_init):
(webkitWebPageDidReceiveUserMessage):
(webkit_web_page_send_message_to_view):
(webkit_web_page_send_message_to_view_finish):

  • WebProcess/InjectedBundle/API/glib/WebKitWebPagePrivate.h:
  • WebProcess/InjectedBundle/API/gtk/WebKitWebExtension.h:
  • WebProcess/InjectedBundle/API/gtk/WebKitWebPage.h:
  • WebProcess/InjectedBundle/API/gtk/webkit-web-extension.h:
  • WebProcess/InjectedBundle/API/wpe/WebKitWebExtension.h:
  • WebProcess/InjectedBundle/API/wpe/WebKitWebPage.h:
  • WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt:
  • WebProcess/InjectedBundle/API/wpe/webkit-web-extension.h:
  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in:
  • WebProcess/WebPage/glib/WebPageGLib.cpp: Added.

(WebKit::WebPage::sendMessageToWebExtensionWithReply):
(WebKit::WebPage::sendMessageToWebExtension):

  • WebProcess/WebProcess.h:
  • WebProcess/WebProcess.messages.in:
  • WebProcess/glib/WebProcessGLib.cpp:

(WebKit::WebProcess::sendMessageToWebExtension):

Tools:

Add a test to check the new API.

  • TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp:

(UserMessageTest::webViewUserMessageReceivedCallback):
(UserMessageTest::webContextUserMessageReceivedCallback):
(UserMessageTest::UserMessageTest):
(UserMessageTest::~UserMessageTest):
(UserMessageTest::sendMessage):
(UserMessageTest::sendMedssageToAllExtensions):
(UserMessageTest::viewUserMessageReceived):
(UserMessageTest::contextUserMessageReceived):
(UserMessageTest::waitUntilViewMessageReceived):
(UserMessageTest::waitUntilContextMessageReceived):
(readFileDescritpor):
(testWebExtensionUserMessages):
(beforeAll):

  • TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp:

(documentLoadedCallback):
(pageMessageReceivedCallback):
(pageCreatedCallback):
(extensionMessageReceivedCallback):
(webkit_web_extension_initialize_with_user_data):

Location:
trunk
Files:
5 added
57 edited
5 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/platform/gtk/po/ChangeLog

    r249634 r251181  
     12019-10-15  Carlos Garcia Campos  <[email protected]>
     2
     3        [GTK][WPE] Add user messages API
     4        https://bugs.webkit.org/show_bug.cgi?id=202847
     5
     6        Reviewed by Adrian Perez de Castro.
     7
     8        * POTFILES.in: Add new files containing translatable strings.
     9
    1102019-09-07  Christian Kirbach  <[email protected]>
    211
  • trunk/Source/WebCore/platform/gtk/po/POTFILES.in

    r245460 r251181  
    88../../../WebKit/Shared/API/glib/WebKitURIRequest.cpp
    99../../../WebKit/Shared/API/glib/WebKitURIResponse.cpp
     10../../../WebKit/Shared/API/glib/WebKitUserMessage.cpp
    1011../../../WebKit/Shared/WebErrors.cpp
    1112../../../WebKit/Shared/gtk/WebErrorsGtk.cpp
     
    4445../../../WebKit/UIProcess/WebsiteData/WebsiteDataRecord.cpp
    4546../../../WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebHitTestResult.cpp
     47../../../WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebExtension.cpp
    4648../../../WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp
  • trunk/Source/WebKit/ChangeLog

    r251179 r251181  
     12019-10-15  Carlos Garcia Campos  <[email protected]>
     2
     3        [GTK][WPE] Add user messages API
     4        https://bugs.webkit.org/show_bug.cgi?id=202847
     5
     6        Reviewed by Adrian Perez de Castro.
     7
     8        We have never exposed an API to send/receive messages to/from Web extensions, to allow applications use their own
     9        IPC. Now, with PSON enabled, it's a lot more difficult to implement the custom IPC on the application side,
     10        because applications need to keep track of all the web processes launched, and the changes of web process in the
     11        web view to send the messages to the right extension. That's already done internally by WebKit, so it would be
     12        easier to provide a simple API so that apps don't need to worry about the web process being used. This patch adds
     13        WebKitUserMessage, a simple message API consisting on a message name, parameters and file descriptors. Messages
     14        can be sent from a WebKitWebContext to all the WebKitWebExtensions, or from a WebKitWebExtension to its
     15        WebKitWebContext, or from a WebKitWebView to its WebKitWebPage (and vice versa).
     16
     17        * PlatformGTK.cmake:
     18        * PlatformWPE.cmake:
     19        * Shared/API/glib/WebKitUserMessage.cpp: Added.
     20        (webkitUserMessageDispose):
     21        (webkitUserMessageGetProperty):
     22        (webkitUserMessageSetProperty):
     23        (webkit_user_message_class_init):
     24        (webkitUserMessageCreate):
     25        (webkitUserMessageGetMessage):
     26        (webkit_user_message_new):
     27        (webkit_user_message_new_with_fd_list):
     28        (webkit_user_message_get_name):
     29        (webkit_user_message_get_parameters):
     30        (webkit_user_message_get_fd_list):
     31        (webkit_user_message_send_reply):
     32        * Shared/API/glib/WebKitUserMessagePrivate.h: Added.
     33        * Shared/glib/ArgumentCodersGLib.cpp: Added.
     34        (IPC::encode):
     35        (IPC::decode):
     36        * Shared/glib/ArgumentCodersGLib.h: Added.
     37        * Shared/glib/UserMessage.cpp: Added.
     38        (WebKit::UserMessage::encode const):
     39        (WebKit::UserMessage::decode):
     40        * Shared/glib/UserMessage.h: Added.
     41        (WebKit::UserMessage::UserMessage):
     42        * SourcesGTK.txt:
     43        * SourcesWPE.txt:
     44        * UIProcess/API/glib/WebKitWebContext.cpp:
     45        (webkitWebContextConstructed):
     46        (webkit_web_context_class_init):
     47        (webkit_web_context_send_message_to_all_extensions):
     48        * UIProcess/API/glib/WebKitWebView.cpp:
     49        (webkit_web_view_class_init):
     50        (webkitWebViewDidReceiveUserMessage):
     51        (webkit_web_view_send_message_to_page):
     52        (webkit_web_view_send_message_to_page_finish):
     53        * UIProcess/API/glib/WebKitWebViewPrivate.h:
     54        * UIProcess/API/gtk/WebKitUserMessage.h: Added.
     55        * UIProcess/API/gtk/WebKitWebContext.h:
     56        * UIProcess/API/gtk/WebKitWebView.h:
     57        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
     58        * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml:
     59        * UIProcess/API/gtk/webkit2.h:
     60        * UIProcess/API/wpe/APIViewClient.h:
     61        (API::ViewClient::didReceiveUserMessage):
     62        * UIProcess/API/wpe/PageClientImpl.cpp:
     63        (WebKit::PageClientImpl::sendMessageToWebView):
     64        * UIProcess/API/wpe/PageClientImpl.h:
     65        * UIProcess/API/wpe/WPEView.cpp:
     66        (WKWPE::View::didReceiveUserMessage):
     67        * UIProcess/API/wpe/WPEView.h:
     68        * UIProcess/API/wpe/WebKitUserMessage.h: Added.
     69        * UIProcess/API/wpe/WebKitWebContext.h:
     70        * UIProcess/API/wpe/WebKitWebView.h:
     71        * UIProcess/API/wpe/docs/wpe-1.0-sections.txt:
     72        * UIProcess/API/wpe/docs/wpe-docs.sgml:
     73        * UIProcess/API/wpe/webkit.h:
     74        * UIProcess/WebPageProxy.h:
     75        * UIProcess/WebPageProxy.messages.in:
     76        * UIProcess/WebProcessPool.h:
     77        * UIProcess/WebProcessProxy.h:
     78        * UIProcess/WebProcessProxy.messages.in:
     79        * UIProcess/glib/WebProcessProxyGLib.cpp:
     80        (WebKit::WebProcessProxy::sendMessageToWebContextWithReply):
     81        (WebKit::WebProcessProxy::sendMessageToWebContext):
     82        * UIProcess/gtk/WebPageProxyGtk.cpp:
     83        (WebKit::WebPageProxy::sendMessageToWebViewWithReply):
     84        (WebKit::WebPageProxy::sendMessageToWebView):
     85        * UIProcess/wpe/WebPageProxyWPE.cpp:
     86        (WebKit::WebPageProxy::sendMessageToWebViewWithReply):
     87        (WebKit::WebPageProxy::sendMessageToWebView):
     88        * WebProcess/InjectedBundle/API/glib/WebKitExtensionManager.h:
     89        (WebKit::WebKitExtensionManager::extension const):
     90        * WebProcess/InjectedBundle/API/glib/WebKitWebExtension.cpp:
     91        (webkitWebExtensionDidReceiveUserMessage):
     92        (webkit_web_extension_send_message_to_context):
     93        (webkit_web_extension_send_message_to_context_finish):
     94        * WebProcess/InjectedBundle/API/glib/WebKitWebExtensionPrivate.h:
     95        * WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp:
     96        (webkit_web_page_class_init):
     97        (webkitWebPageDidReceiveUserMessage):
     98        (webkit_web_page_send_message_to_view):
     99        (webkit_web_page_send_message_to_view_finish):
     100        * WebProcess/InjectedBundle/API/glib/WebKitWebPagePrivate.h:
     101        * WebProcess/InjectedBundle/API/gtk/WebKitWebExtension.h:
     102        * WebProcess/InjectedBundle/API/gtk/WebKitWebPage.h:
     103        * WebProcess/InjectedBundle/API/gtk/webkit-web-extension.h:
     104        * WebProcess/InjectedBundle/API/wpe/WebKitWebExtension.h:
     105        * WebProcess/InjectedBundle/API/wpe/WebKitWebPage.h:
     106        * WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt:
     107        * WebProcess/InjectedBundle/API/wpe/webkit-web-extension.h:
     108        * WebProcess/WebPage/WebPage.h:
     109        * WebProcess/WebPage/WebPage.messages.in:
     110        * WebProcess/WebPage/glib/WebPageGLib.cpp: Added.
     111        (WebKit::WebPage::sendMessageToWebExtensionWithReply):
     112        (WebKit::WebPage::sendMessageToWebExtension):
     113        * WebProcess/WebProcess.h:
     114        * WebProcess/WebProcess.messages.in:
     115        * WebProcess/glib/WebProcessGLib.cpp:
     116        (WebKit::WebProcess::sendMessageToWebExtension):
     117
    11182019-10-15  Wenson Hsieh  <[email protected]>
    2119
  • trunk/Source/WebKit/PlatformGTK.cmake

    r250648 r251181  
    110110    ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitUserContentManager.h
    111111    ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.h
     112    ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitUserMessage.h
    112113    ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitWebContext.h
    113114    ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitWebInspector.h
     
    695696            ${WEBKIT_DIR}/Shared/API/glib/WebKitContextMenuItem.cpp
    696697            ${WEBKIT_DIR}/Shared/API/glib/WebKitHitTestResult.cpp
     698            ${WEBKIT_DIR}/Shared/API/glib/WebKitUserMessage.cpp
    697699            ${WEBKIT_DIR}/Shared/API/glib/WebKitURIRequest.cpp
    698700            ${WEBKIT_DIR}/Shared/API/glib/WebKitURIResponse.cpp
     
    701703            ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitContextMenuItem.h
    702704            ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitHitTestResult.h
     705            ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitUserMessage.h
    703706            ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitURIRequest.h
    704707            ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitURIResponse.h
  • trunk/Source/WebKit/PlatformWPE.cmake

    r250597 r251181  
    135135    ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitUserContentManager.h
    136136    ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitUserMediaPermissionRequest.h
     137    ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitUserMessage.h
    137138    ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitWebContext.h
    138139    ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitWebResource.h
  • trunk/Source/WebKit/Shared/API/glib/WebKitUserMessagePrivate.h

    r251179 r251181  
    11/*
    2  * Copyright (C) 2012 Igalia S.L.
     2 * Copyright (C) 2019 Igalia S.L.
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    2020#pragma once
    2121
    22 #include "InjectedBundle.h"
    23 #include "WebKitWebExtension.h"
     22#include "UserMessage.h"
     23#include "WebKitUserMessage.h"
    2424
    25 WebKitWebExtension* webkitWebExtensionCreate(WebKit::InjectedBundle*);
    26 void webkitWebExtensionSetGarbageCollectOnPageDestroy(WebKitWebExtension*);
     25WebKitUserMessage* webkitUserMessageCreate(WebKit::UserMessage&&);
     26WebKitUserMessage* webkitUserMessageCreate(WebKit::UserMessage&&, CompletionHandler<void(WebKit::UserMessage&&)>&&);
     27WebKit::UserMessage& webkitUserMessageGetMessage(WebKitUserMessage*);
  • trunk/Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp

    r251179 r251181  
    11/*
    2  * Copyright (C) 2017 Igalia S.L.
     2 * Copyright (C) 2019 Igalia S.L.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #pragma once
     26#include "config.h"
     27#include "ArgumentCodersGLib.h"
    2728
    28 typedef struct OpaqueJSContext* JSGlobalContextRef;
     29#include "DataReference.h"
     30#include <glib.h>
     31#include <wtf/text/CString.h>
    2932
    30 namespace WebKit {
    31 class DownloadProxy;
     33namespace IPC {
     34
     35void encode(Encoder& encoder, GVariant* variant)
     36{
     37    if (!variant) {
     38        encoder << CString();
     39        return;
     40    }
     41
     42    encoder << CString(g_variant_get_type_string(variant));
     43    encoder << DataReference(static_cast<const uint8_t*>(g_variant_get_data(variant)), g_variant_get_size(variant));
    3244}
    3345
    34 namespace WKWPE {
    35 class View;
     46Optional<GRefPtr<GVariant>> decode(Decoder& decoder)
     47{
     48    CString variantTypeString;
     49    if (!decoder.decode(variantTypeString))
     50        return WTF::nullopt;
     51
     52    if (variantTypeString.isNull())
     53        return GRefPtr<GVariant>();
     54
     55    if (!g_variant_type_string_is_valid(variantTypeString.data()))
     56        return WTF::nullopt;
     57
     58    DataReference data;
     59    if (!decoder.decode(data))
     60        return WTF::nullopt;
     61
     62    auto* variantType = g_variant_type_new(variantTypeString.data());
     63    GRefPtr<GVariant> variant = g_variant_new_from_data(variantType, data.data(), data.size(), FALSE, nullptr, nullptr);
     64    g_variant_type_free(variantType);
     65    return variant;
    3666}
    3767
    38 namespace API {
    39 
    40 class ViewClient {
    41     WTF_MAKE_FAST_ALLOCATED;
    42 public:
    43     virtual ~ViewClient() = default;
    44 
    45     virtual void frameDisplayed(WKWPE::View&) { }
    46     virtual void handleDownloadRequest(WKWPE::View&, WebKit::DownloadProxy&) { }
    47     virtual void willStartLoad(WKWPE::View&) { }
    48     virtual void didChangePageID(WKWPE::View&) { }
    49 };
    50 
    51 } // namespace API
     68} // namespace IPC
  • trunk/Source/WebKit/Shared/glib/ArgumentCodersGLib.h

    r251179 r251181  
    11/*
    2  * Copyright (C) 2017 Igalia S.L.
     2 * Copyright (C) 2019 Igalia S.L.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 typedef struct OpaqueJSContext* JSGlobalContextRef;
     28#include "ArgumentCoders.h"
     29#include <wtf/glib/GRefPtr.h>
    2930
    30 namespace WebKit {
    31 class DownloadProxy;
    32 }
     31typedef struct _GVariant GVariant;
    3332
    34 namespace WKWPE {
    35 class View;
    36 }
     33namespace IPC {
    3734
    38 namespace API {
     35void encode(Encoder&, GVariant*);
     36Optional<GRefPtr<GVariant>> decode(Decoder&);
    3937
    40 class ViewClient {
    41     WTF_MAKE_FAST_ALLOCATED;
    42 public:
    43     virtual ~ViewClient() = default;
    44 
    45     virtual void frameDisplayed(WKWPE::View&) { }
    46     virtual void handleDownloadRequest(WKWPE::View&, WebKit::DownloadProxy&) { }
    47     virtual void willStartLoad(WKWPE::View&) { }
    48     virtual void didChangePageID(WKWPE::View&) { }
    49 };
    50 
    51 } // namespace API
     38} // namespace IPC
  • trunk/Source/WebKit/Shared/glib/UserMessage.h

    r251179 r251181  
    11/*
    2  * Copyright (C) 2017 Igalia S.L.
     2 * Copyright (C) 2019 Igalia S.L.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 typedef struct OpaqueJSContext* JSGlobalContextRef;
     28#include <wtf/Vector.h>
     29#include <wtf/glib/GRefPtr.h>
     30#include <wtf/text/CString.h>
     31
     32typedef struct _GUnixFDList GUnixFDList;
     33typedef struct _GVariant GVariant;
     34
     35namespace IPC {
     36class Decoder;
     37class Encoder;
     38}
    2939
    3040namespace WebKit {
    31 class DownloadProxy;
    32 }
    3341
    34 namespace WKWPE {
    35 class View;
    36 }
     42struct UserMessage {
     43    enum class Type { Null, Message, Error };
    3744
    38 namespace API {
     45    UserMessage()
     46        : type(Type::Null)
     47    {
     48    }
    3949
    40 class ViewClient {
    41     WTF_MAKE_FAST_ALLOCATED;
    42 public:
    43     virtual ~ViewClient() = default;
     50    UserMessage(const CString& name, uint32_t errorCode)
     51        : type(Type::Error)
     52        , name(name)
     53        , errorCode(errorCode)
     54    {
     55    }
    4456
    45     virtual void frameDisplayed(WKWPE::View&) { }
    46     virtual void handleDownloadRequest(WKWPE::View&, WebKit::DownloadProxy&) { }
    47     virtual void willStartLoad(WKWPE::View&) { }
    48     virtual void didChangePageID(WKWPE::View&) { }
     57    void encode(IPC::Encoder&) const;
     58    static Optional<UserMessage> decode(IPC::Decoder&);
     59
     60    Type type { Type::Null };
     61    CString name;
     62    GRefPtr<GVariant> parameters;
     63    GRefPtr<GUnixFDList> fileDescriptors;
     64    uint32_t errorCode { 0 };
    4965};
    5066
    51 } // namespace API
     67}
  • trunk/Source/WebKit/SourcesGTK.txt

    r250597 r251181  
    6868Shared/API/glib/WebKitURIRequest.cpp @no-unify
    6969Shared/API/glib/WebKitURIResponse.cpp @no-unify
     70Shared/API/glib/WebKitUserMessage.cpp @no-unify
    7071
    7172Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp
     
    8384Shared/cairo/ShareableBitmapCairo.cpp
    8485
     86Shared/glib/ArgumentCodersGLib.cpp
    8587Shared/glib/ProcessExecutablePathGLib.cpp
     88Shared/glib/UserMessage.cpp
    8689Shared/glib/WebContextMenuItemGlib.cpp
    8790
     
    405408WebProcess/WebPage/atk/WebKitWebPageAccessibilityObject.cpp
    406409
     410WebProcess/WebPage/glib/WebPageGLib.cpp
     411
    407412WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp
    408413
  • trunk/Source/WebKit/SourcesWPE.txt

    r250597 r251181  
    6969Shared/API/glib/WebKitURIRequest.cpp @no-unify
    7070Shared/API/glib/WebKitURIResponse.cpp @no-unify
     71Shared/API/glib/WebKitUserMessage.cpp @no-unify
    7172
    7273Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp
     
    8283Shared/cairo/ShareableBitmapCairo.cpp
    8384
     85Shared/glib/ArgumentCodersGLib.cpp
    8486Shared/glib/ProcessExecutablePathGLib.cpp
     87Shared/glib/UserMessage.cpp
    8588Shared/glib/WebContextMenuItemGlib.cpp
    8689
     
    248251WebProcess/WebPage/atk/WebKitWebPageAccessibilityObject.cpp
    249252
     253WebProcess/WebPage/glib/WebPageGLib.cpp
     254
    250255WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp
    251256
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp

    r251127 r251181  
    4848#include "WebKitURISchemeRequestPrivate.h"
    4949#include "WebKitUserContentManagerPrivate.h"
     50#include "WebKitUserMessagePrivate.h"
    5051#include "WebKitWebContextPrivate.h"
    5152#include "WebKitWebViewPrivate.h"
    5253#include "WebKitWebsiteDataManagerPrivate.h"
    5354#include "WebNotificationManagerProxy.h"
     55#include "WebProcessMessages.h"
    5456#include "WebURLSchemeHandler.h"
    5557#include "WebsiteDataType.h"
     
    124126    INITIALIZE_NOTIFICATION_PERMISSIONS,
    125127    AUTOMATION_STARTED,
     128    USER_MESSAGE_RECEIVED,
    126129
    127130    LAST_SIGNAL
     
    373376    priv->processPool = WebProcessPool::create(configuration);
    374377    priv->processPool->setPrimaryDataStore(webkitWebsiteDataManagerGetDataStore(priv->websiteDataManager.get()));
     378    priv->processPool->setUserMessageHandler([webContext](UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler) {
     379        // Sink the floating ref.
     380        GRefPtr<WebKitUserMessage> userMessage = webkitUserMessageCreate(WTFMove(message), WTFMove(completionHandler));
     381        gboolean returnValue;
     382        g_signal_emit(webContext, signals[USER_MESSAGE_RECEIVED], 0, userMessage.get(), &returnValue);
     383    });
    375384
    376385    webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), *priv->processPool);
     
    414423        webkitFaviconDatabaseClose(priv->faviconDatabase.get());
    415424        priv->faviconDatabase = nullptr;
     425    }
     426
     427    if (priv->processPool) {
     428        priv->processPool->setUserMessageHandler(nullptr);
     429        priv->processPool = nullptr;
    416430    }
    417431
     
    575589            G_TYPE_NONE, 1,
    576590            WEBKIT_TYPE_AUTOMATION_SESSION);
     591
     592    /**
     593     * WebKitWebContext::user-message-received:
     594     * @context: the #WebKitWebContext
     595     * @message: the #WebKitUserMessage received
     596     *
     597     * This signal is emitted when a #WebKitUserMessage is received from a
     598     * #WebKitWebExtension. You can reply to the message using
     599     * webkit_user_message_send_reply().
     600     *
     601     * You can handle the user message asynchronously by calling g_object_ref() on
     602     * @message and returning %TRUE.
     603     *
     604     * Returns: %TRUE if the message was handled, or %FALSE otherwise.
     605     *
     606     * Since: 2.28
     607     */
     608    signals[USER_MESSAGE_RECEIVED] = g_signal_new(
     609        "user-message-received",
     610        G_TYPE_FROM_CLASS(gObjectClass),
     611        G_SIGNAL_RUN_LAST,
     612        G_STRUCT_OFFSET(WebKitWebContextClass, user_message_received),
     613        g_signal_accumulator_true_handled, nullptr,
     614        g_cclosure_marshal_generic,
     615        G_TYPE_BOOLEAN, 1,
     616        WEBKIT_TYPE_USER_MESSAGE);
    577617}
    578618
     
    16811721}
    16821722
     1723/**
     1724 * webkit_web_context_send_message_to_all_extensions:
     1725 * @context: the #WebKitWebContext
     1726 * @message: a #WebKitUserMessage
     1727 *
     1728 * Send @message to all #WebKitWebExtension<!-- -->s associated to @context.
     1729 * If @message is floating, it's consumed.
     1730 *
     1731 * Since: 2.28
     1732 */
     1733void webkit_web_context_send_message_to_all_extensions(WebKitWebContext* context, WebKitUserMessage* message)
     1734{
     1735    g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context));
     1736    g_return_if_fail(WEBKIT_IS_USER_MESSAGE(message));
     1737
     1738    // We sink the reference in case of being floating.
     1739    GRefPtr<WebKitUserMessage> adoptedMessage = message;
     1740    for (auto& process : context->priv->processPool->processes())
     1741        process->send(Messages::WebProcess::SendMessageToWebExtension(webkitUserMessageGetMessage(message)), 0);
     1742}
     1743
    16831744void webkitWebContextInitializeNotificationPermissions(WebKitWebContext* context)
    16841745{
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp

    r251132 r251181  
    5757#include "WebKitURIRequestPrivate.h"
    5858#include "WebKitURIResponsePrivate.h"
     59#include "WebKitUserMessagePrivate.h"
    5960#include "WebKitWebContextPrivate.h"
    6061#include "WebKitWebResourcePrivate.h"
     
    6364#include "WebKitWebsiteDataManagerPrivate.h"
    6465#include "WebKitWindowPropertiesPrivate.h"
     66#include "WebPageMessages.h"
    6567#include <JavaScriptCore/APICast.h>
    6668#include <JavaScriptCore/JSRetainPtr.h>
     
    164166#endif
    165167
     168    USER_MESSAGE_RECEIVED,
     169
    166170    LAST_SIGNAL
    167171};
     
    443447    {
    444448        webkitWebViewDidChangePageID(m_webView);
     449    }
     450
     451    void didReceiveUserMessage(WKWPE::View&, UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler) override
     452    {
     453        webkitWebViewDidReceiveUserMessage(m_webView, WTFMove(message), WTFMove(completionHandler));
    445454    }
    446455
     
    20802089        GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
    20812090#endif // PLATFORM(GTK)
     2091
     2092    /**
     2093     * WebKitWebView::user-message-received:
     2094     * @web_view: the #WebKitWebView on which the signal is emitted
     2095     * @message: the #WebKitUserMessage received
     2096     *
     2097     * This signal is emitted when a #WebKitUserMessage is received from the
     2098     * #WebKitWebPage corresponding to @web_view. You can reply to the message
     2099     * using webkit_user_message_send_reply().
     2100     *
     2101     * You can handle the user message asynchronously by calling g_object_ref() on
     2102     * @message and returning %TRUE. If the last reference of @message is removed
     2103     * and the message has not been replied to, the operation in the #WebKitWebPage will
     2104     * finish with error %WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE.
     2105     *
     2106     * Returns: %TRUE if the message was handled, or %FALSE otherwise.
     2107     *
     2108     * Since: 2.28
     2109     */
     2110    signals[USER_MESSAGE_RECEIVED] = g_signal_new(
     2111        "user-message-received",
     2112        G_TYPE_FROM_CLASS(webViewClass),
     2113        G_SIGNAL_RUN_LAST,
     2114        G_STRUCT_OFFSET(WebKitWebViewClass, user_message_received),
     2115        g_signal_accumulator_true_handled, nullptr,
     2116        g_cclosure_marshal_generic,
     2117        G_TYPE_BOOLEAN, 1,
     2118        WEBKIT_TYPE_USER_MESSAGE);
    20822119}
    20832120
     
    25812618{
    25822619    g_object_notify(G_OBJECT(webView), "page-id");
     2620}
     2621
     2622void webkitWebViewDidReceiveUserMessage(WebKitWebView* webView, UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
     2623{
     2624    // Sink the floating ref.
     2625    GRefPtr<WebKitUserMessage> userMessage = webkitUserMessageCreate(WTFMove(message), WTFMove(completionHandler));
     2626    gboolean returnValue;
     2627    g_signal_emit(webView, signals[USER_MESSAGE_RECEIVED], 0, userMessage.get(), &returnValue);
    25832628}
    25842629
     
    42194264}
    42204265#endif // PLATFORM(WPE)
     4266
     4267/**
     4268 * webkit_web_view_send_message_to_page:
     4269 * @web_view: a #WebKitWebView
     4270 * @message: a #WebKitUserMessage
     4271 * @cancellable: (nullable): a #GCancellable or %NULL to ignore
     4272 * @callback: (scope async): (nullable): A #GAsyncReadyCallback to call when the request is satisfied or %NULL
     4273 * @user_data: (closure): the data to pass to callback function
     4274 *
     4275 * Send @message to the #WebKitWebPage corresponding to @web_view. If @message is floating, it's consumed.
     4276 *
     4277 * If you don't expect any reply, or you simply want to ignore it, you can pass %NULL as @callback.
     4278 * When the operation is finished, @callback will be called. You can then call
     4279 * webkit_web_view_send_message_to_page_finish() to get the message reply.
     4280 *
     4281 * Since: 2.28
     4282 */
     4283void webkit_web_view_send_message_to_page(WebKitWebView* webView, WebKitUserMessage* message, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
     4284{
     4285    g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
     4286    g_return_if_fail(WEBKIT_IS_USER_MESSAGE(message));
     4287
     4288    // We sink the reference in case of being floating.
     4289    GRefPtr<WebKitUserMessage> adoptedMessage = message;
     4290    auto& page = getPage(webView);
     4291    if (!callback) {
     4292        page.ensureRunningProcess().send(Messages::WebPage::SendMessageToWebExtension(webkitUserMessageGetMessage(message)), page.webPageID().toUInt64());
     4293        return;
     4294    }
     4295
     4296    GRefPtr<GTask> task = adoptGRef(g_task_new(webView, cancellable, callback, userData));
     4297    CompletionHandler<void(UserMessage&&)> completionHandler = [task = WTFMove(task)](UserMessage&& replyMessage) {
     4298        switch (replyMessage.type) {
     4299        case UserMessage::Type::Null:
     4300            g_task_return_new_error(task.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation was cancelled"));
     4301            break;
     4302        case UserMessage::Type::Message:
     4303            g_task_return_pointer(task.get(), g_object_ref_sink(webkitUserMessageCreate(WTFMove(replyMessage))), static_cast<GDestroyNotify>(g_object_unref));
     4304            break;
     4305        case UserMessage::Type::Error:
     4306            g_task_return_new_error(task.get(), WEBKIT_USER_MESSAGE_ERROR, replyMessage.errorCode, _("Message %s was not handled"), replyMessage.name.data());
     4307            break;
     4308        }
     4309    };
     4310    page.ensureRunningProcess().sendWithAsyncReply(Messages::WebPage::SendMessageToWebExtensionWithReply(webkitUserMessageGetMessage(message)),
     4311        WTFMove(completionHandler), page.webPageID().toUInt64());
     4312}
     4313
     4314/**
     4315 * webkit_web_view_send_message_to_page_finish:
     4316 * @web_view: a #WebKitWebView
     4317 * @result: a #GAsyncResult
     4318 * @error: return location for error or %NULL to ignor
     4319 *
     4320 * Finish an asynchronous operation started with webkit_web_view_send_message_to_page().
     4321 *
     4322 * Returns: (transfer full): a #WebKitUserMessage with the reply or %NULL in case of error.
     4323 *
     4324 * Since: 2.28
     4325 */
     4326WebKitUserMessage* webkit_web_view_send_message_to_page_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
     4327{
     4328    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
     4329    g_return_val_if_fail(g_task_is_valid(result, webView), nullptr);
     4330
     4331    return WEBKIT_USER_MESSAGE(g_task_propagate_pointer(G_TASK(result), error));
     4332}
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h

    r250645 r251181  
    2929#include "APIPageConfiguration.h"
    3030#include "InstallMissingMediaPluginsPermissionRequest.h"
     31#include "UserMessage.h"
    3132#include "WebContextMenuItemData.h"
    3233#include "WebEvent.h"
     
    102103gboolean webkitWebViewRunFileChooser(WebKitWebView*, WebKitFileChooserRequest*);
    103104void webkitWebViewDidChangePageID(WebKitWebView*);
     105void webkitWebViewDidReceiveUserMessage(WebKitWebView*, WebKit::UserMessage&&, CompletionHandler<void(WebKit::UserMessage&&)>&&);
  • trunk/Source/WebKit/UIProcess/API/gtk/WebKitAutocleanups.h

    r242351 r251181  
    6363G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserContentManager, g_object_unref)
    6464G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserMediaPermissionRequest, g_object_unref)
     65G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserMessage, g_object_unref)
    6566G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebContext, g_object_unref)
    6667G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebInspector, g_object_unref)
  • trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebContext.h

    r249419 r251181  
    3535#include <webkit2/WebKitSecurityManager.h>
    3636#include <webkit2/WebKitURISchemeRequest.h>
     37#include <webkit2/WebKitUserMessage.h>
    3738#include <webkit2/WebKitWebsiteDataManager.h>
    3839
     
    144145    GObjectClass parent;
    145146
    146     void (* download_started)                    (WebKitWebContext        *context,
    147                                                   WebKitDownload          *download);
    148     void (* initialize_web_extensions)           (WebKitWebContext        *context);
    149     void (* initialize_notification_permissions) (WebKitWebContext        *context);
    150     void (* automation_started)                  (WebKitWebContext        *context,
    151                                                   WebKitAutomationSession *session);
     147    void     (* download_started)                    (WebKitWebContext        *context,
     148                                                      WebKitDownload          *download);
     149    void     (* initialize_web_extensions)           (WebKitWebContext        *context);
     150    void     (* initialize_notification_permissions) (WebKitWebContext        *context);
     151    void     (* automation_started)                  (WebKitWebContext        *context,
     152                                                      WebKitAutomationSession *session);
     153    gboolean (* user_message_received)               (WebKitWebContext        *context,
     154                                                      WebKitUserMessage       *message);
    152155
    153156    void (*_webkit_reserved0) (void);
    154157    void (*_webkit_reserved1) (void);
    155158    void (*_webkit_reserved2) (void);
    156     void (*_webkit_reserved3) (void);
    157159};
    158160
     
    319321                                                     GList                         *disallowed_origins);
    320322
     323WEBKIT_API void
     324webkit_web_context_send_message_to_all_extensions   (WebKitWebContext              *context,
     325                                                     WebKitUserMessage             *message);
     326
    321327G_END_DECLS
    322328
  • trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebView.h

    r232671 r251181  
    5050#include <webkit2/WebKitURIRequest.h>
    5151#include <webkit2/WebKitUserContentManager.h>
     52#include <webkit2/WebKitUserMessage.h>
    5253#include <webkit2/WebKitWebContext.h>
    5354#include <webkit2/WebKitWebInspector.h>
     
    270271    void       (* web_process_terminated)      (WebKitWebView               *web_view,
    271272                                                WebKitWebProcessTerminationReason reason);
     273    gboolean   (* user_message_received)       (WebKitWebView               *web_view,
     274                                                WebKitUserMessage           *message);
    272275
    273276    void (*_webkit_reserved0) (void);
    274     void (*_webkit_reserved1) (void);
    275277};
    276278
     
    553555                                                      WebKitWebViewSessionState *state);
    554556
     557WEBKIT_API void
     558webkit_web_view_send_message_to_page                 (WebKitWebView             *web_view,
     559                                                      WebKitUserMessage         *message,
     560                                                      GCancellable              *cancellable,
     561                                                      GAsyncReadyCallback        callback,
     562                                                      gpointer                   user_data);
     563
     564WEBKIT_API WebKitUserMessage *
     565webkit_web_view_send_message_to_page_finish          (WebKitWebView             *web_view,
     566                                                      GAsyncResult              *result,
     567                                                      GError                   **error);
     568
    555569G_END_DECLS
    556570
  • trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt

    r249324 r251181  
    7171webkit_web_context_set_process_model
    7272webkit_web_context_initialize_notification_permissions
     73webkit_web_context_send_message_to_all_extensions
    7374
    7475<SUBSECTION URI Scheme>
     
    278279webkit_web_view_restore_session_state
    279280webkit_web_view_get_main_resource
     281webkit_web_view_send_message_to_page
     282webkit_web_view_send_message_to_page_finish
    280283
    281284<SUBSECTION WebKitJavascriptResult>
     
    15391542WebKitWebExtensionInitializeWithUserDataFunction
    15401543webkit_web_extension_get_page
     1544webkit_web_extension_send_message_to_context
     1545webkit_web_extension_send_message_to_context_finish
    15411546
    15421547<SUBSECTION Standard>
     
    15631568webkit_web_page_get_main_frame
    15641569webkit_web_page_get_editor
     1570webkit_web_page_send_message_to_view
     1571webkit_web_page_send_message_to_view_finish
    15651572
    15661573<SUBSECTION Standard>
     
    17391746webkit_uri_for_display
    17401747</SECTION>
     1748
     1749<SECTION>
     1750<FILE>WebKitUserMessage</FILE>
     1751WebKitUserMessage
     1752webkit_user_message_new
     1753webkit_user_message_new_with_fd_list
     1754webkit_user_message_get_name
     1755webkit_user_message_get_parameters
     1756webkit_user_message_get_fd_list
     1757webkit_user_message_send_reply
     1758
     1759<SUBSECTION WebKitUserMessageError>
     1760WEBKIT_USER_MESSAGE_ERROR
     1761WebKitUserMessageError
     1762webkit_user_message_error_quark
     1763
     1764<SUBSECTION Standard>
     1765WebKitUserMessageClass
     1766WEBKIT_TYPE_USER_MESSAGE
     1767WEBKIT_USER_MESSAGE
     1768WEBKIT_IS_USER_MESSAGE
     1769WEBKIT_USER_MESSAGE_CLASS
     1770WEBKIT_IS_USER_MESSAGE_CLASS
     1771WEBKIT_USER_MESSAGE_GET_CLASS
     1772
     1773<SUBSECTION Private>
     1774WebKitUserMessagePrivate
     1775webkit_user_message_get_type
     1776</SECTION>
  • trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml

    r250645 r251181  
    6464    <xi:include href="xml/WebKitApplicationInfo.xml"/>
    6565    <xi:include href="xml/WebKitGeolocationManager.xml"/>
     66    <xi:include href="xml/WebKitUserMessage.xml"/>
    6667  </chapter>
    6768
  • trunk/Source/WebKit/UIProcess/API/gtk/webkit2.h

    r243285 r251181  
    8080#include <webkit2/WebKitUserContentManager.h>
    8181#include <webkit2/WebKitUserMediaPermissionRequest.h>
     82#include <webkit2/WebKitUserMessage.h>
    8283#include <webkit2/WebKitVersion.h>
    8384#include <webkit2/WebKitWebContext.h>
  • trunk/Source/WebKit/UIProcess/API/wpe/APIViewClient.h

    r250645 r251181  
    2626#pragma once
    2727
     28#include "UserMessage.h"
     29#include <wtf/CompletionHandler.h>
     30
    2831typedef struct OpaqueJSContext* JSGlobalContextRef;
    2932
     
    4750    virtual void willStartLoad(WKWPE::View&) { }
    4851    virtual void didChangePageID(WKWPE::View&) { }
     52    virtual void didReceiveUserMessage(WKWPE::View&, WebKit::UserMessage&&, CompletionHandler<void(WebKit::UserMessage&&)>&& completionHandler) { completionHandler(WebKit::UserMessage()); }
    4953};
    5054
  • trunk/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp

    r250645 r251181  
    426426}
    427427
     428void PageClientImpl::sendMessageToWebView(UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
     429{
     430    m_view.didReceiveUserMessage(WTFMove(message), WTFMove(completionHandler));
     431}
     432
    428433} // namespace WebKit
  • trunk/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h

    r250645 r251181  
    4343
    4444class ScrollGestureController;
     45struct UserMessage;
    4546
    4647enum class UndoOrRedo : bool;
     
    6061    AtkObject* accessible();
    6162#endif
     63
     64    void sendMessageToWebView(UserMessage&&, CompletionHandler<void(UserMessage&&)>&&);
    6265
    6366private:
  • trunk/Source/WebKit/UIProcess/API/wpe/WPEView.cpp

    r250651 r251181  
    211211}
    212212
     213void View::didReceiveUserMessage(UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
     214{
     215    m_client->didReceiveUserMessage(*this, WTFMove(message), WTFMove(completionHandler));
     216}
     217
    213218void View::setSize(const WebCore::IntSize& size)
    214219{
  • trunk/Source/WebKit/UIProcess/API/wpe/WPEView.h

    r250645 r251181  
    5050class WebPageGroup;
    5151class WebProcessPool;
     52struct UserMessage;
    5253}
    5354
     
    6970    void willStartLoad();
    7071    void didChangePageID();
     72    void didReceiveUserMessage(WebKit::UserMessage&&, CompletionHandler<void(WebKit::UserMessage&&)>&&);
    7173
    7274    WebKit::WebPageProxy& page() { return *m_pageProxy; }
  • trunk/Source/WebKit/UIProcess/API/wpe/WebKitAutocleanups.h

    r242351 r251181  
    5959G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserContentManager, g_object_unref)
    6060G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserMediaPermissionRequest, g_object_unref)
     61G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserMessage, g_object_unref)
    6162G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebContext, g_object_unref)
    6263G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebResource, g_object_unref)
  • trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebContext.h

    r249419 r251181  
    3535#include <wpe/WebKitSecurityManager.h>
    3636#include <wpe/WebKitURISchemeRequest.h>
     37#include <wpe/WebKitUserMessage.h>
    3738#include <wpe/WebKitWebsiteDataManager.h>
    3839
     
    144145    GObjectClass parent;
    145146
    146     void (* download_started)                    (WebKitWebContext        *context,
    147                                                   WebKitDownload          *download);
    148     void (* initialize_web_extensions)           (WebKitWebContext        *context);
    149     void (* initialize_notification_permissions) (WebKitWebContext        *context);
    150     void (* automation_started)                  (WebKitWebContext        *context,
    151                                                   WebKitAutomationSession *session);
     147    void     (* download_started)                    (WebKitWebContext        *context,
     148                                                      WebKitDownload          *download);
     149    void     (* initialize_web_extensions)           (WebKitWebContext        *context);
     150    void     (* initialize_notification_permissions) (WebKitWebContext        *context);
     151    void     (* automation_started)                  (WebKitWebContext        *context,
     152                                                      WebKitAutomationSession *session);
     153    gboolean (* user_message_received)               (WebKitWebContext        *context,
     154                                                      WebKitUserMessage       *message);
    152155
    153156    void (*_webkit_reserved0) (void);
    154157    void (*_webkit_reserved1) (void);
    155158    void (*_webkit_reserved2) (void);
    156     void (*_webkit_reserved3) (void);
    157159};
    158160
     
    315317                                                     GList                         *disallowed_origins);
    316318
     319WEBKIT_API void
     320webkit_web_context_send_message_to_all_extensions   (WebKitWebContext              *context,
     321                                                     WebKitUserMessage             *message);
     322
    317323G_END_DECLS
    318324
  • trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebView.h

    r242082 r251181  
    4747#include <wpe/WebKitURIRequest.h>
    4848#include <wpe/WebKitUserContentManager.h>
     49#include <wpe/WebKitUserMessage.h>
    4950#include <wpe/WebKitWebContext.h>
    5051#include <wpe/WebKitWebResource.h>
     
    242243    void           (* web_process_terminated)      (WebKitWebView               *web_view,
    243244                                                    WebKitWebProcessTerminationReason reason);
     245    gboolean       (* user_message_received)       (WebKitWebView               *web_view,
     246                                                    WebKitUserMessage           *message);
     247
    244248
    245249    void (*_webkit_reserved0) (void);
     
    250254    void (*_webkit_reserved5) (void);
    251255    void (*_webkit_reserved6) (void);
    252     void (*_webkit_reserved7) (void);
    253256};
    254257
     
    526529                                                      WebKitColor                 *color);
    527530
     531WEBKIT_API void
     532webkit_web_view_send_message_to_page                 (WebKitWebView               *web_view,
     533                                                      WebKitUserMessage           *message,
     534                                                      GCancellable                *cancellable,
     535                                                      GAsyncReadyCallback          callback,
     536                                                      gpointer                     user_data);
     537
     538WEBKIT_API WebKitUserMessage *
     539webkit_web_view_send_message_to_page_finish          (WebKitWebView               *web_view,
     540                                                      GAsyncResult                *result,
     541                                                      GError                     **error);
     542
    528543G_END_DECLS
    529544
  • trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt

    r249324 r251181  
    4848webkit_web_context_set_process_model
    4949webkit_web_context_initialize_notification_permissions
     50webkit_web_context_send_message_to_all_extensions
    5051
    5152<SUBSECTION URI Scheme>
     
    252253webkit_web_view_get_background_color
    253254webkit_web_view_set_background_color
     255webkit_web_view_send_message_to_page
     256webkit_web_view_send_message_to_page_finish
    254257
    255258<SUBSECTION WebKitJavascriptResult>
     
    589592
    590593<SECTION>
     594<FILE>WebKitUserMessage</FILE>
     595WebKitUserMessage
     596webkit_user_message_new
     597webkit_user_message_new_with_fd_list
     598webkit_user_message_get_name
     599webkit_user_message_get_parameters
     600webkit_user_message_get_fd_list
     601webkit_user_message_send_reply
     602
     603<SUBSECTION WebKitUserMessageError>
     604WEBKIT_USER_MESSAGE_ERROR
     605WebKitUserMessageError
     606webkit_user_message_error_quark
     607
     608<SUBSECTION Standard>
     609WebKitUserMessageClass
     610WEBKIT_TYPE_USER_MESSAGE
     611WEBKIT_USER_MESSAGE
     612WEBKIT_IS_USER_MESSAGE
     613WEBKIT_USER_MESSAGE_CLASS
     614WEBKIT_IS_USER_MESSAGE_CLASS
     615WEBKIT_USER_MESSAGE_GET_CLASS
     616
     617<SUBSECTION Private>
     618WebKitUserMessagePrivate
     619webkit_user_message_get_type
     620</SECTION>
     621
     622<SECTION>
    591623<FILE>WebKitWindowProperties</FILE>
    592624WebKitWindowProperties
  • trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-docs.sgml

    r246545 r251181  
    5858    <xi:include href="xml/WebKitColor.xml"/>
    5959    <xi:include href="xml/WebKitGeolocationManager.xml"/>
     60    <xi:include href="xml/WebKitUserMessage.xml"/>
    6061  </chapter>
    6162
     
    9495  </index>
    9596
     97  <index id="api-index-2-28" role="2.28">
     98    <title>Index of new symbols in 2.28</title>
     99    <xi:include href="xml/api-index-2.28.xml"><xi:fallback /></xi:include>
     100  </index>
     101
    96102  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
    97103</book>
  • trunk/Source/WebKit/UIProcess/API/wpe/webkit.h

    r243285 r251181  
    7474#include <wpe/WebKitUserContentManager.h>
    7575#include <wpe/WebKitUserMediaPermissionRequest.h>
     76#include <wpe/WebKitUserMessage.h>
    7677#include <wpe/WebKitVersion.h>
    7778#include <wpe/WebKitWebContext.h>
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r251121 r251181  
    302302struct WebPopupItem;
    303303struct URLSchemeTaskParameters;
     304struct UserMessage;
    304305
    305306enum class ProcessSwapRequestedByClient;
     
    17371738    void requestGeolocationPermissionForFrame(uint64_t geolocationID, WebCore::FrameIdentifier, String originIdentifier);
    17381739
     1740#if PLATFORM(GTK) || PLATFORM(WPE)
     1741    void sendMessageToWebView(UserMessage&&);
     1742    void sendMessageToWebViewWithReply(UserMessage&&, CompletionHandler<void(UserMessage&&)>&&);
     1743#endif
     1744
    17391745#if ENABLE(MEDIA_STREAM)
    17401746    UserMediaPermissionRequestManagerProxy& userMediaPermissionRequestManager();
  • trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in

    r251121 r251181  
    577577    SetMockWebAuthenticationConfiguration(struct WebCore::MockWebAuthenticationConfiguration configuration);
    578578#endif
     579
     580#if PLATFORM(GTK) || PLATFORM(WPE)
     581    SendMessageToWebView(struct WebKit::UserMessage userMessage)
     582    SendMessageToWebViewWithReply(struct WebKit::UserMessage userMessage) -> (struct WebKit::UserMessage replyMessage) Async
     583#endif
    579584}
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r251174 r251181  
    503503    const HashMap<CString, SandboxPermission>& sandboxPaths() const { return m_extraSandboxPaths; };
    504504    bool sandboxEnabled() const { return m_sandboxEnabled; };
     505
     506    void setUserMessageHandler(Function<void(UserMessage&&, CompletionHandler<void(UserMessage&&)>&&)>&& handler) { m_userMessageHandler = WTFMove(handler); }
     507    const Function<void(UserMessage&&, CompletionHandler<void(UserMessage&&)>&&)>& userMessageHandler() const { return m_userMessageHandler; }
    505508#endif
    506509   
     
    782785    bool m_sandboxEnabled { false };
    783786    HashMap<CString, SandboxPermission> m_extraSandboxPaths;
     787
     788    Function<void(UserMessage&&, CompletionHandler<void(UserMessage&&)>&&)> m_userMessageHandler;
    784789#endif
    785790
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.h

    r251121 r251181  
    8181class WebsiteDataStore;
    8282enum class WebsiteDataType;
     83struct UserMessage;
    8384struct WebNavigationDataStore;
    8485struct WebPageCreationParameters;
     
    426427    void maybeShutDown();
    427428
     429#if PLATFORM(GTK) || PLATFORM(WPE)
     430    void sendMessageToWebContext(UserMessage&&);
     431    void sendMessageToWebContextWithReply(UserMessage&&, CompletionHandler<void(UserMessage&&)>&&);
     432#endif
     433
    428434    enum class IsWeak { No, Yes };
    429435    template<typename T> class WeakOrStrongPtr {
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in

    r250673 r251181  
    7878    void AddPlugInAutoStartOriginHash(String pageOrigin, uint32_t hash)
    7979    void PlugInDidReceiveUserInteraction(uint32_t hash)
     80
     81#if PLATFORM(GTK) || PLATFORM(WPE)
     82    SendMessageToWebContext(struct WebKit::UserMessage userMessage)
     83    SendMessageToWebContextWithReply(struct WebKit::UserMessage userMessage) -> (struct WebKit::UserMessage replyMessage) Async
     84#endif
    8085}
  • trunk/Source/WebKit/UIProcess/glib/WebProcessProxyGLib.cpp

    r250169 r251181  
    2727#include "WebProcessProxy.h"
    2828
     29#include "UserMessage.h"
    2930#include "WebProcessPool.h"
    3031#include "WebsiteDataStore.h"
     
    5758}
    5859
     60void WebProcessProxy::sendMessageToWebContextWithReply(UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
     61{
     62    if (const auto& userMessageHandler = m_processPool->userMessageHandler())
     63        userMessageHandler(WTFMove(message), WTFMove(completionHandler));
     64}
     65
     66void WebProcessProxy::sendMessageToWebContext(UserMessage&& message)
     67{
     68    sendMessageToWebContextWithReply(WTFMove(message), [](UserMessage&&) { });
     69}
     70
    5971};
  • trunk/Source/WebKit/UIProcess/gtk/WebPageProxyGtk.cpp

    r249275 r251181  
    2929
    3030#include "PageClientImpl.h"
     31#include "WebKitUserMessage.h"
    3132#include "WebKitWebViewBasePrivate.h"
     33#include "WebKitWebViewPrivate.h"
    3234#include "WebPageMessages.h"
    3335#include "WebPasteboardProxy.h"
     
    167169}
    168170
     171void WebPageProxy::sendMessageToWebViewWithReply(UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
     172{
     173    if (!WEBKIT_IS_WEB_VIEW(viewWidget())) {
     174        completionHandler(UserMessage(message.name, WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE));
     175        return;
     176    }
     177
     178    webkitWebViewDidReceiveUserMessage(WEBKIT_WEB_VIEW(viewWidget()), WTFMove(message), WTFMove(completionHandler));
     179}
     180
     181void WebPageProxy::sendMessageToWebView(UserMessage&& message)
     182{
     183    sendMessageToWebViewWithReply(WTFMove(message), [](UserMessage&&) { });
     184}
     185
    169186} // namespace WebKit
  • trunk/Source/WebKit/UIProcess/wpe/WebPageProxyWPE.cpp

    r245884 r251181  
    8383}
    8484
     85void WebPageProxy::sendMessageToWebViewWithReply(UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
     86{
     87    static_cast<PageClientImpl&>(pageClient()).sendMessageToWebView(WTFMove(message), WTFMove(completionHandler));
     88}
     89
     90void WebPageProxy::sendMessageToWebView(UserMessage&& message)
     91{
     92    sendMessageToWebViewWithReply(WTFMove(message), [](UserMessage&&) { });
     93}
     94
    8595} // namespace WebKit
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitExtensionManager.h

    r228021 r251181  
    4343    __attribute__((visibility("default"))) void initialize(InjectedBundle*, API::Object*);
    4444
     45    WebKitWebExtension* extension() const { return m_extension.get(); }
     46
    4547private:
    4648    WebKitExtensionManager();
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebExtension.cpp

    r249435 r251181  
    2424#include "APIInjectedBundleBundleClient.h"
    2525#include "APIString.h"
     26#include "WebKitUserMessagePrivate.h"
    2627#include "WebKitWebExtensionPrivate.h"
    2728#include "WebKitWebPagePrivate.h"
    2829#include "WebProcess.h"
     30#include "WebProcessProxyMessages.h"
    2931#include <WebCore/GCController.h>
     32#include <glib/gi18n-lib.h>
    3033#include <wtf/HashMap.h>
    3134#include <wtf/glib/GRefPtr.h>
     
    112115enum {
    113116    PAGE_CREATED,
     117    USER_MESSAGE_RECEIVED,
    114118
    115119    LAST_SIGNAL
     
    147151        G_TYPE_NONE, 1,
    148152        WEBKIT_TYPE_WEB_PAGE);
     153
     154    /**
     155     * WebKitWebExtension::user-message-received:
     156     * @extension: the #WebKitWebExtension on which the signal is emitted
     157     * @message: the #WebKitUserMessage received
     158     *
     159     * This signal is emitted when a #WebKitUserMessage is received from the
     160     * #WebKitWebContext corresponding to @extension. Messages sent by #WebKitWebContext
     161     * are always broadcasted to all #WebKitWebExtension<!-- -->s and they can't be
     162     * replied to. Calling webkit_user_message_send_reply() will do nothing.
     163     *
     164     * Since: 2.28
     165     */
     166    signals[USER_MESSAGE_RECEIVED] = g_signal_new(
     167        "user-message-received",
     168        G_TYPE_FROM_CLASS(klass),
     169        G_SIGNAL_RUN_LAST,
     170        0,
     171        nullptr, nullptr,
     172        g_cclosure_marshal_generic,
     173        G_TYPE_NONE, 1,
     174        WEBKIT_TYPE_USER_MESSAGE);
    149175}
    150176
     
    201227}
    202228
     229void webkitWebExtensionDidReceiveUserMessage(WebKitWebExtension* extension, UserMessage&& message)
     230{
     231    // Sink the floating ref.
     232    GRefPtr<WebKitUserMessage> userMessage = webkitUserMessageCreate(WTFMove(message), [](UserMessage&&) { });
     233    g_signal_emit(extension, signals[USER_MESSAGE_RECEIVED], 0, userMessage.get());
     234}
     235
    203236void webkitWebExtensionSetGarbageCollectOnPageDestroy(WebKitWebExtension* extension)
    204237{
     
    230263    return 0;
    231264}
     265
     266/**
     267 * webkit_web_extension_send_message_to_context:
     268 * @extension: a #WebKitWebExtension
     269 * @message: a #WebKitUserMessage
     270 * @cancellable: (nullable): a #GCancellable or %NULL to ignore
     271 * @callback: (scope async): (nullable): A #GAsyncReadyCallback to call when the request is satisfied or %NULL
     272 * @user_data: (closure): the data to pass to callback function
     273 *
     274 * Send @message to the #WebKitWebContext corresponding to @extension. If @message is floating, it's consumed.
     275 *
     276 * If you don't expect any reply, or you simply want to ignore it, you can pass %NULL as @calback.
     277 * When the operation is finished, @callback will be called. You can then call
     278 * webkit_web_extension_send_message_to_context_finish() to get the message reply.
     279 *
     280 * Since: 2.28
     281 */
     282void webkit_web_extension_send_message_to_context(WebKitWebExtension* extension, WebKitUserMessage* message, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
     283{
     284    g_return_if_fail(WEBKIT_IS_WEB_EXTENSION(extension));
     285    g_return_if_fail(WEBKIT_IS_USER_MESSAGE(message));
     286
     287    // We sink the reference in case of being floating.
     288    GRefPtr<WebKitUserMessage> adoptedMessage = message;
     289    if (!callback) {
     290        WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::SendMessageToWebContext(webkitUserMessageGetMessage(message)), 0);
     291        return;
     292    }
     293
     294    GRefPtr<GTask> task = adoptGRef(g_task_new(extension, cancellable, callback, userData));
     295    CompletionHandler<void(UserMessage&&)> completionHandler = [task = WTFMove(task)](UserMessage&& replyMessage) {
     296        switch (replyMessage.type) {
     297        case UserMessage::Type::Null:
     298            g_task_return_new_error(task.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation was cancelled"));
     299            break;
     300        case UserMessage::Type::Message:
     301            g_task_return_pointer(task.get(), g_object_ref_sink(webkitUserMessageCreate(WTFMove(replyMessage))), static_cast<GDestroyNotify>(g_object_unref));
     302            break;
     303        case UserMessage::Type::Error:
     304            g_task_return_new_error(task.get(), WEBKIT_USER_MESSAGE_ERROR, replyMessage.errorCode, _("Message %s was not handled"), replyMessage.name.data());
     305            break;
     306        }
     307    };
     308    WebProcess::singleton().parentProcessConnection()->sendWithAsyncReply(Messages::WebProcessProxy::SendMessageToWebContextWithReply(webkitUserMessageGetMessage(message)), WTFMove(completionHandler));
     309}
     310
     311/**
     312 * webkit_web_extension_send_message_to_context_finish:
     313 * @extension: a #WebKitWebExtension
     314 * @result: a #GAsyncResult
     315 * @error: return location for error or %NULL to ignor
     316 *
     317 * Finish an asynchronous operation started with webkit_web_extension_send_message_to_context().
     318 *
     319 * Returns: (transfer full): a #WebKitUserMessage with the reply or %NULL in case of error.
     320 *
     321 * Since: 2.28
     322 */
     323WebKitUserMessage* webkit_web_extension_send_message_to_context_finish(WebKitWebExtension* extension, GAsyncResult* result, GError** error)
     324{
     325    g_return_val_if_fail(WEBKIT_IS_WEB_EXTENSION(extension), nullptr);
     326    g_return_val_if_fail(g_task_is_valid(result, extension), nullptr);
     327
     328    return WEBKIT_USER_MESSAGE(g_task_propagate_pointer(G_TASK(result), error));
     329}
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebExtensionPrivate.h

    r229395 r251181  
    2121
    2222#include "InjectedBundle.h"
     23#include "UserMessage.h"
    2324#include "WebKitWebExtension.h"
    2425
    2526WebKitWebExtension* webkitWebExtensionCreate(WebKit::InjectedBundle*);
     27void webkitWebExtensionDidReceiveUserMessage(WebKitWebExtension*, WebKit::UserMessage&&);
    2628void webkitWebExtensionSetGarbageCollectOnPageDestroy(WebKitWebExtension*);
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp

    r249501 r251181  
    4242#include "WebKitURIRequestPrivate.h"
    4343#include "WebKitURIResponsePrivate.h"
     44#include "WebKitUserMessagePrivate.h"
    4445#include "WebKitWebEditorPrivate.h"
    4546#include "WebKitWebHitTestResultPrivate.h"
    4647#include "WebKitWebPagePrivate.h"
    4748#include "WebKitWebProcessEnumTypes.h"
     49#include "WebPageProxyMessages.h"
    4850#include "WebProcess.h"
    4951#include <WebCore/Document.h>
     
    7173    FORM_CONTROLS_ASSOCIATED_FOR_FRAME,
    7274    WILL_SUBMIT_FORM,
     75    USER_MESSAGE_RECEIVED,
    7376
    7477    LAST_SIGNAL
     
    668671        G_TYPE_PTR_ARRAY,
    669672        G_TYPE_PTR_ARRAY);
     673
     674    /**
     675     * WebKitWebPage::user-message-received:
     676     * @web_page: the #WebKitWebPage on which the signal is emitted
     677     * @message: the #WebKitUserMessage received
     678     *
     679     * This signal is emitted when a #WebKitUserMessage is received from the
     680     * #WebKitWebView corresponding to @web_page. You can reply to the message
     681     * using webkit_user_message_send_reply().
     682     *
     683     * You can handle the user message asynchronously by calling g_object_ref() on
     684     * @message and returning %TRUE. If the last reference of @message is removed
     685     * and the message has been replied, the operation in the #WebKitWebView will
     686     * finish with error %WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE.
     687     *
     688     * Returns: %TRUE if the message was handled, or %FALSE otherwise.
     689     *
     690     * Since: 2.28
     691     */
     692    signals[USER_MESSAGE_RECEIVED] = g_signal_new(
     693        "user-message-received",
     694        G_TYPE_FROM_CLASS(klass),
     695        G_SIGNAL_RUN_LAST,
     696        0,
     697        g_signal_accumulator_true_handled, nullptr,
     698        g_cclosure_marshal_generic,
     699        G_TYPE_BOOLEAN, 1,
     700        WEBKIT_TYPE_USER_MESSAGE);
    670701}
    671702
     
    734765}
    735766
     767void webkitWebPageDidReceiveUserMessage(WebKitWebPage* webPage, UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
     768{
     769    // Sink the floating ref.
     770    GRefPtr<WebKitUserMessage> userMessage = webkitUserMessageCreate(WTFMove(message), WTFMove(completionHandler));
     771    gboolean returnValue;
     772    g_signal_emit(webPage, signals[USER_MESSAGE_RECEIVED], 0, userMessage.get(), &returnValue);
     773}
     774
    736775/**
    737776 * webkit_web_page_get_dom_document:
     
    823862    return webPage->priv->webEditor.get();
    824863}
     864
     865/**
     866 * webkit_web_page_send_message_to_view:
     867 * @web_page: a #WebKitWebPage
     868 * @message: a #WebKitUserMessage
     869 * @cancellable: (nullable): a #GCancellable or %NULL to ignore
     870 * @callback: (scope async): (nullable): A #GAsyncReadyCallback to call when the request is satisfied or %NULL
     871 * @user_data: (closure): the data to pass to callback function
     872 *
     873 * Send @message to the #WebKitWebView corresponding to @web_page. If @message is floating, it's consumed.
     874 *
     875 * If you don't expect any reply, or you simply want to ignore it, you can pass %NULL as @callback.
     876 * When the operation is finished, @callback will be called. You can then call
     877 * webkit_web_page_send_message_to_view_finish() to get the message reply.
     878 *
     879 * Since: 2.28
     880 */
     881void webkit_web_page_send_message_to_view(WebKitWebPage* webPage, WebKitUserMessage* message, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
     882{
     883    g_return_if_fail(WEBKIT_IS_WEB_PAGE(webPage));
     884    g_return_if_fail(WEBKIT_IS_USER_MESSAGE(message));
     885
     886    // We sink the reference in case of being floating.
     887    GRefPtr<WebKitUserMessage> adoptedMessage = message;
     888    if (!callback) {
     889        webPage->priv->webPage->send(Messages::WebPageProxy::SendMessageToWebView(webkitUserMessageGetMessage(message)));
     890        return;
     891    }
     892
     893    GRefPtr<GTask> task = adoptGRef(g_task_new(webPage, cancellable, callback, userData));
     894    CompletionHandler<void(UserMessage&&)> completionHandler = [task = WTFMove(task)](UserMessage&& replyMessage) {
     895        switch (replyMessage.type) {
     896        case UserMessage::Type::Null:
     897            g_task_return_new_error(task.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation was cancelled"));
     898            break;
     899        case UserMessage::Type::Message:
     900            g_task_return_pointer(task.get(), g_object_ref_sink(webkitUserMessageCreate(WTFMove(replyMessage))), static_cast<GDestroyNotify>(g_object_unref));
     901            break;
     902        case UserMessage::Type::Error:
     903            g_task_return_new_error(task.get(), WEBKIT_USER_MESSAGE_ERROR, replyMessage.errorCode, _("Message %s was not handled"), replyMessage.name.data());
     904            break;
     905        }
     906    };
     907    webPage->priv->webPage->sendWithAsyncReply(Messages::WebPageProxy::SendMessageToWebViewWithReply(webkitUserMessageGetMessage(message)), WTFMove(completionHandler));
     908}
     909
     910/**
     911 * webkit_web_page_send_message_to_view_finish:
     912 * @web_page: a #WebKitWebPage
     913 * @result: a #GAsyncResult
     914 * @error: return location for error or %NULL to ignor
     915 *
     916 * Finish an asynchronous operation started with webkit_web_page_send_message_to_view().
     917 *
     918 * Returns: (transfer full): a #WebKitUserMessage with the reply or %NULL in case of error.
     919 *
     920 * Since: 2.28
     921 */
     922WebKitUserMessage* webkit_web_page_send_message_to_view_finish(WebKitWebPage* webPage, GAsyncResult* result, GError** error)
     923{
     924    g_return_val_if_fail(WEBKIT_IS_WEB_PAGE(webPage), nullptr);
     925    g_return_val_if_fail(g_task_is_valid(result, webPage), nullptr);
     926
     927    return WEBKIT_USER_MESSAGE(g_task_propagate_pointer(G_TASK(result), error));
     928}
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebPagePrivate.h

    r218487 r251181  
    1818 */
    1919
    20 #ifndef WebKitWebPagePrivate_h
    21 #define WebKitWebPagePrivate_h
     20#pragma once
    2221
    2322#include "APIDictionary.h"
     23#include "UserMessage.h"
    2424#include "WebKitWebPage.h"
    2525#include "WebPage.h"
     
    2727WebKitWebPage* webkitWebPageCreate(WebKit::WebPage*);
    2828void webkitWebPageDidReceiveMessage(WebKitWebPage*, const String& messageName, API::Dictionary& message);
     29void webkitWebPageDidReceiveUserMessage(WebKitWebPage*, WebKit::UserMessage&&, CompletionHandler<void(WebKit::UserMessage&&)>&&);
    2930WebKit::WebPage* webkitWebPageGetPage(WebKitWebPage*);
    3031
    31 #endif // WebKitWebPagePrivate_h
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/gtk/WebKitWebExtension.h

    r162441 r251181  
    2727#include <glib-object.h>
    2828#include <webkit2/WebKitDefines.h>
     29#include <webkit2/WebKitUserMessage.h>
    2930#include <webkit2/WebKitWebPage.h>
    3031
     
    7778
    7879WEBKIT_API GType
    79 webkit_web_extension_get_type (void);
     80webkit_web_extension_get_type                       (void);
    8081
    8182WEBKIT_API WebKitWebPage *
    82 webkit_web_extension_get_page (WebKitWebExtension *extension,
    83                                guint64             page_id);
     83webkit_web_extension_get_page                       (WebKitWebExtension *extension,
     84                                                     guint64             page_id);
     85
     86WEBKIT_API void
     87webkit_web_extension_send_message_to_context        (WebKitWebExtension *extension,
     88                                                     WebKitUserMessage  *message,
     89                                                     GCancellable       *cancellable,
     90                                                     GAsyncReadyCallback callback,
     91                                                     gpointer            user_data);
     92
     93WEBKIT_API WebKitUserMessage *
     94webkit_web_extension_send_message_to_context_finish (WebKitWebExtension *extension,
     95                                                     GAsyncResult       *result,
     96                                                     GError            **error);
    8497
    8598G_END_DECLS
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/gtk/WebKitWebExtensionAutocleanups.h

    r242351 r251181  
    3030G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFrame, g_object_unref)
    3131G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitScriptWorld, g_object_unref)
     32G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserMessage, g_object_unref)
    3233G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebEditor, g_object_unref)
    3334G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebExtension, g_object_unref)
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.h

    r226366 r251181  
    2828#include <webkit2/WebKitDefines.h>
    2929#include <webkit2/WebKitFrame.h>
     30#include <webkit2/WebKitUserMessage.h>
    3031#include <webkit2/WebKitWebEditor.h>
    3132#include <webkitdom/webkitdom.h>
     
    7576
    7677WEBKIT_API GType
    77 webkit_web_page_get_type         (void);
     78webkit_web_page_get_type                    (void);
    7879
    7980WEBKIT_API WebKitDOMDocument *
    80 webkit_web_page_get_dom_document (WebKitWebPage *web_page);
     81webkit_web_page_get_dom_document            (WebKitWebPage *web_page);
    8182
    8283WEBKIT_API guint64
    83 webkit_web_page_get_id           (WebKitWebPage *web_page);
     84webkit_web_page_get_id                      (WebKitWebPage *web_page);
    8485
    8586WEBKIT_API const gchar *
    86 webkit_web_page_get_uri          (WebKitWebPage *web_page);
     87webkit_web_page_get_uri                     (WebKitWebPage *web_page);
    8788
    8889WEBKIT_API WebKitFrame *
    89 webkit_web_page_get_main_frame   (WebKitWebPage *web_page);
     90webkit_web_page_get_main_frame              (WebKitWebPage *web_page);
    9091
    9192WEBKIT_API WebKitWebEditor *
    92 webkit_web_page_get_editor       (WebKitWebPage *web_page);
     93webkit_web_page_get_editor                  (WebKitWebPage *web_page);
     94
     95WEBKIT_API void
     96webkit_web_page_send_message_to_view        (WebKitWebPage      *web_page,
     97                                             WebKitUserMessage  *message,
     98                                             GCancellable       *cancellable,
     99                                             GAsyncReadyCallback callback,
     100                                             gpointer            user_data);
     101
     102WEBKIT_API WebKitUserMessage *
     103webkit_web_page_send_message_to_view_finish (WebKitWebPage      *web_page,
     104                                             GAsyncResult       *result,
     105                                             GError            **error);
    93106
    94107G_END_DECLS
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/gtk/webkit-web-extension.h

    r229971 r251181  
    3535#include <webkit2/WebKitURIRequest.h>
    3636#include <webkit2/WebKitURIResponse.h>
     37#include <webkit2/WebKitUserMessage.h>
    3738#include <webkit2/WebKitVersion.h>
    3839#include <webkit2/WebKitWebEditor.h>
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/wpe/WebKitWebExtension.h

    r218684 r251181  
    2727#include <glib-object.h>
    2828#include <wpe/WebKitDefines.h>
     29#include <wpe/WebKitUserMessage.h>
    2930#include <wpe/WebKitWebPage.h>
    3031
     
    7778
    7879WEBKIT_API GType
    79 webkit_web_extension_get_type (void);
     80webkit_web_extension_get_type                       (void);
    8081
    8182WEBKIT_API WebKitWebPage *
    82 webkit_web_extension_get_page (WebKitWebExtension *extension,
    83                                guint64             page_id);
     83webkit_web_extension_get_page                       (WebKitWebExtension *extension,
     84                                                     guint64             page_id);
     85
     86WEBKIT_API void
     87webkit_web_extension_send_message_to_context        (WebKitWebExtension *extension,
     88                                                     WebKitUserMessage  *message,
     89                                                     GCancellable       *cancellable,
     90                                                     GAsyncReadyCallback callback,
     91                                                     gpointer            user_data);
     92
     93WEBKIT_API WebKitUserMessage *
     94webkit_web_extension_send_message_to_context_finish (WebKitWebExtension *extension,
     95                                                     GAsyncResult       *result,
     96                                                     GError            **error);
    8497
    8598G_END_DECLS
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/wpe/WebKitWebExtensionAutocleanups.h

    r242351 r251181  
    3030G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFrame, g_object_unref)
    3131G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitScriptWorld, g_object_unref)
     32G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserMessage, g_object_unref)
    3233G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebEditor, g_object_unref)
    3334G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebExtension, g_object_unref)
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/wpe/WebKitWebPage.h

    r238853 r251181  
    2828#include <wpe/WebKitDefines.h>
    2929#include <wpe/WebKitFrame.h>
     30#include <wpe/WebKitUserMessage.h>
    3031#include <wpe/WebKitWebEditor.h>
    3132#include <wpe/webkitdom.h>
     
    7374
    7475WEBKIT_API GType
    75 webkit_web_page_get_type         (void);
     76webkit_web_page_get_type                    (void);
    7677
    7778WEBKIT_API WebKitDOMDocument *
    78 webkit_web_page_get_dom_document (WebKitWebPage *web_page);
     79webkit_web_page_get_dom_document            (WebKitWebPage *web_page);
    7980
    8081WEBKIT_API guint64
    81 webkit_web_page_get_id           (WebKitWebPage *web_page);
     82webkit_web_page_get_id                      (WebKitWebPage *web_page);
    8283
    8384WEBKIT_API const gchar *
    84 webkit_web_page_get_uri          (WebKitWebPage *web_page);
     85webkit_web_page_get_uri                     (WebKitWebPage *web_page);
    8586
    8687WEBKIT_API WebKitFrame *
    87 webkit_web_page_get_main_frame   (WebKitWebPage *web_page);
     88webkit_web_page_get_main_frame              (WebKitWebPage *web_page);
    8889
    8990WEBKIT_API WebKitWebEditor *
    90 webkit_web_page_get_editor       (WebKitWebPage *web_page);
     91webkit_web_page_get_editor                  (WebKitWebPage *web_page);
     92
     93WEBKIT_API void
     94webkit_web_page_send_message_to_view        (WebKitWebPage      *web_page,
     95                                             WebKitUserMessage  *message,
     96                                             GCancellable       *cancellable,
     97                                             GAsyncReadyCallback callback,
     98                                             gpointer            user_data);
     99
     100WEBKIT_API WebKitUserMessage *
     101webkit_web_page_send_message_to_view_finish (WebKitWebPage      *web_page,
     102                                             GAsyncResult       *result,
     103                                             GError            **error);
     104
    91105
    92106G_END_DECLS
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt

    r245176 r251181  
    1414WebKitWebExtensionInitializeWithUserDataFunction
    1515webkit_web_extension_get_page
     16webkit_web_extension_send_message_to_context
     17webkit_web_extension_send_message_to_context_finish
    1618
    1719<SUBSECTION Standard>
     
    3840webkit_web_page_get_main_frame
    3941webkit_web_page_get_editor
     42webkit_web_page_send_message_to_view
     43webkit_web_page_send_message_to_view_finish
    4044
    4145<SUBSECTION Standard>
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/wpe/webkit-web-extension.h

    r242312 r251181  
    3535#include <wpe/WebKitURIRequest.h>
    3636#include <wpe/WebKitURIResponse.h>
     37#include <wpe/WebKitUserMessage.h>
    3738#include <wpe/WebKitWebEditor.h>
    3839#include <wpe/WebKitWebExtension.h>
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r250946 r251181  
    269269struct LoadParameters;
    270270struct PrintInfo;
     271struct TextInputContext;
     272struct UserMessage;
    271273struct WebAutocorrectionData;
    272274struct WebAutocorrectionContext;
     
    16311633    void paintSnapshotAtSize(const WebCore::IntRect&, const WebCore::IntSize&, SnapshotOptions, WebCore::Frame&, WebCore::FrameView&, WebCore::GraphicsContext&);
    16321634
     1635#if PLATFORM(GTK) || PLATFORM(WPE)
     1636    void sendMessageToWebExtension(UserMessage&&);
     1637    void sendMessageToWebExtensionWithReply(UserMessage&&, CompletionHandler<void(UserMessage&&)>&&);
     1638#endif
     1639
    16331640    WebCore::PageIdentifier m_identifier;
    16341641
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in

    r250946 r251181  
    581581#endif
    582582
     583#if PLATFORM(GTK) || PLATFORM(WPE)
     584    SendMessageToWebExtension(struct WebKit::UserMessage userMessage)
     585    SendMessageToWebExtensionWithReply(struct WebKit::UserMessage userMessage) -> (struct WebKit::UserMessage replyMessage) Async
     586#endif
    583587}
  • trunk/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp

    r251179 r251181  
    11/*
    2  * Copyright (C) 2017 Igalia S.L.
     2 * Copyright (C) 2019 Igalia S.L.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #pragma once
     26#include "config.h"
     27#include "WebPage.h"
    2728
    28 typedef struct OpaqueJSContext* JSGlobalContextRef;
     29#include "UserMessage.h"
     30#include "WebKitExtensionManager.h"
     31#include "WebKitUserMessage.h"
     32#include "WebKitWebExtension.h"
     33#include "WebKitWebPagePrivate.h"
    2934
    3035namespace WebKit {
    31 class DownloadProxy;
     36
     37void WebPage::sendMessageToWebExtensionWithReply(UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
     38{
     39    auto* extension = WebKitExtensionManager::singleton().extension();
     40    if (!extension) {
     41        completionHandler(UserMessage(message.name, WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE));
     42        return;
     43    }
     44
     45    auto* page = webkit_web_extension_get_page(extension, m_identifier.toUInt64());
     46    if (!page) {
     47        completionHandler(UserMessage(message.name, WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE));
     48        return;
     49    }
     50
     51    webkitWebPageDidReceiveUserMessage(page, WTFMove(message), WTFMove(completionHandler));
    3252}
    3353
    34 namespace WKWPE {
    35 class View;
     54void WebPage::sendMessageToWebExtension(UserMessage&& message)
     55{
     56    sendMessageToWebExtensionWithReply(WTFMove(message), [](UserMessage&&) { });
    3657}
    3758
    38 namespace API {
    39 
    40 class ViewClient {
    41     WTF_MAKE_FAST_ALLOCATED;
    42 public:
    43     virtual ~ViewClient() = default;
    44 
    45     virtual void frameDisplayed(WKWPE::View&) { }
    46     virtual void handleDownloadRequest(WKWPE::View&, WebKit::DownloadProxy&) { }
    47     virtual void willStartLoad(WKWPE::View&) { }
    48     virtual void didChangePageID(WKWPE::View&) { }
    49 };
    50 
    51 } // namespace API
     59} // namespace WebKit
  • trunk/Source/WebKit/WebProcess/WebProcess.h

    r251146 r251181  
    118118class WebPage;
    119119class WebPageGroupProxy;
     120struct UserMessage;
    120121struct WebProcessCreationParameters;
    121122struct WebProcessDataStoreParameters;
     
    466467    void clearCurrentModifierStateForTesting();
    467468
     469#if PLATFORM(GTK) || PLATFORM(WPE)
     470    void sendMessageToWebExtension(UserMessage&&);
     471#endif
     472
    468473    RefPtr<WebConnectionToUIProcess> m_webConnection;
    469474
  • trunk/Source/WebKit/WebProcess/WebProcess.messages.in

    r251121 r251181  
    158158    UnblockAccessibilityServer(WebKit::SandboxExtension::Handle handle)
    159159#endif
     160
     161#if PLATFORM(GTK) || PLATFORM(WPE)
     162    SendMessageToWebExtension(struct WebKit::UserMessage userMessage)
     163#endif
    160164}
  • trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp

    r251122 r251181  
    2828#include "WebProcess.h"
    2929
     30#include "WebKitExtensionManager.h"
     31#include "WebKitWebExtensionPrivate.h"
    3032#include "WebProcessCreationParameters.h"
    3133
     
    98100}
    99101
     102void WebProcess::sendMessageToWebExtension(UserMessage&& message)
     103{
     104    if (auto* extension = WebKitExtensionManager::singleton().extension())
     105        webkitWebExtensionDidReceiveUserMessage(extension, WTFMove(message));
     106}
     107
    100108} // namespace WebKit
  • trunk/Tools/ChangeLog

    r251167 r251181  
     12019-10-15  Carlos Garcia Campos  <[email protected]>
     2
     3        [GTK][WPE] Add user messages API
     4        https://bugs.webkit.org/show_bug.cgi?id=202847
     5
     6        Reviewed by Adrian Perez de Castro.
     7
     8        Add a test to check the new API.
     9
     10        * TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp:
     11        (UserMessageTest::webViewUserMessageReceivedCallback):
     12        (UserMessageTest::webContextUserMessageReceivedCallback):
     13        (UserMessageTest::UserMessageTest):
     14        (UserMessageTest::~UserMessageTest):
     15        (UserMessageTest::sendMessage):
     16        (UserMessageTest::sendMedssageToAllExtensions):
     17        (UserMessageTest::viewUserMessageReceived):
     18        (UserMessageTest::contextUserMessageReceived):
     19        (UserMessageTest::waitUntilViewMessageReceived):
     20        (UserMessageTest::waitUntilContextMessageReceived):
     21        (readFileDescritpor):
     22        (testWebExtensionUserMessages):
     23        (beforeAll):
     24        * TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp:
     25        (documentLoadedCallback):
     26        (pageMessageReceivedCallback):
     27        (pageCreatedCallback):
     28        (extensionMessageReceivedCallback):
     29        (webkit_web_extension_initialize_with_user_data):
     30
    1312019-10-15  Aakash Jain  <[email protected]>
    232
  • trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp

    r250646 r251181  
    2121
    2222#include "WebViewTest.h"
     23#include <gio/gunixfdlist.h>
    2324#include <wtf/glib/GRefPtr.h>
    2425
     
    538539}
    539540
     541class UserMessageTest : public WebViewTest {
     542public:
     543    MAKE_GLIB_TEST_FIXTURE(UserMessageTest);
     544
     545    static gboolean webViewUserMessageReceivedCallback(WebKitWebView*, WebKitUserMessage* message, UserMessageTest* test)
     546    {
     547        return test->viewUserMessageReceived(message);
     548    }
     549
     550    static gboolean webContextUserMessageReceivedCallback(WebKitWebContext*, WebKitUserMessage* message, UserMessageTest* test)
     551    {
     552        return test->contextUserMessageReceived(message);
     553    }
     554
     555    UserMessageTest()
     556    {
     557        g_signal_connect(m_webContext.get(), "user-message-received", G_CALLBACK(webContextUserMessageReceivedCallback), this);
     558        g_signal_connect(m_webView, "user-message-received", G_CALLBACK(webViewUserMessageReceivedCallback), this);
     559    }
     560
     561    ~UserMessageTest()
     562    {
     563        g_signal_handlers_disconnect_matched(m_webContext.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
     564        g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
     565    }
     566
     567    WebKitUserMessage* sendMessage(WebKitUserMessage* message, GError** error = nullptr)
     568    {
     569        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
     570        m_receivedViewMessage = nullptr;
     571        webkit_web_view_send_message_to_page(m_webView, message, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
     572            auto* test = static_cast<UserMessageTest*>(userData);
     573            test->m_receivedViewMessage = adoptGRef(webkit_web_view_send_message_to_page_finish(test->m_webView, result, &test->m_receivedError.outPtr()));
     574            if (test->m_receivedViewMessage)
     575                test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(test->m_receivedViewMessage.get()));
     576            else
     577                g_assert_nonnull(test->m_receivedError.get());
     578            test->quitMainLoop();
     579        }, this);
     580        g_main_loop_run(m_mainLoop);
     581        if (error)
     582            *error = m_receivedError.get();
     583        return m_receivedViewMessage.get();
     584    }
     585
     586    void sendMessageToAllExtensions(WebKitUserMessage* message)
     587    {
     588        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
     589        webkit_web_context_send_message_to_all_extensions(m_webContext.get(), message);
     590    }
     591
     592    bool viewUserMessageReceived(WebKitUserMessage* message)
     593    {
     594        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
     595        if (!g_strcmp0(m_expectedViewMessageName.data(), webkit_user_message_get_name(message))) {
     596            m_receivedViewMessage = message;
     597            quitMainLoop();
     598
     599            return true;
     600        }
     601
     602        return false;
     603    }
     604
     605    bool contextUserMessageReceived(WebKitUserMessage* message)
     606    {
     607        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
     608        if (!g_strcmp0(m_expectedContextMessageName.data(), webkit_user_message_get_name(message))) {
     609            m_receivedContextMessage = message;
     610            quitMainLoop();
     611
     612            return true;
     613        }
     614
     615        return false;
     616    }
     617
     618    WebKitUserMessage* waitUntilViewMessageReceived(const char* messageName)
     619    {
     620        m_expectedViewMessageName = messageName;
     621        g_main_loop_run(m_mainLoop);
     622        m_expectedViewMessageName = { };
     623        return m_receivedViewMessage.get();
     624    }
     625
     626    WebKitUserMessage* waitUntilContextMessageReceived(const char* messageName)
     627    {
     628        m_expectedContextMessageName = messageName;
     629        g_main_loop_run(m_mainLoop);
     630        m_expectedContextMessageName = { };
     631        return m_receivedContextMessage.get();
     632    }
     633
     634    GRefPtr<WebKitUserMessage> m_receivedViewMessage;
     635    GRefPtr<WebKitUserMessage> m_receivedContextMessage;
     636    GUniqueOutPtr<GError> m_receivedError;
     637    CString m_expectedViewMessageName;
     638    CString m_expectedContextMessageName;
     639};
     640
     641static bool readFileDescriptor(int fd, char** contents, gsize* length)
     642{
     643    GString* bufferString = g_string_new(nullptr);
     644    while (true) {
     645        gchar buffer[4096];
     646        gssize bytesRead = read(fd, buffer, sizeof(buffer));
     647        if (bytesRead == -1) {
     648            if (errno == EAGAIN || errno == EWOULDBLOCK)
     649                continue;
     650
     651            g_string_free(bufferString, TRUE);
     652
     653            return false;
     654        }
     655
     656        if (!bytesRead)
     657            break;
     658
     659        g_string_append_len(bufferString, buffer, bytesRead);
     660    }
     661
     662    *length = bufferString->len;
     663    *contents = g_string_free(bufferString, FALSE);
     664
     665    return true;
     666}
     667
     668static void testWebExtensionUserMessages(UserMessageTest* test, gconstpointer)
     669{
     670    // Normal message with a reply.
     671    auto* message = webkit_user_message_new("Test.Hello", g_variant_new("s", "WebProcess"));
     672    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "Test.Hello");
     673    auto* parameters = webkit_user_message_get_parameters(message);
     674    g_assert_nonnull(parameters);
     675    const char* parameter = nullptr;
     676    g_variant_get(parameters, "&s", &parameter);
     677    g_assert_cmpstr(parameter, ==, "WebProcess");
     678    g_assert_null(webkit_user_message_get_fd_list(message));
     679    auto* reply = test->sendMessage(message);
     680    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
     681    g_assert_cmpstr(webkit_user_message_get_name(reply), ==, "Test.Hello");
     682    parameters = webkit_user_message_get_parameters(reply);
     683    g_assert_nonnull(parameters);
     684    parameter = nullptr;
     685    g_variant_get(parameters, "&s", &parameter);
     686    g_assert_cmpstr(parameter, ==, "UIProcess");
     687    g_assert_null(webkit_user_message_get_fd_list(reply));
     688
     689    // Message with no parameters.
     690    message = webkit_user_message_new("Test.Ping", nullptr);
     691    g_assert_null(webkit_user_message_get_parameters(message));
     692    reply = test->sendMessage(message);
     693    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
     694    g_assert_cmpstr(webkit_user_message_get_name(reply), ==, "Test.Pong");
     695    g_assert_null(webkit_user_message_get_parameters(reply));
     696
     697    // Message with maybe type in parameters.
     698    message = webkit_user_message_new("Test.Optional", g_variant_new("(sms)", "Hello", "World"));
     699    reply = test->sendMessage(message);
     700    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
     701    g_assert_cmpstr(webkit_user_message_get_name(reply), ==, "Test.Optional");
     702    parameters = webkit_user_message_get_parameters(reply);
     703    g_assert_nonnull(parameters);
     704    g_variant_get(parameters, "&s", &parameter);
     705    g_assert_cmpstr(parameter, ==, "World");
     706    message = webkit_user_message_new("Test.Optional", g_variant_new("(sms)", "Hello", nullptr));
     707    reply = test->sendMessage(message);
     708    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
     709    g_assert_cmpstr(webkit_user_message_get_name(reply), ==, "Test.Optional");
     710    parameters = webkit_user_message_get_parameters(reply);
     711    g_assert_nonnull(parameters);
     712    g_variant_get(parameters, "&s", &parameter);
     713    g_assert_cmpstr(parameter, ==, "NULL");
     714
     715    // Message with file descriptors.
     716    GUniquePtr<char> filename(g_build_filename(Test::getResourcesDir().data(), "simple.json", nullptr));
     717    reply = test->sendMessage(webkit_user_message_new("Test.OpenFile", g_variant_new("s", filename.get())));
     718    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
     719    parameters = webkit_user_message_get_parameters(reply);
     720    g_assert_nonnull(parameters);
     721    gint32 handle;
     722    g_variant_get(parameters, "h", &handle);
     723    g_assert_cmpint(handle, ==, 0);
     724    auto* fdList = webkit_user_message_get_fd_list(reply);
     725    g_assert_true(G_IS_UNIX_FD_LIST(fdList));
     726    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(fdList));
     727    g_assert_cmpint(g_unix_fd_list_get_length(fdList), ==, 1);
     728    GUniqueOutPtr<GError> error;
     729    int fd = g_unix_fd_list_get(fdList, handle, &error.outPtr());
     730    g_assert_cmpint(fd, !=, -1);
     731    g_assert_no_error(error.get());
     732    GUniqueOutPtr<char> fdContents;
     733    gsize fdContentsLength;
     734    g_assert_true(readFileDescriptor(fd, &fdContents.outPtr(), &fdContentsLength));
     735    close(fd);
     736    GUniqueOutPtr<char> fileContents;
     737    gsize fileContentsLength;
     738    g_assert_true(g_file_get_contents(filename.get(), &fileContents.outPtr(), &fileContentsLength, nullptr));
     739    g_assert_cmpmem(fdContents.get(), fdContentsLength, fileContents.get(), fileContentsLength);
     740
     741    // Unhandled message.
     742    GError* messageError = nullptr;
     743    reply = test->sendMessage(webkit_user_message_new("Test.Invalid", nullptr), &messageError);
     744    g_assert_null(reply);
     745    g_assert_error(messageError, WEBKIT_USER_MESSAGE_ERROR, WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE);
     746
     747    // Message that is never replied.
     748    GRefPtr<WebKitWebView> webView = WEBKIT_WEB_VIEW(Test::createWebView(test->m_webContext.get()));
     749    webkit_web_view_send_message_to_page(webView.get(), webkit_user_message_new("Test.Infinite", nullptr), nullptr,
     750        [](GObject* object, GAsyncResult* result, gpointer userData) {
     751            auto* test = static_cast<UserMessageTest*>(userData);
     752            GUniqueOutPtr<GError> error;
     753            g_assert_null(webkit_web_view_send_message_to_page_finish(WEBKIT_WEB_VIEW(object), result, &error.outPtr()));
     754            g_assert_error(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED);
     755            test->quitMainLoop();
     756        }, test);
     757    g_main_loop_run(test->m_mainLoop);
     758
     759    // Wait for received message.
     760    test->loadHtml("<html><body></body></html>", nullptr);
     761    message = test->waitUntilViewMessageReceived("DocumentLoaded");
     762    g_assert_true(WEBKIT_IS_USER_MESSAGE(message));
     763    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "DocumentLoaded");
     764
     765    // Reply to a message received from the web process.
     766    webkit_web_view_send_message_to_page(test->m_webView, webkit_user_message_new("Test.AsyncPing", nullptr), nullptr, nullptr, nullptr);
     767    message = test->waitUntilViewMessageReceived("Test.Ping");
     768    g_assert_true(WEBKIT_IS_USER_MESSAGE(message));
     769    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "Test.Ping");
     770    webkit_user_message_send_reply(message, webkit_user_message_new("Test.Pong", nullptr));
     771    message = test->waitUntilViewMessageReceived("Test.AsyncPong");
     772    g_assert_true(WEBKIT_IS_USER_MESSAGE(message));
     773    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "Test.AsyncPong");
     774
     775    // Create a new page and wait for page created message.
     776    webView = WEBKIT_WEB_VIEW(Test::createWebView(test->m_webContext.get()));
     777    webkit_web_view_load_html(webView.get(), "<html><body></body></html>", nullptr);
     778    message = test->waitUntilContextMessageReceived("PageCreated");
     779    g_assert_true(WEBKIT_IS_USER_MESSAGE(message));
     780    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "PageCreated");
     781    parameters = webkit_user_message_get_parameters(message);
     782    g_assert_nonnull(parameters);
     783    guint64 pageID;
     784    g_variant_get(parameters, "(t)", &pageID);
     785    g_assert_cmpuint(pageID, ==, webkit_web_view_get_page_id(webView.get()));
     786
     787    // Request to start a ping to all processes.
     788    test->sendMessageToAllExtensions(webkit_user_message_new("Test.RequestPing", nullptr));
     789    // We should received two ping requests.
     790    GRefPtr<WebKitUserMessage> ping1 = test->waitUntilContextMessageReceived("Ping");
     791    GRefPtr<WebKitUserMessage> ping2 = test->waitUntilContextMessageReceived("Ping");
     792    webkit_user_message_send_reply(ping1.get(), webkit_user_message_new("Pong", nullptr));
     793    test->waitUntilContextMessageReceived("Test.FinishedPingRequest");
     794    webkit_user_message_send_reply(ping2.get(), webkit_user_message_new("Pong", nullptr));
     795    test->waitUntilContextMessageReceived("Test.FinishedPingRequest");
     796}
     797
    540798void beforeAll()
    541799{
     
    554812    FormSubmissionTest::add("WebKitWebExtension", "form-submission-steps", testWebExtensionFormSubmissionSteps);
    555813    WebViewTest::add("WebKitWebExtension", "page-id", testWebExtensionPageID);
     814    UserMessageTest::add("WebKitWebExtension", "user-messages", testWebExtensionUserMessages);
    556815}
    557816
  • trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp

    r249759 r251181  
    2222#include <JavaScriptCore/JSContextRef.h>
    2323#include <JavaScriptCore/JSRetainPtr.h>
     24#include <fcntl.h>
    2425#include <gio/gio.h>
     26#include <gio/gunixfdlist.h>
     27#include <glib/gstdio.h>
    2528#if USE(GSTREAMER)
    2629#include <gst/gst.h>
     
    163166#endif
    164167
     168    webkit_web_page_send_message_to_view(webPage, webkit_user_message_new("DocumentLoaded", nullptr), nullptr, nullptr, nullptr);
     169
    165170    gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection");
    166171    if (data)
     
    417422}
    418423
     424static gboolean pageMessageReceivedCallback(WebKitWebPage* webPage, WebKitUserMessage* message, WebKitWebExtension* extension)
     425{
     426    const char* messageName = webkit_user_message_get_name(message);
     427    if (!g_strcmp0(messageName, "Test.Hello")) {
     428        auto* parameters = webkit_user_message_get_parameters(message);
     429        g_assert_nonnull(parameters);
     430        const char* parameter = nullptr;
     431        g_variant_get(parameters, "&s", &parameter);
     432        g_assert_cmpstr(parameter, ==, "WebProcess");
     433        g_assert_null(webkit_user_message_get_fd_list(message));
     434        webkit_user_message_send_reply(message, webkit_user_message_new("Test.Hello", g_variant_new("s", "UIProcess")));
     435        return TRUE;
     436    }
     437
     438    if (!g_strcmp0(messageName, "Test.Optional")) {
     439        auto* parameters = webkit_user_message_get_parameters(message);
     440        g_assert_nonnull(parameters);
     441        const char* parameter1 = nullptr;
     442        const char* parameter2 = nullptr;
     443        g_variant_get(parameters, "(&sm&s)", &parameter1, &parameter2);
     444        g_assert_cmpstr(parameter1, ==, "Hello");
     445        webkit_user_message_send_reply(message, webkit_user_message_new("Test.Optional", g_variant_new("s", parameter2 ? parameter2 : "NULL")));
     446        return TRUE;
     447    }
     448
     449    if (!g_strcmp0(messageName, "Test.Ping")) {
     450        g_assert_null(webkit_user_message_get_parameters(message));
     451        webkit_user_message_send_reply(message, webkit_user_message_new("Test.Pong", nullptr));
     452        return TRUE;
     453    }
     454
     455    if (!g_strcmp0(messageName, "Test.OpenFile")) {
     456        auto* parameters = webkit_user_message_get_parameters(message);
     457        g_assert_nonnull(parameters);
     458        const char* filename = nullptr;
     459        g_variant_get(parameters, "&s", &filename);
     460        int fd = g_open(filename, O_RDONLY, 0);
     461        g_assert_cmpint(fd, !=, -1);
     462        GRefPtr<GUnixFDList> fdList = adoptGRef(g_unix_fd_list_new());
     463        GUniqueOutPtr<GError> error;
     464        g_unix_fd_list_append(fdList.get(), fd, &error.outPtr());
     465        g_assert_no_error(error.get());
     466        close(fd);
     467
     468        webkit_user_message_send_reply(message, webkit_user_message_new_with_fd_list("Test.OpenFile", g_variant_new("h", 0), fdList.get()));
     469        return TRUE;
     470    }
     471
     472    if (!g_strcmp0(messageName, "Test.Infinite")) {
     473        abort();
     474        return TRUE;
     475    }
     476
     477    if (!g_strcmp0(messageName, "Test.AsyncPing")) {
     478        webkit_web_page_send_message_to_view(webPage, webkit_user_message_new("Test.Ping", nullptr), nullptr,
     479            [](GObject* object, GAsyncResult* result, gpointer) {
     480                auto* webPage = WEBKIT_WEB_PAGE(object);
     481                GUniqueOutPtr<GError> error;
     482                GRefPtr<WebKitUserMessage> reply = adoptGRef(webkit_web_page_send_message_to_view_finish(webPage, result, &error.outPtr()));
     483                g_assert_no_error(error.get());
     484                g_assert_cmpstr(webkit_user_message_get_name(reply.get()), ==, "Test.Pong");
     485                webkit_web_page_send_message_to_view(webPage, webkit_user_message_new("Test.AsyncPong", nullptr), nullptr, nullptr, nullptr);
     486            }, nullptr);
     487        return TRUE;
     488    }
     489
     490    return FALSE;
     491}
     492
    419493static void emitPageCreated(GDBusConnection* connection, guint64 pageID)
    420494{
     
    437511        delayedSignalsQueue.append(DelayedSignal(PageCreatedSignal, webkit_web_page_get_id(webPage)));
    438512
     513    webkit_web_extension_send_message_to_context(extension, webkit_user_message_new("PageCreated", g_variant_new("(t)", webkit_web_page_get_id(webPage))),
     514        nullptr, nullptr, nullptr);
     515
    439516    g_signal_connect(webPage, "document-loaded", G_CALLBACK(documentLoadedCallback), extension);
    440517    g_signal_connect(webPage, "notify::uri", G_CALLBACK(uriChangedCallback), extension);
     
    444521    g_signal_connect(webPage, "form-controls-associated-for-frame", G_CALLBACK(formControlsAssociatedForFrameCallback), extension);
    445522    g_signal_connect(webPage, "will-submit-form", G_CALLBACK(willSubmitFormCallback), extension);
     523    g_signal_connect(webPage, "user-message-received", G_CALLBACK(pageMessageReceivedCallback), extension);
     524}
     525
     526static gboolean extensionMessageReceivedCallback(WebKitWebExtension* extension, WebKitUserMessage* message)
     527{
     528    const char* messageName = webkit_user_message_get_name(message);
     529    if (g_strcmp0(messageName, "RequestPing")) {
     530        webkit_web_extension_send_message_to_context(extension, webkit_user_message_new("Ping", nullptr), nullptr,
     531            [](GObject* object, GAsyncResult* result, gpointer) {
     532                auto* extension = WEBKIT_WEB_EXTENSION(object);
     533                GUniqueOutPtr<GError> error;
     534                GRefPtr<WebKitUserMessage> reply = adoptGRef(webkit_web_extension_send_message_to_context_finish(extension, result, &error.outPtr()));
     535                g_assert_no_error(error.get());
     536                g_assert_cmpstr(webkit_user_message_get_name(reply.get()), ==, "Pong");
     537                webkit_web_extension_send_message_to_context(extension, webkit_user_message_new("Test.FinishedPingRequest", nullptr), nullptr, nullptr, nullptr);
     538            }, nullptr);
     539        return TRUE;
     540    }
     541
     542    return FALSE;
    446543}
    447544
     
    615712    g_object_set_data_full(G_OBJECT(extension), "wk-script-world", isolatedWorld, g_object_unref);
    616713
     714    g_signal_connect(extension, "user-message-received", G_CALLBACK(extensionMessageReceivedCallback), nullptr);
    617715    g_signal_connect(extension, "page-created", G_CALLBACK(pageCreatedCallback), extension);
    618716    g_signal_connect(webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(windowObjectCleared), nullptr);
Note: See TracChangeset for help on using the changeset viewer.