mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
Ladybird/Android: Move JNI functions into their own files
This should be easier to work on, and keeps the layers of the native code nice and clean cut.
This commit is contained in:
parent
274fd88242
commit
315ad2d391
Notes:
sideshowbarker
2024-07-17 21:16:31 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/315ad2d391 Pull-request: https://github.com/SerenityOS/serenity/pull/21100
8 changed files with 256 additions and 210 deletions
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "WebContentService.h"
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <Ladybird/FontPlugin.h>
|
||||
#include <Ladybird/HelperProcess.h>
|
||||
|
@ -26,8 +27,6 @@
|
|||
#include <LibWebView/WebSocketClientAdapter.h>
|
||||
#include <WebContent/ConnectionFromClient.h>
|
||||
#include <WebContent/PageHost.h>
|
||||
#include <jni.h>
|
||||
#include <unistd.h>
|
||||
|
||||
class NullResourceConnector : public Web::ResourceLoaderConnector {
|
||||
virtual void prefetch_dns(AK::URL const&) override { }
|
||||
|
@ -72,33 +71,3 @@ ErrorOr<int> web_content_main(int ipc_socket, int fd_passing_socket)
|
|||
|
||||
return event_loop.exec();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebContentService_nativeThreadLoop(JNIEnv*, jobject /* thiz */, jint ipc_socket, jint fd_passing_socket)
|
||||
{
|
||||
dbgln("New binding received, sockets {} and {}", ipc_socket, fd_passing_socket);
|
||||
auto ret = web_content_main(ipc_socket, fd_passing_socket);
|
||||
if (ret.is_error()) {
|
||||
warnln("Runtime Error: {}", ret.release_error());
|
||||
} else {
|
||||
outln("Thread exited with code {}", ret.release_value());
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebContentService_initNativeCode(JNIEnv* env, jobject /* thiz */, jstring resource_dir, jstring tag_name)
|
||||
{
|
||||
static Atomic<bool> s_initialized_flag { false };
|
||||
if (s_initialized_flag.exchange(true) == true) {
|
||||
// Skip initializing if someone else already started the process at some point in the past
|
||||
return;
|
||||
}
|
||||
|
||||
char const* raw_resource_dir = env->GetStringUTFChars(resource_dir, nullptr);
|
||||
s_serenity_resource_root = raw_resource_dir;
|
||||
env->ReleaseStringUTFChars(resource_dir, raw_resource_dir);
|
||||
|
||||
char const* raw_tag_name = env->GetStringUTFChars(tag_name, nullptr);
|
||||
AK::set_log_tag_name(raw_tag_name);
|
||||
env->ReleaseStringUTFChars(tag_name, raw_tag_name);
|
||||
}
|
||||
|
|
11
Ladybird/Android/src/main/cpp/WebContentService.h
Normal file
11
Ladybird/Android/src/main/cpp/WebContentService.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
|
||||
ErrorOr<int> web_content_main(int ipc_socket, int fd_passing_socket);
|
41
Ladybird/Android/src/main/cpp/WebContentServiceJNI.cpp
Normal file
41
Ladybird/Android/src/main/cpp/WebContentServiceJNI.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "WebContentService.h"
|
||||
#include <AK/Atomic.h>
|
||||
#include <AK/Format.h>
|
||||
#include <Ladybird/Utilities.h>
|
||||
#include <jni.h>
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebContentService_nativeThreadLoop(JNIEnv*, jobject /* thiz */, jint ipc_socket, jint fd_passing_socket)
|
||||
{
|
||||
dbgln("New binding received, sockets {} and {}", ipc_socket, fd_passing_socket);
|
||||
auto ret = web_content_main(ipc_socket, fd_passing_socket);
|
||||
if (ret.is_error()) {
|
||||
warnln("Runtime Error: {}", ret.release_error());
|
||||
} else {
|
||||
outln("Thread exited with code {}", ret.release_value());
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebContentService_initNativeCode(JNIEnv* env, jobject /* thiz */, jstring resource_dir, jstring tag_name)
|
||||
{
|
||||
static Atomic<bool> s_initialized_flag { false };
|
||||
if (s_initialized_flag.exchange(true) == true) {
|
||||
// Skip initializing if someone else already started the process at some point in the past
|
||||
return;
|
||||
}
|
||||
|
||||
char const* raw_resource_dir = env->GetStringUTFChars(resource_dir, nullptr);
|
||||
s_serenity_resource_root = raw_resource_dir;
|
||||
env->ReleaseStringUTFChars(resource_dir, raw_resource_dir);
|
||||
|
||||
char const* raw_tag_name = env->GetStringUTFChars(tag_name, nullptr);
|
||||
AK::set_log_tag_name(raw_tag_name);
|
||||
env->ReleaseStringUTFChars(tag_name, raw_tag_name);
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "WebViewImplementationNative.h"
|
||||
#include "JNIHelpers.h"
|
||||
#include <Userland/Libraries/LibGfx/Bitmap.h>
|
||||
#include <Userland/Libraries/LibGfx/Painter.h>
|
||||
|
@ -12,9 +13,8 @@
|
|||
#include <android/bitmap.h>
|
||||
#include <jni.h>
|
||||
|
||||
namespace {
|
||||
|
||||
Gfx::BitmapFormat to_gfx_bitmap_format(i32 f)
|
||||
namespace Ladybird {
|
||||
static Gfx::BitmapFormat to_gfx_bitmap_format(i32 f)
|
||||
{
|
||||
switch (f) {
|
||||
case ANDROID_BITMAP_FORMAT_RGBA_8888:
|
||||
|
@ -24,109 +24,82 @@ Gfx::BitmapFormat to_gfx_bitmap_format(i32 f)
|
|||
}
|
||||
}
|
||||
|
||||
class WebViewImplementationNative : public WebView::ViewImplementation {
|
||||
public:
|
||||
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);
|
||||
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);
|
||||
|
||||
on_ready_to_paint = [this]() {
|
||||
JavaEnvironment env(global_vm);
|
||||
env.get()->CallVoidMethod(m_java_instance, invalidate_layout_method);
|
||||
};
|
||||
}
|
||||
on_ready_to_paint = [this]() {
|
||||
JavaEnvironment env(global_vm);
|
||||
env.get()->CallVoidMethod(m_java_instance, invalidate_layout_method);
|
||||
};
|
||||
}
|
||||
|
||||
virtual Gfx::IntRect 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 { }
|
||||
void WebViewImplementationNative::create_client(WebView::EnableCallgrindProfiling)
|
||||
{
|
||||
m_client_state = {};
|
||||
|
||||
NonnullRefPtr<WebView::WebContentClient> bind_web_content_client();
|
||||
auto new_client = bind_web_content_client();
|
||||
|
||||
virtual void create_client(WebView::EnableCallgrindProfiling) override
|
||||
{
|
||||
m_client_state = {};
|
||||
m_client_state.client = new_client;
|
||||
m_client_state.client->on_web_content_process_crash = [] {
|
||||
warnln("WebContent crashed!");
|
||||
// FIXME: launch a new client
|
||||
};
|
||||
|
||||
auto new_client = bind_web_content_client();
|
||||
m_client_state.client_handle = MUST(Web::Crypto::generate_random_uuid());
|
||||
client().async_set_window_handle(m_client_state.client_handle);
|
||||
|
||||
m_client_state.client = new_client;
|
||||
m_client_state.client->on_web_content_process_crash = [] {
|
||||
warnln("WebContent crashed!");
|
||||
// FIXME: launch a new client
|
||||
};
|
||||
client().async_set_device_pixels_per_css_pixel(m_device_pixel_ratio);
|
||||
|
||||
m_client_state.client_handle = MUST(Web::Crypto::generate_random_uuid());
|
||||
client().async_set_window_handle(m_client_state.client_handle);
|
||||
// FIXME: update_palette, update system fonts
|
||||
}
|
||||
|
||||
client().async_set_device_pixels_per_css_pixel(m_device_pixel_ratio);
|
||||
void WebViewImplementationNative::paint_into_bitmap(void* android_bitmap_raw, AndroidBitmapInfo const& info)
|
||||
{
|
||||
// Software bitmaps only for now!
|
||||
VERIFY((info.flags & ANDROID_BITMAP_FLAGS_IS_HARDWARE) == 0);
|
||||
|
||||
// FIXME: update_palette, update system fonts
|
||||
}
|
||||
auto android_bitmap = MUST(Gfx::Bitmap::create_wrapper(to_gfx_bitmap_format(info.format), { info.width, info.height }, 1, info.stride, android_bitmap_raw));
|
||||
Gfx::Painter painter(android_bitmap);
|
||||
if (auto* bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr())
|
||||
painter.blit({ 0, 0 }, *bitmap, bitmap->rect());
|
||||
else
|
||||
painter.clear_rect(painter.clip_rect(), Gfx::Color::Magenta);
|
||||
|
||||
void paint_into_bitmap(void* android_bitmap_raw, AndroidBitmapInfo const& info)
|
||||
{
|
||||
// Software bitmaps only for now!
|
||||
VERIFY((info.flags & ANDROID_BITMAP_FLAGS_IS_HARDWARE) == 0);
|
||||
|
||||
auto android_bitmap = MUST(Gfx::Bitmap::create_wrapper(to_gfx_bitmap_format(info.format), { info.width, info.height }, 1, info.stride, android_bitmap_raw));
|
||||
Gfx::Painter painter(android_bitmap);
|
||||
if (auto* bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr())
|
||||
painter.blit({ 0, 0 }, *bitmap, bitmap->rect());
|
||||
else
|
||||
painter.clear_rect(painter.clip_rect(), Gfx::Color::Magenta);
|
||||
|
||||
// Convert our internal BGRA into RGBA. This will be slowwwwwww
|
||||
// FIXME: Don't do a color format swap here.
|
||||
for (auto y = 0; y < android_bitmap->height(); ++y) {
|
||||
auto* scanline = android_bitmap->scanline(y);
|
||||
for (auto x = 0; x < android_bitmap->width(); ++x) {
|
||||
auto current_pixel = scanline[x];
|
||||
u32 alpha = (current_pixel & 0xFF000000U) >> 24;
|
||||
u32 red = (current_pixel & 0x00FF0000U) >> 16;
|
||||
u32 green = (current_pixel & 0x0000FF00U) >> 8;
|
||||
u32 blue = (current_pixel & 0x000000FFU);
|
||||
scanline[x] = (alpha << 24U) | (blue << 16U) | (green << 8U) | red;
|
||||
}
|
||||
// Convert our internal BGRA into RGBA. This will be slowwwwwww
|
||||
// FIXME: Don't do a color format swap here.
|
||||
for (auto y = 0; y < android_bitmap->height(); ++y) {
|
||||
auto* scanline = android_bitmap->scanline(y);
|
||||
for (auto x = 0; x < android_bitmap->width(); ++x) {
|
||||
auto current_pixel = scanline[x];
|
||||
u32 alpha = (current_pixel & 0xFF000000U) >> 24;
|
||||
u32 red = (current_pixel & 0x00FF0000U) >> 16;
|
||||
u32 green = (current_pixel & 0x0000FF00U) >> 8;
|
||||
u32 blue = (current_pixel & 0x000000FFU);
|
||||
scanline[x] = (alpha << 24U) | (blue << 16U) | (green << 8U) | red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_viewport_geometry(int w, int h)
|
||||
{
|
||||
m_viewport_rect = { { 0, 0 }, { w, h } };
|
||||
client().async_set_viewport_rect(m_viewport_rect);
|
||||
request_repaint();
|
||||
handle_resize();
|
||||
}
|
||||
void WebViewImplementationNative::set_viewport_geometry(int w, int h)
|
||||
{
|
||||
m_viewport_rect = { { 0, 0 }, { w, h } };
|
||||
client().async_set_viewport_rect(m_viewport_rect);
|
||||
request_repaint();
|
||||
handle_resize();
|
||||
}
|
||||
|
||||
void set_device_pixel_ratio(float f)
|
||||
{
|
||||
m_device_pixel_ratio = f;
|
||||
client().async_set_device_pixels_per_css_pixel(m_device_pixel_ratio);
|
||||
}
|
||||
|
||||
static jclass global_class_reference;
|
||||
static jfieldID instance_pointer_field;
|
||||
static jmethodID bind_webcontent_method;
|
||||
static jmethodID invalidate_layout_method;
|
||||
static JavaVM* global_vm;
|
||||
|
||||
jobject java_instance() const { return m_java_instance; }
|
||||
|
||||
private:
|
||||
jobject m_java_instance = nullptr;
|
||||
Gfx::IntRect m_viewport_rect;
|
||||
};
|
||||
jclass WebViewImplementationNative::global_class_reference;
|
||||
jfieldID WebViewImplementationNative::instance_pointer_field;
|
||||
jmethodID WebViewImplementationNative::bind_webcontent_method;
|
||||
jmethodID WebViewImplementationNative::invalidate_layout_method;
|
||||
JavaVM* WebViewImplementationNative::global_vm;
|
||||
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);
|
||||
}
|
||||
|
||||
NonnullRefPtr<WebView::WebContentClient> WebViewImplementationNative::bind_web_content_client()
|
||||
{
|
||||
JavaEnvironment env(WebViewImplementationNative::global_vm);
|
||||
JavaEnvironment env(global_vm);
|
||||
|
||||
int socket_fds[2] {};
|
||||
MUST(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds));
|
||||
|
@ -151,89 +124,4 @@ NonnullRefPtr<WebView::WebContentClient> WebViewImplementationNative::bind_web_c
|
|||
|
||||
return new_client;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_00024Companion_nativeClassInit(JNIEnv* env, jobject /* thiz */)
|
||||
{
|
||||
auto ret = env->GetJavaVM(&WebViewImplementationNative::global_vm);
|
||||
if (ret != 0)
|
||||
TODO();
|
||||
|
||||
auto local_class = env->FindClass("org/serenityos/ladybird/WebViewImplementation");
|
||||
if (!local_class)
|
||||
TODO();
|
||||
WebViewImplementationNative::global_class_reference = reinterpret_cast<jclass>(env->NewGlobalRef(local_class));
|
||||
env->DeleteLocalRef(local_class);
|
||||
|
||||
auto field = env->GetFieldID(WebViewImplementationNative::global_class_reference, "nativeInstance", "J");
|
||||
if (!field)
|
||||
TODO();
|
||||
WebViewImplementationNative::instance_pointer_field = field;
|
||||
|
||||
auto method = env->GetMethodID(WebViewImplementationNative::global_class_reference, "bindWebContentService", "(II)V");
|
||||
if (!method)
|
||||
TODO();
|
||||
WebViewImplementationNative::bind_webcontent_method = method;
|
||||
|
||||
method = env->GetMethodID(WebViewImplementationNative::global_class_reference, "invalidateLayout", "()V");
|
||||
if (!method)
|
||||
TODO();
|
||||
WebViewImplementationNative::invalidate_layout_method = method;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeObjectInit(JNIEnv* env, jobject thiz)
|
||||
{
|
||||
auto ref = env->NewGlobalRef(thiz);
|
||||
auto instance = reinterpret_cast<jlong>(new WebViewImplementationNative(ref));
|
||||
return instance;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeObjectDispose(JNIEnv* env, jobject /* thiz */, jlong instance)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
env->DeleteGlobalRef(impl->java_instance());
|
||||
delete impl;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeDrawIntoBitmap(JNIEnv* env, jobject /* thiz */, jlong instance, jobject bitmap)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
|
||||
AndroidBitmapInfo bitmap_info = {};
|
||||
void* pixels = nullptr;
|
||||
AndroidBitmap_getInfo(env, bitmap, &bitmap_info);
|
||||
AndroidBitmap_lockPixels(env, bitmap, &pixels);
|
||||
if (pixels)
|
||||
impl->paint_into_bitmap(pixels, bitmap_info);
|
||||
|
||||
AndroidBitmap_unlockPixels(env, bitmap);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeSetViewportGeometry(JNIEnv*, jobject /* thiz */, jlong instance, jint w, jint h)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
impl->set_viewport_geometry(w, h);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeLoadURL(JNIEnv* env, jobject /* thiz */, jlong instance, jstring url)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
char const* raw_url = env->GetStringUTFChars(url, nullptr);
|
||||
auto ak_url = AK::URL::create_with_url_or_path(StringView { raw_url, strlen(raw_url) });
|
||||
env->ReleaseStringUTFChars(url, raw_url);
|
||||
impl->load(ak_url);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeSetDevicePixelRatio(JNIEnv*, jobject /* thiz */, jlong instance, jfloat ratio)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
impl->set_device_pixel_ratio(ratio);
|
||||
}
|
||||
|
|
43
Ladybird/Android/src/main/cpp/WebViewImplementationNative.h
Normal file
43
Ladybird/Android/src/main/cpp/WebViewImplementationNative.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Userland/Libraries/LibWebView/ViewImplementation.h>
|
||||
#include <android/bitmap.h>
|
||||
#include <jni.h>
|
||||
|
||||
namespace Ladybird {
|
||||
class WebViewImplementationNative : public WebView::ViewImplementation {
|
||||
public:
|
||||
WebViewImplementationNative(jobject thiz);
|
||||
|
||||
virtual Gfx::IntRect 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;
|
||||
|
||||
void paint_into_bitmap(void* android_bitmap_raw, AndroidBitmapInfo const& info);
|
||||
|
||||
void set_viewport_geometry(int w, int h);
|
||||
void set_device_pixel_ratio(float f);
|
||||
|
||||
static jclass global_class_reference;
|
||||
static jmethodID bind_webcontent_method;
|
||||
static jmethodID invalidate_layout_method;
|
||||
static JavaVM* global_vm;
|
||||
|
||||
jobject java_instance() const { return m_java_instance; }
|
||||
|
||||
private:
|
||||
jobject m_java_instance = nullptr;
|
||||
Gfx::IntRect m_viewport_rect;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "WebViewImplementationNative.h"
|
||||
#include <jni.h>
|
||||
|
||||
using namespace Ladybird;
|
||||
|
||||
jclass WebViewImplementationNative::global_class_reference;
|
||||
jmethodID WebViewImplementationNative::bind_webcontent_method;
|
||||
jmethodID WebViewImplementationNative::invalidate_layout_method;
|
||||
JavaVM* WebViewImplementationNative::global_vm;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_00024Companion_nativeClassInit(JNIEnv* env, jobject /* thiz */)
|
||||
{
|
||||
auto ret = env->GetJavaVM(&WebViewImplementationNative::global_vm);
|
||||
if (ret != 0)
|
||||
TODO();
|
||||
|
||||
auto local_class = env->FindClass("org/serenityos/ladybird/WebViewImplementation");
|
||||
if (!local_class)
|
||||
TODO();
|
||||
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");
|
||||
if (!method)
|
||||
TODO();
|
||||
WebViewImplementationNative::bind_webcontent_method = method;
|
||||
|
||||
method = env->GetMethodID(WebViewImplementationNative::global_class_reference, "invalidateLayout", "()V");
|
||||
if (!method)
|
||||
TODO();
|
||||
WebViewImplementationNative::invalidate_layout_method = method;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeObjectInit(JNIEnv* env, jobject thiz)
|
||||
{
|
||||
auto ref = env->NewGlobalRef(thiz);
|
||||
auto instance = reinterpret_cast<jlong>(new WebViewImplementationNative(ref));
|
||||
return instance;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeObjectDispose(JNIEnv* env, jobject /* thiz */, jlong instance)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
env->DeleteGlobalRef(impl->java_instance());
|
||||
delete impl;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeDrawIntoBitmap(JNIEnv* env, jobject /* thiz */, jlong instance, jobject bitmap)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
|
||||
AndroidBitmapInfo bitmap_info = {};
|
||||
void* pixels = nullptr;
|
||||
AndroidBitmap_getInfo(env, bitmap, &bitmap_info);
|
||||
AndroidBitmap_lockPixels(env, bitmap, &pixels);
|
||||
if (pixels)
|
||||
impl->paint_into_bitmap(pixels, bitmap_info);
|
||||
|
||||
AndroidBitmap_unlockPixels(env, bitmap);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeSetViewportGeometry(JNIEnv*, jobject /* thiz */, jlong instance, jint w, jint h)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
impl->set_viewport_geometry(w, h);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeLoadURL(JNIEnv* env, jobject /* thiz */, jlong instance, jstring url)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
char const* raw_url = env->GetStringUTFChars(url, nullptr);
|
||||
auto ak_url = AK::URL::create_with_url_or_path(StringView { raw_url, strlen(raw_url) });
|
||||
env->ReleaseStringUTFChars(url, raw_url);
|
||||
impl->load(ak_url);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeSetDevicePixelRatio(JNIEnv*, jobject /* thiz */, jlong instance, jfloat ratio)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
impl->set_device_pixel_ratio(ratio);
|
||||
}
|
|
@ -155,10 +155,11 @@ elseif(ANDROID)
|
|||
${SOURCES}
|
||||
Android/src/main/cpp/LadybirdActivity.cpp
|
||||
Android/src/main/cpp/WebViewImplementationNative.cpp
|
||||
Android/src/main/cpp/WebViewImplementationNativeJNI.cpp
|
||||
Android/src/main/cpp/ALooperEventLoopImplementation.cpp
|
||||
Android/src/main/cpp/TimerExecutorService.cpp
|
||||
)
|
||||
target_link_libraries(ladybird PRIVATE LibArchive log jnigraphics android)
|
||||
target_link_libraries(ladybird PRIVATE LibArchive jnigraphics android)
|
||||
else()
|
||||
# TODO: Check for other GUI frameworks here when we move them in-tree
|
||||
# For now, we can export a static library of common files for chromes to link to
|
||||
|
|
|
@ -55,10 +55,9 @@ else()
|
|||
if (ANDROID)
|
||||
target_sources(webcontent PRIVATE
|
||||
../Android/src/main/cpp/WebContentService.cpp
|
||||
../Android/src/main/cpp/ALooperEventLoopImplementation.cpp
|
||||
../Android/src/main/cpp/TimerExecutorService.cpp
|
||||
../Android/src/main/cpp/WebContentServiceJNI.cpp
|
||||
)
|
||||
target_link_libraries(webcontent PRIVATE log android)
|
||||
target_link_libraries(webcontent PRIVATE android)
|
||||
endif()
|
||||
|
||||
add_executable(WebContent main.cpp)
|
||||
|
|
Loading…
Reference in a new issue