diff --git a/Ladybird/Android/src/main/AndroidManifest.xml b/Ladybird/Android/src/main/AndroidManifest.xml
index c654cc0cb0..bcf49bc8a0 100644
--- a/Ladybird/Android/src/main/AndroidManifest.xml
+++ b/Ladybird/Android/src/main/AndroidManifest.xml
@@ -61,6 +61,11 @@
android:enabled="true"
android:exported="false"
android:process=":WebSocket" />
+
diff --git a/Ladybird/Android/src/main/cpp/ImageDecoderService.cpp b/Ladybird/Android/src/main/cpp/ImageDecoderService.cpp
new file mode 100644
index 0000000000..1086a6e2b9
--- /dev/null
+++ b/Ladybird/Android/src/main/cpp/ImageDecoderService.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2018-2020, Andreas Kling
+ * Copyright (c) 2023, Andrew Kaster
+ * Copyright (c) 2023, Lucas Chollet
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include
+#include
+#include
+
+ErrorOr service_main(int ipc_socket, int fd_passing_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();
+}
diff --git a/Ladybird/Android/src/main/cpp/WebContentService.cpp b/Ladybird/Android/src/main/cpp/WebContentService.cpp
index 637c56f408..b0f10d7174 100644
--- a/Ladybird/Android/src/main/cpp/WebContentService.cpp
+++ b/Ladybird/Android/src/main/cpp/WebContentService.cpp
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -41,7 +42,11 @@ static ErrorOr> bind_web_socket_service
return bind_service(&bind_web_socket_java);
}
+template ErrorOr, Error>
+bind_service(void (*)(int, int));
+
static ErrorOr load_content_filters();
+
static ErrorOr load_autoplay_allowlist();
ErrorOr service_main(int ipc_socket, int fd_passing_socket)
diff --git a/Ladybird/Android/src/main/cpp/WebContentService.h b/Ladybird/Android/src/main/cpp/WebContentService.h
index 9e570ab26c..ab67091ca1 100644
--- a/Ladybird/Android/src/main/cpp/WebContentService.h
+++ b/Ladybird/Android/src/main/cpp/WebContentService.h
@@ -13,3 +13,4 @@ ErrorOr> bind_service(void (*bind_method)(int, 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);
diff --git a/Ladybird/Android/src/main/cpp/WebContentServiceJNI.cpp b/Ladybird/Android/src/main/cpp/WebContentServiceJNI.cpp
index e4b4ae8dc3..e050bbb673 100644
--- a/Ladybird/Android/src/main/cpp/WebContentServiceJNI.cpp
+++ b/Ladybird/Android/src/main/cpp/WebContentServiceJNI.cpp
@@ -12,6 +12,7 @@ jobject global_instance;
jclass global_class_reference;
jmethodID bind_request_server_method;
jmethodID bind_web_socket_method;
+jmethodID bind_image_decoder_method;
extern "C" JNIEXPORT void JNICALL
Java_org_serenityos_ladybird_WebContentService_nativeInit(JNIEnv* env, jobject thiz)
@@ -33,6 +34,11 @@ Java_org_serenityos_ladybird_WebContentService_nativeInit(JNIEnv* env, jobject t
if (!method)
TODO();
bind_web_socket_method = method;
+
+ method = env->GetMethodID(global_class_reference, "bindImageDecoder", "(II)V");
+ if (!method)
+ TODO();
+ bind_image_decoder_method = method;
}
void bind_request_server_java(int ipc_socket, int fd_passing_socket)
@@ -46,3 +52,9 @@ void bind_web_socket_java(int ipc_socket, int fd_passing_socket)
Ladybird::JavaEnvironment env(global_vm);
env.get()->CallVoidMethod(global_instance, bind_web_socket_method, ipc_socket, fd_passing_socket);
}
+
+void bind_image_decoder_java(int ipc_socket, int fd_passing_socket)
+{
+ Ladybird::JavaEnvironment env(global_vm);
+ env.get()->CallVoidMethod(global_instance, bind_image_decoder_method, ipc_socket, fd_passing_socket);
+}
diff --git a/Ladybird/Android/src/main/java/org/serenityos/ladybird/ImageDecoderService.kt b/Ladybird/Android/src/main/java/org/serenityos/ladybird/ImageDecoderService.kt
new file mode 100644
index 0000000000..1c5e1cb522
--- /dev/null
+++ b/Ladybird/Android/src/main/java/org/serenityos/ladybird/ImageDecoderService.kt
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2023, Andrew Kaster
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+package org.serenityos.ladybird
+
+import android.os.Message
+
+class ImageDecoderService : LadybirdServiceBase("ImageDecoderService") {
+ override fun handleServiceSpecificMessage(msg: Message): Boolean {
+ return false
+ }
+
+ companion object {
+ init {
+ System.loadLibrary("imagedecoder")
+ }
+ }
+}
diff --git a/Ladybird/Android/src/main/java/org/serenityos/ladybird/WebContentService.kt b/Ladybird/Android/src/main/java/org/serenityos/ladybird/WebContentService.kt
index 705445a236..0108808b9e 100644
--- a/Ladybird/Android/src/main/java/org/serenityos/ladybird/WebContentService.kt
+++ b/Ladybird/Android/src/main/java/org/serenityos/ladybird/WebContentService.kt
@@ -40,7 +40,7 @@ class WebContentService : LadybirdServiceBase("WebContentService") {
val connector = LadybirdServiceConnection(ipcFd, fdPassingFd, resourceDir)
connector.onDisconnect = {
// FIXME: Notify impl that service is dead and might need restarted
- Log.e(TAG, "RequestServer Died! :(")
+ Log.e(TAG, "WebSocket Died! :(")
}
// FIXME: Unbind this at some point maybe
bindService(
@@ -50,6 +50,21 @@ class WebContentService : LadybirdServiceBase("WebContentService") {
)
}
+ private fun bindImageDecoder(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, "ImageDecoder Died! :(")
+ }
+ // FIXME: Unbind this at some point maybe
+ bindService(
+ Intent(this, ImageDecoderService::class.java),
+ connector,
+ Context.BIND_AUTO_CREATE
+ )
+ }
+
external fun nativeInit()
companion object {
diff --git a/Ladybird/ImageCodecPlugin.cpp b/Ladybird/ImageCodecPlugin.cpp
index 95d8c38e59..b10155f1be 100644
--- a/Ladybird/ImageCodecPlugin.cpp
+++ b/Ladybird/ImageCodecPlugin.cpp
@@ -6,7 +6,11 @@
*/
#include "ImageCodecPlugin.h"
-#include "HelperProcess.h"
+#ifdef AK_OS_ANDROID
+# include
+#else
+# include "HelperProcess.h"
+#endif
#include "Utilities.h"
#include
#include
@@ -19,8 +23,12 @@ ImageCodecPlugin::~ImageCodecPlugin() = default;
Optional ImageCodecPlugin::decode_image(ReadonlyBytes bytes)
{
if (!m_client) {
+#ifdef AK_OS_ANDROID
+ m_client = MUST(bind_service(&bind_image_decoder_java));
+#else
auto candidate_image_decoder_paths = get_paths_for_helper_process("ImageDecoder"sv).release_value_but_fixme_should_propagate_errors();
m_client = launch_image_decoder_process(candidate_image_decoder_paths).release_value_but_fixme_should_propagate_errors();
+#endif
m_client->on_death = [&] {
m_client = nullptr;
};
diff --git a/Ladybird/ImageDecoder/CMakeLists.txt b/Ladybird/ImageDecoder/CMakeLists.txt
index a1eca1f9f9..ac506d5a8c 100644
--- a/Ladybird/ImageDecoder/CMakeLists.txt
+++ b/Ladybird/ImageDecoder/CMakeLists.txt
@@ -2,11 +2,22 @@ set(IMAGE_DECODER_SOURCE_DIR ${SERENITY_SOURCE_DIR}/Userland/Services/ImageDecod
set(IMAGE_DECODER_SOURCES
${IMAGE_DECODER_SOURCE_DIR}/ConnectionFromClient.cpp
- main.cpp
)
-add_executable(ImageDecoder ${IMAGE_DECODER_SOURCES})
+if (ANDROID)
+ add_library(imagedecoder SHARED
+ ${IMAGE_DECODER_SOURCES}
+ ../Android/src/main/cpp/ImageDecoderService.cpp
+ ../Android/src/main/cpp/LadybirdServiceBaseJNI.cpp
+ ../Utilities.cpp
+ )
+else()
+ add_library(imagedecoder STATIC ${IMAGE_DECODER_SOURCES})
+endif()
-target_include_directories(ImageDecoder PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services/)
-target_include_directories(ImageDecoder PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..)
-target_link_libraries(ImageDecoder PRIVATE LibCore LibGfx LibIPC LibImageDecoderClient LibMain)
+add_executable(ImageDecoder main.cpp)
+target_link_libraries(ImageDecoder PRIVATE imagedecoder LibMain)
+
+target_include_directories(imagedecoder PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services/)
+target_include_directories(imagedecoder PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..)
+target_link_libraries(imagedecoder PRIVATE LibCore LibGfx LibIPC LibImageDecoderClient LibMain)
diff --git a/Ladybird/WebContent/CMakeLists.txt b/Ladybird/WebContent/CMakeLists.txt
index 2ac635007a..89efdb394c 100644
--- a/Ladybird/WebContent/CMakeLists.txt
+++ b/Ladybird/WebContent/CMakeLists.txt
@@ -37,7 +37,7 @@ else()
add_library(webcontent ${LIB_TYPE} ${WEBCONTENT_SOURCES})
target_include_directories(webcontent PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services/)
target_include_directories(webcontent PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..)
- target_link_libraries(webcontent PRIVATE LibAudio LibCore LibFileSystem LibGfx LibIPC LibJS LibMain LibWeb LibWebSocket LibProtocol LibWebView)
+ target_link_libraries(webcontent PRIVATE LibAudio LibCore LibFileSystem LibGfx LibIPC LibJS LibMain LibWeb LibWebSocket LibProtocol LibWebView LibImageDecoderClient)
target_sources(webcontent PUBLIC FILE_SET ladybird TYPE HEADERS
BASE_DIRS ${SERENITY_SOURCE_DIR}
FILES ../FontPlugin.h