Ladybird: Update Android build to work with current LibWebView/LibCore

Also update to the latest gradle plugin versions and other dependencies
as recommended by Android Studio Jellyfish.
This commit is contained in:
Andrew Kaster 2024-05-04 06:08:53 -06:00 committed by Andrew Kaster
parent b562c9759d
commit 68ec099b66
Notes: sideshowbarker 2024-07-17 03:59:29 +09:00
25 changed files with 89 additions and 94 deletions

View file

@ -6,7 +6,7 @@ The Android port of Ladybird has straightforward integration with the Android St
Ensure that your system has the following tools available:
- Android Studio Giraffe 2022.3.1 Patch 1 or later
- Android Studio Jellyfish 2023.3.1 or later
- CMake 3.23 or higher as the default CMake executable
- 20G or more storage space for SDKs + Emulator images + Gradle dependencies + build artifacts

View file

@ -1,16 +1,17 @@
import com.android.build.gradle.internal.tasks.factory.dependsOn
plugins {
id("com.android.application") version "8.1.1"
id("com.android.application") version "8.4.0"
id("org.jetbrains.kotlin.android") version "1.9.0"
}
var buildDir = layout.buildDirectory.get()
var cacheDir = System.getenv("SERENITY_CACHE_DIR") ?: "$buildDir/caches"
task<Exec>("buildLagomTools") {
commandLine = listOf("./BuildLagomTools.sh")
environment = mapOf(
"BUILD_DIR" to "$buildDir",
"BUILD_DIR" to buildDir,
"CACHE_DIR" to cacheDir,
"PATH" to System.getenv("PATH")!!
)
@ -20,12 +21,12 @@ tasks.named("prepareKotlinBuildScriptModel").dependsOn("buildLagomTools")
android {
namespace = "org.serenityos.ladybird"
compileSdk = 33
compileSdk = 34
defaultConfig {
applicationId = "org.serenityos.ladybird"
minSdk = 30
targetSdk = 33
targetSdk = 34
versionCode = 1
versionName = "1.0"
@ -75,9 +76,9 @@ android {
}
dependencies {
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
testImplementation("junit:junit:4.13.2")

View file

@ -1,6 +1,6 @@
#Fri Sep 01 12:36:55 CEST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View file

@ -50,7 +50,7 @@ ALooperEventLoopManager::ALooperEventLoopManager(jobject timer_service)
if (!m_register_timer)
TODO();
m_unregister_timer = env.get()->GetMethodID(timer_service_class, "unregisterTimer", "(J)Z");
m_unregister_timer = env.get()->GetMethodID(timer_service_class, "unregisterTimer", "(J)V");
if (!m_unregister_timer)
TODO();
env.get()->DeleteLocalRef(timer_service_class);
@ -85,7 +85,7 @@ NonnullOwnPtr<Core::EventLoopImplementation> ALooperEventLoopManager::make_imple
return ALooperEventLoopImplementation::create();
}
int ALooperEventLoopManager::register_timer(Core::EventReceiver& receiver, int milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible visibility)
intptr_t ALooperEventLoopManager::register_timer(Core::EventReceiver& receiver, int milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible visibility)
{
JavaEnvironment env(global_vm);
auto& thread_data = EventLoopThreadData::the();
@ -101,13 +101,12 @@ int ALooperEventLoopManager::register_timer(Core::EventReceiver& receiver, int m
return timer_id;
}
bool ALooperEventLoopManager::unregister_timer(int timer_id)
void ALooperEventLoopManager::unregister_timer(intptr_t timer_id)
{
if (auto timer = EventLoopThreadData::the().timers.take(timer_id); timer.has_value()) {
JavaEnvironment env(global_vm);
return env.get()->CallBooleanMethod(m_timer_service, m_unregister_timer, timer_id);
env.get()->CallVoidMethod(m_timer_service, m_unregister_timer, timer_id);
}
return false;
}
void ALooperEventLoopManager::register_notifier(Core::Notifier& notifier)
@ -203,13 +202,23 @@ void ALooperEventLoopImplementation::post_event(Core::EventReceiver& receiver, N
wake();
}
static int notifier_callback(int fd, int, void* data)
static int notifier_callback(int fd, int events, void* data)
{
auto& notifier = *static_cast<Core::Notifier*>(data);
VERIFY(fd == notifier.fd());
Core::NotifierActivationEvent event(notifier.fd());
Core::NotificationType type = Core::NotificationType::None;
if (events & ALOOPER_EVENT_INPUT)
type |= Core::NotificationType::Read;
if (events & ALOOPER_EVENT_OUTPUT)
type |= Core::NotificationType::Write;
if (events & ALOOPER_EVENT_HANGUP)
type |= Core::NotificationType::HangUp;
if (events & ALOOPER_EVENT_ERROR)
type |= Core::NotificationType::Error;
Core::NotifierActivationEvent event(notifier.fd(), type);
notifier.dispatch_event(event);
// Wake up from ALooper_pollAll, and service this event on the event queue
@ -228,7 +237,12 @@ void ALooperEventLoopImplementation::register_notifier(Core::Notifier& notifier)
case Core::Notifier::Type::Write:
event_flags = ALOOPER_EVENT_OUTPUT;
break;
case Core::Notifier::Type::Exceptional:
case Core::Notifier::Type::Error:
event_flags = ALOOPER_EVENT_ERROR;
break;
case Core::Notifier::Type::HangUp:
event_flags = ALOOPER_EVENT_HANGUP;
break;
case Core::Notifier::Type::None:
TODO();
}

View file

@ -23,8 +23,8 @@ public:
virtual ~ALooperEventLoopManager() override;
virtual NonnullOwnPtr<Core::EventLoopImplementation> make_implementation() override;
virtual int register_timer(Core::EventReceiver&, int milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible) override;
virtual bool unregister_timer(int timer_id) override;
virtual intptr_t register_timer(Core::EventReceiver&, int milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible) override;
virtual void unregister_timer(intptr_t timer_id) override;
virtual void register_notifier(Core::Notifier&) override;
virtual void unregister_notifier(Core::Notifier&) override;

View file

@ -10,13 +10,12 @@
#include <LibCore/EventLoop.h>
#include <LibIPC/SingleServer.h>
ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
ErrorOr<int> service_main(int ipc_socket)
{
Core::EventLoop event_loop;
auto socket = TRY(Core::LocalSocket::adopt_fd(ipc_socket));
auto client = TRY(ImageDecoder::ConnectionFromClient::try_create(move(socket)));
client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(fd_passing_socket)));
return event_loop.exec();
}

View file

@ -177,7 +177,7 @@ ErrorOr<void> extract_tar_archive(String archive_file, ByteString output_directo
path = path.prepend(header.prefix());
ByteString filename = get_override("path"sv).value_or(path.string());
ByteString absolute_path = TRY(FileSystem::absolute_path(filename)).to_byte_string();
ByteString absolute_path = TRY(FileSystem::absolute_path(filename));
auto parent_path = LexicalPath(absolute_path).parent();
auto header_mode = TRY(header.mode());

View file

@ -9,4 +9,4 @@
#include <AK/Error.h>
#include <jni.h>
ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket);
ErrorOr<int> service_main(int ipc_socket);

View file

@ -14,10 +14,9 @@
JavaVM* global_vm;
extern "C" JNIEXPORT void JNICALL
Java_org_serenityos_ladybird_LadybirdServiceBase_nativeThreadLoop(JNIEnv*, jobject /* thiz */, jint ipc_socket, jint fd_passing_socket)
Java_org_serenityos_ladybird_LadybirdServiceBase_nativeThreadLoop(JNIEnv*, jobject /* thiz */, jint ipc_socket)
{
dbgln("New binding received, sockets {} and {}", ipc_socket, fd_passing_socket);
auto ret = service_main(ipc_socket, fd_passing_socket);
auto ret = service_main(ipc_socket);
if (ret.is_error()) {
warnln("Runtime Error: {}", ret.release_error());
} else {

View file

@ -23,13 +23,13 @@
// FIXME: Share b/w RequestServer and WebSocket
ErrorOr<ByteString> find_certificates(StringView serenity_resource_root)
{
auto cert_path = ByteString::formatted("{}/ladybird/cacert.pem", serenity_resource_root);
auto cert_path = ByteString::formatted("{}/res/ladybird/cacert.pem", serenity_resource_root);
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)
ErrorOr<int> service_main(int ipc_socket)
{
// Ensure the certificates are read out here.
DefaultRootCACertificates::set_default_certificate_paths(Vector { TRY(find_certificates(s_serenity_resource_root)) });
@ -43,7 +43,6 @@ ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
auto socket = TRY(Core::LocalSocket::adopt_fd(ipc_socket));
auto client = TRY(RequestServer::ConnectionFromClient::try_create(move(socket)));
client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(fd_passing_socket)));
return event_loop.exec();
}

View file

@ -26,7 +26,7 @@ Java_org_serenityos_ladybird_TimerExecutorService_00024Timer_nativeRun(JNIEnv*,
if (!receiver->is_visible_for_timer_purposes())
return;
event_loop_impl.post_event(*receiver, make<Core::TimerEvent>(id));
event_loop_impl.post_event(*receiver, make<Core::TimerEvent>());
}
// Flush the event loop on this thread to keep any garbage from building up
if (auto num_events = s_event_loop.pump(Core::EventLoop::WaitMode::PollForEvents); num_events != 0) {

View file

@ -19,6 +19,7 @@
#include <LibIPC/ConnectionFromClient.h>
#include <LibImageDecoderClient/Client.h>
#include <LibJS/Bytecode/Interpreter.h>
#include <LibProtocol/RequestClient.h>
#include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/Loader/ContentFilter.h>
@ -37,13 +38,13 @@ static ErrorOr<NonnullRefPtr<Protocol::RequestClient>> bind_request_server_servi
}
template ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>, Error>
bind_service<ImageDecoderClient::Client>(void (*)(int, int));
bind_service<ImageDecoderClient::Client>(void (*)(int));
static ErrorOr<void> load_content_filters();
static ErrorOr<void> load_autoplay_allowlist();
ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
ErrorOr<int> service_main(int ipc_socket)
{
Core::EventLoop event_loop;
@ -75,13 +76,12 @@ ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
auto webcontent_socket = TRY(Core::LocalSocket::adopt_fd(ipc_socket));
auto webcontent_client = TRY(WebContent::ConnectionFromClient::try_create(move(webcontent_socket)));
webcontent_client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(fd_passing_socket)));
return event_loop.exec();
}
template<typename Client>
ErrorOr<NonnullRefPtr<Client>> bind_service(void (*bind_method)(int, int))
ErrorOr<NonnullRefPtr<Client>> bind_service(void (*bind_method)(int))
{
int socket_fds[2] {};
TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds));
@ -89,20 +89,13 @@ ErrorOr<NonnullRefPtr<Client>> bind_service(void (*bind_method)(int, int))
int ui_fd = socket_fds[0];
int server_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 server_fd_passing_fd = fd_passing_socket_fds[1];
// NOTE: The java object takes ownership of the socket fds
(*bind_method)(server_fd, server_fd_passing_fd);
(*bind_method)(server_fd);
auto socket = TRY(Core::LocalSocket::adopt_fd(ui_fd));
TRY(socket->set_blocking(true));
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;
}

View file

@ -9,8 +9,7 @@
#include <AK/NonnullRefPtr.h>
template<typename Client>
ErrorOr<NonnullRefPtr<Client>> bind_service(void (*bind_method)(int, int));
ErrorOr<NonnullRefPtr<Client>> bind_service(void (*bind_method)(int));
void bind_request_server_java(int ipc_socket, int fd_passing_socket);
void bind_web_socket_java(int ipc_socket, int fd_passing_socket);
void bind_image_decoder_java(int ipc_socket, int fd_passing_socket);
void bind_request_server_java(int ipc_socket);
void bind_image_decoder_java(int ipc_socket);

View file

@ -24,25 +24,25 @@ Java_org_serenityos_ladybird_WebContentService_nativeInit(JNIEnv* env, jobject t
global_class_reference = reinterpret_cast<jclass>(env->NewGlobalRef(local_class));
env->DeleteLocalRef(local_class);
auto method = env->GetMethodID(global_class_reference, "bindRequestServer", "(II)V");
auto method = env->GetMethodID(global_class_reference, "bindRequestServer", "(I)V");
if (!method)
TODO();
bind_request_server_method = method;
method = env->GetMethodID(global_class_reference, "bindImageDecoder", "(II)V");
method = env->GetMethodID(global_class_reference, "bindImageDecoder", "(I)V");
if (!method)
TODO();
bind_image_decoder_method = method;
}
void bind_request_server_java(int ipc_socket, int fd_passing_socket)
void bind_request_server_java(int ipc_socket)
{
Ladybird::JavaEnvironment env(global_vm);
env.get()->CallVoidMethod(global_instance, bind_request_server_method, ipc_socket, fd_passing_socket);
env.get()->CallVoidMethod(global_instance, bind_request_server_method, ipc_socket);
}
void bind_image_decoder_java(int ipc_socket, int fd_passing_socket)
void bind_image_decoder_java(int ipc_socket)
{
Ladybird::JavaEnvironment env(global_vm);
env.get()->CallVoidMethod(global_instance, bind_image_decoder_method, ipc_socket, fd_passing_socket);
env.get()->CallVoidMethod(global_instance, bind_image_decoder_method, ipc_socket);
}

View file

@ -6,6 +6,7 @@
#include "WebViewImplementationNative.h"
#include "JNIHelpers.h"
#include <LibWebView/WebContentClient.h>
#include <Userland/Libraries/LibGfx/Bitmap.h>
#include <Userland/Libraries/LibGfx/Painter.h>
#include <Userland/Libraries/LibWeb/Crypto/Crypto.h>
@ -28,14 +29,14 @@ WebViewImplementationNative::WebViewImplementationNative(jobject thiz)
: m_java_instance(thiz)
{
// NOTE: m_java_instance's global ref is controlled by the JNI bindings
create_client(WebView::EnableCallgrindProfiling::No);
initialize_client(CreateNewClient::Yes);
on_ready_to_paint = [this]() {
JavaEnvironment env(global_vm);
env.get()->CallVoidMethod(m_java_instance, invalidate_layout_method);
};
on_load_start = [this](URL const& url, bool is_redirect) {
on_load_start = [this](URL::URL const& url, bool is_redirect) {
JavaEnvironment env(global_vm);
auto url_string = env.jstring_from_ak_string(MUST(url.to_string()));
env.get()->CallVoidMethod(m_java_instance, on_load_start_method, url_string, is_redirect);
@ -43,7 +44,7 @@ WebViewImplementationNative::WebViewImplementationNative(jobject thiz)
};
}
void WebViewImplementationNative::create_client(WebView::EnableCallgrindProfiling)
void WebViewImplementationNative::initialize_client(WebView::ViewImplementation::CreateNewClient)
{
m_client_state = {};
@ -56,9 +57,9 @@ void WebViewImplementationNative::create_client(WebView::EnableCallgrindProfilin
};
m_client_state.client_handle = MUST(Web::Crypto::generate_random_uuid());
client().async_set_window_handle(m_client_state.client_handle);
client().async_set_window_handle(0, m_client_state.client_handle);
client().async_set_device_pixels_per_css_pixel(m_device_pixel_ratio);
client().async_set_device_pixels_per_css_pixel(0, m_device_pixel_ratio);
// FIXME: update_palette, update system fonts
}
@ -93,14 +94,14 @@ void WebViewImplementationNative::paint_into_bitmap(void* android_bitmap_raw, An
void WebViewImplementationNative::set_viewport_geometry(int w, int h)
{
m_viewport_rect = { { 0, 0 }, { w, h } };
client().async_set_viewport_rect(m_viewport_rect);
client().async_set_viewport_rect(0, m_viewport_rect);
handle_resize();
}
void WebViewImplementationNative::set_device_pixel_ratio(float f)
{
m_device_pixel_ratio = f;
client().async_set_device_pixels_per_css_pixel(m_device_pixel_ratio);
client().async_set_device_pixels_per_css_pixel(0, m_device_pixel_ratio);
}
NonnullRefPtr<WebView::WebContentClient> WebViewImplementationNative::bind_web_content_client()
@ -113,20 +114,13 @@ NonnullRefPtr<WebView::WebContentClient> WebViewImplementationNative::bind_web_c
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];
// NOTE: The java object takes ownership of the socket fds
env.get()->CallVoidMethod(m_java_instance, bind_webcontent_method, wc_fd, wc_fd_passing_fd);
env.get()->CallVoidMethod(m_java_instance, bind_webcontent_method, wc_fd);
auto socket = MUST(Core::LocalSocket::adopt_fd(ui_fd));
MUST(socket->set_blocking(true));
auto new_client = make_ref_counted<WebView::WebContentClient>(move(socket), *this);
new_client->set_fd_passing_socket(MUST(Core::LocalSocket::adopt_fd(ui_fd_passing_fd)));
return new_client;
}

View file

@ -15,14 +15,14 @@ class WebViewImplementationNative : public WebView::ViewImplementation {
public:
WebViewImplementationNative(jobject thiz);
virtual Gfx::IntRect viewport_rect() const override { return m_viewport_rect; }
virtual Web::DevicePixelRect viewport_rect() const override { return m_viewport_rect; }
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint p) const override { return p; }
virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint p) const override { return p; }
virtual void update_zoom() override { }
NonnullRefPtr<WebView::WebContentClient> bind_web_content_client();
virtual void create_client(WebView::EnableCallgrindProfiling) override;
virtual void initialize_client(CreateNewClient) override;
void paint_into_bitmap(void* android_bitmap_raw, AndroidBitmapInfo const& info);
@ -38,6 +38,6 @@ public:
private:
jobject m_java_instance = nullptr;
Gfx::IntRect m_viewport_rect;
Web::DevicePixelRect m_viewport_rect;
};
}

View file

@ -23,7 +23,7 @@ Java_org_serenityos_ladybird_WebViewImplementation_00024Companion_nativeClassIni
WebViewImplementationNative::global_class_reference = reinterpret_cast<jclass>(env->NewGlobalRef(local_class));
env->DeleteLocalRef(local_class);
auto method = env->GetMethodID(WebViewImplementationNative::global_class_reference, "bindWebContentService", "(II)V");
auto method = env->GetMethodID(WebViewImplementationNative::global_class_reference, "bindWebContentService", "(I)V");
if (!method)
TODO();
WebViewImplementationNative::bind_webcontent_method = method;

View file

@ -19,7 +19,7 @@ import java.lang.ref.WeakReference
import java.util.concurrent.Executors
const val MSG_SET_RESOURCE_ROOT = 1
const val MSG_TRANSFER_SOCKETS = 2
const val MSG_TRANSFER_SOCKET = 2
abstract class LadybirdServiceBase(protected val TAG: String) : Service() {
private val threadPool = Executors.newCachedThreadPool()
@ -44,8 +44,7 @@ abstract class LadybirdServiceBase(protected val TAG: String) : Service() {
val bundle = msg.data
// FIXME: Handle garbage messages from wierd clients
val ipcSocket = bundle.getParcelable<ParcelFileDescriptor>("IPC_SOCKET")!!
val fdSocket = bundle.getParcelable<ParcelFileDescriptor>("FD_PASSING_SOCKET")!!
createThread(ipcSocket, fdSocket)
createThread(ipcSocket)
}
private fun handleSetResourceRoot(msg: Message) {
@ -61,13 +60,13 @@ abstract class LadybirdServiceBase(protected val TAG: String) : Service() {
}
private fun createThread(ipcSocket: ParcelFileDescriptor, fdSocket: ParcelFileDescriptor) {
private fun createThread(ipcSocket: ParcelFileDescriptor) {
threadPool.execute {
nativeThreadLoop(ipcSocket.detachFd(), fdSocket.detachFd())
nativeThreadLoop(ipcSocket.detachFd())
}
}
private external fun nativeThreadLoop(ipcSocket: Int, fdPassingSocket: Int)
private external fun nativeThreadLoop(ipcSocket: Int)
private external fun initNativeCode(resourceDir: String, tagName: String);
abstract fun handleServiceSpecificMessage(msg: Message): Boolean
@ -78,7 +77,7 @@ abstract class LadybirdServiceBase(protected val TAG: String) : Service() {
Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
when (msg.what) {
MSG_TRANSFER_SOCKETS -> service.get()?.handleTransferSockets(msg)
MSG_TRANSFER_SOCKET -> service.get()?.handleTransferSockets(msg)
?: super.handleMessage(msg)
MSG_SET_RESOURCE_ROOT -> service.get()?.handleSetResourceRoot(msg)

View file

@ -15,7 +15,6 @@ import android.os.ParcelFileDescriptor
class LadybirdServiceConnection(
private var ipcFd: Int,
private var fdPassingFd: Int,
private var resourceDir: String
) :
ServiceConnection {
@ -36,9 +35,8 @@ class LadybirdServiceConnection(
init.data.putString("PATH", resourceDir)
service!!.send(init)
val msg = Message.obtain(null, MSG_TRANSFER_SOCKETS)
val msg = Message.obtain(null, MSG_TRANSFER_SOCKET)
msg.data.putParcelable("IPC_SOCKET", ParcelFileDescriptor.adoptFd(ipcFd))
msg.data.putParcelable("FD_PASSING_SOCKET", ParcelFileDescriptor.adoptFd(fdPassingFd))
service!!.send(msg)
}

View file

@ -30,7 +30,7 @@ class TimerExecutorService {
timer,
milliseconds,
TimeUnit.MILLISECONDS
) else executor.scheduleAtFixedRate(
) else executor.scheduleWithFixedDelay(
timer,
milliseconds,
milliseconds,
@ -40,9 +40,9 @@ class TimerExecutorService {
return id
}
fun unregisterTimer(id: Long): Boolean {
val timer = timers[id] ?: return false
return timer.cancel(false)
fun unregisterTimer(id: Long) {
val timer = timers[id] ?: return
timer.cancel(false)
}
private var nextId: Long = 0

View file

@ -20,9 +20,9 @@ class WebContentService : LadybirdServiceBase("WebContentService") {
nativeInit();
}
private fun bindRequestServer(ipcFd: Int, fdPassingFd: Int)
private fun bindRequestServer(ipcFd: Int)
{
val connector = LadybirdServiceConnection(ipcFd, fdPassingFd, resourceDir)
val connector = LadybirdServiceConnection(ipcFd, resourceDir)
connector.onDisconnect = {
// FIXME: Notify impl that service is dead and might need restarted
Log.e(TAG, "RequestServer Died! :(")
@ -35,9 +35,9 @@ class WebContentService : LadybirdServiceBase("WebContentService") {
)
}
private fun bindImageDecoder(ipcFd: Int, fdPassingFd: Int)
private fun bindImageDecoder(ipcFd: Int)
{
val connector = LadybirdServiceConnection(ipcFd, fdPassingFd, resourceDir)
val connector = LadybirdServiceConnection(ipcFd, resourceDir)
connector.onDisconnect = {
// FIXME: Notify impl that service is dead and might need restarted
Log.e(TAG, "ImageDecoder Died! :(")

View file

@ -41,11 +41,11 @@ class WebView(context: Context, attributeSet: AttributeSet) : View(context, attr
viewImpl.setViewportGeometry(w, h)
}
override fun onDraw(canvas: Canvas?) {
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
viewImpl.drawIntoBitmap(contentBitmap);
canvas?.drawBitmap(contentBitmap, 0f, 0f, null)
canvas.drawBitmap(contentBitmap, 0f, 0f, null)
}
}

View file

@ -50,8 +50,8 @@ class WebViewImplementation(private val view: WebView) {
}
// Functions called from native code
fun bindWebContentService(ipcFd: Int, fdPassingFd: Int) {
val connector = LadybirdServiceConnection(ipcFd, fdPassingFd, resourceDir)
fun bindWebContentService(ipcFd: Int) {
val connector = LadybirdServiceConnection(ipcFd, resourceDir)
connector.onDisconnect = {
// FIXME: Notify impl that service is dead and might need restarted
Log.e("WebContentView", "WebContent Died! :(")

View file

@ -20,7 +20,7 @@ else()
endif()
add_executable(ImageDecoder main.cpp)
target_link_libraries(ImageDecoder PRIVATE imagedecoder LibMain)
target_link_libraries(ImageDecoder PRIVATE imagedecoder LibCore LibMain)
target_include_directories(imagedecoder PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services/)
target_include_directories(imagedecoder PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..)

View file

@ -32,7 +32,7 @@ jobs:
value: '${{ parameters.host_cxx }}'
- name: ndk_version # only relevant for Android
value: '25.2.9519653'
value: '26.1.10909125'
pool:
vmImage: $(job_pool)