Skip to content

Commit

Permalink
Ladybird+LibWebView: Move WebContent process launcher to LibWebView
Browse files Browse the repository at this point in the history
This is to allow headless-browser to reuse this code. We have a similar
helper for launching SQLServer from Ladybird.
  • Loading branch information
trflynn89 authored and linusg committed Mar 13, 2023
1 parent be4da57 commit add15a5
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 47 deletions.
49 changes: 2 additions & 47 deletions Ladybird/WebContentView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,53 +568,8 @@ void WebContentView::create_client()
{
m_client_state = {};

int socket_fds[2] {};
MUST(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds));

int ui_fd = socket_fds[0];
int wc_fd = socket_fds[1];

int fd_passing_socket_fds[2] {};
MUST(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_passing_socket_fds));

int ui_fd_passing_fd = fd_passing_socket_fds[0];
int wc_fd_passing_fd = fd_passing_socket_fds[1];

auto child_pid = fork();
if (!child_pid) {
MUST(Core::System::close(ui_fd_passing_fd));
MUST(Core::System::close(ui_fd));

auto takeover_string = DeprecatedString::formatted("WebContent:{}", wc_fd);
MUST(Core::System::setenv("SOCKET_TAKEOVER"sv, takeover_string, true));

auto webcontent_fd_passing_socket_string = DeprecatedString::number(wc_fd_passing_fd);

Vector<StringView, 5> arguments {
"WebContent"sv,
"--webcontent-fd-passing-socket"sv,
webcontent_fd_passing_socket_string
};

if (!m_webdriver_content_ipc_path.is_empty()) {
arguments.append("--webdriver-content-path"sv);
arguments.append(m_webdriver_content_ipc_path);
}

auto result = spawn_helper_process("WebContent"sv, arguments, Core::System::SearchInPath::Yes);
if (result.is_error())
warnln("Could not launch WebContent: {}", result.error());
VERIFY_NOT_REACHED();
}

MUST(Core::System::close(wc_fd_passing_fd));
MUST(Core::System::close(wc_fd));

auto socket = MUST(Core::LocalSocket::adopt_fd(ui_fd));
MUST(socket->set_blocking(true));

auto new_client = MUST(adopt_nonnull_ref_or_enomem(new (nothrow) WebView::WebContentClient(std::move(socket), *this)));
new_client->set_fd_passing_socket(MUST(Core::LocalSocket::adopt_fd(ui_fd_passing_fd)));
auto candidate_web_content_paths = get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors();
auto new_client = launch_web_content_process(candidate_web_content_paths, m_webdriver_content_ipc_path).release_value_but_fixme_should_propagate_errors();

m_web_content_notifier.setSocket(new_client->socket().fd().value());
m_web_content_notifier.setEnabled(true);
Expand Down
62 changes: 62 additions & 0 deletions Userland/Libraries/LibWebView/ViewImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,66 @@ void ViewImplementation::run_javascript(StringView js_source)
client().async_run_javascript(js_source);
}

#if !defined(AK_OS_SERENITY)

ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ViewImplementation::launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, StringView webdriver_content_ipc_path)
{
int socket_fds[2] {};
TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds));

int ui_fd = socket_fds[0];
int wc_fd = socket_fds[1];

int fd_passing_socket_fds[2] {};
TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_passing_socket_fds));

int ui_fd_passing_fd = fd_passing_socket_fds[0];
int wc_fd_passing_fd = fd_passing_socket_fds[1];

if (auto child_pid = TRY(Core::System::fork()); child_pid == 0) {
TRY(Core::System::close(ui_fd_passing_fd));
TRY(Core::System::close(ui_fd));

auto takeover_string = TRY(String::formatted("WebContent:{}", wc_fd));
TRY(Core::System::setenv("SOCKET_TAKEOVER"sv, takeover_string, true));

auto webcontent_fd_passing_socket_string = TRY(String::number(wc_fd_passing_fd));

Vector<StringView> arguments {
"WebContent"sv,
"--webcontent-fd-passing-socket"sv,
webcontent_fd_passing_socket_string
};

if (!webdriver_content_ipc_path.is_empty()) {
TRY(arguments.try_append("--webdriver-content-path"sv));
TRY(arguments.try_append(webdriver_content_ipc_path));
}

ErrorOr<void> result;
for (auto const& path : candidate_web_content_paths) {
result = Core::System::exec(path, arguments, Core::System::SearchInPath::Yes);
if (!result.is_error())
break;
}

if (result.is_error())
warnln("Could not launch any of {}: {}", candidate_web_content_paths, result.error());
VERIFY_NOT_REACHED();
}

TRY(Core::System::close(wc_fd_passing_fd));
TRY(Core::System::close(wc_fd));

auto socket = TRY(Core::LocalSocket::adopt_fd(ui_fd));
TRY(socket->set_blocking(true));

auto new_client = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) WebView::WebContentClient(move(socket), *this)));
new_client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(ui_fd_passing_fd)));

return new_client;
}

#endif

}
4 changes: 4 additions & 0 deletions Userland/Libraries/LibWebView/ViewImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ class ViewImplementation {
virtual void create_client() = 0;
virtual void update_zoom() = 0;

#if !defined(AK_OS_SERENITY)
ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, StringView webdriver_content_ipc_path);
#endif

struct SharedBitmap {
i32 id { -1 };
i32 pending_paints { 0 };
Expand Down

0 comments on commit add15a5

Please sign in to comment.