You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cordova.apache.org by Niklas Merz <ni...@apache.org> on 2026/01/17 16:45:14 UTC
How does plugin bridge work actually?
Hey everyone,
As some of you know I'm currently trying out if Servo can be used in
Cordova Android. I've made some good progress on my plugin [1] and now I
could use some help with getting plugins going.
If got the bride working with some hacky glue code and now some messages
like this are exchanged:
[ServoWS] Call to prompt []
gap:[1670500204,"Battery","start","Battery1880458036"] servo-bridge.js
<http://localhost:5000/plugins/cordova-plugin-servo-webview/www/servo-
bridge.js> [ServoWS] Intercepted gap: call [1670500204, "Battery",
"start", "Battery1880458036"] servo-bridge.js
<http://localhost:5000/plugins/cordova-plugin-servo-webview/www/servo-
bridge.js> [ServoWS] Call to prompt [false]
gap:[1670500204,"Geolocation","getPermission","Geolocation1880458037"]
servo-bridge.js <http://localhost:5000/plugins/cordova-plugin-servo-
webview/www/servo-bridge.js> [ServoWS] Intercepted gap: call
[1670500204, "Geolocation", "getPermission", "Geolocation1880458037"]
servo-bridge.js <http://localhost:5000/plugins/cordova-plugin-servo-
webview/www/servo-bridge.js> [ServoWS] Received message: 51 S11
Battery1880458036 {"level":59,"isPlugged":true}29 S01
Geolocation1880458037 n36 servo-bridge.js
<http://localhost:5000/plugins/cordova-plugin-servo-webview/www/servo-
bridge.js>
Can someone can point me to any kind documentation on how the plugin
bridge works? I've never looked into the part and if someone has any
info I could save some time digging through the code and reverse
engineering stuff.
The chances are slim, I know, but maybe there is something out there.
Cheers,
Niklas
[1] <https://github.com/NiklasMerz/cordova-plugin-servo-webview>
Re: How does plugin bridge work actually?
Posted by Darryl Pogue <da...@dpogue.ca>.
The parsing of messages from JS -> Platform is done here:
https://github.com/apache/cordova-android/blob/8c8fbc9a50ea23acc25501973a9ad551d68051f8/framework/src/org/apache/cordova/CordovaBridge.java#L133-L137
The construction of response messages from Platform -> JS is done here:
https://github.com/apache/cordova-android/blob/8c8fbc9a50ea23acc25501973a9ad551d68051f8/framework/src/org/apache/cordova/NativeToJsMessageQueue.java#L443-L501
The prompt bridge is very very old, and exists because at the time,
Android WebView didn't have any APIs for adding JS interfaces either,
so intercepting specially-formatted prompt commands was the best
option available.
On Sat, Jan 17, 2026 at 11:07 AM julio cesar sanchez
<jc...@gmail.com> wrote:
>
> Try searching on the mail list, there should be information there. And
> probably in JIRA too.
>
> I’m a little familiar with the addJavascriptInterface bridge, but not with
> the prompt bridge, there are several bridges and the prompt bridge was used
> in old android versions only and I never looked into it.
>
> El El sáb, 17 ene 2026 a las 18:28, Niklas Merz <ni...@apache.org>
> escribió:
>
> > Great thank you. This confirms a lot I found during my digging.
> >
> > You're right I've opted to hack into the prompt method to use it with
> > Websockets because this is currently the only thing that's possible with
> > Servo. Servo lacks addJavascriptInterface and evaluateJavascript today.
> >
> > Did you ever find how out how these messages are built? What things like
> > "51 S11 Battery..." mean? I suppose "S" is for success but I'll still
> > have to figure out how to correctly split and parse these prompt
> > messages.
> >
> > On January 17, 2026, "dev@cordova.apache.org" <de...@cordova.apache.org>
> > wrote:
> > > I don't think there is any documentation but I've done quite a bit of
> > > reverse engineering myself in the past and might be able to loosely
> > > explain the architecture. There are 3 classes that are probably of
> > > interest to look at in the cordova-android framework:
> > >
> > > 1. SystemWebChromeClient
> > > 2. SystemExposedJsApi
> > > 3. CordovaBridge
> > >
> > > Based on my understanding, SystemWebViewEngine contains the entry
> > > point
> > > into native side, by using the onJsPrompt hook. This method is
> > > normally
> > > to handle window.prompt calls but Cordova uses it to deliver a payload
> > > to native. The payload is passed to CordovaBridge and it decides if it
> > > is a bridge call or if it is a regular window.prompt call.
> > >
> > > If it is a bridge call, it does some sanity access checks and pushes
> > > the messages through a queue system which gets routed to plugins
> > > (somehow).
> > >
> > > SystemExposedJsApi has some JavascriptInterface methods, which are
> > > methods exposed directly to the webiew, and JS can call these methods
> > > directly which controls bridge state. It also includes a `exec`
> > > JavascriptInterface method, which seems to deliver a payload to the
> > > bridge, similar to the prompt method. Both of these might be used, and
> > > to me it looks like the bridge call implementation strategy might be
> > > swapped based on certain conditions.
> > >
> > > Although based on your log snippets, it seems like it is using the
> > > prompt method.
> > >
> > > Hopefully this at least puts your focus in the right direction.
> > >
> > > On Sat, 2026-01-17 at 17:45 +0100, Niklas Merz wrote:
> > > > Hey everyone,
> > > >
> > > > As some of you know I'm currently trying out if Servo can be used in
> > > > Cordova Android. I've made some good progress on my plugin [1] and
> > > > now I
> > > > could use some help with getting plugins going.
> > > >
> > > > If got the bride working with some hacky glue code and now some
> > > > messages
> > > > like this are exchanged:
> > > >
> > > > [ServoWS] Call to prompt []
> > > > gap:[1670500204,"Battery","start","Battery1880458036"] servo-
> > > > bridge.js
> > > > <
> > > > <http://localhost:5000/plugins/cordova-plugin-servo-
> > > webview/www/servo>-
> > > > bridge.js> [ServoWS] Intercepted gap: call [1670500204, "Battery",
> > > > "start", "Battery1880458036"] servo-bridge.js
> > > > <
> > > > <http://localhost:5000/plugins/cordova-plugin-servo-
> > > webview/www/servo>-
> > > > bridge.js> [ServoWS] Call to prompt [false]
> > > >
> > > gap:[1670500204,"Geolocation","getPermission","Geolocation1880458037"
> > > > ]
> > > > servo-bridge.js <<http://localhost:5000/plugins/cordova-plugin-
> > > servo>-
> > > > webview/www/servo-bridge.js> [ServoWS] Intercepted gap: call
> > > > [1670500204, "Geolocation", "getPermission",
> > > "Geolocation1880458037"]
> > > > servo-bridge.js <<http://localhost:5000/plugins/cordova-plugin-
> > > servo>-
> > > > webview/www/servo-bridge.js> [ServoWS] Received message: 51 S11
> > > > Battery1880458036 {"level":59,"isPlugged":true}29 S01
> > > > Geolocation1880458037 n36 servo-bridge.js
> > > > <
> > > > <http://localhost:5000/plugins/cordova-plugin-servo-
> > > webview/www/servo>-
> > > > bridge.js>
> > > > Can someone can point me to any kind documentation on how the plugin
> > > > bridge works? I've never looked into the part and if someone has any
> > > > info I could save some time digging through the code and reverse
> > > > engineering stuff.
> > > >
> > > > The chances are slim, I know, but maybe there is something out
> > > there.
> > > >
> > > > Cheers,
> > > > Niklas
> > > >
> > > >
> > > > [1] <<https://github.com/NiklasMerz/cordova-plugin-servo-webview>>
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
> > > For additional commands, e-mail: dev-help@cordova.apache.org
> >
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org
Re: How does plugin bridge work actually?
Posted by julio cesar sanchez <jc...@gmail.com>.
Try searching on the mail list, there should be information there. And
probably in JIRA too.
I’m a little familiar with the addJavascriptInterface bridge, but not with
the prompt bridge, there are several bridges and the prompt bridge was used
in old android versions only and I never looked into it.
El El sáb, 17 ene 2026 a las 18:28, Niklas Merz <ni...@apache.org>
escribió:
> Great thank you. This confirms a lot I found during my digging.
>
> You're right I've opted to hack into the prompt method to use it with
> Websockets because this is currently the only thing that's possible with
> Servo. Servo lacks addJavascriptInterface and evaluateJavascript today.
>
> Did you ever find how out how these messages are built? What things like
> "51 S11 Battery..." mean? I suppose "S" is for success but I'll still
> have to figure out how to correctly split and parse these prompt
> messages.
>
> On January 17, 2026, "dev@cordova.apache.org" <de...@cordova.apache.org>
> wrote:
> > I don't think there is any documentation but I've done quite a bit of
> > reverse engineering myself in the past and might be able to loosely
> > explain the architecture. There are 3 classes that are probably of
> > interest to look at in the cordova-android framework:
> >
> > 1. SystemWebChromeClient
> > 2. SystemExposedJsApi
> > 3. CordovaBridge
> >
> > Based on my understanding, SystemWebViewEngine contains the entry
> > point
> > into native side, by using the onJsPrompt hook. This method is
> > normally
> > to handle window.prompt calls but Cordova uses it to deliver a payload
> > to native. The payload is passed to CordovaBridge and it decides if it
> > is a bridge call or if it is a regular window.prompt call.
> >
> > If it is a bridge call, it does some sanity access checks and pushes
> > the messages through a queue system which gets routed to plugins
> > (somehow).
> >
> > SystemExposedJsApi has some JavascriptInterface methods, which are
> > methods exposed directly to the webiew, and JS can call these methods
> > directly which controls bridge state. It also includes a `exec`
> > JavascriptInterface method, which seems to deliver a payload to the
> > bridge, similar to the prompt method. Both of these might be used, and
> > to me it looks like the bridge call implementation strategy might be
> > swapped based on certain conditions.
> >
> > Although based on your log snippets, it seems like it is using the
> > prompt method.
> >
> > Hopefully this at least puts your focus in the right direction.
> >
> > On Sat, 2026-01-17 at 17:45 +0100, Niklas Merz wrote:
> > > Hey everyone,
> > >
> > > As some of you know I'm currently trying out if Servo can be used in
> > > Cordova Android. I've made some good progress on my plugin [1] and
> > > now I
> > > could use some help with getting plugins going.
> > >
> > > If got the bride working with some hacky glue code and now some
> > > messages
> > > like this are exchanged:
> > >
> > > [ServoWS] Call to prompt []
> > > gap:[1670500204,"Battery","start","Battery1880458036"] servo-
> > > bridge.js
> > > <
> > > <http://localhost:5000/plugins/cordova-plugin-servo-
> > webview/www/servo>-
> > > bridge.js> [ServoWS] Intercepted gap: call [1670500204, "Battery",
> > > "start", "Battery1880458036"] servo-bridge.js
> > > <
> > > <http://localhost:5000/plugins/cordova-plugin-servo-
> > webview/www/servo>-
> > > bridge.js> [ServoWS] Call to prompt [false]
> > >
> > gap:[1670500204,"Geolocation","getPermission","Geolocation1880458037"
> > > ]
> > > servo-bridge.js <<http://localhost:5000/plugins/cordova-plugin-
> > servo>-
> > > webview/www/servo-bridge.js> [ServoWS] Intercepted gap: call
> > > [1670500204, "Geolocation", "getPermission",
> > "Geolocation1880458037"]
> > > servo-bridge.js <<http://localhost:5000/plugins/cordova-plugin-
> > servo>-
> > > webview/www/servo-bridge.js> [ServoWS] Received message: 51 S11
> > > Battery1880458036 {"level":59,"isPlugged":true}29 S01
> > > Geolocation1880458037 n36 servo-bridge.js
> > > <
> > > <http://localhost:5000/plugins/cordova-plugin-servo-
> > webview/www/servo>-
> > > bridge.js>
> > > Can someone can point me to any kind documentation on how the plugin
> > > bridge works? I've never looked into the part and if someone has any
> > > info I could save some time digging through the code and reverse
> > > engineering stuff.
> > >
> > > The chances are slim, I know, but maybe there is something out
> > there.
> > >
> > > Cheers,
> > > Niklas
> > >
> > >
> > > [1] <<https://github.com/NiklasMerz/cordova-plugin-servo-webview>>
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
> > For additional commands, e-mail: dev-help@cordova.apache.org
>
Re: How does plugin bridge work actually?
Posted by Niklas Merz <ni...@apache.org>.
Great thank you. This confirms a lot I found during my digging.
You're right I've opted to hack into the prompt method to use it with
Websockets because this is currently the only thing that's possible with
Servo. Servo lacks addJavascriptInterface and evaluateJavascript today.
Did you ever find how out how these messages are built? What things like
"51 S11 Battery..." mean? I suppose "S" is for success but I'll still
have to figure out how to correctly split and parse these prompt
messages.
On January 17, 2026, "dev@cordova.apache.org" <de...@cordova.apache.org>
wrote:
> I don't think there is any documentation but I've done quite a bit of
> reverse engineering myself in the past and might be able to loosely
> explain the architecture. There are 3 classes that are probably of
> interest to look at in the cordova-android framework:
>
> 1. SystemWebChromeClient
> 2. SystemExposedJsApi
> 3. CordovaBridge
>
> Based on my understanding, SystemWebViewEngine contains the entry
> point
> into native side, by using the onJsPrompt hook. This method is
> normally
> to handle window.prompt calls but Cordova uses it to deliver a payload
> to native. The payload is passed to CordovaBridge and it decides if it
> is a bridge call or if it is a regular window.prompt call.
>
> If it is a bridge call, it does some sanity access checks and pushes
> the messages through a queue system which gets routed to plugins
> (somehow).
>
> SystemExposedJsApi has some JavascriptInterface methods, which are
> methods exposed directly to the webiew, and JS can call these methods
> directly which controls bridge state. It also includes a `exec`
> JavascriptInterface method, which seems to deliver a payload to the
> bridge, similar to the prompt method. Both of these might be used, and
> to me it looks like the bridge call implementation strategy might be
> swapped based on certain conditions.
>
> Although based on your log snippets, it seems like it is using the
> prompt method.
>
> Hopefully this at least puts your focus in the right direction.
>
> On Sat, 2026-01-17 at 17:45 +0100, Niklas Merz wrote:
> > Hey everyone,
> >
> > As some of you know I'm currently trying out if Servo can be used in
> > Cordova Android. I've made some good progress on my plugin [1] and
> > now I
> > could use some help with getting plugins going.
> >
> > If got the bride working with some hacky glue code and now some
> > messages
> > like this are exchanged:
> >
> > [ServoWS] Call to prompt []
> > gap:[1670500204,"Battery","start","Battery1880458036"] servo-
> > bridge.js
> > <
> > <http://localhost:5000/plugins/cordova-plugin-servo-
> webview/www/servo>-
> > bridge.js> [ServoWS] Intercepted gap: call [1670500204, "Battery",
> > "start", "Battery1880458036"] servo-bridge.js
> > <
> > <http://localhost:5000/plugins/cordova-plugin-servo-
> webview/www/servo>-
> > bridge.js> [ServoWS] Call to prompt [false]
> >
> gap:[1670500204,"Geolocation","getPermission","Geolocation1880458037"
> > ]
> > servo-bridge.js <<http://localhost:5000/plugins/cordova-plugin-
> servo>-
> > webview/www/servo-bridge.js> [ServoWS] Intercepted gap: call
> > [1670500204, "Geolocation", "getPermission",
> "Geolocation1880458037"]
> > servo-bridge.js <<http://localhost:5000/plugins/cordova-plugin-
> servo>-
> > webview/www/servo-bridge.js> [ServoWS] Received message: 51 S11
> > Battery1880458036 {"level":59,"isPlugged":true}29 S01
> > Geolocation1880458037 n36 servo-bridge.js
> > <
> > <http://localhost:5000/plugins/cordova-plugin-servo-
> webview/www/servo>-
> > bridge.js>
> > Can someone can point me to any kind documentation on how the plugin
> > bridge works? I've never looked into the part and if someone has any
> > info I could save some time digging through the code and reverse
> > engineering stuff.
> >
> > The chances are slim, I know, but maybe there is something out
> there.
> >
> > Cheers,
> > Niklas
> >
> >
> > [1] <<https://github.com/NiklasMerz/cordova-plugin-servo-webview>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
> For additional commands, e-mail: dev-help@cordova.apache.org
Re: How does plugin bridge work actually?
Posted by Norman Breau via dev <de...@cordova.apache.org>.
I don't think there is any documentation but I've done quite a bit of
reverse engineering myself in the past and might be able to loosely
explain the architecture. There are 3 classes that are probably of
interest to look at in the cordova-android framework:
1. SystemWebChromeClient
2. SystemExposedJsApi
3. CordovaBridge
Based on my understanding, SystemWebViewEngine contains the entry point
into native side, by using the onJsPrompt hook. This method is normally
to handle window.prompt calls but Cordova uses it to deliver a payload
to native. The payload is passed to CordovaBridge and it decides if it
is a bridge call or if it is a regular window.prompt call.
If it is a bridge call, it does some sanity access checks and pushes
the messages through a queue system which gets routed to plugins
(somehow).
SystemExposedJsApi has some JavascriptInterface methods, which are
methods exposed directly to the webiew, and JS can call these methods
directly which controls bridge state. It also includes a `exec`
JavascriptInterface method, which seems to deliver a payload to the
bridge, similar to the prompt method. Both of these might be used, and
to me it looks like the bridge call implementation strategy might be
swapped based on certain conditions.
Although based on your log snippets, it seems like it is using the
prompt method.
Hopefully this at least puts your focus in the right direction.
On Sat, 2026-01-17 at 17:45 +0100, Niklas Merz wrote:
> Hey everyone,
>
> As some of you know I'm currently trying out if Servo can be used in
> Cordova Android. I've made some good progress on my plugin [1] and
> now I
> could use some help with getting plugins going.
>
> If got the bride working with some hacky glue code and now some
> messages
> like this are exchanged:
>
> [ServoWS] Call to prompt []
> gap:[1670500204,"Battery","start","Battery1880458036"] servo-
> bridge.js
> <
> http://localhost:5000/plugins/cordova-plugin-servo-webview/www/servo-
> bridge.js> [ServoWS] Intercepted gap: call [1670500204, "Battery",
> "start", "Battery1880458036"] servo-bridge.js
> <
> http://localhost:5000/plugins/cordova-plugin-servo-webview/www/servo-
> bridge.js> [ServoWS] Call to prompt [false]
> gap:[1670500204,"Geolocation","getPermission","Geolocation1880458037"
> ]
> servo-bridge.js <http://localhost:5000/plugins/cordova-plugin-servo-
> webview/www/servo-bridge.js> [ServoWS] Intercepted gap: call
> [1670500204, "Geolocation", "getPermission", "Geolocation1880458037"]
> servo-bridge.js <http://localhost:5000/plugins/cordova-plugin-servo-
> webview/www/servo-bridge.js> [ServoWS] Received message: 51 S11
> Battery1880458036 {"level":59,"isPlugged":true}29 S01
> Geolocation1880458037 n36 servo-bridge.js
> <
> http://localhost:5000/plugins/cordova-plugin-servo-webview/www/servo-
> bridge.js>
> Can someone can point me to any kind documentation on how the plugin
> bridge works? I've never looked into the part and if someone has any
> info I could save some time digging through the code and reverse
> engineering stuff.
>
> The chances are slim, I know, but maybe there is something out there.
>
> Cheers,
> Niklas
>
>
> [1] <https://github.com/NiklasMerz/cordova-plugin-servo-webview>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org