mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
Ladybird/Android: Create a service for ImageDecoder
This follows the pattern for the other services spawned by WebContent. The notable quirk about this service is that it's actually spawned by the ImageCodecPlugin rather than in main.cpp in the non-Android port. As a result we needed to do some ifdef surgery to get all the pieces in place. But we can now load images in the Android port again :^).
This commit is contained in:
parent
a54baa2c34
commit
c990db0913
Notes:
sideshowbarker
2024-07-16 20:51:53 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/c990db0913 Pull-request: https://github.com/SerenityOS/serenity/pull/21721
10 changed files with 108 additions and 8 deletions
|
@ -61,6 +61,11 @@
|
|||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:process=":WebSocket" />
|
||||
<service
|
||||
android:name=".ImageDecoderService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:process=":ImageDecoder" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
22
Ladybird/Android/src/main/cpp/ImageDecoderService.cpp
Normal file
22
Ladybird/Android/src/main/cpp/ImageDecoderService.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
||||
* Copyright (c) 2023, Lucas Chollet <lucas.chollet@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <ImageDecoder/ConnectionFromClient.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibIPC/SingleServer.h>
|
||||
|
||||
ErrorOr<int> 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();
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
#include <LibCore/LocalServer.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibIPC/ConnectionFromClient.h>
|
||||
#include <LibImageDecoderClient/Client.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
@ -41,7 +42,11 @@ static ErrorOr<NonnullRefPtr<Protocol::WebSocketClient>> bind_web_socket_service
|
|||
return bind_service<Protocol::WebSocketClient>(&bind_web_socket_java);
|
||||
}
|
||||
|
||||
template ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>, Error>
|
||||
bind_service<ImageDecoderClient::Client>(void (*)(int, int));
|
||||
|
||||
static ErrorOr<void> load_content_filters();
|
||||
|
||||
static ErrorOr<void> load_autoplay_allowlist();
|
||||
|
||||
ErrorOr<int> service_main(int ipc_socket, int fd_passing_socket)
|
||||
|
|
|
@ -13,3 +13,4 @@ ErrorOr<NonnullRefPtr<Client>> 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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 ImageDecoderService : LadybirdServiceBase("ImageDecoderService") {
|
||||
override fun handleServiceSpecificMessage(msg: Message): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
init {
|
||||
System.loadLibrary("imagedecoder")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
*/
|
||||
|
||||
#include "ImageCodecPlugin.h"
|
||||
#include "HelperProcess.h"
|
||||
#ifdef AK_OS_ANDROID
|
||||
# include <Ladybird/Android/src/main/cpp/WebContentService.h>
|
||||
#else
|
||||
# include "HelperProcess.h"
|
||||
#endif
|
||||
#include "Utilities.h"
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/ImageFormats/ImageDecoder.h>
|
||||
|
@ -19,8 +23,12 @@ ImageCodecPlugin::~ImageCodecPlugin() = default;
|
|||
Optional<Web::Platform::DecodedImage> ImageCodecPlugin::decode_image(ReadonlyBytes bytes)
|
||||
{
|
||||
if (!m_client) {
|
||||
#ifdef AK_OS_ANDROID
|
||||
m_client = MUST(bind_service<ImageDecoderClient::Client>(&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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue