Inject Android bridge into legacy platform services

This commit is contained in:
2026-06-17 12:15:55 +02:00
parent e1767bdb00
commit a267386188
6 changed files with 84 additions and 22 deletions

View File

@@ -1093,6 +1093,24 @@ void android_main(struct android_app* state) {
// DON'T REMOVE, even if the compiler say it's deprecated // DON'T REMOVE, even if the compiler say it's deprecated
app_dummy(); app_dummy();
auto platform_services = pp::platform::legacy::create_platform_services({ auto platform_services = pp::platform::legacy::create_platform_services({
.android_bridge = {
.clipboard_text = [] { return android_get_clipboard(); },
.set_clipboard_text = [](std::string_view text) {
return android_set_clipboard(std::string(text));
},
.set_virtual_keyboard_visible = [](bool visible) { displayKeyboard(visible); },
.attach_ui_thread = [] { android_attach_jni(); },
.detach_ui_thread = [] { android_detach_jni(); },
.acquire_render_context = [] { android_async_lock(); },
.release_render_context = [] { android_async_unlock(); },
.present_render_context = [] { android_async_swap(); },
.pick_file = [](pp::platform::PickedPathCallback callback) {
android_pick_file(std::move(callback));
},
.pick_save_file = [](pp::platform::PickedPathCallback callback) {
android_pick_file_save(std::move(callback));
},
},
.android_storage_paths = g_android_storage_paths, .android_storage_paths = g_android_storage_paths,
}); });

View File

@@ -1,7 +1,7 @@
# Modernization Debt Log # Modernization Debt Log
Status: live Status: live
Last updated: 2026-06-16 Last updated: 2026-06-17
Every shortcut, temporary adapter, retained vendored dependency, skipped Every shortcut, temporary adapter, retained vendored dependency, skipped
platform gate, compatibility shim, or incomplete automation path must be platform gate, compatibility shim, or incomplete automation path must be
@@ -18,6 +18,13 @@ agent or engineer to remove them without reconstructing context from chat.
## Reductions ## Reductions
- 2026-06-17: `DEBT-0016`/`DEBT-0017` were narrowed again.
`src/platform_legacy/legacy_platform_services.*` now takes an explicit
Android bridge through `create_platform_services(...)`, and
`android/src/cpp/main.cpp` now seeds Android-owned clipboard, keyboard,
JNI-thread attach/detach, async render-context, and file-picker callbacks
into that adapter instead of leaving those JNI/EGL entrypoints declared
directly inside the cross-platform fallback layer.
- 2026-06-17: `DEBT-0017`/`DEBT-0050`/`DEBT-0053`/`DEBT-0057` were narrowed - 2026-06-17: `DEBT-0017`/`DEBT-0050`/`DEBT-0053`/`DEBT-0057` were narrowed
again. `src/platform_legacy/legacy_platform_services.*` now takes an again. `src/platform_legacy/legacy_platform_services.*` now takes an
explicit `WebPlatformServices*` dependency through explicit `WebPlatformServices*` dependency through

View File

@@ -70,6 +70,15 @@ What is already real:
- `pp_app_core` - `pp_app_core`
Latest slice: Latest slice:
- `src/platform_legacy/legacy_platform_services.*` now takes an explicit
Android bridge through `create_platform_services(...)` instead of declaring
Android JNI/EGL/clipboard/file-picker hooks directly inside the legacy
adapter.
- `android/src/cpp/main.cpp` now seeds that Android-owned bridge into its
owned legacy `PlatformServices` instance.
- The touched Android clipboard, keyboard visibility, JNI thread attach/detach,
async render-context, and file-picker ownership now sit at the Android
entrypoint instead of the cross-platform fallback adapter body.
- `src/platform_legacy/legacy_platform_services.*` now takes an explicit - `src/platform_legacy/legacy_platform_services.*` now takes an explicit
`WebPlatformServices*` dependency through `create_platform_services(...)` `WebPlatformServices*` dependency through `create_platform_services(...)`
instead of routing WebGL publish/flush/default-canvas/save-prepared-file instead of routing WebGL publish/flush/default-canvas/save-prepared-file

View File

@@ -78,6 +78,15 @@ Completed, blocked, and superseded task history moved to
the queue is now ordered by code movement instead. the queue is now ordered by code movement instead.
Current slice: Current slice:
- `src/platform_legacy/legacy_platform_services.*` now takes an explicit
Android bridge through `create_platform_services(...)` instead of declaring
Android JNI/EGL/clipboard/file-picker hooks directly inside the legacy
adapter.
- `android/src/cpp/main.cpp` now seeds that Android-owned bridge into its
owned legacy `PlatformServices` instance.
- The touched Android clipboard, keyboard visibility, JNI thread attach/detach,
async render-context, and file-picker ownership now sit at the Android
entrypoint instead of the cross-platform fallback adapter body.
- `src/platform_legacy/legacy_platform_services.*` now takes an explicit - `src/platform_legacy/legacy_platform_services.*` now takes an explicit
`WebPlatformServices*` dependency through `create_platform_services(...)` `WebPlatformServices*` dependency through `create_platform_services(...)`
instead of routing WebGL publish/flush/default-canvas/save-prepared-file instead of routing WebGL publish/flush/default-canvas/save-prepared-file

View File

@@ -12,16 +12,6 @@
#ifdef __ANDROID__ #ifdef __ANDROID__
#include "main.h" #include "main.h"
void displayKeyboard(bool pShow);
void android_async_lock();
void android_async_swap();
void android_async_unlock();
void android_attach_jni();
void android_detach_jni();
void android_pick_file(std::function<void(std::string)> callback);
void android_pick_file_save(std::function<void(std::string)> callback);
std::string android_get_clipboard();
bool android_set_clipboard(const std::string& s);
#elif __APPLE__ #elif __APPLE__
#include <Foundation/Foundation.h> #include <Foundation/Foundation.h>
void delete_all_files_in_path(const std::string& source_path); void delete_all_files_in_path(const std::string& source_path);
@@ -50,6 +40,7 @@ class LegacyPlatformServices final : public pp::platform::PlatformServices {
public: public:
explicit LegacyPlatformServices(pp::platform::legacy::LegacyPlatformServicesConfig config = {}) explicit LegacyPlatformServices(pp::platform::legacy::LegacyPlatformServicesConfig config = {})
: glfw_shell_(std::move(config.glfw_shell)) : glfw_shell_(std::move(config.glfw_shell))
, android_bridge_(std::move(config.android_bridge))
#ifdef __ANDROID__ #ifdef __ANDROID__
, android_storage_paths_(std::move(config.android_storage_paths)) , android_storage_paths_(std::move(config.android_storage_paths))
#endif #endif
@@ -127,7 +118,9 @@ public:
return pp::platform::apple::active_legacy_apple_document_platform_services().clipboard_text(); return pp::platform::apple::active_legacy_apple_document_platform_services().clipboard_text();
#endif #endif
#ifdef __ANDROID__ #ifdef __ANDROID__
return android_get_clipboard(); if (android_bridge_.clipboard_text)
return android_bridge_.clipboard_text();
return {};
#else #else
return {}; return {};
#endif #endif
@@ -142,7 +135,9 @@ public:
#endif #endif
const std::string value(text); const std::string value(text);
#ifdef __ANDROID__ #ifdef __ANDROID__
return android_set_clipboard(value); if (android_bridge_.set_clipboard_text)
return android_bridge_.set_clipboard_text(value);
return false;
#else #else
(void)value; (void)value;
return false; return false;
@@ -163,7 +158,8 @@ public:
#ifdef __IOS__ #ifdef __IOS__
pp::platform::apple::active_legacy_apple_document_platform_services().set_virtual_keyboard_visible(visible); pp::platform::apple::active_legacy_apple_document_platform_services().set_virtual_keyboard_visible(visible);
#elif __ANDROID__ #elif __ANDROID__
displayKeyboard(visible); if (android_bridge_.set_virtual_keyboard_visible)
android_bridge_.set_virtual_keyboard_visible(visible);
#else #else
(void)visible; (void)visible;
#endif #endif
@@ -172,14 +168,16 @@ public:
void attach_ui_thread() override void attach_ui_thread() override
{ {
#ifdef __ANDROID__ #ifdef __ANDROID__
android_attach_jni(); if (android_bridge_.attach_ui_thread)
android_bridge_.attach_ui_thread();
#endif #endif
} }
void detach_ui_thread() override void detach_ui_thread() override
{ {
#ifdef __ANDROID__ #ifdef __ANDROID__
android_detach_jni(); if (android_bridge_.detach_ui_thread)
android_bridge_.detach_ui_thread();
#endif #endif
} }
@@ -188,7 +186,8 @@ public:
#if defined(__IOS__) || defined(__OSX__) #if defined(__IOS__) || defined(__OSX__)
pp::platform::apple::active_legacy_apple_document_platform_services().acquire_render_context(); pp::platform::apple::active_legacy_apple_document_platform_services().acquire_render_context();
#elif __ANDROID__ #elif __ANDROID__
android_async_lock(); if (android_bridge_.acquire_render_context)
android_bridge_.acquire_render_context();
#elif __LINUX__ || __WEB__ #elif __LINUX__ || __WEB__
invoke_legacy_glfw_shell_callback(glfw_shell_.acquire_render_context); invoke_legacy_glfw_shell_callback(glfw_shell_.acquire_render_context);
#endif #endif
@@ -199,7 +198,8 @@ public:
#if defined(__IOS__) || defined(__OSX__) #if defined(__IOS__) || defined(__OSX__)
pp::platform::apple::active_legacy_apple_document_platform_services().release_render_context(); pp::platform::apple::active_legacy_apple_document_platform_services().release_render_context();
#elif __ANDROID__ #elif __ANDROID__
android_async_unlock(); if (android_bridge_.release_render_context)
android_bridge_.release_render_context();
#endif #endif
} }
@@ -208,7 +208,8 @@ public:
#if defined(__IOS__) || defined(__OSX__) #if defined(__IOS__) || defined(__OSX__)
pp::platform::apple::active_legacy_apple_document_platform_services().present_render_context(); pp::platform::apple::active_legacy_apple_document_platform_services().present_render_context();
#elif __ANDROID__ #elif __ANDROID__
android_async_swap(); if (android_bridge_.present_render_context)
android_bridge_.present_render_context();
#elif __LINUX__ || __WEB__ #elif __LINUX__ || __WEB__
invoke_legacy_glfw_shell_callback(glfw_shell_.present_render_context); invoke_legacy_glfw_shell_callback(glfw_shell_.present_render_context);
#endif #endif
@@ -351,7 +352,8 @@ public:
#elif __OSX__ #elif __OSX__
pp::platform::apple::active_legacy_apple_document_platform_services().pick_image(std::move(callback)); pp::platform::apple::active_legacy_apple_document_platform_services().pick_image(std::move(callback));
#elif __ANDROID__ #elif __ANDROID__
android_pick_file(callback); if (android_bridge_.pick_file)
android_bridge_.pick_file(std::move(callback));
#elif __LINUX__ #elif __LINUX__
if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false)) if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false))
invoke_picked_path_if_selected(p, callback); invoke_picked_path_if_selected(p, callback);
@@ -369,7 +371,8 @@ public:
#elif __OSX__ #elif __OSX__
pp::platform::apple::active_legacy_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback)); pp::platform::apple::active_legacy_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback));
#elif __ANDROID__ #elif __ANDROID__
android_pick_file(callback); if (android_bridge_.pick_file)
android_bridge_.pick_file(std::move(callback));
#elif __LINUX__ #elif __LINUX__
if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false)) if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false))
invoke_picked_path_if_selected(p, callback); invoke_picked_path_if_selected(p, callback);
@@ -386,7 +389,8 @@ public:
#if __OSX__ #if __OSX__
pp::platform::apple::active_legacy_apple_document_platform_services().pick_save_file(std::move(file_types), std::move(callback)); pp::platform::apple::active_legacy_apple_document_platform_services().pick_save_file(std::move(file_types), std::move(callback));
#elif __ANDROID__ #elif __ANDROID__
android_pick_file_save(callback); if (android_bridge_.pick_save_file)
android_bridge_.pick_save_file(std::move(callback));
#else #else
(void)file_types; (void)file_types;
(void)callback; (void)callback;
@@ -577,6 +581,7 @@ private:
} }
pp::platform::legacy::LegacyGlfwPlatformShell glfw_shell_; pp::platform::legacy::LegacyGlfwPlatformShell glfw_shell_;
pp::platform::legacy::LegacyAndroidPlatformBridge android_bridge_;
#ifdef __ANDROID__ #ifdef __ANDROID__
std::shared_ptr<pp::platform::PlatformStoragePaths> android_storage_paths_; std::shared_ptr<pp::platform::PlatformStoragePaths> android_storage_paths_;
#endif #endif

View File

@@ -13,8 +13,22 @@ struct LegacyGlfwPlatformShell {
std::function<void()> request_app_close; std::function<void()> request_app_close;
}; };
struct LegacyAndroidPlatformBridge {
std::function<std::string()> clipboard_text;
std::function<bool(std::string_view text)> set_clipboard_text;
std::function<void(bool visible)> set_virtual_keyboard_visible;
std::function<void()> attach_ui_thread;
std::function<void()> detach_ui_thread;
std::function<void()> acquire_render_context;
std::function<void()> release_render_context;
std::function<void()> present_render_context;
std::function<void(PickedPathCallback callback)> pick_file;
std::function<void(PickedPathCallback callback)> pick_save_file;
};
struct LegacyPlatformServicesConfig { struct LegacyPlatformServicesConfig {
LegacyGlfwPlatformShell glfw_shell; LegacyGlfwPlatformShell glfw_shell;
LegacyAndroidPlatformBridge android_bridge;
std::shared_ptr<pp::platform::PlatformStoragePaths> android_storage_paths; std::shared_ptr<pp::platform::PlatformStoragePaths> android_storage_paths;
pp::platform::WebPlatformServices* web_platform_services = nullptr; pp::platform::WebPlatformServices* web_platform_services = nullptr;
}; };