WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
202847
[GTK][WPE] Add user messages API
https://bugs.webkit.org/show_bug.cgi?id=202847
Summary
[GTK][WPE] Add user messages API
Carlos Garcia Campos
Reported
2019-10-11 05:09:25 PDT
We have never exposed an API to send/receive message 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.
Attachments
Patch
(128.36 KB, patch)
2019-10-11 05:18 PDT
,
Carlos Garcia Campos
no flags
Details
Formatted Diff
Diff
Patch
(133.28 KB, patch)
2019-10-14 03:05 PDT
,
Carlos Garcia Campos
no flags
Details
Formatted Diff
Diff
Patch
(132.69 KB, patch)
2019-10-14 03:44 PDT
,
Carlos Garcia Campos
no flags
Details
Formatted Diff
Diff
Patch
(132.95 KB, patch)
2019-10-15 02:03 PDT
,
Carlos Garcia Campos
no flags
Details
Formatted Diff
Diff
Patch
(134.84 KB, patch)
2019-10-15 08:20 PDT
,
Carlos Garcia Campos
aperez
: review+
aperez
: commit-queue-
Details
Formatted Diff
Diff
Show Obsolete
(4)
View All
Add attachment
proposed patch, testcase, etc.
Milan Crha
Comment 1
2019-10-11 05:14:37 PDT
The way I did it recently in Evolution was that I use JSC for the communication on both sides. If the script wants to say something to the client side, it does so through a custom signal of
> window.webkit.messageHandlers.MYSIGNAL.postMessage(data);
to which the client side listens. And when the client side wants to say something to the extension, (well, I do not talk to the extension, I only call javascript routines loaded in the extension), I just use javascript calls too. I mean, there are ways to rely on WebKit's IPC already.
Carlos Garcia Campos
Comment 2
2019-10-11 05:18:51 PDT
Created
attachment 380746
[details]
Patch
EWS Watchlist
Comment 3
2019-10-11 05:19:38 PDT
Thanks for the patch. If this patch contains new public API please make sure it follows the guidelines for new WebKit2 GTK+ API. See
http://trac.webkit.org/wiki/WebKitGTK/AddingNewWebKit2API
Carlos Garcia Campos
Comment 4
2019-10-11 05:19:52 PDT
For now, I've only used the unit tests to check the API. I'll port ephy to use it too.
Carlos Garcia Campos
Comment 5
2019-10-11 05:23:52 PDT
(In reply to Milan Crha from
comment #1
)
> The way I did it recently in Evolution was that I use JSC for the > communication on both sides. If the script wants to say something to the > client side, it does so through a custom signal of > > > window.webkit.messageHandlers.MYSIGNAL.postMessage(data); > > to which the client side listens. And when the client side wants to say > something to the extension, (well, I do not talk to the extension, I only > call javascript routines loaded in the extension), I just use javascript > calls too. > > I mean, there are ways to rely on WebKit's IPC already.
Yes, that's what we have suggested to do for simple cases to avoid having to implement your own IPC. But that's more limited, and doesn't cover all the cases. Epiphany does the same, but it still needs to use DBus for other cases. The new API will make both cases a lot easier in any case.
Adrian Perez
Comment 6
2019-10-11 06:37:51 PDT
Comment on
attachment 380746
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=380746&action=review
This looks really great, thanks for working on it, Carlos! I have some use-cases in mind where this will come in very handy and allow removing custom-written IPC code from applications. Kudos for reusing GVariant to carry data around, and for future-proofing the feature by allowing passing file descriptors around. I just have one small nit/doubt/suggestion below :)
> Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:162 > + * after the message has been sent.
Maybe we want to explicitly have a note indicating that... “If the sender needs to keep the file descriptor, `dup(2)` can be used to send a new descriptor referring to the same data.” I suggest this because my first thought was “what if I need to keep referring to some shared data in both processes” and it took me a minute to realize how to do it. Maybe for many people it's obvious, but it won't hurt pointing it out, I think.
> Source/WebKit/Shared/glib/UserMessage.cpp:50 > + GRefPtr<GDBusMessage> message = adoptGRef(g_dbus_message_new_method_call(nullptr, "/", nullptr, "_"));
Is there any advantage here in abusing GDBusMessage over sending directly a blob of bytes with the GVariant type and the payload? Roughly, I am thinking of something like this: const GvariantType *payloadType = g_variant_get_type(parameters.get()); encoder << IPC::DataReference(g_variant_type_peek_string(payloadType), g_variant_type_get_string_length(payloadType)); encoder << IPC::DataReference(g_variant_get_data(parameters.get(), g_variant_get_size(parameters.get()); This doesn't incur in any allocations in the best case, and only one in the worst case for the buffer where the GVariant gets serialized on demand if needed. Using GDBusMessage involves an additional GObject (and its allocations and deallocations), for no added benefit (I think).
> Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp:2105 > + * and the message has been replied, the operation in the #WebKitWebPage will
From the context I suppose that this is supposed to be “…and the message has not been replied…” ^^^
Michael Catanzaro
Comment 7
2019-10-11 07:42:04 PDT
Comment on
attachment 380746
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=380746&action=review
>> Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp:2105 >> + * and the message has been replied, the operation in the #WebKitWebPage will > > From the context I suppose that this is supposed to be > > “…and the message has not been replied…” > ^^^
"not been replied to"
Carlos Garcia Campos
Comment 8
2019-10-14 01:09:50 PDT
Comment on
attachment 380746
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=380746&action=review
>> Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:162 >> + * after the message has been sent. > > Maybe we want to explicitly have a note indicating that... > > “If the sender needs to keep the file descriptor, `dup(2)` > can be used to send a new descriptor referring to the same > data.” > > I suggest this because my first thought was “what if I need to keep > referring to some shared data in both processes” and it took me a > minute to realize how to do it. Maybe for many people it's obvious, > but it won't hurt pointing it out, I think.
Or we could always dup and avoid confusions. I decided to steal mainly because I think of WebKitUserMessage as a temp object (that's also why it's initially unowned), that you don't care about after being sent.
>> Source/WebKit/Shared/glib/UserMessage.cpp:50 >> + GRefPtr<GDBusMessage> message = adoptGRef(g_dbus_message_new_method_call(nullptr, "/", nullptr, "_")); > > Is there any advantage here in abusing GDBusMessage over sending > directly a blob of bytes with the GVariant type and the payload? > Roughly, I am thinking of something like this: > > const GvariantType *payloadType = g_variant_get_type(parameters.get()); > encoder << IPC::DataReference(g_variant_type_peek_string(payloadType), > g_variant_type_get_string_length(payloadType)); > encoder << IPC::DataReference(g_variant_get_data(parameters.get(), > g_variant_get_size(parameters.get()); > > This doesn't incur in any allocations in the best case, and only one in the > worst case for the buffer where the GVariant gets serialized on demand if > needed. Using GDBusMessage involves an additional GObject (and its allocations > and deallocations), for no added benefit (I think).
I decided to follow the same rules as a DBus message, and using GDBusMessage we avoided copying the serialization code. But there's actually no good reason for that, we could use GVariant data directly and remove all the restrictions of a DBus message (it must be a tuple with only complete types).
>>> Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp:2105 >>> + * and the message has been replied, the operation in the #WebKitWebPage will >> >> From the context I suppose that this is supposed to be >> >> “…and the message has not been replied…” >> ^^^ > > "not been replied to"
Right!
Carlos Garcia Campos
Comment 9
2019-10-14 03:05:33 PDT
Created
attachment 380864
[details]
Patch
Carlos Garcia Campos
Comment 10
2019-10-14 03:34:47 PDT
(In reply to Carlos Garcia Campos from
comment #8
)
> Comment on
attachment 380746
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=380746&action=review
> > >> Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:162 > >> + * after the message has been sent. > > > > Maybe we want to explicitly have a note indicating that... > > > > “If the sender needs to keep the file descriptor, `dup(2)` > > can be used to send a new descriptor referring to the same > > data.” > > > > I suggest this because my first thought was “what if I need to keep > > referring to some shared data in both processes” and it took me a > > minute to realize how to do it. Maybe for many people it's obvious, > > but it won't hurt pointing it out, I think. > > Or we could always dup and avoid confusions. I decided to steal mainly > because I think of WebKitUserMessage as a temp object (that's also why it's > initially unowned), that you don't care about after being sent.
I've realized that we should always dup, otherwise it would be impossible to send a message with fds using webkit_web_context_send_message_to_all_extensions(). I'll update the patch.
Carlos Garcia Campos
Comment 11
2019-10-14 03:44:54 PDT
Created
attachment 380871
[details]
Patch
Carlos Garcia Campos
Comment 12
2019-10-14 08:48:38 PDT
This is how ephy code would be using this API:
https://gitlab.gnome.org/GNOME/epiphany/commit/87578a124becb345b0079879562203a2674f243b
10 files changed, 380 insertions(+), 999 deletions(-) delete mode 100644 embed/ephy-web-process-extension-proxy.c delete mode 100644 embed/ephy-web-process-extension-proxy.h
Carlos Garcia Campos
Comment 13
2019-10-15 02:03:12 PDT
Created
attachment 380972
[details]
Patch
Michael Catanzaro
Comment 14
2019-10-15 04:42:51 PDT
Comment on
attachment 380972
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=380972&action=review
LGTM. I'll leave r+ for Adrian, though.
> Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:46 > + * and Web extensions. A WebKitUserMessage always have a name, and it can also include parameters and
We've never capitalized web before, at least not in web process or web extension. I wouldn't start now. Also: have -> has
> Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:49 > + * corresponding #WebKitWebPage (and vice versa). One to one messages can be replied directly with
"replied to"
> Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:299 > + GRefPtr<WebKitUserMessage> adoptedReply = reply;
Probably a good idea to add your one-line comment about sinking the message here, since you did everywhere else, and it's not obvious.
> Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp:46 > +bool decode(Decoder& decoder, GRefPtr<GVariant>& variant)
Shouldn't it return Optional<GRefPtr<GVariant>&>, using Optional return instead of an out parameter, as you did for the UserMessage class? I think this is an old-style decoder that we're supposed to be moving away from, when you used the modern style in UserMessage.
> Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebExtension.cpp:162 > + * replied. Calling webkit_user_message_send_reply() will do nothing.
replied to.
> Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp:586 > + void sendMedssageToAllExtensions(WebKitUserMessage* message)
Medssage -> Message
> Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp:641 > +static bool readFileDescritpor(int fd, char** contents, gsize* length)
Descritpor -> Descriptor
Carlos Garcia Campos
Comment 15
2019-10-15 05:29:16 PDT
(In reply to Michael Catanzaro from
comment #14
)
> Comment on
attachment 380972
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=380972&action=review
> > LGTM. I'll leave r+ for Adrian, though.
Thanks!
> > Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:46 > > + * and Web extensions. A WebKitUserMessage always have a name, and it can also include parameters and > > We've never capitalized web before, at least not in web process or web > extension. I wouldn't start now.
I don't know who corrected me recently changing web to Web somewhere, anyway let's be consistent in our docs, I'll change it.
> Also: have -> has
Oops.
> > Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:49 > > + * corresponding #WebKitWebPage (and vice versa). One to one messages can be replied directly with > > "replied to"
Ok.
> > Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:299 > > + GRefPtr<WebKitUserMessage> adoptedReply = reply; > > Probably a good idea to add your one-line comment about sinking the message > here, since you did everywhere else, and it's not obvious.
Didn't add it in this case because I thought the adopted prefix in the name was self-explanatory. I'll add the comment in any case, it won't hurt.
> > Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp:46 > > +bool decode(Decoder& decoder, GRefPtr<GVariant>& variant) > > Shouldn't it return Optional<GRefPtr<GVariant>&>, using Optional return > instead of an out parameter, as you did for the UserMessage class? I think > this is an old-style decoder that we're supposed to be moving away from, > when you used the modern style in UserMessage.
Right, I'll use Optional instead.
> > Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebExtension.cpp:162 > > + * replied. Calling webkit_user_message_send_reply() will do nothing. > > replied to.
Ok.
> > Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp:586 > > + void sendMedssageToAllExtensions(WebKitUserMessage* message) > > Medssage -> Message
Oops.
> > Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp:641 > > +static bool readFileDescritpor(int fd, char** contents, gsize* length) > > Descritpor -> Descriptor
You are good catching my typos :-D
Michael Catanzaro
Comment 16
2019-10-15 06:50:32 PDT
(In reply to Carlos Garcia Campos from
comment #15
)
> I don't know who corrected me recently changing web to Web somewhere, anyway > let's be consistent in our docs, I'll change it.
That was Adrian... we had a little argument about that afterwards. I hope I've successfully argued my case for lowercase web. :P
> > > Source/WebKit/Shared/API/glib/WebKitUserMessage.cpp:299 > > > + GRefPtr<WebKitUserMessage> adoptedReply = reply; > > > > Probably a good idea to add your one-line comment about sinking the message > > here, since you did everywhere else, and it's not obvious. > > Didn't add it in this case because I thought the adopted prefix in the name > was self-explanatory. I'll add the comment in any case, it won't hurt.
I didn't notice, but that arguably makes it even worse because people might assume from the variable name that you forgot to adopt the ref.
> You are good catching my typos :-D
I think you use copy/paste more than I do. It's easy to make a typo once, when declaring or calling a function, but it's rare that I make the same typo in both places. So normally the compiler yells when I mess up. But if you use Ctrl+V to paste the function name, typos can go unnoticed.
Adrian Perez
Comment 17
2019-10-15 06:58:36 PDT
(In reply to Michael Catanzaro from
comment #16
)
> (In reply to Carlos Garcia Campos from
comment #15
) > > I don't know who corrected me recently changing web to Web somewhere, anyway > > let's be consistent in our docs, I'll change it. > > That was Adrian... we had a little argument about that afterwards. I hope > I've successfully argued my case for lowercase web :P
It was me, indeed. In the end we agreed that it's okay to use lowercase, in 2019 The Web™ is not such a special thing anymore after all :-) That way we also avoid the ugly looking “GNOME Web Web browser” expression (“GNOME Web web browser” looks a bit better), and we don't have to change all the lowercase occurrences that were already in the code.
Adrian Perez
Comment 18
2019-10-15 07:29:44 PDT
Comment on
attachment 380972
[details]
Patch I had already a good feeling about this patch, and after reading the MR uses the API in Epiphany I am truly convinced that having this in WebKit{GTK,WPE} will be beneficial for most (if not all) applications which are using WebExtensions. Really nice work :D One last thing, could you please add also a definition to allow usage of g_autoptr() for WebKitUserMessage in Source/WebKit/UIProcess/API/{gtk,wpe}/WebKitAutocleanups.h and Source/WebKit/WebProcess/InjectedBundle/API/{gtk,wpe}/WebKitWebExtensionAutocleanups.h? With that, and the changes suggested by Michael, I think this will be ready for landing 👍
Carlos Garcia Campos
Comment 19
2019-10-15 07:53:55 PDT
(In reply to Adrian Perez from
comment #18
)
> Comment on
attachment 380972
[details]
> Patch > > I had already a good feeling about this patch, and after reading > the MR uses the API in Epiphany I am truly convinced that having > this in WebKit{GTK,WPE} will be beneficial for most (if not all) > applications which are using WebExtensions. Really nice work :D > > One last thing, could you please add also a definition to allow > usage of g_autoptr() for WebKitUserMessage in > Source/WebKit/UIProcess/API/{gtk,wpe}/WebKitAutocleanups.h and > Source/WebKit/WebProcess/InjectedBundle/API/{gtk,wpe}/ > WebKitWebExtensionAutocleanups.h?
Sure, I always forget the auto cleanups thing.
> With that, and the changes suggested by Michael, I think this will > be ready for landing 👍
\o/
Carlos Garcia Campos
Comment 20
2019-10-15 08:20:37 PDT
Created
attachment 380987
[details]
Patch
Adrian Perez
Comment 21
2019-10-15 15:17:23 PDT
Comment on
attachment 380987
[details]
Patch Just one minor nit: the autocleanup definitions are still missing from Source/WebKit/WebProcess/InjectedBundle/API/{gtk,wpe}/WebKitWebExtensionAutocleanups.h Please add them before landing :)
Carlos Garcia Campos
Comment 22
2019-10-16 00:06:31 PDT
(In reply to Adrian Perez from
comment #21
)
> Comment on
attachment 380987
[details]
> Patch > > Just one minor nit: the autocleanup definitions are still missing from > Source/WebKit/WebProcess/InjectedBundle/API/{gtk,wpe}/ > WebKitWebExtensionAutocleanups.h > Please add them before landing :)
Are you sure we have to duplicate them? We don't do that for all other shared objects. Wouldn't we end up with duplicated symbols? it's the same library in the end.
Carlos Garcia Campos
Comment 23
2019-10-16 00:36:35 PDT
Committed
r251181
: <
https://trac.webkit.org/changeset/251181
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug