WebView: use Asset_read() instead of Asset_openFileDescriptor()

openFileDescriptor doesn't work for assets which are compressed inside
the APK.
This commit is contained in:
Julian Winkler 2024-10-04 17:59:47 +02:00
parent 0627ae7e54
commit 21a75d7ff0
4 changed files with 45 additions and 7 deletions

View file

@ -92,6 +92,7 @@ libtranslationlayer_so = shared_library('translation_layer_main', [
'src/api-impl-jni/app/android_app_AlertDialog.c', 'src/api-impl-jni/app/android_app_AlertDialog.c',
'src/api-impl-jni/app/android_app_Dialog.c', 'src/api-impl-jni/app/android_app_Dialog.c',
'src/api-impl-jni/app/android_app_NotificationManager.c', 'src/api-impl-jni/app/android_app_NotificationManager.c',
'src/api-impl-jni/AssetInputStream.c',
'src/api-impl-jni/audio/android_media_AudioTrack.c', 'src/api-impl-jni/audio/android_media_AudioTrack.c',
'src/api-impl-jni/audio/android_media_SoundPool.c', 'src/api-impl-jni/audio/android_media_SoundPool.c',
'src/api-impl-jni/content/android_content_ClipboardManager.c', 'src/api-impl-jni/content/android_content_ClipboardManager.c',

View file

@ -0,0 +1,30 @@
#include <androidfw/androidfw_c_api.h>
#include "AssetInputStream.h"
static gssize asset_input_stream_read(GInputStream *gstream, void *buffer, gsize count, GCancellable *cancellable, GError **error) {
return Asset_read(ATL_ASSET_INPUT_STREAM(gstream)->asset, buffer, count);
}
static gboolean asset_input_stream_close(GInputStream *gstream, GCancellable *cancellable, GError **error) {
AssetInputStream *stream = ATL_ASSET_INPUT_STREAM(gstream);
Asset_delete(stream->asset);
stream->asset = NULL;
return TRUE;
}
static void asset_input_stream_class_init(AssetInputStreamClass *class) {
class->parent_class.read_fn = asset_input_stream_read;
class->parent_class.close_fn = asset_input_stream_close;
}
static void asset_input_stream_init(AssetInputStream *self) {
}
G_DEFINE_TYPE(AssetInputStream, asset_input_stream, G_TYPE_INPUT_STREAM)
GInputStream *asset_input_stream_new(struct Asset *asset) {
AssetInputStream *stream = g_object_new(asset_input_stream_get_type(), NULL);
stream->asset = asset;
return &stream->parent_instance;
}

View file

@ -0,0 +1,11 @@
#include <gio/gio.h>
struct _AssetInputStream
{
GInputStream parent_instance;
struct Asset *asset;
};
G_DECLARE_FINAL_TYPE(AssetInputStream, asset_input_stream, ATL, ASSET_INPUT_STREAM, GInputStream);
GInputStream *asset_input_stream_new(struct Asset *asset);

View file

@ -8,6 +8,7 @@
#include "../util.h" #include "../util.h"
#include "WrapperWidget.h" #include "WrapperWidget.h"
#include "../AssetInputStream.h"
#include "../generated_headers/android_view_View.h" #include "../generated_headers/android_view_View.h"
#include "../generated_headers/android_webkit_WebView.h" #include "../generated_headers/android_webkit_WebView.h"
@ -23,13 +24,8 @@ static void asset_uri_scheme_request_cb(WebKitURISchemeRequest *request, gpointe
jobject asset_manager_obj = (*env)->CallObjectMethod(env, wrapper->jobj, handle_cache.webview.internalGetAssetManager); jobject asset_manager_obj = (*env)->CallObjectMethod(env, wrapper->jobj, handle_cache.webview.internalGetAssetManager);
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(asset_manager_obj, "mObject")); struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(asset_manager_obj, "mObject"));
struct Asset *asset = AssetManager_openNonAsset(asset_manager, path, ACCESS_STREAMING); struct Asset *asset = AssetManager_openNonAsset(asset_manager, path, ACCESS_STREAMING);
off_t offset; GInputStream *stream = asset_input_stream_new(asset);
off_t size; webkit_uri_scheme_request_finish(request, stream, Asset_getLength(asset), NULL);
int fd = Asset_openFileDescriptor(asset, &offset, &size);
Asset_delete(asset);
GInputStream *stream = g_unix_input_stream_new(fd, TRUE);
g_input_stream_skip(stream, offset, NULL, NULL);
webkit_uri_scheme_request_finish(request, stream, size, NULL);
g_object_unref(stream); g_object_unref(stream);
} }