Coming back to this after a (long) break, I've now built a demo/exercise app using a webview widget for the user interface, with bidirectional Javascript-Pascal in-process RPC.
The main body of the code loads in-app static content, then binds the names 'HostSayHello' and 'HostExit' for callback to Pascal code from Javascript. Said Pascal code in turns invokes Javascript to manipulate the DOM.
webwidget := dw_html_new(1001); // 1001 is an identifier
if webwidget <> nil then
begin
dw_box_pack_start(mainwindow, webwidget, 0, 0, DW_TRUE, DW_TRUE, 0);
dw_html_url(webwidget, 'file:///android_asset/index.html');
dw_html_javascript_add(webwidget, 'HostSayHello');
dw_html_javascript_add(webwidget, 'HostExit');
dw_signal_connect(webwidget, DW_SIGNAL_HTML_MESSAGE, @html_message_callback, nil);
end;
Screenshot of the app running in Android emulator attached.