mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03:00
Ladybird/Android: Bind WebSocketService for WebSocket purposes
Similar to the RequestServer, bind this from the WebContentService implementation and have it work the same way. Deduplicate some code while we're here.
This commit is contained in:
parent
a243bc465f
commit
ff0494c63b
Notes:
sideshowbarker
2024-07-16 18:26:46 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/ff0494c63b Pull-request: https://github.com/SerenityOS/serenity/pull/21100
@ -56,6 +56,11 @@
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:process=":RequestServer" />
|
||||
<service
|
||||
android:name=".WebSocketService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:process=":WebSocket" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
@ -29,7 +29,18 @@
|
||||
#include <WebContent/ConnectionFromClient.h>
|
||||
#include <WebContent/PageHost.h>
|
||||
|
||||
static ErrorOr<NonnullRefPtr<Protocol::RequestClient>> bind_request_server_service();
|
||||
template<typename Client>
|
||||
static ErrorOr<NonnullRefPtr<Client>> bind_service(void (*bind_method)(int, int));
|
||||
|
||||
static ErrorOr<NonnullRefPtr<Protocol::RequestClient>> bind_request_server_service()
|
||||
{
|
||||
return bind_service<Protocol::RequestClient>(&bind_request_server_java);
|
||||
}
|
||||
|
||||
static ErrorOr<NonnullRefPtr<Protocol::WebSocketClient>> bind_web_socket_service()
|
||||
{
|
||||
return bind_service<Protocol::WebSocketClient>(&bind_web_socket_java);
|
||||
}
|
||||
|
||||
ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
|
||||
{
|
||||
@ -48,6 +59,9 @@ ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
|
||||
auto request_server_client = TRY(bind_request_server_service());
|
||||
Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create(move(request_server_client))));
|
||||
|
||||
auto web_socket_client = TRY(bind_web_socket_service());
|
||||
Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create(move(web_socket_client))));
|
||||
|
||||
bool is_layout_test_mode = false;
|
||||
|
||||
Web::HTML::Window::set_internals_object_exposed(is_layout_test_mode);
|
||||
@ -66,7 +80,8 @@ ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
|
||||
return event_loop.exec();
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<Protocol::RequestClient>> bind_request_server_service()
|
||||
template<typename Client>
|
||||
static ErrorOr<NonnullRefPtr<Client>> bind_service(void (*bind_method)(int, int))
|
||||
{
|
||||
int socket_fds[2] {};
|
||||
TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds));
|
||||
@ -81,12 +96,12 @@ ErrorOr<NonnullRefPtr<Protocol::RequestClient>> bind_request_server_service()
|
||||
int server_fd_passing_fd = fd_passing_socket_fds[1];
|
||||
|
||||
// NOTE: The java object takes ownership of the socket fds
|
||||
bind_request_server_java(server_fd, server_fd_passing_fd);
|
||||
(*bind_method)(server_fd, server_fd_passing_fd);
|
||||
|
||||
auto socket = TRY(Core::LocalSocket::adopt_fd(ui_fd));
|
||||
TRY(socket->set_blocking(true));
|
||||
|
||||
auto new_client = TRY(try_make_ref_counted<Protocol::RequestClient>(move(socket)));
|
||||
auto new_client = TRY(try_make_ref_counted<Client>(move(socket)));
|
||||
new_client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(ui_fd_passing_fd)));
|
||||
|
||||
return new_client;
|
||||
|
@ -7,3 +7,4 @@
|
||||
#pragma once
|
||||
|
||||
void bind_request_server_java(int ipc_socket, int fd_passing_socket);
|
||||
void bind_web_socket_java(int ipc_socket, int fd_passing_socket);
|
||||
|
@ -11,6 +11,7 @@
|
||||
jobject global_instance;
|
||||
jclass global_class_reference;
|
||||
jmethodID bind_request_server_method;
|
||||
jmethodID bind_web_socket_method;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebContentService_nativeInit(JNIEnv* env, jobject thiz)
|
||||
@ -27,6 +28,11 @@ Java_org_serenityos_ladybird_WebContentService_nativeInit(JNIEnv* env, jobject t
|
||||
if (!method)
|
||||
TODO();
|
||||
bind_request_server_method = method;
|
||||
|
||||
method = env->GetMethodID(global_class_reference, "bindWebSocket", "(II)V");
|
||||
if (!method)
|
||||
TODO();
|
||||
bind_web_socket_method = method;
|
||||
}
|
||||
|
||||
void bind_request_server_java(int ipc_socket, int fd_passing_socket)
|
||||
@ -34,3 +40,9 @@ void bind_request_server_java(int ipc_socket, int fd_passing_socket)
|
||||
JavaEnvironment env(global_vm);
|
||||
env.get()->CallVoidMethod(global_instance, bind_request_server_method, ipc_socket, fd_passing_socket);
|
||||
}
|
||||
|
||||
void bind_web_socket_java(int ipc_socket, int fd_passing_socket)
|
||||
{
|
||||
JavaEnvironment env(global_vm);
|
||||
env.get()->CallVoidMethod(global_instance, bind_web_socket_method, ipc_socket, fd_passing_socket);
|
||||
}
|
||||
|
46
Ladybird/Android/src/main/cpp/WebSocketService.cpp
Normal file
46
Ladybird/Android/src/main/cpp/WebSocketService.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com>
|
||||
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <Ladybird/Utilities.h>
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/LocalServer.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibFileSystem/FileSystem.h>
|
||||
#include <LibIPC/SingleServer.h>
|
||||
#include <LibTLS/Certificate.h>
|
||||
#include <WebSocket/ConnectionFromClient.h>
|
||||
|
||||
// FIXME: Share b/w RequestServer and WebSocket
|
||||
ErrorOr<String> find_certificates(StringView serenity_resource_root)
|
||||
{
|
||||
auto cert_path = TRY(String::formatted("{}/res/ladybird/cacert.pem", serenity_resource_root));
|
||||
if (!FileSystem::exists(cert_path)) {
|
||||
auto app_dir = LexicalPath::dirname(TRY(Core::System::current_executable_path()).to_deprecated_string());
|
||||
|
||||
cert_path = TRY(String::formatted("{}/cacert.pem", LexicalPath(app_dir).parent()));
|
||||
if (!FileSystem::exists(cert_path))
|
||||
return Error::from_string_view("Don't know how to load certs!"sv);
|
||||
}
|
||||
return cert_path;
|
||||
}
|
||||
|
||||
ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
|
||||
{
|
||||
// Ensure the certificates are read out here.
|
||||
DefaultRootCACertificates::set_default_certificate_path(TRY(find_certificates(s_serenity_resource_root)));
|
||||
[[maybe_unused]] auto& certs = DefaultRootCACertificates::the();
|
||||
|
||||
Core::EventLoop event_loop;
|
||||
|
||||
auto socket = TRY(Core::LocalSocket::adopt_fd(ipc_socket));
|
||||
auto client = TRY(WebSocket::ConnectionFromClient::try_create(move(socket)));
|
||||
client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(fd_passing_socket)));
|
||||
|
||||
return event_loop.exec();
|
||||
}
|
@ -35,6 +35,21 @@ class WebContentService : LadybirdServiceBase("WebContentService") {
|
||||
)
|
||||
}
|
||||
|
||||
private fun bindWebSocket(ipcFd: Int, fdPassingFd: Int)
|
||||
{
|
||||
val connector = LadybirdServiceConnection(ipcFd, fdPassingFd, resourceDir)
|
||||
connector.onDisconnect = {
|
||||
// FIXME: Notify impl that service is dead and might need restarted
|
||||
Log.e(TAG, "RequestServer Died! :(")
|
||||
}
|
||||
// FIXME: Unbind this at some point maybe
|
||||
bindService(
|
||||
Intent(this, WebSocketService::class.java),
|
||||
connector,
|
||||
Context.BIND_AUTO_CREATE
|
||||
)
|
||||
}
|
||||
|
||||
external fun nativeInit()
|
||||
|
||||
companion object {
|
||||
|
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
package org.serenityos.ladybird
|
||||
|
||||
import android.os.Message
|
||||
|
||||
class WebSocketService : LadybirdServiceBase("WebSocketService") {
|
||||
override fun handleServiceSpecificMessage(msg: Message): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
init {
|
||||
System.loadLibrary("websocket")
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,18 @@
|
||||
set(SOURCES
|
||||
"${SERENITY_SOURCE_DIR}/Userland/Services/WebSocket/ConnectionFromClient.cpp"
|
||||
main.cpp
|
||||
)
|
||||
|
||||
add_executable(WebSocketServer ${SOURCES})
|
||||
if (ANDROID)
|
||||
add_library(websocket SHARED
|
||||
${SOURCES}
|
||||
../Android/src/main/cpp/WebSocketService.cpp
|
||||
../Android/src/main/cpp/LadybirdServiceBaseJNI.cpp
|
||||
../Utilities.cpp
|
||||
)
|
||||
else()
|
||||
add_library(websocket STATIC ${SOURCES})
|
||||
endif()
|
||||
add_executable(WebSocketServer main.cpp)
|
||||
target_link_libraries(WebSocketServer PRIVATE websocket)
|
||||
set_target_properties(WebSocketServer PROPERTIES OUTPUT_NAME WebSocket)
|
||||
target_link_libraries(WebSocketServer PRIVATE LibCore LibFileSystem LibIPC LibMain LibTLS LibWebSocket LibWebView)
|
||||
target_link_libraries(websocket PUBLIC LibCore LibFileSystem LibIPC LibMain LibTLS LibWebSocket LibWebView)
|
||||
|
@ -45,7 +45,7 @@ macro(install_service_lib service)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
foreach(service IN LISTS webcontent requestserver)
|
||||
foreach(service IN LISTS webcontent requestserver websocket)
|
||||
install_service_lib(${service})
|
||||
endforeach()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user